From 7f2cdbe5da583010466d725197137f503e1fb771 Mon Sep 17 00:00:00 2001 From: polwex Date: Sat, 16 Aug 2025 15:50:10 +0700 Subject: damn good --- src/components/tones/ToneSelectorClient.tsx | 19 ++++++++++++++----- src/lib/db/prosodydb.ts | 4 ++-- src/lib/types/phonetics.ts | 25 +++++++++++++++++++++++++ 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(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) { ); } + console.log({ currentWord }); return (
@@ -242,7 +245,10 @@ function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) { }`} > {/* Front */} -
+

Current Word

@@ -256,7 +262,10 @@ function Inner({ isLoading, currentWord, goPrev, goNext }: IProps) {
{/* Back */} -
+

Details

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) { + fetchWordsByToneAndSyls(tones: Array): 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; 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 = { + "˧": "mid", + "˨˩": "low", + "˥˩": "falling", + "˦˥": "high", + "˩˩˦": "rising", +}; +export const thaiToneNums: Record = { + "˧": 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 ; } -- cgit v1.2.3