add search
This commit is contained in:
		
							parent
							
								
									58750dee48
								
							
						
					
					
						commit
						36759022a1
					
				@ -718,6 +718,9 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Ничего не найдено" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Новый пароль" : {
 | 
			
		||||
      "comment" : "Новый пароль",
 | 
			
		||||
@ -944,6 +947,9 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Поиск" : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Пока что у вас нет чатов" : {
 | 
			
		||||
      "localizations" : {
 | 
			
		||||
@ -977,6 +983,9 @@
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Попробуйте изменить запрос поиска." : {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    "Приглашение достигло лимита использования." : {
 | 
			
		||||
      "localizations" : {
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ struct ChatsTab: View {
 | 
			
		||||
    var currentUserId: String? = nil
 | 
			
		||||
    @StateObject private var viewModel = PrivateChatsViewModel()
 | 
			
		||||
    @State private var selectedChatId: String?
 | 
			
		||||
    @State private var searchText: String = ""
 | 
			
		||||
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        content
 | 
			
		||||
@ -38,6 +39,14 @@ struct ChatsTab: View {
 | 
			
		||||
 | 
			
		||||
    private var chatList: some View {
 | 
			
		||||
        List {
 | 
			
		||||
            VStack(spacing: 0) {
 | 
			
		||||
                searchBar
 | 
			
		||||
                    .padding(.horizontal, 16)
 | 
			
		||||
                    .padding(.top, 8)
 | 
			
		||||
                    .padding(.bottom, 8)
 | 
			
		||||
            }
 | 
			
		||||
            .background(Color(UIColor.systemBackground))
 | 
			
		||||
 | 
			
		||||
            if let message = viewModel.errorMessage {
 | 
			
		||||
                Section {
 | 
			
		||||
                    HStack(alignment: .top, spacing: 8) {
 | 
			
		||||
@ -57,47 +66,126 @@ struct ChatsTab: View {
 | 
			
		||||
                .listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ForEach(viewModel.chats) { chat in
 | 
			
		||||
                Button {
 | 
			
		||||
                    selectedChatId = chat.chatId
 | 
			
		||||
                } label: {
 | 
			
		||||
                    ChatRowView(chat: chat, currentUserId: currentUserId)
 | 
			
		||||
                        .contentShape(Rectangle())
 | 
			
		||||
            if filteredChats.isEmpty && isSearching {
 | 
			
		||||
                Section {
 | 
			
		||||
                    emptySearchResultView
 | 
			
		||||
                }
 | 
			
		||||
                .buttonStyle(.plain)
 | 
			
		||||
                .contextMenu {
 | 
			
		||||
                    Button(action: {}) {
 | 
			
		||||
                        Label(NSLocalizedString("Закрепить (скоро)", comment: ""), systemImage: "pin")
 | 
			
		||||
                .listRowInsets(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16))
 | 
			
		||||
                .listRowSeparator(.hidden)
 | 
			
		||||
            } else {
 | 
			
		||||
                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: {}) {
 | 
			
		||||
                        Label(NSLocalizedString("Без звука (скоро)", comment: ""), systemImage: "speaker.slash")
 | 
			
		||||
                    }
 | 
			
		||||
                        Button(action: {}) {
 | 
			
		||||
                            Label(NSLocalizedString("Без звука (скоро)", comment: ""), systemImage: "speaker.slash")
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    Button(role: .destructive, action: {}) {
 | 
			
		||||
                        Label(NSLocalizedString("Удалить чат (скоро)", comment: ""), systemImage: "trash")
 | 
			
		||||
                        Button(role: .destructive, action: {}) {
 | 
			
		||||
                            Label(NSLocalizedString("Удалить чат (скоро)", comment: ""), systemImage: "trash")
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                .background(
 | 
			
		||||
                    NavigationLink(
 | 
			
		||||
                        destination: ChatPlaceholderView(chat: chat),
 | 
			
		||||
                        tag: chat.chatId,
 | 
			
		||||
                        selection: $selectedChatId
 | 
			
		||||
                    ) {
 | 
			
		||||
                        EmptyView()
 | 
			
		||||
                    .background(
 | 
			
		||||
                        NavigationLink(
 | 
			
		||||
                            destination: ChatPlaceholderView(chat: chat),
 | 
			
		||||
                            tag: chat.chatId,
 | 
			
		||||
                            selection: $selectedChatId
 | 
			
		||||
                        ) {
 | 
			
		||||
                            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
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .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 {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user