fix: 4 mobile issues — slot indicator, view days, list header, scroll sync
1. cellDuration indicator: compare against local `cellDuration` state (not effectiveCellDuration which reads stale profile.cellDuration since saveSetting bails early for DEVICE_SETTINGS_KEYS) 2. viewDays on mobile now uses orientation instead of fixed width: portrait (h > w) → 1 day, landscape → 3 days, for ≤768px. Applied consistently in useEffect, early profile load, and cookie override blocks so the responsive value is never overridden by the saved DB preference on mobile. 3. list-view day header on mobile: changed from sticky to position:relative so it flows with content and never covers tasks 4. time/day column scroll sync: weekly-days-grid was overflow-y:auto on mobile, creating an independent scroll container that drifted from the time column. Changed to overflow-y:visible so only time-grid-wrapper scrolls. Added touch-action:pan-y to day columns so iOS handles pan immediately without waiting for JS. v1.81.7
This commit is contained in:
parent
5ee99d6d2f
commit
676c5612ed
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "my-weekly-todo-list",
|
||||
"version": "1.81.6",
|
||||
"version": "1.81.7",
|
||||
"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": {
|
||||
|
||||
@ -3479,10 +3479,11 @@ h3 {
|
||||
border-bottom-color: var(--weekly-border, #333);
|
||||
}
|
||||
|
||||
/* On mobile, list-view day header must clear the sticky mobile header bar (~48px) */
|
||||
/* On mobile, list-view day header is not sticky — it just flows with content */
|
||||
@media (max-width: 768px) {
|
||||
.weekly-container.list-view .weekly-day-header {
|
||||
top: calc(48px + env(safe-area-inset-top, 0px));
|
||||
position: relative !important;
|
||||
top: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4943,16 +4944,17 @@ h3 {
|
||||
min-height: 100% !important;
|
||||
}
|
||||
}
|
||||
/* Mobile: allow scroll on grid but keep day columns visible for sticky headers */
|
||||
/* Mobile: all inner containers stay non-scrolling — time-grid-wrapper is the sole scroll container */
|
||||
@media (max-width: 768px) {
|
||||
.time-grid-on .weekly-days-grid {
|
||||
overflow-y: auto !important;
|
||||
overflow-y: visible !important;
|
||||
overflow-x: clip !important;
|
||||
}
|
||||
.time-grid-on .weekly-day-column {
|
||||
overflow-y: visible !important;
|
||||
overflow-x: visible !important;
|
||||
max-height: none !important;
|
||||
touch-action: pan-y;
|
||||
}
|
||||
.time-grid-on .time-slots-container,
|
||||
.time-grid-on .time-column-slots,
|
||||
|
||||
@ -569,17 +569,19 @@ export default function WeeklyView() {
|
||||
const savedViewDaysRef = useRef(7); // Track user's saved preference for restoring on resize
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// Responsive: auto-adjust viewDays based on screen width
|
||||
// Responsive: auto-adjust viewDays based on screen orientation / width
|
||||
useEffect(() => {
|
||||
const getResponsiveViewDays = (width: number): number => {
|
||||
if (width <= 480) return 1;
|
||||
if (width <= 768) return 3;
|
||||
const getResponsiveViewDays = (width: number, height: number): number => {
|
||||
if (width <= 768) {
|
||||
// Mobile: portrait → 1 day, landscape → 3 days
|
||||
return height > width ? 1 : 3;
|
||||
}
|
||||
if (width <= 1024) return Math.min(savedViewDaysRef.current, 5);
|
||||
return savedViewDaysRef.current;
|
||||
};
|
||||
|
||||
const handleResize = () => {
|
||||
const responsiveDays = getResponsiveViewDays(window.innerWidth);
|
||||
const responsiveDays = getResponsiveViewDays(window.innerWidth, window.innerHeight);
|
||||
setViewDays(responsiveDays);
|
||||
};
|
||||
|
||||
@ -1249,7 +1251,13 @@ export default function WeeklyView() {
|
||||
|
||||
// Sync individual states to profile data
|
||||
if (profileData.viewStyle) setViewStyle(profileData.viewStyle);
|
||||
if (profileData.viewDays) setViewDays(profileData.viewDays);
|
||||
if (profileData.viewDays) {
|
||||
savedViewDaysRef.current = profileData.viewDays;
|
||||
const w = window.innerWidth, h = window.innerHeight;
|
||||
if (w <= 768) setViewDays(h > w ? 1 : 3);
|
||||
else if (w <= 1024) setViewDays(Math.min(profileData.viewDays, 5));
|
||||
else setViewDays(profileData.viewDays);
|
||||
}
|
||||
if (profileData.showTimeGrid !== undefined) setShowTimeGrid(profileData.showTimeGrid);
|
||||
if (profileData.showSomeday !== undefined) setShowSomeday(profileData.showSomeday);
|
||||
if (profileData.showAllDayEvents !== undefined) setShowAllDay(profileData.showAllDayEvents);
|
||||
@ -2244,10 +2252,9 @@ export default function WeeklyView() {
|
||||
}
|
||||
if (data.user.viewDays !== undefined) {
|
||||
savedViewDaysRef.current = data.user.viewDays;
|
||||
const width = window.innerWidth;
|
||||
if (width <= 480) setViewDays(1);
|
||||
else if (width <= 768) setViewDays(3);
|
||||
else if (width <= 1024) setViewDays(Math.min(data.user.viewDays, 5));
|
||||
const w = window.innerWidth, h = window.innerHeight;
|
||||
if (w <= 768) setViewDays(h > w ? 1 : 3);
|
||||
else if (w <= 1024) setViewDays(Math.min(data.user.viewDays, 5));
|
||||
else setViewDays(data.user.viewDays);
|
||||
}
|
||||
if (data.user.cellDuration !== undefined)
|
||||
@ -2258,10 +2265,9 @@ export default function WeeklyView() {
|
||||
if (cookieViewDays) {
|
||||
const v = Number(cookieViewDays);
|
||||
savedViewDaysRef.current = v;
|
||||
const width = window.innerWidth;
|
||||
if (width <= 480) setViewDays(1);
|
||||
else if (width <= 768) setViewDays(3);
|
||||
else if (width <= 1024) setViewDays(Math.min(v, 5));
|
||||
const w = window.innerWidth, h = window.innerHeight;
|
||||
if (w <= 768) setViewDays(h > w ? 1 : 3);
|
||||
else if (w <= 1024) setViewDays(Math.min(v, 5));
|
||||
else setViewDays(v);
|
||||
}
|
||||
if (data.user.weekdayFormat) {
|
||||
@ -5442,7 +5448,7 @@ export default function WeeklyView() {
|
||||
<div style={{ display: "flex", gap: "4px" }}>
|
||||
{[15, 30, 60].map((d) => (
|
||||
<button key={d} onClick={() => { setCellDuration(d as CellDuration); saveSetting("cellDuration", d); }}
|
||||
style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: effectiveCellDuration === d ? 700 : 400, background: effectiveCellDuration === d ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: effectiveCellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>
|
||||
style={{ flex: 1, padding: "5px 0", fontSize: "0.8rem", borderRadius: "6px", border: "none", cursor: "pointer", fontWeight: cellDuration === d ? 700 : 400, background: cellDuration === d ? (darkMode ? "#374151" : "#333") : (darkMode ? "#1f2937" : "#e5e7eb"), color: cellDuration === d ? "#fff" : (darkMode ? "#9ca3af" : "#6b7280") }}>
|
||||
{d}m
|
||||
</button>
|
||||
))}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user