= ({version, className}) => {
return (
-
Version {environment.version}
+
Version {version}
boolean;
+
+ version: string;
}
export const OptionsDialog: FC> =
({
selectWelcoming = GameSelectors.welcoming,
- selectOpen = AppSelectors.isOpen(AppDialogType.OPTIONS)
+ selectOpen = AppSelectors.isOpen(AppDialogType.OPTIONS),
+ version
}) => {
const welcoming = useSelector(selectWelcoming);
return (
@@ -25,7 +28,7 @@ export const OptionsDialog: FC> =
selectOpen={selectOpen}
>
-
+
);
};
diff --git a/src/components/particles/audio.types.tsx b/src/components/particles/audio.types.tsx
index 6417758..6eb954e 100644
--- a/src/components/particles/audio.types.tsx
+++ b/src/components/particles/audio.types.tsx
@@ -4,18 +4,18 @@ import {environment} from '../../environment/environment';
import {UiOption} from './ui/UiSelect';
export const AUDIO_FILES = [
- `${environment.base}/audio/music/bonkers-for-arcades.mp3`,
- `${environment.base}/audio/music/the-ice-cream-man.mp3`,
- `${environment.base}/audio/music/8-bit-perplexion.mp3`,
- `${environment.base}/audio/music/its-raining-pixels.mp3`,
- `${environment.base}/audio/music/arcade-puzzler.mp3`
+ `${environment.base}audio/music/bonkers-for-arcades.mp3`,
+ `${environment.base}audio/music/the-ice-cream-man.mp3`,
+ `${environment.base}audio/music/8-bit-perplexion.mp3`,
+ `${environment.base}audio/music/its-raining-pixels.mp3`,
+ `${environment.base}audio/music/arcade-puzzler.mp3`
];
-export const SOUND_FINISHED = `${environment.base}/audio/sounds/power-down-13.mp3`;
-export const SOUND_LEVEL = `${environment.base}/audio/sounds/retro-chip-power.mp3`;
-export const SOUND_SCORE = `${environment.base}/audio/sounds/ui-quirky-19.mp3`;
-export const SOUND_DROP = `${environment.base}/audio/sounds/zapsplat_bambo_swoosh.mp3`;
-export const SOUND_LEVEL_10 = `${environment.base}/audio/sounds/zapsplat_level_up.mp3`;
+export const SOUND_FINISHED = `${environment.base}audio/sounds/power-down-13.mp3`;
+export const SOUND_LEVEL = `${environment.base}audio/sounds/retro-chip-power.mp3`;
+export const SOUND_SCORE = `${environment.base}audio/sounds/ui-quirky-19.mp3`;
+export const SOUND_DROP = `${environment.base}audio/sounds/zapsplat_bambo_swoosh.mp3`;
+export const SOUND_LEVEL_10 = `${environment.base}audio/sounds/zapsplat_level_up.mp3`;
export const PRELOAD_AUDIO = [
SOUND_FINISHED,
diff --git a/src/components/particles/hooks/usePersist.tsx b/src/components/particles/hooks/usePersist.tsx
index 1925a95..945daa7 100644
--- a/src/components/particles/hooks/usePersist.tsx
+++ b/src/components/particles/hooks/usePersist.tsx
@@ -2,10 +2,10 @@ import {useEffect} from 'react';
import {useSelector} from 'react-redux';
import {useAppDispatch} from '../../../store/app-store';
import {AppActions} from '../../../store/app/app-actions';
-import {APP_PERSIST_DEFAULT, AppPersist} from '../../../store/app/app-model';
+import {AppPersist} from '../../../store/app/app-model';
import {AppSelectors} from '../../../store/app/app-selectors';
-export const usePersist = (storageKey: string) => {
+export const usePersist = (version: string, storageKey: string) => {
const persist = useSelector(AppSelectors.persist);
const dispatch = useAppDispatch();
@@ -13,17 +13,18 @@ export const usePersist = (storageKey: string) => {
const json = localStorage.getItem(storageKey);
if (json) {
try {
- const data: AppPersist = JSON.parse(json);
- if (data?.version === APP_PERSIST_DEFAULT.version) {
- dispatch(AppActions.persist(data));
+ const data: AppPersist & {version: string} = JSON.parse(json);
+ if (data?.version === version) {
+ const {version, ...state} = data;
+ dispatch(AppActions.persist(state));
}
} catch (err) {
console.error('Could not read persist data.', err);
}
}
- }, [storageKey, dispatch]);
+ }, [version, storageKey, dispatch]);
useEffect(() => {
- localStorage.setItem(storageKey, JSON.stringify(persist));
- }, [storageKey, persist]);
+ localStorage.setItem(storageKey, JSON.stringify({...persist, version}));
+ }, [version, storageKey, persist]);
};
diff --git a/src/components/templates/App.tsx b/src/components/templates/App.tsx
index caaa517..3c9ccd2 100644
--- a/src/components/templates/App.tsx
+++ b/src/components/templates/App.tsx
@@ -18,14 +18,18 @@ import {GameDesktop} from './GameDesktop';
import {GameMobile} from './GameMobile';
import {Welcome} from './Welcome';
-export const App: FC = () => {
+export interface AppProps {
+ version: string;
+}
+
+export const App: FC = ({version}) => {
const welcoming = useSelector(GameSelectors.welcoming);
const isWideScreen = useMediaQuery('(min-width:600px)');
const isShortScreen = useMediaQuery('(max-height:850px)');
const isNarrowScreen = useMediaQuery('(max-width:380px)');
usePageView('/');
- usePersist(environment.storageKey);
+ usePersist(version, environment.storageKey);
useTitle();
const game = useMemo(() => {
@@ -49,7 +53,7 @@ export const App: FC = () => {
-
+
);
diff --git a/src/environment/environment.ts b/src/environment/environment.ts
index 555cf95..94b5230 100644
--- a/src/environment/environment.ts
+++ b/src/environment/environment.ts
@@ -1,3 +1,5 @@
+const endsInSlash = (str: string): string => str.endsWith('/') ? str : `${str}/`;
+
export interface Environment {
analytics: string;
@@ -9,6 +11,9 @@ export interface Environment {
storageKey: string;
+ /**
+ * @deprecated
+ */
version: string;
}
@@ -18,5 +23,5 @@ export const environment: Environment = {
github: process.env.NEXT_PUBLIC_GITHUB as string,
storageKey: process.env.NEXT_PUBLIC_STORAGE_KEY as string,
version: process.env.NEXT_PUBLIC_VERSION as string,
- base: process.env.NEXT_PUBLIC_BASE as string
+ base: endsInSlash(process.env.NEXT_PUBLIC_BASE as string ?? '/')
};
diff --git a/src/store/app/app-model.ts b/src/store/app/app-model.ts
index 32be5fa..d66fdc7 100644
--- a/src/store/app/app-model.ts
+++ b/src/store/app/app-model.ts
@@ -102,23 +102,6 @@ export type AppPersist = Pick<
| 'music_type'
| 'high_scores'
| 'keys'
-> & {version: string};
-
-/**
- * Defaults persist values.
- */
-export const APP_PERSIST_DEFAULT: AppPersist = {
- dark: APP_INITIAL_STATE.dark,
- ghost_piece: APP_INITIAL_STATE.ghost_piece,
- start_level: APP_INITIAL_STATE.start_level,
- sound: APP_INITIAL_STATE.sound,
- sound_volume: APP_INITIAL_STATE.sound_volume,
- music: APP_INITIAL_STATE.music,
- music_volume: APP_INITIAL_STATE.music_volume,
- music_type: APP_INITIAL_STATE.music_type,
- high_scores: APP_INITIAL_STATE.high_scores,
- keys: APP_INITIAL_STATE.keys,
- version: environment.version
-};
+>;
export const APP_NAME = 'app';
diff --git a/src/store/app/app-selectors.ts b/src/store/app/app-selectors.ts
index ec2b938..d1d456a 100644
--- a/src/store/app/app-selectors.ts
+++ b/src/store/app/app-selectors.ts
@@ -1,7 +1,6 @@
import {createSelector} from '@reduxjs/toolkit';
-import {environment} from '../../environment/environment';
import {selectRoot} from '../select-root';
-import {AppDialogType, AppPersist} from './app-model';
+import {AppDialogType, AppModel, AppPersist} from './app-model';
export namespace AppSelectors {
/**
@@ -97,7 +96,6 @@ export namespace AppSelectors {
keys
): AppPersist => {
return {
- version: environment.version,
dark,
ghost_piece,
start_level,
diff --git a/src/store/app/app-state.ts b/src/store/app/app-state.ts
index df0a3f6..c12ebe9 100644
--- a/src/store/app/app-state.ts
+++ b/src/store/app/app-state.ts
@@ -1,9 +1,8 @@
import {createSlice} from '@reduxjs/toolkit';
import ReactGA from 'react-ga';
import {KEY_BINDINGS} from '../../components/particles/key_bindings.types';
-import {environment} from '../../environment/environment';
import {AppActions} from './app-actions';
-import {APP_INITIAL_STATE, APP_NAME} from './app-model';
+import {APP_INITIAL_STATE, APP_NAME, AppModel} from './app-model';
export namespace AppState {
const track = (action: string, value?: number) => {
@@ -104,13 +103,7 @@ export namespace AppState {
};
})
.addCase(AppActions.persist, (state, {payload}) => {
- const {version, ...restore} = payload;
- if (version === environment.version) {
- return {
- ...state,
- ...restore
- };
- }
+ return {...payload} satisfies AppModel;
});
}
});