Fix folder picker window focus and ensure auto-sync of embedded metadata on scan
This commit is contained in:
@@ -342,6 +342,7 @@ mark{background:rgba(34,211,238,.28);color:#fff;border-radius:2px;padding:0 1px}
|
|||||||
<div class="folderRow">
|
<div class="folderRow">
|
||||||
<input id="folder" spellcheck="false" placeholder="/path/to/your/photos">
|
<input id="folder" spellcheck="false" placeholder="/path/to/your/photos">
|
||||||
<button id="btnBrowseFolder" title="Open native macOS folder chooser">📁 Browse</button>
|
<button id="btnBrowseFolder" title="Open native macOS folder chooser">📁 Browse</button>
|
||||||
|
<input type="file" id="fallbackFolderInput" webkitdirectory style="display:none">
|
||||||
<button id="btnScan">◈ Scan Directory</button>
|
<button id="btnScan">◈ Scan Directory</button>
|
||||||
</div>
|
</div>
|
||||||
<button id="btnStart" class="btn-primary" disabled>▶ Start Pipeline</button>
|
<button id="btnStart" class="btn-primary" disabled>▶ Start Pipeline</button>
|
||||||
@@ -1010,13 +1011,16 @@ async function api(path, body){
|
|||||||
if($("btnBrowseFolder")){
|
if($("btnBrowseFolder")){
|
||||||
$("btnBrowseFolder").onclick = async ()=>{
|
$("btnBrowseFolder").onclick = async ()=>{
|
||||||
$("btnBrowseFolder").disabled = true;
|
$("btnBrowseFolder").disabled = true;
|
||||||
|
showToast("Opening folder chooser…", "info");
|
||||||
const j = await api("/api/choose_folder");
|
const j = await api("/api/choose_folder");
|
||||||
$("btnBrowseFolder").disabled = false;
|
$("btnBrowseFolder").disabled = false;
|
||||||
if(j.ok && j.folder){
|
if(j.ok && j.folder){
|
||||||
$("folder").value = j.folder;
|
$("folder").value = j.folder;
|
||||||
showToast("Selected folder: " + j.folder, "ok");
|
showToast("Selected folder: " + j.folder, "ok");
|
||||||
const scanRes = await api("/api/scan",{folder: j.folder});
|
scanned = true;
|
||||||
if(scanRes.images!=null){ scanned=true; setBadge("idle"); }
|
setBadge("idle");
|
||||||
|
} else if($("fallbackFolderInput")){
|
||||||
|
$("fallbackFolderInput").click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
18
server.py
18
server.py
@@ -1779,7 +1779,7 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
elif self.path == "/api/choose_folder":
|
elif self.path == "/api/choose_folder":
|
||||||
try:
|
try:
|
||||||
cmd = ["osascript", "-e", 'POSIX path of (choose folder with prompt "Select Photo Folder to Organize:")']
|
cmd = ["osascript", "-e", 'tell application "System Events" to set frontmost of (first process whose background only is false) to true', "-e", 'POSIX path of (choose folder with prompt "Select Photo Folder to Organize:")']
|
||||||
r = subprocess.run(cmd, capture_output=True, timeout=60)
|
r = subprocess.run(cmd, capture_output=True, timeout=60)
|
||||||
if r.returncode == 0:
|
if r.returncode == 0:
|
||||||
chosen = r.stdout.decode("utf-8").strip()
|
chosen = r.stdout.decode("utf-8").strip()
|
||||||
@@ -1787,9 +1787,21 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
with S.lock:
|
with S.lock:
|
||||||
S.folder = chosen
|
S.folder = chosen
|
||||||
save_folder_config(chosen)
|
save_folder_config(chosen)
|
||||||
self._json({"ok": True, "folder": chosen})
|
images, videos, sidecars = scan_folder(chosen)
|
||||||
|
done = sum(1 for p in images if p in S.done_paths)
|
||||||
|
with S.lock:
|
||||||
|
S.files = images
|
||||||
|
S.total_images = len(images)
|
||||||
|
S.video_files = videos
|
||||||
|
S.skipped_videos = len(videos)
|
||||||
|
S.skipped_sidecars = sidecars
|
||||||
|
S.status = "idle"
|
||||||
|
sync_metadata_from_folder(chosen)
|
||||||
|
load_journal()
|
||||||
|
push_stats()
|
||||||
|
self._json({"ok": True, "folder": chosen, "images": len(images), "videos": len(videos), "alreadyDone": done})
|
||||||
return
|
return
|
||||||
self._json({"error": "No folder selected"}, 400)
|
self._json({"error": "No folder selected or dialog cancelled"}, 400)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._json({"error": str(e)}, 500)
|
self._json({"error": str(e)}, 500)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user