✨ (card) add animation and true level adding
This commit is contained in:
@@ -200,6 +200,8 @@ $header-height: 40px;
|
||||
}
|
||||
|
||||
.note {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: justify;
|
||||
overflow-y: auto;
|
||||
height: 100vh;
|
||||
|
||||
@@ -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: [] }>()
|
||||
|
||||
const flipped = ref(false)
|
||||
const flip = () => (flipped.value = !flipped.value)
|
||||
@@ -43,7 +43,7 @@ $border-radius: 0.5rem;
|
||||
padding: 0 1rem;
|
||||
margin: auto;
|
||||
user-select: none;
|
||||
transition: 0.1s;
|
||||
transition: 0.3s;
|
||||
perspective: 1500px;
|
||||
|
||||
&:hover {
|
||||
|
||||
68
src/modules/card/components/FlipCardList.vue
Normal file
68
src/modules/card/components/FlipCardList.vue
Normal 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>
|
||||
@@ -13,7 +13,7 @@ import { computed, nextTick, watch } from 'vue'
|
||||
|
||||
const MAX_LEVEL = 10
|
||||
|
||||
interface Repetition {
|
||||
export interface Repetition {
|
||||
repetition: RepetitionCard
|
||||
card: Card
|
||||
}
|
||||
@@ -80,22 +80,6 @@ export const useSpacedRepetitionCards = () => {
|
||||
{ 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 repetition = await data.get<DataType.RepetitionCard, RepetitionCard>(
|
||||
cardId
|
||||
@@ -104,13 +88,13 @@ export const useSpacedRepetitionCards = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const newLevel = repetition.level + 1
|
||||
|
||||
await data.update<DataType.RepetitionCard, RepetitionCard>({
|
||||
...repetition,
|
||||
level: Math.min(repetition.level, MAX_LEVEL),
|
||||
repeatDate: addDays(new Date(), repetition.level)
|
||||
level: Math.min(newLevel, MAX_LEVEL),
|
||||
repeatDate: addDays(new Date(), newLevel)
|
||||
})
|
||||
|
||||
await execute()
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -122,7 +106,7 @@ export const useSpacedRepetitionCards = () => {
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(cardFiles, () => execute(), { immediate: true })
|
||||
watch(cardFiles, () => execute())
|
||||
|
||||
return { cards, failRepetition, successRepetition, isLoading: !isReady }
|
||||
return { cards, successRepetition, isLoading: !isReady }
|
||||
}
|
||||
|
||||
@@ -1,40 +1,28 @@
|
||||
<script lang="ts" setup>
|
||||
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 { computed } from 'vue'
|
||||
|
||||
defineProps<{
|
||||
user: string
|
||||
repo: string
|
||||
}>()
|
||||
|
||||
const { cards, isLoading, successRepetition, failRepetition } =
|
||||
useSpacedRepetitionCards()
|
||||
|
||||
const firstCard = computed(() => {
|
||||
const [repetitionCard] = cards.value
|
||||
return repetitionCard
|
||||
})
|
||||
const { cards, isLoading, successRepetition } = useSpacedRepetitionCards()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="spaced-repetition-card repo-note">
|
||||
<flux-note
|
||||
key="spaced-repetition-card"
|
||||
class="card-container"
|
||||
:user="user"
|
||||
:repo="repo"
|
||||
:with-content="false"
|
||||
>
|
||||
<div id="tweet-1675991484753952769"></div>
|
||||
<section v-if="isLoading">Loading...</section>
|
||||
<section v-else-if="firstCard">
|
||||
<h3 class="subtitle is-3">Level: {{ firstCard.repetition.level }}</h3>
|
||||
<flip-card
|
||||
:card="firstCard.card"
|
||||
@success="() => successRepetition(firstCard.repetition._id ?? '')"
|
||||
@fail="() => failRepetition(firstCard.repetition._id ?? '')"
|
||||
/>
|
||||
<section v-else-if="cards.length" class="cards">
|
||||
<flip-card-list :cards="cards" @success="successRepetition" />
|
||||
</section>
|
||||
<section v-else>No cards to review!</section>
|
||||
</flux-note>
|
||||
@@ -45,5 +33,14 @@ const firstCard = computed(() => {
|
||||
.spaced-repetition-card {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cards {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user