summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2017-06-09 01:03:54 +0900
committersyuilo <syuilotan@yahoo.co.jp>2017-06-09 01:03:54 +0900
commit4e5545af384f610a56b3d19ea73c3b801b0be6c6 (patch)
tree4cd0b12e891bd1d8991ac4ad14cbbb7af83a0aee
parentv2038 (diff)
downloadmisskey-4e5545af384f610a56b3d19ea73c3b801b0be6c6.tar.gz
misskey-4e5545af384f610a56b3d19ea73c3b801b0be6c6.tar.bz2
misskey-4e5545af384f610a56b3d19ea73c3b801b0be6c6.zip
nanka iroiro
-rw-r--r--locales/en.yml4
-rw-r--r--locales/ja.yml4
-rw-r--r--package.json299
-rw-r--r--src/api/stream/server.ts20
-rw-r--r--src/api/streaming.ts6
-rw-r--r--src/index.ts6
-rw-r--r--src/utils/stats.ts25
-rw-r--r--src/web/app/common/scripts/home-stream.js18
-rw-r--r--src/web/app/common/scripts/messaging-stream.js52
-rw-r--r--src/web/app/common/scripts/server-stream.js14
-rw-r--r--src/web/app/common/scripts/stream.js15
-rw-r--r--src/web/app/common/tags/messaging/room.tag16
-rw-r--r--src/web/app/desktop/tags/home-widgets/activity.tag15
-rw-r--r--src/web/app/desktop/tags/home-widgets/server.tag177
-rw-r--r--src/web/app/desktop/tags/home.tag1
-rw-r--r--src/web/app/desktop/tags/index.js1
-rw-r--r--src/web/app/init.js4
17 files changed, 472 insertions, 205 deletions
diff --git a/locales/en.yml b/locales/en.yml
index 6104cbdc9d..e15a7c9ae4 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -243,6 +243,10 @@ desktop:
title: "Notifications"
settings: "Notification settings"
+ mk-server-home-widget:
+ title: "Server info"
+ toggle: "Toggle views"
+
mk-activity-home-widget:
title: "Activity"
toggle: "Toggle views"
diff --git a/locales/ja.yml b/locales/ja.yml
index e83c0eb724..5ed1d4f1ee 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -243,6 +243,10 @@ desktop:
title: "通知"
settings: "通知の設定"
+ mk-server-home-widget:
+ title: "サーバー情報"
+ toggle: "表示を切り替え"
+
mk-activity-home-widget:
title: "アクティビティ"
toggle: "表示を切り替え"
diff --git a/package.json b/package.json
index fd10ea50cb..93f87561fa 100644
--- a/package.json
+++ b/package.json
@@ -1,150 +1,153 @@
{
- "name": "misskey",
- "author": "syuilo <i@syuilo.com>",
- "version": "0.0.2038",
- "license": "MIT",
- "description": "A miniblog-based SNS",
- "bugs": "https://github.com/syuilo/misskey/issues",
- "repository": "https://github.com/syuilo/misskey.git",
- "main": "./built/index.js",
- "private": true,
- "scripts": {
- "config": "node ./tools/init.js",
- "start": "node ./built",
- "debug": "DEBUG=misskey:* node ./built",
- "swagger": "node ./swagger.js",
- "build": "gulp build",
- "rebuild": "gulp rebuild",
- "clean": "gulp clean",
- "cleanall": "gulp cleanall",
- "lint": "gulp lint",
- "test": "gulp test"
- },
- "devDependencies": {
- "@types/bcryptjs": "2.4.0",
- "@types/body-parser": "1.16.3",
- "@types/chai": "4.0.0",
- "@types/chai-http": "0.0.30",
- "@types/chalk": "0.4.31",
- "@types/compression": "0.0.33",
- "@types/cors": "2.8.1",
- "@types/debug": "0.0.29",
- "@types/deep-equal": "1.0.0",
- "@types/elasticsearch": "5.0.13",
- "@types/event-stream": "3.3.31",
- "@types/express": "4.0.35",
- "@types/gm": "1.17.31",
- "@types/gulp": "4.0.3",
- "@types/gulp-mocha": "0.0.30",
- "@types/gulp-rename": "0.0.32",
- "@types/gulp-replace": "0.0.30",
- "@types/gulp-tslint": "3.6.31",
- "@types/gulp-typescript": "2.13.0",
- "@types/gulp-uglify": "0.0.30",
- "@types/gulp-util": "3.0.31",
- "@types/inquirer": "0.0.34",
- "@types/is-root": "1.0.0",
- "@types/is-url": "1.2.28",
- "@types/js-yaml": "3.5.30",
- "@types/mocha": "2.2.41",
- "@types/mongodb": "2.2.3",
- "@types/monk": "1.0.5",
- "@types/morgan": "1.7.32",
- "@types/ms": "0.7.29",
- "@types/multer": "0.0.34",
- "@types/node": "7.0.29",
- "@types/ratelimiter": "2.1.28",
- "@types/redis": "2.6.0",
- "@types/request": "0.0.43",
- "@types/rimraf": "0.0.28",
- "@types/riot": "2.6.2",
- "@types/serve-favicon": "2.2.28",
- "@types/uuid": "3.0.0",
- "@types/webpack": "2.2.15",
- "@types/webpack-stream": "3.2.7",
- "@types/websocket": "0.0.33",
- "chai": "4.0.2",
- "chai-http": "3.0.0",
- "css-loader": "0.28.4",
- "event-stream": "3.3.4",
- "gulp": "3.9.1",
- "gulp-cssnano": "2.1.2",
- "gulp-imagemin": "3.3.0",
- "gulp-mocha": "4.3.1",
- "gulp-pug": "3.3.0",
- "gulp-rename": "1.2.2",
- "gulp-replace": "0.5.4",
- "gulp-tslint": "8.1.1",
- "gulp-typescript": "3.1.7",
- "gulp-uglify": "3.0.0",
- "gulp-util": "3.0.8",
- "mocha": "3.4.2",
- "riot-tag-loader": "1.0.0",
- "string-replace-webpack-plugin": "0.1.3",
- "style-loader": "0.18.2",
- "stylus": "0.54.5",
- "stylus-loader": "3.0.1",
- "swagger-jsdoc": "1.9.4",
- "tslint": "5.4.3",
- "uglify-es": "3.0.15",
- "uglify-es-webpack-plugin": "0.0.2",
- "uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony",
- "webpack": "2.6.1"
- },
- "dependencies": {
- "accesses": "2.5.0",
- "animejs": "2.0.2",
- "autwh": "0.0.1",
- "bcryptjs": "2.4.3",
- "body-parser": "1.17.2",
- "cafy": "2.4.0",
- "chalk": "1.1.3",
- "compression": "1.6.2",
- "cors": "2.8.3",
- "cropperjs": "1.0.0-rc.2",
- "crypto": "0.0.3",
- "debug": "2.6.8",
- "deep-equal": "1.0.1",
- "deepcopy": "0.6.3",
- "download": "6.2.2",
- "elasticsearch": "13.0.1",
- "escape-regexp": "0.0.1",
- "express": "4.15.3",
- "file-type": "5.0.0",
- "fuckadblock": "3.2.1",
- "gm": "1.23.0",
- "inquirer": "3.1.0",
- "is-root": "1.0.0",
- "is-url": "1.2.2",
- "js-yaml": "3.8.4",
- "mongodb": "2.2.28",
- "monk": "6.0.0",
- "morgan": "1.8.2",
- "ms": "2.0.0",
- "multer": "1.3.0",
- "nprogress": "0.2.0",
- "page": "1.7.1",
- "pictograph": "2.0.4",
- "prominence": "0.2.0",
- "pug": "2.0.0-rc.2",
- "ratelimiter": "3.0.3",
- "recaptcha-promise": "0.1.2",
- "reconnecting-websocket": "3.0.5",
- "redis": "2.7.1",
- "request": "2.81.0",
- "rimraf": "2.6.1",
- "riot": "3.6.0",
- "rndstr": "1.0.0",
- "s-age": "1.1.0",
- "serve-favicon": "2.4.3",
- "summaly": "2.0.3",
- "syuilo-password-strength": "0.0.1",
- "tcp-port-used": "0.1.2",
- "textarea-caret": "3.0.2",
- "ts-node": "3.0.6",
- "typescript": "2.3.4",
- "uuid": "3.0.1",
- "vhost": "3.0.2",
- "websocket": "1.0.24"
- }
+ "name": "misskey",
+ "author": "syuilo <i@syuilo.com>",
+ "version": "0.0.2038",
+ "license": "MIT",
+ "description": "A miniblog-based SNS",
+ "bugs": "https://github.com/syuilo/misskey/issues",
+ "repository": "https://github.com/syuilo/misskey.git",
+ "main": "./built/index.js",
+ "private": true,
+ "scripts": {
+ "config": "node ./tools/init.js",
+ "start": "node ./built",
+ "debug": "DEBUG=misskey:* node ./built",
+ "swagger": "node ./swagger.js",
+ "build": "gulp build",
+ "rebuild": "gulp rebuild",
+ "clean": "gulp clean",
+ "cleanall": "gulp cleanall",
+ "lint": "gulp lint",
+ "test": "gulp test"
+ },
+ "devDependencies": {
+ "@types/bcryptjs": "2.4.0",
+ "@types/body-parser": "1.16.3",
+ "@types/chai": "4.0.0",
+ "@types/chai-http": "0.0.30",
+ "@types/chalk": "0.4.31",
+ "@types/compression": "0.0.33",
+ "@types/cors": "2.8.1",
+ "@types/debug": "0.0.29",
+ "@types/deep-equal": "1.0.0",
+ "@types/elasticsearch": "5.0.13",
+ "@types/event-stream": "3.3.31",
+ "@types/express": "4.0.35",
+ "@types/gm": "1.17.31",
+ "@types/gulp": "4.0.3",
+ "@types/gulp-mocha": "0.0.30",
+ "@types/gulp-rename": "0.0.32",
+ "@types/gulp-replace": "0.0.30",
+ "@types/gulp-tslint": "3.6.31",
+ "@types/gulp-typescript": "2.13.0",
+ "@types/gulp-uglify": "0.0.30",
+ "@types/gulp-util": "3.0.31",
+ "@types/inquirer": "0.0.34",
+ "@types/is-root": "1.0.0",
+ "@types/is-url": "1.2.28",
+ "@types/js-yaml": "3.5.30",
+ "@types/mocha": "2.2.41",
+ "@types/mongodb": "2.2.3",
+ "@types/monk": "1.0.5",
+ "@types/morgan": "1.7.32",
+ "@types/ms": "0.7.29",
+ "@types/multer": "0.0.34",
+ "@types/node": "7.0.29",
+ "@types/ratelimiter": "2.1.28",
+ "@types/redis": "2.6.0",
+ "@types/request": "0.0.43",
+ "@types/rimraf": "0.0.28",
+ "@types/riot": "2.6.2",
+ "@types/serve-favicon": "2.2.28",
+ "@types/uuid": "3.0.0",
+ "@types/webpack": "2.2.15",
+ "@types/webpack-stream": "3.2.7",
+ "@types/websocket": "0.0.33",
+ "chai": "4.0.2",
+ "chai-http": "3.0.0",
+ "css-loader": "0.28.4",
+ "event-stream": "3.3.4",
+ "gulp": "3.9.1",
+ "gulp-cssnano": "2.1.2",
+ "gulp-imagemin": "3.3.0",
+ "gulp-mocha": "4.3.1",
+ "gulp-pug": "3.3.0",
+ "gulp-rename": "1.2.2",
+ "gulp-replace": "0.5.4",
+ "gulp-tslint": "8.1.1",
+ "gulp-typescript": "3.1.7",
+ "gulp-uglify": "3.0.0",
+ "gulp-util": "3.0.8",
+ "mocha": "3.4.2",
+ "riot-tag-loader": "1.0.0",
+ "string-replace-webpack-plugin": "0.1.3",
+ "style-loader": "0.18.2",
+ "stylus": "0.54.5",
+ "stylus-loader": "3.0.1",
+ "swagger-jsdoc": "1.9.4",
+ "tslint": "5.4.3",
+ "uglify-es": "3.0.15",
+ "uglify-es-webpack-plugin": "0.0.2",
+ "uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony",
+ "webpack": "2.6.1"
+ },
+ "dependencies": {
+ "accesses": "2.5.0",
+ "animejs": "2.0.2",
+ "autwh": "0.0.1",
+ "bcryptjs": "2.4.3",
+ "body-parser": "1.17.2",
+ "cafy": "2.4.0",
+ "chalk": "1.1.3",
+ "compression": "1.6.2",
+ "cors": "2.8.3",
+ "cropperjs": "1.0.0-rc.2",
+ "crypto": "0.0.3",
+ "debug": "2.6.8",
+ "deep-equal": "1.0.1",
+ "deepcopy": "0.6.3",
+ "diskusage": "^0.2.2",
+ "download": "6.2.2",
+ "elasticsearch": "13.0.1",
+ "escape-regexp": "0.0.1",
+ "express": "4.15.3",
+ "file-type": "5.0.0",
+ "fuckadblock": "3.2.1",
+ "gm": "1.23.0",
+ "inquirer": "3.1.0",
+ "is-root": "1.0.0",
+ "is-url": "1.2.2",
+ "js-yaml": "3.8.4",
+ "mongodb": "2.2.28",
+ "monk": "6.0.0",
+ "morgan": "1.8.2",
+ "ms": "2.0.0",
+ "multer": "1.3.0",
+ "nprogress": "0.2.0",
+ "os-utils": "0.0.14",
+ "page": "1.7.1",
+ "pictograph": "2.0.4",
+ "prominence": "0.2.0",
+ "pug": "2.0.0-rc.2",
+ "ratelimiter": "3.0.3",
+ "recaptcha-promise": "0.1.2",
+ "reconnecting-websocket": "3.0.5",
+ "redis": "2.7.1",
+ "request": "2.81.0",
+ "rimraf": "2.6.1",
+ "riot": "3.6.0",
+ "rndstr": "1.0.0",
+ "s-age": "1.1.0",
+ "serve-favicon": "2.4.3",
+ "summaly": "2.0.3",
+ "syuilo-password-strength": "0.0.1",
+ "tcp-port-used": "0.1.2",
+ "textarea-caret": "3.0.2",
+ "ts-node": "3.0.6",
+ "typescript": "2.3.4",
+ "uuid": "3.0.1",
+ "vhost": "3.0.2",
+ "websocket": "1.0.24",
+ "xev": "^2.0.0"
+ }
}
diff --git a/src/api/stream/server.ts b/src/api/stream/server.ts
new file mode 100644
index 0000000000..6de5337499
--- /dev/null
+++ b/src/api/stream/server.ts
@@ -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);
+ });
+}
diff --git a/src/api/streaming.ts b/src/api/streaming.ts
index e1d79481d3..c71132100c 100644
--- a/src/api/streaming.ts
+++ b/src/api/streaming.ts
@@ -8,6 +8,7 @@ import isNativeToken from './common/is-native-token';
import homeStream from './stream/home';
import messagingStream from './stream/messaging';
+import serverStream from './stream/server';
module.exports = (server: http.Server) => {
/**
@@ -20,6 +21,11 @@ module.exports = (server: http.Server) => {
ws.on('request', async (request) => {
const connection = request.accept();
+ if (request.resourceURL.pathname === '/server') {
+ serverStream(request, connection);
+ return;
+ }
+
const user = await authenticate(connection, request.resourceURL.query.i);
if (user == null) {
diff --git a/src/index.ts b/src/index.ts
index 0b568b5d44..da83dde108 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -12,17 +12,20 @@ import * as chalk from 'chalk';
// import portUsed = require('tcp-port-used');
import isRoot = require('is-root');
import { master } from 'accesses';
+import Xev from 'xev';
import Logger from './utils/logger';
import ProgressBar from './utils/cli/progressbar';
import EnvironmentInfo from './utils/environmentInfo';
import MachineInfo from './utils/machineInfo';
import DependencyInfo from './utils/dependencyInfo';
+import stats from './utils/stats';
import { Config, path as configPath } from './config';
import loadConfig from './config';
const clusterLog = debug('misskey:cluster');
+const ev = new Xev();
process.title = 'Misskey';
@@ -35,6 +38,9 @@ main();
function main() {
if (cluster.isMaster) {
masterMain();
+
+ ev.mount();
+ stats();
} else {
workerMain();
}
diff --git a/src/utils/stats.ts b/src/utils/stats.ts
new file mode 100644
index 0000000000..1615268310
--- /dev/null
+++ b/src/utils/stats.ts
@@ -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);
+}
diff --git a/src/web/app/common/scripts/home-stream.js b/src/web/app/common/scripts/home-stream.js
new file mode 100644
index 0000000000..24f13cd291
--- /dev/null
+++ b/src/web/app/common/scripts/home-stream.js
@@ -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;
diff --git a/src/web/app/common/scripts/messaging-stream.js b/src/web/app/common/scripts/messaging-stream.js
index 50d41c2be9..261525d5f6 100644
--- a/src/web/app/common/scripts/messaging-stream.js
+++ b/src/web/app/common/scripts/messaging-stream.js
@@ -1,42 +1,22 @@
-const ReconnectingWebSocket = require('reconnecting-websocket');
-import * as riot from 'riot';
-import CONFIG from './config';
+'use strict';
-class Connection {
- constructor(me, otherparty) {
- // BIND -----------------------------------
- this.onOpen = this.onOpen.bind(this);
- this.onMessage = this.onMessage.bind(this);
- this.close = this.close.bind(this);
- // ----------------------------------------
-
- this.event = riot.observable();
- this.me = me;
-
- 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);
- }
+import Stream from './stream';
- 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
- }
- }
+/**
+ * Messaging stream connection
+ */
+class Connection extends Stream {
+ constructor(me, otherparty) {
+ super('messaging', {
+ i: me.token,
+ otherparty
+ });
- close() {
- this.socket.removeEventListener('open', this.onOpen);
- this.socket.removeEventListener('message', this.onMessage);
+ this.on('_connected_', () => {
+ this.send({
+ i: me.token
+ });
+ });
}
}
diff --git a/src/web/app/common/scripts/server-stream.js b/src/web/app/common/scripts/server-stream.js
new file mode 100644
index 0000000000..a1c466b35d
--- /dev/null
+++ b/src/web/app/common/scripts/server-stream.js
@@ -0,0 +1,14 @@
+'use strict';
+
+import Stream from './stream';
+
+/**
+ * Server stream connection
+ */
+class Connection extends Stream {
+ constructor() {
+ super('server');
+ }
+}
+
+export default Connection;
diff --git a/src/web/app/common/scripts/stream.js b/src/web/app/common/scripts/stream.js
index ac3dd67153..981118b5de 100644
--- a/src/web/app/common/scripts/stream.js
+++ b/src/web/app/common/scripts/stream.js
@@ -5,10 +5,10 @@ import * as riot from 'riot';
import CONFIG from './config';
/**
- * Home stream connection
+ * Misskey stream connection
*/
class Connection {
- constructor(me) {
+ constructor(endpoint, params) {
// BIND -----------------------------------
this.onOpen = this.onOpen.bind(this);
this.onClose = this.onClose.bind(this);
@@ -20,16 +20,19 @@ class Connection {
riot.observable(this);
this.state = 'initializing';
- this.me = me;
this.buffer = [];
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('close', this.onClose);
this.socket.addEventListener('message', this.onMessage);
-
- this.on('i_updated', me.update);
}
/**
diff --git a/src/web/app/common/tags/messaging/room.tag b/src/web/app/common/tags/messaging/room.tag
index bd49a4d782..93f07f2cee 100644
--- a/src/web/app/common/tags/messaging/room.tag
+++ b/src/web/app/common/tags/messaging/room.tag
@@ -137,8 +137,8 @@
this.connection = new MessagingStreamConnection(this.I, this.user.id);
this.on('mount', () => {
- this.connection.event.on('message', this.onMessage);
- this.connection.event.on('read', this.onRead);
+ this.connection.on('message', this.onMessage);
+ this.connection.on('read', this.onRead);
document.addEventListener('visibilitychange', this.onVisibilitychange);
@@ -153,8 +153,8 @@
});
this.on('unmount', () => {
- this.connection.event.off('message', this.onMessage);
- this.connection.event.off('read', this.onRead);
+ this.connection.off('message', this.onMessage);
+ this.connection.off('read', this.onRead);
this.connection.close();
document.removeEventListener('visibilitychange', this.onVisibilitychange);
@@ -174,10 +174,10 @@
this.messages.push(message);
if (message.user_id != this.I.id && !document.hidden) {
- this.connection.socket.send(JSON.stringify({
+ this.connection.send({
type: 'read',
id: message.id
- }));
+ });
}
this.update();
@@ -239,10 +239,10 @@
if (document.hidden) return;
this.messages.forEach(message => {
if (message.user_id !== this.I.id && !message.is_read) {
- this.connection.socket.send(JSON.stringify({
+ this.connection.send({
type: 'read',
id: message.id
- }));
+ });
}
});
};
diff --git a/src/web/app/desktop/tags/home-widgets/activity.tag b/src/web/app/desktop/tags/home-widgets/activity.tag
index 621702fa17..3a8afdfa33 100644
--- a/src/web/app/desktop/tags/home-widgets/activity.tag
+++ b/src/web/app/desktop/tags/home-widgets/activity.tag
@@ -100,6 +100,8 @@
</svg>
<style>
:scope
+ display block
+
> svg
display block
padding 10px
@@ -131,7 +133,7 @@
</mk-activity-home-widget-calender>
<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
riot-points={ pointsPost }
fill="none"
@@ -155,6 +157,8 @@
</svg>
<style>
:scope
+ display block
+
> svg
display block
padding 10px
@@ -163,6 +167,7 @@
</style>
<script>
this.viewBoxX = 140;
+ this.viewBoxY = 60;
this.zoom = 1;
this.pos = 0;
@@ -176,10 +181,10 @@
this.render = () => {
this.update({
- pointsPost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * 60}`).join(' '),
- pointsReply: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * 60}`).join(' '),
- pointsRepost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * 60}`).join(' '),
- pointsTotal: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / 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)) * this.viewBoxY}`).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)) * this.viewBoxY}`).join(' ')
});
};
diff --git a/src/web/app/desktop/tags/home-widgets/server.tag b/src/web/app/desktop/tags/home-widgets/server.tag
new file mode 100644
index 0000000000..7a51299585
--- /dev/null
+++ b/src/web/app/desktop/tags/home-widgets/server.tag
@@ -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>
+
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index 0e4a2ced10..41053ccbbe 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -70,6 +70,7 @@
'rss-reader',
'trends',
'photo-stream',
+ 'server',
'version'
],
right: [
diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index 1e0ebd44cf..177ba41293 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -45,6 +45,7 @@ require('./home-widgets/version.tag');
require('./home-widgets/recommended-polls.tag');
require('./home-widgets/trends.tag');
require('./home-widgets/activity.tag');
+require('./home-widgets/server.tag');
require('./timeline.tag');
require('./messaging/window.tag');
require('./messaging/room-window.tag');
diff --git a/src/web/app/init.js b/src/web/app/init.js
index 17f9a2d09e..b442d36a15 100644
--- a/src/web/app/init.js
+++ b/src/web/app/init.js
@@ -8,7 +8,7 @@ import * as riot from 'riot';
import api from './common/scripts/api';
import signout from './common/scripts/signout';
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 generateDefaultUserdata from './common/scripts/generate-default-userdata';
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;
// ミックスイン初期化