This commit is contained in:
syuilo 2017-11-21 07:06:36 +09:00
parent cad1e0458f
commit 411c006d9f
2 changed files with 103 additions and 42 deletions

View file

@ -35,6 +35,13 @@ export default class MiOS extends EventEmitter {
return this.i != null; return this.i != null;
} }
/**
* Whether is debug mode
*/
public get debug() {
return localStorage.getItem('debug') == 'true';
}
/** /**
* A connection manager of home stream * A connection manager of home stream
*/ */
@ -49,13 +56,37 @@ export default class MiOS extends EventEmitter {
super(); super();
//#region BIND //#region BIND
this.log = this.log.bind(this);
this.logInfo = this.logInfo.bind(this);
this.logWarn = this.logWarn.bind(this);
this.logError = this.logError.bind(this);
this.init = this.init.bind(this); this.init = this.init.bind(this);
this.api = this.api.bind(this); this.api = this.api.bind(this);
this.getMeta = this.getMeta.bind(this); this.getMeta = this.getMeta.bind(this);
this.swSubscribe = this.swSubscribe.bind(this); this.registerSw = this.registerSw.bind(this);
//#endregion //#endregion
} }
public log(...args) {
if (!this.debug) return;
console.log.apply(null, args);
}
public logInfo(...args) {
if (!this.debug) return;
console.info.apply(null, args);
}
public logWarn(...args) {
if (!this.debug) return;
console.warn.apply(null, args);
}
public logError(...args) {
if (!this.debug) return;
console.error.apply(null, args);
}
/** /**
* Initialize MiOS (boot) * Initialize MiOS (boot)
* @param callback A function that call when initialized * @param callback A function that call when initialized
@ -136,30 +167,20 @@ export default class MiOS extends EventEmitter {
// Finish init // Finish init
callback(); callback();
//#region Service worker //#region Post
const isSwSupported =
('serviceWorker' in navigator) && ('PushManager' in window);
if (isSwSupported && this.isSignedin) { // Init service worker
// When service worker activated this.registerSw();
navigator.serviceWorker.ready.then(this.swSubscribe);
// Register service worker
navigator.serviceWorker.register(`/sw.${VERSION}.${LANG}.js`).then(registration => {
// 登録成功
console.info('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(err => {
// 登録失敗 :(
console.error('ServiceWorker registration failed: ', err);
});
}
//#endregion //#endregion
}; };
// Get cached account data // Get cached account data
const cachedMe = JSON.parse(localStorage.getItem('me')); const cachedMe = JSON.parse(localStorage.getItem('me'));
// キャッシュがあったとき
if (cachedMe) { if (cachedMe) {
// とりあえずキャッシュされたデータでお茶を濁して(?)おいて、
fetched(cachedMe); fetched(cachedMe);
// 後から新鮮なデータをフェッチ // 後から新鮮なデータをフェッチ
@ -175,27 +196,64 @@ export default class MiOS extends EventEmitter {
} }
} }
private async swSubscribe(swRegistration: ServiceWorkerRegistration) { /**
this.swRegistration = swRegistration; * Register service worker
*/
private registerSw() {
// Check whether service worker and push manager supported
const isSwSupported =
('serviceWorker' in navigator) && ('PushManager' in window);
// Subscribe // Reject when browser not service worker supported
this.swRegistration.pushManager.subscribe({ if (!isSwSupported) return;
// Reject when not signed in to Misskey
if (!this.isSignedin) return;
// When service worker activated
navigator.serviceWorker.ready.then(registration => {
this.log('[sw] ready: ', registration);
this.swRegistration = registration;
// Options of pushManager.subscribe
const opts = {
// A boolean indicating that the returned push subscription // A boolean indicating that the returned push subscription
// will only be used for messages whose effect is made visible to the user. // will only be used for messages whose effect is made visible to the user.
userVisibleOnly: true userVisibleOnly: true
}).then(subscription => { };
console.log('Subscribe OK:', subscription);
// Subscribe push notification
this.swRegistration.pushManager.subscribe(opts).then(subscription => {
this.log('[sw] Subscribe OK:', subscription);
function encode(buffer: ArrayBuffer) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
}
// Register // Register
this.api('sw/register', { this.api('sw/register', {
endpoint: subscription.endpoint, endpoint: subscription.endpoint,
auth: btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('auth')))), auth: encode(subscription.getKey('auth')),
publickey: btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('p256dh')))) publickey: encode(subscription.getKey('p256dh'))
}); });
}).then(() => { }).then(() => {
console.log('Server Stored Subscription.'); this.logInfo('[sw] Server Stored Subscription.');
}).catch(err => { }).catch(err => {
console.error('Subscribe Error:', err); this.logError('[sw] Subscribe Error:', err);
});
});
// The path of service worker script
const sw = `/sw.${VERSION}.${LANG}.js`;
// Register service worker
navigator.serviceWorker.register(sw).then(registration => {
// 登録成功
this.logInfo('[sw] Registration successful with scope: ', registration.scope);
}).catch(err => {
// 登録失敗 :(
this.logError('[sw] Registration failed: ', err);
}); });
} }

View file

@ -6,25 +6,28 @@ import composeNotification from './common/scripts/compose-notification';
// インストールされたとき // インストールされたとき
self.addEventListener('install', () => { self.addEventListener('install', () => {
console.log('[sw]', 'Your ServiceWorker is installed'); console.info('installed');
}); });
// プッシュ通知を受け取ったとき // プッシュ通知を受け取ったとき
self.addEventListener('push', ev => { self.addEventListener('push', ev => {
console.log('pushed');
// クライアント取得 // クライアント取得
self.clients.matchAll({ ev.waitUntil(self.clients.matchAll({
includeUncontrolled: true includeUncontrolled: true
}).then(clients => { }).then(clients => {
// クライアントがあったらストリームに接続しているということなので通知しない // クライアントがあったらストリームに接続しているということなので通知しない
if (clients.length != 0) return; if (clients.length != 0) return;
const { type, body } = ev.data.json(); const { type, body } = ev.data.json();
console.log(type, body);
const n = composeNotification(type, body); const n = composeNotification(type, body);
if (n) { return self.registration.showNotification(n.title, {
self.registration.showNotification(n.title, {
body: n.body, body: n.body,
icon: n.icon, icon: n.icon,
}); });
} }));
});
}); });