/ src / Storage.ts
Storage.ts
  1  import { Level, LevelDynamic, LevelManager, LevelUser } from './Level'
  2  
  3  const LEVELS_STORAGE_KEY = 'levels'
  4  
  5  export class Storage {
  6    private readonly levelManager: LevelManager
  7  
  8    public constructor(levelManager: LevelManager) {
  9      this.levelManager = levelManager
 10    }
 11  
 12    public getLevels(): { [key: string]: Level } {
 13      const levels: { [key: string]: Level } = {}
 14  
 15      const levelsUser = this.getLevelsUser()
 16  
 17      let previousLevel: Level | null = null
 18  
 19      for (const [ name, fixed ] of Object.entries(this.levelManager.getLevels())) {
 20        let accessible = false
 21  
 22        if (levelsUser[name].success) {
 23          accessible = true
 24        } else {
 25          if (previousLevel === null) {
 26            accessible = true
 27          } else {
 28            accessible = previousLevel.user.success
 29          }
 30        }
 31  
 32        const dynamic: LevelDynamic = {
 33          accessible,
 34        }
 35  
 36        const level: Level = {
 37          fixed,
 38          dynamic,
 39          user: levelsUser[name],
 40        }
 41  
 42        levels[name] = level
 43  
 44        previousLevel = level
 45      }
 46  
 47      return levels
 48    }
 49  
 50    public successfulLevel(levelName: string): void {
 51      const levels = this.getStoredLevels()
 52  
 53      levels[levelName].success = true
 54  
 55      this.saveLevels(levels)
 56    }
 57  
 58    public reset(): void {
 59      localStorage.clear()
 60    }
 61  
 62    public getNextLevelOf(levelName: string): Level | null {
 63      const levels = this.getLevels()
 64  
 65      const keys = Object.keys(levels)
 66      const nextIndex = keys.indexOf(levelName) + 1
 67      const nextLevelName = keys[nextIndex]
 68  
 69      if (nextLevelName in levels) {
 70        return levels[nextLevelName]
 71      }
 72  
 73      return null
 74    }
 75  
 76    /**
 77     * Tous les niveaux ont-ils été réussis ?
 78     */
 79    public areAllLevelsSucceeded(): boolean {
 80      const levels = this.getLevels()
 81  
 82      for (const [_name, level] of Object.entries(levels)) {
 83        // Dès qu'on rencontre un niveau non-réussi, on retourne `false`
 84        if (!level.user.success) {
 85          return false
 86        }
 87      }
 88  
 89      return true
 90    }
 91  
 92    private getLevelsUser(): { [key: string]: LevelUser } {
 93      const levels: { [key: string]: LevelUser } = {}
 94  
 95      for (const [ name ] of Object.entries(this.levelManager.getLevels())) {
 96        levels[name] = {
 97          success: false,
 98        }
 99      }
100  
101      const l = this.getStoredLevels()
102  
103      for (const [ name, level ] of Object.entries(l)) {
104        if (name in levels) {
105          levels[name] = level
106        }
107      }
108  
109      this.saveLevels(levels)
110  
111      return levels
112    }
113  
114    private getStoredLevels(): { [key: string]: LevelUser } {
115      if (localStorage.getItem(LEVELS_STORAGE_KEY) !== null) {
116        const jsonLevels = localStorage.getItem(LEVELS_STORAGE_KEY)
117  
118        let levels: { [key: string]: LevelUser } = {}
119  
120        try {
121          levels = JSON.parse(jsonLevels) as { [key: string]: LevelUser }
122        } catch (e) {
123          // Si la donnée est corrompue, on repart à zéro
124          return {}
125        }
126  
127        return levels
128      }
129  
130      return {}
131    }
132  
133    private saveLevels(levels: { [key: string]: LevelUser }): void {
134      localStorage.setItem(LEVELS_STORAGE_KEY, JSON.stringify(levels))
135    }
136  }