✨ Save score in IndexedDB
This commit is contained in:
@@ -3,18 +3,36 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------- Styles --------------------------------------------------------
|
||||
import { useRef } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import './styles.scss';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { gameStateAtom } from '../../contexts/gameState';
|
||||
import localforage from 'localforage';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const store = localforage.createInstance({
|
||||
name: 'leaderboard',
|
||||
driver: localforage.INDEXEDDB,
|
||||
version: 1.0,
|
||||
storeName: 'leaderboard',
|
||||
description: 'Store 10 best game time',
|
||||
});
|
||||
|
||||
const Home = () => {
|
||||
const difficultyRef = useRef<HTMLSelectElement>(null);
|
||||
const sizeRef = useRef<HTMLSelectElement>(null);
|
||||
|
||||
const [, setGameState] = useRecoilState(gameStateAtom);
|
||||
|
||||
useEffect(() => {
|
||||
const initIDB = async () => {
|
||||
if ((await store.getItem('leaderboard')) === null) {
|
||||
await store.setItem('leaderboard', []);
|
||||
}
|
||||
};
|
||||
initIDB();
|
||||
}, []);
|
||||
|
||||
const onClick = () => {
|
||||
if (difficultyRef.current !== null && sizeRef.current !== null) {
|
||||
const difficulty = difficultyRef.current.value;
|
||||
|
||||
@@ -39,9 +39,8 @@ const LeaderBoard = () => {
|
||||
useEffect(() => {
|
||||
const getData = async () => {
|
||||
const storeData = await store.getItem<LeaderBoardItem[]>('leaderboard');
|
||||
if (storeData) {
|
||||
setData(storeData);
|
||||
}
|
||||
|
||||
setData(storeData || []);
|
||||
};
|
||||
|
||||
if (data.length === 0) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import Clock from '../../../assets/clock';
|
||||
import '../styles.scss';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { gameStateAtom } from '../../../contexts/gameState';
|
||||
import { saveToLocalStorage } from '../../../utils/generics';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const Timer = () => {
|
||||
@@ -53,7 +54,9 @@ const Timer = () => {
|
||||
...prev,
|
||||
gameTime: displayedTime,
|
||||
}));
|
||||
|
||||
clearInterval(intervalId);
|
||||
saveToLocalStorage(displayedTime);
|
||||
}
|
||||
}, [intervalId, gameState.endType, setGameState, displayedTime]);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { atom } from 'recoil';
|
||||
export const gameStateAtom = atom({
|
||||
key: 'gameState',
|
||||
default: {
|
||||
status: 'settings',
|
||||
status: 'board',
|
||||
difficulty: 'beginner',
|
||||
gridSize: 12,
|
||||
bombs: 0,
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
export type Difficulty = 'beginner' | 'intermediate' | 'expert';
|
||||
export type CellValue = 'empty' | 'bomb' | number;
|
||||
export type GridType = { hidden: boolean; value: CellValue; flag: boolean }[][];
|
||||
export type LeaderBoardItem = { date: string; time: `${number | ''}${number}m ${number}${number}s` };
|
||||
export type LeaderBoardItem = { date: string; time: string };
|
||||
|
||||
@@ -1,3 +1,46 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
//! Imports
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------- Stockage -------------------------------------------------------
|
||||
import localforage from 'localforage';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------ Types --------------------------------------------------------
|
||||
import { LeaderBoardItem } from '../types/game';
|
||||
// ---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
export const getRandomArbitrary = (min: number, max: number): number => {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
};
|
||||
|
||||
const store = localforage.createInstance({
|
||||
name: 'leaderboard',
|
||||
driver: localforage.INDEXEDDB,
|
||||
version: 1.0,
|
||||
storeName: 'leaderboard',
|
||||
description: 'Store 10 best game time',
|
||||
});
|
||||
|
||||
export const saveToLocalStorage = async (time: string) => {
|
||||
let leaderboard = await store.getItem<LeaderBoardItem[]>('leaderboard');
|
||||
|
||||
const currentDate = new Date().toLocaleString().split(' ')[0];
|
||||
|
||||
if (!leaderboard) {
|
||||
leaderboard = [];
|
||||
}
|
||||
|
||||
leaderboard.push({
|
||||
date: currentDate,
|
||||
time: `${time.replace(':', 'm ')}s`,
|
||||
});
|
||||
|
||||
leaderboard = leaderboard.sort((a, b) => (a.time > b.time ? 1 : -1));
|
||||
|
||||
if (leaderboard.length > 20) {
|
||||
leaderboard = leaderboard.slice(0, 20);
|
||||
}
|
||||
|
||||
await store.setItem('leaderboard', leaderboard);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user