Skip to content

Commit

Permalink
Merge pull request #77 from anggoran/dev
Browse files Browse the repository at this point in the history
release/v0.5.1
  • Loading branch information
anggoran authored Nov 10, 2024
2 parents 2c10188 + 31dd991 commit 8200ec0
Show file tree
Hide file tree
Showing 34 changed files with 407 additions and 166,241 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
102 changes: 37 additions & 65 deletions controllers/listening.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,46 @@
import { FreshContext } from "$fresh/server.ts";
import { HanziModel, PinyinPartModel } from "../models/pinyin.ts";
import { PinyinModel } from "../models/pinyin.ts";
import { readJSON } from "../utils/read-json.ts";
import { readTXT } from "../utils/read-txt.ts";
import { supabase } from "../utils/supabase.ts";

export const getListening = async (
req: Request,
ctx: FreshContext,
) => {
const url = new URL(req.url);
const params = {
question: url.searchParams.get("question"),
answer: url.searchParams.get("answer"),
question: url.searchParams.get("q_id"),
answer: url.searchParams.get("a"),
};

const hanziTXT: string[] = await readTXT("unihan");
const pinyinJSON: PinyinModel[] = await readJSON("pinyins");
const initialJSON: PinyinPartModel[] = await readJSON("initials");
const finalJSON: PinyinPartModel[] = await readJSON("finals");
const toneJSON: PinyinPartModel[] = await readJSON("tones");
let hp: { id: string; form: string | null; sound: string | null };
let truth: boolean | undefined;

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;
if (params.answer) {
const { data } = await supabase.from("hanzis_pinyins")
.select("id, hanzi:hanzi_id (form), pinyin:pinyin_id (sound)")
.eq("id", params.question)
.single();
const hanzi = Array.isArray(data!.hanzi) ? data!.hanzi[0] : data!.hanzi;
const pinyin = Array.isArray(data!.pinyin) ? data!.pinyin[0] : data!.pinyin;
hp = { id: data!.id, form: hanzi.form, sound: pinyin.sound };
truth = pinyin.sound === params.answer;
} else {
const { count } = await supabase.from("hanzis_pinyins")
.select("*", { count: "exact" });
const randomNumber = Math.floor(Math.random() * count!);
const { data } = await supabase.from("hanzis_pinyins")
.select("id, hanzi:hanzi_id (form)")
.eq("id", randomNumber)
.single();
const hanzi = Array.isArray(data!.hanzi) ? data!.hanzi[0] : data!.hanzi;
hp = { id: data!.id, form: hanzi.form, sound: null };
}

return ctx.render({
question,
answer,
solution,
id: hp.id,
question: hp.form,
solution: hp.sound,
answer: params.answer,
truth,
options: {
pinyins: pinyinJSON,
initials: initialJSON,
finals: finalJSON,
tones: toneJSON,
},
});
};

Expand All @@ -61,36 +51,18 @@ export const postListening = async (
const url = new URL(req.url);
const form = await req.formData();
const entries = {
question: form.get("question"),
initial: form.get("initial"),
final: form.get("final"),
q_id: form.get("q_id"),
latin: form.get("latin"),
tone: form.get("tone"),
};

const hanziTXT: string[] = await readTXT("unihan");
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 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 { data } = await supabase.from("pinyins")
.select("sound")
.eq("latin", entries.latin).eq("tone", entries.tone)
.single();
const questionURI = encodeURIComponent(entries.q_id as string);
const answerURI = encodeURIComponent(data?.sound ?? "N.A.");

const params = `question=${questionURI}` + "&" + `answer=${answerURI}`;
const params = `q_id=${questionURI}` + "&" + `a=${answerURI}`;
return Response.redirect(`${url}?${params}`, 303);
};
149 changes: 73 additions & 76 deletions controllers/reading.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
import { FreshContext } from "$fresh/server.ts";
import { HanziModel, PinyinModel, PinyinPartModel } from "../models/pinyin.ts";
import { readJSON } from "../utils/read-json.ts";
import { readTXT } from "../utils/read-txt.ts";
import { supabase } from "../utils/supabase.ts";

export interface ReadingQuizProps {
id: string;
question: string;
answer: string | undefined;
hint: string;
solutions: string[];
truth: boolean | undefined;
}
interface HanziPinyinData {
id: string;
hanzi: {
form: string;
meaning: string;
};
pinyin: {
sound: string;
};
}

interface HanziData {
id: string;
form: string;
meaning: string;
}

export const getReading = (
_req: Request,
Expand All @@ -27,56 +50,48 @@ export const getReadingQuiz = async (
const url = new URL(req.url);
const params = {
quiz: ctx.params["quiz"],
question: url.searchParams.get("question"),
answer: url.searchParams.get("answer"),
question: url.searchParams.get("q_id"),
answer: url.searchParams.get("a"),
};

const hanziTXT: string[] = await readTXT("unihan");
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 hanziList = decodeURIComponent(params.quiz).split("");
const randomNumber = Math.floor(Math.random() * hanziList.length);
const randomHanzi: HanziModel = JSON.parse(
hanziTXT.find((e) =>
e.includes(`"character":"${hanziList[randomNumber]}"`)
)!,
);

let question = randomHanzi.character;
let hint = randomHanzi.definition;
let answer = { initial_id: 0, final_id: 0, tone_id: 0 };
let solution = null;
let truth = null;
let props: ReadingQuizProps;
let truth: boolean | undefined;

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;
hint = currentHanzi.definition;
answer = { ...currentAnswer };
solution = currentHanzi.pinyin[0];
truth = solution === currentAnswer.name;
if (params.answer) {
const res = await supabase.from("hanzis_pinyins")
.select("id, hanzi:hanzi_id (form, meaning), pinyin:pinyin_id (sound)")
.eq("hanzi_id", parseInt(params.question!))
.returns<HanziPinyinData[]>();
const [{ hanzi: { form, meaning } }] = res.data!;
const solutions = res.data!.map(({ pinyin: { sound } }) => sound);
truth = solutions.includes(params.answer);
props = {
id: params.question!,
question: form,
hint: meaning,
solutions,
answer: params.answer,
truth,
};
} else {
const hanziList = decodeURIComponent(params.quiz).split("");
const randomNumber = Math.floor(Math.random() * hanziList.length);
const res = await supabase.from("hanzis")
.select("id, form, meaning")
.eq("form", hanziList[randomNumber])
.returns<HanziData>()
.single();
const { id, form, meaning } = res.data!;
props = {
id,
question: form,
hint: meaning,
solutions: [],
answer: undefined,
truth: undefined,
};
}

return ctx.render({
question,
hint,
answer,
solution,
truth,
options: {
pinyins: pinyinJSON,
initials: initialJSON,
finals: finalJSON,
tones: toneJSON,
},
});
return ctx.render(props);
};

export const postReadingQuiz = async (
Expand All @@ -86,36 +101,18 @@ export const postReadingQuiz = async (
const url = new URL(req.url);
const form = await req.formData();
const entries = {
question: form.get("question"),
initial: form.get("initial"),
final: form.get("final"),
q_id: form.get("q_id"),
latin: form.get("latin"),
tone: form.get("tone"),
};

const hanziTXT: string[] = await readTXT("unihan");
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 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 { data } = await supabase.from("pinyins")
.select("sound")
.eq("latin", entries.latin).eq("tone", entries.tone)
.single();
const questionURI = encodeURIComponent(entries.q_id as string);
const answerURI = encodeURIComponent(data?.sound ?? "N.A.");

const params = `question=${questionURI}` + "&" + `answer=${answerURI}`;
const params = `q_id=${questionURI}` + "&" + `a=${answerURI}`;
return Response.redirect(`${url}?${params}`, 303);
};
5 changes: 5 additions & 0 deletions controllers/word.ts → controllers/search.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { WordModel } from "../models/hanzi.ts";
import { supabase } from "../utils/supabase.ts";

export const getLatinList = async ({ keyword }: { keyword: string }) => {
const { data } = await supabase.rpc("latin_search", { search_term: keyword });
return data!.map((e: { latin: string }) => e.latin);
};

export const getWordList = async (
{ keyword, scroll }: { keyword: string; scroll: number },
) => {
Expand Down
50 changes: 28 additions & 22 deletions controllers/writing.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import { FreshContext } from "$fresh/server.ts";
import { HanziModel } from "../models/pinyin.ts";
import { readTXT } from "../utils/read-txt.ts";
import { supabase } from "../utils/supabase.ts";

export interface WritingQuizProps {
form: string;
meaning: string;
sounds: string[];
}

interface HanziPinyinData {
id: string;
hanzi: {
form: string;
meaning: string;
};
pinyin: {
sound: string;
};
}

export const getWriting = (
_req: Request,
Expand Down Expand Up @@ -29,26 +45,16 @@ export const getWritingQuiz = async (
hanzi: url.searchParams.get("hanzi"),
};

const hanziTXT: string[] = await readTXT("unihan");

const hanziList = decodeURIComponent(params.quiz).split("");
const randomNumber = Math.floor(Math.random() * hanziList.length);
const randomHanzi: HanziModel = JSON.parse(
hanziTXT.find((e) =>
e.includes(`"character":"${hanziList[randomNumber]}"`)
)!,
);

let form = randomHanzi.character;
const sound = randomHanzi.pinyin[0];
const meaning = randomHanzi.definition;

if (params.hanzi !== null) {
const currentHanzi: HanziModel = JSON.parse(
hanziTXT.find((e) => e.includes(`"character":"${params.hanzi}"`))!,
);
form = currentHanzi.character;
}

return ctx.render({ form, sound, meaning });
const res = await supabase.from("hanzis_pinyins")
.select("id, hanzi:hanzis!inner (form, meaning), pinyin:pinyin_id (sound)")
.eq("hanzis.form", hanziList[randomNumber])
.returns<HanziPinyinData[]>();

const [{ hanzi }] = res.data!;
const sounds = res.data!.map(({ pinyin: { sound } }) => sound);
const props: WritingQuizProps = { ...hanzi, sounds };

return ctx.render(props);
};
Loading

0 comments on commit 8200ec0

Please sign in to comment.