12 Commits

Author SHA1 Message Date
Sravan f2b965bd3d desktop v0.1.20 + web: notify on download complete (was silent) (batch135)
Suppressing the save dialog made downloads completely silent — "nothing happened" even though
the file saved to Downloads. Now on download 'done': (1) tell the web UI → branded toast
"Saved X to your Downloads folder" when the window is focused; (2) native OS notification
(click → reveal in Explorer) when the app is minimized/in the tray, so it's never double-noticed;
(3) a failure notice. preload exposes onDownloadDone; home.html shows the toast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:03:24 +05:30
Sravan a0017f2036 feat: detect new web builds + hard-refresh escape hatch (0.1.17/batch78)
Root cause of "the fix works on mobile but not on desktop/web": nothing was wrong with
the code — the desktop app now CLOSES TO TRAY, so it can run for weeks on the page it
loaded on day one and never re-fetch after a deploy. There was also no way to force it
off a stale page (no menu bar → no reload accelerator).

- Server: GET /api/build returns home.html's __BUILD marker.
- Client: polls it (boot, on focus/visibility, every 10 min); when the server's build
  differs from the running one, shows a branded "A new version is available — Refresh"
  banner. Settings gains an always-available "Refresh app" with the current build shown.
- hardReloadApp(): in the browser it unregisters service workers + clears CacheStorage
  then reloads cache-busted; in the shell it calls the native hard reload.
- Desktop: hard-reload IPC (clears the session HTTP cache + reloadIgnoringCache), wired to
  Ctrl+R (reload), Ctrl+Shift+R / F5 (hard reload), and a "Refresh app (get latest)" tray
  item. Previously there was literally no way to clear the cache from the app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:38:55 +05:30
Sravan e562099344 feat(remote-control): viewer can control a desktop sharer's screen, with consent (0.1.13/batch70)
Fixes the core "viewer can't control the sharer even on desktop" gap. Three root
causes addressed:
- share.html DISCARDED every input-channel message (onmessage=()=>{}). It now
  parses the viewer's mouse/keyboard events and forwards them to the desktop shell.
- The main desktop app had NO OS injector (it lived only in the separate agent).
  Ported the nut-js injector (agent/input/inject.js) into desktop/input, wired an
  inject IPC + injectInput bridge, HARD-gated behind a consent flag (rcArmed).
- /share runs in an iframe (no direct bridge access) → it postMessages input to
  the top frame (home.html), which relays to the native bridge.

Consent + safety: the sharer sees an Allow/Deny prompt the first time the agent
interacts; while active a persistent "your screen is being controlled — Stop"
banner; instant revoke; auto-release on session end/teardown. Browser sharers stay
view-only (no OS injection possible). nut-js is an optionalDependency (N-API, ABI-
stable across Electron) — degrades to no-op if the native module is unavailable.
Windows-first; maps to the primary display.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:30:39 +05:30
Sravan aa4bb2902d fix: group toast icon, left-click spell suggestions, scroll no-yank (0.1.12/batch66)
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>
2026-07-10 14:57:02 +05:30
Sravan 62a5f750af 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>
2026-07-08 18:00:56 +05:30
Sravan 49718e5d37 feat: hyperlinks, group seen-by for all, profile-pic preview, in-call invite fix + desktop update progress (0.1.6)
- #1: URLs in chat are now clickable links (open externally on desktop).
- #2: group 'Seen by X, Y +N more' now shows under the LATEST message to EVERYONE
  (server computes reads for all messages; click shows the names).
- #5: tapping the conversation-header avatar previews the DP/group photo full-size.
- #4: in-call invite lists only people you've messaged, excludes those already in the
  call/invited, and the Invite button is sticky.
- #3 (0.1.6 shell): auto-updater emits checking/available/downloading/ready/error to
  the web UI, which shows a progress banner (+ Restart button) so updates aren't silent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 15:58:09 +05:30
Sravan ff436704ec feat(desktop 0.1.5): show version + Check for updates in Settings (#12)
- Settings now shows 'Biz Connect for Desktop · Version x.y.z' with a Check for
  updates button (desktop only, feature-detected).
- preload exposes checkForUpdates(); main.js adds the check-updates IPC (returns
  available/current/dev/error) and, when a build finishes downloading, shows a
  Restart now / Later dialog instead of only the silent on-next-launch install.
- desktop version bumped 0.1.4 -> 0.1.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:12:21 +05:30
Sravan 21ae3e1aa5 feat(desktop): Phase D — inline-reply notifications (Windows toast reply box)
Reply to a chat straight from the OS notification, no app switch:
- node-notifier (bundles SnoreToast) renders a native Windows toast with a reply box —
  Electron's own Notification can't do Windows inline reply.
- main.js reply-notification handler resolves {text}|{open}|null; preload exposes replyNotify.
- home.html notify() routes chat toasts through it on desktop: a typed reply -> sendReplyTo()
  POSTs to /api/messages without opening the app; a click opens the chat. Web/PWA path unchanged.
- Works only in the installed app (needs the installer's AppUserModelID). desktop 0.1.2, build batch21.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:36:02 +05:30
Sravan 899770ed02 feat: Windows download link + self-served update feed + install tracking
Downloads/updates:
- config: DOWNLOADS_DIR (override to a mounted volume in prod).
- static.js: serves /downloads/* (installer, latest.yml, .blockmap) with range support for
  resumable + differential auto-updates; /download/windows redirects to the current .exe
  (stable link). Landing page gets a "Download the Windows desktop app" button (hidden in-app).

Install tracking (who installed the app):
- db app_installs + repos.appInstalls (upsert by install_id, fills in the user on sign-in).
- POST /api/v1/telemetry/install (records install + user once authenticated);
  GET /api/v1/admin/installs (admin: list installs with user/version/os/last-seen).
- desktop main.js: stable per-install id in userData, exposed via preload
  (bizConnectNative.installId/version/os); home.html reportInstall() posts it after login.
- e2e: +2 checks (telemetry recorded, admin sees it). 119/119. build batch20.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:28:53 +05:30
Sravan 1ca0b836e1 feat(desktop): unread-chat count badge on the taskbar icon
Mirrors the rail's unread-chat count onto the Windows taskbar icon (overlay) and the
macOS/Linux dock badge. updateRailUnread() draws a small red count badge on a canvas
and hands it to the shell via bizConnectNative.setUnread(count, dataUrl); main sets it
with win.setOverlayIcon + app.setBadgeCount. Clears at 0, shows 99+ past 99. No-op in a
browser/mobile. (home.html build batch17)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:28:15 +05:30
Sravan 5a98ae4d34 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>
2026-07-01 16:16:40 +05:30
Sravan 593a4677b6 feat(clients): scaffold mobile (Capacitor) + desktop (Electron) shells
Plan + decisions in CLIENTS.md (parallel mobile+desktop; desktop = technician
client + existing remote-control agent host; mobile = Capacitor wrap).

- desktop/: Electron technician client — loads the live Connect UI, native
  screen capture via setDisplayMediaRequestHandler, persisted session, external
  links to browser; electron-builder config for Win/Mac/Linux installers.
- mobile/: Capacitor project — server.url loads Connect UI, push/camera/status-bar
  plugins declared, www splash fallback; iOS/Android added via `cap add`.
- Reuses the existing /api/v1 + Bearer auth backend; no web-code changes.
- .gitignore: ignore generated mobile/android, mobile/ios platform dirs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:49:41 +05:30