From 96df095b0bfbbc17ded0497b14d8a20efec36768 Mon Sep 17 00:00:00 2001 From: topAmity <112688936+topAmity@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:37:41 +0700 Subject: [PATCH] Fix direct chat back button: pop instead of dismiss, enlarge hit area AmityChatPage's back button had two issues in direct (conversation) chat: 1. Closes the whole UIKit instead of returning to the chat list. The chat room is pushed onto the nav stack by AmityChatHomePage, so "back" must pop. It called dismissOrPop(), which checks presentingViewController first and dismisses the entire modal when the nav stack itself was presented modally (the common host integration). AmityGroupChatPage already pops directly; direct chat now matches by preferring popViewController whenever it is not the nav-stack root, falling back to dismissOrPop() otherwise. 2. Back tap can fall through to the adjacent avatar (which, when a chatPageBehavior is registered, opens the profile image viewer). The back button was a bare 16x16 target with .buttonStyle(.plain) sitting 12pt from a 40x40 avatar. Expanded the tappable region to the 44x44 minimum with .contentShape(Rectangle()), which also hardens hit-test routing when the page is embedded in a custom container/nav wrapper. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Chat/Pages/DirectChat/AmityChatPage.swift | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/UpstraUIKit/AmityUIKit4/AmityUIKit4/Chat/Pages/DirectChat/AmityChatPage.swift b/UpstraUIKit/AmityUIKit4/AmityUIKit4/Chat/Pages/DirectChat/AmityChatPage.swift index d1f56603..5142ea94 100644 --- a/UpstraUIKit/AmityUIKit4/AmityUIKit4/Chat/Pages/DirectChat/AmityChatPage.swift +++ b/UpstraUIKit/AmityUIKit4/AmityUIKit4/Chat/Pages/DirectChat/AmityChatPage.swift @@ -351,7 +351,17 @@ public struct AmityChatPage: AmityPageView { VStack(spacing: 0) { HStack(spacing: 0) { Button { - host.controller?.dismissOrPop() + // The chat room is PUSHED onto the nav stack by AmityChatHomePage, + // so "back" must POP. dismissOrPop() checks presentingViewController + // first and dismisses the whole modal (closing the UIKit) when the + // nav stack itself was presented — the reported bug. Prefer popping + // whenever we're not the root of the nav stack; fall back otherwise. + if let nav = host.controller?.navigationController, + nav.viewControllers.count > 1 { + nav.popViewController(animated: true) + } else { + host.controller?.dismissOrPop() + } } label: { Image(AmityIcon.Chat.backButtonIcon.imageResource) .renderingMode(.template) @@ -359,9 +369,16 @@ public struct AmityChatPage: AmityPageView { .scaledToFit() .foregroundColor(Color(viewConfig.theme.baseColor)) .frame(width: 16, height: 16) + // Expand the tappable region to the 44x44 minimum target so a + // tap near the chevron can't fall through to the adjacent avatar. + // contentShape makes the whole frame hit-testable (not just the + // glyph), which also hardens routing when the page is embedded in + // a custom container/nav wrapper. + .frame(width: 44, height: 44) + .contentShape(Rectangle()) } .buttonStyle(.plain) - .padding(.trailing, 12) + .padding(.trailing, 0) Button { if let userId = pageViewModel.otherUserId {