Skip to content

Commit 605c7fa

Browse files
committed
feat(mdviewer): add upload button to Edit Image URL dialog
Add an Upload button to the bottom-left of the image edit dialog that opens the native file picker and uses the existing bridge:uploadImage flow to replace the current image. Shows the uploading placeholder while the upload completes.
1 parent 774e43b commit 605c7fa

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

src-mdviewer/src/components/image-popover.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { emit, on } from "../core/events.js";
66
import { t } from "../core/i18n.js";
77
import { getState } from "../core/state.js";
88

9+
const UPLOAD_PLACEHOLDER_SRC = "https://user-cdn.phcode.site/images/uploading.svg";
10+
const ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
11+
912
let popover = null;
1013
let currentImg = null;
1114
let contentEl = null;
@@ -199,9 +202,15 @@ function showEditDialog(imgEl, currentSrc, currentAlt) {
199202
<input type="text" id="img-edit-alt-input" placeholder="${t("image_dialog.alt_placeholder") || "Image description"}"
200203
style="width: 100%; padding: 6px 8px; border: 1px solid var(--color-border); border-radius: 4px; background: var(--color-bg); color: var(--color-text);" />
201204
</div>
202-
<div class="confirm-dialog-buttons">
203-
<button class="confirm-dialog-btn confirm-dialog-btn-cancel" id="img-edit-cancel">${t("dialog.cancel") || "Cancel"}</button>
204-
<button class="confirm-dialog-btn confirm-dialog-btn-save" id="img-edit-save">${t("dialog.save") || "Save"}</button>
205+
<div class="confirm-dialog-buttons" style="justify-content: space-between;">
206+
<button class="confirm-dialog-btn" id="img-edit-upload" style="display: flex; align-items: center; gap: 4px;">
207+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></svg>
208+
${t("format.image_upload") || "Upload"}
209+
</button>
210+
<div style="display: flex; gap: 8px;">
211+
<button class="confirm-dialog-btn confirm-dialog-btn-cancel" id="img-edit-cancel">${t("dialog.cancel") || "Cancel"}</button>
212+
<button class="confirm-dialog-btn confirm-dialog-btn-save" id="img-edit-save">${t("dialog.save") || "Save"}</button>
213+
</div>
205214
</div>
206215
</div>`;
207216
document.body.appendChild(backdrop);
@@ -234,6 +243,26 @@ function showEditDialog(imgEl, currentSrc, currentAlt) {
234243
close();
235244
});
236245

246+
backdrop.querySelector("#img-edit-upload").addEventListener("click", () => {
247+
const fileInput = document.createElement("input");
248+
fileInput.type = "file";
249+
fileInput.accept = "image/*";
250+
fileInput.addEventListener("change", () => {
251+
const file = fileInput.files && fileInput.files[0];
252+
if (!file || !ALLOWED_IMAGE_TYPES.includes(file.type)) {
253+
return;
254+
}
255+
// Show uploading placeholder on the existing image
256+
const origSrc = imgEl.getAttribute("src");
257+
const uploadId = crypto.randomUUID();
258+
imgEl.setAttribute("src", UPLOAD_PLACEHOLDER_SRC);
259+
imgEl.setAttribute("data-upload-id", uploadId);
260+
emit("bridge:uploadImage", { blob: file, filename: file.name, uploadId });
261+
close();
262+
});
263+
fileInput.click();
264+
});
265+
237266
backdrop.addEventListener("keydown", (e) => {
238267
if (e.key === "Enter") {
239268
e.preventDefault();

0 commit comments

Comments
 (0)