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
@@ -239,6 +239,10 @@ class TimelineInteractionHandler {
text = content.caption ?? ""
htmlText = content.formattedCaptionHTMLString
editType = text.isEmpty ? .addCaption : .editCaption
case .gallery(let content):
text = content.caption ?? ""
htmlText = content.formattedCaptionHTMLString
editType = text.isEmpty ? .addCaption : .editCaption
default:
text = messageTimelineItem.body
}
@@ -569,6 +573,16 @@ class TimelineInteractionHandler {
}
}
/// Opens a media preview scoped to a single gallery's attachments. The preview pages
/// only between the items of that one gallery — siblings in the wider timeline aren't
/// reachable from this entry point (use the regular media tap for that).
func processGalleryItemTap(itemID: TimelineItemIdentifier, index: Int) -> TimelineControllerAction {
guard let galleryItem = timelineController.timelineItems.firstUsingStableID(itemID) as? GalleryRoomTimelineItem else {
return .none
}
return .displayGalleryPreview(galleryItem: galleryItem, initialIndex: index)
}
// MARK: - Private
private func buildReplyInfo(for item: EventBasedTimelineItemProtocol) -> ReplyInfo {