From f8a3561d9a5a45330cf5a8292da6c4efb89185d5 Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Tue, 19 Nov 2024 22:18:56 +0100 Subject: [PATCH 1/6] Use localStorage for restoring saveGame --- src/alfagok/static/game.js | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index 0ea9245..8d3bf09 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -1,5 +1,8 @@ document.addEventListener('alpine:init', () => { Alpine.store('alfagok', { + // isLocalStorageAvailable: this.testLocalStorage(), + isLocalStorageAvailable: false, + /* Main alfagok application, state etc */ gameID: 0, @@ -7,6 +10,7 @@ document.addEventListener('alpine:init', () => { winTime: null, startTime: null, + gaveUpTime: null, // not implemented yet nrGuesses: 0, guessesBefore: [], @@ -88,6 +92,90 @@ document.addEventListener('alpine:init', () => { this.resultGuesses = '🤔 '+ this.nrGuesses + ' gokken'; this.resultTimeTaken = '⏱️ ' + getFormattedTime(this.winTime - this.startTime); } + }, + setEmptyGameState() { + this.winTime = null; + this.startTime = null; + + this.nrGuesses = 0; + this.guessesBefore = []; + this.guessesAfter = []; + + this.guessValue = ''; + + this.guessError = ''; + + this.resultGameID = ''; + this.resultGuesses = ''; + this.resultTimeTaken = ''; + + this.getGameID(); + }, + // # Local Storage Persistence + storeGameState() { + }, + getStoredGameState() { + if (!this.isLocalStorageAvailable) return undefined; + + const savedGameJson = localStorage.getItem('saveGame'); + try { + return savedGameJSON && JSON.parse(savedGameJSON); + } catch (e) { + localStorage.removeItem('saveGame'); + } + return undefined; + }, + loadGameState() { + const savedGame = this.getStoredGameState(); + + if (!savedGame || !savedGame.gameID || (savedGame.gameID !== this.gameID)) { + this.setEmptyGameState(); + return; + } + if (!savedGame || !savedGame.startTime) { + this.setEmptyGameState(); + return; + } + const startTime = new Date(savedGame.startTime); + if (!isPlayDateToday(app.playDate)) { + this.setEmptyGameState(); + return; + } + const savedGameForToday = getDOY(startTime) === getDOY(now()); + if (!savedGameForToday) { + this.resetSavedGames(); + this.setEmptyGameState(); + return; + } + const { + winTime, + guessesBefore, + guessesAfter, + guessValue, + } = savedGame; + const gaveUpTime = null; // to be implemented + this.startTime = startTime; + this.winTime = (winTime && new Date(winTime)) || null; + this.guessesBefore = guessesBefore || []; + this.guessesAfter = guessesAfter || []; + if (gaveUpTime || this.winTime) { + this.guessValue = guessValue; + } + }, + resetSavedGames() { + localStorage.removeItem('saveGame'); + }, + testLocalStorage() { + // stolen from https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available + const test = 'test'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + this.isLocalStorageAvailable = true; + } catch (e) { + this.isLocalStorageAvailable = false; + } + console.log('Local storage is available? ' + this.isLocalStorageAvailable); } }), @@ -177,4 +265,5 @@ go(); document.addEventListener('alpine:initialized', () => { /* On AlpineJS completely loaded, do all this */ Alpine.store('alfagok').getGameID(); + Alpine.store('alfagok').testLocalStorage(); }) From 48ccb99492d576825ebb2a64676328d18de32e45 Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Sat, 23 Nov 2024 21:38:42 +0100 Subject: [PATCH 2/6] Restored accidentally removed test-for-localStorage functions --- src/alfagok/static/game.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index 829b06c..a95236a 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -120,7 +120,7 @@ document.addEventListener('alpine:init', () => { const savedGameJson = localStorage.getItem('saveGame'); try { - return savedGameJSON && JSON.parse(savedGameJSON); + return savedGameJson && JSON.parse(savedGameJson); } catch (e) { localStorage.removeItem('saveGame'); } @@ -162,6 +162,21 @@ document.addEventListener('alpine:init', () => { if (gaveUpTime || this.winTime) { this.guessValue = guessValue; } + }, + resetSavedGames() { + localStorage.removeItem('saveGame'); + }, + testLocalStorage() { + // stolen from https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available + const test = 'test'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + this.isLocalStorageAvailable = true; + } catch (e) { + this.isLocalStorageAvailable = false; + } + console.log('Local storage is available? ' + this.isLocalStorageAvailable); }, getFormattedTime(milliseconds) { if (!Number.isInteger(milliseconds)) { From 795ee7aa16d0d72e359c4fffcd05d4bf55451c9e Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Sat, 23 Nov 2024 22:16:47 +0100 Subject: [PATCH 3/6] Started work on saving game state --- src/alfagok/static/game.js | 16 ++++++++++++---- src/alfagok/templates/index.html | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index a95236a..8dab7f6 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -2,6 +2,7 @@ document.addEventListener('alpine:init', () => { Alpine.store('alfagok', { // isLocalStorageAvailable: this.testLocalStorage(), isLocalStorageAvailable: false, + savedGameKey: 'saveGame', /* Main alfagok application, state etc */ gameID: 0, @@ -114,15 +115,21 @@ document.addEventListener('alpine:init', () => { }, // # Local Storage Persistence storeGameState() { + localStorage.setItem(this.savedGameKey, JSON.stringify({ + startTime, + winTime, + gaveUpTime, + guessesBefore, + })); }, getStoredGameState() { if (!this.isLocalStorageAvailable) return undefined; - const savedGameJson = localStorage.getItem('saveGame'); + const savedGameJson = localStorage.getItem(this.savedGameKey); try { return savedGameJson && JSON.parse(savedGameJson); } catch (e) { - localStorage.removeItem('saveGame'); + localStorage.removeItem(this.savedGameKey); } return undefined; }, @@ -164,7 +171,7 @@ document.addEventListener('alpine:init', () => { } }, resetSavedGames() { - localStorage.removeItem('saveGame'); + localStorage.removeItem(this.savedGameKey); }, testLocalStorage() { // stolen from https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available @@ -178,6 +185,7 @@ document.addEventListener('alpine:init', () => { } console.log('Local storage is available? ' + this.isLocalStorageAvailable); }, + // # Countdown timer getFormattedTime(milliseconds) { if (!Number.isInteger(milliseconds)) { return ''; @@ -215,7 +223,7 @@ document.addEventListener('alpine:init', () => { let secondsRemain = Math.floor(diff%60); nextgame.innerHTML = ''+addZero(hoursRemain)+':'+addZero(minutesRemain)+':'+addZero(secondsRemain)+' over'; } - }), + }) Alpine.store('darkMode', { /* Different Alpine app, dark mode settings for the game */ diff --git a/src/alfagok/templates/index.html b/src/alfagok/templates/index.html index f06205f..5fc3501 100644 --- a/src/alfagok/templates/index.html +++ b/src/alfagok/templates/index.html @@ -11,13 +11,14 @@ +
- alfagok puzzel # | gokken + alfagok puzzel # | gokken

Raad het woord van de dag. Elke gok geeft een hint over waar het woord zich in het alfabet bevindt.

From bbfa172e7ad4c241ba5ae66552ebb3b7c10b748f Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Sun, 24 Nov 2024 16:32:13 +0100 Subject: [PATCH 4/6] Persist the important game data in localStorage --- src/alfagok/static/game.js | 34 ++++++++++++++++---------------- src/alfagok/templates/index.html | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index 8dab7f6..5cfe4ee 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -5,26 +5,26 @@ document.addEventListener('alpine:init', () => { savedGameKey: 'saveGame', /* Main alfagok application, state etc */ - gameID: 0, + gameID: Alpine.$persist(0).as('gameID'), countingDown: '', loading: false, - winTime: null, - startTime: null, - gaveUpTime: null, // not implemented yet + winTime: Alpine.$persist(null).as('winTime'), + startTime: Alpine.$persist(null).as('startTime'), + gaveUpTime: Alpine.$persist(null).as('gaveUpTime'), // not implemented yet - nrGuesses: 0, - guessesBefore: [], - guessesAfter: [], + nrGuesses: Alpine.$persist(0).as('nrGuesses'), + guessesBefore: Alpine.$persist([]).as('guessesBefore'), + guessesAfter: Alpine.$persist([]).as('guessesAfter'), - guessValue: '', + guessValue: Alpine.$persist('').as('guessValue'), guessError: '', - resultGameID: '', - resultGuesses: '', - resultTimeTaken: '', + resultGameID: Alpine.$persist('').as('resultGameID'), + resultGuesses: Alpine.$persist('').as('resultGuesses'), + resultTimeTaken: Alpine.$persist('').as('resultTimeTaken'), async getGameID() { /* Get the game number from the backend */ @@ -115,12 +115,12 @@ document.addEventListener('alpine:init', () => { }, // # Local Storage Persistence storeGameState() { - localStorage.setItem(this.savedGameKey, JSON.stringify({ - startTime, - winTime, - gaveUpTime, - guessesBefore, - })); + // localStorage.setItem(this.savedGameKey, JSON.stringify({ + // startTime, + // winTime, + // gaveUpTime, + // guessesBefore, + // })); }, getStoredGameState() { if (!this.isLocalStorageAvailable) return undefined; diff --git a/src/alfagok/templates/index.html b/src/alfagok/templates/index.html index 5fc3501..3aca6db 100644 --- a/src/alfagok/templates/index.html +++ b/src/alfagok/templates/index.html @@ -11,7 +11,7 @@ - + From f52ae3cb8f0fa2f27ae7c56d41cf5d0b4c5f846e Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Sun, 24 Nov 2024 16:45:23 +0100 Subject: [PATCH 5/6] Cleaned up non-Alpine.js persistence code --- src/alfagok/static/game.js | 76 +++----------------------------- src/alfagok/templates/index.html | 2 +- 2 files changed, 6 insertions(+), 72 deletions(-) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index 5cfe4ee..81eb4fb 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -92,7 +92,10 @@ document.addEventListener('alpine:init', () => { this.winTime = new Date(); this.resultGameID = '🧩 Puzzel #' + this.gameID; this.resultGuesses = '🤔 '+ this.nrGuesses + ' gokken'; - this.resultTimeTaken = '⏱️ ' + getFormattedTime(this.winTime - this.startTime); + let winTimeDate = new Date(this.winTime); + let startTimeDate = new Date(this.startTime); + // this.resultTimeTaken = '⏱️ ' + getFormattedTime(this.winTime - this.startTime); + this.resultTimeTaken = '⏱️ ' + getFormattedTime(winTimeDate - startTimeDate); } }, setEmptyGameState() { @@ -114,77 +117,9 @@ document.addEventListener('alpine:init', () => { this.getGameID(); }, // # Local Storage Persistence - storeGameState() { - // localStorage.setItem(this.savedGameKey, JSON.stringify({ - // startTime, - // winTime, - // gaveUpTime, - // guessesBefore, - // })); - }, - getStoredGameState() { - if (!this.isLocalStorageAvailable) return undefined; - - const savedGameJson = localStorage.getItem(this.savedGameKey); - try { - return savedGameJson && JSON.parse(savedGameJson); - } catch (e) { - localStorage.removeItem(this.savedGameKey); - } - return undefined; - }, - loadGameState() { - const savedGame = this.getStoredGameState(); - - if (!savedGame || !savedGame.gameID || (savedGame.gameID !== this.gameID)) { - this.setEmptyGameState(); - return; - } - if (!savedGame || !savedGame.startTime) { - this.setEmptyGameState(); - return; - } - const startTime = new Date(savedGame.startTime); - if (!isPlayDateToday(app.playDate)) { - this.setEmptyGameState(); - return; - } - const savedGameForToday = getDOY(startTime) === getDOY(now()); - if (!savedGameForToday) { - this.resetSavedGames(); - this.setEmptyGameState(); - return; - } - const { - winTime, - guessesBefore, - guessesAfter, - guessValue, - } = savedGame; - const gaveUpTime = null; // to be implemented - this.startTime = startTime; - this.winTime = (winTime && new Date(winTime)) || null; - this.guessesBefore = guessesBefore || []; - this.guessesAfter = guessesAfter || []; - if (gaveUpTime || this.winTime) { - this.guessValue = guessValue; - } - }, - resetSavedGames() { + resetSavedGames() { localStorage.removeItem(this.savedGameKey); }, - testLocalStorage() { - // stolen from https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available - const test = 'test'; - try { - localStorage.setItem(test, test); - localStorage.removeItem(test); - this.isLocalStorageAvailable = true; - } catch (e) { - this.isLocalStorageAvailable = false; - } - console.log('Local storage is available? ' + this.isLocalStorageAvailable); - }, // # Countdown timer getFormattedTime(milliseconds) { if (!Number.isInteger(milliseconds)) { @@ -311,5 +246,4 @@ go(); document.addEventListener('alpine:initialized', () => { /* On AlpineJS completely loaded, do all this */ Alpine.store('alfagok').getGameID(); - Alpine.store('alfagok').testLocalStorage(); }) diff --git a/src/alfagok/templates/index.html b/src/alfagok/templates/index.html index 3aca6db..4a2562b 100644 --- a/src/alfagok/templates/index.html +++ b/src/alfagok/templates/index.html @@ -47,7 +47,7 @@

-

🔗 alfagok.diginaut.net

+

🔗 alfagok.diginaut.net

From 0ae7b8618f962e6b437ccec617e76d98c6ba1465 Mon Sep 17 00:00:00 2001 From: Michiel Scholten Date: Sun, 24 Nov 2024 16:49:00 +0100 Subject: [PATCH 6/6] Reset game state when new/different game has started --- src/alfagok/static/game.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/alfagok/static/game.js b/src/alfagok/static/game.js index 81eb4fb..f5e2699 100644 --- a/src/alfagok/static/game.js +++ b/src/alfagok/static/game.js @@ -35,6 +35,9 @@ document.addEventListener('alpine:init', () => { console.log(result); this.loading = false; if (result.game) { + if (this.gameID !== result.game) { + this.setEmptyGameState(); + } return this.gameID = result.game; } }, @@ -116,10 +119,6 @@ document.addEventListener('alpine:init', () => { this.getGameID(); }, - // # Local Storage Persistence - resetSavedGames() { - localStorage.removeItem(this.savedGameKey); - }, // # Countdown timer getFormattedTime(milliseconds) { if (!Number.isInteger(milliseconds)) {