✨ (card) add animation and true level adding
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
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
|
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 }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user