diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 4866719469..ecc86de4dc 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -101,7 +101,7 @@ final class ChatModel: ObservableObject { } func updateContact(_ contact: Contact) { - updateChat(.direct(contact: contact), addMissing: !contact.isIndirectContact && !contact.viaGroupLink) + updateChat(.direct(contact: contact), addMissing: contact.directContact) } func updateGroup(_ groupInfo: GroupInfo) { diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index f5a62e7f0b..d889c0d150 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -917,7 +917,7 @@ func processReceivedMsg(_ res: ChatResponse) async { case let .contactConnectionDeleted(connection): m.removeChat(connection.id) case let .contactConnected(contact, _): - if !contact.viaGroupLink { + if contact.directContact { m.updateContact(contact) m.dismissConnReqView(contact.activeConn.id) m.removeChat(contact.activeConn.id) @@ -925,7 +925,7 @@ func processReceivedMsg(_ res: ChatResponse) async { NtfManager.shared.notifyContactConnected(contact) } case let .contactConnecting(contact): - if !contact.viaGroupLink { + if contact.directContact { m.updateContact(contact) m.dismissConnReqView(contact.activeConn.id) m.removeChat(contact.activeConn.id) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index 0095af6eba..ac28a5419c 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -42,9 +42,16 @@ struct GroupMemberInfoView: View { groupMemberInfoHeader(member) .listRowBackground(Color.clear) - if let contactId = member.memberContactId, groupInfo.fullGroupPreferences.directMessages.enable == .on { - Section { - openDirectChatButton(contactId) + if let contactId = member.memberContactId { + if let chat = chatModel.getContactChat(contactId), + chat.chatInfo.contact?.directContact ?? false { + Section { + knownDirectChatButton(chat) + } + } else if groupInfo.fullGroupPreferences.directMessages.on { + Section { + newDirectChatButton(contactId) + } } } @@ -112,26 +119,30 @@ struct GroupMemberInfoView: View { } } - func openDirectChatButton(_ contactId: Int64) -> some View { + func knownDirectChatButton(_ chat: Chat) -> some View { Button { - var chat = chatModel.getContactChat(contactId) - if chat == nil { - do { - chat = try apiGetChat(type: .direct, id: contactId) - if let chat = chat { - // TODO it's not correct to blindly set network status to connected - we should manage network status in model / backend - chat.serverInfo = Chat.ServerInfo(networkStatus: .connected) - chatModel.addChat(chat) - } - } catch let error { - logger.error("openDirectChatButton apiGetChat error: \(responseError(error))") - } + dismissAllSheets(animated: true) + DispatchQueue.main.async { + chatModel.chatId = chat.id } - if let chat = chat { + } label: { + Label("Send direct message", systemImage: "message") + } + } + + func newDirectChatButton(_ contactId: Int64) -> some View { + Button { + do { + let chat = try apiGetChat(type: .direct, id: contactId) + // TODO it's not correct to blindly set network status to connected - we should manage network status in model / backend + chat.serverInfo = Chat.ServerInfo(networkStatus: .connected) + chatModel.addChat(chat) dismissAllSheets(animated: true) DispatchQueue.main.async { chatModel.chatId = chat.id } + } catch let error { + logger.error("openDirectChatButton apiGetChat error: \(responseError(error))") } } label: { Label("Send direct message", systemImage: "message") diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index b606712e0f..1540ed6fa1 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -802,6 +802,7 @@ public struct Contact: Identifiable, Decodable, NamedChat { public var profile: LocalProfile public var activeConn: Connection public var viaGroup: Int64? + public var contactUsed: Bool public var chatSettings: ChatSettings public var userPreferences: Preferences public var mergedPreferences: ContactUserPreferences @@ -817,12 +818,8 @@ public struct Contact: Identifiable, Decodable, NamedChat { public var image: String? { get { profile.image } } public var localAlias: String { profile.localAlias } - public var isIndirectContact: Bool { - activeConn.connLevel > 0 || viaGroup != nil - } - - public var viaGroupLink: Bool { - activeConn.viaGroupLink + public var directContact: Bool { + (activeConn.connLevel == 0 && !activeConn.viaGroupLink) || contactUsed } public var contactConnIncognito: Bool { @@ -834,6 +831,7 @@ public struct Contact: Identifiable, Decodable, NamedChat { localDisplayName: "alice", profile: LocalProfile.sampleData, activeConn: Connection.sampleData, + contactUsed: true, chatSettings: ChatSettings.defaults, userPreferences: Preferences.sampleData, mergedPreferences: ContactUserPreferences.sampleData,