The selected companion everywhere, each with a small trait; next-APK notes
- state/companion.ts: one store for the chosen companion (also in localStorage so splash/login show it).
BrandMark (the orange «π» tile) now shows the companion's symbol (Σ Δ π ω) in its colour; screen-header
mascots, loaders and empty/error states default to it; the assistant is «از {name} بپرس» with its face,
colour and wording; the shop, lesson and quiz «ask» buttons name it; the active tab takes its tint.
- Traits, all client-side and light: Σ sigma keeps a running tally of correct answers in the quiz header;
Δ delta shows a flame «×N» chip and an extra buzz for answers in a row; π pi gives a short solving tip
after a wrong answer; ω omega throws gold confetti at the end of every island whatever the score.
Each companion's «correct» sound is pitched differently; confetti uses its colours. Characters screen
lists each trait.
- android/README.md: what MainActivity.kt has that the installed APK lacks (vibrate bridge, media gesture,
in-app gateway + paysInApp), what to check on a phone after building, signing owner, Bazaar policy note.
Checked in headless Chrome with Sigma, Delta and Omega selected (home, assistant, shop, characters, quiz).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
|
||||
import { api, type Character, type Grade, type HomeResponse, type UserProfile, type UserSummary } from '@/api';
|
||||
import { seyarFromSlug, type SeyarChar } from '@/mascots/seyar';
|
||||
import { companionStore, useCompanion } from '@/state/companion';
|
||||
|
||||
/**
|
||||
* دادههایی که چند صفحه با هم لازم دارند: پروفایل، آمار، نقشه، همراهِ انتخابی
|
||||
@@ -48,7 +49,9 @@ export function AppDataProvider({
|
||||
const [summary, setSummary] = useState<UserSummary | null>(prefetch?.summary ?? null);
|
||||
const [home, setHome] = useState<HomeResponse | null>(prefetch?.home ?? null);
|
||||
const [homeError, setHomeError] = useState<unknown>(null);
|
||||
const [companion, setCompanionChar] = useState<SeyarChar>('sigma');
|
||||
// همراه در companionStore است تا بیرون از AppData (اسپلش، نشان، لودرها) هم خوانده شود.
|
||||
const companion = useCompanion().char;
|
||||
const setCompanionChar = companionStore.set;
|
||||
const [unreadCount, setUnreadCount] = useState(0);
|
||||
|
||||
const refreshHome = useCallback(async () => {
|
||||
@@ -84,10 +87,10 @@ export function AppDataProvider({
|
||||
api.characters
|
||||
.list()
|
||||
.then((list) => {
|
||||
const selected = seyarFromSlug(list.find((c) => c.selected)?.slug);
|
||||
if (selected) setCompanionChar(selected);
|
||||
// بیانتخاب یعنی پیشفرضِ سرور (سیگما)؛ همراهِ کاربرِ قبلی روی این دستگاه نباید بماند.
|
||||
setCompanionChar(seyarFromSlug(list.find((c) => c.selected)?.slug) ?? 'sigma');
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch((err: unknown) => console.warn('companion lookup failed; keeping the stored one', err));
|
||||
// فقط بارِ اول؛ prefetch بعد از mount عوض نمیشود.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [refreshHome, refreshSummary, refreshUnread]);
|
||||
|
||||
Reference in New Issue
Block a user