From 7ef7d08c00114e13995baa04c1bccf93fb25b9f9 Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Mon, 24 Oct 2022 16:22:00 +0400 Subject: [PATCH] mobile: use viaGroupLink to avoid adding missing chats on subscriptions (#1249) --- .../main/java/chat/simplex/app/model/ChatModel.kt | 9 ++++++--- .../main/java/chat/simplex/app/model/SimpleXAPI.kt | 12 ++++++------ apps/ios/Shared/Model/ChatModel.swift | 2 +- apps/ios/Shared/Model/SimpleXAPI.swift | 10 +++++----- apps/ios/SimpleX NSE/NotificationService.swift | 4 ++-- apps/ios/SimpleXChat/APITypes.swift | 12 ++++++------ apps/ios/SimpleXChat/ChatTypes.swift | 8 +++++++- 7 files changed, 33 insertions(+), 24 deletions(-) diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt index d80bea76da..3ece28cf82 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -90,7 +90,7 @@ class ChatModel(val controller: ChatController) { fun updateContactConnection(contactConnection: PendingContactConnection) = updateChat(ChatInfo.ContactConnection(contactConnection)) - fun updateContact(contact: Contact) = updateChat(ChatInfo.Direct(contact), addMissing = !contact.isIndirectContact) + fun updateContact(contact: Contact) = updateChat(ChatInfo.Direct(contact), addMissing = !contact.isIndirectContact && !contact.viaGroupLink) fun updateGroup(groupInfo: GroupInfo) = updateChat(ChatInfo.Group(groupInfo)) @@ -540,6 +540,9 @@ data class Contact( val isIndirectContact: Boolean get() = activeConn.connLevel > 0 || viaGroup != null + val viaGroupLink: Boolean get() = + activeConn.viaGroupLink + val contactConnIncognito = activeConn.customUserProfileId != null @@ -571,10 +574,10 @@ class ContactSubStatus( ) @Serializable -class Connection(val connId: Long, val connStatus: ConnStatus, val connLevel: Int, val customUserProfileId: Long? = null) { +class Connection(val connId: Long, val connStatus: ConnStatus, val connLevel: Int, val viaGroupLink: Boolean, val customUserProfileId: Long? = null) { val id: ChatId get() = ":$connId" companion object { - val sampleData = Connection(connId = 1, connStatus = ConnStatus.Ready, connLevel = 0, customUserProfileId = null) + val sampleData = Connection(connId = 1, connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, customUserProfileId = null) } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index c24b1dc320..8b3c138618 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -923,7 +923,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a chatModel.removeChat(r.connection.id) } is CR.ContactConnected -> { - if (!r.viaGroupLink) { + if (!r.contact.viaGroupLink) { chatModel.updateContact(r.contact) chatModel.dismissConnReqView(r.contact.activeConn.id) chatModel.removeChat(r.contact.activeConn.id) @@ -932,7 +932,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a } } is CR.ContactConnecting -> { - if (!r.viaGroupLink) { + if (!r.contact.viaGroupLink) { chatModel.updateContact(r.contact) chatModel.dismissConnReqView(r.contact.activeConn.id) chatModel.removeChat(r.contact.activeConn.id) @@ -1765,8 +1765,8 @@ sealed class CR { @Serializable @SerialName("userContactLinkUpdated") class UserContactLinkUpdated(val contactLink: UserContactLinkRec): CR() @Serializable @SerialName("userContactLinkCreated") class UserContactLinkCreated(val connReqContact: String): CR() @Serializable @SerialName("userContactLinkDeleted") class UserContactLinkDeleted: CR() - @Serializable @SerialName("contactConnected") class ContactConnected(val contact: Contact, val userCustomProfile: Profile?, val viaGroupLink: Boolean): CR() - @Serializable @SerialName("contactConnecting") class ContactConnecting(val contact: Contact, val viaGroupLink: Boolean): CR() + @Serializable @SerialName("contactConnected") class ContactConnected(val contact: Contact, val userCustomProfile: Profile?): CR() + @Serializable @SerialName("contactConnecting") class ContactConnecting(val contact: Contact): CR() @Serializable @SerialName("receivedContactRequest") class ReceivedContactRequest(val contactRequest: UserContactRequest): CR() @Serializable @SerialName("acceptingContactRequest") class AcceptingContactRequest(val contact: Contact): CR() @Serializable @SerialName("contactRequestRejected") class ContactRequestRejected: CR() @@ -1786,7 +1786,7 @@ sealed class CR { @Serializable @SerialName("contactsList") class ContactsList(val contacts: List): CR() // group events @Serializable @SerialName("groupCreated") class GroupCreated(val groupInfo: GroupInfo): CR() - @Serializable @SerialName("sentGroupInvitation") class SentGroupInvitation(val groupInfo: GroupInfo, val contact: Contact, val member: GroupMember, val viaGroupLink: Boolean): CR() + @Serializable @SerialName("sentGroupInvitation") class SentGroupInvitation(val groupInfo: GroupInfo, val contact: Contact, val member: GroupMember): CR() @Serializable @SerialName("userAcceptedGroupSent") class UserAcceptedGroupSent (val groupInfo: GroupInfo): CR() @Serializable @SerialName("userDeletedMember") class UserDeletedMember(val groupInfo: GroupInfo, val member: GroupMember): CR() @Serializable @SerialName("leftMemberUser") class LeftMemberUser(val groupInfo: GroupInfo): CR() @@ -1975,7 +1975,7 @@ sealed class CR { is ChatItemDeleted -> "deletedChatItem:\n${json.encodeToString(deletedChatItem)}\ntoChatItem:\n${json.encodeToString(toChatItem)}" is ContactsList -> json.encodeToString(contacts) is GroupCreated -> json.encodeToString(groupInfo) - is SentGroupInvitation -> "groupInfo: $groupInfo\ncontact: $contact\nmember: $member\nviaGroupLink: $viaGroupLink" + is SentGroupInvitation -> "groupInfo: $groupInfo\ncontact: $contact\nmember: $member" is UserAcceptedGroupSent -> json.encodeToString(groupInfo) is UserDeletedMember -> "groupInfo: $groupInfo\nmember: $member" is LeftMemberUser -> json.encodeToString(groupInfo) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index b9277284cd..f0ff0a765e 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -98,7 +98,7 @@ final class ChatModel: ObservableObject { } func updateContact(_ contact: Contact) { - updateChat(.direct(contact: contact), addMissing: !contact.isIndirectContact) + updateChat(.direct(contact: contact), addMissing: !contact.isIndirectContact && !contact.viaGroupLink) } func updateGroup(_ groupInfo: GroupInfo) { diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index d5b710ad39..78749e0eb3 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -694,7 +694,7 @@ func apiNewGroup(_ p: GroupProfile) throws -> GroupInfo { func apiAddMember(_ groupId: Int64, _ contactId: Int64, _ memberRole: GroupMemberRole) async throws -> GroupMember { let r = await chatSendCmd(.apiAddMember(groupId: groupId, contactId: contactId, memberRole: memberRole)) - if case let .sentGroupInvitation(_, _, member, _) = r { return member } + if case let .sentGroupInvitation(_, _, member) = r { return member } throw r } @@ -881,16 +881,16 @@ func processReceivedMsg(_ res: ChatResponse) async { m.updateContactConnection(connection) case let .contactConnectionDeleted(connection): m.removeChat(connection.id) - case let .contactConnected(contact, _, viaGroupLink): - if !viaGroupLink { + case let .contactConnected(contact, _): + if !contact.viaGroupLink { m.updateContact(contact) m.dismissConnReqView(contact.activeConn.id) m.removeChat(contact.activeConn.id) m.updateNetworkStatus(contact.id, .connected) NtfManager.shared.notifyContactConnected(contact) } - case let .contactConnecting(contact, viaGroupLink): - if !viaGroupLink { + case let .contactConnecting(contact): + if !contact.viaGroupLink { m.updateContact(contact) m.dismissConnReqView(contact.activeConn.id) m.removeChat(contact.activeConn.id) diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift index 4decfde072..0555244999 100644 --- a/apps/ios/SimpleX NSE/NotificationService.swift +++ b/apps/ios/SimpleX NSE/NotificationService.swift @@ -207,9 +207,9 @@ func chatRecvMsg() async -> ChatResponse? { func receivedMsgNtf(_ res: ChatResponse) async -> (String, UNMutableNotificationContent)? { logger.debug("NotificationService processReceivedMsg: \(res.responseType)") switch res { - case let .contactConnected(contact, _, _): + case let .contactConnected(contact, _): return (contact.id, createContactConnectedNtf(contact)) -// case let .contactConnecting(contact, _): +// case let .contactConnecting(contact): // TODO profile update case let .receivedContactRequest(contactRequest): return (UserContact(contactRequest: contactRequest).id, createContactRequestNtf(contactRequest)) diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index a5388f197d..c9a3f4e971 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -301,8 +301,8 @@ public enum ChatResponse: Decodable, Error { case userContactLinkUpdated(contactLink: UserContactLink) case userContactLinkCreated(connReqContact: String) case userContactLinkDeleted - case contactConnected(contact: Contact, userCustomProfile: Profile?, viaGroupLink: Bool) - case contactConnecting(contact: Contact, viaGroupLink: Bool) + case contactConnected(contact: Contact, userCustomProfile: Profile?) + case contactConnecting(contact: Contact) case receivedContactRequest(contactRequest: UserContactRequest) case acceptingContactRequest(contact: Contact) case contactRequestRejected @@ -322,7 +322,7 @@ public enum ChatResponse: Decodable, Error { case contactsList(contacts: [Contact]) // group events case groupCreated(groupInfo: GroupInfo) - case sentGroupInvitation(groupInfo: GroupInfo, contact: Contact, member: GroupMember, viaGroupLink: Bool) + case sentGroupInvitation(groupInfo: GroupInfo, contact: Contact, member: GroupMember) case userAcceptedGroupSent(groupInfo: GroupInfo) case userDeletedMember(groupInfo: GroupInfo, member: GroupMember) case leftMemberUser(groupInfo: GroupInfo) @@ -503,8 +503,8 @@ public enum ChatResponse: Decodable, Error { case let .userContactLinkUpdated(contactLink): return contactLink.responseDetails case let .userContactLinkCreated(connReq): return connReq case .userContactLinkDeleted: return noDetails - case let .contactConnected(contact, _, _): return String(describing: contact) - case let .contactConnecting(contact, _): return String(describing: contact) + case let .contactConnected(contact, _): return String(describing: contact) + case let .contactConnecting(contact): return String(describing: contact) case let .receivedContactRequest(contactRequest): return String(describing: contactRequest) case let .acceptingContactRequest(contact): return String(describing: contact) case .contactRequestRejected: return noDetails @@ -523,7 +523,7 @@ public enum ChatResponse: Decodable, Error { case let .chatItemDeleted(deletedChatItem, toChatItem): return "deletedChatItem:\n\(String(describing: deletedChatItem))\ntoChatItem:\n\(String(describing: toChatItem))" case let .contactsList(contacts): return String(describing: contacts) case let .groupCreated(groupInfo): return String(describing: groupInfo) - case let .sentGroupInvitation(groupInfo, contact, member, viaGroupLink): return "groupInfo: \(groupInfo)\ncontact: \(contact)\nmember: \(member)\nviaGroupLink: \(viaGroupLink)" + case let .sentGroupInvitation(groupInfo, contact, member): return "groupInfo: \(groupInfo)\ncontact: \(contact)\nmember: \(member)" case let .userAcceptedGroupSent(groupInfo): return String(describing: groupInfo) case let .userDeletedMember(groupInfo, member): return "groupInfo: \(groupInfo)\nmember: \(member)" case let .leftMemberUser(groupInfo): return String(describing: groupInfo) diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index f7b76b634f..15fc3a9f25 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -337,6 +337,10 @@ public struct Contact: Identifiable, Decodable, NamedChat { activeConn.connLevel > 0 || viaGroup != nil } + public var viaGroupLink: Bool { + activeConn.viaGroupLink + } + public var contactConnIncognito: Bool { activeConn.customUserProfileId != nil } @@ -368,6 +372,7 @@ public struct Connection: Decodable { var connId: Int64 var connStatus: ConnStatus public var connLevel: Int + public var viaGroupLink: Bool public var customUserProfileId: Int64? public var id: ChatId { get { ":\(connId)" } } @@ -375,7 +380,8 @@ public struct Connection: Decodable { static let sampleData = Connection( connId: 1, connStatus: .ready, - connLevel: 0 + connLevel: 0, + viaGroupLink: false ) }