14 Commits
Author SHA1 Message Date
3d80ac2993 feat: increase feature parity between mobile and desktop (#298)
* mobile: add invitations, network creation, and settings (parity phase 1)

Surface backend capabilities that already existed in the mobile API client
but had no UI:

- NetworkListScreen now lists pending invitations with an Accept action and
  a header "+" to create a network; empty state offers creation instead of
  pointing users to desktop.
- New CreateNetworkSheet and use-invitations hooks (accept invite, create
  network) following the existing react-query patterns.
- SettingsScreen replaces its placeholder with an email-notifications toggle
  (optimistic, mirrors desktop), app version, and sign out.
- Wire the previously-unreachable Settings row into the Drawer.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* mobile: network member management and avatars (parity phase 2)

- New NetworkSettingsScreen (reachable from the stream-list header) lists
  members with admin remove, an invite-by-email sheet, and pending
  invitations with revoke — backed by new use-member-management hooks.
- Avatars: add avatar_object_id to HumanSchema, uploadAvatar/deleteAvatar/
  getAvatarDownloadUrl client methods (raw PUT via expo-file-system), a
  use-avatar-url hook, and image rendering in the shared Avatar component.
  AccountScreen gains a tap-to-change profile picture via expo-image-picker.
- auth-store gains refreshUser to pick up avatar changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* mobile: task particles — view, edit, and compose (parity phase 3)

Bring the task particle to parity with desktop's richer model:

- Replace the thin `quest` schema with desktop's `task` model
  (ChecklistItem, TaskProperties: title/notes/checklist/assigned_to/done)
  in the discriminated union, the Firestore converter, and consumers
  (StreamCard, FallbackParticleView).
- New TaskParticleView renders an editable card (round done checkbox,
  title, notes, checklist with add/toggle/edit/remove, assignee chips)
  persisting each edit to Firestore; an 8s dwell auto-advances and
  field focus suspends playback. Wired into StreamView's render switch.
- Compose: a task button in the ComposeDock opens a TaskComposeSheet
  (createTaskParticle helper). Gated off in the new-stream flow, where a
  stream's first particle must be text or media.

Note: particles are written client-side to Firestore, matching desktop;
Orion's REST validator still only accepts `quest`, which is a pre-existing
inconsistency to reconcile backend-side separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* mobile: paper and file particle views (parity phase 4)

- Extract the shared markdown renderer/theme out of TextParticleView into
  a reusable MarkdownBody component (DRY).
- PaperParticleView renders desktop-authored documents (title + markdown)
  with a length-based dwell.
- FileParticleView shows name/size and a Download action that opens a
  signed URL via the OS.
- Both wired into StreamView's render switch; FallbackParticleView is now a
  true catch-all for unknown/folder types only.

Deferred (documented for a follow-up phase): composing papers/files from
mobile, particle attachments + lightbox, and link previews in text.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* mobile: billing & usage in network settings (parity phase 5)

Surface the network plan, daily usage, and Stripe management — all backed
by client methods that already existed. New use-billing hooks and a
BillingSection (mirroring desktop): every member sees the plan + usage
summary; admins get cadence selection + "Upgrade to Pro" (checkout) and
"Manage subscription" (portal), opening Stripe in the system browser.
Added to NetworkSettingsScreen.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* mobile: let users dismiss the keyboard from a task card

Focusing a task field opened the keyboard with no way out — it covered the
card and the stream's tap-to-advance zones. Now:

- A "Done" pill appears at the card's top-right while editing (reusing the
  existing `editing` flag) and calls Keyboard.dismiss(); the title row
  reserves space so the pill never overlaps a long title.
- The card ScrollView gains keyboardDismissMode (interactive on iOS, on-drag
  on Android) so dragging the card also dismisses the keyboard.

Dismissing blurs the active field, which flips `editing` off and resumes the
dwell timer and tap navigation automatically.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV

* decrease clutter in stream-view

* format

* format

* consolidate avatar

---------

Co-authored-by: Claude <[email protected]>
2026-06-21 10:38:16 -07:00
Arjun PatelandGitHub 79cc14490a chore: bump mobile version to v0.6.1 (#235) 2026-06-02 08:40:36 -07:00
Arjun PatelandGitHub a8a0b7db1b infra: add linting and formatting for js projects (#230)
* wip

* wip

* wip

* format

* wip(mobile): lint and format

* cleanup

* nits

* nits

* idiomatic react

* nit

* format all root files
2026-06-02 07:44:24 -07:00
Arjun Patel 613a350292 chore: bump versions 2026-05-30 11:12:08 -07:00
2eba834838 feat: use inline markdown editor (#227)
* Use inline WYSIWYG markdown editor for long text messages

Desktop: replace the Write/Preview tab toggle in the compose card with
MDXEditor, an inline WYSIWYG that renders markdown as you type (Obsidian/
Notion feel) and round-trips plain markdown, matching how particle content
is stored. Immersive mode is unchanged — short, plain notes still get the
centered large-type textarea, and ⌘+M still drops into the rich editor.
Shortcut handling moves to the capture phase so ⌘+Enter / Esc win over the
editor's own key handling.

Mobile: render markdown on the display side via react-native-marked's
useMarkdown hook (no FlatList, so it nests cleanly in the existing
ScrollView). Mirrors desktop's immersive-vs-card logic: short plain notes
stay centered; anything with markdown renders formatted instead of showing
raw syntax. Composer stays plain text.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* cleanup desktop app description

* Fix markdown editor rendering and pasted-link duplication

- Restore heading/list typography in the editor: MDXEditor relies on the
  browser's default styles for <h1>/<ul> sizing, which Tailwind's Preflight
  resets. Markdown shortcuts fired but the block looked unchanged. Style the
  editor content explicitly, mirroring the rendered display.
- Keep pasted/typed URLs as plain text (linkPlugin disableAutoLink) so they
  don't become `[url](url)`, which duplicated both the URL and its preview
  card. Also dedupe extractUrls defensively so a repeated URL yields one card.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* Complete GFM support: tables, task lists, strikethrough

Editor: add tablePlugin so markdown tables round-trip and render. Task
lists (`- [ ]`), strikethrough, code (inline + fenced), headings, lists,
quotes, and links already work via listsPlugin/core/markdownShortcut. CSS:
suppress the disc bullet on task-list items (they draw their own checkbox)
and style tables.

Display: render task-list checkboxes (no stray bullet), GFM tables, and
strikethrough so the read view matches what the editor produces.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* Unify markdown on one engine (Milkdown Crepe)

Replace the two-engine setup (MDXEditor for editing + react-markdown for
display) with a single Crepe-based component used for both. Editing is inline
WYSIWYG with full GFM that actually works — task lists, tables, and code
blocks via type-to-create / the slash menu — and read-only mode renders the
exact same way, so write and read can no longer drift (the root cause of the
heading/list/table/checkbox bugs).

- markdown-editor.tsx: Crepe wrapper supporting edit + readOnly, themed to the
  glass card via --crepe-* variable overrides (scoped to .milkdown so they win
  over frame-dark's own definitions).
- text-particle-view.tsx: render the message card with the read-only editor;
  drop the react-markdown component map.
- Remove now-unused deps: @mdxeditor/editor, react-markdown, remark-gfm,
  rehype-highlight, highlight.js.

The compose immersive mode (short, centered plain text) is unchanged.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* Fix Crepe slash-menu transparency and match the app font

The floating menus (slash menu, toolbar, link tooltip) portal to <body>,
outside .milkdown, so the --crepe-* overrides never reached them and their
background fell back to transparent — unreadable over the content. Declare the
palette on those selectors too, keep --crepe-color-surface (near-)opaque so the
menus read clearly, and add a backdrop blur.

Also set --crepe-font-default/title to inherit (and a monospace stack for code)
so the editor uses the application font instead of Crepe's bundled Noto faces.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* Give the slash menu the full card by padding the editor, not the card

Crepe appends the slash menu to .milkdown and (in this version) doesn't expose
a way to portal it to <body>, so it's clipped by the editor's scroll box. That
box sat inside the card's p-5 padding, so the menu cut off at the padding edge.
Move the padding onto the ProseMirror content instead and drop the redundant
inner scroll container, so the menu's clipping bounds become the full card.

https://claude.ai/code/session_019DU6V5z6Nr4Vu7b1fBDnq4

* tweaks

* mobile: render markdown text consistent with desktop

---------

Co-authored-by: Claude <[email protected]>
2026-05-30 11:10:49 -07:00
Arjun Patel 9645391f6a chore: bump version 2026-05-28 12:46:03 -07:00
Arjun Patel 72bc41733f chore: bump version 2026-05-26 17:22:38 -07:00
96f5a727d6 feat(mobile): add support for huddles to mobile app (#219)
* feat(mobile): add huddles with LiveKit

Mirrors the desktop huddle window: tap the headphones button on a stream
to fetch a LiveKit token from Orion and join a video room. Active huddles
show a red badge on the stream card (participant count) and a red Join
pill in the stream top bar — both driven by huddle_active_participants
synced from the LiveKit webhook.

The HuddleScreen lives at its own route (not a modal/window): video tile
grid with placeholders for camera-off, mic/camera toggles, and a leave
button. Adds the LiveKit RN SDK plus the WebRTC + LiveKit Expo config
plugins for prebuild.

https://claude.ai/code/session_01Po5tAD17MXhnqGQ9hKh6PC

* fix(mobile): exiting from huddle

* fix: pause stream during huddle

---------

Co-authored-by: Claude <[email protected]>
2026-05-26 16:37:37 -07:00
Arjun Patel 54bc77444b chore: bump version 2026-05-26 10:27:09 -07:00
Arjun PatelandGitHub d262f734f0 Mobile notifications for iOS (#210)
* mobile: wire notification registration and listener

* implement backend components for push notifications

* refactor: agentic comment cleanup

* docs: use proper module name for particle processor

* set required env variables for push notifications

* bump version

* fix: always upsert push token on mobile start

* Revert "fix: always upsert push token on mobile start"

This reverts commit 90ff18a788.

* send push notifications regardless of online status
2026-05-18 12:44:31 -07:00
talksik 9fd28e26a0 bump version 2026-05-17 16:52:09 -07:00
talksik 4b468ed1ae chore: bump version 2026-05-01 09:24:07 -07:00
talksik 127c57fa7c chore: bump version 2026-04-30 18:21:14 -07:00
Arjun PatelandGitHub e3461dd5cd mobile v0.1 with deployment for ios (#191)
* stage 1: project init

* stage 2: skeleton with navigation

* step 2.5: streams list

* step 4: stream playback experience

* step 5-6: compose experience

* fix: broken record

* transcode media particles to mp4

* build: reproducible go generate

* build: rename skaffold module for particle processor worker

* infra: increase particle processor worker resources

Was dealing with OOM errors

* tweaks to mobile

* log transcode work

* view on desktop placeholder

* tweak padding

* cap video resolution to save on memory

* infra: bump memory limits as insurance

* ux improvements

* update bundle id for mobile

* config for mobile
2026-04-29 17:39:11 -07:00