feat: live filename preview in rename tab
Shows first 3 filenames with color-coded prefixes (feature=purple, fav=amber, user-prefix=blue). Updates on mode change, prefix input, fav-prefix input, feature checkbox toggle, tab switch, and details open. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+78
@@ -234,6 +234,13 @@
|
||||
.fav-preview-more { width: 36px; height: 36px; border-radius: 5px; background: rgba(245,158,11,0.15); color: #B45309; font-size: 0.72rem; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
||||
.fav-preview-text { font-size: 0.83rem; color: #92400E; line-height: 1.4; }
|
||||
.fav-preview-text strong { color: #B45309; }
|
||||
/* Rename preview */
|
||||
.rename-preview { margin-top: 0.75rem; padding: 0.6rem 0.75rem; background: var(--bg); border-radius: 8px; border: 1px solid var(--border); }
|
||||
.rename-preview-label { font-size: 0.75rem; color: var(--faint); margin-bottom: 0.3rem; }
|
||||
.rename-preview-name { font-family: ui-monospace, monospace; font-size: 0.78rem; color: var(--text); line-height: 1.75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.rename-preview-name .pfx-feat { color: #7C3AED; }
|
||||
.rename-preview-name .pfx-fav { color: #B45309; }
|
||||
.rename-preview-name .pfx-user { color: var(--blue-dark); }
|
||||
|
||||
/* ── Ordner-Auswahl-Button in Drop-Zone ── */
|
||||
#folder-picker-btn:hover { border-color: var(--blue); color: var(--blue); }
|
||||
@@ -468,6 +475,10 @@
|
||||
</div>
|
||||
<span class="hint-row">Wird beim Export pro Foto erkannt — verlangsamt den Export leicht</span>
|
||||
</div>
|
||||
<div class="rename-preview" id="rename-preview" style="display:none">
|
||||
<div class="rename-preview-label">Vorschau (erste Dateien)</div>
|
||||
<div id="rename-preview-lines"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: Bildeditor -->
|
||||
@@ -1558,14 +1569,81 @@
|
||||
document.querySelectorAll(".export-panel").forEach(p => p.classList.remove("active"));
|
||||
tab.classList.add("active");
|
||||
el("tab-" + tab.dataset.tab).classList.add("active");
|
||||
if (tab.dataset.tab === "rename") updateRenamePreview();
|
||||
});
|
||||
});
|
||||
el("export-opts").addEventListener("toggle", () => {
|
||||
if (el("export-opts").open) updateRenamePreview();
|
||||
});
|
||||
|
||||
el("rename-mode").addEventListener("change", () => {
|
||||
el("rename-prefix-row").style.display =
|
||||
el("rename-mode").value === "prefix_seq" ? "" : "none";
|
||||
updateRenamePreview();
|
||||
});
|
||||
|
||||
function updateRenamePreview() {
|
||||
const samples = okPaths.slice(0, 3);
|
||||
if (samples.length === 0) { el("rename-preview").style.display = "none"; return; }
|
||||
|
||||
const mode = el("rename-mode").value;
|
||||
const prefix = el("rename-prefix").value.trim();
|
||||
const favPrefix = el("fav-prefix").value || "FAV_";
|
||||
const today = new Date().toISOString().slice(0, 10).replace(/-/g, "-");
|
||||
const featActive = ["feat-qr","feat-bc","feat-face","feat-pano"].some(id => el(id).checked);
|
||||
const featLabel = featActive ? "FEAT_" : ""; // placeholder, real detection on export
|
||||
|
||||
const lines = el("rename-preview-lines");
|
||||
lines.textContent = "";
|
||||
|
||||
samples.forEach((path, i) => {
|
||||
const filename = path.split("/").pop();
|
||||
const dotIdx = filename.lastIndexOf(".");
|
||||
const stem = dotIdx > 0 ? filename.slice(0, dotIdx) : filename;
|
||||
const ext = (dotIdx > 0 ? filename.slice(dotIdx) : ".jpg").toLowerCase();
|
||||
const isFav = favoritePaths.has(path);
|
||||
const idx = String(i + 1).padStart(4, "0");
|
||||
|
||||
let base;
|
||||
if (mode === "original") base = prefix ? prefix + filename : filename;
|
||||
else if (mode === "datetime") base = prefix + today.replace(/-/g, "-") + "_000000" + ext;
|
||||
else if (mode === "date_seq") base = prefix + today + "_" + idx + ext;
|
||||
else if (mode === "prefix_seq") base = prefix + idx + ext;
|
||||
else base = prefix + idx + "_" + stem + ext;
|
||||
|
||||
const row = document.createElement("div");
|
||||
row.className = "rename-preview-name";
|
||||
|
||||
function span(text, cls) {
|
||||
const s = document.createElement("span");
|
||||
s.className = cls; s.textContent = text;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (featActive) row.appendChild(span(featLabel, "pfx-feat"));
|
||||
if (isFav) row.appendChild(span(favPrefix, "pfx-fav"));
|
||||
if (prefix && mode !== "original") row.appendChild(span(prefix, "pfx-user"));
|
||||
|
||||
const stripped = base.slice(prefix && mode !== "original" ? prefix.length : 0);
|
||||
row.appendChild(document.createTextNode(stripped));
|
||||
lines.appendChild(row);
|
||||
});
|
||||
|
||||
if (featActive) {
|
||||
const note = document.createElement("div");
|
||||
note.style.cssText = "font-size:0.72rem; color:var(--faint); margin-top:0.3rem;";
|
||||
note.textContent = "FEAT_ steht für den tatsächlich erkannten Präfix (QR_, BC_, …)";
|
||||
lines.appendChild(note);
|
||||
}
|
||||
|
||||
el("rename-preview").style.display = "";
|
||||
}
|
||||
|
||||
["rename-prefix","fav-prefix"].forEach(id =>
|
||||
el(id).addEventListener("input", updateRenamePreview));
|
||||
["feat-qr","feat-bc","feat-face","feat-pano"].forEach(id =>
|
||||
el(id).addEventListener("change", updateRenamePreview));
|
||||
|
||||
// Slider labels
|
||||
[["exp-rotation","°"],["exp-brightness",""],["exp-contrast",""],["exp-saturation",""],
|
||||
["wm-font-size",""],["wm-text-opacity",""],["wm-image-opacity",""],["wm-image-scale",""]
|
||||
|
||||
Reference in New Issue
Block a user