feat(desktop): media/notification permissions + notification raises the app

- desktop/main.js: grant media (camera/mic), display-capture, notifications, clipboard,
  fullscreen, pointerLock for the app origin (Electron denies these by default, which
  silently broke meetings' camera/mic). Adds setPermissionRequestHandler +
  setPermissionCheckHandler on the app session.
- Clicking a notification now raises + focuses the window: preload exposes
  bizConnectNative.focusApp(), main handles 'focus-window' IPC, and the web notify()
  onclick calls it when running in the desktop shell. (home.html build batch16)
- CLIENTS.md: Phase D — inline-reply notifications (Windows Toast RemoteInput /
  Android RemoteInput / iOS UNTextInputNotificationAction) queued right after packaging.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 16:16:40 +05:30
parent 7a2ab3fc8d
commit 5a98ae4d34
4 changed files with 48 additions and 11 deletions
+2 -2
View File
@@ -721,7 +721,7 @@
</head>
<body>
<script src="/icons.js?v=4"></script>
<script>window.__BUILD='2026-06-30-batch15';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);</script>
<script>window.__BUILD='2026-06-30-batch16';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);</script>
<div class="loading" id="loading">Loading…</div>
<header>
@@ -1863,7 +1863,7 @@ function notify(title, body, kind, id){
try{
if(!('Notification' in window) || Notification.permission!=='granted') return;
const n=new Notification(title, { body, icon:'/logo.png' });
n.onclick=()=>{ try{ window.focus(); }catch(_){} const u='/home?openKind='+encodeURIComponent(kind||'')+'&openId='+encodeURIComponent(id||''); n.close(); location.assign(u); };
n.onclick=()=>{ try{ window.focus(); }catch(_){} try{ if(window.bizConnectNative&&window.bizConnectNative.focusApp) window.bizConnectNative.focusApp(); }catch(_){} const u='/home?openKind='+encodeURIComponent(kind||'')+'&openId='+encodeURIComponent(id||''); n.close(); location.assign(u); };
setTimeout(()=>{ try{ n.close(); }catch(_){} }, 8000);
}catch(_){}
}