diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index ca38c82..06fda34 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -232,22 +232,30 @@ pub fn run_scan_pipeline( root: &Path, cancel: &std::sync::atomic::AtomicBool, mut on_progress: impl FnMut(ScanProgress), + on_refresh: impl Fn(), ) { let result = archive_indexer::pipeline::scan_source(db, source_id, root, cancel, &mut on_progress); match result { Ok(stats) => { - tracing::info!(?stats, source_id, "스캔 완료 — 메타데이터 추출 시작"); + tracing::info!(?stats, source_id, "스캔(열거) 완료 — 즉시 표시 후 메타 진행"); + // 열거가 끝나면 파일 행은 이미 DB에 있다. 느린 메타(특히 영상 ffprobe)를 + // 기다리지 않고 ① 썸네일 생성을 시작하고 ② 그리드를 바로 띄운다. + thumbs.enqueue_pending(db, Some(source_id)); + on_refresh(); + // 이미지 메타는 헤더만 읽어 빠름 → 끝나면 사진 종횡비 재배치. match archive_indexer::meta::extract_image_meta(db, source_id, cancel) { Ok(n) => tracing::info!(count = n, "이미지 메타 추출 완료"), Err(e) => tracing::error!("이미지 메타 추출 오류: {e}"), } + on_refresh(); + // 영상 메타(ffprobe)는 파일당 프로세스라 느림 → 백그라운드에서 진행. + // 완료 후 재배치는 호출자의 최종 library-changed가 담당. if let Some(t) = tools { match archive_indexer::meta::extract_video_meta(db, source_id, cancel, t) { Ok(n) => tracing::info!(count = n, "영상 메타 추출 완료"), Err(e) => tracing::error!("영상 메타 추출 오류: {e}"), } } - thumbs.enqueue_pending(db, Some(source_id)); } Err(e) => tracing::warn!("스캔 중단: {e}"), } @@ -272,12 +280,26 @@ pub fn spawn_scan_thread( .spawn(move || { // 스캔/메타 오케스트레이션 스레드도 저우선순위로 — UI 응답성 우선 archive_indexer::prio::set_current_thread_low(); - run_scan_pipeline(&db, &tools, &thumbs, source_id, Path::new(&root), &cancel, |p| { - if let Some(ch) = &on_progress { - let _ = ch.send(p); - } - }); + let app_refresh = app.clone(); + run_scan_pipeline( + &db, + &tools, + &thumbs, + source_id, + Path::new(&root), + &cancel, + |p| { + if let Some(ch) = &on_progress { + let _ = ch.send(p); + } + }, + // 열거 직후·이미지 메타 후 그리드를 즉시 갱신 (영상 메타를 기다리지 않음) + move || { + let _ = app_refresh.emit("library-changed", source_id); + }, + ); running.store(false, Ordering::SeqCst); + // 영상 메타까지 끝난 뒤 최종 재배치 let _ = app.emit("library-changed", source_id); }) .map_err(err_str)?; diff --git a/src-tauri/src/watcher.rs b/src-tauri/src/watcher.rs index 8fd6ff1..89eb228 100644 --- a/src-tauri/src/watcher.rs +++ b/src-tauri/src/watcher.rs @@ -64,6 +64,9 @@ impl WatcherManager { Path::new(&root), &state.scan_cancel, |_| {}, + || { + let _ = app.emit("library-changed", source_id); + }, ); state.scan_running.store(false, Ordering::SeqCst); let _ = app.emit("library-changed", source_id);