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:
+18
-3
@@ -840,7 +840,7 @@
|
||||
<body>
|
||||
<script src="/icons.js?v=5"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@twemoji/api@15.1.0/dist/twemoji.min.js" crossorigin="anonymous"></script>
|
||||
<script>window.__BUILD='2026-07-08-batch61';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
|
||||
<script>window.__BUILD='2026-07-08-batch62';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
|
||||
// Render modern (Twemoji) emojis in place of the OS's flat ones. No-op if the CDN didn't load
|
||||
// (emojis stay as plain Unicode). (#5)
|
||||
function twemojify(el){ try{ if(el && window.twemoji) window.twemoji.parse(el, { folder:'svg', ext:'.svg' }); }catch(_){} }</script>
|
||||
@@ -1398,6 +1398,17 @@ async function loadSidebar(){
|
||||
ROWS=items;
|
||||
renderChats(searchVal());
|
||||
updateRailUnread();
|
||||
prewarmNotifAvatars();
|
||||
}
|
||||
// Desktop only: hand the shell every contact/group DP URL so it caches them up front — the first
|
||||
// notification (chat OR call) from anyone then shows their photo instantly, with no per-toast wait.
|
||||
let _avatarsWarmed=false;
|
||||
function prewarmNotifAvatars(){
|
||||
try{
|
||||
const n=window.bizConnectNative; if(!n||!n.precacheAvatars||_avatarsWarmed) return;
|
||||
const urls=[...new Set((ROWS||[]).map(r=>r.avatar).filter(u=>u && /^https?:\/\//i.test(u)))];
|
||||
if(urls.length){ _avatarsWarmed=true; n.precacheAvatars(urls); }
|
||||
}catch(_){}
|
||||
}
|
||||
|
||||
// ----- conversation view -----
|
||||
@@ -1794,11 +1805,13 @@ function showCallInvite(room, byName, ret, sub, quiet){
|
||||
+'<button class="ci-join">'+ic('video',16)+' Join</button>'
|
||||
+'<button class="ci-decline" title="Decline">'+ic('callEnd',16)+' Decline</button>';
|
||||
document.body.appendChild(el);
|
||||
if(!quiet){ try{ notify('📞 '+who, (sub?('Group call · '+sub):'is calling you'), ret&&ret.kind, ret&&ret.id, {persistent:true}); }catch(_){} } // OS notification too (skip when merely re-showing on chat open)
|
||||
let closed=false;
|
||||
const close=()=>{ if(closed) return; closed=true; try{ el.remove(); }catch(_){} stopRing(); };
|
||||
// Wire Join/Decline BEFORE firing the OS notification so the buttons are live the instant the popup
|
||||
// shows (previously notify() ran first — the click did nothing until the toast plumbing settled).
|
||||
el.querySelector('.ci-join').onclick=()=>{ close(); meetReturn=ret||null; switchTab('meeting'); enterMeeting(room); };
|
||||
el.querySelector('.ci-decline').onclick=()=>{ close(); if(ret&&ret.kind==='dm'){ postJSON('/api/calls/decline',{room}).catch(()=>{}); } }; // 1:1 → notify caller; group → silent
|
||||
if(!quiet){ try{ notify('📞 '+who, (sub?('Group call · '+sub):'is calling you'), ret&&ret.kind, ret&&ret.id, {persistent:true}); }catch(_){} } // OS notification too (skip when merely re-showing on chat open)
|
||||
setTimeout(close, 45000);
|
||||
}
|
||||
// Scheduled-meeting invitation (toast + the meeting shows up in their list).
|
||||
@@ -2353,7 +2366,9 @@ function openFromNotif(kind,id){
|
||||
// The app is already running (the notification came from it) → open the chat IN-PLACE. A full-page
|
||||
// reload was slow (#19) and dropped live state: the sidebar hadn't reloaded so the header showed
|
||||
// "Conversation" with no DP (#7), and an incoming call's Join/invite popup was lost (#2).
|
||||
if(window.ME && ME.id && typeof selectChat==='function'){
|
||||
// NB: use bare `ME`, NOT `window.ME` — ME is declared with `let`, which does NOT create a global
|
||||
// property, so `window.ME` was always undefined and EVERY click hit the reload fallback below.
|
||||
if(ME && ME.id && typeof selectChat==='function'){
|
||||
if(id){ try{ switchTab('chat'); }catch(_){} try{ selectChat(kind||'dm', id); }catch(_){} }
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user