mirror of
https://github.com/misskey-dev/misskey.git
synced 2024-12-29 11:59:08 +01:00
✌️
This commit is contained in:
parent
2dc4f24f18
commit
c0e9cc1902
6 changed files with 97 additions and 53 deletions
|
@ -1568,6 +1568,8 @@ _notification:
|
||||||
youReceivedFollowRequest: "フォローリクエストが来ました"
|
youReceivedFollowRequest: "フォローリクエストが来ました"
|
||||||
yourFollowRequestAccepted: "フォローリクエストが承認されました"
|
yourFollowRequestAccepted: "フォローリクエストが承認されました"
|
||||||
youWereInvitedToGroup: "{userName}があなたをグループに招待しました"
|
youWereInvitedToGroup: "{userName}があなたをグループに招待しました"
|
||||||
|
readAllNotifications: "通知はすべて既読です"
|
||||||
|
readAllMessagingMessages: "チャットはすべて既読です"
|
||||||
|
|
||||||
_types:
|
_types:
|
||||||
all: "すべて"
|
all: "すべて"
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue