diff options
Diffstat (limited to 'views/admin/album.erb')
| -rw-r--r-- | views/admin/album.erb | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/views/admin/album.erb b/views/admin/album.erb index 9d98c5e..49ec4ca 100644 --- a/views/admin/album.erb +++ b/views/admin/album.erb @@ -14,6 +14,13 @@ <form method="post" action="/admin/edit/<%= @rel %>"> <fieldset class="album-settings"> <legend>Album</legend> + <% unless @rel.empty? %> + <div class="form-row"> + <label>Folder name + <input type="text" name="folder_name" value="<%= File.basename(@dir) %>"> + </label> + </div> + <% end %> <div class="form-row"> <label>Title override <input type="text" name="album_title" value="<%= @data['title'] %>" placeholder="(use directory name)"> @@ -108,4 +115,62 @@ </ul> </section> <% end %> + + <section class="admin-update"> + <h2>Update</h2> + <p class="update-hint">Scans this album for new/removed files, extracts EXIF data, and generates missing thumbnails.</p> + <button id="update-btn" class="btn" onclick="startUpdate()">Run Update</button> + <div id="update-panel" class="update-panel hidden"> + <div id="update-status" class="update-status"></div> + <pre id="update-log" class="update-log"></pre> + </div> + </section> + + <script> + async function startUpdate() { + const btn = document.getElementById('update-btn'); + const panel = document.getElementById('update-panel'); + const log = document.getElementById('update-log'); + const status = document.getElementById('update-status'); + const rel = <%= @rel.to_json %>; + + btn.disabled = true; + btn.textContent = 'Running…'; + log.textContent = ''; + status.textContent = 'Running…'; + status.className = 'update-status running'; + panel.classList.remove('hidden'); + + const res = await fetch('/admin/update', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ rel }) + }); + const { job_id } = await res.json(); + + let seen = 0; + const poll = setInterval(async () => { + const r = await fetch('/admin/update/' + job_id); + const data = await r.json(); + const fresh = data.lines.slice(seen); + if (fresh.length) { + log.textContent += fresh.join('\n') + '\n'; + log.scrollTop = log.scrollHeight; + seen = data.lines.length; + } + if (data.status !== 'running') { + clearInterval(poll); + btn.disabled = false; + btn.textContent = 'Run Update'; + if (data.status === 'done') { + status.textContent = 'Done ✓'; + status.className = 'update-status done'; + } else { + status.textContent = 'Error ✗'; + status.className = 'update-status error'; + } + } + }, 1500); + } + </script> </div> |
