Mobile app map
Expo Router app at apps/mobile/. Path alias @/ → src/.
Screens → data
| Screen | Route file | Primary data / hooks |
|---|---|---|
| Home | (tabs)/index.tsx |
useApp() — dueCount, profile |
| Stats | (tabs)/stats.tsx |
useApp() — radar, statsSummary |
| Study list | (tabs)/study-list.tsx |
repositories.getStudyItems() |
| Explore | (tabs)/explore.tsx |
Daily quiz entry, featured feed (mocks/featured.ts), browse → catalog |
| Explore catalog | explore/catalog.tsx |
repositories.getModules(), pathways |
| Daily quiz | quiz/daily.tsx, quiz/session.tsx, quiz/complete.tsx |
QuizRepository — no SRS/XP |
| Featured detail | featured/[id].tsx |
Mock featured items; Markdown in-app |
| Users | (tabs)/users.tsx |
useApp() — profile; mocks/subscription.ts — plans/pricing; setSubscriptionTier() |
| Onboarding | onboarding.tsx |
completeOnboarding() |
| Module detail | module/[slug].tsx |
Content + progress repos |
| Pathway detail | pathway/[slug].tsx |
Content repo |
| Review session | review/session.tsx |
Due cards, submitReview() — affects SRS, XP, streak |
| Review complete | review/complete.tsx |
SRS session summary |
| Social profile | social/profile/[id].tsx |
Mock social data |
Components (reusable)
| Component | Role |
|---|---|
Screen.tsx |
Page wrapper (safe area, padding) |
QuizCardContent.tsx |
One-off quiz card UI (MCQ/cloze) |
FeaturedFeedCard.tsx |
Explore featured feed row |
MarkdownBody.tsx |
In-app Markdown for featured articles |
RadarChart.tsx |
Six-axis radar visualization |
SwipeReviewCard.tsx |
Review card UI + swipe gestures |
CustomTabBar.tsx |
Bottom tab bar |
SwipeableTabPager.tsx |
Horizontal swipe pager with parallax (social sub-tabs) |
ParallaxScene.tsx |
Parallax opacity/translate wrapper for tab scenes |
tabNavigation.ts |
Shared tab gesture & transition constants |
SocialMenuSheet.tsx |
Social menu overlay (swipeable sub-tabs) |
SocialMenuButton.tsx |
Trigger for social sheet |
FoxAvatar.tsx |
Avatar display |
WebUnsupported.tsx |
Shown when Platform.OS === ‘web’ |
Context
| Context | Provides |
|---|---|
AppContext |
ready, profile, radar, statsSummary, dueCount, refresh() |
SocialMenuContext |
Social sheet open/close state |
Theme & copy
src/theme/colors.ts— color tokenssrc/hooks/useTheme.ts— light/dark aware colorssrc/i18n/zh-TW.ts— UI strings (Traditional Chinese)
Mock data (v0.1)
| Module | Path | Purpose |
|---|---|---|
| Social | src/mocks/social.ts |
Friends, leaderboard, groups — used by SocialMenuSheet, social/profile/[id] |
| Subscription | src/mocks/subscription.ts |
Three tiers (探索者 / 學者 / 哲人), HKD pricing — used by (tabs)/users.tsx |
| Featured | src/mocks/featured.ts |
Official + UGC featured articles/videos/quizzes — explore feed & detail |
Subscription tier is persisted in SQLite (user_profile.subscription_tier); mock file only defines display plans and prices. Change tier via repositories.setSubscriptionTier(tier) then refresh().
Daily quiz vs SRS review
Daily quiz (/quiz/*) |
SRS review (/review/*) |
|
|---|---|---|
| Card source | All cards (date-seeded 10) or featured mock IDs | Study list modules only |
| Subscription limits | Not counted | Daily new cards enforced |
| Persistence | daily_quiz_completions only |
user_card_states, review_events, XP |
| Outcome | Mock percentile | Due count, streak, radar |
Navigation notes
- Onboarding redirect logic in
app/_layout.tsx(RootNavigator) - Review screens use modal presentation
- Tab order in
(tabs)/_layout.tsx: stats → study-list → index (center) → explore → users - Main tabs use Material Top Tabs (
withLayoutContext) with bottomCustomTabBar; all 5 tabs support horizontal swipe - Social menu (
SocialMenuSheet) usesSwipeableTabPagerfor friends / ranking / groups sub-tabs with parallax transition - Shared tab transition constants in
tabNavigation.ts(ParallaxScene,SwipeableTabPager)