diff --git a/app/components/maps/SidebarSettings.tsx b/app/components/maps/SidebarSettings.tsx index 97fc5c4b..de0225fa 100644 --- a/app/components/maps/SidebarSettings.tsx +++ b/app/components/maps/SidebarSettings.tsx @@ -21,8 +21,9 @@ const SidebarSettings = (): JSX.Element => { showInputOverlay, setShowInputOverlay, replayLineOpacity, setReplayLineOpacity, replayCarOpacity, setReplayCarOpacity, - showFullTrail, setShowFullTrail, - showTrailToStart, setShowTrailToStart, + showFullTrail, changeShowFullTrail, + showTrailToStart, changeShowTrailToStart, + revealTrailTime, changeRevealTrailTime, } = useContext( SettingsContext, ); @@ -125,7 +126,7 @@ const SidebarSettings = (): JSX.Element => { className="select-none" checked={showFullTrail} onChange={(e) => { - setShowFullTrail(e.target.checked); + changeShowFullTrail(e.target.checked); timeLineGlobal.showFullTrail = e.target.checked; }} > @@ -138,7 +139,7 @@ const SidebarSettings = (): JSX.Element => { disabled={showFullTrail} checked={showTrailToStart} onChange={(e) => { - setShowTrailToStart(e.target.checked); + changeShowTrailToStart(e.target.checked); timeLineGlobal.showTrailToStart = e.target.checked; }} > @@ -154,13 +155,13 @@ const SidebarSettings = (): JSX.Element => { addonAfter="ms" className="w-full" disabled={showFullTrail || showTrailToStart} - defaultValue={timeLineGlobal.revealTrailTime} + defaultValue={revealTrailTime} min={0} step={100} precision={0} onChange={(e) => { if (typeof e === 'number') { - timeLineGlobal.revealTrailTime = e; + changeRevealTrailTime(e); } }} /> diff --git a/app/lib/api/reactQuery/hooks/localStorage/localStorage.ts b/app/lib/api/reactQuery/hooks/localStorage/localStorage.ts new file mode 100644 index 00000000..acbecede --- /dev/null +++ b/app/lib/api/reactQuery/hooks/localStorage/localStorage.ts @@ -0,0 +1,18 @@ +import { useState } from 'react'; +import store from 'store2'; + +const useLocalStorage = (key: string, initialValue: any) => { + const [storedValue, setStoredValue] = useState(() => { + const item = store.get(key); + return item !== null ? item : initialValue; + }); + + const setValue = (value: any) => { + setStoredValue(value); + store.set(key, value); + }; + + return [storedValue, setValue]; +}; + +export default useLocalStorage; diff --git a/app/lib/contexts/SettingsContext.constants.ts b/app/lib/contexts/SettingsContext.constants.ts new file mode 100644 index 00000000..0c002ed1 --- /dev/null +++ b/app/lib/contexts/SettingsContext.constants.ts @@ -0,0 +1,10 @@ +/* eslint-disable import/prefer-default-export */ + +export const SHOW_GEAR_CHANGE = false; +export const SHOW_FPS = false; +export const SHOW_INPUT_OVERLAY = true; +export const REPLAY_LINE_OPACITY = 0.5; +export const REPLAY_CAR_OPACITY = 0.5; +export const SHOW_FULL_TRAIL = true; +export const SHOW_TRAIL_TO_START = true; +export const REVEAL_TRAIL_TIME = 1000; diff --git a/app/lib/contexts/SettingsContext.tsx b/app/lib/contexts/SettingsContext.tsx index 9e80d438..8a30e9a7 100644 --- a/app/lib/contexts/SettingsContext.tsx +++ b/app/lib/contexts/SettingsContext.tsx @@ -1,6 +1,16 @@ import React, { createContext, useState } from 'react'; +import store from 'store2'; import { LineType, LineTypes } from '../../components/viewer/ReplayLines'; import GlobalTimeLineInfos from '../singletons/timeLineInfos'; +import useLocalStorage from '../api/reactQuery/hooks/localStorage/localStorage'; +import { + REPLAY_CAR_OPACITY, + REPLAY_LINE_OPACITY, + REVEAL_TRAIL_TIME, + SHOW_FPS, SHOW_FULL_TRAIL, SHOW_GEAR_CHANGE, + SHOW_INPUT_OVERLAY, + SHOW_TRAIL_TO_START, +} from './SettingsContext.constants'; // eslint false positive https://stackoverflow.com/questions/63961803/ // eslint-disable-next-line no-shadow @@ -28,45 +38,114 @@ export interface SettingsContextProps { numColorChange: number; setNumColorChange: (numColorChange: number) => void; showFullTrail: boolean; - setShowFullTrail: (showFullTrail: boolean) => void; + changeShowFullTrail: (showFullTrail: boolean) => void; showTrailToStart: boolean; - setShowTrailToStart: (showFullTrail: boolean) => void; + changeShowTrailToStart: (showFullTrail: boolean) => void; + revealTrailTime: number; + changeRevealTrailTime: (revealTrailTime: number) => void; } export const SettingsContext = createContext({ lineType: LineTypes.default, changeLineType: () => { }, - showGearChanges: false, + showGearChanges: SHOW_GEAR_CHANGE, setShowGearChanges: () => { }, - showFPS: false, + showFPS: SHOW_FPS, setShowFPS: () => { }, - showInputOverlay: true, + showInputOverlay: SHOW_INPUT_OVERLAY, setShowInputOverlay: () => { }, - replayLineOpacity: 0.5, + replayLineOpacity: REPLAY_LINE_OPACITY, setReplayLineOpacity: () => { }, - replayCarOpacity: 0.5, + replayCarOpacity: REPLAY_CAR_OPACITY, setReplayCarOpacity: () => { }, numColorChange: 0, setNumColorChange: () => { }, - showFullTrail: timeLineInfos.showFullTrail, - setShowFullTrail: () => { }, - showTrailToStart: timeLineInfos.showTrailToStart, - setShowTrailToStart: () => { }, + showFullTrail: SHOW_FULL_TRAIL, + changeShowFullTrail: () => { }, + showTrailToStart: SHOW_TRAIL_TO_START, + changeShowTrailToStart: () => { }, + revealTrailTime: REVEAL_TRAIL_TIME, + changeRevealTrailTime: () => { }, }); +const getLineType = (): LineType => { + const storedLineType = store.get('lineType'); + + if (storedLineType && LineTypes[storedLineType.toLowerCase()] !== null) { + const storedLineTypeValue = LineTypes[storedLineType.toLowerCase()]; + return storedLineTypeValue; + } + + return LineTypes.default; +}; + +const getShowFullTrail = (): boolean => { + const storedShowFullTrail = store.get('showFullTrail'); + + if (storedShowFullTrail !== null) { + timeLineInfos.showFullTrail = storedShowFullTrail; + return storedShowFullTrail; + } + + timeLineInfos.showFullTrail = SHOW_FULL_TRAIL; + return SHOW_FULL_TRAIL; +}; +const getShowTrailToStart = (): boolean => { + const storedShowTrailToStart = store.get('showTrailToStart'); + + if (storedShowTrailToStart !== null) { + timeLineInfos.showTrailToStart = storedShowTrailToStart; + return storedShowTrailToStart; + } + + timeLineInfos.showTrailToStart = SHOW_TRAIL_TO_START; + return SHOW_TRAIL_TO_START; +}; + +const getRevealTrailTime = (): number => { + const storedRevealTrailTime = store.get('revealTrailTime'); + + if (storedRevealTrailTime !== null) { + timeLineInfos.revealTrailTime = storedRevealTrailTime; + return storedRevealTrailTime; + } + + timeLineInfos.revealTrailTime = REVEAL_TRAIL_TIME; + return REVEAL_TRAIL_TIME; +}; + export const SettingsProvider = ({ children }: any): JSX.Element => { - const [lineType, setLineType] = useState(LineTypes.default); - const [showGearChanges, setShowGearChanges] = useState(false); - const [showFPS, setShowFPS] = useState(false); - const [showInputOverlay, setShowInputOverlay] = useState(true); - const [replayLineOpacity, setReplayLineOpacity] = useState(0.5); - const [replayCarOpacity, setReplayCarOpacity] = useState(0.5); + const [lineType, setLineType] = useState(getLineType()); + const [showGearChanges, setShowGearChanges] = useLocalStorage('showGearChanges', SHOW_GEAR_CHANGE); + const [showFPS, setShowFPS] = useLocalStorage('showFPS', SHOW_FPS); + const [showInputOverlay, setShowInputOverlay] = useLocalStorage('showInputOverlay', SHOW_INPUT_OVERLAY); + const [replayLineOpacity, setReplayLineOpacity] = useLocalStorage('replayLineOpacity', REPLAY_LINE_OPACITY); + const [replayCarOpacity, setReplayCarOpacity] = useLocalStorage('replayCarOpacity', REPLAY_CAR_OPACITY); const [numColorChange, setNumColorChange] = useState(0); - const [showFullTrail, setShowFullTrail] = useState(timeLineInfos.showFullTrail); - const [showTrailToStart, setShowTrailToStart] = useState(timeLineInfos.showTrailToStart); + const [showFullTrail, setShowFullTrail] = useState(getShowFullTrail()); + const [showTrailToStart, setShowTrailToStart] = useState(getShowTrailToStart()); + const [revealTrailTime, setRevealTrailTime] = useState(getRevealTrailTime()); const changeLineType = (type: LineType) => { setLineType(type); + store.set('lineType', type.name); + }; + + const changeShowFullTrail = (show: boolean) => { + setShowFullTrail(show); + timeLineInfos.showFullTrail = show; + store.set('showFullTrail', show); + }; + const changeShowTrailToStart = (show: boolean) => { + setShowTrailToStart(show); + timeLineInfos.showTrailToStart = show; + store.set('showTrailToStart', show); + }; + + const changeRevealTrailTime = (time: number) => { + setRevealTrailTime(time); + timeLineInfos.revealTrailTime = time; + store.set('revealTrailTime', time); }; return ( @@ -87,9 +166,11 @@ export const SettingsProvider = ({ children }: any): JSX.Element => { numColorChange, setNumColorChange, showFullTrail, - setShowFullTrail, + changeShowFullTrail, showTrailToStart, - setShowTrailToStart, + changeShowTrailToStart, + revealTrailTime, + changeRevealTrailTime, }} > {children} diff --git a/app/package-lock.json b/app/package-lock.json index 77d324e0..59e85447 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -28,6 +28,7 @@ "react": "^17.0.2", "react-color": "^2.19.3", "react-dom": "^17.0.2", + "store2": "^2.14.2", "tailwindcss": "^2.1.2", "three": "^0.128.0", "three-stdlib": "^2.3.0", @@ -8613,6 +8614,11 @@ "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", "integrity": "sha1-scPcRtlEmLV4t/05hbgaznExzH0=" }, + "node_modules/store2": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz", + "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==" + }, "node_modules/string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", @@ -16079,6 +16085,11 @@ "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", "integrity": "sha1-scPcRtlEmLV4t/05hbgaznExzH0=" }, + "store2": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz", + "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==" + }, "string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", diff --git a/app/package.json b/app/package.json index 08b5fffb..063e3ffb 100644 --- a/app/package.json +++ b/app/package.json @@ -30,6 +30,7 @@ "react": "^17.0.2", "react-color": "^2.19.3", "react-dom": "^17.0.2", + "store2": "^2.14.2", "tailwindcss": "^2.1.2", "three": "^0.128.0", "three-stdlib": "^2.3.0", @@ -57,4 +58,4 @@ "postcss": "^8.2.8", "typescript": "^4.3.2" } -} \ No newline at end of file +}