From 45e782a21a64e6bcd7d72769e4b027d19353f6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Advaita=20K=E1=B9=9B=E1=B9=A3=E1=B9=87a=20D=C4=81sa?= Date: Sun, 4 Jun 2023 12:49:22 +0200 Subject: [PATCH] feat(settings): review cards in random order (#250) --- src/app/decks/review/pages/ReviewDeckPage.vue | 14 ++++++++++-- src/app/library/pages/LibraryPage.vue | 1 + src/app/settings/pages/SettingsPage.vue | 8 +++++++ src/app/settings/stores/useSettingsStore.ts | 5 +++-- .../shared/composables/useArrayShuffler.ts | 22 +++++++++++++++++++ src/app/shared/index.ts | 1 + src/app/welcome/pages/WelcomePage.vue | 3 +-- src/init/app/initParams.ts | 6 +++++ src/locale/en/settings.json | 3 ++- src/locale/ru/settings.json | 3 ++- src/locale/uk/settings.json | 3 ++- 11 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 src/app/shared/composables/useArrayShuffler.ts diff --git a/src/app/decks/review/pages/ReviewDeckPage.vue b/src/app/decks/review/pages/ReviewDeckPage.vue index 969531f5..42626452 100644 --- a/src/app/decks/review/pages/ReviewDeckPage.vue +++ b/src/app/decks/review/pages/ReviewDeckPage.vue @@ -73,7 +73,7 @@ import { StackedFlipCardsDeck , useIndexedList, useLibraryCache } from '@/app/de import { ReviewFlipCard, ReviewDeckEmpty, ReviewCardSwipeOverlay, GradeCardButtons } from '@/app/decks/review' import { useSettingsStore } from '@/app/settings' import { TutorialSteps, useTutorialStore } from '@/app/tutorial' -import { useApplication , BackgroundTasks } from '@/app/shared' +import { useApplication , BackgroundTasks, useArrayShuffler } from '@/app/shared' /* -------------------------------------------------------------------------- */ @@ -85,6 +85,7 @@ const libraryCache = useLibraryCache(application.instance()) const indexedList = useIndexedList() const settings = useSettingsStore() const tutorial = useTutorialStore() +const shuffler = useArrayShuffler() /* -------------------------------------------------------------------------- */ @@ -159,12 +160,21 @@ async function onOpened() { reviewCards = await app.reviewDeck.dueToCards(app.timeMachine.now) await libraryCache.load(reviewCards.map(x => x.verseId)) + // Create cards order array and shuffle if needed + const orderArray = [...Array(reviewCards.length).keys()] + const order = settings.reviewCardsInRandomOrder + ? shuffler.shuffle(orderArray) + : orderArray + + // Create view cards const result = [] for (const [index, card] of reviewCards.entries()) { result.push({ - id: card.id.value, index, flipped: false, verseId: card.verseId + id: card.id.value, index: order[index], flipped: false, verseId: card.verseId }) } + + // Return result cardsToShow.value = result } diff --git a/src/app/library/pages/LibraryPage.vue b/src/app/library/pages/LibraryPage.vue index 88d9ed4b..da98f031 100644 --- a/src/app/library/pages/LibraryPage.vue +++ b/src/app/library/pages/LibraryPage.vue @@ -107,6 +107,7 @@ async function onRefresherPullDown( event: IonRefresherCustomEvent ) { await syncLibrary(true) + await onSearchQueryChanged(searchQuery.value) event.target.complete() } diff --git a/src/app/settings/pages/SettingsPage.vue b/src/app/settings/pages/SettingsPage.vue index 6f533637..e431feec 100644 --- a/src/app/settings/pages/SettingsPage.vue +++ b/src/app/settings/pages/SettingsPage.vue @@ -61,6 +61,14 @@ + + + {{ $t('settings.reviewCardsInRandomOrder') }} + + + { const language = ref('') // language will be set in initLocale at app initialization const showGradeButtons = ref(true) const colorfulCards = ref(true) + const reviewCardsInRandomOrder = ref(true) // welcome const welcomeDone = ref(false) @@ -45,6 +46,6 @@ export const useSettingsStore = defineStore('settings', () => { return { language, showGradeButtons, colorfulCards, syncLibraryAt, welcomeDone, authToken, authSessionId, authStrategy, authRefreshedAt, authExpiresAt, syncCollectionId, syncAt, - showAccountControls, autoSyncOnLogin, + showAccountControls, autoSyncOnLogin, reviewCardsInRandomOrder } }) diff --git a/src/app/shared/composables/useArrayShuffler.ts b/src/app/shared/composables/useArrayShuffler.ts new file mode 100644 index 00000000..b916c4b3 --- /dev/null +++ b/src/app/shared/composables/useArrayShuffler.ts @@ -0,0 +1,22 @@ + +export function useArrayShuffler() { + + function shuffle(array: Array) { + let currentIndex = array.length, randomIndex + + // While there remain elements to shuffle. + while (currentIndex != 0) { + // Pick a remaining element. + randomIndex = Math.floor(Math.random() * currentIndex) + currentIndex--; + + // And swap it with the current element. + [array[currentIndex], array[randomIndex]] = [ + array[randomIndex], array[currentIndex]] + } + + return array + } + + return { shuffle } +} diff --git a/src/app/shared/index.ts b/src/app/shared/index.ts index ce6dbf26..925fae57 100644 --- a/src/app/shared/index.ts +++ b/src/app/shared/index.ts @@ -12,6 +12,7 @@ export * from './composables/useEmitter' export * from './composables/useTestId' export * from './composables/useClearCache' export * from './composables/useAppVersion' +export * from './composables/useArrayShuffler' // tasks: export * from './tasks/runSyncTask' diff --git a/src/app/welcome/pages/WelcomePage.vue b/src/app/welcome/pages/WelcomePage.vue index 3bdbdb29..924a5673 100644 --- a/src/app/welcome/pages/WelcomePage.vue +++ b/src/app/welcome/pages/WelcomePage.vue @@ -119,13 +119,13 @@ async function onOpened() { await syncLibraryTask.sync() await loadLibrary.sync() settingsStore.syncLibraryAt = new Date().getTime() + settingsStore.welcomeDone = true } async function onSignIn(strategy: string) { try { await auth.authenticate(strategy) emitter.emit('signedIn') - settingsStore.welcomeDone = true router.replace(go('library')) } catch (e) { const alert = await alertController.create({ @@ -143,7 +143,6 @@ async function onEmailSignIn() { } function onSigInAsGuest() { - settingsStore.welcomeDone = true router.replace(go('library')) } diff --git a/src/init/app/initParams.ts b/src/init/app/initParams.ts index 8fa9e2c7..9f591bd0 100644 --- a/src/init/app/initParams.ts +++ b/src/init/app/initParams.ts @@ -12,6 +12,7 @@ export async function initParams( const tutorialEnabled = params.get('tutorialEnabled') const libraryLastSyncDate = params.get('libraryLastSyncDate') const autoSyncOnLogin = params.get('autoSyncOnLogin') + const reviewCardsInRandomOrder = params.get('reviewCardsInRandomOrder') const date = params.get('date') const tutorialStore = useTutorialStore() @@ -32,6 +33,11 @@ export async function initParams( settingsStore.autoSyncOnLogin = ['true', '1'].includes(autoSyncOnLogin) } + if (reviewCardsInRandomOrder) { + console.debug('[params] reviewCardsInRandomOrder', reviewCardsInRandomOrder) + settingsStore.reviewCardsInRandomOrder = ['true', '1'].includes(reviewCardsInRandomOrder) + } + if (date) { console.debug('[params] date', date) diff --git a/src/locale/en/settings.json b/src/locale/en/settings.json index f30317fc..85e33f3f 100644 --- a/src/locale/en/settings.json +++ b/src/locale/en/settings.json @@ -7,7 +7,8 @@ "colorfulCards": "Colorful cards", "contactUs": "Contact us", "update": "Update", - "clearCache": "Clear cache" + "clearCache": "Clear cache", + "reviewCardsInRandomOrder": "Randomize review cards" }, "account": { "welcomeBack": "Welcome back!", diff --git a/src/locale/ru/settings.json b/src/locale/ru/settings.json index d4e1ae97..81a6e1e5 100644 --- a/src/locale/ru/settings.json +++ b/src/locale/ru/settings.json @@ -7,7 +7,8 @@ "colorfulCards": "Цветные карточки", "contactUs": "Напишите нам", "update": "Обновить", - "clearCache": "Очистить кэш" + "clearCache": "Очистить кэш", + "reviewCardsInRandomOrder": "Обзор в случайном порядке" }, "account": { "welcomeBack": "Добро пожаловать!", diff --git a/src/locale/uk/settings.json b/src/locale/uk/settings.json index 2a7db8f8..5d831ac0 100644 --- a/src/locale/uk/settings.json +++ b/src/locale/uk/settings.json @@ -6,7 +6,8 @@ "gradeButtons": "Показувати кнопки оцінок", "colorfulCards": "Кольорові картки", "contactUs": "Зв'язатися з нами", - "update": "Update" + "update": "Update", + "reviewCardsInRandomOrder": "Випадковий порядок" }, "account": { "welcomeBack": "З Поверненням!",