* 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]>
When the local user sends a particle while positioned on the last one in a
stream, advance playback to the newly created particle so they stay caught up
and the stream isn't left in an unseen state. If they're browsing earlier
particles, their position is left untouched.
The mobile reducer only auto-advanced on PARTICLE_ADDED when status was
already "ended", so sending while sitting on (but not finished with) the last
particle left it unseen. This threads an onParticleCreated callback from
ComposeDock's default send paths up to StreamView, which follows the particle
via goToParticle only when currentIndex is the last slot — mirroring desktop's
StreamView.handleParticleCreated.
Co-authored-by: Claude <[email protected]>
More explicit feedback of the state of their upload. Also prevents
recording more media at the same time or interacting with the stream
which would feel stale to the human since they just created something
and it's yet to be present in the stream.
* 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