feat: edit photos in conversation replies (Closes #947)
CI / lint (pull_request) Successful in 2m4s
CI / build-release (pull_request) Successful in 6s
CI / browser-journey (pull_request) Successful in 57s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-16 07:28:10 +00:00
1 parent 6270253c24
commit 0d5fa13d65
7 files changed
+82 -6

No files matched your search

+1 -1
View File
@@ -704,7 +704,7 @@ textarea { resize: vertical; min-height: 120px; }
.conversation-evidence-review { grid-template-columns:1fr; width:100%; min-width:0; box-sizing:border-box; overflow-x:hidden; }
.conversation-evidence-review > img { grid-row:auto; width:100%; height:auto; max-height:280px; }
.conversation-evidence-review .issue-evidence-tray { overflow-x:auto; }
.conversation-evidence-review .issue-evidence-review-actions { grid-template-columns:repeat(3,minmax(0,1fr)); }
.conversation-evidence-review .issue-evidence-review-actions { grid-template-columns:repeat(4,minmax(0,1fr)); }
.conversation-evidence-review .issue-evidence-review-actions button { min-width:44px; min-height:44px; width:100%; }
@media (max-width:390px) {
.conversation-evidence-review .issue-evidence-review-actions { grid-template-columns:1fr; }
+39
View File
@@ -508,6 +508,19 @@
note: qs('#issue-attachment-note'),
noteLabel: qs('#issue-attachment-note-label'),
status: qs('#issue-comment-status'),
editor: {
document,
edit: qs('#edit-issue-attachment'),
dialog: qs('#issue-evidence-editor'),
canvas: qs('#issue-evidence-editor-canvas'),
exportCanvas: qs('#issue-evidence-editor-export'),
crop: qs('#crop-issue-evidence'), redact: qs('#redact-issue-evidence'),
highlight: qs('#highlight-issue-evidence'), arrow: qs('#arrow-issue-evidence'),
undo: qs('#undo-issue-evidence-edit'), reset: qs('#reset-issue-evidence-edit'),
cancel: qs('#cancel-issue-evidence-edit'), apply: qs('#apply-issue-evidence-edit'),
status: qs('#issue-evidence-editor-status'),
appliedMessage: 'Edited photo flattened and ready to send.',
},
createObjectURL: file => URL.createObjectURL(file),
revokeObjectURL: url => URL.revokeObjectURL(url),
readDataUrl: file => new Promise((resolve, reject) => {
@@ -545,6 +558,19 @@
note: qs('#pull-attachment-note'),
noteLabel: qs('#pull-attachment-note-label'),
status: qs('#pull-comment-status'),
editor: {
document,
edit: qs('#edit-pull-attachment'),
dialog: qs('#issue-evidence-editor'),
canvas: qs('#issue-evidence-editor-canvas'),
exportCanvas: qs('#issue-evidence-editor-export'),
crop: qs('#crop-issue-evidence'), redact: qs('#redact-issue-evidence'),
highlight: qs('#highlight-issue-evidence'), arrow: qs('#arrow-issue-evidence'),
undo: qs('#undo-issue-evidence-edit'), reset: qs('#reset-issue-evidence-edit'),
cancel: qs('#cancel-issue-evidence-edit'), apply: qs('#apply-issue-evidence-edit'),
status: qs('#issue-evidence-editor-status'),
appliedMessage: 'Edited photo flattened and ready to send.',
},
createObjectURL: file => URL.createObjectURL(file),
revokeObjectURL: url => URL.revokeObjectURL(url),
upload: payload => {
@@ -575,6 +601,19 @@
status: qs('#update-reply-status'),
readyMessage: 'Screenshot ready to send with this reply.',
removedMessage: 'Screenshot removed. Your reply is unchanged.',
editor: {
document,
edit: qs('#edit-update-reply-attachment'),
dialog: qs('#issue-evidence-editor'),
canvas: qs('#issue-evidence-editor-canvas'),
exportCanvas: qs('#issue-evidence-editor-export'),
crop: qs('#crop-issue-evidence'), redact: qs('#redact-issue-evidence'),
highlight: qs('#highlight-issue-evidence'), arrow: qs('#arrow-issue-evidence'),
undo: qs('#undo-issue-evidence-edit'), reset: qs('#reset-issue-evidence-edit'),
cancel: qs('#cancel-issue-evidence-edit'), apply: qs('#apply-issue-evidence-edit'),
status: qs('#issue-evidence-editor-status'),
appliedMessage: 'Edited photo flattened and ready to send.',
},
createObjectURL: file => URL.createObjectURL(file),
revokeObjectURL: url => URL.revokeObjectURL(url),
upload: payload => fetchReviewJson(
+6 -3
View File
@@ -677,6 +677,7 @@
</label>
<div class="issue-evidence-review-actions" aria-label="Reorder selected photo">
<button id="move-issue-attachment-earlier" type="button">Move earlier</button>
<button id="edit-issue-attachment" type="button">Edit photo</button>
<button id="remove-issue-attachment" type="button">Remove selected</button>
<button id="move-issue-attachment-later" type="button">Move later</button>
</div>
@@ -954,10 +955,11 @@
<div id="create-issue-capture-status" class="small" aria-live="assertive"></div>
</form>
</section>
<section class="issue-evidence-editor" id="issue-evidence-editor" role="dialog" aria-modal="true" aria-labelledby="issue-evidence-editor-heading" hidden>
</div>
<section class="issue-evidence-editor" id="issue-evidence-editor" role="dialog" aria-modal="true" aria-labelledby="issue-evidence-editor-heading" hidden>
<div class="issue-evidence-editor-panel">
<header>
<div><h3 id="issue-evidence-editor-heading">Edit screenshot evidence</h3><span class="small">Edits stay on this device until you file.</span></div>
<div><h3 id="issue-evidence-editor-heading">Edit selected photo</h3><span class="small">Edits stay on this device until you send or file.</span></div>
<button id="cancel-issue-evidence-edit" type="button">Cancel</button>
</header>
<canvas id="issue-evidence-editor-canvas" role="img" aria-label="Screenshot editing canvas. Drag to crop, redact, highlight, or point with an arrow."></canvas>
@@ -974,7 +976,6 @@
<button class="issue-evidence-editor-apply" id="apply-issue-evidence-edit" type="button">Apply flattened edit</button>
</div>
</section>
</div>
<section class="issue-filing-review" id="issue-filing-review" role="dialog" aria-modal="true" aria-labelledby="issue-filing-review-heading" hidden>
<div class="issue-filing-review-panel">
@@ -1077,6 +1078,7 @@
</label>
<div class="issue-evidence-review-actions" aria-label="Reorder selected photo">
<button id="move-update-reply-attachment-earlier" type="button">Move earlier</button>
<button id="edit-update-reply-attachment" type="button">Edit photo</button>
<button id="remove-update-reply-attachment" type="button">Remove selected</button>
<button id="move-update-reply-attachment-later" type="button">Move later</button>
</div>
@@ -1158,6 +1160,7 @@
</label>
<div class="issue-evidence-review-actions" aria-label="Reorder selected photo">
<button id="move-pull-attachment-earlier" type="button">Move earlier</button>
<button id="edit-pull-attachment" type="button">Edit photo</button>
<button id="remove-pull-attachment" type="button">Remove selected</button>
<button id="move-pull-attachment-later" type="button">Move later</button>
</div>
+2 -1
View File
@@ -377,7 +377,8 @@
onApplied: async index => {
const value = await controller.serialize();
review.render(value, index);
options.status.textContent = 'Edited screenshot flattened and ready to file.';
options.status.textContent = options.editor.appliedMessage ||
'Edited screenshot flattened and ready to file.';
},
});
options.editor.edit.disabled = !controller.state();
+1
View File
@@ -200,6 +200,7 @@
if (source && model) paint({source, model, canvas:options.canvas, maxDimension:1600});
}
function close() {
if (!source && !model) return;
options.dialog.hidden = true;
if (source && typeof source.close === 'function') source.close();
source = null;