diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index de8fe90a15..0430922807 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -344,16 +344,19 @@ private struct ActiveProfilePicker: View { @State private var switchingProfileByTimeout = false @State private var lastSwitchingProfileByTimeoutCall: Double? @State private var profiles: [User] = [] + @State private var searchTextOrPassword = "" @State var selectedProfile: User + var trimmedSearchTextOrPassword: String { searchTextOrPassword.trimmingCharacters(in: .whitespaces)} + var body: some View { viewBody() .navigationTitle("Select chat profile") + .searchable(text: $searchTextOrPassword, placement: .navigationBarDrawer(displayMode: .always)) .navigationBarTitleDisplayMode(.large) .onAppear { profiles = chatModel.users .map { $0.user } - .filter({ u in u.activeUser || !u.hidden }) .sorted { u, _ in u.activeUser } } .onChange(of: incognitoEnabled) { incognito in @@ -462,17 +465,28 @@ private struct ActiveProfilePicker: View { @ViewBuilder private func viewBody() -> some View { - NavigationView { - profilePicker() - .modifier(ThemedBackground(grouped: true)) - .overlay { - if switchingProfileByTimeout { - ProgressView() - .scaleEffect(2) - .frame(maxWidth: .infinity, maxHeight: .infinity) - } + profilePicker() + .allowsHitTesting(!switchingProfileByTimeout) + .modifier(ThemedBackground(grouped: true)) + .overlay { + if switchingProfileByTimeout { + ProgressView() + .scaleEffect(2) + .frame(maxWidth: .infinity, maxHeight: .infinity) } - }.allowsHitTesting(!switchingProfileByTimeout) + } + } + + private func filteredProfiles() -> [User] { + let s = trimmedSearchTextOrPassword + let lower = s.localizedLowercase + + return profiles.filter { u in + if (u.activeUser || !u.hidden) && (s == "" || u.chatViewName.localizedLowercase.contains(lower)) { + return true + } + return correctPassword(u, s) + } } @ViewBuilder private func profilePicker() -> some View { @@ -495,7 +509,8 @@ private struct ActiveProfilePicker: View { } } } - ForEach(profiles) { item in + let filteredProfiles = filteredProfiles() + ForEach(filteredProfiles) { item in Button { if selectedProfile != item || incognitoEnabled { switchingProfile = true diff --git a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift index 160130bccc..06342db529 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift @@ -406,6 +406,13 @@ public func chatPasswordHash(_ pwd: String, _ salt: String) -> String { return hash } +public func correctPassword(_ user: User, _ pwd: String) -> Bool { + if let ph = user.viewPwdHash { + return pwd != "" && chatPasswordHash(pwd, ph.salt) == ph.hash + } + return false +} + struct UserProfilesView_Previews: PreviewProvider { static var previews: some View { UserProfilesView(showSettings: Binding.constant(true))