This commit is contained in:
tamaina 2021-02-17 02:20:45 +09:00
parent 2dc4f24f18
commit c0e9cc1902
6 changed files with 97 additions and 53 deletions

View file

@ -1568,6 +1568,8 @@ _notification:
youReceivedFollowRequest: "フォローリクエストが来ました" youReceivedFollowRequest: "フォローリクエストが来ました"
yourFollowRequestAccepted: "フォローリクエストが承認されました" yourFollowRequestAccepted: "フォローリクエストが承認されました"
youWereInvitedToGroup: "{userName}があなたをグループに招待しました" youWereInvitedToGroup: "{userName}があなたをグループに招待しました"
readAllNotifications: "通知はすべて既読です"
readAllMessagingMessages: "チャットはすべて既読です"
_types: _types:
all: "すべて" all: "すべて"

View file

@ -56,7 +56,7 @@ import { router } from '@/router';
import { applyTheme } from '@/scripts/theme'; import { applyTheme } from '@/scripts/theme';
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode'; import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { api, stream, isMobile, dialog, post } from '@/os'; import { stream, isMobile, dialog, post } from '@/os';
import * as sound from '@/scripts/sound'; import * as sound from '@/scripts/sound';
import { $i, refreshAccount, login, updateAccount, signout } from '@/account'; import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
import { defaultStore, ColdDeviceStorage } from '@/store'; import { defaultStore, ColdDeviceStorage } from '@/store';
@ -68,7 +68,6 @@ import { initializeSw } from '@/scripts/initialize-sw';
import { reloadChannel } from '@/scripts/unison-reload'; import { reloadChannel } from '@/scripts/unison-reload';
import { deleteLoginId } from '@/scripts/login-id'; import { deleteLoginId } from '@/scripts/login-id';
import { getAccountFromId } from '@/scripts/get-account-from-id'; import { getAccountFromId } from '@/scripts/get-account-from-id';
import { SwMessage } from '@/sw/types';
console.info(`Misskey v${version}`); console.info(`Misskey v${version}`);
@ -240,33 +239,6 @@ components(app);
await router.isReady(); await router.isReady();
//#region Listen message from SW
navigator.serviceWorker.addEventListener('message', ev => {
if (_DEV_) {
console.log('sw msg', ev.data);
}
const data = ev.data as SwMessage;
if (data.type !== 'order') return;
if (data.loginId !== $i?.id) {
return getAccountFromId(data.loginId).then(account => {
if (!account) return;
return login(account.token, data.url);
});
}
switch (data.order) {
case 'post':
return post(data.options);
case 'push':
return router.push(data.url);
default:
return;
}
});
//#endregion
//document.body.innerHTML = '<div id="app"></div>'; //document.body.innerHTML = '<div id="app"></div>';
app.mount('body'); app.mount('body');
@ -415,22 +387,3 @@ if ($i) {
signout(); signout();
}); });
} }
/**
* Convert the URL safe base64 string to a Uint8Array
* @param base64String base64 string
*/
function urlBase64ToUint8Array(base64String: string): Uint8Array {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}

View file

@ -169,14 +169,42 @@ async function composeNotification(data: pushNotificationData): Promise<[string,
icon: body.user.avatarUrl, icon: body.user.avatarUrl,
tag: `messaging:user:${body.userId}`, tag: `messaging:user:${body.userId}`,
data, data,
renotify: true,
}]; }];
} }
return [t('_notification.youGotMessagingMessageFromGroup', { name: body.group.name }), { return [t('_notification.youGotMessagingMessageFromGroup', { name: body.group.name }), {
icon: body.user.avatarUrl, icon: body.user.avatarUrl,
tag: `messaging:group:${body.groupId}`, tag: `messaging:group:${body.groupId}`,
data, data,
renotify: true,
}]; }];
default: default:
return null; return null;
} }
} }
export async function createAllReadNotification(type: 'notifications' | 'messagingMessages') {
const n = await composeAllReadNotification(type);
if (n) return self.registration.showNotification(...n);
}
async function composeAllReadNotification(type: string): Promise<[string, NotificationOptions] | null | undefined> {
if (!swLang.i18n) swLang.fetchLocale();
const i18n = await swLang.i18n as I18n<any>;
const { t } = i18n;
if (type === 'notifications') {
return [t('readAllNotifications'), {
silent: true,
tag: 'user_visible_auto_notification',
}];
}
if (type === 'messagingMessages') {
return [t('readAllMessagingMessages'), {
silent: true,
tag: 'user_visible_auto_notification',
}];
}
return;
}

View file

@ -61,7 +61,12 @@ export async function openPost(options: any, loginId: string) {
export async function openClient(order: swMessageOrderType, url: string, loginId: string, query: any = {}) { export async function openClient(order: swMessageOrderType, url: string, loginId: string, query: any = {}) {
const client = await self.clients.matchAll({ const client = await self.clients.matchAll({
type: 'window' type: 'window'
}).then(clients => clients.length > 0 ? clients[0] as WindowClient : null); }).then(clients => {
for (const c of clients) {
if (c.url.indexOf('?zen') < 0) return c;
}
return null;
});
if (client) { if (client) {
client.postMessage({ type: 'order', ...query, order, loginId, url } as SwMessage); client.postMessage({ type: 'order', ...query, order, loginId, url } as SwMessage);

View file

@ -38,6 +38,14 @@ self.addEventListener('fetch', ev => {
//#region When: Caught Notification //#region When: Caught Notification
self.addEventListener('push', ev => { self.addEventListener('push', ev => {
setTimeout(async () => {
console.log('to');
for (const n of await self.registration.getNotifications({ tag: 'user_visible_auto_notification' })) {
console.log(close)
n.close();
}
}, 5000);
// クライアント取得 // クライアント取得
ev.waitUntil(self.clients.matchAll({ ev.waitUntil(self.clients.matchAll({
includeUncontrolled: true, includeUncontrolled: true,

View file

@ -14,10 +14,15 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue'; import { defineAsyncComponent, defineComponent, inject } from 'vue';
import { stream, popup, popups, uploads, pendingApiRequestsCount } from '@/os'; import { stream, popup, popups, uploads, pendingApiRequestsCount, pageWindow, post } from '@/os';
import * as sound from '@/scripts/sound'; import * as sound from '@/scripts/sound';
import { $i } from '@/account'; import { $i, login } from '@/account';
import { SwMessage } from '@/sw/types';
import { popout } from '@/scripts/popout';
import { defaultStore, ColdDeviceStorage } from '@/store';
import { getAccountFromId } from '@/scripts/get-account-from-id';
import { router } from '@/router';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -45,6 +50,49 @@ export default defineComponent({
if ($i) { if ($i) {
const connection = stream.useSharedConnection('main', 'UI'); const connection = stream.useSharedConnection('main', 'UI');
connection.on('notification', onNotification); connection.on('notification', onNotification);
const navHook = inject('navHook', null);
const sideViewHook = inject('sideViewHook', null);
//#region Listen message from SW
navigator.serviceWorker.addEventListener('message', ev => {
if (_DEV_) {
console.log('sw msg', ev.data);
}
const data = ev.data as SwMessage;
if (data.type !== 'order') return;
if (data.loginId !== $i?.id) {
return getAccountFromId(data.loginId).then(account => {
if (!account) return;
return login(account.token, data.url);
});
}
switch (data.order) {
case 'post':
return post(data.options);
case 'push':
if (data.url.startsWith('/my/messaging')) {
if (router.currentRoute.value.path === data.url) return;
if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return pageWindow(data.url);
if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return popout(data.url);
}
if (router.currentRoute.value.path === data.url) {
return window.scroll({ top: 0, behavior: 'smooth' });
}
if (navHook) {
return navHook(data.url);
}
if (sideViewHook && defaultStore.state.defaultSideView && data.url !== '/') {
return sideViewHook(data.url);
}
return router.push(data.url);
default:
return;
}
});
} }
return { return {
@ -52,7 +100,7 @@ export default defineComponent({
popups, popups,
pendingApiRequestsCount, pendingApiRequestsCount,
}; };
}, }
}); });
</script> </script>