summaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
Diffstat (limited to 'src/web')
-rw-r--r--src/web/about/assets/style.css208
-rw-r--r--src/web/about/index.ts18
-rw-r--r--src/web/app/auth/script.js6
-rw-r--r--src/web/app/auth/view.pug5
-rw-r--r--src/web/app/base.pug6
-rw-r--r--src/web/app/boot.js197
-rw-r--r--src/web/app/client/script.js29
-rw-r--r--src/web/app/client/view.pug5
-rw-r--r--src/web/app/desktop/script.js6
-rw-r--r--src/web/app/dev/script.js6
-rw-r--r--src/web/app/dev/view.pug4
-rw-r--r--src/web/app/init.js186
-rw-r--r--src/web/app/mobile/script.js6
-rw-r--r--src/web/serve-app.ts9
-rw-r--r--src/web/server.ts20
15 files changed, 232 insertions, 479 deletions
diff --git a/src/web/about/assets/style.css b/src/web/about/assets/style.css
deleted file mode 100644
index 028bffa525..0000000000
--- a/src/web/about/assets/style.css
+++ /dev/null
@@ -1,208 +0,0 @@
-html {
- font-family: sans-serif;
-}
-
-body {
- margin: 0;
- color: #34495e;
-}
-
-nav {
- display: block;
- float: left;
- width: 210px;
-}
-nav ul {
- display: block;
- margin: 0 0 16px 0;
- padding: 0 0 0 16px;
- list-style: none;
-}
-nav ul li {
- margin: 0;
- padding: 0;
-}
-nav ul li p {
- margin: 16px 0 0 0;
-}
-@media screen and (max-width: 910px) {
- nav {
- display: none;
- }
-}
-
-main {
- float: left;
- box-sizing: border-box;
- padding: 32px;
- width: 100%;
- max-width: 700px;
- overflow-wrap: break-word;
-}
-@media screen and (max-width: 700px) {
- main {
- font-size: 8px;
- }
-}
-
-footer {
- padding: 32px 0 0 0;
- margin: 32px 0 0 0;
- border-top: solid 1px #eee;
-}
-
-footer .contribution {
- margin: 0 0 16px 0;
-}
-
-footer .copyright {
- margin: 16px 0 0 0;
- color: #aaa;
-}
-
-a {
- text-decoration: none;
- color: #f76d6c;
-}
- a:hover {
- text-decoration: underline;
- }
-
-hr {
- border-top: solid 1px #eee;
-}
-
-section {
- margin: 32px 0;
-}
-
-h1 {
- margin: 0 0 24px 0;
- padding: 16px 0;
- font-size: 1.5em;
- border-bottom: solid 2px #eee;
-}
-
-h2 {
- margin: 0 0 24px 0;
- padding: 0 0 16px 0;
- font-size: 1.4em;
- border-bottom: solid 1px #eee;
-}
-
-h3 {
- margin: 0;
- padding: 0;
- font-size: 1.25em;
-}
-
-h4 {
- margin: 0;
-}
-
-p {
- margin: 1em 0;
- line-height: 1.6em;
-}
-
-p.tip {
- position: relative;
- padding: 12px 24px 12px 30px;
- margin: 1em 0;
- font-size: 0.9em;
- border-left: 4px solid #f66;
- background-color: #f8f8f8;
- border-bottom-right-radius: 2px;
- border-top-right-radius: 2px;
-}
- p.tip:before {
- position: absolute;
- top: 14px;
- left: -12px;
- background-color: #f66;
- color: #fff;
- content: "!";
- width: 20px;
- height: 20px;
- border-radius: 100%;
- text-align: center;
- line-height: 20px;
- font-weight: bold;
- font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
- font-size: 14px;
- }
-
-hr {
- margin: 1em 0;
-}
-
-table {
- width: 100%;
- border-spacing: 0;
- border-collapse: collapse;
-}
-
-table thead {
- font-weight: bold;
- border-bottom: solid 2px #eee;
-}
-
-table tbody tr {
- border-bottom: dashed 1px #eee;
-}
-
-table th, table td {
- padding: 8px 16px;
-}
-
-table.entity tbody tr td:nth-child(1) {
- font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
-}
-
-table.entity tbody tr td:nth-child(2) {
- font-style: italic;
-}
-
-table.entity tr td:nth-child(3):after {
- margin-left: 8px;
- opacity: 0.7;
-}
-
-table.entity tr.nullable td:nth-child(2):after {
- content: "?";
- opacity: 0.7;
-}
-table.entity tr.nullable td:nth-child(3):after {
- content: "(Null許容)";
-}
-
-table.entity tr.optional {
- opacity: 0.7;
-}
-table.entity tr.optional td:nth-child(3):after {
- content: "(省略可能)";
-}
-
-table.entity tr.nullable.optional td:nth-child(3):after {
- content: "(Null許容かつ省略可能)";
-}
-
-pre, code, var, samp, kbd {
- font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
-}
-
-code {
- display: inline-block;
- margin: 0 4px;
- padding: 0 8px;
- color: #525252;
- background: #f8f8f8;
- border-radius: 2px;
-}
-
-pre code {
- display: block;
- overflow: auto;
- margin: 0;
- padding: 32px;
-}
diff --git a/src/web/about/index.ts b/src/web/about/index.ts
deleted file mode 100644
index 9fedeb6273..0000000000
--- a/src/web/about/index.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as express from 'express';
-import ms = require('ms');
-
-const router = express.Router();
-
-router.use('/@/about/assets', express.static(`${__dirname}/assets`, {
- maxAge: ms('7 days')
-}));
-
-router.get('/@/about/', (req, res) => {
- res.sendFile(`${__dirname}/pages/index.html`);
-});
-
-router.get('/@/about/:page(*)', (req, res) => {
- res.sendFile(`${__dirname}/pages/${req.params.page}.html`);
-});
-
-module.exports = router;
diff --git a/src/web/app/auth/script.js b/src/web/app/auth/script.js
index 19391b2b9e..fe7f9befe8 100644
--- a/src/web/app/auth/script.js
+++ b/src/web/app/auth/script.js
@@ -7,14 +7,14 @@ import './style.styl';
import * as riot from 'riot';
require('./tags');
-import boot from '../boot';
+import init from '../init';
document.title = 'Misskey | アプリの連携';
/**
- * Boot
+ * init
*/
-boot(me => {
+init(me => {
mount(document.createElement('mk-index'));
});
diff --git a/src/web/app/auth/view.pug b/src/web/app/auth/view.pug
deleted file mode 100644
index afa1e408f8..0000000000
--- a/src/web/app/auth/view.pug
+++ /dev/null
@@ -1,5 +0,0 @@
-extends ../base
-
-block head
- meta(name='viewport' content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no')
- script(src=`/assets/auth.${version}.ja.js` async defer)
diff --git a/src/web/app/base.pug b/src/web/app/base.pug
index 912157a2e8..fd57f55931 100644
--- a/src/web/app/base.pug
+++ b/src/web/app/base.pug
@@ -9,11 +9,15 @@ html
meta(name='application-name' content='Misskey')
meta(name='theme-color' content=themeColor)
meta(name='referrer' content='origin')
+
title Misskey
+
style
include ./../../../built/web/assets/init.css
+ script
+ include ./../../../built/web/assets/boot.js
+
script(src='https://use.fontawesome.com/22aba0df4f.js' async)
- block head
body
noscript: p
diff --git a/src/web/app/boot.js b/src/web/app/boot.js
index 242df13c77..4df44ed793 100644
--- a/src/web/app/boot.js
+++ b/src/web/app/boot.js
@@ -1,186 +1,35 @@
/**
- * boot loader
+ * MISSKEY ENTRY POINT
*/
-"use strict";
+const Url = new URL(location.href);
-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 mixin from './common/mixins';
-import generateDefaultUserdata from './common/scripts/generate-default-userdata';
-import CONFIG from './common/scripts/config';
-require('./common/tags');
+let app = Url.host.split('.')[0];
-/**
- * MISSKEY ENTRY POINT!
- */
-
-console.info(`Misskey v${VERSION}`);
-
-document.domain = CONFIG.host;
+// Detect user language
+let lang = navigator.language.split('-')[0];
+if (!/^(en|ja)$/.test(lang)) lang = 'en';
-// Set global configuration
-riot.mixin({ CONFIG });
-
-// ↓ NodeList、HTMLCollection、FileList、DataTransferItemListで forEach を使えるようにする
-if (NodeList.prototype.forEach === undefined) {
- NodeList.prototype.forEach = Array.prototype.forEach;
-}
-if (HTMLCollection.prototype.forEach === undefined) {
- HTMLCollection.prototype.forEach = Array.prototype.forEach;
-}
-if (FileList.prototype.forEach === undefined) {
- FileList.prototype.forEach = Array.prototype.forEach;
-}
-if (window.DataTransferItemList && DataTransferItemList.prototype.forEach === undefined) {
- DataTransferItemList.prototype.forEach = Array.prototype.forEach;
-}
+// Detect user agent
+const ua = navigator.userAgent.toLowerCase();
+const isMobile = /mobile|iphone|ipad|android/.test(ua);
-// iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
-try {
- localStorage.setItem('kyoppie', 'yuppie');
-} catch (e) {
- Storage.prototype.setItem = () => { }; // noop
-}
+const head = document.getElementsByTagName('head')[0];
-// クライアントを更新すべきならする
-if (localStorage.getItem('should-refresh') == 'true') {
- localStorage.removeItem('should-refresh');
- location.reload(true);
+if (isMobile) {
+ const meta = document.createElement('meta');
+ meta.setAttribute('name', 'viewport');
+ meta.setAttribute('content', 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no');
+ head.appendChild(meta);
}
-// 更新チェック
-setTimeout(checkForUpdate, 3000);
-
-// ユーザーをフェッチしてコールバックする
-export default callback => {
- // Get cached account data
- let cachedMe = JSON.parse(localStorage.getItem('me'));
-
- if (cachedMe) {
- fetched(cachedMe);
-
- // 後から新鮮なデータをフェッチ
- fetchme(cachedMe.token, freshData => {
- Object.assign(cachedMe, freshData);
- cachedMe.trigger('updated');
- });
- } else {
- // Get token from cookie
- const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];
-
- fetchme(i, fetched);
- }
-
- // フェッチが完了したとき
- function fetched(me) {
- if (me) {
- riot.observable(me);
-
- // この me オブジェクトを更新するメソッド
- me.update = data => {
- if (data) Object.assign(me, data);
- me.trigger('updated');
- };
-
- // ローカルストレージにキャッシュ
- localStorage.setItem('me', JSON.stringify(me));
-
- me.on('updated', () => {
- // キャッシュ更新
- localStorage.setItem('me', JSON.stringify(me));
- });
- }
-
- // ミックスイン初期化
- mixin(me);
-
- // ローディング画面クリア
- const ini = document.getElementById('ini');
- ini.parentNode.removeChild(ini);
-
- // アプリ基底要素マウント
- const app = document.createElement('div');
- app.setAttribute('id', 'app');
- document.body.appendChild(app);
-
- try {
- callback(me);
- } catch (e) {
- panic(e);
- }
- }
-};
-
-// ユーザーをフェッチしてコールバックする
-function fetchme(token, cb) {
- let me = null;
-
- // Return when not signed in
- if (token == null) {
- return done();
- }
-
- // Fetch user
- fetch(`${CONFIG.apiUrl}/i`, {
- method: 'POST',
- body: JSON.stringify({
- i: token
- })
- }).then(res => { // When success
- // When failed to authenticate user
- if (res.status !== 200) {
- return signout();
- }
-
- res.json().then(i => {
- me = i;
- me.token = token;
-
- // initialize it if user data is empty
- me.data ? done() : init();
- });
- }, () => { // When failure
- // Display error screen
- riot.mount(document.body.appendChild(
- document.createElement('mk-error')));
- });
-
- function done() {
- if (cb) cb(me);
- }
-
- // Initialize user data
- function init() {
- const data = generateDefaultUserdata();
- api(token, 'i/appdata/set', {
- data
- }).then(() => {
- me.data = data;
- done();
- });
- }
+if (app == 'misskey') {
+ app = isMobile ? 'mobile' : 'desktop';
}
-// BSoD
-function panic(e) {
- console.error(e);
-
- // Display blue screen
- document.body.innerHTML =
- `<div id="error">
- <h1>:( 致命的な問題が発生しました。</h1>
- <p>お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。</p>
- <hr>
- <p>エラーコード: ${e.toString()}</p>
- <p>ブラウザ バージョン: ${navigator.userAgent}</p>
- <p>クライアント バージョン: ${VERSION}</p>
- <hr>
- <p>問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。</p>
- <p>Thank you for using Misskey.</p>
- </div>`;
-
- // TODO: Report the bug
-}
+// Load app script
+const script = document.createElement('script');
+script.setAttribute('src', `/assets/${app}.${VERSION}.${lang}.js`);
+script.setAttribute('async', 'true');
+script.setAttribute('defer', 'true');
+head.appendChild(script);
diff --git a/src/web/app/client/script.js b/src/web/app/client/script.js
deleted file mode 100644
index 465d3edb38..0000000000
--- a/src/web/app/client/script.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * MISSKEY CLIENT ENTRY POINT
- */
-
-const head = document.getElementsByTagName('head')[0];
-
-// Detect user language
-let lang = navigator.language.split('-')[0];
-if (!/^(en|ja)$/.test(lang)) lang = 'en';
-
-// Detect user agent
-const ua = navigator.userAgent.toLowerCase();
-const isMobile = /mobile|iphone|ipad|android/.test(ua);
-
-const app = isMobile ? 'mobile' : 'desktop';
-
-// Load app script
-const script = document.createElement('script');
-script.setAttribute('src', `/assets/${app}.${VERSION}.${lang}.js`);
-script.setAttribute('async', 'true');
-script.setAttribute('defer', 'true');
-head.appendChild(script);
-
-if (isMobile) {
- const meta = document.createElement('meta');
- meta.setAttribute('name', 'viewport');
- meta.setAttribute('content', 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no');
- head.appendChild(meta);
-}
diff --git a/src/web/app/client/view.pug b/src/web/app/client/view.pug
deleted file mode 100644
index 3441631cd7..0000000000
--- a/src/web/app/client/view.pug
+++ /dev/null
@@ -1,5 +0,0 @@
-extends ../base
-
-block head
- script
- include ./../../../../built/web/assets/client/script.js
diff --git a/src/web/app/desktop/script.js b/src/web/app/desktop/script.js
index af986b53bd..b3691f7ff2 100644
--- a/src/web/app/desktop/script.js
+++ b/src/web/app/desktop/script.js
@@ -8,14 +8,14 @@ import './style.styl';
require('./tags');
require('./mixins');
import * as riot from 'riot';
-import boot from '../boot';
+import init from '../init';
import route from './router';
import fuckAdBlock from './scripts/fuck-ad-block';
/**
- * Boot
+ * init
*/
-boot(me => {
+init(me => {
/**
* Fuck AD Block
*/
diff --git a/src/web/app/dev/script.js b/src/web/app/dev/script.js
index 38e864af0b..32f0285e17 100644
--- a/src/web/app/dev/script.js
+++ b/src/web/app/dev/script.js
@@ -6,13 +6,13 @@
import './style.styl';
require('./tags');
-import boot from '../boot';
+import init from '../init';
const route = require('./router');
/**
- * Boot
+ * init
*/
-boot(me => {
+init(me => {
// Start routing
route(me);
});
diff --git a/src/web/app/dev/view.pug b/src/web/app/dev/view.pug
deleted file mode 100644
index 1a9a0e5bbd..0000000000
--- a/src/web/app/dev/view.pug
+++ /dev/null
@@ -1,4 +0,0 @@
-extends ../base
-
-block head
- script(src=`/assets/dev.${version}.js` async defer)
diff --git a/src/web/app/init.js b/src/web/app/init.js
new file mode 100644
index 0000000000..e480b2b774
--- /dev/null
+++ b/src/web/app/init.js
@@ -0,0 +1,186 @@
+/**
+ * App initializer
+ */
+
+"use strict";
+
+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 mixin from './common/mixins';
+import generateDefaultUserdata from './common/scripts/generate-default-userdata';
+import CONFIG from './common/scripts/config';
+require('./common/tags');
+
+/**
+ * APP ENTRY POINT!
+ */
+
+console.info(`Misskey v${VERSION}`);
+
+document.domain = CONFIG.host;
+
+// Set global configuration
+riot.mixin({ CONFIG });
+
+// ↓ NodeList、HTMLCollection、FileList、DataTransferItemListで forEach を使えるようにする
+if (NodeList.prototype.forEach === undefined) {
+ NodeList.prototype.forEach = Array.prototype.forEach;
+}
+if (HTMLCollection.prototype.forEach === undefined) {
+ HTMLCollection.prototype.forEach = Array.prototype.forEach;
+}
+if (FileList.prototype.forEach === undefined) {
+ FileList.prototype.forEach = Array.prototype.forEach;
+}
+if (window.DataTransferItemList && DataTransferItemList.prototype.forEach === undefined) {
+ DataTransferItemList.prototype.forEach = Array.prototype.forEach;
+}
+
+// iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
+try {
+ localStorage.setItem('kyoppie', 'yuppie');
+} catch (e) {
+ Storage.prototype.setItem = () => { }; // noop
+}
+
+// クライアントを更新すべきならする
+if (localStorage.getItem('should-refresh') == 'true') {
+ localStorage.removeItem('should-refresh');
+ location.reload(true);
+}
+
+// 更新チェック
+setTimeout(checkForUpdate, 3000);
+
+// ユーザーをフェッチしてコールバックする
+export default callback => {
+ // Get cached account data
+ let cachedMe = JSON.parse(localStorage.getItem('me'));
+
+ if (cachedMe) {
+ fetched(cachedMe);
+
+ // 後から新鮮なデータをフェッチ
+ fetchme(cachedMe.token, freshData => {
+ Object.assign(cachedMe, freshData);
+ cachedMe.trigger('updated');
+ });
+ } else {
+ // Get token from cookie
+ const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];
+
+ fetchme(i, fetched);
+ }
+
+ // フェッチが完了したとき
+ function fetched(me) {
+ if (me) {
+ riot.observable(me);
+
+ // この me オブジェクトを更新するメソッド
+ me.update = data => {
+ if (data) Object.assign(me, data);
+ me.trigger('updated');
+ };
+
+ // ローカルストレージにキャッシュ
+ localStorage.setItem('me', JSON.stringify(me));
+
+ me.on('updated', () => {
+ // キャッシュ更新
+ localStorage.setItem('me', JSON.stringify(me));
+ });
+ }
+
+ // ミックスイン初期化
+ mixin(me);
+
+ // ローディング画面クリア
+ const ini = document.getElementById('ini');
+ ini.parentNode.removeChild(ini);
+
+ // アプリ基底要素マウント
+ const app = document.createElement('div');
+ app.setAttribute('id', 'app');
+ document.body.appendChild(app);
+
+ try {
+ callback(me);
+ } catch (e) {
+ panic(e);
+ }
+ }
+};
+
+// ユーザーをフェッチしてコールバックする
+function fetchme(token, cb) {
+ let me = null;
+
+ // Return when not signed in
+ if (token == null) {
+ return done();
+ }
+
+ // Fetch user
+ fetch(`${CONFIG.apiUrl}/i`, {
+ method: 'POST',
+ body: JSON.stringify({
+ i: token
+ })
+ }).then(res => { // When success
+ // When failed to authenticate user
+ if (res.status !== 200) {
+ return signout();
+ }
+
+ res.json().then(i => {
+ me = i;
+ me.token = token;
+
+ // initialize it if user data is empty
+ me.data ? done() : init();
+ });
+ }, () => { // When failure
+ // Display error screen
+ riot.mount(document.body.appendChild(
+ document.createElement('mk-error')));
+ });
+
+ function done() {
+ if (cb) cb(me);
+ }
+
+ // Initialize user data
+ function init() {
+ const data = generateDefaultUserdata();
+ api(token, 'i/appdata/set', {
+ data
+ }).then(() => {
+ me.data = data;
+ done();
+ });
+ }
+}
+
+// BSoD
+function panic(e) {
+ console.error(e);
+
+ // Display blue screen
+ document.body.innerHTML =
+ `<div id="error">
+ <h1>:( 致命的な問題が発生しました。</h1>
+ <p>お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。</p>
+ <hr>
+ <p>エラーコード: ${e.toString()}</p>
+ <p>ブラウザ バージョン: ${navigator.userAgent}</p>
+ <p>クライアント バージョン: ${VERSION}</p>
+ <hr>
+ <p>問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。</p>
+ <p>Thank you for using Misskey.</p>
+ </div>`;
+
+ // TODO: Report the bug
+}
diff --git a/src/web/app/mobile/script.js b/src/web/app/mobile/script.js
index 22150f46ad..503e0fd673 100644
--- a/src/web/app/mobile/script.js
+++ b/src/web/app/mobile/script.js
@@ -6,13 +6,13 @@
import './style.styl';
require('./tags');
-import boot from '../boot';
+import init from '../init';
import route from './router';
/**
- * Boot
+ * init
*/
-boot(me => {
+init(me => {
// http://qiita.com/junya/items/3ff380878f26ca447f85
document.body.setAttribute('ontouchstart', '');
diff --git a/src/web/serve-app.ts b/src/web/serve-app.ts
deleted file mode 100644
index a298d593aa..0000000000
--- a/src/web/serve-app.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as path from 'path';
-import * as express from 'express';
-import ms = require('ms');
-
-export default (name: string) => (req: express.Request, res: express.Response) => {
- res.sendFile(path.resolve(`${__dirname}/app/${name}/view.html`), {
- maxAge: ms('7 days')
- });
-};
diff --git a/src/web/server.ts b/src/web/server.ts
index 17e455b172..d701d83b28 100644
--- a/src/web/server.ts
+++ b/src/web/server.ts
@@ -2,6 +2,7 @@
* Web Server
*/
+import * as path from 'path';
import ms = require('ms');
// express modules
@@ -9,8 +10,6 @@ import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as favicon from 'serve-favicon';
import * as compression from 'compression';
-const subdomain = require('subdomain');
-import serveApp from './serve-app';
import config from '../conf';
@@ -62,19 +61,12 @@ app.get('/config.json', (req, res) => {
});
/**
- * Subdomain
- */
-app.use(subdomain({
- base: config.host,
- prefix: '@'
-}));
-
-/**
* Routing
*/
-app.use(require('./about')); // about docs
-app.get('/@/auth/*', serveApp('auth')); // authorize form
-app.get('/@/dev/*', serveApp('dev')); // developer center
-app.get('*', serveApp('client')); // client
+app.get('*', (req, res) => {
+ res.sendFile(path.resolve(`${__dirname}/app/base.html`), {
+ maxAge: ms('7 days')
+ });
+});
module.exports = app;