Commit Graph

6 Commits

Author SHA1 Message Date
Sravan ee95f594c6 style(share-ext): clean SF-Symbol X + paper-plane instead of heavy pill/circle
The top-bar buttons looked heavy against the navy bar (thick grey X-circle, bold
"Send" pill). Swapped for light SF Symbols on the navy bar: a thin `xmark` for
cancel and a `paperplane.fill` for send (semibold, enables when ≥1 chat is picked).
Icon-only send matches the Teams reference — the radio checks already show what's
selected, so the "(N)" count text is dropped. Native-only — needs a build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 19:08:38 +05:30
Sravan 854bc86a6e feat(share-ext): fix double "Send to", Teams-style layout, clearer branding
Two things from testing (the in-sheet picker with avatars + multi-select works):

1. Double "Send to": after the extension sent, opening the app ALSO popped the web
   "Send to" modal for the same file. Cause: the extension wrote a safety-net
   manifest up front, which the app then picked up. Now the manifest represents an
   UNSENT share only — written solely when the extension can't send (no token) or a
   send fails. A successful in-sheet send clears the staged files and leaves nothing,
   so the app never re-offers it. Cancel also clears staged files (no orphans).

2. Layout aligned to the Teams reference:
   - Preview strip of thumbnails for what's being shared (image → the image, video →
     first frame via AVAssetImageGenerator, else a doc icon).
   - Radio selectors on the right — an always-visible empty circle that fills to a
     navy check when selected (clearer multi-select than an appear-on-select tick).
   - "Recent chats" section header; subtitle under each name (Direct message /
     Group · N members).
   - Clearer branding: bold white "Share to Biz Connect" on the navy bar.

Native-only — NEEDS A NEW iOS BUILD. Balance + selectors checked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 18:25:15 +05:30
Sravan 4d446a5425 feat(share-ext): avatars, multi-select, and Biz Connect branding in the picker
Three follow-ups on the in-sheet picker:
- Profile photos: rows now show the real avatar (fetched from the conversations
  API's `avatar` field with the bearer token, or a data-URL decoded inline),
  rendered as a circle; coloured initials as the fallback — matching the app.
- Multi-select: tap toggles a checkmark instead of sending immediately; a "Send (N)"
  button in the nav bar sends to every selected chat. Each file is uploaded ONCE and
  its attachment id reused across all targets (the server allows the uploader to
  reattach the same id), so multi-send doesn't re-upload.
- Branding: navy (#1F3B73) navigation bar with a white "Biz Connect" prompt over the
  "Send to…" title and white controls.

Native-only — NEEDS A NEW iOS BUILD. Balance + selectors checked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 18:00:01 +05:30
Sravan d664dde798 feat(share): send from inside the share sheet — the Teams-style in-extension picker
Replaces the wrong approach (stage + try to bounce into the app, which iOS blocks)
with the one Teams/WhatsApp actually use: the picker and the send happen INSIDE the
share extension, so there's no app-open at all. Tap Share → Biz Connect → pick a
chat → it uploads and sends, right there in the sheet.

How the extension can send without the app: it's a separate process that can't see
the web app's HttpOnly cookie, so:
- server: GET /api/share/token mints a bearer token for the logged-in user.
- web: on every launch the app fetches that token and hands it to the extension via
  the App Group (ShareInbox.setAuth writes token+base to the shared UserDefaults).
- extension: reads the token and calls the SAME API the native client uses —
  GET /api/messages/conversations to list chats, POST /api/messages/upload for each
  file, POST /api/messages to send. Native UITableView picker with search.

Robustness: it still stages the files + writes a manifest first, so if there's no
token yet (user never signed in) or the send fails, the file isn't lost — the app
collects it on next open, exactly as before. On success the manifest is cleared so
the app doesn't re-offer it.

Server + web are live now; the token endpoint is harmless until a build ships the
extension. NEEDS A NEW iOS BUILD for the picker itself.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 16:33:23 +05:30
Sravan 2ec0a0c0cd feat(share-ext): confirmation card instead of a confusing blank flash
A Share Extension opening its host app is unsupported on modern iOS (restricted
~iOS 14), so the programmatic bizconnect://share open is silently blocked and the
user just saw a blank flash back to Photos — looking broken even though the files
staged fine.

The extension now shows a small native card after staging: "✓ Ready to send — Open
Biz Connect to choose a chat", with an "Open Biz Connect" button (user-initiated
open has the best chance of working) and a Done button. It still attempts the
auto-open first. Either way the app collects the staged files when next opened, so
the manual path that already works is unchanged — this just removes the "did it
even work?" confusion.

Renamed the local `staged` array to `collected` to free `staged` for the state
flag. Balance + selectors checked. NEEDS A NEW iOS BUILD (native change).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 16:24:15 +05:30
Sravan 0a2c7376b9 feat(share): "Biz Connect" in the iOS share sheet — share a photo/file into a chat
Adds the reverse direction: share FROM Photos/Files/Safari INTO a Biz Connect
conversation. An app can only appear in the iOS share sheet as an app-extension
target, so this is real native work, not a web change.

Pieces:
- mobile/ios-share/ShareViewController.swift: a UI-less Share Extension. It stages
  the shared items into the App Group container and opens bizconnect://share. It
  deliberately does NOT reimplement the chat picker — that lives in the app, which
  already has the chat list, search and upload progress. Appends to the manifest
  (never overwrites), so sharing twice before opening the app loses nothing.
- mobile/scripts/add-share-extension.rb: injects the extension target into the
  Capacitor-generated Xcode project on every CI build (Codemagic checks out fresh),
  using the xcodeproj gem that ships with CocoaPods. Embeds it, sets the bundle id
  <app>.share, and MERGES the App Group into the app's entitlements rather than
  clobbering them (push's aps-environment must survive). Idempotent.
- mobile/plugins/share-inbox: getPending()/clear() to read that manifest — the App
  Group container isn't one of Filesystem's known directories, so it needs a bridge.
- home.html: on bizconnect://share (and every resume, and cold-launch), read the
  inbox and show a "Send to…" picker over the chat list; chosen files run the SAME
  upload + /api/messages send as an in-app attachment. Reuses convertFileSrc to read
  the staged bytes with no base64 marshalling.
- ios-patch.sh registers the bizconnect URL scheme; codemagic.yaml fetches a profile
  for the .share bundle id too.

One-time manual gate (CI cannot toggle App capabilities): the App Group
group.com.bizgaze.connect must be created and enabled on both App IDs in the Apple
portal — documented in mobile/IOS_SETUP.md. Without it the two processes can't see
each other's files and sharing silently no-ops; everything else still works.

Validated cross-file: pod-name/jsName/method wiring for all three plugins, App
Group id identical in all 4 files, URL scheme consistent across extension/plist/web,
entitlement-merge preserves push. Needs a new iOS build (new targets + plugins).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 22:58:08 +05:30