wip
This commit is contained in:
@ -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
|
||||
|
@ -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 エンドポイント名
|
||||
|
@ -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}`;
|
||||
|
31
src/web/assets/sw.js
Normal file
31
src/web/assets/sw.js
Normal file
@ -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',
|
||||
});
|
||||
}
|
||||
};
|
@ -37,28 +37,45 @@ 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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user