feat: Albums view, auto albums, EXIF details, download, bulk select
Albums tab with manual album CRUD (create/delete, cover photo grid) and Smart Albums auto-generated by year, city, and camera model using SQLite window functions — no extra storage, computed from existing data. Lightbox gets a download-original button (streams raw file with Content-Disposition: attachment). DetailPanel Camera section expands to show ISO, aperture, shutter speed, focal length, and lens model extracted at ingest time; five new DB columns added via safe ALTER TABLE migration. Bulk selection: hover a photo to reveal a circle checkbox; selecting any photo activates a floating action bar for star/unstar and add-to-album across the whole selection. PhotoCard wrapped in React.memo to limit re-renders to only affected cards. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
f8b32dd440
commit
51c752602a
11 files changed
+598
-31
No files matched your search
+9
-2
@@ -115,6 +115,11 @@ export function openDb(dbPath) {
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN place_country TEXT'); } catch {}
|
||||
try { db.exec("ALTER TABLE photos ADD COLUMN media_type TEXT NOT NULL DEFAULT 'photo'"); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN duration REAL'); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN iso INTEGER'); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN aperture REAL'); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN shutter_speed TEXT'); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN focal_length REAL'); } catch {}
|
||||
try { db.exec('ALTER TABLE photos ADD COLUMN lens_model TEXT'); } catch {}
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_photos_starred ON photos(starred)');
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_photos_place_city ON photos(place_city)');
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_photos_media_type ON photos(media_type)');
|
||||
@@ -128,11 +133,13 @@ export function openDb(dbPath) {
|
||||
INSERT OR IGNORE INTO photos
|
||||
(filepath, thumb_path, preview_path, date_taken, date_imported,
|
||||
camera_model, gps_lat, gps_lon, phash, width, height, filesize,
|
||||
place_city, place_country, media_type, duration)
|
||||
place_city, place_country, media_type, duration,
|
||||
iso, aperture, shutter_speed, focal_length, lens_model)
|
||||
VALUES
|
||||
(@filepath, @thumb_path, @preview_path, @date_taken, @date_imported,
|
||||
@camera_model, @gps_lat, @gps_lon, @phash, @width, @height, @filesize,
|
||||
@place_city, @place_country, @media_type, @duration)
|
||||
@place_city, @place_country, @media_type, @duration,
|
||||
@iso, @aperture, @shutter_speed, @focal_length, @lens_model)
|
||||
`),
|
||||
exists: db.prepare('SELECT 1 FROM photos WHERE filepath = ? LIMIT 1'),
|
||||
remove: db.prepare('DELETE FROM photos WHERE filepath = ?'),
|
||||
|
||||
Reference in new issue
Block a user