From 075ccdba04fb8a0177ac79b32bfff904444890b0 Mon Sep 17 00:00:00 2001 From: mARTin Date: Tue, 7 Apr 2026 23:29:35 +0200 Subject: [PATCH] feat: persist view style and start-on preference per device viewStyle, showTimeGrid, and startDayOffset now also write to a device cookie so each device remembers its own view independently. Cookie wins over DB on load, giving phone/desktop their own default view without losing the cross-device DB fallback. - DEVICE_ALSO_COOKIE_KEYS: viewStyle, showTimeGrid, startDayOffset - saveSetting writes cookie for these in addition to DB - viewStyle and showTimeGrid lazy-init from cookie on first render - Both fetchProfile and fetchUserInfo apply cookie overrides last v1.94.1 --- package.json | 2 +- src/components/WeeklyView.tsx | 38 +++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 27baba3..0747a40 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.94.0", + "version": "1.94.1", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 3707f0b..ad909ed 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -117,6 +117,9 @@ const DEVICE_SETTINGS_KEYS = ["viewDays", "cellDuration", "startHour", "endHour" const DEVICE_VIEW_SETTINGS_KEYS = ["showSomeday", "showAllDayEvents", "showTaskCheckboxes", "showProjectIcons", "weatherEnabled"] as const; type DeviceViewSettingKey = typeof DEVICE_VIEW_SETTINGS_KEYS[number]; +// Settings that save to DB (cross-device default) AND to cookie (device override wins on load) +const DEVICE_ALSO_COOKIE_KEYS = ["viewStyle", "showTimeGrid", "startDayOffset"]; + function getCookie(name: string): string | null { if (typeof document === "undefined") return null; const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`)); @@ -999,7 +1002,10 @@ export default function WeeklyView() { }; const [cellDuration, setCellDuration] = useState(30); const [draggedTask, setDraggedTask] = useState(null); - const [showTimeGrid, setShowTimeGrid] = useState(true); + const [showTimeGrid, setShowTimeGrid] = useState(() => { + const c = getCookie("setting_showTimeGrid"); + return c !== null ? c === "true" : true; + }); const [slideDirection, setSlideDirection] = useState<"next" | "prev" | null>( null, ); @@ -1018,7 +1024,10 @@ export default function WeeklyView() { listId?: string; slotIdx?: number; } | null>(null); - const [viewStyle, setViewStyle] = useState("simple"); + const [viewStyle, setViewStyle] = useState(() => { + const c = getCookie("setting_viewStyle"); + return (c as ViewStyle) || "simple"; + }); // Per-view settings: overrides that apply only to a specific view type PerViewOverrides = { @@ -1407,6 +1416,12 @@ export default function WeeklyView() { if (_cStart) setStartHour(Number(_cStart)); const _cEnd = getCookie("setting_endHour"); if (_cEnd) setEndHour(Number(_cEnd)); + const _cVS = getCookie("setting_viewStyle"); + if (_cVS) { setViewStyle(_cVS as ViewStyle); setProfile((p: any) => ({ ...p, viewStyle: _cVS })); } + const _cTG = getCookie("setting_showTimeGrid"); + if (_cTG !== null) { const v = _cTG === "true"; setShowTimeGrid(v); setProfile((p: any) => ({ ...p, showTimeGrid: v })); } + const _cSDO = getCookie("setting_startDayOffset"); + if (_cSDO !== null) setProfile((p: any) => ({ ...p, startDayOffset: Number(_cSDO) })); // Show onboarding wizard for new users if (profileData.hasCompletedOnboarding === false) { @@ -2271,6 +2286,10 @@ export default function WeeklyView() { setCookie(`setting_${key}`, String(value)); return; // Don't write to DB — that would overwrite other devices } + // Also persist to device cookie so this device remembers its own preference on reload + if (DEVICE_ALSO_COOKIE_KEYS.includes(key)) { + setCookie(`setting_${key}`, String(value)); + } // Keep profile object in sync so the debounced auto-save never sends stale values setProfile((p: any) => ({ ...p, [key]: value })); try { @@ -2499,6 +2518,21 @@ export default function WeeklyView() { setCellDuration(data.user.cellDuration as CellDuration); if (data.user.viewStyle) setViewStyle(data.user.viewStyle as ViewStyle); + + // Cookie overrides for settings that are also device-local + const _cVS2 = getCookie("setting_viewStyle"); + if (_cVS2) { setViewStyle(_cVS2 as ViewStyle); setProfile((p: any) => ({ ...p, viewStyle: _cVS2, showTimeGrid: _cVS2 === "simple" || _cVS2 === "calendar" })); } + const _cTG2 = getCookie("setting_showTimeGrid"); + if (_cTG2 !== null) setShowTimeGrid(_cTG2 === "true"); + const _cSDO2 = getCookie("setting_startDayOffset"); + if (_cSDO2 !== null) { + const offset = Number(_cSDO2); + setProfile((p: any) => ({ ...p, startDayOffset: offset })); + if (offset !== 0) { + const d = new Date(); d.setHours(0, 0, 0, 0); d.setDate(d.getDate() + offset); + setCurrentWeekStart(d); + } + } } } } catch (e) {