diff --git a/apps/ios/Shared/Views/Chat/Contacts/ContactListNavLink.swift b/apps/ios/Shared/Views/Chat/Contacts/ContactListNavLink.swift new file mode 100644 index 0000000000..6903aae1b9 --- /dev/null +++ b/apps/ios/Shared/Views/Chat/Contacts/ContactListNavLink.swift @@ -0,0 +1,35 @@ +// +// ContactListNavLink.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 06.05.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat + +struct ContactListNavLink: View { + var contact: Contact + + var body: some View { + HStack{ + ProfileImage(imageStr: contact.image, size: 30) + .padding(.trailing, 2) + Text(contact.chatViewName) + .lineLimit(1) + if contact.contactConnIncognito { + Spacer() + Image(systemName: "theatermasks") + .resizable() + .scaledToFit() + .frame(width: 22, height: 22) + .foregroundColor(.secondary) + } + } + } +} + +#Preview { + ContactListNavLink(contact: Contact.sampleData) +} diff --git a/apps/ios/Shared/Views/Chat/Contacts/ContactsView.swift b/apps/ios/Shared/Views/Chat/Contacts/ContactsView.swift index cb76407885..1a90e9ad17 100644 --- a/apps/ios/Shared/Views/Chat/Contacts/ContactsView.swift +++ b/apps/ios/Shared/Views/Chat/Contacts/ContactsView.swift @@ -30,60 +30,64 @@ struct ContactsView: View { VStack { contactList } + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) .listStyle(.plain) } @ViewBuilder private var contactList: some View { - let cs = filteredContacts() + let contacts = chatModel.chats.compactMap{ $0.chatInfo.contact } + let filteredContacts = oneHandUI ? filteredContacts(contacts).reversed() : filteredContacts(contacts) ZStack { VStack { List { - if !chatModel.chats.isEmpty { + if !contacts.isEmpty { ContactsSearchBar( searchMode: $searchMode, searchFocussed: $searchFocussed, searchText: $searchText ) + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) .listRowSeparator(.hidden) .frame(maxWidth: .infinity) } - ForEach(cs, id: \.viewId) { chat in - ChatListNavLink(chat: chat) + ForEach(filteredContacts, id: \.id) { contact in + ContactListNavLink(contact: contact) + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) .padding(.trailing, -16) - .disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id)) + .disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(contact.id)) } .offset(x: -8) } } - if cs.isEmpty && !chatModel.chats.isEmpty { + if filteredContacts.isEmpty && !contacts.isEmpty { Text("No filtered contacts") + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) + .foregroundColor(.secondary) + } else if contacts.isEmpty { + Text("No contacts") + .scaleEffect(x: 1, y: oneHandUI ? -1 : 1, anchor: .center) .foregroundColor(.secondary) } } } - private func filteredContacts() -> [Chat] { + private func filteredContacts(_ contacts: [Contact]) -> [Contact] { let s = searchString() - return chatModel.chats.filter { chat in - let cInfo = chat.chatInfo - switch cInfo { - case let .direct(contact): - return s == "" - ? true - : (viewNameContains(cInfo, s) || - contact.profile.displayName.localizedLowercase.contains(s) || - contact.fullName.localizedLowercase.contains(s)) - default: - return false - } + return contacts.filter { contact in + return s == "" + ? true + : (viewNameContains(contact, s) || + contact.profile.displayName.localizedLowercase.contains(s) || + contact.fullName.localizedLowercase.contains(s)) } + .sorted{ $0.displayName.lowercased() < $1.displayName.lowercased() } func searchString() -> String { searchText.trimmingCharacters(in: .whitespaces).localizedLowercase } - func viewNameContains(_ cInfo: ChatInfo, _ s: String) -> Bool { - cInfo.chatViewName.localizedLowercase.contains(s) + func viewNameContains(_ contact: Contact, _ s: String) -> Bool { + contact.chatViewName.localizedLowercase.contains(s) } } } diff --git a/apps/ios/Shared/Views/Home/HomeView.swift b/apps/ios/Shared/Views/Home/HomeView.swift index 5c5bff54bf..5159c80483 100644 --- a/apps/ios/Shared/Views/Home/HomeView.swift +++ b/apps/ios/Shared/Views/Home/HomeView.swift @@ -247,8 +247,9 @@ struct HomeView: View { } } - private func contactsView() -> some View { + @ViewBuilder private func contactsView() -> some View { ContactsView() + .padding(.top, 5) } @ViewBuilder private func chatsView() -> some View { diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index b482b97a43..e89cfc26d2 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -178,6 +178,7 @@ 648679AB2BC96A74006456E7 /* ChatItemForwardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648679AA2BC96A74006456E7 /* ChatItemForwardingView.swift */; }; 649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; }; 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; }; + 64A596452BE90DEC00B69266 /* ContactListNavLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A596442BE90DEC00B69266 /* ContactListNavLink.swift */; }; 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; }; 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; }; 64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */; }; @@ -477,6 +478,7 @@ 6493D667280ED77F007A76FB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeImageView.swift; sourceTree = ""; }; 649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = ""; }; + 64A596442BE90DEC00B69266 /* ContactListNavLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactListNavLink.swift; sourceTree = ""; }; 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = ""; }; 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = ""; }; 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemInfoView.swift; sourceTree = ""; }; @@ -934,6 +936,7 @@ isa = PBXGroup; children = ( 6485F7C52BE8DB6500FAE413 /* ContactsView.swift */, + 64A596442BE90DEC00B69266 /* ContactListNavLink.swift */, ); path = Contacts; sourceTree = ""; @@ -1173,6 +1176,7 @@ 5CB0BA9A2827FD8800B3292C /* HowItWorks.swift in Sources */, 5C13730B28156D2700F43030 /* ContactConnectionView.swift in Sources */, 644EFFE0292CFD7F00525D5B /* CIVoiceView.swift in Sources */, + 64A596452BE90DEC00B69266 /* ContactListNavLink.swift in Sources */, 6432857C2925443C00FBE5C8 /* GroupPreferencesView.swift in Sources */, 5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */, 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */,