* 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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqGPzXQ1AA9CqYHgCgmbtV
* decrease clutter in stream-view
* format
* format
* consolidate avatar
---------
Co-authored-by: Claude <noreply@anthropic.com>
* 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