integrate need review cards

This commit is contained in:
Julien Calixte
2023-08-06 21:27:01 +02:00
parent af421042ad
commit 32a76ca3b7
11 changed files with 120 additions and 18 deletions

View File

@@ -3,7 +3,7 @@ import { ref } from 'vue'
import { Card } from '../models/Card'
defineProps<{ card: Card }>()
const emit = defineEmits<{ success: []; fail: [] }>()
const emit = defineEmits<{ success: []; fail: []; needsReview: [] }>()
const flipped = ref(false)
const flip = () => {
@@ -11,8 +11,8 @@ const flip = () => {
}
const success = () => emit('success')
const fail = () => emit('fail')
const needsReview = () => emit('needsReview')
</script>
<template>
@@ -27,8 +27,13 @@ const fail = () => emit('fail')
<div class="actions">
<p>Did you remember this?</p>
<div class="buttons is-centered">
<div class="button is-warning" @click.stop="fail">failed</div>
<div class="button is-success" @click.stop="success">got it</div>
<button class="button is-warning" @click.stop="fail">failed</button>
<button class="button is-success" @click.stop="success">
got it
</button>
<button class="button is-danger" @click.stop="needsReview">
<em>needs review</em>
</button>
</div>
</div>
</div>

View File

@@ -7,6 +7,7 @@ const props = defineProps<{ cards: Repetition[] }>()
const emits = defineEmits<{
success: [id: string]
fail: [id: string]
needsReview: [id: string]
}>()
const cards = ref(
@@ -32,6 +33,12 @@ const goToNextCard = (success: boolean) => {
currentIndex.value++
}
const needsReview = () => {
const id = cards.value[currentIndex.value].repetition._id ?? ''
emits('needsReview', id)
currentIndex.value++
}
</script>
<template>
@@ -52,6 +59,7 @@ const goToNextCard = (success: boolean) => {
:card="card.card"
@success="goToNextCard(true)"
@fail="goToNextCard(false)"
@needs-review="needsReview"
/>
</div>
<div v-else>No more cards to check!</div>

View File

@@ -0,0 +1,22 @@
import { data } from '@/data/data'
import { DataType } from '@/data/DataType.enum'
import { RepetitionCard } from '@/modules/card/models/RepetitionCard'
import { useAsyncState } from '@vueuse/core'
export const useNeedReviewCards = () => {
const { state: cardsToReview, isReady } = useAsyncState(async () => {
const repetitions = await data.getAll<
DataType.RepetitionCard,
RepetitionCard
>({
prefix: DataType.RepetitionCard
})
return repetitions.filter((repetition) => repetition.needsReview)
}, [])
return {
cardsToReview,
isReady
}
}

View File

@@ -1,7 +1,7 @@
// https://npm.io/package/supermemo
import { DataType } from '@/data/DataType.enum'
import { data } from '@/data/data'
import { DataType } from '@/data/DataType.enum'
import { useFile } from '@/hooks/useFile.hook'
import { useLinks } from '@/hooks/useLinks.hook'
import { useMarkdown } from '@/hooks/useMarkdown.hook'
@@ -53,12 +53,14 @@ export const useSpacedRepetitionCards = () => {
>(data.generateId(DataType.RepetitionCard, cardFile.path), {
$type: DataType.RepetitionCard,
level: 1,
repeatDate: new Date()
repeatDate: new Date(),
needsReview: false
})
if (
isAfter(new Date(repetition.repeatDate), new Date()) ||
repetition.level === MAX_LEVEL
repetition.level === MAX_LEVEL ||
repetition.needsReview
) {
continue
}
@@ -95,6 +97,7 @@ export const useSpacedRepetitionCards = () => {
await data.update<DataType.RepetitionCard, RepetitionCard>({
...repetition,
needsReview: false,
level: Math.min(repetition.level + 1, MAX_LEVEL),
repeatDate: addDays(new Date(), 2 ** repetition.level)
})
@@ -113,10 +116,25 @@ export const useSpacedRepetitionCards = () => {
await data.update<DataType.RepetitionCard, RepetitionCard>({
...repetition,
level,
needsReview: false,
repeatDate: addDays(new Date(), level)
})
}
const needsReview = async (cardId: string) => {
const repetition = await data.get<DataType.RepetitionCard, RepetitionCard>(
cardId
)
if (!repetition) {
return
}
await data.update<DataType.RepetitionCard, RepetitionCard>({
...repetition,
needsReview: true
})
}
watch(
cards,
() =>
@@ -128,5 +146,11 @@ export const useSpacedRepetitionCards = () => {
watch(cardFiles, () => execute())
return { cards, successRepetition, failRepetition, isLoading: !isReady }
return {
cards,
successRepetition,
failRepetition,
needsReview,
isLoading: !isReady
}
}

View File

@@ -4,4 +4,5 @@ import { Model } from '@/data/models/Model'
export interface RepetitionCard extends Model<DataType.RepetitionCard> {
level: number
repeatDate: Date
needsReview: boolean
}

View File

@@ -0,0 +1,42 @@
import { describe, expect, it } from 'vitest'
import { resolvePath } from './resolvePath'
describe('resolve path service', () => {
it('set the absolute path if path to resolve is empty', () => {
expect(resolvePath('standard/README.md', '')).toEqual('standard/')
})
it('returns the path sanitized if there is no absolute path', () => {
expect(resolvePath('', './here/note.md')).toEqual('here/note.md')
})
it('set the absolute path from the current path', () => {
expect(resolvePath('standard/README.md', './other-note.md')).toEqual(
'standard/other-note.md'
)
})
it('set the absolute path from the current path with multiple level', () => {
expect(
resolvePath('standard/you/are/here/README.md', './other-note.md')
).toEqual('standard/you/are/here/other-note.md')
})
it('set the absolute path from the current path with a go back in the relative path', () => {
expect(
resolvePath('standard/you/are/here/README.md', '../other-note.md')
).toEqual('standard/you/are/other-note.md')
expect(
resolvePath('standard/you/are/here/README.md', '../../other-note.md')
).toEqual('standard/you/other-note.md')
expect(
resolvePath('standard/you/are/here/README.md', './../../other-note.md')
).toEqual('standard/you/other-note.md')
expect(
resolvePath('standard/you/are/here/README.md', './../../../other-note.md')
).toEqual('standard/other-note.md')
})
})