From 91ce77a6e7d723a725c16ab8e406c1c088977f4b Mon Sep 17 00:00:00 2001 From: Anggoran Date: Sat, 11 May 2024 18:57:09 +0700 Subject: [PATCH 1/6] edit: change syntax --- routes/reading/index.tsx | 12 +++--------- tests/main_test.ts | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/routes/reading/index.tsx b/routes/reading/index.tsx index 7f89afd..2534586 100644 --- a/routes/reading/index.tsx +++ b/routes/reading/index.tsx @@ -2,19 +2,13 @@ import { Handlers } from "$fresh/server.ts"; import { getReading, postReading } from "../../controllers/reading.ts"; export const handler: Handlers = { - async GET(req, ctx) { - return await getReading(req, ctx); - }, - async POST(req, ctx) { - return await postReading(req, ctx); - }, + GET: (req, ctx) => getReading(req, ctx), + POST: async (req, ctx) => await postReading(req, ctx), }; export default function ReadingPage() { return ( -
+
diff --git a/tests/main_test.ts b/tests/main_test.ts index c1c3e73..e92e343 100644 --- a/tests/main_test.ts +++ b/tests/main_test.ts @@ -1,10 +1,25 @@ -import { ServeHandlerInfo } from "$fresh/server.ts"; -import { listeningTest } from "./listening.ts"; -import { readingTest } from "./reading.ts"; +import { createHandler, ServeHandlerInfo } from "$fresh/server.ts"; +import manifest from "../fresh.gen.ts"; +import config from "../fresh.config.ts"; +import * as listening from "./listening.ts"; +import * as reading from "./reading.ts"; -const CONNECTION: ServeHandlerInfo = { +export const CONNECTION: ServeHandlerInfo = { remoteAddr: { hostname: "localhost", port: 8000, transport: "tcp" }, }; +export const handler = await createHandler(manifest, config); -listeningTest(CONNECTION); -readingTest(CONNECTION); +Deno.test("Feature: Listening Pinyin", async (t) => { + await t.step("Get the question", listening.getQuestion); + await t.step("Post the answer", listening.postAnswer); + await t.step("Get the correct state", listening.getCorrectState); + await t.step("Get the false state", listening.getFalseState); +}); + +Deno.test("Feature: Reading Hanzi", async (t) => { + await t.step("Render creation form", reading.renderCreationForm); + await t.step("Start a quiz", reading.startQuiz); + await t.step("Post the answer", reading.postAnswer); + await t.step("Get correct state", reading.getCorrectState); + await t.step("Get false state", reading.getFalseState); +}); From 9bba3069073c8b2611a73b3fa0efaef70b6e0f75 Mon Sep 17 00:00:00 2001 From: Anggoran Date: Sat, 11 May 2024 18:57:33 +0700 Subject: [PATCH 2/6] remove: pinyin randomization --- utils/randomize.ts | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 utils/randomize.ts diff --git a/utils/randomize.ts b/utils/randomize.ts deleted file mode 100644 index d339209..0000000 --- a/utils/randomize.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PinyinModel } from "../models/pinyin.ts"; - -export const randomize = (data: PinyinModel[]) => { - const random = Math.random() * (data.length - 1) + 1; - const result = Math.floor(random); - return data.find((item) => item.id == result)!; -}; From 6c265baa19704f9dfad2a781cfef2f697509e5fd Mon Sep 17 00:00:00 2001 From: Anggoran Date: Sat, 11 May 2024 18:57:59 +0700 Subject: [PATCH 3/6] add: read txt --- utils/read-txt.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 utils/read-txt.ts diff --git a/utils/read-txt.ts b/utils/read-txt.ts new file mode 100644 index 0000000..e47645f --- /dev/null +++ b/utils/read-txt.ts @@ -0,0 +1,7 @@ +export const readTXT = async ( + data: string, +) => { + const name = Deno.cwd() + `/static/data/${data}.txt`; + const content = await Deno.readTextFile(name); + return content.split("\n"); +}; From dd7bb2ea9e768b1a2f71c87f3e55660696e8c5f5 Mon Sep 17 00:00:00 2001 From: Anggoran Date: Sat, 11 May 2024 18:59:58 +0700 Subject: [PATCH 4/6] hotfix: hanzi listening --- controllers/listening.ts | 118 +++++++++++++++++++++---------------- routes/listening/index.tsx | 55 ++++++++--------- 2 files changed, 92 insertions(+), 81 deletions(-) diff --git a/controllers/listening.ts b/controllers/listening.ts index 96c7ceb..6f8a253 100644 --- a/controllers/listening.ts +++ b/controllers/listening.ts @@ -1,41 +1,56 @@ import { FreshContext } from "$fresh/server.ts"; -import { PinyinPartModel } from "../models/pinyin.ts"; +import { HanziModel, PinyinPartModel } from "../models/pinyin.ts"; import { PinyinModel } from "../models/pinyin.ts"; -import { randomize } from "../utils/randomize.ts"; import { readJSON } from "../utils/read-json.ts"; +import { readTXT } from "../utils/read-txt.ts"; export const getListening = async ( req: Request, ctx: FreshContext, ) => { const url = new URL(req.url); - const questionParams = url.searchParams.get("question"); - const answerParams = url.searchParams.get("answer"); - const truthParams = url.searchParams.get("truth"); - const pinyins: PinyinModel[] = await readJSON("pinyins"); - const initials: PinyinPartModel[] = await readJSON("initials"); - const finals: PinyinPartModel[] = await readJSON("finals"); - const tones: PinyinPartModel[] = await readJSON("tones"); - const question = pinyins.find((e) => e.name === questionParams) ?? - randomize(pinyins); - const { initial_id, final_id, tone_id } = - pinyins.find((e) => e.name === answerParams) ?? - { initial_id: 0, final_id: 0, tone_id: 0 }; - const answer = { initial_id, final_id, tone_id }; - const truth = truthParams === "true" - ? true - : truthParams === "false" - ? false - : null; + const params = { + question: url.searchParams.get("question"), + answer: url.searchParams.get("answer"), + }; + + const hanziTXT: string[] = await readTXT("hanzis"); + const pinyinJSON: PinyinModel[] = await readJSON("pinyins"); + const initialJSON: PinyinPartModel[] = await readJSON("initials"); + const finalJSON: PinyinPartModel[] = await readJSON("finals"); + const toneJSON: PinyinPartModel[] = await readJSON("tones"); + + const randomNumber = Math.floor(Math.random() * hanziTXT.length); + const randomHanzi: HanziModel = JSON.parse(hanziTXT[randomNumber]); + + let question = randomHanzi.character; + let answer = { initial_id: 0, final_id: 0, tone_id: 0 }; + let solution = null; + let truth = null; + + if (params.question !== null && params.answer !== null) { + const currentHanzi: HanziModel = JSON.parse( + hanziTXT.find((e) => e.includes(`"character":"${params.question}"`))!, + ); + const currentAnswer = pinyinJSON.find((e) => e.name === params.answer)!; + + question = currentHanzi.character; + answer = { ...currentAnswer }; + solution = currentHanzi.pinyin[0]; + truth = solution === currentAnswer.name; + } return ctx.render({ - pinyins, - initials, - finals, - tones, question, answer, + solution, truth, + options: { + pinyins: pinyinJSON, + initials: initialJSON, + finals: finalJSON, + tones: toneJSON, + }, }); }; @@ -45,36 +60,37 @@ export const postListening = async ( ) => { const url = new URL(req.url); const form = await req.formData(); - const pinyins: PinyinModel[] = await readJSON("pinyins"); - const initials: PinyinPartModel[] = await readJSON("initials"); - const finals: PinyinPartModel[] = await readJSON("finals"); - const tones: PinyinPartModel[] = await readJSON("tones"); - const question_id = form.get("question_id"); - const initial = form.get("initial"); - const final = form.get("final"); - const tone = form.get("tone"); - const question = pinyins.find((e) => e.id.toString() === (question_id!)); - const { initial_id, final_id, tone_id } = question!; - const solution = { initial_id, final_id, tone_id }; - const answer = { - initial_id: initials.find((e) => e.name == initial)!.id, - final_id: finals.find((e) => e.name == final)!.id, - tone_id: tones.find((e) => e.name == tone)!.id, + const entries = { + question: form.get("question"), + initial: form.get("initial"), + final: form.get("final"), + tone: form.get("tone"), }; - const proposed = pinyins.find((e) => - e.initial_id === answer.initial_id && - e.final_id === answer.final_id && - e.tone_id === answer.tone_id - ); - const myQuestion = encodeURIComponent(question!.name); - let myAnswer = "N.A."; + const hanziTXT: string[] = await readTXT("hanzis"); + const pinyinJSON: PinyinModel[] = await readJSON("pinyins"); + const initialJSON: PinyinPartModel[] = await readJSON("initials"); + const finalJSON: PinyinPartModel[] = await readJSON("finals"); + const toneJSON: PinyinPartModel[] = await readJSON("tones"); - if (proposed !== undefined) { - myAnswer = encodeURIComponent(proposed.name); - } + const rawHanzi = hanziTXT.find((e) => + e.includes(`"character":"${entries.question}"`) + )!; + const hanzi: HanziModel = JSON.parse(rawHanzi); + const questionURI = encodeURIComponent(hanzi.character); + + const rawAnswer = { + initial_id: initialJSON.find((e) => e.name == entries.initial)!.id, + final_id: finalJSON.find((e) => e.name == entries.final)!.id, + tone_id: toneJSON.find((e) => e.name == entries.tone)!.id, + }; + const answer = pinyinJSON.find((e) => + e.initial_id === rawAnswer.initial_id && + e.final_id === rawAnswer.final_id && + e.tone_id === rawAnswer.tone_id + ); + const answerURI = encodeURIComponent(answer?.name ?? "N.A."); - const params = `question=${myQuestion}&answer=${myAnswer}&` + - `truth=${JSON.stringify(solution) === JSON.stringify(answer)}`; + const params = `question=${questionURI}` + "&" + `answer=${answerURI}`; return Response.redirect(`${url}?${params}`, 303); }; diff --git a/routes/listening/index.tsx b/routes/listening/index.tsx index 5773707..890871f 100644 --- a/routes/listening/index.tsx +++ b/routes/listening/index.tsx @@ -1,4 +1,4 @@ -import { signal } from "@preact/signals"; +import { Signal, signal } from "@preact/signals"; import { Dropdown } from "../../islands/Dropdown.tsx"; import { Menu } from "../../islands/Menu.tsx"; import { SoundButton } from "../../islands/SoundButton.tsx"; @@ -12,30 +12,26 @@ import { import { getListening, postListening } from "../../controllers/listening.ts"; interface Data { - pinyins: PinyinModel[]; - initials: PinyinPartModel[]; - finals: PinyinPartModel[]; - tones: PinyinPartModel[]; - question: PinyinModel; + question: string; answer: AnswerModel; + solution: string | null; truth: boolean | null; + options: { + pinyins: PinyinModel[]; + initials: PinyinPartModel[]; + finals: PinyinPartModel[]; + tones: PinyinPartModel[]; + }; } export const handler: Handlers = { - async GET(req, ctx) { - return await getListening(req, ctx); - }, - async POST(req, ctx) { - return await postListening(req, ctx); - }, + GET: async (req, ctx) => await getListening(req, ctx), + POST: async (req, ctx) => await postListening(req, ctx), }; export default function ListeningPage(props: PageProps) { - const { pinyins, initials, finals, tones, question, answer, truth } = - props.data; - - const { initial_id, final_id, tone_id } = answer; - const myAnswer = signal({ initial_id, final_id, tone_id }); + const { question, answer, solution, truth, options } = props.data; + const answerState: Signal = signal({ ...answer }); return (
) { : "bg-white" } `} > -
+