feat: complete Today from mobile HUD (Closes #601)
This commit is contained in:
1 parent
f023414929
commit
7aa25f1d8c
5 files changed
+94
-4
No files matched your search
@@ -574,9 +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 { 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) minmax(112px,auto); grid-template-areas:"summary complete" "progress toggle"; 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 { grid-area: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] { grid-area:progress; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||||
.mobile-today-hud [data-mobile-today-complete] { grid-area:complete; }
|
||||
.mobile-today-hud [data-mobile-today-toggle] { grid-area:toggle; }
|
||||
.mobile-today-hud button { min-height:44px; max-width:100%; }
|
||||
.mobile-today-hud [data-work-session-adjust-plan] { grid-column:1 / -1; }
|
||||
}
|
||||
|
||||
@@ -955,6 +955,10 @@
|
||||
selectTodayWork();
|
||||
workSession.reopen(todayMyWork.find(item => todayWork.identity(item) === identity));
|
||||
},
|
||||
onComplete: identity => {
|
||||
const item = todayMyWork.find(entry => todayWork.identity(entry) === identity);
|
||||
return completeTodayItem(item);
|
||||
},
|
||||
});
|
||||
renderAttentionInterruption();
|
||||
qs('#return-to-today').addEventListener('click', () => {
|
||||
|
||||
@@ -813,6 +813,7 @@
|
||||
|
||||
<section class="mobile-today-hud" data-mobile-today-hud aria-label="Active Today session" hidden>
|
||||
<button class="mobile-today-summary" data-mobile-today-open type="button" aria-label="Open current Today item"></button>
|
||||
<button data-mobile-today-complete type="button" hidden>Done & next</button>
|
||||
<div class="small" data-work-session-progress aria-live="polite"></div>
|
||||
<button data-mobile-today-toggle data-work-session-timer-toggle type="button">Pause timer</button>
|
||||
<button data-work-session-adjust-plan type="button" hidden>Adjust remaining plan</button>
|
||||
|
||||
+16
-1
@@ -200,7 +200,7 @@ function createTodayTimer({ storage, getLogin, now = () => Date.now() }) {
|
||||
};
|
||||
}
|
||||
|
||||
function createTodayTimerView({ timer, isActive, queryAll, formatEstimate, getRunway, getItem, onReopen }) {
|
||||
function createTodayTimerView({ timer, isActive, queryAll, formatEstimate, getRunway, getItem, onReopen, onComplete }) {
|
||||
let progress = null;
|
||||
let runway = null;
|
||||
queryAll('[data-mobile-today-open]').forEach(button =>
|
||||
@@ -212,6 +212,12 @@ function createTodayTimerView({ timer, isActive, queryAll, formatEstimate, getRu
|
||||
queryAll('[data-mobile-today-toggle]').forEach(button =>
|
||||
button.addEventListener('click', () => view.toggle())
|
||||
);
|
||||
queryAll('[data-mobile-today-complete]').forEach(button =>
|
||||
button.addEventListener('click', () => {
|
||||
const identity = timer.snapshot().identity;
|
||||
if (identity) onComplete?.(identity);
|
||||
})
|
||||
);
|
||||
if (typeof document !== 'undefined') queryAll('.work-session-nav').forEach(nav => {
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
@@ -247,6 +253,15 @@ function createTodayTimerView({ timer, isActive, queryAll, formatEstimate, getRu
|
||||
queryAll('[data-mobile-today-open]').forEach(element => {
|
||||
element.textContent = active ? String(getItem?.(snapshot.identity)?.title || 'Current Today item') : '';
|
||||
});
|
||||
queryAll('[data-mobile-today-complete]').forEach(button => {
|
||||
const itemTitle = String(getItem?.(snapshot.identity)?.title || 'current Today item');
|
||||
const finalItem = Boolean(progress && progress.index >= progress.total);
|
||||
button.hidden = !active;
|
||||
button.textContent = finalItem ? 'Done & recap' : 'Done & next';
|
||||
button.setAttribute('aria-label', finalItem ?
|
||||
'Complete ' + itemTitle + ' and open Today recap' :
|
||||
'Complete ' + itemTitle + ' and open next Today item');
|
||||
});
|
||||
if (typeof document !== 'undefined') document.body.classList.toggle('mobile-today-active', active);
|
||||
if (!progress) return;
|
||||
const sourceRunway = getRunway?.(snapshot) || runway;
|
||||
|
||||
Reference in new issue
Block a user