feat: 🎸 implemented dissapearing toolbar on chat list

toolbar dissapears when scrolling down and shows when scrolling back up
in normal UI. Also implemented for one hand ui
This commit is contained in:
Diogo Cunha
2024-06-13 22:32:07 +01:00
parent dfdb3ca4a2
commit 8ed075f6db
2 changed files with 94 additions and 20 deletions

View File

@@ -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()

View File

@@ -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<Content: View>: 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))
}