persist LLM sentence explainer with supabase
This commit is contained in:
1 parent
e734d09039
commit
82b51c0703
2 files changed
+56
-10
No files matched your search
@@ -67,14 +67,24 @@
|
|||||||
<div v-else v-html="v.notes"></div>
|
<div v-else v-html="v.notes"></div>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<div v-if="example">
|
<div v-if="example">
|
||||||
<blockquote
|
<div v-if="exNotes">
|
||||||
v-if="exNotes"
|
<button
|
||||||
v-html="markdownIt.render(exNotes)"
|
type="button"
|
||||||
></blockquote>
|
@click="
|
||||||
<button type="button" v-else @click="explainSentence(example.ko)">
|
exNotes = '';
|
||||||
|
explainSentence(example.ko);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
New explanation
|
||||||
|
</button>
|
||||||
|
<blockquote v-html="markdownIt.render(exNotes)" />
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<button type="button" @click="explainSentence(example.ko)">
|
||||||
Explain sentence
|
Explain sentence
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</nav>
|
</nav>
|
||||||
<details :class="$style.options">
|
<details :class="$style.options">
|
||||||
@@ -168,7 +178,7 @@ const vaud = useTemplateRef<InstanceType<typeof SentenceAudio>>("vaud");
|
|||||||
|
|
||||||
const v = computed(() => vList.value[vIndex.value]);
|
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[exIndex.value];
|
return ex[exIndex.value];
|
||||||
});
|
});
|
||||||
@@ -200,6 +210,25 @@ watch(quizState, () => {
|
|||||||
saveQuizState();
|
saveQuizState();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(example, () => {
|
||||||
|
exNotes.value = "";
|
||||||
|
if (!example.value) return;
|
||||||
|
|
||||||
|
if (supabase) {
|
||||||
|
let { ko } = example.value;
|
||||||
|
ko = ko.replaceAll("**", "");
|
||||||
|
|
||||||
|
supabase
|
||||||
|
.from("sentence-explain")
|
||||||
|
.select<any, { explain: string }>("explain")
|
||||||
|
.eq("ko", ko)
|
||||||
|
.then((r) => {
|
||||||
|
if (!r.data?.[0]) return;
|
||||||
|
exNotes.value = r.data[0].explain;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const vocabulary: Record<string, IVoc[]> = {};
|
const vocabulary: Record<string, IVoc[]> = {};
|
||||||
|
|
||||||
for (const [k, vs] of Object.entries(
|
for (const [k, vs] of Object.entries(
|
||||||
@@ -400,7 +429,9 @@ const markdownIt = new MarkdownIt({
|
|||||||
typographer: true,
|
typographer: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
async function explainSentence(s: string) {
|
async function explainSentence(ko: string) {
|
||||||
|
ko = ko.replaceAll("**", "");
|
||||||
|
|
||||||
for await (const data of LLMstream({
|
for await (const data of LLMstream({
|
||||||
model: "deepseek-v4-flash",
|
model: "deepseek-v4-flash",
|
||||||
messages: [
|
messages: [
|
||||||
@@ -409,14 +440,29 @@ async function explainSentence(s: string) {
|
|||||||
content:
|
content:
|
||||||
"Explain how this sentence works in 500 characters. Give key vocabularies.",
|
"Explain how this sentence works in 500 characters. Give key vocabularies.",
|
||||||
},
|
},
|
||||||
{ role: "user", content: s },
|
{ role: "user", content: ko },
|
||||||
],
|
],
|
||||||
})) {
|
})) {
|
||||||
if (data.done) return;
|
if (data.done) break;
|
||||||
if (data.content) {
|
if (data.content) {
|
||||||
exNotes.value += data.content;
|
exNotes.value += data.content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (supabase) {
|
||||||
|
console.log(supabase);
|
||||||
|
const user_id = await supabase.auth.getUser().then((r) => r.data.user?.id);
|
||||||
|
console.log(user_id);
|
||||||
|
|
||||||
|
await supabase.from("sentence-explain").upsert(
|
||||||
|
{
|
||||||
|
user_id,
|
||||||
|
ko,
|
||||||
|
explain: exNotes.value,
|
||||||
|
},
|
||||||
|
{ onConflict: "ko,user_id" },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onModalClickOutside(ev: MouseEvent) {
|
function onModalClickOutside(ev: MouseEvent) {
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ vocabulary:
|
|||||||
audio: https://www.howtostudykorean.com/wp-content/uploads/2015/11/Lesson20v6.mp3
|
audio: https://www.howtostudykorean.com/wp-content/uploads/2015/11/Lesson20v6.mp3
|
||||||
en: powder
|
en: powder
|
||||||
examples:
|
examples:
|
||||||
- ko: 케이크 반죽에 **밀가루**를 넣으세요
|
- ko: 케이크 반죽에 밀**가루**를 넣으세요
|
||||||
en: Put some **flour** into the cake batter, please
|
en: Put some **flour** into the cake batter, please
|
||||||
- ko: 봄에는 꽃**가루** 알레르기를 조심해 야 해요
|
- ko: 봄에는 꽃**가루** 알레르기를 조심해 야 해요
|
||||||
en: You need to be careful about **pollen** allergies in the spring
|
en: You need to be careful about **pollen** allergies in the spring
|
||||||
|
|||||||
Reference in new issue
Block a user