mirror of
https://github.com/tiennm99/loto.git
synced 2026-10-11 03:13:40 +00:00
Plans were split across three trees: plans/, web/plans/, and android/plans/. Merge them into plans/ at the repo root. Sweep the shipped Android experience pass and the two reports for it, carrying the residual forward into plans/todo.md: the device QA checklist (open only because this environment has no device or emulator), the clipped web PWA icons defect, and the untested native assumptions. Merge android/plans/todo.md in the same pass, dropping items the experience pass already delivered -- haptics, back button, safe-area insets, launcher icon, and splash -- each verified against MainActivity.java, web/src/app.css, and the res/ tree. Correct two stale claims while merging: web/ is a plain directory in this monorepo, not a git submodule, and the serialize-javascript override is held by @rollup/plugin-terser rather than workbox-build. The retired native Kotlin/Compose port plan moves as-is; it is superseded by the Capacitor wrapper but not yet swept.
6.5 KiB
6.5 KiB
Xia Recon — Upstream tiennm99/loto → Android port sync
Source manifest
- Repo:
tiennm99/loto(SvelteKit web app, Svelte 5 + Vite 7) - Branch:
main - Local clone:
/config/workspace/tiennm99/loto - Latest commit at recon:
2fb35f2(2026-04-29 14:53 +0700) - Port baseline: Android
fe52232(2026-04-27 19:33 +0700) — bundles upstream throughad6291e(2026-04-27 18:57) - Window of drift: 2026-04-27 19:33 → 2026-04-29 14:53 (≈ 44 h, 15 commits)
Source map (logic-relevant)
src/lib/game-logic.js— pure card gen, persistence, row helperssrc/lib/auto-tick.js— pure helper for master→player auto-tick (NEW since baseline)src/lib/call-bus.svelte.js— one-slot bussrc/lib/settings-store.svelte.js— settings + DOM applysrc/lib/voice.js— bundled-MP3 playbacksrc/lib/vietnamese-number.js— number-to-wordssrc/lib/PlayerBoard.svelte— player UI + bingo/chờ statesrc/lib/MasterPanel.svelte— host UIsrc/lib/SettingsButton.svelte— settings modalsrc/app.css— palette, animations, decorative borders
Local map (Android)
game/GameLogic.kt,game/VietnameseNumber.kt— pure logicstate/CallBus.kt,state/PlayerBoardViewModel.kt,state/MasterPanelViewModel.kt— coroutine stateaudio/VoicePlayer.kt,audio/VoiceManifest.ktsettings/SettingsRepository.kt,settings/SettingsState.ktui/board/*,ui/master/*,ui/settings/*,ui/theme/*
Drift analysis
Commits on/after port baseline (15 total). Filtered to logic/UX-relevant:
| Commit | Subject | Layer | Port? |
|---|---|---|---|
2fb35f2 |
drop gradients, solid-color palette | UI | YES |
a60ea08 |
persistent Chờ ring + livelier confetti | UI + tier | YES |
2b74b2e |
"Cả hai" glyph + sticky title/footer | settings UI | PART |
3e6cb90 |
extract auto-tick into pure helper + tests | refactor | OPT |
ee71bf0 |
per-mode voice hint copy (+ PWA fixes) | copy | YES |
f7db20c |
UI polish v2 + PWA | UI + web | DONE |
9f24b6d |
PWA cache eviction tighten | web only | NO |
7c893aa |
CSP sha256 hash | web only | NO |
558d0c7 |
inline-script guard | web only | NO |
d94294d |
npm vuln overrides | web only | NO |
| chore(plans) ×4 | plan docs | - | NO |
Behavior delta (the part that matters)
1. Confetti tier rule (PlayerBoardViewModel.kt:166)
- Was:
tier = 2 if celebratedRows.size >= 3 else 1 - Now:
tier = 2 if celebratedRows.size >= 2 OR (celebratedRows.size >= 1 AND any other row in Chờ) else 1 - Reason: 9-row card rarely hits 3 bingos; old threshold under-celebrated wins.
2. Confetti emoji + size
- Add
🥢 🎋 🏮to set; per-piece size jitter 1.5–2.4rem (sp).
3. Section Chờ ring
- New
sectionHasWaiting[3]derived flag — true iff any of its 3 rows is one cell from bingo and not yet completed. Section label gets persistent amber ring/glow (animation respects reduced-motion).
4. Per-mode voice-master hint
- Mode =
both→ hint: "Đọc số đã xổ + báo Chờ/Kinh." - Mode =
master→ hint: "Đọc số đã xổ." - Currently Android has no hint at all under the master-voice toggle.
5. Solid-color palette
- Drop every gradient (Wordmark stays — it's the only intentional brand gradient). Use solid: rose-600 (player+UI), amber-600 (host), emerald-600 (draw), sky-600 (master ≤49).
- Replaces master ≤49 pink → sky.
- Player accent: indigo → rose.
- "Ván mới" amber→rose gradient → solid amber-600.
- Background warmer cream
#fffbeb(light only).
6. Auto-tick pure helper (optional)
- Upstream extracted
processAutoTick({grid, crossed, lastDraw, lastHandledAt, mode})intosrc/lib/auto-tick.js. - Android
PlayerBoardViewModel.consumeBusEventalready implements the same dedup-by-id invariant. Optional refactor for unit-testability parity.
7. Settings sticky title/footer
- Web fix for iPhone SE viewport (375×667).
- Android:
ModalBottomSheetalready gives system-pinned drag handle- scroll behavior — same problem already solved by the platform. Skip.
8. "Cả hai" glyph
- Web mode picker has SVG glyphs; Android
ModePickeris text-only (SegmentedButton+Text). Skip.
Decision matrix
| Decision | Source's way | Local equivalent | Recommendation |
|---|---|---|---|
| Confetti tier | 2nd OR (1st + Chờ) | 3+ | Port (P0 — game feel) |
| Confetti emoji+size | + hội-chợ + jitter | base set, fixed 20.sp | Port (P1) |
| Section Chờ ring | amber pulsing band | - | Port (P1) |
| Voice-master hint copy | per-mode | (no hint shown) | Port (P2) |
| Solid-color palette | rose/amber/emerald/sky | rose/amber/emerald/pink+gr | Port (P1) |
| Auto-tick helper | extracted pure fn | inline in VM (semantics ✓) | Optional (P3) |
| Sticky modal bands | sticky CSS | ModalBottomSheet (native) | Skip |
| "Cả hai" glyph | inline SVG | text-only segment | Skip |
Risk score
Low. No data-shape changes; no migration. All ports are additive (new state field, new strings, new colors) or threshold tweaks. Tests cover the existing tier rule — must update fixtures to the new threshold. No risk to DataStore schema, audio assets, or audio-call coordination.
Approach
--port mode: rewrite idiomatically for Compose/Kotlin. No transplanting
Svelte/CSS — the visual outcomes get expressed in Compose primitives.
Open questions
- Should the Confetti emoji set still ship with
🥢 🎋 🏮on devices where the system font lacks coverage? Android default fonts since API 24 cover these. No action, but revisit if QA reports tofu glyphs on older OEM builds. - The amber pulsing ring uses
prefers-reduced-motion. Compose has no direct equivalent; recommend gating onLocalAccessibilityManager.currentreduce-motion or simply using a static glow (no animation) — defer to phase-02 implementation choice.