Open a full-screen preview when tapping a gallery item

Tapping a gallery tile/row opens the existing media preview scoped to that gallery's attachments, paging between them. Introduces a typed MediaPreviewItemID (replacing the stringly-typed preview identifier) and a gallery-scoped TimelineMediaPreviewDataSource; the tap routes through TimelineInteractionHandler/TimelineViewModel. Non-previewable (.other) items are skipped without shifting the tapped index.

Co-authored-by: svetoslav.mitov <svetoslav.mitov@sportinno.com>

just use id instead of previewID

removed horrible multiline ternary

pr suggestions

remove redundant code

remove empty caption display + gallery uses the appropriate media timeline actions
This commit is contained in:
Mauro Romito
2026-07-27 19:14:23 +02:00
committed by Mauro
parent b4f397ed6a
commit 7ea9aeb174
15 changed files with 343 additions and 112 deletions
@@ -15,8 +15,21 @@ enum TimelineMediaPreviewViewModelAction: Equatable {
case dismiss
}
/// Identifies a media preview item — either a whole timeline item or a single gallery attachment.
enum MediaPreviewItemID: Hashable {
case timelineItem(TimelineItemIdentifier.EventOrTransactionID)
case galleryItem(GalleryItemID)
/// Identifies by event/transaction ID only, since the unique ID differs across timelines
/// and matching must survive rebuilding a filtered timeline to fetch the other media.
init(timelineItem: EventBasedMessageTimelineItemProtocol) {
guard let id = timelineItem.id.eventOrTransactionID else { fatalError("Virtual items cannot be previewed.") }
self = .timelineItem(id)
}
}
enum TimelineMediaPreviewDriverAction {
case itemLoaded(TimelineItemIdentifier.EventOrTransactionID)
case itemLoaded(MediaPreviewItemID)
case showItemDetails(TimelineMediaPreviewItem.Media)
case exportFile(TimelineMediaPreviewFileExportPicker.File)
case authorizationRequired(appMediator: AppMediatorProtocol)