From f654806e919b383f1a25b0421dbc63e39340ac55 Mon Sep 17 00:00:00 2001 From: Boris Klimenko <2@borisklimenko.ru> Date: Mon, 15 Jun 2026 21:27:20 +0200 Subject: [PATCH 1/2] Add haptic feedback between media messages --- .../GalleryUI/Sources/GalleryController.swift | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index 018b5fc9f8..2a42d05a4a 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -654,6 +654,19 @@ public struct GalleryEntry { } } +private enum GalleryEntryBoundaryId: Equatable { + case message(UInt32) + case group(UInt32) +} + +private func galleryEntryBoundaryId(_ entry: GalleryEntry) -> GalleryEntryBoundaryId { + if let groupId = entry.entry.message.groupInfo?.stableId { + return .group(groupId) + } else { + return .message(entry.entry.message.stableId) + } +} + private func galleryEntriesForMessageHistoryEntries(_ entries: [MessageHistoryEntry], mediaSubject: GalleryMediaSubject?) -> [GalleryEntry] { var results: [GalleryEntry] = [] for entry in entries { @@ -749,6 +762,8 @@ public class GalleryController: ViewController, StandalonePresentableController, private let baseNavigationController: NavigationController? private var hiddenMediaManagerIndex: Int? + private let boundaryHaptic = HapticFeedback() + private var currentBoundaryId: GalleryEntryBoundaryId? private let actionInteraction: GalleryControllerActionInteraction? private var performAction: (GalleryControllerInteractionTapAction) -> Void @@ -816,6 +831,7 @@ public class GalleryController: ViewController, StandalonePresentableController, } self.titleView = GalleryTitleView(context: context, presentationData: self.presentationData) + self.boundaryHaptic.prepareTap() super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: GalleryController.darkNavigationTheme, strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))) @@ -1697,7 +1713,13 @@ public class GalleryController: ViewController, StandalonePresentableController, if let index = index { let entry = strongSelf.entries[index] let message = strongSelf.entries[index].entry.message - + let boundaryId = galleryEntryBoundaryId(entry) + if let currentBoundaryId = strongSelf.currentBoundaryId, currentBoundaryId != boundaryId { + strongSelf.boundaryHaptic.tap() + } + strongSelf.currentBoundaryId = boundaryId + strongSelf.boundaryHaptic.prepareTap() + strongSelf.centralEntryStableId = entry.stableId if let selectedMedia = selectedMediaForMessage(message: message, mediaSubject: entry.mediaSubject) { hiddenItem = (message.id, selectedMedia) From a8f6975a97abcd66620d1ac055df4e10b25fceea Mon Sep 17 00:00:00 2001 From: Boris Klimenko <2@borisklimenko.ru> Date: Mon, 15 Jun 2026 22:40:37 +0200 Subject: [PATCH 2/2] Initialize gallery boundary haptic state --- submodules/GalleryUI/Sources/GalleryController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index 2a42d05a4a..5937f057fc 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -1706,6 +1706,9 @@ public class GalleryController: ViewController, StandalonePresentableController, } self.galleryNode.pager.replaceItems(items, centralItemIndex: centralItemIndex) + if let centralItemIndex = centralItemIndex, centralItemIndex < self.entries.count { + self.currentBoundaryId = galleryEntryBoundaryId(self.entries[centralItemIndex]) + } self.galleryNode.pager.centralItemIndexUpdated = { [weak self] index in if let strongSelf = self {