summaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
Diffstat (limited to 'src/web')
-rw-r--r--src/web/app/boot.js4
-rw-r--r--src/web/app/common/mios.ts49
-rw-r--r--src/web/app/common/scripts/config.ts10
-rw-r--r--src/web/assets/sw.js31
-rw-r--r--src/web/server.ts27
5 files changed, 111 insertions, 10 deletions
diff --git a/src/web/app/boot.js b/src/web/app/boot.js
index ac6c18d649..4a8ea030a1 100644
--- a/src/web/app/boot.js
+++ b/src/web/app/boot.js
@@ -27,7 +27,9 @@
// misskey.alice => misskey
// misskey.strawberry.pasta => misskey
// dev.misskey.arisu.tachibana => dev
- let app = url.host.split('.')[0];
+ let app = url.host == 'localhost'
+ ? 'misskey'
+ : url.host.split('.')[0];
// Detect the user language
// Note: The default language is English
diff --git a/src/web/app/common/mios.ts b/src/web/app/common/mios.ts
index 9704e92af8..4a36d6375f 100644
--- a/src/web/app/common/mios.ts
+++ b/src/web/app/common/mios.ts
@@ -37,6 +37,11 @@ export default class MiOS extends EventEmitter {
*/
public stream: HomeStreamManager;
+ /**
+ * A registration of service worker
+ */
+ private swRegistration: ServiceWorkerRegistration = null;
+
constructor() {
super();
@@ -44,6 +49,7 @@ export default class MiOS extends EventEmitter {
this.init = this.init.bind(this);
this.api = this.api.bind(this);
this.getMeta = this.getMeta.bind(this);
+ this.swSubscribe = this.swSubscribe.bind(this);
//#endregion
}
@@ -126,6 +132,25 @@ export default class MiOS extends EventEmitter {
// Finish init
callback();
+
+ //#region Service worker
+ const isSwSupported =
+ ('serviceWorker' in navigator) && ('PushManager' in window);
+
+ if (isSwSupported && this.isSignedin) {
+ // When service worker activated
+ navigator.serviceWorker.ready.then(this.swSubscribe);
+
+ // Register service worker
+ navigator.serviceWorker.register('/sw.js').then(registration => {
+ // 登録成功
+ console.info('ServiceWorker registration successful with scope: ', registration.scope);
+ }).catch(err => {
+ // 登録失敗 :(
+ console.error('ServiceWorker registration failed: ', err);
+ });
+ }
+ //#endregion
};
// Get cached account data
@@ -147,6 +172,30 @@ export default class MiOS extends EventEmitter {
}
}
+ private async swSubscribe(swRegistration: ServiceWorkerRegistration) {
+ this.swRegistration = swRegistration;
+
+ // Subscribe
+ this.swRegistration.pushManager.subscribe({
+ // A boolean indicating that the returned push subscription
+ // will only be used for messages whose effect is made visible to the user.
+ userVisibleOnly: true
+ }).then(subscription => {
+ console.log('Subscribe OK:', subscription);
+
+ // Register
+ this.api('sw/register', {
+ endpoint: subscription.endpoint,
+ auth: subscription.getKey('auth') ? btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('auth')))) : '',
+ publickey: subscription.getKey('p256dh') ? btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('p256dh')))) : ''
+ });
+ }).then(() => {
+ console.log('Server Stored Subscription.');
+ }).catch(err => {
+ console.error('Subscribe Error:', err);
+ });
+ }
+
/**
* Misskey APIにリクエストします
* @param endpoint エンドポイント名
diff --git a/src/web/app/common/scripts/config.ts b/src/web/app/common/scripts/config.ts
index c5015622f0..b4801a44de 100644
--- a/src/web/app/common/scripts/config.ts
+++ b/src/web/app/common/scripts/config.ts
@@ -1,9 +1,11 @@
-const Url = new URL(location.href);
+const _url = new URL(location.href);
-const isRoot = Url.host.split('.')[0] == 'misskey';
+const isRoot = _url.host == 'localhost'
+ ? true
+ : _url.host.split('.')[0] == 'misskey';
-const host = isRoot ? Url.host : Url.host.substring(Url.host.indexOf('.') + 1, Url.host.length);
-const scheme = Url.protocol;
+const host = isRoot ? _url.host : _url.host.substring(_url.host.indexOf('.') + 1, _url.host.length);
+const scheme = _url.protocol;
const url = `${scheme}//${host}`;
const apiUrl = `${scheme}//api.${host}`;
const chUrl = `${scheme}//ch.${host}`;
diff --git a/src/web/assets/sw.js b/src/web/assets/sw.js
new file mode 100644
index 0000000000..6a1251614a
--- /dev/null
+++ b/src/web/assets/sw.js
@@ -0,0 +1,31 @@
+/**
+ * Service Worker
+ */
+
+// インストールされたとき
+self.addEventListener('install', () => {
+ console.log('[sw]', 'Your ServiceWorker is installed');
+});
+
+// プッシュ通知を受け取ったとき
+self.addEventListener('push', ev => {
+ // クライアント取得
+ self.clients.matchAll({
+ includeUncontrolled: true
+ }).then(clients => {
+ // クライアントがあったらストリームに接続しているということなので通知しない
+ if (clients.length != 0) return;
+
+ const { type, body } = ev.data.json();
+ handlers[type](body);
+ });
+});
+
+const handlers = {
+ mention: body => {
+ self.registration.showNotification('mentioned', {
+ body: body.text,
+ icon: body.user.avatar_url + '?thumbnail&size=64',
+ });
+ }
+};
diff --git a/src/web/server.ts b/src/web/server.ts
index dde4eca5ec..300f3ed477 100644
--- a/src/web/server.ts
+++ b/src/web/server.ts
@@ -37,29 +37,46 @@ app.use((req, res, next) => {
* Static assets
*/
app.use(favicon(`${__dirname}/assets/favicon.ico`));
-app.get('/manifest.json', (req, res) => res.sendFile(`${__dirname}/assets/manifest.json`));
app.get('/apple-touch-icon.png', (req, res) => res.sendFile(`${__dirname}/assets/apple-touch-icon.png`));
app.use('/assets', express.static(`${__dirname}/assets`, {
maxAge: ms('7 days')
}));
+app.get('/sw.js', (req, res) => res.sendFile(`${__dirname}/assets/sw.js`));
+
/**
- * Common API
+ * Manifest
*/
-app.get(/\/api:url/, require('./service/url-preview'));
+app.get('/manifest.json', (req, res) => {
+ const manifest = require((`${__dirname}/assets/manifest.json`));
+
+ // Service Worker
+ if (config.sw) {
+ manifest['gcm_sender_id'] = config.sw.gcm_sender_id;
+ }
+
+ res.send(manifest);
+});
/**
* Serve config
*/
app.get('/config.json', (req, res) => {
- res.send({
+ const conf = {
recaptcha: {
siteKey: config.recaptcha.siteKey
}
- });
+ };
+
+ res.send(conf);
});
/**
+ * Common API
+ */
+app.get(/\/api:url/, require('./service/url-preview'));
+
+/**
* Routing
*/
app.get('*', (req, res) => {