(card) add animation and true level adding

This commit is contained in:
Julien Calixte
2023-07-08 00:22:44 +02:00
parent 3f8cb0985a
commit 3ab1d0eab3
5 changed files with 93 additions and 42 deletions

View File

@@ -200,6 +200,8 @@ $header-height: 40px;
} }
.note { .note {
display: flex;
flex-direction: column;
text-align: justify; text-align: justify;
overflow-y: auto; overflow-y: auto;
height: 100vh; height: 100vh;

View File

@@ -3,7 +3,7 @@ import { ref } from 'vue'
import { Card } from '../models/Card' import { Card } from '../models/Card'
defineProps<{ card: Card }>() defineProps<{ card: Card }>()
const emit = defineEmits(['success', 'fail']) const emit = defineEmits<{ success: []; fail: [] }>()
const flipped = ref(false) const flipped = ref(false)
const flip = () => (flipped.value = !flipped.value) const flip = () => (flipped.value = !flipped.value)
@@ -43,7 +43,7 @@ $border-radius: 0.5rem;
padding: 0 1rem; padding: 0 1rem;
margin: auto; margin: auto;
user-select: none; user-select: none;
transition: 0.1s; transition: 0.3s;
perspective: 1500px; perspective: 1500px;
&:hover { &:hover {

View File

@@ -0,0 +1,68 @@
<script setup lang="ts">
import FlipCard from '@/modules/card/components/FlipCard.vue'
import { Repetition } from '@/modules/card/hooks/useSpacedRepetitionCards'
import { computed, ref } from 'vue'
const props = defineProps<{ cards: Repetition[] }>()
const emits = defineEmits<{
success: [id: string]
}>()
const cards = ref(props.cards)
const currentIndex = ref(0)
const cardsToDisplay = computed(() => {
return cards.value
})
const goToNextCard = (success: boolean) => {
if (success) {
const id = cardsToDisplay.value[currentIndex.value].repetition._id ?? ''
emits('success', id)
} else {
const failedCard = cards.value.at(currentIndex.value)
if (failedCard) {
cards.value.push(failedCard)
}
}
currentIndex.value++
}
</script>
<template>
<div class="flip-card-list">
<h3 class="subtitle is-3">
Level: {{ cardsToDisplay[currentIndex].repetition.level }}
</h3>
<h4>cards left: {{ cardsToDisplay.length - currentIndex }}</h4>
<div v-if="currentIndex < cards.length">
<flip-card
v-for="(card, index) in cardsToDisplay"
:key="card.repetition._id ?? ''"
class="card"
:style="{
left: `${(index - currentIndex) * 550}px`
}"
:card="card.card"
@success="goToNextCard(true)"
@fail="goToNextCard(false)"
/>
</div>
<div v-else>No more cards to check!</div>
</div>
</template>
<style scoped lang="scss">
.flip-card-list {
overflow-x: hidden;
height: 100%;
.card {
position: relative;
transition: left 0.7s ease-out;
}
}
</style>

View File

@@ -13,7 +13,7 @@ import { computed, nextTick, watch } from 'vue'
const MAX_LEVEL = 10 const MAX_LEVEL = 10
interface Repetition { export interface Repetition {
repetition: RepetitionCard repetition: RepetitionCard
card: Card card: Card
} }
@@ -80,22 +80,6 @@ export const useSpacedRepetitionCards = () => {
{ immediate: false } { immediate: false }
) )
const failRepetition = async (cardId: string) => {
const repetition = await data.get<DataType.RepetitionCard, RepetitionCard>(
cardId
)
if (!repetition) {
return
}
await data.update<DataType.RepetitionCard, RepetitionCard>({
...repetition,
repeatDate: addDays(new Date(), 1)
})
await execute()
}
const successRepetition = async (cardId: string) => { const successRepetition = async (cardId: string) => {
const repetition = await data.get<DataType.RepetitionCard, RepetitionCard>( const repetition = await data.get<DataType.RepetitionCard, RepetitionCard>(
cardId cardId
@@ -104,13 +88,13 @@ export const useSpacedRepetitionCards = () => {
return return
} }
const newLevel = repetition.level + 1
await data.update<DataType.RepetitionCard, RepetitionCard>({ await data.update<DataType.RepetitionCard, RepetitionCard>({
...repetition, ...repetition,
level: Math.min(repetition.level, MAX_LEVEL), level: Math.min(newLevel, MAX_LEVEL),
repeatDate: addDays(new Date(), repetition.level) repeatDate: addDays(new Date(), newLevel)
}) })
await execute()
} }
watch( watch(
@@ -122,7 +106,7 @@ export const useSpacedRepetitionCards = () => {
{ immediate: true } { immediate: true }
) )
watch(cardFiles, () => execute(), { immediate: true }) watch(cardFiles, () => execute())
return { cards, failRepetition, successRepetition, isLoading: !isReady } return { cards, successRepetition, isLoading: !isReady }
} }

View File

@@ -1,40 +1,28 @@
<script lang="ts" setup> <script lang="ts" setup>
import FluxNote from '@/components/FluxNote.vue' import FluxNote from '@/components/FluxNote.vue'
import FlipCard from '@/modules/card/components/FlipCard.vue' import FlipCardList from '@/modules/card/components/FlipCardList.vue'
import { useSpacedRepetitionCards } from '@/modules/card/hooks/useSpacedRepetitionCards' import { useSpacedRepetitionCards } from '@/modules/card/hooks/useSpacedRepetitionCards'
import { computed } from 'vue'
defineProps<{ defineProps<{
user: string user: string
repo: string repo: string
}>() }>()
const { cards, isLoading, successRepetition, failRepetition } = const { cards, isLoading, successRepetition } = useSpacedRepetitionCards()
useSpacedRepetitionCards()
const firstCard = computed(() => {
const [repetitionCard] = cards.value
return repetitionCard
})
</script> </script>
<template> <template>
<div class="spaced-repetition-card repo-note"> <div class="spaced-repetition-card repo-note">
<flux-note <flux-note
key="spaced-repetition-card" key="spaced-repetition-card"
class="card-container"
:user="user" :user="user"
:repo="repo" :repo="repo"
:with-content="false" :with-content="false"
> >
<div id="tweet-1675991484753952769"></div>
<section v-if="isLoading">Loading...</section> <section v-if="isLoading">Loading...</section>
<section v-else-if="firstCard"> <section v-else-if="cards.length" class="cards">
<h3 class="subtitle is-3">Level: {{ firstCard.repetition.level }}</h3> <flip-card-list :cards="cards" @success="successRepetition" />
<flip-card
:card="firstCard.card"
@success="() => successRepetition(firstCard.repetition._id ?? '')"
@fail="() => failRepetition(firstCard.repetition._id ?? '')"
/>
</section> </section>
<section v-else>No cards to review!</section> <section v-else>No cards to review!</section>
</flux-note> </flux-note>
@@ -45,5 +33,14 @@ const firstCard = computed(() => {
.spaced-repetition-card { .spaced-repetition-card {
display: flex; display: flex;
flex: 1; flex: 1;
.card-container {
display: flex;
flex-direction: column;
}
.cards {
flex: 1;
}
} }
</style> </style>