기존엔 항상 라이브러리 전체를 대상으로 했다. 이제 중복 검토 패널에서
현재 보고 있는 뷰(폴더=하위 포함 / 소스)로 범위를 좁힐 수 있고,
폴더/소스 뷰에서는 기본값이 '현재 위치'다. 전체/검색/태그/스마트 뷰는
전체 라이브러리로 고정.
- dedupe::Scope { All | Source | Folder{recursive} } 도입, load_files/run에 적용
(folder_snapshot과 동일한 경로 프리픽스 스코핑)
- start_dedupe에 folder_id/recursive 파라미터 추가
- DedupePanel: view() 기반 범위 세그먼트 컨트롤
- 테스트: folder_scope_restricts_detection (folderA=1그룹, 전체=2그룹, 누출 없음)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
썸네일 미준비 셀이 빈 칸으로 보이던 것을 개선. 스냅샷 flags에
비트1(생성 실패, thumb_state=2)을 추가해 대기/실패를 구분한다.
- 대기(생성 전): 은은한 pulse 스켈레톤(bg-hover)
- 실패: 정적 아이콘(🖼) — 무한 pulse 방지
- 준비됨: 썸네일 이미지
검증: 619개 대기 상태에서 하단 스크롤 시 pulse 스켈레톤 50개 →
생성 완료되며 이미지로 즉시 전환 확인(bg #33363d, animation pulse).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
원인: 실사진(수십 MP) 스캔 시 메타 추출(rayon)과 썸네일 워커가
NORMAL 우선순위로 전 코어를 포화시켜 WebView UI 스레드를 굶김.
풀해상도 JPEG 디코드는 파일당 ~72MB를 할당해 병렬 시 메모리 대역폭까지 포화.
- prio 모듈: 현재 스레드 우선순위 낮추기(Win BELOW_NORMAL / macOS nice+5),
메타 전용 저우선순위 rayon 풀(코어-1, 전역 풀과 분리)
- 썸네일 워커 스레드·스캔 스레드를 저우선순위로 → CPU 포화 시 UI 우선 스케줄
- meta 이미지/영상 추출을 저우선순위 풀에서 실행
- JPEG는 jpeg-decoder DCT 축소 디코드(1/8 등) 사용:
24MP 기준 풀디코드 63ms/72MB → 축소 38ms/1MB (1.7배·메모리 ~70배 절감),
RGB24/L8만 처리하고 그 외(CMYK)는 기존 경로로 폴백
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 사이드바 소스 행 hover 시 ✕ 버튼 → 확인 후 인덱스/폴더/태그/썸네일
캐시 제거. 디스크의 실제 파일은 삭제하지 않음.
- 로컬: 파일 워처 해제. 원격: 연결 해제 + 자격증명(키체인/볼트) 삭제.
- maintenance::remove_source (defer_foreign_keys로 자기참조 FK 처리),
스캔 중 제외 방지, 제외한 소스를 보던 중이면 전체 뷰로 전환.
Rust 테스트: 실제 파일 보존 + 인덱스/썸네일 제거 검증 통과.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
P1 원격 소스 UX:
- remote_thumbs: VFS 다운로드로 원격 썸네일 생성(이미지 EXIF 내장 우선,
영상은 미디어서버 bridge URL로 ffmpeg Range 추출)
- 앱 시작 시 키체인 자격증명으로 원격 소스 자동 재연결
- fileops: physical_move에 Windows 공유위반 재시도
P3 그리드/포맷:
- RAW(cr2/nef/arw/dng 등) 내장 JPEG 프리뷰 추출 썸네일(scan_largest_jpeg)
- 그리드 마퀴(드래그 사각형) 다중선택
- .gitattributes 줄바꿈 정규화
Rust 테스트 51개 통과.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>