aa4bb2902d
1. Group message toast had no icon: the generated group icon is a data: URL, but the 0.1.11 handler only used ALREADY-cached icons and skipped it. data: URLs are synchronous — use them immediately, so every group toast shows an icon. 2. Spell suggestions on a LEFT click: clicking a red-squiggled word in the message box now pops the native suggestions menu (renderer asks the shell to synthesize a right-click at that point → real dictionary suggestions). No right-click. 3. Scroll felt "stuck" because an incoming message yanked you to the bottom even when you'd scrolled up to read history (worse now that bg messages arrive live). appendBubble now keeps your position unless you were at the bottom / it's your own message, and surfaces the "jump to latest" control instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
39 lines
2.7 KiB
JavaScript
39 lines
2.7 KiB
JavaScript
// 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.
|
|
const { contextBridge, ipcRenderer } = require('electron');
|
|
|
|
// 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 (_) {}
|
|
|
|
contextBridge.exposeInMainWorld('__NATIVE__', 'desktop');
|
|
contextBridge.exposeInMainWorld('bizConnectNative', Object.freeze({
|
|
platform: 'desktop',
|
|
version: info.appVersion || '0.1.0',
|
|
installId: info.installId || '',
|
|
os: info.os || '',
|
|
// 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'),
|
|
// 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 }),
|
|
// 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),
|
|
// 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); } },
|
|
// 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 (_) {} },
|
|
// 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'),
|
|
// #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 (_) {} },
|
|
restartToUpdate: () => ipcRenderer.invoke('restart-to-update'),
|
|
}));
|