diff --git a/client/src/components/app_bar.tsx b/client/src/components/app_bar.tsx index c1d1a10..2c65a81 100644 --- a/client/src/components/app_bar.tsx +++ b/client/src/components/app_bar.tsx @@ -103,7 +103,6 @@ function InputModeButton({setNavOpen, isDropdown}) { /** toggle input mode if allowed */ function toggleInputMode(ev: React.MouseEvent) { if (!lockInputMode){ - localStorage.setItem("lean4game:typewriterMode", JSON.stringify(!typewriterMode)) setTypewriterMode(!typewriterMode) setNavOpen(false) } diff --git a/client/src/components/level.tsx b/client/src/components/level.tsx index c77b354..ccfbf17 100644 --- a/client/src/components/level.tsx +++ b/client/src/components/level.tsx @@ -22,7 +22,7 @@ import { ConnectionContext, connection, useLeanClient } from '../connection' import { useAppDispatch, useAppSelector } from '../hooks' import { useGetGameInfoQuery, useLoadInventoryOverviewQuery, useLoadLevelQuery } from '../state/api' import { changedSelection, codeEdited, selectCode, selectSelections, selectCompleted, helpEdited, - selectHelp, selectDifficulty, selectInventory } from '../state/progress' + selectHelp, selectDifficulty, selectInventory, selectTypewriterMode, changeTypewriterMode } from '../state/progress' import { store } from '../state/store' import { Button } from './button' import Markdown from './markdown' @@ -204,12 +204,17 @@ function PlayableLevel({impressum, setImpressum}) { const {worldId, levelId} = useContext(WorldLevelIdContext) const {mobile} = React.useContext(MobileContext) + const dispatch = useAppDispatch() + const difficulty = useSelector(selectDifficulty(gameId)) const initialCode = useAppSelector(selectCode(gameId, worldId, levelId)) const initialSelections = useAppSelector(selectSelections(gameId, worldId, levelId)) const inventory: Array = useSelector(selectInventory(gameId)) - const gameInfo = useGetGameInfoQuery({game: gameId}) + const typewriterMode = useSelector(selectTypewriterMode(gameId)) + const setTypewriterMode = (newTypewriterMode: boolean) => dispatch(changeTypewriterMode({game: gameId, typewriterMode: newTypewriterMode})) + + const gameInfo = useGetGameInfoQuery({game: gameId}) const level = useLoadLevelQuery({game: gameId, world: worldId, level: levelId}) // The state variables for the `ProofContext` @@ -221,15 +226,11 @@ function PlayableLevel({impressum, setImpressum}) { const [showHelp, setShowHelp] = useState>(new Set()) // Only for mobile layout const [pageNumber, setPageNumber] = useState(0) - const [typewriterMode, setTypewriterMode] = useState(()=>{ - const savedMode = localStorage.getItem('lean4game:typewriterMode'); - return savedMode !== null ? JSON.parse(savedMode) : true; - }) + // set to true to prevent switching between typewriter and editor const [lockInputMode, setLockInputMode] = useState(false) const [typewriterInput, setTypewriterInput] = useState("") const lastLevel = levelId >= gameInfo.data?.worldSize[worldId] - const dispatch = useAppDispatch() // impressum pop-up function toggleImpressum() {setImpressum(!impressum)} diff --git a/client/src/state/progress.ts b/client/src/state/progress.ts index f553159..d622703 100644 --- a/client/src/state/progress.ts +++ b/client/src/state/progress.ts @@ -26,7 +26,8 @@ export interface GameProgressState { inventory: string[], difficulty: number, openedIntro: boolean, - data: WorldProgressState + data: WorldProgressState, + typewriterMode: boolean } /** @@ -53,7 +54,7 @@ const initalLevelProgressState: LevelProgressState = {code: "", completed: false /** Add an empty skeleton with progress for the current game */ function addGameProgress (state: ProgressState, action: PayloadAction<{game: string}>) { if (!state.games[action.payload.game]) { - state.games[action.payload.game] = {inventory: [], openedIntro: true, data: {}, difficulty: DEFAULT_DIFFICULTY} + state.games[action.payload.game] = {inventory: [], openedIntro: true, data: {}, difficulty: DEFAULT_DIFFICULTY, typewriterMode: true} } if (!state.games[action.payload.game].data) { state.games[action.payload.game].data = {} @@ -99,7 +100,7 @@ export const progressSlice = createSlice({ }, /** delete all progress for this game */ deleteProgress(state: ProgressState, action: PayloadAction<{game: string}>) { - state.games[action.payload.game] = {inventory: [], data: {}, openedIntro: true, difficulty: DEFAULT_DIFFICULTY} + state.games[action.payload.game] = {inventory: [], data: {}, openedIntro: true, difficulty: DEFAULT_DIFFICULTY, typewriterMode: true} }, /** delete progress for this level */ deleteLevelProgress(state: ProgressState, action: PayloadAction<{game: string, world: string, level: number}>) { @@ -126,6 +127,10 @@ export const progressSlice = createSlice({ addGameProgress(state, action) state.games[action.payload.game].openedIntro = action.payload.openedIntro }, + changeTypewriterMode(state: ProgressState, action: PayloadAction<{game: string, typewriterMode: boolean}>) { + addGameProgress(state, action) + state.games[action.payload.game].typewriterMode = action.payload.typewriterMode + } } }) @@ -196,7 +201,15 @@ export function selectOpenedIntro(game: string) { } } +/** return whether the intro has been read */ +export function selectTypewriterMode(game: string) { + return (state) => { + return state.progress.games[game] ? state.progress.games[game].typewriterMode : true + } +} + + /** Export actions to modify the progress */ export const { changedSelection, codeEdited, levelCompleted, deleteProgress, deleteLevelProgress, loadProgress, helpEdited, changedInventory, changedOpenedIntro, - changedDifficulty } = progressSlice.actions + changedDifficulty, changeTypewriterMode} = progressSlice.actions