From e6c67a52f0dde15447212d81765fe14b7b242915 Mon Sep 17 00:00:00 2001 From: JonathanMM Date: Fri, 19 May 2023 18:43:49 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20possibilit=C3=A9=20de=20jouer?= =?UTF-8?q?=20=C3=A0=20la=20partie=20de=20la=20veille?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 5 ++ public/jeu.css | 16 ++++-- ts/copieHelper.ts | 6 ++- ts/finDePartiePanel.ts | 31 ++++++++++- ts/gestionnaire.ts | 37 ++++++++++++- ts/sauvegardeur.ts | 120 ++++++++++++++++++++++++++++++++++++----- 6 files changed, 196 insertions(+), 19 deletions(-) diff --git a/public/index.html b/public/index.html index 1e7437f..04173f6 100644 --- a/public/index.html +++ b/public/index.html @@ -101,6 +101,11 @@ d="M216 960q-29.7 0-50.85-21.15Q144 917.7 144 888V336h72v552h456v72H216Zm144-144q-29.7 0-50.85-21.15Q288 773.7 288 744V264q0-29.7 21.15-50.85Q330.3 192 360 192h384q29.7 0 50.85 21.15Q816 234.3 816 264v480q0 29.7-21.15 50.85Q773.7 816 744 816H360Zm0-72h384V264H360v480Zm0 0V264v480Z" /> + + + diff --git a/public/jeu.css b/public/jeu.css index 36f7d0e..e2ce549 100644 --- a/public/jeu.css +++ b/public/jeu.css @@ -435,7 +435,7 @@ h1 { } .stats-numerique-case-valeur { - font-size: 28px; + font-size: 24px; } .stats-numerique-case-secondaire { @@ -477,16 +477,26 @@ h1 { text-align: start; } +#fin-de-partie-panel-partie-veille-area { + text-align: start; +} + +#fin-de-partie-panel-resume-bouton, +#fin-de-partie-panel-stats-bouton, +#fin-de-partie-panel-reset-bouton { + font-size: 1rem; + position: relative; +} + #fin-de-partie-panel-resume-bouton, #fin-de-partie-panel-stats-bouton { - font-size: 1rem; margin-left: 1rem; - position: relative; } .bouton-partage-texte { bottom: 4px; position: absolute; + width: max-content; } #config-sauvegarde-area { diff --git a/ts/copieHelper.ts b/ts/copieHelper.ts index b4b598f..2d59de5 100644 --- a/ts/copieHelper.ts +++ b/ts/copieHelper.ts @@ -29,6 +29,10 @@ export default class CopieHelper { } public static creerBoutonPartage(idBouton: string, label?: string): HTMLElement { + return this.creerBoutonAvecIcone(idBouton, "#icone-copie", label); + } + + public static creerBoutonAvecIcone(idBouton: string, icone: string, label?: string): HTMLElement { const lien = document.createElement("a"); lien.id = idBouton; lien.className = "bouton-partage"; @@ -36,7 +40,7 @@ export default class CopieHelper { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const useSvg = document.createElementNS("http://www.w3.org/2000/svg", "use") as SVGUseElement; - useSvg.setAttribute("href", "#icone-copie"); + useSvg.setAttribute("href", icone); useSvg.setAttribute("stroke", "var(--couleur-icone)"); useSvg.setAttribute("fill", "var(--couleur-icone)"); svg.appendChild(useSvg); diff --git a/ts/finDePartiePanel.ts b/ts/finDePartiePanel.ts index 0e7feb5..a61fc86 100644 --- a/ts/finDePartiePanel.ts +++ b/ts/finDePartiePanel.ts @@ -3,6 +3,7 @@ import Configuration from "./entites/configuration"; import LettreResultat from "./entites/lettreResultat"; import { LettreStatut } from "./entites/lettreStatut"; import SauvegardeStats from "./entites/sauvegardeStats"; +import Gestionnaire from "./gestionnaire"; import InstanceConfiguration from "./instanceConfiguration"; import PanelManager from "./panelManager"; import Sauvegardeur from "./sauvegardeur"; @@ -12,6 +13,7 @@ export default class FinDePartiePanel { private readonly _datePartie: Date; private readonly _panelManager: PanelManager; private readonly _statsButton: HTMLElement; + private readonly _gestionnaire: Gestionnaire; private _resumeTexte: string = ""; private _resumeTexteLegacy: string = ""; @@ -19,11 +21,12 @@ export default class FinDePartiePanel { private _estVictoire: boolean = false; private _partieEstFinie: boolean = false; - public constructor(datePartie: Date, panelManager: PanelManager) { + public constructor(datePartie: Date, panelManager: PanelManager, gestionnaire: Gestionnaire) { this._datePartie = new Date(datePartie); this._datePartie.setHours(0, 0, 0); this._panelManager = panelManager; this._statsButton = document.getElementById("configuration-stats-bouton") as HTMLElement; + this._gestionnaire = gestionnaire; this._statsButton.addEventListener( "click", @@ -132,6 +135,19 @@ export default class FinDePartiePanel {

"; } contenu += StatistiquesDisplayer.genererResumeTexte(this._resumeTexteLegacy).outerHTML; + + if (Sauvegardeur.hasPartieVeilleNonTerminee()) { + const partieVeilleArea = document.createElement("div"); + partieVeilleArea.id = "fin-de-partie-panel-partie-veille-area"; + + const partieVeilleLabel = document.createElement("div"); + partieVeilleLabel.innerText = "Il semblerait que vous n'avez pas terminé votre partie d'hier…"; + partieVeilleArea.appendChild(partieVeilleLabel); + + partieVeilleArea.appendChild(CopieHelper.creerBoutonAvecIcone("fin-de-partie-panel-reset-bouton", "#icone-restaure", "Terminer la partie")); + + contenu += partieVeilleArea.outerHTML; + } } let stats = Sauvegardeur.chargerSauvegardeStats(); @@ -143,6 +159,19 @@ export default class FinDePartiePanel { this._panelManager.setClasses(["fin-de-partie-panel"]); if (this._partieEstFinie) this.attacherPartage(); if (stats) this.attacherPartageStats(stats); + + const resetButton = document.getElementById("fin-de-partie-panel-reset-bouton") as HTMLElement; + if (resetButton) { + const veille = new Date(); + veille.setDate(veille.getDate() - 1); + resetButton.addEventListener( + "click", + (() => { + this._gestionnaire.chargerPartieAncienne(veille, Sauvegardeur.chargerPartieVeille()); + this._panelManager.cacherPanel(); + }).bind(this) + ); + } this._panelManager.afficherPanel(); } diff --git a/ts/gestionnaire.ts b/ts/gestionnaire.ts index d862f48..95fd94a 100644 --- a/ts/gestionnaire.ts +++ b/ts/gestionnaire.ts @@ -21,7 +21,7 @@ export default class Gestionnaire { private _grille: Grille | null = null; private _input: Input | null = null; private readonly _reglesPanel: ReglesPanel; - private readonly _finDePartiePanel: FinDePartiePanel; + private _finDePartiePanel: FinDePartiePanel; private readonly _configurationPanel: ConfigurationPanel; private readonly _propositions: Array; private readonly _resultats: Array>; @@ -65,7 +65,7 @@ export default class Gestionnaire { this._panelManager = new PanelManager(); this._themeManager = new ThemeManager(this._config); this._reglesPanel = new ReglesPanel(this._panelManager); - this._finDePartiePanel = new FinDePartiePanel(this._datePartieEnCours, this._panelManager); + this._finDePartiePanel = new FinDePartiePanel(this._datePartieEnCours, this._panelManager, this); this._configurationPanel = new ConfigurationPanel(this._panelManager, this._audioPanel, this._themeManager); this.choisirMot(this._idPartieEnCours, this._datePartieEnCours) @@ -269,4 +269,37 @@ export default class Gestionnaire { this._reglesPanel.afficher(); } + + public chargerPartieAncienne(datePartie: Date, etatPartie: PartieEnCours): void { + let partieEnCours = etatPartie; + + this._idPartieEnCours = this.getIdPartie(partieEnCours); + + if (this._idPartieEnCours !== partieEnCours.idPartie && partieEnCours.idPartie !== undefined) { + partieEnCours = new PartieEnCours(); + } + + if (partieEnCours.datePartie) { + this._datePartieEnCours = partieEnCours.datePartie; + } else { + this._datePartieEnCours = datePartie; + } + this._dateFinPartie = undefined; + + this._propositions.splice(0); + this._resultats.splice(0); + this._finDePartiePanel = new FinDePartiePanel(this._datePartieEnCours, this._panelManager, this); + + this.choisirMot(this._idPartieEnCours, this._datePartieEnCours) + .then(async (mot) => { + this._motATrouver = mot; + this._input = new Input(this, this._config, this._motATrouver.length, this._motATrouver[0]); + this._panelManager.setInput(this._input); + this._grille = new Grille(this._motATrouver.length, this._maxNbPropositions, this._motATrouver[0], this._audioPanel); + this._configurationPanel.setInput(this._input); + this._compositionMotATrouver = this.decompose(this._motATrouver); + await this.chargerPropositions(partieEnCours.propositions); + }) + .catch((raison) => NotificationMessage.ajouterNotification("Aucun mot n'a été trouvé pour aujourd'hui")); + } } diff --git a/ts/sauvegardeur.ts b/ts/sauvegardeur.ts index 4b76915..843497c 100644 --- a/ts/sauvegardeur.ts +++ b/ts/sauvegardeur.ts @@ -8,6 +8,7 @@ import NotificationMessage from "./notificationMessage"; export default class Sauvegardeur { private static readonly _cleStats = "statistiques"; private static readonly _clePartieEnCours = "partieEnCours"; + private static readonly _clePartieVeille = "partieVeille"; private static readonly _cleConfiguration = "configuration"; public static sauvegarderStats(stats: SauvegardeStats): void { @@ -48,19 +49,54 @@ export default class Sauvegardeur { } public static chargerSauvegardePartieEnCours(): PartieEnCours | undefined { - let dataPartieEnCours = localStorage.getItem(this._clePartieEnCours); - if (!dataPartieEnCours) return; - - let partieEnCours = JSON.parse(dataPartieEnCours) as SauvegardePartie; let aujourdhui = new Date(); - let datePartieEnCours = new Date(partieEnCours.datePartie); - if ( - aujourdhui.getDate() !== datePartieEnCours.getDate() || - aujourdhui.getMonth() !== datePartieEnCours.getMonth() || - aujourdhui.getFullYear() !== datePartieEnCours.getFullYear() - ) { - localStorage.removeItem(this._clePartieEnCours); - return; + let partieEnCours: SauvegardePartie; + let datePartieEnCours: Date; + + let dataPartieEnCours = localStorage.getItem(this._clePartieEnCours); + if (!dataPartieEnCours) { + // On regarde si par hasard, on n'a pas la partie du jour dans les infos de la veille + const partieVeille = this.getInfoVeille(); + + if ( + partieVeille && + aujourdhui.getDate() === partieVeille.datePartie.getDate() && + aujourdhui.getMonth() === partieVeille.datePartie.getMonth() && + aujourdhui.getFullYear() === partieVeille.datePartie.getFullYear() + ) { + partieEnCours = partieVeille; + datePartieEnCours = partieVeille.datePartie; + localStorage.removeItem(this._clePartieVeille); + } else { + return; + } + } else { + partieEnCours = JSON.parse(dataPartieEnCours) as SauvegardePartie; + datePartieEnCours = new Date(partieEnCours.datePartie); + if ( + aujourdhui.getDate() !== datePartieEnCours.getDate() || + aujourdhui.getMonth() !== datePartieEnCours.getMonth() || + aujourdhui.getFullYear() !== datePartieEnCours.getFullYear() + ) { + // On regarde si par hasard, on n'a pas la partie du jour dans les infos de la veille + const partieVeille = this.getInfoVeille(); + + if ( + partieVeille && + aujourdhui.getDate() === partieVeille.datePartie.getDate() && + aujourdhui.getMonth() === partieVeille.datePartie.getMonth() && + aujourdhui.getFullYear() === partieVeille.datePartie.getFullYear() + ) { + partieEnCours = partieVeille; + datePartieEnCours = partieVeille.datePartie; + // Et on inverse les données + localStorage.setItem(this._clePartieVeille, dataPartieEnCours); + } else { + localStorage.setItem(this._clePartieVeille, dataPartieEnCours); + localStorage.removeItem(this._clePartieEnCours); + return; + } + } } let dateFinPartie = partieEnCours.dateFinPartie === undefined ? undefined : new Date(partieEnCours.dateFinPartie); @@ -72,6 +108,66 @@ export default class Sauvegardeur { }; } + private static getInfoVeille(): SauvegardePartie | undefined { + const dataPartieVeille = localStorage.getItem(this._clePartieVeille); + if (!dataPartieVeille) return undefined; + + const veille = new Date(); + veille.setDate(veille.getDate() - 1); + + let partieVeille = JSON.parse(dataPartieVeille) as SauvegardePartie; + if (partieVeille.datePartie) partieVeille.datePartie = new Date(partieVeille.datePartie); + if (partieVeille.dateFinPartie) partieVeille.dateFinPartie = new Date(partieVeille.dateFinPartie); + return partieVeille; + } + + public static hasPartieVeilleNonTerminee(): boolean { + const partieVeille = this.getInfoVeille(); + if (!partieVeille) return true; + + const veille = new Date(); + veille.setDate(veille.getDate() - 1); + + return ( + veille.getDate() === partieVeille.datePartie.getDate() && + veille.getMonth() === partieVeille.datePartie.getMonth() && + veille.getFullYear() === partieVeille.datePartie.getFullYear() && + !partieVeille.dateFinPartie + ); + } + + public static chargerPartieVeille(): PartieEnCours { + const veille = new Date(); + veille.setDate(veille.getDate() - 1); + const partieVeille = this.getInfosPartieVeille(veille); + let dateFinPartie = partieVeille.dateFinPartie === undefined ? undefined : new Date(partieVeille.dateFinPartie); + + // On va sauvegarder la partie en cours dans la veille pour ne pas la perde + const partieEnCours = localStorage.getItem(this._clePartieEnCours); + if (partieEnCours) { + localStorage.setItem(this._clePartieVeille, partieEnCours); + localStorage.removeItem(this._clePartieEnCours); + } + + return { + datePartie: new Date(partieVeille.datePartie), + dateFinPartie: dateFinPartie, + propositions: partieVeille.propositions, + idPartie: partieVeille.idPartie, + }; + } + + private static getInfosPartieVeille(veille: Date): SauvegardePartie { + const dataPartieVeille = localStorage.getItem(this._clePartieVeille); + if (!dataPartieVeille) { + const dataPartie = new SauvegardePartie(); + dataPartie.datePartie = veille; + return dataPartie; + } + + return JSON.parse(dataPartieVeille) as SauvegardePartie; + } + public static sauvegarderConfig(config: Configuration): void { localStorage.setItem(this._cleConfiguration, JSON.stringify(config)); }