* 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]>
68 lines
2.3 KiB
JSON
68 lines
2.3 KiB
JSON
{
|
|
"name": "flowy-mobile",
|
|
"version": "0.6.1",
|
|
"private": true,
|
|
"main": "index.ts",
|
|
"scripts": {
|
|
"start": "expo start -c",
|
|
"ios": "expo run:ios --device",
|
|
"publish:ios": "eas build --platform ios --auto-submit && echo 'Go to App Store Connect and submit the testflight build for app review. Visit for more information: https://docs.expo.dev/submit/introduction/'",
|
|
"android": "expo run:android",
|
|
"compile": "tsc --noEmit",
|
|
"lint": "expo lint",
|
|
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\" \"*.{ts,tsx,js,cjs,json}\"",
|
|
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\" \"*.{ts,tsx,js,cjs,json}\""
|
|
},
|
|
"packageManager": "[email protected]",
|
|
"dependencies": {
|
|
"@config-plugins/react-native-webrtc": "^12.0.0",
|
|
"@livekit/react-native": "^2.7.5",
|
|
"@livekit/react-native-expo-plugin": "^1.0.2",
|
|
"@livekit/react-native-webrtc": "^144.1.0",
|
|
"@react-native-async-storage/async-storage": "2.2.0",
|
|
"@react-navigation/native": "^7.0.14",
|
|
"@react-navigation/native-stack": "^7.2.0",
|
|
"@tanstack/react-query": "^5.90.21",
|
|
"clsx": "^2.1.1",
|
|
"expo": "~54.0.0",
|
|
"expo-audio": "~1.0.13",
|
|
"expo-camera": "~17.0.10",
|
|
"expo-constants": "~18.0.13",
|
|
"expo-device": "~8.0.10",
|
|
"expo-file-system": "~19.0.16",
|
|
"expo-haptics": "~15.0.7",
|
|
"expo-image-picker": "~17.0.8",
|
|
"expo-notifications": "~0.32.17",
|
|
"expo-secure-store": "~15.0.8",
|
|
"expo-status-bar": "~3.0.9",
|
|
"expo-video": "~3.0.10",
|
|
"firebase": "^12.10.0",
|
|
"livekit-client": "^2.15.2",
|
|
"lucide-react-native": "^0.575.0",
|
|
"nativewind": "^4.1.23",
|
|
"react": "19.1.0",
|
|
"react-native": "0.81.5",
|
|
"react-native-gesture-handler": "~2.28.0",
|
|
"react-native-marked": "^8.1.0",
|
|
"react-native-reanimated": "~4.1.1",
|
|
"react-native-safe-area-context": "~5.6.0",
|
|
"react-native-screens": "~4.16.0",
|
|
"react-native-svg": "15.12.1",
|
|
"react-native-worklets": "0.5.1",
|
|
"sonner-native": "^0.21.0",
|
|
"tailwind-merge": "^3.5.0",
|
|
"zod": "^4.3.6",
|
|
"zustand": "^5.0.11"
|
|
},
|
|
"devDependencies": {
|
|
"@types/react": "~19.1.0",
|
|
"eslint": "^9",
|
|
"eslint-config-expo": "^56.0.4",
|
|
"eslint-config-prettier": "^10.1.8",
|
|
"expo-build-properties": "~1.0.10",
|
|
"prettier": "^3.8.3",
|
|
"tailwindcss": "^3.4.17",
|
|
"typescript": "~5.9.0"
|
|
}
|
|
}
|