From 96e7b354197a7566ce23779f215aec27f453fa2a Mon Sep 17 00:00:00 2001 From: timmy Date: Tue, 11 Aug 2026 23:29:50 +0000 Subject: [PATCH] feat: keep active Today visible on mobile (Closes #599) --- frontend/dashboard.css | 9 ++++ frontend/dashboard.js | 6 +++ frontend/index.html | 6 +++ frontend/mobile-task-dock.js | 4 ++ frontend/today-timer.js | 30 +++++++++-- src/frontend_bundle.py | 2 +- tests/test_mobile_task_dock.py | 29 ++++++++++- tests/test_my_work.py | 91 +++++++++++++++++++++++++++++++++- 8 files changed, 167 insertions(+), 10 deletions(-) diff --git a/frontend/dashboard.css b/frontend/dashboard.css index 1353074..7ba29d5 100644 --- a/frontend/dashboard.css +++ b/frontend/dashboard.css @@ -503,13 +503,17 @@ textarea { resize: vertical; min-height: 120px; } .pull-retry { min-height:44px; width:100%; margin-top:10px; } .mobile-task-dock { display:none; } .mobile-task-dock[hidden] { display:none; } +.mobile-today-hud { display:none; } +.mobile-today-hud[hidden], .mobile-today-hud[data-overlay-hidden="true"] { display:none; } .mobile-task-action { min-width:0; min-height:44px; padding:6px 2px; border:0; border-radius:8px; background:transparent; display:grid; place-items:center; gap:2px; font-size:12px; } +.mobile-task-action[hidden] { display:none; } .mobile-task-action[aria-current="page"] { color:#bfdbfe; background:#17365a; outline:1px solid #31577f; } .mobile-task-count { min-width:18px; min-height:18px; padding:1px 5px; border-radius:999px; background:#31577f; font-size:11px; line-height:16px; } .attention-interruption:not([hidden]) { max-width:100%; display:flex; align-items:center; justify-content:space-between; gap:10px; margin:0 0 12px; padding:10px 12px; border:1px solid #31577f; border-radius:10px; background:#102641; } .attention-interruption button { min-height:44px; flex:0 0 auto; } @media (max-width: 600px) { body { padding-bottom:calc(66px + env(safe-area-inset-bottom)); } + body.mobile-today-active { padding-bottom:calc(166px + env(safe-area-inset-bottom)); } header { min-height:56px; max-height:64px; padding:6px 10px; align-items:center; gap:8px; background:rgba(11,21,38,.98); } .app-brand .muted, #clock { display:none; } .app-live-status { margin-left:auto; } @@ -570,6 +574,11 @@ textarea { resize: vertical; min-height: 120px; } .composer-keyboard-active .update-reply { scroll-margin-block:12px; padding-bottom:env(safe-area-inset-bottom); } .mobile-task-dock { position:fixed; inset:auto 0 0; z-index:45; display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:2px; padding:6px 8px; padding-bottom:env(safe-area-inset-bottom); border-top:1px solid #2a496e; background:rgba(11,21,38,.98); backdrop-filter:blur(12px); } .mobile-task-dock[data-attention="true"] { grid-template-columns:repeat(6,minmax(0,1fr)); } + .mobile-today-hud { position:fixed; left:8px; right:8px; bottom:calc(56px + env(safe-area-inset-bottom)); z-index:44; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:4px 8px; max-width:100%; padding:8px; border:1px solid #31577f; border-radius:12px 12px 0 0; background:rgba(16,38,65,.98); box-shadow:0 -8px 24px rgba(0,0,0,.28); } + .mobile-today-summary { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:left; font-weight:700; } + .mobile-today-hud [data-work-session-progress] { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } + .mobile-today-hud button { min-height:44px; max-width:100%; } + .mobile-today-hud [data-work-session-adjust-plan] { grid-column:1 / -1; } } .obi { width:14px; height:14px; background: url('data:image/svg+xml;utf8,') center/contain no-repeat; display:inline-block; } .footer { padding: 12px; text-align: center; color:#4e6b8a; font-size:12px; } diff --git a/frontend/dashboard.js b/frontend/dashboard.js index e89c158..41d6f53 100644 --- a/frontend/dashboard.js +++ b/frontend/dashboard.js @@ -74,6 +74,7 @@ }); const mobileTaskDock = createMobileTaskDock({ nav: qs('#mobile-task-dock'), + sessionHud: qs('[data-mobile-today-hud]'), buttons: mobileTaskButtons, workLabel: qs('#mobile-work-label'), attentionBadge: qs('#mobile-attention-count'), @@ -949,6 +950,11 @@ isActive: () => workSession.checkpointed(), queryAll: s => document.querySelectorAll(s), formatEstimate: formatPlanMinutes, + getItem: identity => [...todayMyWork, ...activeMyWork].find(item => todayWork.identity(item) === identity), + onReopen: identity => { + selectTodayWork(); + workSession.reopen(todayMyWork.find(item => todayWork.identity(item) === identity)); + }, }); renderAttentionInterruption(); qs('#return-to-today').addEventListener('click', () => { diff --git a/frontend/index.html b/frontend/index.html index bef97e7..b9b0ef3 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -811,6 +811,12 @@ +