diff --git a/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx b/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx index 90c8375..b62feb4 100644 --- a/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx +++ b/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx @@ -26,20 +26,64 @@ type SelectionOverride = { sound: boolean; timer: boolean; }; +interface StoredWorkspaceSelection { + sceneId?: string; + timerPresetId?: string; + soundPresetId?: string; + override?: Partial; +} -const resolveInitialRoomId = (roomIdFromQuery: string | null) => { +const WORKSPACE_SELECTION_STORAGE_KEY = 'viberoom:workspace-selection:v1'; + +const readStoredWorkspaceSelection = (): StoredWorkspaceSelection => { + if (typeof window === 'undefined') { + return {}; + } + + const raw = window.localStorage.getItem(WORKSPACE_SELECTION_STORAGE_KEY); + + if (!raw) { + return {}; + } + + try { + const parsed = JSON.parse(raw); + + if (!parsed || typeof parsed !== 'object') { + return {}; + } + + return parsed as StoredWorkspaceSelection; + } catch { + return {}; + } +}; + +const resolveInitialRoomId = (roomIdFromQuery: string | null, storedSceneId?: string) => { if (roomIdFromQuery && getRoomById(roomIdFromQuery)) { return roomIdFromQuery; } + if (storedSceneId && getRoomById(storedSceneId)) { + return storedSceneId; + } + return ROOM_THEMES[0].id; }; -const resolveInitialSoundPreset = (presetIdFromQuery: string | null, recommendedPresetId?: string) => { +const resolveInitialSoundPreset = ( + presetIdFromQuery: string | null, + storedPresetId: string | undefined, + recommendedPresetId?: string, +) => { if (presetIdFromQuery && SOUND_PRESETS.some((preset) => preset.id === presetIdFromQuery)) { return presetIdFromQuery; } + if (storedPresetId && SOUND_PRESETS.some((preset) => preset.id === storedPresetId)) { + return storedPresetId; + } + if (recommendedPresetId && SOUND_PRESETS.some((preset) => preset.id === recommendedPresetId)) { return recommendedPresetId; } @@ -66,11 +110,26 @@ const resolveTimerLabelFromPresetId = (presetId?: string) => { return preset.label; }; -const resolveInitialTimerLabel = (timerLabelFromQuery: string | null, recommendedPresetId?: string) => { +const resolveTimerPresetIdFromLabel = (timerLabel: string) => { + const preset = TIMER_SELECTION_PRESETS.find((candidate) => candidate.label === timerLabel); + return preset?.id; +}; + +const resolveInitialTimerLabel = ( + timerLabelFromQuery: string | null, + storedPresetId?: string, + recommendedPresetId?: string, +) => { if (timerLabelFromQuery && TIMER_SELECTION_PRESETS.some((preset) => preset.label === timerLabelFromQuery)) { return timerLabelFromQuery; } + const storedLabel = resolveTimerLabelFromPresetId(storedPresetId); + + if (storedLabel) { + return storedLabel; + } + const recommendedLabel = resolveTimerLabelFromPresetId(recommendedPresetId); if (recommendedLabel) { @@ -82,6 +141,7 @@ const resolveInitialTimerLabel = (timerLabelFromQuery: string | null, recommende export const SpaceWorkspaceWidget = () => { const searchParams = useSearchParams(); + const storedSelection = useMemo(() => readStoredWorkspaceSelection(), []); const { thoughts, thoughtCount, @@ -92,15 +152,17 @@ export const SpaceWorkspaceWidget = () => { setThoughtCompleted, } = useThoughtInbox(); - const initialRoomId = resolveInitialRoomId(searchParams.get('room')); + const initialRoomId = resolveInitialRoomId(searchParams.get('room'), storedSelection.sceneId); const initialRoom = getRoomById(initialRoomId) ?? ROOM_THEMES[0]; const initialGoal = searchParams.get('goal')?.trim() ?? ''; const initialSoundPresetId = resolveInitialSoundPreset( searchParams.get('sound'), + storedSelection.soundPresetId, initialRoom.recommendedSoundPresetId, ); const initialTimerLabel = resolveInitialTimerLabel( searchParams.get('timer'), + storedSelection.timerPresetId, initialRoom.recommendedTimerPresetId, ); @@ -109,7 +171,10 @@ export const SpaceWorkspaceWidget = () => { const [selectedTimerLabel, setSelectedTimerLabel] = useState(initialTimerLabel); const [goalInput, setGoalInput] = useState(initialGoal); const [selectedGoalId, setSelectedGoalId] = useState(null); - const [selectionOverride, setSelectionOverride] = useState({ sound: false, timer: false }); + const [selectionOverride, setSelectionOverride] = useState({ + sound: Boolean(storedSelection.override?.sound), + timer: Boolean(storedSelection.override?.timer), + }); const { selectedPresetId, @@ -258,6 +323,24 @@ export const SpaceWorkspaceWidget = () => { }; }, []); + useEffect(() => { + if (typeof window === 'undefined') { + return; + } + + const timerPresetId = resolveTimerPresetIdFromLabel(selectedTimerLabel); + + window.localStorage.setItem( + WORKSPACE_SELECTION_STORAGE_KEY, + JSON.stringify({ + sceneId: selectedRoomId, + timerPresetId, + soundPresetId: selectedPresetId, + override: selectionOverride, + }), + ); + }, [selectedRoomId, selectedTimerLabel, selectedPresetId, selectionOverride]); + return (