import { useSyncExternalStore } from 'react'; import { KEYS, store } from '@/lib/storage'; import { SEYAR_INFO, seyarFromSlug, type SeyarChar } from '@/mascots/seyar'; /** * همراهِ انتخابیِ کاربر، یک جا برای کلِ اپ: نشانِ سرِ خانه، ماسکوتِ سربرگ‌ها و لودرها، نام و چهره‌ی دستیار، و ویژگیِ * کوچکِ هر همراه. پیش‌تر هر صفحه همراهِ خودش را ثابت نوشته بود (فروشگاه و دستیار «پی»، درس‌ها «سیگما»، …) و انتخابِ * کاربر فقط در خانه و درس دیده می‌شد. * * در localStorage هم می‌ماند تا اسپلش و صفحه‌ی ورود پیش از رسیدنِ پاسخِ سرور همان همراه را نشان دهند؛ منبعِ حقیقت * همچنان سرور است (AppData بعد از ورود از /characters می‌خواند و این را به‌روز می‌کند). */ export interface CompanionLook { char: SeyarChar; name: string; symbol: string; /** رنگِ اصلی (بدنه‌ی ماسکوت) و رنگِ روشن‌ترِ کنارش، برای نشان و ته‌رنگ. */ color: string; light: string; /** ویژگیِ این همراه؛ در صفحه‌ی همراه‌ها نوشته شده و در آزمون دیده می‌شود (QuizScreen). */ trait: { title: string; text: string }; /** گامِ صدای «درست» نسبت به سیگما (نیم‌پرده)؛ هر همراه صدای خودش را دارد. */ pitch: number; } export const COMPANIONS: Record = { sigma: { char: 'sigma', name: SEYAR_INFO.sigma.name, symbol: 'Σ', color: '#4C5FD5', light: '#7A8CFF', pitch: 0, trait: { title: 'جمع‌زن', text: 'تو آزمون جوابای درستت رو یکی‌یکی برات جمع می‌زنه.' }, }, delta: { char: 'delta', name: SEYAR_INFO.delta.name, symbol: 'Δ', color: '#FF7A3D', light: '#FFB25E', pitch: 2, trait: { title: 'شعله سرعت', text: 'جوابای درست پشت هم رو آتیشی می‌کنه و تشویقت می‌کنه.' }, }, pi: { char: 'pi', name: SEYAR_INFO.pi.name, symbol: 'π', color: '#9B7BFF', light: '#C6B3FF', pitch: 4, trait: { title: 'راهنمای مهربون', text: 'وقتی غلط می‌زنی یه نکته کوچیک می‌گه که دفعه بعد گیر نکنی.' }, }, tedi: { char: 'tedi', name: SEYAR_INFO.tedi.name, symbol: 'ω', color: '#E8A400', light: '#FFC63D', pitch: 7, trait: { title: 'جشن‌ساز', text: 'آخر هر جزیره، هر نمره‌ای بگیری، برات جشن طلایی می‌گیره.' }, }, }; let current: SeyarChar = seyarFromSlug(store.get(KEYS.companion)) ?? 'sigma'; const listeners = new Set<() => void>(); export const companionStore = { get: () => current, set(char: SeyarChar) { if (char === current) return; current = char; store.set(KEYS.companion, char); listeners.forEach((l) => l()); }, subscribe(listener: () => void) { listeners.add(listener); return () => listeners.delete(listener); }, }; export function useCompanion(): CompanionLook { const char = useSyncExternalStore(companionStore.subscribe, companionStore.get, companionStore.get); return COMPANIONS[char]; } /** «من سیگمام»، «من پی‌ام». */ export function iAm(name: string): string { return name.endsWith('ی') ? `${name}‌ام` : `${name}م`; }