Files
mExifEditor/app/static/index.html
T

207 lines
9.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#121820">
<title>Photo Date Editor</title>
<link rel="manifest" href="/manifest.webmanifest">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div class="app-shell">
<header class="topbar">
<div class="brand">
<div class="brand-mark" aria-hidden="true">◫</div>
<div>
<h1 id="app-name">Photo Date Editor</h1>
<p>Local folder · in-place JPEG metadata</p>
</div>
</div>
<div class="top-actions">
<button id="shortcuts-button" class="button ghost">⌨ Keyboard shortcuts</button>
<button id="open-folder-top" class="button primary">Open photo folder</button>
</div>
</header>
<main class="workspace">
<aside class="sidebar left-panel">
<section class="panel-section folder-section">
<div class="section-label">Folder</div>
<div class="folder-row">
<div>
<strong id="folder-name">No folder selected</strong>
<span id="folder-access">Choose a local folder</span>
</div>
<button id="open-folder" class="button compact">Change</button>
</div>
</section>
<section class="panel-section progress-section">
<div class="section-heading">
<span>Progress</span>
<span id="progress-count">0 / 0</span>
</div>
<div class="progress-track"><div id="progress-bar" class="progress-bar"></div></div>
<div class="status-legend">
<span><i class="dot saved"></i>Saved</span>
<span><i class="dot skipped"></i>Skipped</span>
<span><i class="dot pending"></i>Pending</span>
<span><i class="dot failed"></i>Failed</span>
</div>
</section>
<section class="panel-section file-section">
<div class="section-heading"><span>Photos</span><span id="photo-count">0</span></div>
<input id="filter-input" class="input filter" type="search" placeholder="Filter filenames…" disabled>
<div id="file-list" class="file-list" aria-live="polite">
<div class="empty-list">Choose a folder containing JPG or JPEG photos.</div>
</div>
</section>
<section class="sidebar-footer">
<button id="rescan-folder" class="button wide" disabled>↻ Rescan folder</button>
</section>
</aside>
<section class="viewer-panel">
<div id="viewer-empty" class="viewer-empty">
<div class="empty-icon">▧</div>
<h2>Choose your scanned-photo folder</h2>
<p>The site will request read/write access. Photos stay on this device.</p>
<button id="open-folder-center" class="button primary large">Open photo folder</button>
</div>
<div id="viewer-content" class="viewer-content hidden">
<div class="image-stage">
<img id="photo-preview" alt="Current scanned photograph">
</div>
<div class="viewer-tools">
<div class="tool-group">
<button id="zoom-out" class="icon-button" title="Zoom out">−</button>
<button id="zoom-in" class="icon-button" title="Zoom in">+</button>
<button id="fit-image" class="button compact">Fit</button>
</div>
<div class="filename-block">
<strong id="current-filename">—</strong>
<span id="current-filesize">—</span>
</div>
<div class="tool-group">
<button id="rotate-left" class="icon-button" title="Rotate preview left">↶</button>
<button id="rotate-right" class="icon-button" title="Rotate preview right">↷</button>
<button id="reset-view" class="icon-button" title="Reset preview">⟳</button>
</div>
</div>
<div class="navigation-bar">
<button id="previous-button" class="button">← Previous</button>
<div id="viewer-position" class="position">0 / 0</div>
<div class="navigation-actions">
<button id="skip-button" class="button ghost">Skip</button>
<button id="save-button" class="button">Save current</button>
<button id="save-next-button" class="button primary">Save &amp; Next →</button>
</div>
</div>
</div>
</section>
<aside class="sidebar right-panel">
<div class="tabs" role="tablist">
<button class="tab active" data-tab="date" role="tab">Date &amp; time</button>
<button class="tab" data-tab="details" role="tab">Details</button>
<button class="tab" data-tab="keywords" role="tab">Keywords</button>
</div>
<form id="metadata-form" autocomplete="off">
<section class="tab-panel active" data-panel="date">
<fieldset>
<legend>Date precision</legend>
<label class="radio-row"><input type="radio" name="precision" value="exact" checked> <span>Exact date</span></label>
<label class="radio-row"><input type="radio" name="precision" value="month"> <span>Month and year</span></label>
<label class="radio-row"><input type="radio" name="precision" value="year"> <span>Year only</span></label>
<label class="radio-row"><input type="radio" name="precision" value="approximate"> <span>Approximate year</span></label>
</fieldset>
<div class="field-grid date-grid">
<label class="field">
<span>Day</span>
<input id="day-input" class="input" type="number" min="1" max="31" value="1">
</label>
<label class="field month-field">
<span>Month</span>
<select id="month-input" class="input">
<option value="1">January</option><option value="2">February</option>
<option value="3">March</option><option value="4">April</option>
<option value="5">May</option><option value="6">June</option>
<option value="7">July</option><option value="8">August</option>
<option value="9">September</option><option value="10">October</option>
<option value="11">November</option><option value="12">December</option>
</select>
</label>
<label class="field">
<span>Year</span>
<input id="year-input" class="input" type="number" min="1800" max="2200" placeholder="1987" required>
</label>
</div>
<label class="field">
<span>Time</span>
<select id="time-mode" class="input">
<option value="unknown">Unknown — use 12:00:00</option>
<option value="known">Enter a time</option>
</select>
</label>
<label id="time-field" class="field hidden">
<span>Time value</span>
<input id="time-input" class="input" type="time" step="1" value="12:00:00">
</label>
<div class="info-card">
<strong>Partial dates</strong>
<p>EXIF requires a full timestamp. Month/year uses day 1; year-only uses January 1. XMP also stores the reduced precision.</p>
</div>
</section>
<section class="tab-panel" data-panel="details">
<label class="field">
<span>Description</span>
<textarea id="description-input" class="input textarea" rows="7" maxlength="2000" placeholder="Who, where, occasion, or other context…"></textarea>
</label>
<div class="helper-row"><span>Written to EXIF, XMP and IPTC</span><span id="description-count">0 / 2000</span></div>
</section>
<section class="tab-panel" data-panel="keywords">
<label class="field">
<span>People and keywords</span>
<textarea id="keywords-input" class="input textarea" rows="7" placeholder="Daniel, family, birthday, Bergen"></textarea>
</label>
<p class="field-help">Separate entries with commas or new lines. Written as XMP Subject and IPTC Keywords.</p>
</section>
</form>
<section class="right-footer">
<div id="save-status" class="save-status idle">
<span class="status-icon">●</span>
<div><strong>No photo selected</strong><span>Open a folder to begin.</span></div>
</div>
<button id="copy-previous" class="button wide" disabled>Copy previous values</button>
</section>
</aside>
</main>
</div>
<dialog id="shortcuts-dialog">
<div class="dialog-heading"><h2>Keyboard shortcuts</h2><button id="close-shortcuts" class="icon-button">×</button></div>
<dl class="shortcut-list">
<div><dt>Enter / Ctrl+Enter</dt><dd>Save and open next photo</dd></div>
<div><dt>Ctrl+S</dt><dd>Save current photo and stay on it</dd></div>
<div><dt>← / →</dt><dd>Previous or next photo</dd></div>
<div><dt>S</dt><dd>Mark skipped and open next photo</dd></div>
<div><dt>C</dt><dd>Copy previous photo's values</dd></div>
</dl>
</dialog>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="/app.js" type="module"></script>
</body>
</html>