fix: preserve screenshots while editing queued captures (Closes #475)
This commit is contained in:
1 parent
535658185a
commit
d161cf41c0
7 files changed
+126
-9
No files matched your search
@@ -35,6 +35,7 @@ function createIndexedDbTransaction(indexedDB, dbName = 'stackchain-background-o
|
||||
transaction.onerror = () => reject(transaction.error);
|
||||
transaction.onabort = () => reject(transaction.error || new Error('Issue outbox transaction aborted'));
|
||||
Promise.resolve(work({
|
||||
get: id => requested(objectStore.get(id)),
|
||||
getAll: () => requested(objectStore.getAll()),
|
||||
put: value => requested(objectStore.put(value)),
|
||||
delete: id => requested(objectStore.delete(id)),
|
||||
@@ -187,6 +188,7 @@ function createIssueSyncStore({ transaction, indexedDB = globalThis.indexedDB, n
|
||||
}
|
||||
|
||||
return {
|
||||
get: id => transact(records => records.get(id)),
|
||||
reconcile,
|
||||
upsert,
|
||||
update,
|
||||
@@ -529,6 +531,7 @@ function createBackgroundIssueSync({
|
||||
|
||||
return {
|
||||
flush, send, purge, resume,
|
||||
get: id => store.get(id),
|
||||
reconcile: (items, outboxLane) => store.reconcile(items, outboxLane),
|
||||
snapshot: () => store.snapshot(),
|
||||
setReceiptPreference: (ownerLogin, enabled) => store.setReceiptPreference(ownerLogin, enabled),
|
||||
|
||||
+17
-7
@@ -1710,16 +1710,26 @@
|
||||
});
|
||||
});
|
||||
list.querySelectorAll('.draft-edit').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
button.addEventListener('click', async () => {
|
||||
const item = lastDrafts[Number(button.dataset.draftIndex)];
|
||||
const queued = issueOutbox.list().find(candidate => candidate.id === item?.outbox_id);
|
||||
if (!queued) return;
|
||||
editingOutboxId = queued.id;
|
||||
issueCapture.saveDraft(queued);
|
||||
openCreateIssueSheet();
|
||||
if (queued.attachment) createIssueAttachmentController.restore(queued.attachment);
|
||||
else createIssueAttachmentController.clear();
|
||||
qs('#create-issue-status').textContent = 'Edit this queued issue, then send again.';
|
||||
button.disabled = true;
|
||||
try {
|
||||
const hydrated = await issueOutbox.hydrateForEdit(queued.id);
|
||||
if (!hydrated) return;
|
||||
editingOutboxId = hydrated.id;
|
||||
issueCapture.saveDraft(hydrated);
|
||||
openCreateIssueSheet();
|
||||
if (hydrated.attachment) createIssueAttachmentController.restore(hydrated.attachment);
|
||||
else createIssueAttachmentController.clear();
|
||||
qs('#create-issue-status').textContent = 'Edit this queued issue, then send again.';
|
||||
} catch (error) {
|
||||
qs('#my-work-action-status').textContent = String(error?.message ||
|
||||
'The saved screenshot could not be loaded. Retry before editing this issue.');
|
||||
} finally {
|
||||
button.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
list.querySelectorAll('.draft-send').forEach(button => {
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
const contentType = String(value?.contentType || '');
|
||||
const filename = String(value?.filename || '');
|
||||
const data = String(value?.data || '');
|
||||
if (!data) {
|
||||
clear();
|
||||
throw new Error('The saved screenshot is unavailable. Retry before editing this issue.');
|
||||
}
|
||||
const padding = (data.match(/=*$/) || [''])[0].length;
|
||||
const size = Math.max(1, Math.floor(data.length * 3 / 4) - padding);
|
||||
select({ name: filename, type: contentType, size });
|
||||
|
||||
@@ -100,6 +100,21 @@ function createIssueOutbox({ storage, fetchJson, coordinator, backgroundSync, ge
|
||||
}
|
||||
}
|
||||
|
||||
async function hydrateForEdit(id) {
|
||||
const item = read().find(candidate => candidate.id === id);
|
||||
if (!item) return null;
|
||||
if (!item.attachment?.stored || item.attachment.data) return { ...item };
|
||||
if (!backgroundSync?.get) {
|
||||
throw new Error('The saved screenshot is unavailable. Retry before editing this issue.');
|
||||
}
|
||||
const durable = await backgroundSync.get(id);
|
||||
const attachment = captureAttachment(durable?.attachment);
|
||||
if (!attachment?.data || durable?.operationId !== item.operationId) {
|
||||
throw new Error('The saved screenshot is unavailable. Retry before editing this issue.');
|
||||
}
|
||||
return { ...item, attachment };
|
||||
}
|
||||
|
||||
function prepareUpdate(id, draft) {
|
||||
let updated = null;
|
||||
const items = read().map(item => {
|
||||
@@ -388,7 +403,7 @@ function createIssueOutbox({ storage, fetchJson, coordinator, backgroundSync, ge
|
||||
}
|
||||
|
||||
return {
|
||||
enqueue, enqueueDurably, update, updateDurably, discard, flush, retry, reconcileBackground,
|
||||
enqueue, enqueueDurably, hydrateForEdit, update, updateDurably, discard, flush, retry, reconcileBackground,
|
||||
pendingCompletions, completeIntent, list: () => read().map(item => ({ ...item })),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user