mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
ui: desktop notification click event
This commit is contained in:
1 parent
22680fe73d
commit
34aa867672
2 files changed
+70
-77
No files matched your search
@@ -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<boolean>((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<string>([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<string>([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<boolean>((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;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/ui-default",
|
||||
"version": "4.35.2",
|
||||
"version": "4.35.3",
|
||||
"author": "undefined <i@undefined.moe>",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "hydro.js",
|
||||
|
||||
Reference in new issue
Block a user