core, ios: improve business address (connection plan, repeat requests, feature items) (#5303)

* core, ios: connection plan for business address

* core: store xcontact_id on business groups to prevent duplicate contact requests

* core: create feature items in new groups and in business groups

* fix tests

* error message
This commit is contained in:
Evgeny
2024-12-03 12:11:38 +00:00
committed by GitHub
parent e61babdc8f
commit 9d992735f4
17 changed files with 195 additions and 132 deletions
+27 -18
View File
@@ -2208,9 +2208,11 @@ processChatCommand' vr = \case
gVar <- asks random
-- [incognito] generate incognito profile for group membership
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
groupInfo <- withFastStore $ \db -> createNewGroup db vr gVar user gProfile incognitoProfile
createInternalChatItem user (CDGroupSnd groupInfo) (CISndGroupE2EEInfo $ E2EInfo {pqEnabled = PQEncOff}) Nothing
pure $ CRGroupCreated user groupInfo
gInfo <- withFastStore $ \db -> createNewGroup db vr gVar user gProfile incognitoProfile
let cd = CDGroupSnd gInfo
createInternalChatItem user cd (CISndGroupE2EEInfo E2EInfo {pqEnabled = PQEncOff}) Nothing
createGroupFeatureItems user cd CISndGroupFeature gInfo
pure $ CRGroupCreated user gInfo
NewGroup incognito gProfile -> withUser $ \User {userId} ->
processChatCommand $ APINewGroup userId incognito gProfile
APIAddMember groupId contactId memRole -> withUser $ \user -> withGroupLock "addMember" groupId $ do
@@ -3137,7 +3139,8 @@ processChatCommand' vr = \case
| not (contactReady ct) && contactActive ct -> pure $ CPContactAddress (CAPConnectingProhibit ct)
| contactDeleted ct -> pure $ CPContactAddress CAPOk
| otherwise -> pure $ CPContactAddress (CAPKnown ct)
Just _ -> throwChatError $ CECommandError "found connection entity is not RcvDirectMsgConnection"
Just (RcvGroupMsgConnection _ gInfo _) -> groupPlan gInfo
Just _ -> throwChatError $ CECommandError "found connection entity is not RcvDirectMsgConnection or RcvGroupMsgConnection"
-- group link
Just _ ->
withFastStore' (\db -> getGroupInfoByUserContactLinkConnReq db vr user cReqSchemas) >>= \case
@@ -3152,12 +3155,13 @@ processChatCommand' vr = \case
| not (contactReady ct) && contactActive ct -> pure $ CPGroupLink (GLPConnectingProhibit gInfo_)
| otherwise -> pure $ CPGroupLink GLPOk
(Nothing, Just _) -> throwChatError $ CECommandError "found connection entity is not RcvDirectMsgConnection"
(Just gInfo@GroupInfo {membership}, _)
| not (memberActive membership) && not (memberRemoved membership) ->
pure $ CPGroupLink (GLPConnectingProhibit gInfo_)
| memberActive membership -> pure $ CPGroupLink (GLPKnown gInfo)
| otherwise -> pure $ CPGroupLink GLPOk
(Just gInfo, _) -> groupPlan gInfo
where
groupPlan gInfo@GroupInfo {membership}
| not (memberActive membership) && not (memberRemoved membership) =
pure $ CPGroupLink (GLPConnectingProhibit $ Just gInfo)
| memberActive membership = pure $ CPGroupLink (GLPKnown gInfo)
| otherwise = pure $ CPGroupLink GLPOk
cReqSchemas :: (ConnReqContact, ConnReqContact)
cReqSchemas =
( CRContactUri crData {crScheme = SSSimplex},
@@ -4035,6 +4039,9 @@ acceptBusinessJoinRequestAsync
let chatV = vr `peerConnChatVersion` cReqChatVRange
connIds <- agentAcceptContactAsync user True invId msg subMode PQSupportOff chatV
withStore' $ \db -> createAcceptedMemberConnection db user connIds chatV ucr groupMemberId subMode
let cd = CDGroupSnd gInfo
createInternalChatItem user cd (CISndGroupE2EEInfo E2EInfo {pqEnabled = PQEncOff}) Nothing
createGroupFeatureItems user cd CISndGroupFeature gInfo
pure gInfo
where
businessGroupProfile :: Profile -> GroupPreferences -> GroupProfile
@@ -5086,8 +5093,9 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
case memberCategory m of
GCHostMember -> do
toView $ CRUserJoinedGroup user gInfo {membership = membership {memberStatus = GSMemConnected}} m {memberStatus = GSMemConnected}
createInternalChatItem user (CDGroupRcv gInfo m) (CIRcvGroupE2EEInfo $ E2EInfo {pqEnabled = PQEncOff}) Nothing
createGroupFeatureItems gInfo m
let cd = CDGroupRcv gInfo m
createInternalChatItem user cd (CIRcvGroupE2EEInfo E2EInfo {pqEnabled = PQEncOff}) Nothing
createGroupFeatureItems user cd CIRcvGroupFeature gInfo
let GroupInfo {groupProfile = GroupProfile {description}} = gInfo
memberConnectedChatItem gInfo m
unless expectHistory $ forM_ description $ groupDescriptionChatItem gInfo m
@@ -5597,6 +5605,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
profileContactRequest invId chatVRange p xContactId_ reqPQSup = do
withStore (\db -> createOrUpdateContactRequest db vr user userContactLinkId invId chatVRange p xContactId_ reqPQSup) >>= \case
CORContact contact -> toView $ CRContactRequestAlreadyAccepted user contact
CORGroup gInfo -> toView $ CRBusinessRequestAlreadyAccepted user gInfo
CORRequest cReq -> do
ucl <- withStore $ \db -> getUserContactLinkById db userId userContactLinkId
let (UserContactLink {connReqContact, autoAccept}, groupId_, gLinkMemRole) = ucl
@@ -6487,13 +6496,6 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
let state = featureState $ getContactUserPreference f mergedPreferences
createInternalChatItem user (CDDirectRcv ct) (uncurry (CIRcvChatFeature $ chatFeature f) state) Nothing
createGroupFeatureItems :: GroupInfo -> GroupMember -> CM ()
createGroupFeatureItems g@GroupInfo {fullGroupPreferences} m =
forM_ allGroupFeatures $ \(AGF f) -> do
let p = getGroupPreference f fullGroupPreferences
(_, param, role) = groupFeatureState p
createInternalChatItem user (CDGroupRcv g m) (CIRcvGroupFeature (toGroupFeature f) (toGroupPreference p) param role) Nothing
xInfoProbe :: ContactOrMember -> Probe -> CM ()
xInfoProbe cgm2 probe = do
contactMerge <- readTVarIO =<< asks contactMergeEnabled
@@ -8179,6 +8181,13 @@ createGroupFeatureChangedItems user cd ciContent GroupInfo {fullGroupPreferences
sameGroupProfileInfo :: GroupProfile -> GroupProfile -> Bool
sameGroupProfileInfo p p' = p {groupPreferences = Nothing} == p' {groupPreferences = Nothing}
createGroupFeatureItems :: MsgDirectionI d => User -> ChatDirection 'CTGroup d -> (GroupFeature -> GroupPreference -> Maybe Int -> Maybe GroupMemberRole -> CIContent d) -> GroupInfo -> CM ()
createGroupFeatureItems user cd ciContent GroupInfo {fullGroupPreferences} =
forM_ allGroupFeatures $ \(AGF f) -> do
let p = getGroupPreference f fullGroupPreferences
(_, param, role) = groupFeatureState p
createInternalChatItem user cd (ciContent (toGroupFeature f) (toGroupPreference p) param role) Nothing
createInternalChatItem :: (ChatTypeI c, MsgDirectionI d) => User -> ChatDirection c d -> CIContent d -> Maybe UTCTime -> CM ()
createInternalChatItem user cd content itemTs_ =
lift (createInternalItemsForChats user itemTs_ [(cd, [content])]) >>= \case