add dummy edit button
This commit is contained in:
1 parent
e682dfae6e
commit
7c48643759
1 file changed
+104
-2
@@ -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>
|
||||||
Reference in new issue
Block a user