From 8ed075f6db088befff3e8dcbaba4effbdac933f4 Mon Sep 17 00:00:00 2001 From: Diogo Cunha Date: Thu, 13 Jun 2024 22:32:07 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20implemented=20dissapeari?= =?UTF-8?q?ng=20toolbar=20on=20chat=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit toolbar dissapears when scrolling down and shows when scrolling back up in normal UI. Also implemented for one hand ui --- .../Shared/Views/ChatList/ChatListView.swift | 61 ++++++++++++++++--- apps/ios/Shared/Views/Home/HomeView.swift | 53 +++++++++++++--- 2 files changed, 94 insertions(+), 20 deletions(-) diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index da8d1723f6..aa5ea356f9 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -17,7 +17,7 @@ struct ChatListView: View { @State private var searchText = "" @State private var searchShowingSimplexLink = false @State private var searchChatFilteredBySimplexLink: String? = nil - + @State var topVisibleRowIndex: Int? = nil; @AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false @AppStorage(DEFAULT_ONE_HAND_UI) private var oneHandUI = false @@ -57,8 +57,8 @@ struct ChatListView: View { let cs = filteredChats() ZStack { VStack { - List { - if !chatModel.chats.isEmpty { + ScrollViewReader { scrollViewProxy in + if !chatModel.chats.isEmpty && oneHandUI{ ChatListSearchBar( searchMode: $searchMode, searchFocussed: $searchFocussed, @@ -66,17 +66,41 @@ struct ChatListView: View { searchShowingSimplexLink: $searchShowingSimplexLink, searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink ) - .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) + .scaleEffect(x: 1, y: -1, anchor: .center) .listRowSeparator(.hidden) .frame(maxWidth: .infinity) + .padding(10) } - ForEach(cs, id: \.viewId) { chat in - ChatListNavLink(chat: chat) - .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) - .padding(.trailing, -16) - .disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id)) + List { + if !chatModel.chats.isEmpty && !oneHandUI{ + ChatListSearchBar( + searchMode: $searchMode, + searchFocussed: $searchFocussed, + searchText: $searchText, + searchShowingSimplexLink: $searchShowingSimplexLink, + searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink + ) + .listRowSeparator(.hidden) + .frame(maxWidth: .infinity) + } + ForEach(cs.indices, id: \.self) { index in + ChatListNavLink(chat: cs[index]) + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) + .padding(.trailing, -16) + .disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(cs[index].chatInfo.id)) + .background(GeometryReader { proxy in + Color.clear + .onAppear { + updateTopVisibleRowIndex(proxy: proxy, index: index) + } + .onChange(of: proxy.frame(in: .named("SCROLL")).minY) { _ in + updateTopVisibleRowIndex(proxy: proxy, index: index) + } + }) + } + .offset(x: -8) } - .offset(x: -8) + .coordinateSpace(name: "SCROLL") } } .onChange(of: chatModel.chatId) { _ in @@ -92,6 +116,23 @@ struct ChatListView: View { } } } + + private func updateTopVisibleRowIndex(proxy: GeometryProxy, index: Int) { + let frame = proxy.frame(in: .named("SCROLL")) + + if frame.minY >= 0 && frame.minY < frame.height / 2 { + if topVisibleRowIndex != index { + let shouldShowToolbar: Bool + if let topVisibleRowIndex = topVisibleRowIndex { + shouldShowToolbar = topVisibleRowIndex > index + } else { + shouldShowToolbar = true + } + topVisibleRowIndex = index + NotificationCenter.default.post(name: .toolbarVisibilityChanged, object: shouldShowToolbar) + } + } + } private func unreadBadge(_ text: Text? = Text(" "), size: CGFloat = 18) -> some View { Circle() diff --git a/apps/ios/Shared/Views/Home/HomeView.swift b/apps/ios/Shared/Views/Home/HomeView.swift index 90f9974ef2..ecd1101583 100644 --- a/apps/ios/Shared/Views/Home/HomeView.swift +++ b/apps/ios/Shared/Views/Home/HomeView.swift @@ -61,16 +61,15 @@ struct HomeView: View { case .chats: withToolbar("Chats", chatListView) } } - .toolbar { - ToolbarItemGroup(placement: .bottomBar) { - settingsButton() - Spacer() - contactsButton() - Spacer() - chatsButton() - Spacer() - newChatButton() - } + + ToolbarView { + settingsButton() + Spacer() + contactsButton() + Spacer() + chatsButton() + Spacer() + newChatButton() } if #unavailable(iOS 16) { @@ -224,6 +223,40 @@ struct HomeView: View { } } +extension Notification.Name { + static let toolbarVisibilityChanged = Notification.Name("toolbarVisibilityChanged") +} + +struct ToolbarView: View { + @State var isVisible: Bool = true; + let content: Content + + init(@ViewBuilder content: () -> Content) { + self.content = content() + } + + var body: some View { + VStack { + Spacer() + if isVisible { + VStack {} + .toolbar { + ToolbarItemGroup(placement: .bottomBar) { + content + } + } + } + } + .onReceive(NotificationCenter.default.publisher(for: .toolbarVisibilityChanged)) { notification in + if let visibility = notification.object as? Bool { + if isVisible != visibility { + isVisible.toggle() + } + } + } + } +} + #Preview { HomeView(showSettings: Binding.constant(false)) }