2026-06-30 17:49:41 +05:30
// Minimal, safe bridge into the web UI. Runs with contextIsolation, so it only exposes a
// frozen marker the web app can feature-detect against (e.g. to hide the PWA install prompt
// or prefer native push). No Node APIs are exposed to page JS.
2026-07-01 16:16:40 +05:30
const { contextBridge , ipcRenderer } = require ( 'electron' );
2026-06-30 17:49:41 +05:30
2026-07-01 21:28:53 +05:30
// Pull the stable install id + version/os from main (synchronous, one-time at preload).
let info = { installId : '' , appVersion : '' , os : '' };
try { info = ipcRenderer . sendSync ( 'get-install-info' ) || info ; } catch ( _ ) {}
2026-06-30 17:49:41 +05:30
contextBridge . exposeInMainWorld ( '__NATIVE__' , 'desktop' );
contextBridge . exposeInMainWorld ( 'bizConnectNative' , Object . freeze ({
platform : 'desktop' ,
2026-07-01 21:28:53 +05:30
version : info . appVersion || '0.1.0' ,
installId : info . installId || '' ,
os : info . os || '' ,
2026-07-01 16:16:40 +05:30
// Bring the app window to the foreground (e.g. when a notification is clicked) — the web
// Notification's window.focus() can't raise an Electron window; the main process must.
focusApp : () => ipcRenderer . send ( 'focus-window' ),
2026-07-01 16:28:15 +05:30
// Show the unread-chat count as a badge on the taskbar icon. count=number of chats with
// unread; dataUrl=a small PNG badge the renderer drew (null to clear).
setUnread : ( count , dataUrl ) => ipcRenderer . send ( 'set-unread' , { count , dataUrl }),
2026-07-01 22:36:02 +05:30
// Native Windows toast with an inline reply box. Resolves to {text} (replied), {open} (clicked)
// or null. Lets the user reply to a chat straight from the notification.
replyNotify : ( payload ) => ipcRenderer . invoke ( 'reply-notification' , payload ),
2026-07-08 18:00:56 +05:30
// Pre-warm the notification DP cache with contact photo URLs (called after chats load) so the first
// toast from anyone already has their photo — no per-notification download lag.
precacheAvatars : ( urls ) => { try { return ipcRenderer . invoke ( 'precache-avatars' , urls ); } catch ( _ ) { return Promise . resolve ( false ); } },
2026-07-10 14:57:02 +05:30
// Ask the shell to show native spelling suggestions for the word at page coords (x,y) — used to bring
// up corrections on a LEFT click in the message box (not just right-click).
spellSuggestAt : ( x , y ) => { try { ipcRenderer . send ( 'spell-suggest' , { x , y }); } catch ( _ ) {} },
2026-07-10 16:30:39 +05:30
// Remote control (screen the local user is sharing): whether OS injection is possible on this machine,
// arm/disarm the consent gate, and forward a viewer's input event for injection. Injection only happens
// while armed (the user granted control) — see main.js rcArmed.
rcAvailable : () => { try { return !! ipcRenderer . sendSync ( 'rc-available' ); } catch ( _ ) { return false ; } },
rcArm : ( on ) => { try { ipcRenderer . send ( 'rc-arm' , !! on ); } catch ( _ ) {} },
rcInput : ( evt ) => { try { ipcRenderer . send ( 'rc-input' , evt ); } catch ( _ ) {} },
2026-07-14 13:38:55 +05:30
// Force the newest web build: clears the shell's HTTP cache and reloads ignoring cache. The app closes
// to tray and can run for weeks, so without this it would keep serving the page it first loaded.
hardReload : () => { try { return ipcRenderer . invoke ( 'hard-reload' ); } catch ( _ ) { return Promise . resolve ( false ); } },
2026-07-07 16:12:21 +05:30
// Manual "Check for updates" from Settings. Resolves {status:'available'|'current'|'dev'|'error', version?}.
// On 'available' the shell downloads in the background and prompts to restart when ready.
checkForUpdates : () => ipcRenderer . invoke ( 'check-updates' ),
2026-07-08 15:58:09 +05:30
// #3: subscribe to auto-update lifecycle events so the UI can show download progress + "ready".
// cb receives {phase:'checking'|'available'|'downloading'|'ready'|'current'|'error', percent?, version?}.
onUpdateEvent : ( cb ) => { try { ipcRenderer . on ( 'update-event' , ( _e , data ) => { try { cb ( data ); } catch ( _ ) {} }); } catch ( _ ) {} },
2026-07-19 16:03:24 +05:30
onDownloadDone : ( cb ) => { try { ipcRenderer . on ( 'download-done' , ( _e , data ) => { try { cb ( data ); } catch ( _ ) {} }); } catch ( _ ) {} }, // desktop: a file finished downloading to the Downloads folder → show a toast
2026-07-08 15:58:09 +05:30
restartToUpdate : () => ipcRenderer . invoke ( 'restart-to-update' ),
2026-06-30 17:49:41 +05:30
}));