edit button with validator and YAML

This commit is contained in:
polv committed 2026-07-17 18:03:49 +07:00
1 parent ee87eeb616
commit 72cd3bcd09
8 files changed
+68 -35

No files matched your search

+2 -1
View File
@@ -29,5 +29,6 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.maxTokenizationLineLength": 2500
}
},
"vue3snippets.enable-compile-vue-file-on-did-save-code": false
}
@@ -15,15 +15,7 @@
import { useTemplateRef } from "vue";
import TTS from "./TTS.vue";
import AudioButton from "./AudioButton.vue";
export interface IVoc {
ko: string;
audio?: string;
en: string;
usages?: IVoc[];
notes?: string;
examples?: IVoc[];
}
import { IVoc } from "../types.ts";
defineProps<{
v: IVoc;
@@ -57,7 +57,7 @@
<nav>
<label v-for="c in vCats" :key="c">
<input type="checkbox" :name="c" checked @change="updateCats(c)" />
{{ c.replace("_", " ") }}
{{ c.replace(/_/g, " ") }}
</label>
</nav>
<nav>
@@ -99,8 +99,10 @@ import {
useTemplateRef,
watch,
} from "vue";
import SentenceAudio, { IVoc } from "./SentenceAudio.vue";
import yaml from "yaml";
import SentenceAudio from "./SentenceAudio.vue";
import { supabase } from "../supabase.ts";
import { IVoc, Voc } from "../types.ts";
const { fmKey = "vocabulary" } = defineProps<{
fmKey?: string;
@@ -157,7 +159,7 @@ watch(isKoFirst, () => {
watch(isEdit, () => {
if (isEdit.value) {
const { ko, ...vContent } = v.value;
vEditContent.value = JSON.stringify(vContent, null, 2);
vEditContent.value = yaml.stringify(vContent);
} else {
vEditContent.value = "";
}
@@ -240,7 +242,7 @@ function updateCats(cat: string) {
async function onVContentSave() {
const oldV = v.value;
const newV = { ko: oldV.ko, ...JSON.parse(vEditContent.value) };
const newV = Voc.parse({ ko: oldV.ko, ...yaml.parse(vEditContent.value) });
let key = "";
let vKey = oldV.ko;
@@ -257,7 +259,8 @@ async function onVContentSave() {
vCount.set(v.ko, i + 1);
if (oldV.ko === v.ko && oldV.en === v.en) {
key = k;
// TODO: handling multiple fmKey comma-separated
key = JSON.stringify([fmKey, k]);
vKey = vK;
vocabulary[k][i_vs] = newV;
+16
View File
@@ -0,0 +1,16 @@
import * as z from "zod";
export const Voc = z.object({
ko: z.string(),
audio: z.string().optional(),
en: z.string(),
get usage() {
return z.array(Voc).optional();
},
notes: z.string().optional(),
get examples() {
return z.array(Voc).optional();
},
});
export type IVoc = z.infer<typeof Voc>;
+4 -4
View File
@@ -420,7 +420,7 @@ vocabulary:
examples:
- ko: 우리 집은 너무 **멀어요**
en: Our home is very **far**
- ko: 저는 먼 병원에 갔어요
- ko: 저는 먼 **병원에** 갔어요
en: I went to a **far away** hospital (a hospital that is **far away**)
- ko: 마르다
@@ -440,7 +440,7 @@ vocabulary:
examples:
- ko: 저와 저의 아버지는 너무 **비슷해요**
en: My father and I are very **similar**
- ko: 저는 친구와 비슷해요
- ko: 저는 친구와 **비슷해요**
en: I am **similar** to my friend
- ko: 싫다
@@ -1245,7 +1245,7 @@ Example:
Example:
- &NoBreak;<TTS class="md">우리 집은 너무 **멀어요**</TTS> = <span class="md spoiler">Our home is very **far**</span>
- &NoBreak;<TTS class="md">저는 먼 병원에 갔어요</TTS> = <span class="md spoiler">I went to a **far away** hospital (a hospital that is **far away**)</span>
- &NoBreak;<TTS class="md">저는 먼 **병원에** 갔어요</TTS> = <span class="md spoiler">I went to a **far away** hospital (a hospital that is **far away**)</span>
</Details>
@@ -1274,7 +1274,7 @@ The pronunciation of this word is closer to “비스타다”
Examples:
- &NoBreak;<TTS class="md">저와 저의 아버지는 너무 **비슷해요**</TTS> = <span class="md spoiler">My father and I are very **similar**</span>
- &NoBreak;<TTS class="md">저는 친구와 비슷해요</TTS> = <span class="md spoiler">I am **similar** to my friend</span>
- &NoBreak;<TTS class="md">저는 친구와 **비슷해요**</TTS> = <span class="md spoiler">I am **similar** to my friend</span>
</Details>
+8 -8
View File
@@ -67,7 +67,7 @@ vocabulary:
audio: https://www.howtostudykorean.com/wp-content/uploads/2015/11/Lesson13v6.mp3
en: underground
examples:
- ko: 차는 지하 **주차장**에 있어요
- ko: 차는 **지하** 주차장에 있어요
en: The car is in the **underground** parking lot
- ko: 빵
@@ -80,7 +80,7 @@ vocabulary:
en: I made **bread** for my friend
- ko: 우리는 **빵**을 같이 먹었어요
en: We ate **bread** together
- ko: 애기는 **밥**하고 빵을 먹었어요
- ko: 애기는 밥하고 **빵**을 먹었어요
en: The baby ate rice and **bread**
- ko: 쓰레기
@@ -291,7 +291,7 @@ vocabulary:
examples:
- ko: 우리가 **늦**어서 죄송해요
en: Sorry we arrived **late**
- ko: 우리는 늦은 저녁을 먹었어요
- ko: 우리는 **늦**은 저녁을 먹었어요
en: We ate a **late** dinner
- ko: 그녀는 언제나 **늦**게 와요
en: She comes **late** every time
@@ -434,7 +434,7 @@ vocabulary:
en: I want to eat what we ate **(together)** last time
- ko: 이 일을 **같이** 하고 싶으면 우리는 협조해야 돼요
en: If we want to do this job **together**, we have to cooperate
- ko: 우리 학교에서 학생들은 역사와 지리를 같이 배워요
- ko: 우리 학교에서 학생들은 역사와 지리를 **같이** 배워요
en: At our school, students learn history and geography **together**
---
@@ -571,7 +571,7 @@ Common Usages:
Examples:
- 차는 지하 **주차장**에 있어요 = <span class="md spoiler">The car is in the **underground** parking lot</span>
- 차는 **지하** 주차장에 있어요 = <span class="md spoiler">The car is in the **underground** parking lot</span>
</Details>
@@ -589,7 +589,7 @@ Example:
- 저는 **빵**을 먹고 싶어요 = <span class="md spoiler">I want to eat **bread**</span>
- 저는 친구를 위해 **빵**을 만들었어요 = <span class="md spoiler">I made **bread** for my friend</span>
- 우리는 **빵**을 같이 먹었어요 = <span class="md spoiler">We ate **bread** together</span>
- 애기는 **밥**하고 빵을 먹었어요 = <span class="md spoiler">The baby ate rice and **bread**</span>
- 애기는 밥하고 **빵**을 먹었어요 = <span class="md spoiler">The baby ate rice and **bread**</span>
</Details>
@@ -927,7 +927,7 @@ This is often irrelevant, but 늦다 is both <span class="md spoiler">a verb and
It is often used as an adjective to describe a time that is late. For example:
- 우리는 늦은 저녁을 먹었어요 = <span class="md spoiler">We ate a **late** dinner</span>
- 우리는 **늦**은 저녁을 먹었어요 = <span class="md spoiler">We ate a **late** dinner</span>
As an adjective, ~게 is often added to it in order to create <span class="md spoiler">an adverb</span>. For example:
@@ -1136,7 +1136,7 @@ Examples:
- 엄마가 우리랑 **같이** 못 먹어서 안타까워요 = <span class="md spoiler">It’s too bad that your mom can’t eat **together** (with us)</span>
- 나는 우리가 지난 번에 **같이** 먹은 것을 먹고 싶어 = <span class="md spoiler">I want to eat what we ate **(together)** last time</span>
- 이 일을 **같이** 하고 싶으면 우리는 협조해야 돼요 = <span class="md spoiler">If we want to do this job **together**, we have to cooperate</span>
- 우리 학교에서 학생들은 역사와 지리를 같이 배워요 = <span class="md spoiler">At our school, students learn history and geography **together**</span>
- 우리 학교에서 학생들은 역사와 지리를 **같이** 배워요 = <span class="md spoiler">At our school, students learn history and geography **together**</span>
</Details>
+3 -1
View File
@@ -27,6 +27,8 @@
"dependencies": {
"@supabase/supabase-js": "^2.110.5",
"pdfjs-dist": "^5.7.284",
"tauri-plugin-tts-api": "^0.1.11"
"tauri-plugin-tts-api": "^0.1.11",
"yaml": "^2.9.0",
"zod": "^4.4.3"
}
}
+26 -7
View File
@@ -17,13 +17,19 @@ importers:
tauri-plugin-tts-api:
specifier: ^0.1.11
version: 0.1.11
yaml:
specifier: ^2.9.0
version: 2.9.0
zod:
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@tauri-apps/cli':
specifier: ^2.11.4
version: 2.11.4
vitepress:
specifier: 2.0.0-alpha.17
version: 2.0.0-alpha.17(postcss@8.5.16)
version: 2.0.0-alpha.17(postcss@8.5.16)(yaml@2.9.0)
vue:
specifier: ^3.5.39
version: 3.5.39
@@ -950,6 +956,14 @@ packages:
typescript:
optional: true
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
hasBin: true
zod@4.4.3:
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -1329,10 +1343,10 @@ snapshots:
'@ungap/structured-clone@1.3.2': {}
'@vitejs/plugin-vue@6.0.7(vite@7.3.6)(vue@3.5.39)':
'@vitejs/plugin-vue@6.0.7(vite@7.3.6(yaml@2.9.0))(vue@3.5.39)':
dependencies:
'@rolldown/pluginutils': 1.0.1
vite: 7.3.6
vite: 7.3.6(yaml@2.9.0)
vue: 3.5.39
'@vue/compiler-core@3.5.39':
@@ -1683,7 +1697,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
vite@7.3.6:
vite@7.3.6(yaml@2.9.0):
dependencies:
esbuild: 0.28.1
fdir: 6.5.0(picomatch@4.0.5)
@@ -1693,8 +1707,9 @@ snapshots:
tinyglobby: 0.2.17
optionalDependencies:
fsevents: 2.3.3
yaml: 2.9.0
vitepress@2.0.0-alpha.17(postcss@8.5.16):
vitepress@2.0.0-alpha.17(postcss@8.5.16)(yaml@2.9.0):
dependencies:
'@docsearch/css': 4.6.3
'@docsearch/js': 4.6.3
@@ -1704,7 +1719,7 @@ snapshots:
'@shikijs/transformers': 3.23.0
'@shikijs/types': 3.23.0
'@types/markdown-it': 14.1.2
'@vitejs/plugin-vue': 6.0.7(vite@7.3.6)(vue@3.5.39)
'@vitejs/plugin-vue': 6.0.7(vite@7.3.6(yaml@2.9.0))(vue@3.5.39)
'@vue/devtools-api': 8.1.5
'@vue/shared': 3.5.39
'@vueuse/core': 14.3.0(vue@3.5.39)
@@ -1713,7 +1728,7 @@ snapshots:
mark.js: 8.11.1
minisearch: 7.2.0
shiki: 3.23.0
vite: 7.3.6
vite: 7.3.6(yaml@2.9.0)
vue: 3.5.39
optionalDependencies:
postcss: 8.5.16
@@ -1750,4 +1765,8 @@ snapshots:
'@vue/server-renderer': 3.5.39(vue@3.5.39)
'@vue/shared': 3.5.39
yaml@2.9.0: {}
zod@4.4.3: {}
zwitch@2.0.4: {}