fix(desktop): notification click no longer reloads to a dead page (0.1.9/batch62)
Root cause of the persistent "notification opens a dead page / no Join" bug: openFromNotif gated the in-place open on `window.ME`, but ME is declared with `let` — which never creates a global property — so window.ME was ALWAYS undefined and every click hit the full-page-reload fallback. Use bare `ME`. Also: - Notifications fire instantly: never block on the DP download. Use the photo only if already cached; warm the cache in the background + pre-warm all contact DPs on chat load (precache-avatars IPC). Removes the ~2.5s lag. - Wire call Join/Decline handlers BEFORE firing the OS notification so Join is live the instant the invite popup appears (was dead until the toast settled). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+17
-8
@@ -83,6 +83,13 @@ function avatarToTempPng(src) {
|
||||
});
|
||||
}
|
||||
|
||||
// Pre-warm the DP cache for the renderer's contacts (called after chats load), so the FIRST
|
||||
// notification from anyone already has their photo — no per-toast download wait.
|
||||
ipcMain.handle('precache-avatars', async (_e, urls = []) => {
|
||||
try { for (const u of (Array.isArray(urls) ? urls : []).slice(0, 100)) { try { await avatarToTempPng(u); } catch (_) {} } } catch (_) {}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Keep STRONG references to live notifications. Electron/Windows garbage-collects a Notification
|
||||
// with no reference, which closed the toast within ~1s and made clicks do nothing.
|
||||
const activeNotifs = new Set();
|
||||
@@ -90,14 +97,16 @@ const activeNotifs = new Set();
|
||||
// Resolves {open} when the toast is clicked (renderer then opens that chat), else null.
|
||||
ipcMain.handle('reply-notification', async (_e, payload = {}) => {
|
||||
if (!Notification.isSupported()) return null;
|
||||
// Do NOT block the toast on the avatar download (that made desktop notifications lag ~15s vs the
|
||||
// browser's instant one). Race it against a cap: use the DP only if it's ready in time. Chat toasts
|
||||
// stay snappy (700ms). CALL toasts (persistent) ring for ~40s, so we can afford to wait longer
|
||||
// (2.5s) to actually show the caller's photo — the whole point of a call notification.
|
||||
const img = await Promise.race([
|
||||
avatarToTempPng(payload.avatar),
|
||||
new Promise((r) => setTimeout(() => r(null), payload.persistent ? 2500 : 700)),
|
||||
]);
|
||||
// Fire the toast IMMEDIATELY — NEVER block on a download (waiting made notifications lag; a late
|
||||
// call/chat alert is worse than one without a photo). Use the DP only if it's ALREADY cached
|
||||
// (instant). If not, kick off a background fetch so the SAME sender's NEXT notification has it.
|
||||
// Contacts are also pre-warmed on load (precache-avatars), so the photo is usually already cached.
|
||||
let img = null;
|
||||
try {
|
||||
const c = payload.avatar && avatarCache.get(payload.avatar);
|
||||
if (c && fs.existsSync(c)) img = c;
|
||||
else if (payload.avatar) avatarToTempPng(payload.avatar).catch(() => {}); // warm for next time
|
||||
} catch (_) {}
|
||||
return await new Promise((resolve) => {
|
||||
let done = false;
|
||||
let n;
|
||||
|
||||
Reference in New Issue
Block a user