Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: restore tutorial state #196

Merged
merged 1 commit into from
Apr 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/app/decks/inbox/pages/InboxDeckPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@
<script lang="ts" setup>
import { InboxCard, InboxCardMemorized, UpdateVerseStatus, Verse, VerseId } from '@akdasa-studios/shlokas-core'
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, onIonViewWillEnter, onIonViewDidLeave } from '@ionic/vue'
import { computed, ref, reactive } from 'vue'
import { computed, ref, reactive, watch } from 'vue'
import { testId } from '@/app/TestId'
import { InboxFlipCard, InboxCardSwipeOverlay, InboxDeckEmpty } from '@/app/decks/inbox'
import { useLibraryCache, useIndexedList, StackedFlipCardsDeck } from '@/app/decks/shared'
import { useTutorialStore, TutorialSteps } from '@/app/tutorial'
import { useApp } from '@/app/shared'
import { useApplication } from '@/app/shared'


/* -------------------------------------------------------------------------- */
/* Dependencies */
/* -------------------------------------------------------------------------- */

const application = useApp()
const application = useApplication()
const libraryCache = useLibraryCache(application.instance())
const indexedList = useIndexedList()
const tutorial = useTutorialStore()
Expand Down Expand Up @@ -101,6 +101,7 @@ let inboxCards: readonly InboxCard[] = []

onIonViewWillEnter(async () => await onOpened())
onIonViewDidLeave(() => cards.value = [])
watch([application.now, application.currentContextName], onOpened)


/* -------------------------------------------------------------------------- */
Expand Down
5 changes: 3 additions & 2 deletions src/app/decks/review/pages/ReviewDeckPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ 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 { useApp } from '@/app/shared'
import { useApplication } from '@/app/shared'


/* -------------------------------------------------------------------------- */
/* Dependencies */
/* -------------------------------------------------------------------------- */

const application = useApp()
const application = useApplication()
const libraryCache = useLibraryCache(application.instance())
const indexedList = useIndexedList()
const settings = useSettingsStore()
Expand Down Expand Up @@ -137,6 +137,7 @@ watch(currentStep, async (value: number) => {
await onOpened()
}
})
watch([application.now, application.currentContextName], onOpened)

/* -------------------------------------------------------------------------- */
/* Lifehooks */
Expand Down
2 changes: 1 addition & 1 deletion src/app/home/components/HomePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const tutorialStore = useTutorialStore()

const { cardsInInbox, cardsInReview } = storeToRefs(statisticsStore)
const {
enabled: tutorialEnabled,
isEnabled: tutorialEnabled,
isCompleted: isTutorialCompleted
} = storeToRefs(tutorialStore)
</script>
4 changes: 2 additions & 2 deletions src/app/library/pages/LibraryPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ import { IonRefresherCustomEvent, RefresherEventDetail } from '@ionic/core'
import { useLoadLibraryIntoMemory, useSyncLibraryTask, VersesList } from '@/app/library'
import { useSettingsStore } from '@/app/settings'
import { TutorialSteps, useTutorialStore } from '@/app/tutorial'
import { useApp } from '@/app/shared'
import { useApplication } from '@/app/shared'

/* -------------------------------------------------------------------------- */
/* Dependencies */
/* -------------------------------------------------------------------------- */

const application = useApp()
const application = useApplication()
const libraryDatabase = inject('verses')
const syncLibraryTask = useSyncLibraryTask(libraryDatabase)
const loadLibrary = useLoadLibraryIntoMemory(application.instance(), libraryDatabase)
Expand Down
4 changes: 2 additions & 2 deletions src/app/library/pages/VersePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { computed, defineProps, onMounted, shallowRef } from 'vue'
import { AddVerseToInboxDeck, Decks, Declamation, UpdateVerseStatus, Verse, VerseId, VerseImage, VerseStatus } from '@akdasa-studios/shlokas-core'
import { Transaction } from '@akdasa-studios/framework'
import { VerseDetails } from '@/app/library'
import { go, useApp } from '@/app/shared'
import { go, useApplication } from '@/app/shared'
import { TutorialSteps, useTutorialStore } from '@/app/tutorial'

/* -------------------------------------------------------------------------- */
Expand All @@ -55,7 +55,7 @@ const props = defineProps<{
/* Dependencies */
/* -------------------------------------------------------------------------- */

const application = useApp()
const application = useApplication()
const router = useIonRouter()
const tutorial = useTutorialStore()

Expand Down
4 changes: 2 additions & 2 deletions src/app/settings/components/account/AccountPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ import { AuthService } from '@/services/AuthService'
import { AUTH_HOST } from '@/app/Env'

import { createRepositories } from '@/app/utils/sync'
import { useApp } from '@/app/shared'
import { useApplication } from '@/app/shared'
import LogInViaEmailPage from './email/LogInViaEmailPage.vue'
import SignUpViaEmailPage from './email/SignUpViaEmailPage.vue'

const inProgress = ref(false)
const emitter = inject('emitter') as EventEmitter2
const application = useApp()
const application = useApplication()
const account = useAccountStore()
const { isAuthenticated, syncHost, token, email } = storeToRefs(account)
const { logOut } = account
Expand Down
2 changes: 1 addition & 1 deletion src/app/settings/stores/useAccountStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import { computed, Ref, ref, watch } from 'vue'
import { useDeviceStore } from '@/app/useDeviceStorage'
import { useDeviceStore } from '@/app/shared'
import { AuthToken } from '@/services/AuthService'
import { HOST, IS_DEVELOPMENT } from '../../Env'

Expand Down
2 changes: 1 addition & 1 deletion src/app/settings/stores/useSettingsStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import { ref, watch } from 'vue'
import { useDeviceStore } from '@/app/useDeviceStorage'
import { useDeviceStore } from '@/app/shared'


interface LocaleSettings {
Expand Down
4 changes: 2 additions & 2 deletions src/app/shared/composables/useApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const currentContextName = ref<string>('')
const now = ref(new Date())


export function useApp() {
export function useApplication() {
function init(app: Application) {
application = app
application.contextChanged.subscribe(onContextChanged)
Expand Down Expand Up @@ -54,5 +54,5 @@ export function useApp() {
})


return { init, switchContextTo, registerContext, currentContextName, goInFuture, daysInFuture, application, now, instance }
return { init, switchContextTo, registerContext, currentContextName, goInFuture, daysInFuture, application, now, instance, setTime }
}
3 changes: 2 additions & 1 deletion src/app/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export * from './composables/useLinks'
export * from './composables/useEnv'
export * from './composables/useStringHasher'
export * from './composables/useLogger'
export * from './composables/useApp'
export * from './composables/useApp'
export * from './composables/useDeviceStorage'
4 changes: 2 additions & 2 deletions src/app/statistics/tasks/runUpdateStatisticsTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { EventEmitter2 } from 'eventemitter2'

import { watch } from 'vue'
import { useStatisticsStore } from '@/app/statistics'
import { useApp } from '@/app/shared'
import { useApplication } from '@/app/shared'


export function runUpdateStatisticsTask(emitter: EventEmitter2) {
const statisticsStore = useStatisticsStore()
const app = useApp()
const app = useApplication()


watch(app.now, async () => await updateStatistics())
Expand Down
14 changes: 9 additions & 5 deletions src/app/tutorial/components/TutorialCard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
id="root"
class="tutorial-card"
:class="{ 'visible': props.visible, 'hidden': !props.visible }"
>
<slot />
Expand All @@ -23,6 +23,7 @@
</div>
</template>


<script setup lang="ts">
import { defineProps, defineEmits, toRefs } from 'vue'
import { IonButton } from '@ionic/vue'
Expand All @@ -47,25 +48,26 @@ const emit = defineEmits<{
(event: 'button-clicked', buttonId: string): void
}>()


/* -------------------------------------------------------------------------- */
/* State */
/* -------------------------------------------------------------------------- */

const { progress } = toRefs(props)


/* -------------------------------------------------------------------------- */
/* Handlers */
/* -------------------------------------------------------------------------- */

function onClicked(buttonId: string) {
emit('button-clicked', buttonId)
}

</script>


<style scoped>
#root {
.tutorial-card {
bottom: -50px;
position: absolute;
width: calc(100% - 20px);
Expand All @@ -80,14 +82,16 @@ function onClicked(buttonId: string) {
flex-direction: column;
gap: 5px;
overflow: hidden;
pointer-events: visible;
}

#root.hidden {
.tutorial-card.hidden {
opacity: 0;
bottom: -50px;
visibility: hidden;
}

#root.visible {
.tutorial-card.visible {
opacity: .9;
bottom: 0px;
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/tutorial/components/TutorialCards.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div id="root2">
<div class="tutorial-cards">
<TutorialCard
v-if="activeCard"
:visible="activeCardVisible"
Expand Down Expand Up @@ -101,8 +101,9 @@ setInterval(() => {
}, 100)
</script>


<style scoped>
#root2 {
.tutorial-cards {
bottom: calc(v-bind(positionBottom) * 1px + var(--ion-safe-area-bottom));
position: absolute;
width: 100%;
Expand Down
39 changes: 26 additions & 13 deletions src/app/tutorial/components/TutorialPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,61 @@
:duration="5000"
/>
<TutorialCards
:cards="steps"
:cards="tutorialSteps"
:step="currentStep"
@card-clicked="onCardClicked"
/>
</div>
</template>


<script lang="ts" setup>
import { storeToRefs } from 'pinia'
import { ref } from 'vue'
import { ref, watch } from 'vue'
import ConfettiExplosion from 'vue-confetti-explosion'
import { TutorialCards, TutorialSteps, useTutorialStore } from '@/app/tutorial'
import { useApp } from '@/app/shared'
import { TutorialCards, TutorialStep, TutorialSteps, useTutorialStore } from '@/app/tutorial'
import { useApplication } from '@/app/shared'


/* -------------------------------------------------------------------------- */
/* Dependencies */
/* -------------------------------------------------------------------------- */

const application = useApp()
const application = useApplication()
const tutorialStore = useTutorialStore()


/* -------------------------------------------------------------------------- */
/* State */
/* -------------------------------------------------------------------------- */

const { currentStep, steps } = storeToRefs(tutorialStore)
const { currentStep } = storeToRefs(tutorialStore)
const showConfetti = ref(false)


/* -------------------------------------------------------------------------- */
/* Watch */
/* -------------------------------------------------------------------------- */

watch(currentStep, onStepChanged)

/* -------------------------------------------------------------------------- */
/* Handlers */
/* -------------------------------------------------------------------------- */

function onCardClicked() {
// tutorialStore.completeStep()
async function onStepChanged(current: TutorialSteps, prev: TutorialSteps) {
const prevStep = tutorialSteps[prev]
const currStep = tutorialSteps[current]

if (prevStep && prevStep.onLeave) { await prevStep.onLeave() }
if (currStep && currStep.onEnter) { await currStep.onEnter() }
}


function goToTheNextStep() {
tutorialStore.completeStep(tutorialStore.currentStep)
}

tutorialStore.registerSteps([
const tutorialSteps: TutorialStep[] = [
{
id: TutorialSteps.OverallIntroduction,
text: 'tutorial.introduction',
Expand Down Expand Up @@ -183,7 +195,7 @@ tutorialStore.registerSteps([
id: TutorialSteps.ReviewDeckGradeAllCards,
text: 'tutorial.reviewDeck.gradeAllCards',
duration: 5000,
onEnter: () => application.goInFuture(7)
onEnter: async () => application.goInFuture(7)
},

{
Expand All @@ -197,17 +209,18 @@ tutorialStore.registerSteps([
id: TutorialSteps.TutorialCongratulations,
text: 'tutorial.congratulations',
duration: 5000,
onEnter: () => {
onEnter: async () => {
showConfetti.value = true
},
async onTimeout() {
currentStep.value = TutorialSteps.TutorialEnd
application.switchContextTo('main')
}
},
])
]
</script>


<style scoped>
.confetti {
position: absolute;
Expand Down
3 changes: 2 additions & 1 deletion src/app/tutorial/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export * from './stores/useTutorialStore'
export * from './models/TutorialStep'

// tasks:
export * from './tasks/runTutorialPersistenceTask'
export * from './tasks/runTutorialPersistenceTask'
export * from './tasks/runTutorialRestoreTask'
4 changes: 2 additions & 2 deletions src/app/tutorial/models/TutorialStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export interface TutorialStep {
buttons?: TutorialButton[]
onButtonClicked?: (buttonId: string) => void
onTimeout?: () => void
onLeave?: () => void
onEnter?: () => void
onLeave?: () => Promise<void>
onEnter?: () => Promise<void>
}

export enum TutorialSteps {
Expand Down
Loading