feat: resume mobile Agenda sessions (Closes #733)
This commit is contained in:
1 parent
1fc70f6890
commit
715df380e0
5 files changed
+118
-18
No files matched your search
+26
-4
@@ -72,6 +72,7 @@
|
||||
let mobileQueueCounts = {};
|
||||
const mobileQueueLauncher = createMobileQueueLauncher({
|
||||
openToday: () => mobileWorkEntry.open(),
|
||||
openAgenda: openAgendaSession,
|
||||
selectFilter: selectMobileQueue,
|
||||
firstAction: name => qs('#my-work-list .my-work-card-main, #my-work-list .draft-resume, #my-work-list .draft-continue, #my-work-list .draft-edit'),
|
||||
announce: message => { qs('#my-work-action-status').textContent = message; },
|
||||
@@ -1082,6 +1083,15 @@
|
||||
'Session recovery could not be saved on this device. You can keep working.';
|
||||
},
|
||||
});
|
||||
const agendaSessionCheckpoint = createWorkSessionCheckpoint({
|
||||
storage: localStorage,
|
||||
getLogin: () => confirmedOwnerLogin,
|
||||
key: 'stackchain.agenda-session.v1',
|
||||
onError: () => {
|
||||
qs('#my-work-action-status').textContent =
|
||||
'Agenda progress could not be saved on this device. You can keep working.';
|
||||
},
|
||||
});
|
||||
const timer = createTodayTimer({
|
||||
storage: localStorage,
|
||||
getLogin: () => confirmedOwnerLogin,
|
||||
@@ -1150,8 +1160,10 @@
|
||||
const active = workSession.active();
|
||||
const startWorkSession = qs('#start-work-session');
|
||||
startWorkSession.hidden = active;
|
||||
startWorkSession.textContent = selectedWorkFilter === 'agenda' ? 'Start Agenda' : 'Start work';
|
||||
qs('#resume-today-session').hidden = active || !todayMyWork.length || !workSession.resumable();
|
||||
startWorkSession.textContent = selectedWorkFilter === 'agenda' ?
|
||||
(agendaSessionCheckpoint.read() ? 'Resume Agenda' : 'Start Agenda') : 'Start work';
|
||||
qs('#resume-today-session').hidden = active || selectedWorkFilter !== 'today' ||
|
||||
!todayMyWork.length || !workSession.resumable();
|
||||
qs('#end-today-session').hidden = !active;
|
||||
updateDetailDeferLabels(active);
|
||||
mobileTaskDock.updateWork(mobileWorkEntry.mode());
|
||||
@@ -1164,8 +1176,9 @@
|
||||
getFilter: () => selectedWorkFilter === 'today' ? 'all' :
|
||||
selectedWorkFilter === 'agenda' ? 'all' : selectedWorkFilter,
|
||||
getMilestone: () => selectedWorkFilter === 'agenda' ? 'all' : selectedWorkMilestone,
|
||||
checkpoint: sessionCheckpoint,
|
||||
checkpointEnabled: () => selectedWorkFilter === 'today',
|
||||
checkpoint: () => selectedWorkFilter === 'agenda' ? agendaSessionCheckpoint : sessionCheckpoint,
|
||||
checkpointEnabled: () => ['today', 'agenda'].includes(selectedWorkFilter),
|
||||
checkpointedEnabled: () => selectedWorkFilter === 'today',
|
||||
onOpen: openWorkSessionItem,
|
||||
onProgress: state => {
|
||||
updateWorkSessionActions();
|
||||
@@ -1186,6 +1199,7 @@
|
||||
updateWorkSessionActions();
|
||||
if (selectedWorkFilter === 'agenda') {
|
||||
closeOpenWorkSheets();
|
||||
window.location.hash = '#/my-work/agenda';
|
||||
qs('#my-work-action-status').textContent = 'Agenda complete.';
|
||||
return;
|
||||
}
|
||||
@@ -1196,6 +1210,13 @@
|
||||
qs('[data-work-filter="today"]').click();
|
||||
}
|
||||
|
||||
function openAgendaSession() {
|
||||
selectMobileQueue('agenda');
|
||||
const opened = agendaSessionCheckpoint.read() ? workSession.resume() : workSession.start();
|
||||
if (!opened) qs('#my-work-action-status').textContent = 'No deadlines are ready in Agenda.';
|
||||
return opened ? 'opened' : 'empty';
|
||||
}
|
||||
|
||||
let todayReadinessTrigger = null;
|
||||
let todayReadinessBlockerFocus = null;
|
||||
let searchPreviewReturnKind = null;
|
||||
@@ -5886,6 +5907,7 @@
|
||||
return;
|
||||
}
|
||||
if (selectedWorkFilter === 'today') runTodayTransition('start');
|
||||
else if (selectedWorkFilter === 'agenda' && agendaSessionCheckpoint.read()) workSession.resume();
|
||||
else workSession.start();
|
||||
});
|
||||
qs('#resume-today-session').addEventListener('click', () => resumeTodaySession());
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
function open(name) {
|
||||
if (name === 'today') return options.openToday();
|
||||
if (name === 'agenda') return options.openAgenda();
|
||||
options.selectFilter(name);
|
||||
const action = options.firstAction(name);
|
||||
if (!action) {
|
||||
|
||||
+10
-9
@@ -675,13 +675,14 @@ function createWorkSessionCheckpoint({
|
||||
|
||||
function createWorkSession({
|
||||
getItems, getFilter, getMilestone = () => 'all', checkpoint = null,
|
||||
checkpointEnabled = () => true,
|
||||
checkpointEnabled = () => true, checkpointedEnabled = checkpointEnabled,
|
||||
onOpen, onProgress, onFinish,
|
||||
}) {
|
||||
let currentIdentity = '';
|
||||
let currentIndex = -1;
|
||||
let running = false;
|
||||
let durable = false;
|
||||
const activeCheckpoint = () => typeof checkpoint === 'function' ? checkpoint() : checkpoint;
|
||||
|
||||
const queue = () => filterMyWork(getItems() || [], getFilter(), getMilestone());
|
||||
const report = (items, index) => onProgress({
|
||||
@@ -696,7 +697,7 @@ function createWorkSession({
|
||||
durable = false;
|
||||
currentIdentity = '';
|
||||
currentIndex = -1;
|
||||
if (clearCheckpoint) checkpoint?.clear();
|
||||
if (clearCheckpoint) activeCheckpoint()?.clear();
|
||||
onFinish();
|
||||
return false;
|
||||
};
|
||||
@@ -704,7 +705,7 @@ function createWorkSession({
|
||||
if (!items.length || index < 0 || index >= items.length) return finish();
|
||||
currentIndex = index;
|
||||
currentIdentity = workIdentity(items[index]);
|
||||
if (durable) checkpoint?.save(currentIdentity, currentIndex);
|
||||
if (durable) activeCheckpoint()?.save(currentIdentity, currentIndex);
|
||||
report(items, index);
|
||||
onOpen(items[index]);
|
||||
return true;
|
||||
@@ -712,9 +713,9 @@ function createWorkSession({
|
||||
|
||||
return {
|
||||
active: () => running,
|
||||
checkpointed: item => running && durable && (!item || workIdentity(item) === currentIdentity),
|
||||
checkpointed: item => running && durable && checkpointedEnabled() && (!item || workIdentity(item) === currentIdentity),
|
||||
end: () => finish(),
|
||||
resumable: () => Boolean(checkpoint?.read()),
|
||||
resumable: () => Boolean(activeCheckpoint()?.read()),
|
||||
reopen(requested = null) {
|
||||
if (!running) return false;
|
||||
const items = queue();
|
||||
@@ -723,13 +724,13 @@ function createWorkSession({
|
||||
if (index < 0) return false;
|
||||
currentIdentity = requestedIdentity;
|
||||
currentIndex = index;
|
||||
if (durable && requested) checkpoint?.save(currentIdentity, currentIndex);
|
||||
if (durable && requested) activeCheckpoint()?.save(currentIdentity, currentIndex);
|
||||
report(items, index);
|
||||
onOpen(items[index]);
|
||||
return true;
|
||||
},
|
||||
resume(requested = null) {
|
||||
const saved = checkpoint?.read();
|
||||
const saved = activeCheckpoint()?.read();
|
||||
if (!saved) return false;
|
||||
durable = true;
|
||||
const items = queue();
|
||||
@@ -743,7 +744,7 @@ function createWorkSession({
|
||||
const items = queue();
|
||||
if (!items.length) return finish();
|
||||
running = true;
|
||||
durable = Boolean(checkpoint && checkpointEnabled());
|
||||
durable = Boolean(activeCheckpoint() && checkpointEnabled());
|
||||
const requested = item ? items.findIndex(candidate => workIdentity(candidate) === workIdentity(item)) : 0;
|
||||
return openAt(items, requested >= 0 ? requested : 0);
|
||||
},
|
||||
@@ -791,7 +792,7 @@ function createWorkSession({
|
||||
if (!items.length) return null;
|
||||
if (action === 'start') return items[0];
|
||||
if (action === 'resume') {
|
||||
const saved = checkpoint?.read();
|
||||
const saved = activeCheckpoint()?.read();
|
||||
if (!saved) return null;
|
||||
const exact = items.findIndex(item => workIdentity(item) === saved.identity);
|
||||
return items[exact >= 0 ? exact : Math.min(saved.index, items.length - 1)];
|
||||
|
||||
Reference in new issue
Block a user