Fix sensitive chat bubble on iOS 18
This commit fixes an issue with the chat bubble view where it would unexpectedly trigger the reaction emoji keyboard when scrolling or swiping, which became specially sensitive on iOS 18. The fix consists of 2 parts: - Changing the long press gesture logic to better adhere to Apple's API specs - Modify the SwipeActions library to allow the gesture priority to be configurable, and demote the swiping gesture to have normal priority (it was found that having a high-priority drag gesture prevents long-presses from being activated) Closes: https://github.com/damus-io/damus/issues/2577 Changelog-Fixed: Fix sensitive long-press gesture on event chat bubble in iOS 18 Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -5564,10 +5564,10 @@
|
||||
};
|
||||
D78DB8572C1CE9CA00F0AB12 /* XCRemoteSwiftPackageReference "SwipeActions" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/aheze/SwipeActions";
|
||||
repositoryURL = "https://github.com/damus-io/SwipeActions.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 1.1.0;
|
||||
kind = revision;
|
||||
revision = 33d99756c3112e1a07c1732e3cddc5ad5bd0c5f4;
|
||||
};
|
||||
};
|
||||
D7A343EC2AD0D77C00CED48B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "babaf4d5748afecf49bbb702530d8e9576460692f478b0a50ee43195dd4440e2",
|
||||
"originHash" : "1b14e62192b3fa4b04a57cb4601d175b325dc16cb5f22c4c8eb975a675328637",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "emojikit",
|
||||
@@ -92,10 +92,9 @@
|
||||
{
|
||||
"identity" : "swipeactions",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/aheze/SwipeActions",
|
||||
"location" : "https://github.com/damus-io/SwipeActions.git",
|
||||
"state" : {
|
||||
"revision" : "41e6f6dce02d8cfa164f8c5461a41340850ca3ab",
|
||||
"version" : "1.1.0"
|
||||
"revision" : "33d99756c3112e1a07c1732e3cddc5ad5bd0c5f4"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -27,8 +27,6 @@ struct ChatEventView: View {
|
||||
// MARK: long-press reaction control objects
|
||||
/// Whether the user is actively pressing the view
|
||||
@State var is_pressing = false
|
||||
/// The dispatched work item scheduled by a timer to bounce the event bubble and show the emoji selector
|
||||
@State var long_press_bounce_work_item: DispatchWorkItem?
|
||||
@State var popover_state: PopoverState = .closed {
|
||||
didSet {
|
||||
let generator = UIImpactFeedbackGenerator(style: popover_state.some_sheet_open() ? .heavy : .light)
|
||||
@@ -39,6 +37,7 @@ struct ChatEventView: View {
|
||||
|
||||
@State private var isOnTopHalfOfScreen: Bool = false
|
||||
@ObservedObject var bar: ActionBarModel
|
||||
@Environment(\.swipeViewGroupSelection) var swipeViewGroupSelection
|
||||
|
||||
enum PopoverState: String {
|
||||
case closed
|
||||
@@ -206,28 +205,18 @@ struct ChatEventView: View {
|
||||
.scaleEffect(self.popover_state.some_sheet_open() ? 1.08 : is_pressing ? 1.02 : 1)
|
||||
.shadow(color: (is_pressing || self.popover_state.some_sheet_open()) ? .black.opacity(0.1) : .black.opacity(0.3), radius: (is_pressing || self.popover_state.some_sheet_open()) ? 8 : 0, y: (is_pressing || self.popover_state.some_sheet_open()) ? 15 : 0)
|
||||
.onLongPressGesture(minimumDuration: 0.5, maximumDistance: 10, perform: {
|
||||
long_press_bounce_work_item?.cancel()
|
||||
withAnimation(.bouncy(duration: 0.2, extraBounce: 0.35)) {
|
||||
let should_show_zap_sheet = !damus_state.settings.nozaps && damus_state.settings.onlyzaps_mode
|
||||
popover_state = should_show_zap_sheet ? .open_zap_sheet : .open_emoji_selector
|
||||
}
|
||||
}, onPressingChanged: { is_pressing in
|
||||
withAnimation(is_pressing ? .easeIn(duration: 0.5) : .easeOut(duration: 0.1)) {
|
||||
self.is_pressing = is_pressing
|
||||
if popover_state != .closed {
|
||||
return
|
||||
}
|
||||
if self.is_pressing {
|
||||
let item = DispatchWorkItem {
|
||||
// Ensure the action is performed only if the condition is still valid
|
||||
if self.is_pressing {
|
||||
withAnimation(.bouncy(duration: 0.2, extraBounce: 0.35)) {
|
||||
let should_show_zap_sheet = !damus_state.settings.nozaps && damus_state.settings.onlyzaps_mode
|
||||
popover_state = should_show_zap_sheet ? .open_zap_sheet : .open_emoji_selector
|
||||
}
|
||||
}
|
||||
}
|
||||
long_press_bounce_work_item = item
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: item)
|
||||
}
|
||||
}
|
||||
})
|
||||
.onChange(of: swipeViewGroupSelection.wrappedValue) { newValue in
|
||||
self.is_pressing = false
|
||||
}
|
||||
.background(
|
||||
GeometryReader { geometry in
|
||||
EmptyView()
|
||||
@@ -310,6 +299,7 @@ struct ChatEventView: View {
|
||||
.swipeSpacing(-20)
|
||||
.swipeActionsStyle(.mask)
|
||||
.swipeMinimumDistance(20)
|
||||
.swipeDragGesturePriority(.normal)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user