From 110839627f2fc8121006c2461581faf916b22c25 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 10 Aug 2024 22:18:49 +0100 Subject: [PATCH] ios: new message sheet detents (#4639) * ios: new message sheet detents * animation * use isActive * fix sheet rendering * minor * increase onTap area * cleanup * cleanup * refactor, dont allow reducing sheet once opened --------- Co-authored-by: Levitating Pineapple --- .../Views/NewChat/NewChatMenuButton.swift | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift index 13c8bad611..bcca763a75 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift @@ -61,18 +61,39 @@ struct NewChatSheet: View { @State private var searchShowingSimplexLink = false @State private var searchChatFilteredBySimplexLink: String? = nil @Binding var alert: SomeAlert? - + + // Sheet height management + @State private var isAddContactActive = false + @State private var isScanPasteLinkActive = false + @State private var isLargeSheet = false + @State private var allowSmallSheet = true + + @AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true + var body: some View { - NavigationView { - viewBody() + let showArchive = !filterContactTypes(chats: chatModel.chats, contactTypes: [.chatDeleted]).isEmpty + let v = NavigationView { + viewBody(showArchive) .navigationTitle("New message") .navigationBarTitleDisplayMode(.large) .navigationBarHidden(searchMode) .modifier(ThemedBackground(grouped: true)) } + if #available(iOS 16.0, *), oneHandUI { + let sheetHeight: CGFloat = showArchive ? 575 : 500 + v.presentationDetents( + allowSmallSheet ? [.height(sheetHeight), .large] : [.large], + selection: Binding( + get: { isLargeSheet || !allowSmallSheet ? .large : .height(sheetHeight) }, + set: { isLargeSheet = $0 == .large } + ) + ) + } else { + v + } } - - @ViewBuilder private func viewBody() -> some View { + + @ViewBuilder private func viewBody(_ showArchive: Bool) -> some View { List { HStack { ContactsListSearchBar( @@ -90,21 +111,25 @@ struct NewChatSheet: View { if (searchText.isEmpty) { Section { - NavigationLink { + NavigationLink(isActive: $isAddContactActive) { NewChatView(selection: .invite, parentAlert: $alert) .navigationTitle("New chat") .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { - Label("Add contact", systemImage: "link.badge.plus") + navigateOnTap(Label("Add contact", systemImage: "link.badge.plus")) { + isAddContactActive = true + } } - NavigationLink { + NavigationLink(isActive: $isScanPasteLinkActive) { NewChatView(selection: .connect, showQRCodeScanner: true, parentAlert: $alert) .navigationTitle("New chat") .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { - Label("Scan / Paste link", systemImage: "qrcode") + navigateOnTap(Label("Scan / Paste link", systemImage: "qrcode")) { + isScanPasteLinkActive = true + } } NavigationLink { AddGroupView() @@ -116,7 +141,7 @@ struct NewChatSheet: View { } } - if (!filterContactTypes(chats: chatModel.chats, contactTypes: [.chatDeleted]).isEmpty) { + if (showArchive) { Section { NavigationLink { DeletedChats() @@ -140,6 +165,22 @@ struct NewChatSheet: View { } } + /// Extends label's tap area to match `.insetGrouped` list row insets + private func navigateOnTap(_ label: L, setActive: @escaping () -> Void) -> some View { + label + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading, 16).padding(.vertical, 8).padding(.trailing, 32) + .contentShape(Rectangle()) + .onTapGesture { + isLargeSheet = true + DispatchQueue.main.async { + allowSmallSheet = false + setActive() + } + } + .padding(.leading, -16).padding(.vertical, -8).padding(.trailing, -32) + } + func newChatActionButton(_ icon: String, color: Color/* = .secondary*/, content: @escaping () -> Content) -> some View { ZStack(alignment: .leading) { Image(systemName: icon)