fix(journey): dedupe gallery photos and fix Immich picker button visibility on mobile (#802 #819)

Fix #802: ProviderPicker modal now uses dvh-based max-height, items-end
on mobile (bottom-sheet), flex-shrink-0 on all fixed sections, min-h-0
on the scrollable grid, and env(safe-area-inset-bottom) padding so the
Add button is always reachable above the iOS home indicator.

Fix #819: Gallery view now deduplicates photos by photo_id (underlying
trek_photos.id) so a photo linked from Gallery into an activity no longer
appears twice. Gallery delete cascades to all copies. EntryEditor From
Gallery grid and photo count also deduplicated. Server photo_count uses
COUNT(DISTINCT photo_id). Preserves #729 guarantee (removing from an
activity does not delete the Gallery copy).
This commit is contained in:
jubnl
2026-04-21 23:26:02 +02:00
parent 45fa6fd0d3
commit 3f489880da
2 changed files with 39 additions and 25 deletions
+2 -2
View File
@@ -58,7 +58,7 @@ export function listJourneys(userId: number) {
return db.prepare(`
SELECT DISTINCT j.*,
(SELECT COUNT(*) FROM journey_entries je WHERE je.journey_id = j.id AND je.type != 'skeleton') as entry_count,
(SELECT COUNT(*) FROM journey_photos jp JOIN journey_entries je2 ON jp.entry_id = je2.id WHERE je2.journey_id = j.id) as photo_count,
(SELECT COUNT(DISTINCT jp.photo_id) FROM journey_photos jp JOIN journey_entries je2 ON jp.entry_id = je2.id WHERE je2.journey_id = j.id) as photo_count,
(SELECT COUNT(DISTINCT je3.location_name) FROM journey_entries je3 WHERE je3.journey_id = j.id AND je3.location_name IS NOT NULL AND je3.location_name != '') as place_count,
(SELECT MIN(t.start_date) FROM journey_trips jt JOIN trips t ON jt.trip_id = t.id WHERE jt.journey_id = j.id) as trip_date_min,
(SELECT MAX(t.end_date) FROM journey_trips jt JOIN trips t ON jt.trip_id = t.id WHERE jt.journey_id = j.id) as trip_date_max
@@ -160,7 +160,7 @@ export function getJourneyFull(journeyId: number, userId: number) {
// stats
const entryCount = entries.filter(e => e.type === 'entry').length;
const photoCount = photos.length;
const photoCount = new Set(photos.map(p => p.photo_id)).size;
const places = [...new Set(entries.map(e => e.location_name).filter(Boolean))];
const userPrefs = db.prepare(