add search
This commit is contained in:
parent
58750dee48
commit
36759022a1
@ -718,6 +718,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Ничего не найдено" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Новый пароль" : {
|
"Новый пароль" : {
|
||||||
"comment" : "Новый пароль",
|
"comment" : "Новый пароль",
|
||||||
@ -944,6 +947,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Поиск" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Пока что у вас нет чатов" : {
|
"Пока что у вас нет чатов" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@ -977,6 +983,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Попробуйте изменить запрос поиска." : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Приглашение достигло лимита использования." : {
|
"Приглашение достигло лимита использования." : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ struct ChatsTab: View {
|
|||||||
var currentUserId: String? = nil
|
var currentUserId: String? = nil
|
||||||
@StateObject private var viewModel = PrivateChatsViewModel()
|
@StateObject private var viewModel = PrivateChatsViewModel()
|
||||||
@State private var selectedChatId: String?
|
@State private var selectedChatId: String?
|
||||||
|
@State private var searchText: String = ""
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
content
|
content
|
||||||
@ -38,6 +39,14 @@ struct ChatsTab: View {
|
|||||||
|
|
||||||
private var chatList: some View {
|
private var chatList: some View {
|
||||||
List {
|
List {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
searchBar
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.top, 8)
|
||||||
|
.padding(.bottom, 8)
|
||||||
|
}
|
||||||
|
.background(Color(UIColor.systemBackground))
|
||||||
|
|
||||||
if let message = viewModel.errorMessage {
|
if let message = viewModel.errorMessage {
|
||||||
Section {
|
Section {
|
||||||
HStack(alignment: .top, spacing: 8) {
|
HStack(alignment: .top, spacing: 8) {
|
||||||
@ -57,47 +66,126 @@ struct ChatsTab: View {
|
|||||||
.listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
|
.listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
ForEach(viewModel.chats) { chat in
|
if filteredChats.isEmpty && isSearching {
|
||||||
Button {
|
Section {
|
||||||
selectedChatId = chat.chatId
|
emptySearchResultView
|
||||||
} label: {
|
|
||||||
ChatRowView(chat: chat, currentUserId: currentUserId)
|
|
||||||
.contentShape(Rectangle())
|
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.listRowInsets(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16))
|
||||||
.contextMenu {
|
.listRowSeparator(.hidden)
|
||||||
Button(action: {}) {
|
} else {
|
||||||
Label(NSLocalizedString("Закрепить (скоро)", comment: ""), systemImage: "pin")
|
ForEach(filteredChats) { chat in
|
||||||
|
Button {
|
||||||
|
selectedChatId = chat.chatId
|
||||||
|
} label: {
|
||||||
|
ChatRowView(chat: chat, currentUserId: currentUserId)
|
||||||
|
.contentShape(Rectangle())
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.contextMenu {
|
||||||
|
Button(action: {}) {
|
||||||
|
Label(NSLocalizedString("Закрепить (скоро)", comment: ""), systemImage: "pin")
|
||||||
|
}
|
||||||
|
|
||||||
Button(action: {}) {
|
Button(action: {}) {
|
||||||
Label(NSLocalizedString("Без звука (скоро)", comment: ""), systemImage: "speaker.slash")
|
Label(NSLocalizedString("Без звука (скоро)", comment: ""), systemImage: "speaker.slash")
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(role: .destructive, action: {}) {
|
Button(role: .destructive, action: {}) {
|
||||||
Label(NSLocalizedString("Удалить чат (скоро)", comment: ""), systemImage: "trash")
|
Label(NSLocalizedString("Удалить чат (скоро)", comment: ""), systemImage: "trash")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.background(
|
||||||
.background(
|
NavigationLink(
|
||||||
NavigationLink(
|
destination: ChatPlaceholderView(chat: chat),
|
||||||
destination: ChatPlaceholderView(chat: chat),
|
tag: chat.chatId,
|
||||||
tag: chat.chatId,
|
selection: $selectedChatId
|
||||||
selection: $selectedChatId
|
) {
|
||||||
) {
|
EmptyView()
|
||||||
EmptyView()
|
}
|
||||||
|
.hidden()
|
||||||
|
)
|
||||||
|
.onAppear {
|
||||||
|
guard !isSearching else { return }
|
||||||
|
viewModel.loadMoreIfNeeded(currentItem: chat)
|
||||||
}
|
}
|
||||||
.hidden()
|
|
||||||
)
|
|
||||||
.onAppear {
|
|
||||||
viewModel.loadMoreIfNeeded(currentItem: chat)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.isLoadingMore {
|
if viewModel.isLoadingMore && !isSearching {
|
||||||
loadingMoreRow
|
loadingMoreRow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listStyle(.plain)
|
.listStyle(.plain)
|
||||||
|
// .safeAreaInset(edge: .top) {
|
||||||
|
// VStack(spacing: 0) {
|
||||||
|
// searchBar
|
||||||
|
// .padding(.horizontal, 16)
|
||||||
|
// .padding(.top, 8)
|
||||||
|
// .padding(.bottom, 8)
|
||||||
|
// Divider()
|
||||||
|
// }
|
||||||
|
// .background(Color(UIColor.systemBackground))
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private var searchBar: some View {
|
||||||
|
HStack(spacing: 8) {
|
||||||
|
Image(systemName: "magnifyingglass")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
TextField(NSLocalizedString("Поиск", comment: ""), text: $searchText)
|
||||||
|
.textFieldStyle(.plain)
|
||||||
|
.textInputAutocapitalization(.never)
|
||||||
|
.autocorrectionDisabled()
|
||||||
|
if !searchText.isEmpty {
|
||||||
|
Button(action: { searchText = "" }) {
|
||||||
|
Image(systemName: "xmark.circle.fill")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 12)
|
||||||
|
.padding(.vertical, 10)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
||||||
|
.fill(Color(UIColor.secondarySystemBackground))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isSearching: Bool {
|
||||||
|
!searchText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
private var filteredChats: [PrivateChatListItem] {
|
||||||
|
let trimmedQuery = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmedQuery.isEmpty else { return viewModel.chats }
|
||||||
|
let lowercasedQuery = trimmedQuery.lowercased()
|
||||||
|
return viewModel.chats.filter { chat in
|
||||||
|
let searchableValues = [
|
||||||
|
chat.chatData?.customName,
|
||||||
|
chat.chatData?.fullName,
|
||||||
|
chat.chatData?.login,
|
||||||
|
chat.lastMessage?.content
|
||||||
|
]
|
||||||
|
return searchableValues
|
||||||
|
.compactMap { $0?.lowercased() }
|
||||||
|
.contains(where: { $0.contains(lowercasedQuery) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var emptySearchResultView: some View {
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
Image(systemName: "text.magnifyingglass")
|
||||||
|
.font(.system(size: 40))
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
Text(NSLocalizedString("Ничего не найдено", comment: ""))
|
||||||
|
.font(.headline)
|
||||||
|
Text(NSLocalizedString("Попробуйте изменить запрос поиска.", comment: ""))
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var loadingState: some View {
|
private var loadingState: some View {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user