nanka iroiro

This commit is contained in:
syuilo 2017-06-09 01:03:54 +09:00
parent 0db3c8bcee
commit a2190ba2c1
17 changed files with 472 additions and 205 deletions

View file

@ -243,6 +243,10 @@ desktop:
title: "Notifications" title: "Notifications"
settings: "Notification settings" settings: "Notification settings"
mk-server-home-widget:
title: "Server info"
toggle: "Toggle views"
mk-activity-home-widget: mk-activity-home-widget:
title: "Activity" title: "Activity"
toggle: "Toggle views" toggle: "Toggle views"

View file

@ -243,6 +243,10 @@ desktop:
title: "通知" title: "通知"
settings: "通知の設定" settings: "通知の設定"
mk-server-home-widget:
title: "サーバー情報"
toggle: "表示を切り替え"
mk-activity-home-widget: mk-activity-home-widget:
title: "アクティビティ" title: "アクティビティ"
toggle: "表示を切り替え" toggle: "表示を切り替え"

View file

@ -1,150 +1,153 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "0.0.2038", "version": "0.0.2038",
"license": "MIT", "license": "MIT",
"description": "A miniblog-based SNS", "description": "A miniblog-based SNS",
"bugs": "https://github.com/syuilo/misskey/issues", "bugs": "https://github.com/syuilo/misskey/issues",
"repository": "https://github.com/syuilo/misskey.git", "repository": "https://github.com/syuilo/misskey.git",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,
"scripts": { "scripts": {
"config": "node ./tools/init.js", "config": "node ./tools/init.js",
"start": "node ./built", "start": "node ./built",
"debug": "DEBUG=misskey:* node ./built", "debug": "DEBUG=misskey:* node ./built",
"swagger": "node ./swagger.js", "swagger": "node ./swagger.js",
"build": "gulp build", "build": "gulp build",
"rebuild": "gulp rebuild", "rebuild": "gulp rebuild",
"clean": "gulp clean", "clean": "gulp clean",
"cleanall": "gulp cleanall", "cleanall": "gulp cleanall",
"lint": "gulp lint", "lint": "gulp lint",
"test": "gulp test" "test": "gulp test"
}, },
"devDependencies": { "devDependencies": {
"@types/bcryptjs": "2.4.0", "@types/bcryptjs": "2.4.0",
"@types/body-parser": "1.16.3", "@types/body-parser": "1.16.3",
"@types/chai": "4.0.0", "@types/chai": "4.0.0",
"@types/chai-http": "0.0.30", "@types/chai-http": "0.0.30",
"@types/chalk": "0.4.31", "@types/chalk": "0.4.31",
"@types/compression": "0.0.33", "@types/compression": "0.0.33",
"@types/cors": "2.8.1", "@types/cors": "2.8.1",
"@types/debug": "0.0.29", "@types/debug": "0.0.29",
"@types/deep-equal": "1.0.0", "@types/deep-equal": "1.0.0",
"@types/elasticsearch": "5.0.13", "@types/elasticsearch": "5.0.13",
"@types/event-stream": "3.3.31", "@types/event-stream": "3.3.31",
"@types/express": "4.0.35", "@types/express": "4.0.35",
"@types/gm": "1.17.31", "@types/gm": "1.17.31",
"@types/gulp": "4.0.3", "@types/gulp": "4.0.3",
"@types/gulp-mocha": "0.0.30", "@types/gulp-mocha": "0.0.30",
"@types/gulp-rename": "0.0.32", "@types/gulp-rename": "0.0.32",
"@types/gulp-replace": "0.0.30", "@types/gulp-replace": "0.0.30",
"@types/gulp-tslint": "3.6.31", "@types/gulp-tslint": "3.6.31",
"@types/gulp-typescript": "2.13.0", "@types/gulp-typescript": "2.13.0",
"@types/gulp-uglify": "0.0.30", "@types/gulp-uglify": "0.0.30",
"@types/gulp-util": "3.0.31", "@types/gulp-util": "3.0.31",
"@types/inquirer": "0.0.34", "@types/inquirer": "0.0.34",
"@types/is-root": "1.0.0", "@types/is-root": "1.0.0",
"@types/is-url": "1.2.28", "@types/is-url": "1.2.28",
"@types/js-yaml": "3.5.30", "@types/js-yaml": "3.5.30",
"@types/mocha": "2.2.41", "@types/mocha": "2.2.41",
"@types/mongodb": "2.2.3", "@types/mongodb": "2.2.3",
"@types/monk": "1.0.5", "@types/monk": "1.0.5",
"@types/morgan": "1.7.32", "@types/morgan": "1.7.32",
"@types/ms": "0.7.29", "@types/ms": "0.7.29",
"@types/multer": "0.0.34", "@types/multer": "0.0.34",
"@types/node": "7.0.29", "@types/node": "7.0.29",
"@types/ratelimiter": "2.1.28", "@types/ratelimiter": "2.1.28",
"@types/redis": "2.6.0", "@types/redis": "2.6.0",
"@types/request": "0.0.43", "@types/request": "0.0.43",
"@types/rimraf": "0.0.28", "@types/rimraf": "0.0.28",
"@types/riot": "2.6.2", "@types/riot": "2.6.2",
"@types/serve-favicon": "2.2.28", "@types/serve-favicon": "2.2.28",
"@types/uuid": "3.0.0", "@types/uuid": "3.0.0",
"@types/webpack": "2.2.15", "@types/webpack": "2.2.15",
"@types/webpack-stream": "3.2.7", "@types/webpack-stream": "3.2.7",
"@types/websocket": "0.0.33", "@types/websocket": "0.0.33",
"chai": "4.0.2", "chai": "4.0.2",
"chai-http": "3.0.0", "chai-http": "3.0.0",
"css-loader": "0.28.4", "css-loader": "0.28.4",
"event-stream": "3.3.4", "event-stream": "3.3.4",
"gulp": "3.9.1", "gulp": "3.9.1",
"gulp-cssnano": "2.1.2", "gulp-cssnano": "2.1.2",
"gulp-imagemin": "3.3.0", "gulp-imagemin": "3.3.0",
"gulp-mocha": "4.3.1", "gulp-mocha": "4.3.1",
"gulp-pug": "3.3.0", "gulp-pug": "3.3.0",
"gulp-rename": "1.2.2", "gulp-rename": "1.2.2",
"gulp-replace": "0.5.4", "gulp-replace": "0.5.4",
"gulp-tslint": "8.1.1", "gulp-tslint": "8.1.1",
"gulp-typescript": "3.1.7", "gulp-typescript": "3.1.7",
"gulp-uglify": "3.0.0", "gulp-uglify": "3.0.0",
"gulp-util": "3.0.8", "gulp-util": "3.0.8",
"mocha": "3.4.2", "mocha": "3.4.2",
"riot-tag-loader": "1.0.0", "riot-tag-loader": "1.0.0",
"string-replace-webpack-plugin": "0.1.3", "string-replace-webpack-plugin": "0.1.3",
"style-loader": "0.18.2", "style-loader": "0.18.2",
"stylus": "0.54.5", "stylus": "0.54.5",
"stylus-loader": "3.0.1", "stylus-loader": "3.0.1",
"swagger-jsdoc": "1.9.4", "swagger-jsdoc": "1.9.4",
"tslint": "5.4.3", "tslint": "5.4.3",
"uglify-es": "3.0.15", "uglify-es": "3.0.15",
"uglify-es-webpack-plugin": "0.0.2", "uglify-es-webpack-plugin": "0.0.2",
"uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony", "uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony",
"webpack": "2.6.1" "webpack": "2.6.1"
}, },
"dependencies": { "dependencies": {
"accesses": "2.5.0", "accesses": "2.5.0",
"animejs": "2.0.2", "animejs": "2.0.2",
"autwh": "0.0.1", "autwh": "0.0.1",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"body-parser": "1.17.2", "body-parser": "1.17.2",
"cafy": "2.4.0", "cafy": "2.4.0",
"chalk": "1.1.3", "chalk": "1.1.3",
"compression": "1.6.2", "compression": "1.6.2",
"cors": "2.8.3", "cors": "2.8.3",
"cropperjs": "1.0.0-rc.2", "cropperjs": "1.0.0-rc.2",
"crypto": "0.0.3", "crypto": "0.0.3",
"debug": "2.6.8", "debug": "2.6.8",
"deep-equal": "1.0.1", "deep-equal": "1.0.1",
"deepcopy": "0.6.3", "deepcopy": "0.6.3",
"download": "6.2.2", "diskusage": "^0.2.2",
"elasticsearch": "13.0.1", "download": "6.2.2",
"escape-regexp": "0.0.1", "elasticsearch": "13.0.1",
"express": "4.15.3", "escape-regexp": "0.0.1",
"file-type": "5.0.0", "express": "4.15.3",
"fuckadblock": "3.2.1", "file-type": "5.0.0",
"gm": "1.23.0", "fuckadblock": "3.2.1",
"inquirer": "3.1.0", "gm": "1.23.0",
"is-root": "1.0.0", "inquirer": "3.1.0",
"is-url": "1.2.2", "is-root": "1.0.0",
"js-yaml": "3.8.4", "is-url": "1.2.2",
"mongodb": "2.2.28", "js-yaml": "3.8.4",
"monk": "6.0.0", "mongodb": "2.2.28",
"morgan": "1.8.2", "monk": "6.0.0",
"ms": "2.0.0", "morgan": "1.8.2",
"multer": "1.3.0", "ms": "2.0.0",
"nprogress": "0.2.0", "multer": "1.3.0",
"page": "1.7.1", "nprogress": "0.2.0",
"pictograph": "2.0.4", "os-utils": "0.0.14",
"prominence": "0.2.0", "page": "1.7.1",
"pug": "2.0.0-rc.2", "pictograph": "2.0.4",
"ratelimiter": "3.0.3", "prominence": "0.2.0",
"recaptcha-promise": "0.1.2", "pug": "2.0.0-rc.2",
"reconnecting-websocket": "3.0.5", "ratelimiter": "3.0.3",
"redis": "2.7.1", "recaptcha-promise": "0.1.2",
"request": "2.81.0", "reconnecting-websocket": "3.0.5",
"rimraf": "2.6.1", "redis": "2.7.1",
"riot": "3.6.0", "request": "2.81.0",
"rndstr": "1.0.0", "rimraf": "2.6.1",
"s-age": "1.1.0", "riot": "3.6.0",
"serve-favicon": "2.4.3", "rndstr": "1.0.0",
"summaly": "2.0.3", "s-age": "1.1.0",
"syuilo-password-strength": "0.0.1", "serve-favicon": "2.4.3",
"tcp-port-used": "0.1.2", "summaly": "2.0.3",
"textarea-caret": "3.0.2", "syuilo-password-strength": "0.0.1",
"ts-node": "3.0.6", "tcp-port-used": "0.1.2",
"typescript": "2.3.4", "textarea-caret": "3.0.2",
"uuid": "3.0.1", "ts-node": "3.0.6",
"vhost": "3.0.2", "typescript": "2.3.4",
"websocket": "1.0.24" "uuid": "3.0.1",
} "vhost": "3.0.2",
"websocket": "1.0.24",
"xev": "^2.0.0"
}
} }

20
src/api/stream/server.ts Normal file
View file

@ -0,0 +1,20 @@
import * as websocket from 'websocket';
import Xev from 'xev';
const ev = new Xev();
export default function homeStream(request: websocket.request, connection: websocket.connection): void {
const onStats = stats => {
connection.send(JSON.stringify({
type: 'stats',
body: stats
}));
};
ev.addListener('stats', onStats);
connection.on('close', () => {
console.log('yooo');
ev.removeListener('stats', onStats);
});
}

View file

@ -8,6 +8,7 @@ import isNativeToken from './common/is-native-token';
import homeStream from './stream/home'; import homeStream from './stream/home';
import messagingStream from './stream/messaging'; import messagingStream from './stream/messaging';
import serverStream from './stream/server';
module.exports = (server: http.Server) => { module.exports = (server: http.Server) => {
/** /**
@ -20,6 +21,11 @@ module.exports = (server: http.Server) => {
ws.on('request', async (request) => { ws.on('request', async (request) => {
const connection = request.accept(); const connection = request.accept();
if (request.resourceURL.pathname === '/server') {
serverStream(request, connection);
return;
}
const user = await authenticate(connection, request.resourceURL.query.i); const user = await authenticate(connection, request.resourceURL.query.i);
if (user == null) { if (user == null) {

View file

@ -12,17 +12,20 @@ import * as chalk from 'chalk';
// import portUsed = require('tcp-port-used'); // import portUsed = require('tcp-port-used');
import isRoot = require('is-root'); import isRoot = require('is-root');
import { master } from 'accesses'; import { master } from 'accesses';
import Xev from 'xev';
import Logger from './utils/logger'; import Logger from './utils/logger';
import ProgressBar from './utils/cli/progressbar'; import ProgressBar from './utils/cli/progressbar';
import EnvironmentInfo from './utils/environmentInfo'; import EnvironmentInfo from './utils/environmentInfo';
import MachineInfo from './utils/machineInfo'; import MachineInfo from './utils/machineInfo';
import DependencyInfo from './utils/dependencyInfo'; import DependencyInfo from './utils/dependencyInfo';
import stats from './utils/stats';
import { Config, path as configPath } from './config'; import { Config, path as configPath } from './config';
import loadConfig from './config'; import loadConfig from './config';
const clusterLog = debug('misskey:cluster'); const clusterLog = debug('misskey:cluster');
const ev = new Xev();
process.title = 'Misskey'; process.title = 'Misskey';
@ -35,6 +38,9 @@ main();
function main() { function main() {
if (cluster.isMaster) { if (cluster.isMaster) {
masterMain(); masterMain();
ev.mount();
stats();
} else { } else {
workerMain(); workerMain();
} }

25
src/utils/stats.ts Normal file
View file

@ -0,0 +1,25 @@
import * as os from 'os';
const osUtils = require('os-utils');
import * as diskusage from 'diskusage';
import Xev from 'xev';
const ev = new Xev();
/**
* Report stats regularly
*/
export default function() {
setInterval(() => {
osUtils.cpuUsage(cpuUsage => {
const disk = diskusage.checkSync(os.platform() == 'win32' ? 'c:' : '/');
ev.emit('stats', {
cpu_usage: cpuUsage,
mem: {
total: os.totalmem(),
free: os.freemem()
},
disk
});
});
}, 1000);
}

View file

@ -0,0 +1,18 @@
'use strict';
import Stream from './stream';
/**
* Home stream connection
*/
class Connection extends Stream {
constructor(me) {
super('', {
i: me.token
});
this.on('i_updated', me.update);
}
}
export default Connection;

View file

@ -1,42 +1,22 @@
const ReconnectingWebSocket = require('reconnecting-websocket'); 'use strict';
import * as riot from 'riot';
import CONFIG from './config';
class Connection { import Stream from './stream';
/**
* Messaging stream connection
*/
class Connection extends Stream {
constructor(me, otherparty) { constructor(me, otherparty) {
// BIND ----------------------------------- super('messaging', {
this.onOpen = this.onOpen.bind(this); i: me.token,
this.onMessage = this.onMessage.bind(this); otherparty
this.close = this.close.bind(this); });
// ----------------------------------------
this.event = riot.observable(); this.on('_connected_', () => {
this.me = me; this.send({
i: me.token
const host = CONFIG.apiUrl.replace('http', 'ws'); });
this.socket = new ReconnectingWebSocket(`${host}/messaging?i=${me.token}&otherparty=${otherparty}`); });
this.socket.addEventListener('open', this.onOpen);
this.socket.addEventListener('message', this.onMessage);
}
onOpen() {
this.socket.send(JSON.stringify({
i: this.me.token
}));
}
onMessage(message) {
try {
const msg = JSON.parse(message.data);
if (msg.type) this.event.trigger(msg.type, msg.body);
} catch(e) {
// noop
}
}
close() {
this.socket.removeEventListener('open', this.onOpen);
this.socket.removeEventListener('message', this.onMessage);
} }
} }

View file

@ -0,0 +1,14 @@
'use strict';
import Stream from './stream';
/**
* Server stream connection
*/
class Connection extends Stream {
constructor() {
super('server');
}
}
export default Connection;

View file

@ -5,10 +5,10 @@ import * as riot from 'riot';
import CONFIG from './config'; import CONFIG from './config';
/** /**
* Home stream connection * Misskey stream connection
*/ */
class Connection { class Connection {
constructor(me) { constructor(endpoint, params) {
// BIND ----------------------------------- // BIND -----------------------------------
this.onOpen = this.onOpen.bind(this); this.onOpen = this.onOpen.bind(this);
this.onClose = this.onClose.bind(this); this.onClose = this.onClose.bind(this);
@ -20,16 +20,19 @@ class Connection {
riot.observable(this); riot.observable(this);
this.state = 'initializing'; this.state = 'initializing';
this.me = me;
this.buffer = []; this.buffer = [];
const host = CONFIG.apiUrl.replace('http', 'ws'); const host = CONFIG.apiUrl.replace('http', 'ws');
this.socket = new ReconnectingWebSocket(`${host}?i=${me.token}`); const query = params
? Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&')
: null;
this.socket = new ReconnectingWebSocket(`${host}/${endpoint}${query ? '?' + query : ''}`);
this.socket.addEventListener('open', this.onOpen); this.socket.addEventListener('open', this.onOpen);
this.socket.addEventListener('close', this.onClose); this.socket.addEventListener('close', this.onClose);
this.socket.addEventListener('message', this.onMessage); this.socket.addEventListener('message', this.onMessage);
this.on('i_updated', me.update);
} }
/** /**

View file

@ -137,8 +137,8 @@
this.connection = new MessagingStreamConnection(this.I, this.user.id); this.connection = new MessagingStreamConnection(this.I, this.user.id);
this.on('mount', () => { this.on('mount', () => {
this.connection.event.on('message', this.onMessage); this.connection.on('message', this.onMessage);
this.connection.event.on('read', this.onRead); this.connection.on('read', this.onRead);
document.addEventListener('visibilitychange', this.onVisibilitychange); document.addEventListener('visibilitychange', this.onVisibilitychange);
@ -153,8 +153,8 @@
}); });
this.on('unmount', () => { this.on('unmount', () => {
this.connection.event.off('message', this.onMessage); this.connection.off('message', this.onMessage);
this.connection.event.off('read', this.onRead); this.connection.off('read', this.onRead);
this.connection.close(); this.connection.close();
document.removeEventListener('visibilitychange', this.onVisibilitychange); document.removeEventListener('visibilitychange', this.onVisibilitychange);
@ -174,10 +174,10 @@
this.messages.push(message); this.messages.push(message);
if (message.user_id != this.I.id && !document.hidden) { if (message.user_id != this.I.id && !document.hidden) {
this.connection.socket.send(JSON.stringify({ this.connection.send({
type: 'read', type: 'read',
id: message.id id: message.id
})); });
} }
this.update(); this.update();
@ -239,10 +239,10 @@
if (document.hidden) return; if (document.hidden) return;
this.messages.forEach(message => { this.messages.forEach(message => {
if (message.user_id !== this.I.id && !message.is_read) { if (message.user_id !== this.I.id && !message.is_read) {
this.connection.socket.send(JSON.stringify({ this.connection.send({
type: 'read', type: 'read',
id: message.id id: message.id
})); });
} }
}); });
}; };

View file

@ -100,6 +100,8 @@
</svg> </svg>
<style> <style>
:scope :scope
display block
> svg > svg
display block display block
padding 10px padding 10px
@ -131,7 +133,7 @@
</mk-activity-home-widget-calender> </mk-activity-home-widget-calender>
<mk-activity-home-widget-chart> <mk-activity-home-widget-chart>
<svg riot-viewBox="0 0 { viewBoxX } 60" preserveAspectRatio="none" onmousedown={ onMousedown }> <svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none" onmousedown={ onMousedown }>
<polyline <polyline
riot-points={ pointsPost } riot-points={ pointsPost }
fill="none" fill="none"
@ -155,6 +157,8 @@
</svg> </svg>
<style> <style>
:scope :scope
display block
> svg > svg
display block display block
padding 10px padding 10px
@ -163,6 +167,7 @@
</style> </style>
<script> <script>
this.viewBoxX = 140; this.viewBoxX = 140;
this.viewBoxY = 60;
this.zoom = 1; this.zoom = 1;
this.pos = 0; this.pos = 0;
@ -176,10 +181,10 @@
this.render = () => { this.render = () => {
this.update({ this.update({
pointsPost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * 60}`).join(' '), pointsPost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' '),
pointsReply: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * 60}`).join(' '), pointsReply: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' '),
pointsRepost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * 60}`).join(' '), pointsRepost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' '),
pointsTotal: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * 60}`).join(' ') pointsTotal: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ')
}); });
}; };

View file

@ -0,0 +1,177 @@
<mk-server-home-widget>
<p class="title"><i class="fa fa-server"></i>%i18n:desktop.tags.mk-server-home-widget.title%</p>
<button onclick={ toggle } title="%i18n:desktop.tags.mk-server-home-widget.toggle%"><i class="fa fa-sort"></i></button>
<p class="initializing" if={ initializing }><i class="fa fa-spinner fa-pulse fa-fw"></i>%i18n:common.loading%<mk-ellipsis/></p>
<mk-server-home-widget-stats if={ !initializing && view == 0 }/>
<mk-server-home-widget-info if={ !initializing && view == 1 } meta={ meta }/>
<style>
:scope
display block
background #fff
> .title
z-index 1
margin 0
padding 0 16px
line-height 42px
font-size 0.9em
font-weight bold
color #888
box-shadow 0 1px rgba(0, 0, 0, 0.07)
> i
margin-right 4px
> button
position absolute
z-index 2
top 0
right 0
padding 0
width 42px
font-size 0.9em
line-height 42px
color #ccc
&:hover
color #aaa
&:active
color #999
> .initializing
margin 0
padding 16px
text-align center
color #aaa
> i
margin-right 4px
</style>
<script>
this.mixin('api');
this.initializing = true;
this.view = 0;
this.on('mount', () => {
this.api('meta').then(meta => {
this.update({
initializing: false,
meta
});
});
});
this.toggle = () => {
this.view++;
if (this.view == 2) this.view = 0;
};
</script>
</mk-server-home-widget>
<mk-server-home-widget-stats>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
<text dx="1" dy="5">CPU</text>
<polygon
riot-points={ cpuPolygonPoints }
riot-fill={ cpuColor }
fill-opacity="0.5"/>
<polyline
riot-points={ cpuPolylinePoints }
fill="none"
stroke-width="1"
riot-stroke={ cpuColor }/>
</svg>
<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none">
<text dx="1" dy="5">MEM</text>
<polygon
riot-points={ memPolygonPoints }
riot-fill={ memColor }
fill-opacity="0.5"/>
<polyline
riot-points={ memPolylinePoints }
fill="none"
stroke-width="1"
riot-stroke={ memColor }/>
</svg>
<style>
:scope
display block
> svg
display block
padding 10px
width 50%
float left
&:first-child
padding-right 5px
&:last-child
padding-left 5px
> text
font-size 5px
fill #7b7b7b
&:after
content ""
display block
clear both
</style>
<script>
import Connection from '../../../common/scripts/server-stream';
this.viewBoxX = 50;
this.viewBoxY = 30;
this.stats = [];
this.connection = new Connection();
this.on('mount', () => {
this.connection.on('stats', this.onStats);
});
this.on('unmount', () => {
this.connection.off('stats', this.onStats);
this.connection.close();
});
this.onStats = stats => {
this.stats.push(stats);
if (this.stats.length > 50) this.stats.shift();
const cpuPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - s.cpu_usage) * this.viewBoxY}`).join(' ');
const memPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(s.mem.free / s.mem.total) * this.viewBoxY}`).join(' ');
const cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ cpuPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
const memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ memPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
const cpuColor = `hsl(${180 - (stats.cpu_usage * 180)}, 80%, 70%)`;
const memColor = `hsl(${180 - (stats.mem.free / stats.mem.total * 180)}, 80%, 70%)`;
this.update({
cpuPolylinePoints,
memPolylinePoints,
cpuPolygonPoints,
memPolygonPoints,
cpuColor,
memColor
});
};
</script>
</mk-server-home-widget-stats>
<mk-server-home-widget-info>
<p>Maintainer: { meta.maintainer }</p>
<style>
:scope
display block
padding 10px
</style>
<script>
this.meta = this.opts.meta;
</script>
</mk-server-home-widget-info>

View file

@ -70,6 +70,7 @@
'rss-reader', 'rss-reader',
'trends', 'trends',
'photo-stream', 'photo-stream',
'server',
'version' 'version'
], ],
right: [ right: [

View file

@ -45,6 +45,7 @@ require('./home-widgets/version.tag');
require('./home-widgets/recommended-polls.tag'); require('./home-widgets/recommended-polls.tag');
require('./home-widgets/trends.tag'); require('./home-widgets/trends.tag');
require('./home-widgets/activity.tag'); require('./home-widgets/activity.tag');
require('./home-widgets/server.tag');
require('./timeline.tag'); require('./timeline.tag');
require('./messaging/window.tag'); require('./messaging/window.tag');
require('./messaging/room-window.tag'); require('./messaging/room-window.tag');

View file

@ -8,7 +8,7 @@ import * as riot from 'riot';
import api from './common/scripts/api'; import api from './common/scripts/api';
import signout from './common/scripts/signout'; import signout from './common/scripts/signout';
import checkForUpdate from './common/scripts/check-for-update'; import checkForUpdate from './common/scripts/check-for-update';
import Connection from './common/scripts/stream'; import Connection from './common/scripts/home-stream';
import mixin from './common/mixins'; import mixin from './common/mixins';
import generateDefaultUserdata from './common/scripts/generate-default-userdata'; import generateDefaultUserdata from './common/scripts/generate-default-userdata';
import CONFIG from './common/scripts/config'; import CONFIG from './common/scripts/config';
@ -95,7 +95,7 @@ export default callback => {
}); });
} }
// Init stream connection // Init home stream connection
const stream = me ? new Connection(me) : null; const stream = me ? new Connection(me) : null;
// ミックスイン初期化 // ミックスイン初期化