From 24380b0322957504279811ae31455e05ad8ca1cd Mon Sep 17 00:00:00 2001 From: Chad Miller Date: Wed, 15 Apr 2026 17:34:15 -0700 Subject: [PATCH] fix: collapse exif section when current photo has no metadata - Animate height to zero when swiping to a photo without camera data - Only render settings row (aperture, ISO, etc.) when at least one value exists Co-Authored-By: Claude Opus 4.6 --- Grain/Views/Components/ExifInfoView.swift | 13 +++++++------ Grain/Views/Components/GalleryCardView.swift | 8 ++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Grain/Views/Components/ExifInfoView.swift b/Grain/Views/Components/ExifInfoView.swift index c0de71e..9be1e11 100644 --- a/Grain/Views/Components/ExifInfoView.swift +++ b/Grain/Views/Components/ExifInfoView.swift @@ -69,13 +69,14 @@ struct ExifInfoView: View { .foregroundStyle(style) .opacity(exif?.lens != nil ? 1 : 0) } - ExifSettingsRow( - tokens: [exif?.focalLength, exif?.fNumber, exif?.exposureTime, exif?.iso], - style: style - ) + let settingsTokens = [exif?.focalLength, exif?.fNumber, exif?.exposureTime, exif?.iso] + if settingsTokens.contains(where: { $0 != nil }) { + ExifSettingsRow( + tokens: settingsTokens, + style: style + ) + } } - // Single opacity for the whole block so all rows appear/disappear together. - // nil animation suppresses any inherited transaction so it's always instant. .opacity(exif != nil ? 1 : 0) .animation(.easeInOut(duration: 0.2), value: exif == nil) } diff --git a/Grain/Views/Components/GalleryCardView.swift b/Grain/Views/Components/GalleryCardView.swift index 10972f0..1c3756c 100644 --- a/Grain/Views/Components/GalleryCardView.swift +++ b/Grain/Views/Components/GalleryCardView.swift @@ -530,12 +530,13 @@ struct GalleryCardView: View { @ViewBuilder private func captionSection(lr: LabelResolution) -> some View { - // EXIF info — always rendered when any photo in the gallery has exif so - // the card height stays locked; content fades in/out per photo. + // EXIF info — collapses when the current photo has no metadata, + // expands smoothly when swiping to a photo that does. let allPhotos = gallery.items ?? [] if allPhotos.contains(where: { $0.exif?.hasDisplayableData ?? false }) { let currentExif = allPhotos.indices.contains(currentPage) ? allPhotos[currentPage].exif : nil + let hasCurrentExif = currentExif?.hasDisplayableData ?? false ExifInfoView( exif: currentExif?.displayData, reserveCameraRow: allPhotos.contains(where: { $0.exif?.cameraName != nil }), @@ -544,6 +545,9 @@ struct GalleryCardView: View { .transaction { $0.animation = nil } .padding(.horizontal, 12) .padding(.top, 8) + .frame(maxHeight: hasCurrentExif ? nil : 0, alignment: .top) + .clipped() + .animation(.easeInOut(duration: 0.2), value: hasCurrentExif) } // Title & description -- 2.51.2