Commit Graph

25 Commits

Author SHA1 Message Date
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 7682e17a53 fix(desktop 0.1.6): fast + persistent native notifications + screen picker
- Desktop notifications were slow (~15s), vanished in ~1s, and clicks did nothing:
  * don't block the toast on the avatar download (race a 600ms cap) → shows instantly
  * keep a strong reference to each Notification (Electron GC'd them → premature close
    + dead click)
  * call invites use timeoutType:'never' + a 45s window so they stay until clicked/ended;
    web marks call notifications persistent.
- #9: enable the OS screen/window PICKER (useSystemPicker) so users choose what to share
  (a single window avoids the whole-screen mirror); falls back to primary display.
- desktop 0.1.5 -> 0.1.6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 15:43:07 +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 a1887064eb feat(chat/notif): single hover action-pill; sender DP in desktop+mobile notifications
- Message actions (reply/react/edit/delete) consolidated into ONE hover pill anchored to the
  bubble's top-right, overlapping it so on short messages the icons no longer float off into
  empty space and vanish before you can click.
- Desktop toast + mobile(FCM)/web-background push now show the sender's real DP:
  * renderer passes the DP URL through; desktop shell downloads it for the toast icon
    (canvas-drawing an external DP tainted it → initials). Desktop bumped to 0.1.4.
  * DM push payload carries icon=sender avatar; sw.js already uses it (web background),
    sendFcm sets notification.image (Android).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:01:32 +05:30
Sravan dc1915bb43 feat: live presence, delivery-tick sync, brand rollout, call fixes, desktop 0.1.3
Live presence (fixes stale in-call/status until refresh — impossible in apps):
- server broadcasts a user's status over the chat socket on connect/disconnect, call
  join/leave, and status change (chat.js broadcastPresence; signaling + routes hooks).
- client onPresence() updates the contact dot + open-chat header live.

Chat delivery ticks (#6): chat-list row now mirrors the thread (delivered→double grey,
read→blue) via a new 'with' field on the delivered relay + onChatRead/onChatDelivered.

Call fixes: no bogus 'host handed over' when a 1:1 call ends (leaveMeeting forced);
branded call-connecting + chat-thread loaders; header subtitle tracks live call state.

Notifications: web notify + sw.js use sender/group DP + brand icon (not old wordmark);
desktop shell drops Web Push so only the single native toast fires (#5).

Brand: master icon/splash/loaders wired everywhere (PWA/favicon/apple-touch/.ico),
branded login (blue + gold CTA), branded toasts (BZToast) on all pages, Electron splash.

Desktop: dev auto-targets localhost (packaged→prod); version 0.1.3 with new multi-size
icon; dropped unused node-notifier; removed home-mockup.html.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:43:02 +05:30
Sravan a152005b71 feat(brand): roll out master app icon, splash & branded loaders everywhere
From brand-assets/ masters (C + orbiting-dot on brand blue):
- Regenerated PWA icons (192/512/maskable), apple-touch (180), favicons
  (32/16 + root favicon.ico) from the 1024 master; bumped manifest to v3.
- Rebuilt desktop/build/icon.ico as a proper multi-size ICO (16..256,
  PNG-compressed) to fix the tiny/blurry taskbar icon.
- Updated mobile masters (resources/icon.png 1024, splash.png/splash-dark.png
  2732) for capacitor-assets to regenerate native icons/splash.
- Wired the animated branded orbit loader into the app boot 'Loading…' screen;
  added favicon/theme-color links to index + home heads.
- logo.png (horizontal wordmark) left untouched — masters have no wordmark.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:41:48 +05:30
Sravan 2b27889e07 fix(desktop): use Electron's native Notification (reliable click-to-open)
node-notifier/SnoreToast click callback never fired without the crashing wait mode. Switch the
chat toast to Electron's built-in Notification: shows avatar + message and its 'click' event
reliably raises the app + opens the chat. No SnoreToast, no external tools.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:16:35 +05:30
Sravan f8978ff796 fix(desktop): drop crashing SnoreToast reply path — clean click-to-open toast
The bundled SnoreToast crashes (0xC0000409) handling a text reply, and that crash triggered
a second (fallback) toast. Removed the direct-SnoreToast reply path entirely; the chat toast
now reliably shows avatar + message via node-notifier and opens the chat on click. Inline
text reply needs a different toast engine (deferred).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:58:26 +05:30
Sravan 0b58d33117 fix(desktop): drop -w — SnoreToast waits by default; -w made it fail (exit -1)
Testing showed SnoreToast blocks/waits for the toast interaction when given -pipeName; the
-w flag actually fails on this build (exit -1) which forced the reply-less fallback. Without
-w it waits, captures the typed reply, and writes it to our pipe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:43:40 +05:30
Sravan 0f5e5bf00a fix(desktop): spawn SnoreToast from app.asar.unpacked (was ENOENT inside asar)
snoreExe returned the app.asar path (fs.existsSync lies about asar paths), so spawn failed
with ENOENT and always fell back to the reply-less WindowsToaster. Map to app.asar.unpacked
unconditionally so the real SnoreToast binary (with -w) runs and captures the reply.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:28:43 +05:30
Sravan c0f7926210 fix(desktop): direct SnoreToast -w to capture reply + WindowsToaster fallback
Root cause: node-notifier's toaster whitelist has no -w, so SnoreToast never waits and the
reply is lost. Now drive SnoreToast directly with -w + our own pipe (correct args, no
-application which had broken the toast). If the binary is missing or fails to show, fall
back to node-notifier's WindowsToaster so a toast always appears. Logs code+raw for diagnosis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:06:01 +05:30
Sravan 1abf6855d8 fix(desktop): drive SnoreToast directly with own named pipe + raw reply logging
node-notifier returned an empty result for text replies. Now spawn the bundled SnoreToast
with -tb -w -pipeName against our own pipe, read the raw UTF-16LE result, and parse the
reply (keeps spaces). Logs the raw pipe string to userData/toast-debug.log to pin the
exact reply field on real hardware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:44:08 +05:30
Sravan 3f209bf619 feat(desktop): real Windows inline reply via SnoreToast -tb + sender/group avatar
- node-notifier's WindowsToaster forwards raw opts to SnoreToast, so inject -tb (reply box)
  + -p (image). Reuses its named-pipe + result parsing (exit 5 = TextEntered). No pwsh needed.
  Logs the raw toast result to userData/toast-debug.log to confirm the reply field on real HW.
- home.html: notifAvatarDataUrl draws the DM sender's pic / group's DP (else colored initials)
  to a round PNG and passes it as the toast image. Reply -> sendReplyTo; click -> open chat.
- dropped powertoast (ESM + needs pwsh 7, absent here). build batch22.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:26:24 +05:30
Sravan ffe04e6bff fix(desktop): asarUnpack node-notifier so SnoreToast can launch from the packaged app
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:03:48 +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 e5c94ebf6d fix: login submits on Enter (real <form>) + desktop notifications show "Biz Connect"
- home.html: login is now a real <form> with a submit button, so Enter (or click) both
  submit natively — replaces the ad-hoc keydown handler. (build batch19; header stays removed)
- desktop/main.js: app.setAppUserModelId('com.bizgaze.connect.desktop') so Windows resolves
  the installed shortcut and toasts read "Biz Connect" instead of "electron.app.BizConnect".
- desktop version → 0.1.1; installer rebuilt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 18:19:01 +05:30
Sravan e84e5eb241 feat(desktop): open the landing page (pre-login), not /home directly
The desktop app was hardcoded to /home, so it jumped straight to the login form and
skipped the 'before login' landing (no-login 'Share my screen' + sign-in). Now loads / —
same entry as the website; it redirects logged-in users to /home.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:55:49 +05:30
Sravan 07286899c5 chore(desktop): one-click installer (no scope/folder prompts)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:37:58 +05:30
Sravan c605304c67 chore(desktop): add author field (cleaner electron-builder output)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:21:54 +05:30
Sravan 1500d42cd2 feat(desktop): packaging + self-hosted auto-update (electron-builder/updater)
- package.json build config: NSIS installer, app icon, generic publish provider →
  https://remote.bizgaze.com/downloads/ (self-hosted update feed).
- main.js: electron-updater checks the feed on launch + every 6h, downloads in the
  background, installs on restart. Active only in packaged builds.
- build/icon.ico app icon; PACKAGING.md documents build/release/signing.
- Key design: web/UI changes reach installed apps instantly (they load the live server);
  only native shell changes need an auto-updated build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:03:18 +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 7a2ab3fc8d fix(agent): remote-control input now works (data channel + nut-js API)
Two latent bugs that broke input control on any setup:
- Data channel was created by the viewer (the answerer), so the agent's offer had
  no SCTP m-line and the channel never opened -> no input reached the agent. The
  agent (offerer) now creates the 'input' channel; the viewer receives it.
- inject.js used nut.screen.getResolution() which doesn't exist in this nut-js;
  switched to screen.width()/height() with per-session caching.

Verified end-to-end locally: screen streams + mouse injection moves the remote cursor.
Also commits desktop/ + mobile/ package-lock.json from client installs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 15:47:09 +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