# NVideo Local Bookshelf — v0.2 (대용량 책장 최적화)

NVideo Downloader의 **로컬 책장 + 이미지 뷰어**를 참고한 별도의 정적 웹앱입니다. 사용자 PC의 로컬 폴더를 브라우저에서 직접 읽습니다. 서버로 원본 이미지를 업로드하지 않습니다. 기존 PySide6 애플리케이션의 전체 기능을 1:1 이식한 버전은 아닙니다.

## v0.2에서 달라진 점

- **작가 모드** — 선택한 루트 폴더의 첫 번째 하위 폴더를 작가명으로 간주합니다. 작가 카드에 작품 수를 표시하고, 선택하면 해당 작가의 작품만 펼칩니다. 작가 이름이 없는 루트 직속 ZIP은 `미분류`로 묶입니다.
- **한눈에 보기** — 전체 작품을 이름순 등으로 탐색합니다.
- **최근 파일순** — 파일의 `lastModified`(마지막 수정 시각)를 우선 사용합니다. 수정 시각을 가져올 수 없으면 **책장 색인에서 최초 발견한 시각**을 사용합니다. 원본 다운로드 시각과 정확히 일치하지 않을 수 있습니다.
- **한 번에 48개부터 화면에 표시** — 스크롤할 때 추가로 48개씩 로딩하며 **최대 약 192개 카드 DOM**만 유지합니다. 예전처럼 작품 4만 개의 카드를 전부 만들지 않습니다. 이전 항목도 위로 스크롤하거나 `↑ 이전 항목 불러오기`로 다시 볼 수 있습니다.
- **IndexedDB 책장 메타데이터 캐시** — 작품 ID, 상대 경로, 작가, 이미지 수, 최초 발견 시각, 파일 수정 시각만 저장합니다. 원본 ZIP, 원본 이미지, 실제 절대 경로를 이 색인에 저장하지 않습니다.
- **캐시 우선 표시 + 주기적 전체 재스캔** — 저장된 목록을 우선 표시하고, 마지막 스캔에서 **6시간 이상** 지났거나 색인이 미완성이면 권한이 있는 폴더에 한해 백그라운드 재스캔합니다. 바로 새 작품/삭제 항목을 확인하려면 `↻ 다시 스캔`을 누릅니다.
- **2단계 초기 스캔** — 작품 경로를 찾으면 먼저 중간 캐시를 저장하고, 파일 수정 시각을 최대 4개씩 조회하여 색인을 완성합니다. 최초 스캔은 저장 장치와 파일 수에 따라 오래 걸릴 수 있습니다.

## 사용 방법

1. `https://<프로젝트명>.pages.dev/`로 접속합니다. 권장 브라우저는 최신 Chrome/Edge입니다.
2. `+ 로컬 폴더 등록`에서 **작품 폴더들이 있는 상위 폴더**를 선택합니다.
3. `작가 모드`에서 작가 카드를 선택하거나 `한눈에 보기`/`최근 파일순`으로 전환합니다.
4. 작품을 클릭해 한 쪽·두 쪽·스크롤 뷰어로 감상합니다.
5. 새 작품이 추가되거나 삭제됐다면 `↻ 다시 스캔`을 누릅니다. 자동 재검사는 6시간 간격 조건으로 수행됩니다.

## 폴더 구조와 그룹 기준

```text
작가별_재정리/                ← 등록한 폴더
  작가 A/
    작품 1.zip
    작품 2.cbz
  작가 B/
    시리즈/
      작품 3.zip
  작품 4.zip                ← 작가 '미분류'
```

작가 모드는 원본 NVideo의 고급 작가 DB 병합/수동 묶음과 **동일하지 않습니다.** 첫 단계 폴더명만 활용하는 v0.2 기본 그룹입니다. 원본 앱의 작가 매핑, 중복 작가 병합, 그룹/태그/평점은 후속 이식 대상입니다.

## 캐시와 파일 변동

- **작품 캐시:** `IndexedDB`의 `nvideo-local-bookshelf-index-v2`에 브라우저 프로필·웹사이트 주소 단위로 저장합니다.
- **기존 등록 폴더 정보:** v0.1의 `nvideo-local-bookshelf-v1`를 계속 사용합니다.
- **즐겨찾기/독서 진행도:** v0.1과 동일한 `localStorage` 키를 계속 사용합니다.
- **작품이 삭제되면:** 재스캔 시 색인에서 제외합니다. 이 과정에서 **실제 원본 파일을 삭제하지 않습니다.**
- **작품이 추가되면:** 재스캔 시 최초 발견 시각을 새로 기록합니다.
- **기존 파일의 수정 시각이 바뀌면:** 수동 재스캔에서 시각을 다시 읽습니다. 자동 재스캔에서는 기존 항목의 날짜를 재사용하여 속도를 개선합니다.
- **권한이 끊기면:** 기존 메타데이터는 표시할 수 있으나 표지/작품 열람에는 폴더 재연결이 필요합니다.
- **저장소 정리/시크릿 모드:** 브라우저 데이터를 지우면 메타데이터 캐시가 사라질 수 있습니다. 원본 파일은 영향받지 않습니다.

## 지원/제한

- 이미지: JPG/JPEG/PNG/WEBP/GIF/BMP/AVIF (브라우저 코덱에 따라 일부 제외)
- 아카이브: ZIP/CBZ (STORE 또는 DEFLATE, 비암호화/일반 ZIP)
- 아직 미지원: RAR/7z, ZIP64, PDF, 원본 NVideo SQLite DB 가져오기, 고급 작가 매핑·수동 그룹 등
- ZIP 파일은 **필요한 이미지 부분만 압축 해제**하지만, 파일 메타데이터 검색 자체는 로컬 디스크 I/O를 사용합니다.
- 루트 폴더 1개에 파일이 수만 개면 **첫 스캔/수정 시각 수집**은 오래 걸릴 수 있습니다. 다음 방문에는 캐시를 우선 표시합니다.
- 파일 자동 감시는 지원하지 않습니다. 변동 사항은 수동 재스캔 또는 6시간 조건 재스캔으로 반영합니다.
- 이 버전의 캐시에는 **파일 경로(상대 경로)**와 작가/작품 이름이 저장됩니다. 브라우저 프로필을 함께 쓰는 다른 사람에게는 해당 이름이 보일 수 있습니다.
- 페이지가 다른 도메인으로 이전되면 이전 도메인의 IndexedDB를 자동 이전하지 않습니다.

## 배포

Cloudflare Pages에서 정적 사이트로 배포할 수 있습니다. 기존 비공개 GitHub 저장소를 사용하는 경우 **자동 배포 패키지의 `DEPLOY_PRIVATE_CLOUDFLARE.bat`**를 사용하세요. 저장소에 HTML/CSS/JS 파일만 업로드합니다. 기존 브라우저의 로컬 책장 데이터에는 영향을 주지 않습니다.

## 검증

- JavaScript 구문 검사
- 가상 로컬 폴더에서 44,400개 ZIP 항목 스캔 및 작가 분류·메타데이터 시각 비교
- 배포 ZIP 구조와 무결성 검사

실제 Chrome/Edge에서의 성능·동작 테스트는 실시하지 않았습니다. 특히 수만 개 로컬 작품의 스캔 시간과 HDD/외장 드라이브 성능은 환경에 따라 다를 수 있습니다.
