mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-31 13:15:42 +00:00
Merge branch 'contacts-ui-feature-branch' of github.com:diogofcunha/simplex-chat into dc/contacts-search
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
import SwiftUI
|
||||
import SimpleXChat
|
||||
|
||||
struct ChatListView: View {
|
||||
struct ChatListView<ToolbarContent: View>: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
|
||||
@State private var searchMode = false
|
||||
@@ -17,9 +17,11 @@ struct ChatListView: View {
|
||||
@State private var searchText = ""
|
||||
@State private var searchShowingSimplexLink = false
|
||||
@State private var searchChatFilteredBySimplexLink: String? = nil
|
||||
|
||||
@State var topVisibleRowIndex: Int? = nil;
|
||||
@State private var searchVisible: Bool = true;
|
||||
@AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false
|
||||
@AppStorage(DEFAULT_ONE_HAND_UI) private var oneHandUI = false
|
||||
let toolbarContent: ToolbarContent?
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16.0, *) {
|
||||
@@ -28,6 +30,10 @@ struct ChatListView: View {
|
||||
viewBody
|
||||
}
|
||||
}
|
||||
|
||||
init(@ViewBuilder toolbarContent: () -> ToolbarContent?) {
|
||||
self.toolbarContent = toolbarContent()
|
||||
}
|
||||
|
||||
private var viewBody: some View {
|
||||
VStack {
|
||||
@@ -55,28 +61,30 @@ struct ChatListView: View {
|
||||
|
||||
@ViewBuilder private var chatList: some View {
|
||||
let cs = filteredChats()
|
||||
ZStack {
|
||||
ZStack(alignment: .top) {
|
||||
VStack {
|
||||
List {
|
||||
if !chatModel.chats.isEmpty {
|
||||
ChatListSearchBar(
|
||||
searchMode: $searchMode,
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.frame(maxWidth: .infinity)
|
||||
ScrollViewReader { scrollViewProxy in
|
||||
List {
|
||||
Color.clear
|
||||
.frame(height: oneHandUI ? 80 : 30)
|
||||
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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
.offset(x: -8)
|
||||
.coordinateSpace(name: "SCROLL")
|
||||
}
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { _ in
|
||||
@@ -90,6 +98,68 @@ struct ChatListView: View {
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
VStack {
|
||||
if let tbcontent = toolbarContent, oneHandUI, #available(iOS 16.0, *), !searchFocussed {
|
||||
tbcontent
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.horizontal, 25)
|
||||
.padding(.bottom, 5)
|
||||
.toolbar(.hidden, for: .bottomBar)
|
||||
}
|
||||
|
||||
if !chatModel.chats.isEmpty && searchVisible {
|
||||
VStack {
|
||||
ChatListSearchBar(
|
||||
searchMode: $searchMode,
|
||||
searchFocussed: $searchFocussed,
|
||||
searchText: $searchText,
|
||||
searchShowingSimplexLink: $searchShowingSimplexLink,
|
||||
searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink
|
||||
)
|
||||
.scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center)
|
||||
.listRowSeparator(.hidden)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(.bar)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private func updateTopVisibleRowIndex(proxy: GeometryProxy, index: Int) {
|
||||
let frame = proxy.frame(in: .named("SCROLL"))
|
||||
|
||||
if (oneHandUI) {
|
||||
let screenHeight = UIScreen.main.bounds.height
|
||||
|
||||
if frame.maxY <= screenHeight && frame.maxY > screenHeight - frame.height / 2 {
|
||||
if topVisibleRowIndex != index {
|
||||
if let topVisibleRowIndex = topVisibleRowIndex {
|
||||
searchVisible = topVisibleRowIndex > index || index == 0
|
||||
} else {
|
||||
searchVisible = true
|
||||
}
|
||||
|
||||
topVisibleRowIndex = index
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if frame.minY >= 0 && frame.minY < frame.height / 2 {
|
||||
if topVisibleRowIndex != index {
|
||||
if let topVisibleRowIndex = topVisibleRowIndex {
|
||||
searchVisible = topVisibleRowIndex > index
|
||||
} else {
|
||||
searchVisible = true
|
||||
}
|
||||
|
||||
topVisibleRowIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,10 +345,12 @@ struct ChatListView_Previews: PreviewProvider {
|
||||
|
||||
]
|
||||
return Group {
|
||||
ChatListView()
|
||||
.environmentObject(chatModel)
|
||||
ChatListView()
|
||||
.environmentObject(ChatModel())
|
||||
ChatListView {
|
||||
EmptyView()
|
||||
}.environmentObject(chatModel)
|
||||
ChatListView {
|
||||
EmptyView()
|
||||
}.environmentObject(ChatModel())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,16 @@ struct HomeView: View {
|
||||
ConnectDesktopView()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func toolbar() -> some View {
|
||||
settingsButton()
|
||||
Spacer()
|
||||
contactsButton()
|
||||
Spacer()
|
||||
chatsButton()
|
||||
Spacer()
|
||||
newChatButton()
|
||||
}
|
||||
|
||||
@ViewBuilder private func homeView() -> some View {
|
||||
let v = VStack {
|
||||
@@ -61,15 +71,10 @@ struct HomeView: View {
|
||||
case .chats: withToolbar("Chats", chatListView)
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
ToolbarItemGroup(placement: .bottomBar) {
|
||||
settingsButton()
|
||||
Spacer()
|
||||
contactsButton()
|
||||
Spacer()
|
||||
chatsButton()
|
||||
Spacer()
|
||||
newChatButton()
|
||||
toolbar()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +217,11 @@ struct HomeView: View {
|
||||
|
||||
@ViewBuilder private func chatListView() -> some View {
|
||||
// TODO reverse scale effect for swipe actions
|
||||
ChatListView()
|
||||
ChatListView {
|
||||
HStack {
|
||||
toolbar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private func chatView() -> some View {
|
||||
|
||||
Reference in New Issue
Block a user