fix: keep delivery recovery single-flight (Closes #1016)
This commit is contained in:
1 parent
9a2b8d97bd
commit
437da72f3d
4 files changed
+172
-19
No files matched your search
@@ -90,10 +90,17 @@
|
||||
qs('#my-work').scrollIntoView({block:'start'});
|
||||
qs('#my-work').focus();
|
||||
}
|
||||
async function recoverMobileDelivery(item) {
|
||||
if (!item?.outbox_id || !activeFlushLogin) throw new Error('Sign in again to retry.');
|
||||
const authored = item.kind === 'authored-outbox';
|
||||
const result = await (authored ? authoredOutbox : issueOutbox).retry(item.outbox_id, activeFlushLogin);
|
||||
(authored ? applyAuthoredOutboxResult : applyOutboxResult)(result);
|
||||
}
|
||||
let mobileQueueCounts = {};
|
||||
const mobileDeliveryRecovery = createMobileDeliveryRecovery({
|
||||
getItems: () => draftInbox.partition(lastDrafts).deliveries,
|
||||
getIndex: item => lastDrafts.indexOf(item),
|
||||
activate: recoverMobileDelivery,
|
||||
beforeOpen: () => selectMobileQueue('draft'),
|
||||
onComplete: () => {
|
||||
if (!mobileStartDay.completePhase('delivery')) showMobileQueueCompletion('Delivery', true);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
};
|
||||
let currentId = '';
|
||||
let active = false;
|
||||
let inFlight = null;
|
||||
|
||||
function currentItem(items) {
|
||||
return items.find(item => identity(item) === currentId) || items[0];
|
||||
@@ -107,36 +108,41 @@
|
||||
return 'opened';
|
||||
}
|
||||
|
||||
async function defaultActivate(item) {
|
||||
async function attend(item) {
|
||||
if (typeof document === 'undefined') return false;
|
||||
const index = options.getIndex ? options.getIndex(item) : -1;
|
||||
const selector = item.status === 'authorization' ? '.draft-authorize' :
|
||||
item.checklist_conflict ? '.draft-review-checklist' : item.quarantined ? '.draft-copy' :
|
||||
item.status === 'attention' ? '.draft-resume' : '.draft-send';
|
||||
const selector = item.quarantined ? '.draft-copy' :
|
||||
item.checklist_conflict ? '.draft-review-checklist' : '.draft-resume';
|
||||
const action = document.querySelector('#my-work-list ' + selector + '[data-draft-index="' + index + '"]');
|
||||
if (!action) {
|
||||
if (elements.status) elements.status.textContent = 'This delivery changed. Reopen recovery to load its current action.';
|
||||
return false;
|
||||
}
|
||||
if (!action) throw new Error('This delivery changed. Reopen recovery to load its current action.');
|
||||
action.click();
|
||||
if (selector === '.draft-resume' || selector === '.draft-copy') elements.dialog.close();
|
||||
await Promise.resolve();
|
||||
return true;
|
||||
}
|
||||
|
||||
async function activate() {
|
||||
function activate() {
|
||||
if (inFlight) return inFlight;
|
||||
const items = ordered();
|
||||
const item = currentItem(items);
|
||||
const perform = options.activate || defaultActivate;
|
||||
if (!item) return render();
|
||||
const perform = state(item) === 'attention' ? attend : options.activate;
|
||||
if (!item) return Promise.resolve(render());
|
||||
if (elements?.action) elements.action.disabled = true;
|
||||
if (elements?.status) elements.status.textContent = 'Working…';
|
||||
try {
|
||||
await perform(item, state(item));
|
||||
} finally {
|
||||
if (elements?.action) elements.action.disabled = false;
|
||||
}
|
||||
return render();
|
||||
inFlight = (async () => {
|
||||
let failure = null;
|
||||
try {
|
||||
await perform(item, state(item));
|
||||
} catch (error) {
|
||||
failure = String(error?.message || 'Delivery could not be completed.').trim().slice(0, 160);
|
||||
} finally {
|
||||
if (elements?.action) elements.action.disabled = false;
|
||||
}
|
||||
const result = render();
|
||||
if (failure && elements?.status) {
|
||||
elements.status.textContent = failure + ' Try again when the connection is ready.';
|
||||
}
|
||||
return result;
|
||||
})().finally(() => { inFlight = null; });
|
||||
return inFlight;
|
||||
}
|
||||
|
||||
function start() {
|
||||
|
||||
Reference in new issue
Block a user