diff options
author | polwex <polwex@sortug.com> | 2025-08-16 15:50:10 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-08-16 15:50:10 +0700 |
commit | 7f2cdbe5da583010466d725197137f503e1fb771 (patch) | |
tree | 09e10e50aed0fe3fc11139163fbca165fb9fe814 | |
parent | 274a7bbb1f82e99cdc9876f6d0de430585282797 (diff) |
damn good
-rw-r--r-- | src/components/tones/ToneSelectorClient.tsx | 19 | ||||
-rw-r--r-- | src/lib/db/prosodydb.ts | 4 | ||||
-rw-r--r-- | src/lib/types/phonetics.ts | 25 | ||||
-rw-r--r-- | src/pages/tones.tsx | 16 |
4 files changed, 55 insertions, 9 deletions
diff --git a/src/components/tones/ToneSelectorClient.tsx b/src/components/tones/ToneSelectorClient.tsx index 8abbd38..438fc8a 100644 --- a/src/components/tones/ToneSelectorClient.tsx +++ b/src/components/tones/ToneSelectorClient.tsx @@ -1,6 +1,7 @@ "use client"; import { Spinner } from "@/components/ui/spinner"; +import "../Flashcard/cards.css"; import { useState, useEffect, useTransition, useRef, useCallback } from "react"; import { WordData } from "@/zoom/logic/types"; import { @@ -25,7 +26,7 @@ import { } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { Skeleton } from "@/components/ui/skeleton"; // For loading state -import { MutationOrder, ToneQuery } from "@/lib/types/phonetics"; +import { MutationOrder, PhoneticData, ToneQuery } from "@/lib/types/phonetics"; import { ProsodySyllable } from "@/lib/types/cards"; import { ArrowLeft, ArrowRight, Volume2, FlipHorizontal2 } from "lucide-react"; @@ -131,9 +132,10 @@ export default function ToneSelectorClient({ initialData, initialTones, }: { - initialData: any[]; + initialData: PhoneticData[]; initialTones: ToneQuery; }) { + console.log({ initialData }); const [data, setData] = useState<any[]>(initialData); const [currentIdx, setCurrentIdx] = useState(0); const [isLoading, startTransition] = useTransition(); @@ -187,7 +189,7 @@ export default function ToneSelectorClient({ } type IProps = { isLoading: boolean; - currentWord: any; + currentWord: PhoneticData; goPrev: () => void; goNext: () => void; }; @@ -225,6 +227,7 @@ function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) { </Card> ); } + console.log({ currentWord }); return ( <div className="relative w-full max-w-2xl mx-auto h-100 perspective"> @@ -242,7 +245,10 @@ function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) { }`} > {/* Front */} - <div className="absolute inset-0 bg-white dark:bg-slate-800 rounded-xl backface-hidden flex flex-col"> + <div + id="frontside" + className="absolute inset-0 bg-white dark:bg-slate-800 rounded-xl backface-hidden flex flex-col" + > <div className="px-6 pt-6 pb-2"> <h3 className="text-center text-lg font-semibold">Current Word</h3> </div> @@ -256,7 +262,10 @@ function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) { </div> {/* Back */} - <div className="absolute inset-0 bg-slate-50 dark:bg-slate-700 rounded-xl backface-hidden rotate-y-180 flex flex-col"> + <div + id="backside" + className="absolute inset-0 bg-slate-50 dark:bg-slate-700 rounded-xl backface-hidden rotate-y-180 flex flex-col" + > <div className="px-6 pt-6 pb-2"> <h3 className="text-center text-lg font-semibold">Details</h3> </div> diff --git a/src/lib/db/prosodydb.ts b/src/lib/db/prosodydb.ts index fdadafb..513b195 100644 --- a/src/lib/db/prosodydb.ts +++ b/src/lib/db/prosodydb.ts @@ -1,5 +1,5 @@ import Database from "bun:sqlite"; -import { MutationOrder, Phoneme, Tone } from "../types/phonetics"; +import { MutationOrder, Phoneme, PhoneticData, Tone } from "../types/phonetics"; import { ProsodyWord, ProsodyWordDB } from "../types/cards"; type Str = string | null; type ItemType = "word" | "syllable" | "idiom"; @@ -101,7 +101,7 @@ class DatabaseHandler { return query.all(onset) as any[]; } // tones - fetchWordsByToneAndSyls(tones: Array<string | null>) { + fetchWordsByToneAndSyls(tones: Array<string | null>): PhoneticData[] { const toneString = tones .reduce((acc: string, item) => { if (!item) return `${acc},%`; diff --git a/src/lib/types/phonetics.ts b/src/lib/types/phonetics.ts index f7289c7..1d0db5a 100644 --- a/src/lib/types/phonetics.ts +++ b/src/lib/types/phonetics.ts @@ -24,3 +24,28 @@ export type Syllable = { export type ToneQuery = Array<string | null>; export type MutationType = { change: string } | { keep: string }; export type MutationOrder = MutationType[]; + +export type PhoneticData = { + word_id: number; + tone_sequence: string; + syllable_count: number; + syl_seq: string; + spelling: string; + ipa: string; + frequency: number; +}; + +export const thaiTones: Record<string, string> = { + "˧": "mid", + "˨˩": "low", + "˥˩": "falling", + "˦˥": "high", + "˩˩˦": "rising", +}; +export const thaiToneNums: Record<string, number> = { + "˧": 33, + "˨˩": 21, + "˥˩": 41, + "˦˥": 45, + "˩˩˦": 214, +}; diff --git a/src/pages/tones.tsx b/src/pages/tones.tsx index 8658401..20c1237 100644 --- a/src/pages/tones.tsx +++ b/src/pages/tones.tsx @@ -3,18 +3,30 @@ import { Suspense } from "react"; import { fetchWordsByToneAndSyllables } from "@/actions/tones"; import ToneSelectorClient from "@/components/tones/ToneSelectorClient"; import { Skeleton } from "@/components/ui/skeleton"; // For Suspense fallback +import { thaiTones } from "@/lib/types/phonetics"; +import { randomFromArray } from "@/lib/utils"; export const getConfig = async () => { return { render: "static", // Or 'dynamic' if you prefer SSR for every request }; }; +async function randomTones(tries = 0) { + const syllables = Math.floor(Math.random() * 5); + const toneStrings = Object.values(thaiTones); + const tones = Array.from(Array(syllables)).map((_) => + randomFromArray(toneStrings), + ); + console.log({ tones, toneStrings }); + const initialWords = await fetchWordsByToneAndSyllables(tones); + if (!initialWords || initialWords.length === 0) return randomTones(tries + 1); + else return {initialWords, tones}; +} // Function to fetch the initial word on the server async function InitialWordLoader() { // Fetch a random 1-syllable Thai word with any tone initially - const tones = ["falling", "falling"]; - const initialWords = await fetchWordsByToneAndSyllables(tones); + const {initialWords, tones]} = await randomTones(); return <ToneSelectorClient initialData={initialWords} initialTones={tones} />; } |