From 34aa8676727db656aa51bf84716efa85a8d0251e Mon Sep 17 00:00:00 2001 From: undefined Date: Thu, 5 May 2022 23:07:06 +0800 Subject: [PATCH] ui: desktop notification click event --- .../components/message/index.page.ts | 145 +++++++++--------- packages/ui-default/package.json | 2 +- 2 files changed, 70 insertions(+), 77 deletions(-) diff --git a/packages/ui-default/components/message/index.page.ts b/packages/ui-default/components/message/index.page.ts index 088646162..b6728dff6 100644 --- a/packages/ui-default/components/message/index.page.ts +++ b/packages/ui-default/components/message/index.page.ts @@ -6,55 +6,6 @@ import { FLAG_ALERT } from 'vj/constant/message'; import i18n from 'vj/utils/i18n'; import tpl from 'vj/utils/tpl'; import { nanoid } from 'nanoid'; -import sleep from 'vj/utils/delay'; - -function asMaster() { - console.log('init as master'); - const channel = new BroadcastChannel('hydro-messages'); - const interval = setInterval(() => channel.postMessage({ type: 'master' }), 5000); - const url = new URL('/home/messages-conn', window.location.href.replace('http', 'ws')); - url.searchParams.append('sid', document.cookie); - const sock = new ReconnectingWebsocket(url.toString()); - function destory() { - sock.close(); - channel.close(); - clearInterval(interval); - } - const pending = {}; - sock.onopen = () => console.log('Connected'); - sock.onerror = console.error; - sock.onclose = (...args) => console.log('Closed', ...args); - sock.onmessage = async (message) => { - if (process.env.NODE_ENV !== 'production') console.log('onmessage: ', message); - const payload = JSON.parse(message.data); - if (['PermissionError', 'PrivilegeError'].includes(payload.error)) { - destory(); - return; - } - const id = nanoid(); - channel.postMessage({ type: 'message', id, payload }); - const success = await new Promise((resolve) => { - pending[id] = resolve; - setTimeout(() => { - delete pending[id]; - resolve(false); - }, 1000); - }); - if (!success && window.Notification?.permission === 'granted') { - // eslint-disable-next-line no-new - new window.Notification( - payload.udoc.uname || 'Hydro Notification', - { - icon: payload.udoc.avatarUrl || '/android-chrome-192x192.png', - body: payload.mdoc.content, - }, - ); - } - }; - channel.onmessage = (msg) => { - if (msg.data.type === 'message-push') pending[msg.data.id]?.(true); - }; -} const onmessage = (msg) => { console.log('Received message', msg); @@ -83,32 +34,6 @@ const onmessage = (msg) => { }).show(); }; -async function asSlave() { - console.log('message load as slave'); - const channel = new BroadcastChannel('hydro-messages'); - const selfId = nanoid(); - setInterval(() => channel.postMessage({ type: 'node', id: selfId }), 5000); - let alive = false; - let nodes = new Set([selfId]); - channel.onmessage = (msg) => { - if (msg.data.target && msg.data.target !== selfId) return; - if (msg.data.type === 'master') alive = true; - if (msg.data.type === 'node') nodes.add(msg.data.id); - if (msg.data.type === 'message') { - if (!document.hidden) { - channel.postMessage({ type: 'message-push', id: msg.data.id }); - onmessage(msg.data.payload); - } - } - }; - while (true) { // eslint-disable-line no-constant-condition - alive = false; - nodes = new Set([selfId]); - await sleep(7000); - if (!alive && Array.from(nodes).sort()[0] === selfId) asMaster(); - } -} - const messagePage = new AutoloadPage('messagePage', (pagename) => { if (pagename === 'home_messages' || !UserContext._id) return; if (UserContext.unreadMsg) { @@ -123,7 +48,75 @@ const messagePage = new AutoloadPage('messagePage', (pagename) => { console.error('BoardcastChannel not supported'); return; } - asSlave(); + + let isMaster = false; + const selfId = nanoid(); + const channel = new BroadcastChannel('hydro-messages'); + const pages = JSON.parse(localStorage.getItem('pages') || '[]') as string[]; + pages.push(selfId); + pages.sort(); + localStorage.setItem('pages', JSON.stringify(pages)); + + window.onunload = () => { + const c = JSON.parse(localStorage.getItem('pages') || '[]') as string[]; + localStorage.setItem('pages', JSON.stringify(c.filter((i) => i !== selfId))); + if (!isMaster) return; + localStorage.removeItem('page.master'); + channel?.postMessage({ type: 'master' }); + }; + + function asMaster() { + console.log('init as master'); + isMaster = true; + localStorage.setItem('page.master', selfId); + const masterChannel = new BroadcastChannel('hydro-messages'); + const url = new URL('/home/messages-conn', window.location.href.replace('http', 'ws')); + // TODO handle a better way for cookie + url.searchParams.append('sid', document.cookie); + const sock = new ReconnectingWebsocket(url.toString()); + const pending = {}; + sock.onopen = () => console.log('Connected'); + sock.onerror = console.error; + sock.onclose = (...args) => console.log('Closed', ...args); + sock.onmessage = async (message) => { + if (process.env.NODE_ENV !== 'production') console.log('onmessage: ', message); + const payload = JSON.parse(message.data); + const id = nanoid(); + masterChannel.postMessage({ type: 'message', id, payload }); + const success = await new Promise((resolve) => { + pending[id] = resolve; + setTimeout(() => { + delete pending[id]; + resolve(false); + }, 1000); + }); + if (!success && window.Notification?.permission === 'granted') { + const notification = new window.Notification( + payload.udoc.uname || 'Hydro Notification', + { + icon: payload.udoc.avatarUrl || '/android-chrome-192x192.png', + body: payload.mdoc.content, + }, + ); + notification.onclick = () => window.open('/home/messages'); + } + }; + masterChannel.onmessage = (msg) => { + if (msg.data.type === 'message-push') pending[msg.data.id]?.(true); + }; + } + + channel.onmessage = (msg) => { + if (msg.data.type === 'message' && !document.hidden) { + channel.postMessage({ type: 'message-push', id: msg.data.id }); + onmessage(msg.data.payload); + } + if (msg.data.type === 'master') { + const c = JSON.parse(localStorage.getItem('pages') || '[]') as string[]; + if (c[0] === selfId) asMaster(); + } + }; + if (!localStorage.getItem('page.master')) asMaster(); }); export default messagePage; diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 882932c39..7bc1b184a 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.35.2", + "version": "4.35.3", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js",