add dummy edit button

This commit is contained in:
polv committed 2026-07-15 16:27:07 +07:00
1 parent e682dfae6e
commit 7c48643759
1 file changed
+104 -2
+104 -2
View File
@@ -1,7 +1,20 @@
<template> <template>
<div> <div>
<nav v-if="v"> <nav v-if="v">
<Teleport to="body">
<div v-if="isEdit" :class="$style.modal" ref="modal">
<nav>
<span> ko: {{ v.ko }} </span>
<div style="flex-grow: 1"></div>
<button type="button" @click="onVContentSave()">Save</button>
<button type="button" @click="isEdit = false">×</button>
</nav>
<textarea v-model="vEditContent" spellcheck="false"></textarea>
</div>
</Teleport>
<div :class="$style.mark"> <div :class="$style.mark">
<button type="button" name="edit" @click="isEdit = true">✎</button>
<button type="button" name="right" @click="mark(true)">✓</button> <button type="button" name="right" @click="mark(true)">✓</button>
<button <button
type="button" type="button"
@@ -77,7 +90,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { useData } from "vitepress"; import { useData } from "vitepress";
import { computed, nextTick, ref, useTemplateRef, watch } from "vue"; import {
computed,
nextTick,
onBeforeUnmount,
onMounted,
ref,
useTemplateRef,
watch,
} from "vue";
import SentenceAudio, { IVoc } from "./SentenceAudio.vue"; import SentenceAudio, { IVoc } from "./SentenceAudio.vue";
const { fmKey = "vocabulary" } = defineProps<{ const { fmKey = "vocabulary" } = defineProps<{
@@ -88,10 +109,15 @@ const vCats = ref<string[]>([]);
const vChosenCats = ref<string[]>([]); const vChosenCats = ref<string[]>([]);
const vList = ref<IVoc[]>([]); const vList = ref<IVoc[]>([]);
const vIndex = ref(-1); const vIndex = ref(-1);
const exIndex = ref(0);
const isEdit = ref(false);
const vEditContent = ref("");
const isAutoplayAudio = ref(true); const isAutoplayAudio = ref(true);
const isKoFirst = ref(true); const isKoFirst = ref(true);
const modalRef = useTemplateRef("modal");
const sentenceDetails = useTemplateRef("sdetails"); const sentenceDetails = useTemplateRef("sdetails");
const saud = useTemplateRef<InstanceType<typeof SentenceAudio>>("saud"); const saud = useTemplateRef<InstanceType<typeof SentenceAudio>>("saud");
const vaud = useTemplateRef<InstanceType<typeof SentenceAudio>>("vaud"); const vaud = useTemplateRef<InstanceType<typeof SentenceAudio>>("vaud");
@@ -100,7 +126,7 @@ const v = computed(() => vList.value[vIndex.value]);
const example = computed(() => { const example = computed(() => {
if (!v.value.examples?.length) return null; if (!v.value.examples?.length) return null;
const ex = v.value.examples; const ex = v.value.examples;
return ex[Math.floor(Math.random() * ex.length)]; return ex[exIndex.value];
}); });
const MAX_VOC = 5; const MAX_VOC = 5;
@@ -128,6 +154,15 @@ watch(isKoFirst, () => {
makeVList(); makeVList();
}); });
watch(isEdit, () => {
if (isEdit.value) {
const { ko, ...vContent } = v.value;
vEditContent.value = JSON.stringify(vContent, null, 2);
} else {
vEditContent.value = "";
}
});
function makeVList() { function makeVList() {
nextTick(() => { nextTick(() => {
if (sentenceDetails.value) { if (sentenceDetails.value) {
@@ -146,6 +181,9 @@ function makeVList() {
vIndex.value = Math.floor( vIndex.value = Math.floor(
Math.random() * Math.min(MAX_VOC, vList.value.length), Math.random() * Math.min(MAX_VOC, vList.value.length),
); );
const ex = v.value.examples;
exIndex.value = ex ? Math.floor(Math.random() * ex.length) : 0;
} }
function mark(isRight: boolean) { function mark(isRight: boolean) {
@@ -184,6 +222,9 @@ function mark(isRight: boolean) {
} else { } else {
vIndex.value = i; vIndex.value = i;
} }
const ex = v.value.examples;
exIndex.value = ex ? Math.floor(Math.random() * ex.length) : 0;
} }
function updateCats(cat: string) { function updateCats(cat: string) {
@@ -196,6 +237,35 @@ function updateCats(cat: string) {
makeVList(); makeVList();
} }
function onVContentSave() {
const newV = { ko: v.value.ko, ...JSON.parse(vEditContent.value) };
const newVList = [...vList.value];
newVList[vIndex.value] = newV;
vList.value = newVList;
isEdit.value = false;
}
function onModalClickOutside(ev: MouseEvent) {
if (!(ev.target instanceof HTMLElement)) return;
if (ev.target.matches('[name="edit"]')) return;
if (!modalRef.value) {
isEdit.value = false;
} else if (!modalRef.value.contains(ev.target.parentNode)) {
isEdit.value = false;
}
}
onMounted(() => {
document.addEventListener("click", onModalClickOutside);
});
onBeforeUnmount(() => {
document.addEventListener("click", onModalClickOutside);
});
</script> </script>
<style module> <style module>
@@ -275,4 +345,36 @@ function updateCats(cat: string) {
} }
} }
} }
.modal {
--margin-top: calc(120px + env(safe-area-inset-top));
position: absolute;
top: var(--margin-top);
left: 50%;
transform: translateX(-50%);
width: calc(100vw - 4em);
max-width: 1000px;
nav {
display: flex;
flex-direction: row;
background-color: rgba(128, 128, 128, 0.8);
padding: 0.5em;
border-radius: 0.5em 0.5em 0 0;
* + * {
margin-inline-start: 1em;
}
}
textarea {
width: 100%;
height: calc(90vh - var(--margin-top) - env(safe-area-inset-bottom));
padding: 1em;
border-radius: 0 0 0.5em 0.5em;
font-family: sans-serif;
resize: none;
}
}
</style> </style>