From 57ed903a4845a1963bc606636592e1f81d5735cb Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Fri, 26 May 2023 13:52:06 +0400 Subject: [PATCH] Revert "core: don't keep connection of the merged contact (#2507)" (for cross-version compatibility) This reverts commit 6093219ce97093fd13f8a40622dcf75fc1484433. --- .../simplex/app/views/chat/ChatInfoView.kt | 13 +------ .../app/src/main/res/values/strings.xml | 1 - apps/ios/Shared/Views/Chat/ChatInfoView.swift | 8 ----- src/Simplex/Chat.hs | 35 +++++-------------- src/Simplex/Chat/Store.hs | 25 +++++++++---- src/Simplex/Chat/View.hs | 6 +++- tests/ChatTests/Groups.hs | 31 ++++++++-------- tests/ChatTests/Utils.hs | 7 +--- 8 files changed, 49 insertions(+), 77 deletions(-) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index c3c35aa7a..a97d59138 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -196,8 +196,8 @@ fun ChatInfoLayout( } ContactPreferencesButton(openPreferences) } - SectionDividerSpaced() + SectionDividerSpaced() if (contact.contactLink != null) { val context = LocalContext.current SectionView(stringResource(R.string.address_section_title).uppercase()) { @@ -208,17 +208,6 @@ fun ChatInfoLayout( SectionDividerSpaced() } - if (developerTools) { - SectionView(title = stringResource(R.string.contact_info_section_title_contact)) { - val connLevel = contact.activeConn.connLevel - val connLevelDesc = - if (connLevel == 0) stringResource(R.string.conn_level_desc_direct) - else String.format(generalGetString(R.string.conn_level_desc_indirect), connLevel) - InfoRow(stringResource(R.string.info_row_connection), connLevelDesc) - } - SectionDividerSpaced() - } - SectionView(title = stringResource(R.string.conn_stats_section_title_servers)) { SwitchAddressButton(switchContactAddress) if (connStats != null) { diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index 5f6094f3a..2017bae84 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -1140,7 +1140,6 @@ Member will be removed from group - this cannot be undone! Remove MEMBER - CONTACT Role Change role Change diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index 2e083d86e..b72006b3f 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -131,14 +131,6 @@ struct ChatInfoView: View { } } - if developerTools { - Section("Contact") { - let connLevel = contact.activeConn.connLevel - let connLevelDesc = connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), connLevel) - infoRow("Connection", connLevelDesc) - } - } - Section("Servers") { networkStatusRow() .onTapGesture { diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index f344d24cb..4b6b5d259 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -2656,7 +2656,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do _ -> Nothing processDirectMessage :: ACommand 'Agent e -> ConnectionEntity -> Connection -> Maybe Contact -> m () - processDirectMessage agentMsg connEntity conn@Connection {connId, viaUserContactLink, customUserProfileId} = \case + processDirectMessage agentMsg connEntity conn@Connection {connId, viaUserContactLink, groupLinkId, customUserProfileId} = \case Nothing -> case agentMsg of CONF confId _ connInfo -> do -- [incognito] send saved profile @@ -2758,6 +2758,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do whenUserNtfs user $ do setActive $ ActiveC c showToast (c <> "> ") "connected" + forM_ groupLinkId $ \_ -> probeMatchingContacts ct $ contactConnIncognito ct forM_ viaUserContactLink $ \userContactLinkId -> withStore' (\db -> getUserContactLinkById db userId userContactLinkId) >>= \case Just (UserContactLink {autoAccept = Just AutoAccept {autoReply = mc_}}, groupId_, gLinkMemRole) -> do @@ -2902,11 +2903,6 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do whenUserNtfs user $ do setActive $ ActiveG gName showToast ("#" <> gName) "you are connected to group" - withStore' (\db -> getContactViaMember db user m) >>= \case - Nothing -> messageWarning "connected host does not have contact" - Just ct@Contact {activeConn = Connection {groupLinkId}} -> do - let connectedIncognito = contactConnIncognito ct || memberIncognito membership - forM_ groupLinkId $ \_ -> probeMatchingContacts ct connectedIncognito GCInviteeMember -> do memberConnectedChatItem gInfo m toView $ CRJoinedGroupMember user gInfo m {memberStatus = GSMemConnected} @@ -3829,9 +3825,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do probeMatch c1@Contact {contactId = cId1, profile = p1} c2@Contact {contactId = cId2, profile = p2} probe = if profilesMatch (fromLocalProfile p1) (fromLocalProfile p2) && cId1 /= cId2 then do - let (toCt, fromCt) = mergeToFromContacts c1 c2 - void . sendDirectContactMessage toCt $ XInfoProbeOk probe - mergeContacts toCt fromCt + void . sendDirectContactMessage c1 $ XInfoProbeOk probe + mergeContacts c1 c2 else messageWarning "probeMatch ignored: profiles don't match or same contact id" xInfoProbeOk :: Contact -> Probe -> m () @@ -3839,22 +3834,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do r <- withStore' $ \db -> matchSentProbe db user c1 probe forM_ r $ \c2@Contact {contactId = cId2} -> if cId1 /= cId2 - then do - let (toCt, fromCt) = mergeToFromContacts c1 c2 - mergeContacts toCt fromCt + then mergeContacts c1 c2 else messageWarning "xInfoProbeOk ignored: same contact id" - mergeToFromContacts :: Contact -> Contact -> (Contact, Contact) - mergeToFromContacts c1 c2 - | d1 && not d2 = (c1, c2) - | d2 && not d1 = (c2, c1) - | ctCreatedAt c1 <= ctCreatedAt c2 = (c1, c2) - | otherwise = (c2, c1) - where - d1 = directOrUsed c1 - d2 = directOrUsed c2 - ctCreatedAt Contact {createdAt} = createdAt - -- to party accepting call xCallInv :: Contact -> CallId -> CallInvitation -> RcvMessage -> MsgMeta -> m () xCallInv ct@Contact {contactId} callId CallInvitation {callType, callDhPubKey} msg@RcvMessage {sharedMsgId_} msgMeta = do @@ -3961,10 +3943,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do messageError $ eventName <> ": wrong call state " <> T.pack (show $ callStateTag callState) mergeContacts :: Contact -> Contact -> m () - mergeContacts toCt fromCt = do - deleteAgentConnectionAsync user $ aConnId $ contactConn fromCt - withStore' $ \db -> mergeContactRecords db userId toCt fromCt - toView $ CRContactsMerged user toCt fromCt + mergeContacts c1 c2 = do + withStore' $ \db -> mergeContactRecords db userId c1 c2 + toView $ CRContactsMerged user c1 c2 saveConnInfo :: Connection -> ConnInfo -> m () saveConnInfo activeConn connInfo = do diff --git a/src/Simplex/Chat/Store.hs b/src/Simplex/Chat/Store.hs index e6b7a3805..12ac37032 100644 --- a/src/Simplex/Chat/Store.hs +++ b/src/Simplex/Chat/Store.hs @@ -1708,8 +1708,9 @@ matchSentProbe db user@User {userId} _from@Contact {contactId} (Probe probe) = d cId : _ -> eitherToMaybe <$> runExceptT (getContact db user cId) mergeContactRecords :: DB.Connection -> UserId -> Contact -> Contact -> IO () -mergeContactRecords db userId toCt fromCt = do - let Contact {contactId = toContactId} = toCt +mergeContactRecords db userId ct1 ct2 = do + let (toCt, fromCt) = toFromContacts ct1 ct2 + Contact {contactId = toContactId} = toCt Contact {contactId = fromContactId, localDisplayName} = fromCt currentTs <- getCurrentTime -- TODO next query fixes incorrect unused contacts deletion; consider more thorough fix @@ -1718,6 +1719,10 @@ mergeContactRecords db userId toCt fromCt = do db "UPDATE contacts SET contact_used = 1, updated_at = ? WHERE user_id = ? AND contact_id = ?" (currentTs, userId, toContactId) + DB.execute + db + "UPDATE connections SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?" + (toContactId, currentTs, fromContactId, userId) DB.execute db "UPDATE connections SET via_contact = ?, updated_at = ? WHERE via_contact = ? AND user_id = ?" @@ -1730,10 +1735,6 @@ mergeContactRecords db userId toCt fromCt = do db "UPDATE chat_items SET contact_id = ?, updated_at = ? WHERE contact_id = ? AND user_id = ?" (toContactId, currentTs, fromContactId, userId) - DB.execute - db - "UPDATE chat_item_reactions SET contact_id = ?, updated_at = ? WHERE contact_id = ?" - (toContactId, currentTs, fromContactId) DB.executeNamed db [sql| @@ -1753,6 +1754,17 @@ mergeContactRecords db userId toCt fromCt = do deleteContactProfile_ db userId fromContactId DB.execute db "DELETE FROM contacts WHERE contact_id = ? AND user_id = ?" (fromContactId, userId) DB.execute db "DELETE FROM display_names WHERE local_display_name = ? AND user_id = ?" (localDisplayName, userId) + where + toFromContacts :: Contact -> Contact -> (Contact, Contact) + toFromContacts c1 c2 + | d1 && not d2 = (c1, c2) + | d2 && not d1 = (c2, c1) + | ctCreatedAt c1 <= ctCreatedAt c2 = (c1, c2) + | otherwise = (c2, c1) + where + d1 = directOrUsed c1 + d2 = directOrUsed c2 + ctCreatedAt Contact {createdAt} = createdAt getConnectionEntity :: DB.Connection -> User -> AgentConnId -> ExceptT StoreError IO ConnectionEntity getConnectionEntity db user@User {userId, userContactId} agentConnId = do @@ -2352,7 +2364,6 @@ createNewContactMemberAsync db gVar user@User {userId, userContactId} groupId Co :. (userId, localDisplayName, contactId, localProfileId profile, createdAt, createdAt) ) --- this method differs from getViaGroupContact in that it does not join with groups on contacts.via_group getContactViaMember :: DB.Connection -> User -> GroupMember -> IO (Maybe Contact) getContactViaMember db user@User {userId} GroupMember {groupMemberId} = maybeFirstRow (toContact user) $ diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 70fb01a13..c13318250 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -116,7 +116,11 @@ responseToView user_ ChatConfig {logLevel, showReactions, testView} liveItems ts CRGroupCreated u g -> ttyUser u $ viewGroupCreated g CRGroupMembers u g -> ttyUser u $ viewGroupMembers g CRGroupsList u gs -> ttyUser u $ viewGroupsList gs - CRSentGroupInvitation u g c _ -> ttyUser u ["invitation to join the group " <> ttyGroup' g <> " sent to " <> ttyContact' c] + CRSentGroupInvitation u g c _ -> + ttyUser u $ + if viaGroupLink . contactConn $ c + then [ttyContact' c <> " invited to group " <> ttyGroup' g <> " via your group link"] + else ["invitation to join the group " <> ttyGroup' g <> " sent to " <> ttyContact' c] CRFileTransferStatus u ftStatus -> ttyUser u $ viewFileTransferStatus ftStatus CRFileTransferStatusXFTP u ci -> ttyUser u $ viewFileTransferStatusXFTP ci CRUserProfile u p -> ttyUser u $ viewUserProfile p diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 860826e8c..305f1620c 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -1544,7 +1544,7 @@ testGroupLink = concurrentlyN_ [ do alice <## "bob (Bob): contact is connected" - alice <## "invitation to join the group #team sent to bob" + alice <## "bob invited to group #team via your group link" alice <## "#team: bob joined the group", do bob <## "alice (Alice): contact is connected" @@ -1580,7 +1580,7 @@ testGroupLink = <### [ "cath_1 (Catherine): contact is connected", "contact cath_1 is merged into cath", "use @cath to send messages", - StartsWith "invitation to join the group #team sent to cath", + EndsWith "invited to group #team via your group link", EndsWith "joined the group" ], cath @@ -1634,7 +1634,7 @@ testGroupLinkDeleteGroupRejoin = concurrentlyN_ [ do alice <## "bob (Bob): contact is connected" - alice <## "invitation to join the group #team sent to bob" + alice <## "bob invited to group #team via your group link" alice <## "#team: bob joined the group", do bob <## "alice (Alice): contact is connected" @@ -1660,7 +1660,7 @@ testGroupLinkDeleteGroupRejoin = <### [ "bob_1 (Bob): contact is connected", "contact bob_1 is merged into bob", "use @bob to send messages", - StartsWith "invitation to join the group #team sent to bob", + EndsWith "invited to group #team via your group link", EndsWith "joined the group" ], bob @@ -1690,7 +1690,7 @@ testGroupLinkContactUsed = concurrentlyN_ [ do alice <## "bob (Bob): contact is connected" - alice <## "invitation to join the group #team sent to bob" + alice <## "bob invited to group #team via your group link" alice <## "#team: bob joined the group", do bob <## "alice (Alice): contact is connected" @@ -1752,7 +1752,7 @@ testGroupLinkIncognitoMembership = [ do bob <## ("cath (Catherine): contact is connected, your incognito profile for this contact is " <> bobIncognito) bob <## "use /i cath to print out this incognito profile again" - bob <## "invitation to join the group #team sent to cath" + bob <## "cath invited to group #team via your group link" bob <## "#team: cath joined the group", do cath <## (bobIncognito <> ": contact is connected") @@ -1778,7 +1778,7 @@ testGroupLinkIncognitoMembership = [ do bob <## (danIncognito <> ": contact is connected, your incognito profile for this contact is " <> bobIncognito) bob <## ("use /i " <> danIncognito <> " to print out this incognito profile again") - bob <## ("invitation to join the group #team sent to " <> danIncognito) + bob <## (danIncognito <> " invited to group #team via your group link") bob <## ("#team: " <> danIncognito <> " joined the group"), do dan <## (bobIncognito <> ": contact is connected, your incognito profile for this contact is " <> danIncognito) @@ -1841,7 +1841,7 @@ testGroupLinkUnusedHostContactDeleted = concurrentlyN_ [ do alice <## "bob (Bob): contact is connected" - alice <## "invitation to join the group #team sent to bob" + alice <## "bob invited to group #team via your group link" alice <## "#team: bob joined the group", do bob <## "alice (Alice): contact is connected" @@ -1861,7 +1861,7 @@ testGroupLinkUnusedHostContactDeleted = <### [ "bob_1 (Bob): contact is connected", "contact bob_1 is merged into bob", "use @bob to send messages", - StartsWith "invitation to join the group #club sent to bob", + EndsWith "invited to group #club via your group link", EndsWith "joined the group" ], bob @@ -1936,7 +1936,7 @@ testGroupLinkIncognitoUnusedHostContactsDeleted = concurrentlyN_ [ do alice <## (bobIncognito <> ": contact is connected") - alice <## ("invitation to join the group #" <> group <> " sent to " <> bobIncognito) + alice <## (bobIncognito <> " invited to group #" <> group <> " via your group link") alice <## ("#" <> group <> ": " <> bobIncognito <> " joined the group"), do bob <## (bobsAliceContact <> " (Alice): contact is connected, your incognito profile for this contact is " <> bobIncognito) @@ -1973,7 +1973,7 @@ testGroupLinkMemberRole = concurrentlyN_ [ do alice <## "bob (Bob): contact is connected" - alice <## "invitation to join the group #team sent to bob" + alice <## "bob invited to group #team via your group link" alice <## "#team: bob joined the group", do bob <## "alice (Alice): contact is connected" @@ -1986,11 +1986,12 @@ testGroupLinkMemberRole = cath ##> ("/c " <> gLink) cath <## "connection request sent!" alice <## "cath (Catherine): accepting request to join group #team..." + -- if contact existed it is merged concurrentlyN_ [ alice <### [ "cath (Catherine): contact is connected", - "invitation to join the group #team sent to cath", - "#team: cath joined the group" + EndsWith "invited to group #team via your group link", + EndsWith "joined the group" ], cath <### [ "alice (Alice): contact is connected", @@ -2040,7 +2041,7 @@ testGroupLinkLeaveDelete = <### [ "bob_1 (Bob): contact is connected", "contact bob_1 is merged into bob", "use @bob to send messages", - StartsWith "invitation to join the group #team sent to bob", + EndsWith "invited to group #team via your group link", EndsWith "joined the group" ], bob @@ -2056,7 +2057,7 @@ testGroupLinkLeaveDelete = concurrentlyN_ [ alice <### [ "cath (Catherine): contact is connected", - "invitation to join the group #team sent to cath", + "cath invited to group #team via your group link", "#team: cath joined the group" ], cath diff --git a/tests/ChatTests/Utils.hs b/tests/ChatTests/Utils.hs index 58b80fa1e..db8d63457 100644 --- a/tests/ChatTests/Utils.hs +++ b/tests/ChatTests/Utils.hs @@ -267,11 +267,7 @@ cc <##.. ls = do unless prefix $ print ("expected to start from one of: " <> show ls, ", got: " <> l) prefix `shouldBe` True -data ConsoleResponse - = ConsoleString String - | WithTime String - | EndsWith String - | StartsWith String +data ConsoleResponse = ConsoleString String | WithTime String | EndsWith String deriving (Show) instance IsString ConsoleResponse where fromString = ConsoleString @@ -291,7 +287,6 @@ getInAnyOrder f cc ls = do ConsoleString s -> l == s WithTime s -> dropTime_ l == Just s EndsWith s -> s `isSuffixOf` l - StartsWith s -> s `isPrefixOf` l (<###) :: HasCallStack => TestCC -> [ConsoleResponse] -> Expectation (<###) = getInAnyOrder id