diff --git a/public/assets/card_6.png b/public/assets/card_6.png index c6dabf2..950ef38 100644 Binary files a/public/assets/card_6.png and b/public/assets/card_6.png differ diff --git a/public/assets/card_back.png b/public/assets/card_back.png index a91a281..126ccea 100644 Binary files a/public/assets/card_back.png and b/public/assets/card_back.png differ diff --git a/public/card_back.png b/public/card_back.png deleted file mode 100644 index a91a281..0000000 Binary files a/public/card_back.png and /dev/null differ diff --git a/src/components/MemogameLeaderboard.vue b/src/components/MemogameLeaderboard.vue new file mode 100644 index 0000000..c34cf84 --- /dev/null +++ b/src/components/MemogameLeaderboard.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/components/MemoryCard.vue b/src/components/MemoryCard.vue index 70f0c54..6960e31 100644 --- a/src/components/MemoryCard.vue +++ b/src/components/MemoryCard.vue @@ -3,29 +3,77 @@ import { Card } from '@/types/game.types' import { useMemoryGame } from '@/composables/useMemoryGame' const { flipCard } = useMemoryGame() -defineProps<{ +interface Props { card: Card -}>() +} + +defineProps() diff --git a/src/components/WinModal.vue b/src/components/WinModal.vue index 92526de..36aa50f 100644 --- a/src/components/WinModal.vue +++ b/src/components/WinModal.vue @@ -24,16 +24,20 @@ import { ref, watch } from 'vue' import { useLeaderboard } from '@/composables/useLeaderboard' import { useWinModal } from '@/composables/useWinModal' -const props = defineProps<{ +interface Props { isOpen: boolean pairsFound: number totalPairs: number elapsedTime: number -}>() +} + +const props = defineProps() -const emit = defineEmits<{ +interface Emits { (e: 'submitName'): void -}>() +} + +const emit = defineEmits() const { addEntry, formatTime } = useLeaderboard() const { name: defaultName } = useWinModal() @@ -42,7 +46,7 @@ const name = ref('') // to set a default value and then automatically update the localname ref when the input value changes watch( - () => defaultName.value, + defaultName, (newName) => { if (newName && newName.trim() && !name.value) { name.value = newName diff --git a/src/composables/useLeaderboard.ts b/src/composables/useLeaderboard.ts index f1d3744..8bf6b8f 100644 --- a/src/composables/useLeaderboard.ts +++ b/src/composables/useLeaderboard.ts @@ -16,9 +16,12 @@ export function useLeaderboard() { // format time to minutes:seconds const formatTime = (seconds: number) => { - const mins = Math.floor(seconds / 60) - const secs = seconds % 60 - return `${mins} min ${secs.toString().padStart(2, '0')}s` + return new Intl.DurationFormat(navigator.language, { + style: 'long', + }).format({ + minutes: Math.floor(seconds / 60), + seconds: seconds % 60, + }) } // reset the leaderboard diff --git a/src/composables/useMemoryGame.ts b/src/composables/useMemoryGame.ts index 21e1b64..a693d86 100644 --- a/src/composables/useMemoryGame.ts +++ b/src/composables/useMemoryGame.ts @@ -1,4 +1,4 @@ -import { computed, onMounted, ref, watch } from 'vue' +import { computed, ref, watch } from 'vue' import { Card, GameSettings, ValidGameSizes } from '@/types/game.types' import { useStorageService } from '@/composables/useStorageService' @@ -23,6 +23,10 @@ const { size: 8 as ValidGameSizes, showTimer: true, }) + +export const gameDescription = + 'MemoGame is a singleplayer memory game that trains your concentration and recall. Tap two matching cards to flip & find all pairs as fast as possible! Enter your name after winning to save your time on the leaderboard.' + export function useMemoryGame() { const initCards = () => { const size = memorySize.value @@ -94,19 +98,15 @@ export function useMemoryGame() { initCards() } - onMounted(() => { - watch( - ready, - (isReady) => { - if (!isReady) return + const init = () => { + watch(ready, (isReady) => { + if (!isReady) return - memorySize.value = storedSettings.value.size - showTimer.value = storedSettings.value.showTimer - initCards() - }, - { immediate: true } - ) - }) + memorySize.value = storedSettings.value.size + showTimer.value = storedSettings.value.showTimer + initCards() + }) + } const updateMemorySize = async (value: ValidGameSizes) => { memorySize.value = value @@ -131,6 +131,7 @@ export function useMemoryGame() { updateMemorySize, showTimer, updateShowTimer, + init, } } diff --git a/src/composables/useWinModal.ts b/src/composables/useWinModal.ts index 1bcba56..88ef227 100644 --- a/src/composables/useWinModal.ts +++ b/src/composables/useWinModal.ts @@ -8,13 +8,14 @@ const { data, ready, setData } = useStorageService(WINMODAL_KEY, '') export function useWinModal() { const name = computed(() => data.value) - watch( - ready, - (isReady) => { - if (!isReady) return - }, - { immediate: true } - ) + const init = () => { + watch( + ready, + (isReady) => { + if (!isReady) return + }, + ) + } const updateDefaultName = async (newName: string) => { await setData(newName) @@ -29,5 +30,6 @@ export function useWinModal() { updateDefaultName, reset, ready, + init, } } diff --git a/src/main.ts b/src/main.ts index 9f96810..8fe9512 100644 --- a/src/main.ts +++ b/src/main.ts @@ -34,6 +34,8 @@ import '@ionic/vue/css/palettes/high-contrast.system.css' /* Theme variables */ import './theme/variables.css' +import { useMemoryGame } from './composables/useMemoryGame' +import { useWinModal } from './composables/useWinModal' const app = createApp(App) .use(IonicVue, { @@ -41,6 +43,12 @@ const app = createApp(App) }) .use(router) +const { init: initMemoGame } = useMemoryGame() +const { init: initWinModal } = useWinModal() + +initMemoGame() +initWinModal() + router.isReady().then(() => { app.mount('#app') }) diff --git a/src/types/intl.types.d.ts b/src/types/intl.types.d.ts new file mode 100644 index 0000000..46b07b4 --- /dev/null +++ b/src/types/intl.types.d.ts @@ -0,0 +1,6 @@ +declare namespace Intl { + declare class DurationFormat { + constructor(locales: string, options: object) + format: (obj: object) => string + } +} diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 9a2519a..6a53677 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -3,7 +3,7 @@ - Start a Game + MemoGame - Your Memory Game @@ -21,18 +21,34 @@ Leaderboard + + + Play Guide + Open Settings + diff --git a/src/views/SettingsView.vue b/src/views/SettingsView.vue index 5f1b091..45277db 100644 --- a/src/views/SettingsView.vue +++ b/src/views/SettingsView.vue @@ -99,6 +99,7 @@ const setOpen = (state: boolean) => { const validateToggle = (event: ToggleCustomEvent<{ checked: boolean }>) => { isTouched.value = true isValid.value = event.detail.checked + setOpen(true) updateShowTimer(event.detail.checked) } diff --git a/src/views/gameviews/SingleplayerView.vue b/src/views/gameviews/SingleplayerView.vue index 022d299..dc10ea9 100644 --- a/src/views/gameviews/SingleplayerView.vue +++ b/src/views/gameviews/SingleplayerView.vue @@ -15,18 +15,19 @@
- + Back to Home
+