mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 12:53:18 +00:00
android, desktop: group knocking (#5816)
This commit is contained in:
1 parent
3095b980cb
commit
805a69da94
34 files changed
+1844
-748
No files matched your search
@@ -1578,7 +1578,7 @@ processChatCommand' vr = \case
|
||||
case memberConnId m of
|
||||
Just connId -> do
|
||||
cStats@ConnectionStats {ratchetSyncState = rss} <- withAgent $ \a -> synchronizeRatchet a connId PQSupportOff force
|
||||
(g', m', scopeInfo) <- liftIO $ mkGroupChatScope g m
|
||||
(g', m', scopeInfo) <- mkGroupChatScope g m
|
||||
createInternalChatItem user (CDGroupSnd g' scopeInfo) (CISndConnEvent . SCERatchetSync rss . Just $ groupMemberRef m') Nothing
|
||||
pure $ CRGroupMemberRatchetSyncStarted user g' m' cStats
|
||||
_ -> throwChatError CEGroupMemberNotActive
|
||||
@@ -2244,7 +2244,7 @@ processChatCommand' vr = \case
|
||||
pure m {memberStatus = GSMemRemoved}
|
||||
deletePendingMember :: ([ChatError], [GroupMember], [AChatItem]) -> User -> GroupInfo -> [GroupMember] -> GroupMember -> CM ([ChatError], [GroupMember], [AChatItem])
|
||||
deletePendingMember (accErrs, accDeleted, accACIs) user gInfo recipients m = do
|
||||
(m', scopeInfo) <- liftIO $ mkMemberSupportChatInfo m
|
||||
(m', scopeInfo) <- mkMemberSupportChatInfo m
|
||||
(errs, deleted, acis) <- deleteMemsSend user gInfo (Just scopeInfo) recipients [m']
|
||||
pure (errs <> accErrs, deleted <> accDeleted, acis <> accACIs)
|
||||
deleteMemsSend :: User -> GroupInfo -> Maybe GroupChatScopeInfo -> [GroupMember] -> [GroupMember] -> CM ([ChatError], [GroupMember], [AChatItem])
|
||||
@@ -2280,7 +2280,7 @@ processChatCommand' vr = \case
|
||||
cancelFilesInProgress user filesInfo
|
||||
let recipients = filter memberCurrentOrPending members
|
||||
msg <- sendGroupMessage' user gInfo recipients XGrpLeave
|
||||
(gInfo', scopeInfo) <- liftIO $ mkLocalGroupChatScope gInfo
|
||||
(gInfo', scopeInfo) <- mkLocalGroupChatScope gInfo
|
||||
ci <- saveSndChatItem user (CDGroupSnd gInfo' scopeInfo) msg (CISndGroupEvent SGEUserLeft)
|
||||
toView $ CRNewChatItems user [AChatItem SCTGroup SMDSnd (GroupChat gInfo' scopeInfo) ci]
|
||||
-- TODO delete direct connections that were unused
|
||||
|
||||
@@ -1323,7 +1323,7 @@ getGroupRecipients vr user gInfo@GroupInfo {membership} scope modsCompatVersion
|
||||
compatible GroupMember {activeConn, memberChatVRange} =
|
||||
maxVersion (maybe memberChatVRange peerChatVRange activeConn) >= modsCompatVersion
|
||||
|
||||
mkLocalGroupChatScope :: GroupInfo -> IO (GroupInfo, Maybe GroupChatScopeInfo)
|
||||
mkLocalGroupChatScope :: GroupInfo -> CM (GroupInfo, Maybe GroupChatScopeInfo)
|
||||
mkLocalGroupChatScope gInfo@GroupInfo {membership}
|
||||
| memberPending membership = do
|
||||
(gInfo', scopeInfo) <- mkGroupSupportChatInfo gInfo
|
||||
@@ -1331,7 +1331,7 @@ mkLocalGroupChatScope gInfo@GroupInfo {membership}
|
||||
| otherwise =
|
||||
pure (gInfo, Nothing)
|
||||
|
||||
mkGroupChatScope :: GroupInfo -> GroupMember -> IO (GroupInfo, GroupMember, Maybe GroupChatScopeInfo)
|
||||
mkGroupChatScope :: GroupInfo -> GroupMember -> CM (GroupInfo, GroupMember, Maybe GroupChatScopeInfo)
|
||||
mkGroupChatScope gInfo@GroupInfo {membership} m
|
||||
| memberPending membership = do
|
||||
(gInfo', scopeInfo) <- mkGroupSupportChatInfo gInfo
|
||||
@@ -1344,38 +1344,40 @@ mkGroupChatScope gInfo@GroupInfo {membership} m
|
||||
|
||||
mkGetMessageChatScope :: VersionRangeChat -> User -> GroupInfo -> GroupMember -> Maybe MsgScope -> CM (GroupInfo, GroupMember, Maybe GroupChatScopeInfo)
|
||||
mkGetMessageChatScope vr user gInfo@GroupInfo {membership} m msgScope_ =
|
||||
liftIO (mkGroupChatScope gInfo m) >>= \case
|
||||
mkGroupChatScope gInfo m >>= \case
|
||||
groupScope@(_gInfo', _m', Just _scopeInfo) -> pure groupScope
|
||||
(_, _, Nothing) -> case msgScope_ of
|
||||
Nothing -> pure (gInfo, m, Nothing)
|
||||
Just (MSMember mId)
|
||||
| sameMemberId mId membership -> do
|
||||
(gInfo', scopeInfo) <- liftIO $ mkGroupSupportChatInfo gInfo
|
||||
(gInfo', scopeInfo) <- mkGroupSupportChatInfo gInfo
|
||||
pure (gInfo', m, Just scopeInfo)
|
||||
| otherwise -> do
|
||||
referredMember <- withStore $ \db -> getGroupMemberByMemberId db vr user gInfo mId
|
||||
-- TODO [knocking] return patched _referredMember' too?
|
||||
(_referredMember', scopeInfo) <- liftIO $ mkMemberSupportChatInfo referredMember
|
||||
(_referredMember', scopeInfo) <- mkMemberSupportChatInfo referredMember
|
||||
pure (gInfo, m, Just scopeInfo)
|
||||
|
||||
mkGroupSupportChatInfo :: GroupInfo -> IO (GroupInfo, GroupChatScopeInfo)
|
||||
mkGroupSupportChatInfo :: GroupInfo -> CM (GroupInfo, GroupChatScopeInfo)
|
||||
mkGroupSupportChatInfo gInfo@GroupInfo {membership} =
|
||||
case supportChat membership of
|
||||
Nothing -> do
|
||||
chatTs <- getCurrentTime
|
||||
let gInfo' = gInfo {membership = membership {supportChat = Just $ GroupSupportChat chatTs 1 0 0}}
|
||||
chatTs <- liftIO getCurrentTime
|
||||
withStore' $ \db -> setSupportChatTs db (groupMemberId' membership) chatTs
|
||||
let gInfo' = gInfo {membership = membership {supportChat = Just $ GroupSupportChat chatTs 0 0 0}}
|
||||
scopeInfo = GCSIMemberSupport {groupMember_ = Nothing}
|
||||
pure (gInfo', scopeInfo)
|
||||
Just _supportChat ->
|
||||
let scopeInfo = GCSIMemberSupport {groupMember_ = Nothing}
|
||||
in pure (gInfo, scopeInfo)
|
||||
|
||||
mkMemberSupportChatInfo :: GroupMember -> IO (GroupMember, GroupChatScopeInfo)
|
||||
mkMemberSupportChatInfo m@GroupMember {supportChat} =
|
||||
mkMemberSupportChatInfo :: GroupMember -> CM (GroupMember, GroupChatScopeInfo)
|
||||
mkMemberSupportChatInfo m@GroupMember {groupMemberId, supportChat} =
|
||||
case supportChat of
|
||||
Nothing -> do
|
||||
chatTs <- getCurrentTime
|
||||
let m' = m {supportChat = Just $ GroupSupportChat chatTs 1 0 0}
|
||||
chatTs <- liftIO getCurrentTime
|
||||
withStore' $ \db -> setSupportChatTs db groupMemberId chatTs
|
||||
let m' = m {supportChat = Just $ GroupSupportChat chatTs 0 0 0}
|
||||
scopeInfo = GCSIMemberSupport {groupMember_ = Just m'}
|
||||
pure (m', scopeInfo)
|
||||
Just _supportChat ->
|
||||
|
||||
@@ -777,7 +777,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
else pure $ memberStatus membership
|
||||
pure (GSMemConnected, membershipStatus)
|
||||
toView $ CRUserJoinedGroup user gInfo {membership = membership {memberStatus = membershipStatus}} m {memberStatus = mStatus}
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
let cd = CDGroupRcv gInfo' scopeInfo m'
|
||||
createInternalChatItem user cd (CIRcvGroupE2EEInfo E2EInfo {pqEnabled = PQEncOff}) Nothing
|
||||
createGroupFeatureItems user cd CIRcvGroupFeature gInfo'
|
||||
@@ -788,7 +788,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
if not (memberPending m)
|
||||
then withStore' $ \db -> updateGroupMemberStatus db userId m GSMemConnected $> GSMemConnected
|
||||
else pure $ memberStatus m
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
memberConnectedChatItem gInfo' scopeInfo m'
|
||||
toView $ CRJoinedGroupMember user gInfo' m' {memberStatus = mStatus}
|
||||
let Connection {viaUserContactLink} = conn
|
||||
@@ -843,7 +843,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
tags <- newTVarIO []
|
||||
withAckMessage "group msg" agentConnId msgMeta True (Just tags) $ \eInfo -> do
|
||||
-- possible improvement is to choose scope based on event (some events specify scope)
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
checkIntegrityCreateItem (CDGroupRcv gInfo' scopeInfo m') msgMeta `catchChatError` \_ -> pure ()
|
||||
forM_ aChatMsgs $ \case
|
||||
Right (ACMsg _ chatMsg) ->
|
||||
@@ -936,12 +936,12 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
when continued $ sendPendingGroupMessages user m conn
|
||||
SWITCH qd phase cStats -> do
|
||||
toView $ CRGroupMemberSwitch user gInfo m (SwitchProgress qd phase cStats)
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
when (phase == SPStarted || phase == SPCompleted) $ case qd of
|
||||
QDRcv -> createInternalChatItem user (CDGroupSnd gInfo' scopeInfo) (CISndConnEvent . SCESwitchQueue phase . Just $ groupMemberRef m') Nothing
|
||||
QDSnd -> createInternalChatItem user (CDGroupRcv gInfo' scopeInfo m') (CIRcvConnEvent $ RCESwitchQueue phase) Nothing
|
||||
RSYNC rss cryptoErr_ cStats -> do
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
case (rss, connectionCode, cryptoErr_) of
|
||||
(RSRequired, _, Just cryptoErr) -> processErr gInfo' scopeInfo m' cryptoErr
|
||||
(RSAllowed, _, Just cryptoErr) -> processErr gInfo' scopeInfo m' cryptoErr
|
||||
@@ -1234,7 +1234,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
| otherwise -> do
|
||||
let profileMode = ExistingIncognito <$> incognitoMembershipProfile gInfo
|
||||
mem <- acceptGroupJoinRequestAsync user gInfo cReq acceptance useRole profileMode
|
||||
(gInfo', mem', scopeInfo) <- liftIO $ mkGroupChatScope gInfo mem
|
||||
(gInfo', mem', scopeInfo) <- mkGroupChatScope gInfo mem
|
||||
createInternalChatItem user (CDGroupRcv gInfo' scopeInfo mem') (CIRcvGroupEvent RGEInvitedViaGroupLink) Nothing
|
||||
toView $ CRAcceptingGroupJoinRequestMember user gInfo' mem'
|
||||
Left rjctReason
|
||||
@@ -1379,7 +1379,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
|
||||
notifyMemberConnected :: GroupInfo -> GroupMember -> Maybe Contact -> CM ()
|
||||
notifyMemberConnected gInfo m ct_ = do
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
memberConnectedChatItem gInfo' scopeInfo m'
|
||||
lift $ mapM_ (`setContactNetworkStatus` NSConnected) ct_
|
||||
toView $ CRConnectedToGroupMember user gInfo' m' ct_
|
||||
@@ -2165,7 +2165,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
BCCustomer -> customerId == memberId
|
||||
createProfileUpdatedItem m' =
|
||||
when createItems $ do
|
||||
(gInfo', m'', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m'
|
||||
(gInfo', m'', scopeInfo) <- mkGroupChatScope gInfo m'
|
||||
let ciContent = CIRcvGroupEvent $ RGEMemberProfileUpdated (fromLocalProfile p) p'
|
||||
createInternalChatItem user (CDGroupRcv gInfo' scopeInfo m'') ciContent itemTs_
|
||||
|
||||
@@ -2458,7 +2458,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
Just (MSMember _) -> GSMemPendingReview
|
||||
_ -> GSMemAnnounced
|
||||
memberAnnouncedToView announcedMember@GroupMember {groupMemberId, memberProfile} = do
|
||||
(announcedMember', scopeInfo) <- liftIO $ getMemNewChatScope announcedMember
|
||||
(announcedMember', scopeInfo) <- getMemNewChatScope announcedMember
|
||||
let event = RGEMemberAdded groupMemberId (fromLocalProfile memberProfile)
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo scopeInfo m) msg brokerTs (CIRcvGroupEvent event)
|
||||
groupMsgToView gInfo scopeInfo ci
|
||||
@@ -2555,7 +2555,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
| senderRole < GRAdmin || senderRole < fromRole = messageError "x.grp.mem.role with insufficient member permissions"
|
||||
| otherwise = do
|
||||
withStore' $ \db -> updateGroupMemberRole db user member memRole
|
||||
(gInfo'', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo' m
|
||||
(gInfo'', m', scopeInfo) <- mkGroupChatScope gInfo' m
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo'' scopeInfo m') msg brokerTs (CIRcvGroupEvent gEvent)
|
||||
groupMsgToView gInfo'' scopeInfo ci
|
||||
toView CRMemberRole {user, groupInfo = gInfo'', byMember = m', member = member {memberRole = memRole}, fromRole, toRole = memRole}
|
||||
@@ -2584,7 +2584,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
bm' <- setMemberBlocked bm
|
||||
toggleNtf user bm' (not blocked)
|
||||
let ciContent = CIRcvGroupEvent $ RGEMemberBlocked bmId (fromLocalProfile bmp) blocked
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo' scopeInfo m') msg brokerTs ciContent
|
||||
groupMsgToView gInfo' scopeInfo ci
|
||||
toView CRMemberBlockedForAll {user, groupInfo = gInfo', byMember = m', member = bm, blocked}
|
||||
@@ -2669,7 +2669,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
messageError "x.grp.mem.del with insufficient member permissions"
|
||||
| otherwise = a
|
||||
deleteMemberItem gEvent = do
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo' scopeInfo m') msg brokerTs (CIRcvGroupEvent gEvent)
|
||||
groupMsgToView gInfo' scopeInfo ci
|
||||
deleteMessages :: MsgDirectionI d => GroupMember -> SMsgDirection d -> CM ()
|
||||
@@ -2682,7 +2682,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
deleteMemberConnection user m
|
||||
-- member record is not deleted to allow creation of "member left" chat item
|
||||
withStore' $ \db -> updateGroupMemberStatus db userId m GSMemLeft
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo' scopeInfo m') msg brokerTs (CIRcvGroupEvent RGEMemberLeft)
|
||||
groupMsgToView gInfo' scopeInfo ci
|
||||
toView $ CRLeftMember user gInfo' m' {memberStatus = GSMemLeft}
|
||||
@@ -2696,7 +2696,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
pure members
|
||||
-- member records are not deleted to keep history
|
||||
deleteMembersConnections user ms
|
||||
(gInfo'', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo'', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
ci <- saveRcvChatItemNoParse user (CDGroupRcv gInfo'' scopeInfo m') msg brokerTs (CIRcvGroupEvent RGEGroupDeleted)
|
||||
groupMsgToView gInfo'' scopeInfo ci
|
||||
toView $ CRGroupDeleted user gInfo'' {membership = membership {memberStatus = GSMemGroupDeleted}} m'
|
||||
@@ -2707,7 +2707,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
| otherwise = case businessChat of
|
||||
Nothing -> unless (p == p') $ do
|
||||
g' <- withStore $ \db -> updateGroupProfile db user g p'
|
||||
(g'', m', scopeInfo) <- liftIO $ mkGroupChatScope g' m
|
||||
(g'', m', scopeInfo) <- mkGroupChatScope g' m
|
||||
toView $ CRGroupUpdated user g g'' (Just m')
|
||||
let cd = CDGroupRcv g'' scopeInfo m'
|
||||
unless (sameGroupProfileInfo p p') $ do
|
||||
@@ -2726,7 +2726,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
unless (groupPreferences p == Just ps') $ do
|
||||
g' <- withStore' $ \db -> updateGroupPreferences db user g ps'
|
||||
toView $ CRGroupUpdated user g g' (Just m)
|
||||
(g'', m', scopeInfo) <- liftIO $ mkGroupChatScope g' m
|
||||
(g'', m', scopeInfo) <- mkGroupChatScope g' m
|
||||
let cd = CDGroupRcv g'' scopeInfo m'
|
||||
createGroupFeatureChangedItems user cd CIRcvGroupFeature g g''
|
||||
|
||||
@@ -2768,7 +2768,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
dm <- encodeConnInfo $ XInfo p
|
||||
joinAgentConnectionAsync user True connReq dm subMode
|
||||
createItems mCt' m' = do
|
||||
(g', m'', scopeInfo) <- liftIO $ mkGroupChatScope g m'
|
||||
(g', m'', scopeInfo) <- mkGroupChatScope g m'
|
||||
createInternalChatItem user (CDGroupRcv g' scopeInfo m'') (CIRcvGroupEvent RGEMemberCreatedContact) Nothing
|
||||
toView $ CRNewMemberContactReceivedInv user mCt' g' m''
|
||||
forM_ mContent_ $ \mc -> do
|
||||
@@ -2827,7 +2827,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
|
||||
groupMsgReceived :: GroupInfo -> GroupMember -> Connection -> MsgMeta -> NonEmpty MsgReceipt -> CM ()
|
||||
groupMsgReceived gInfo m conn@Connection {connId} msgMeta msgRcpts = do
|
||||
(gInfo', m', scopeInfo) <- liftIO $ mkGroupChatScope gInfo m
|
||||
(gInfo', m', scopeInfo) <- mkGroupChatScope gInfo m
|
||||
checkIntegrityCreateItem (CDGroupRcv gInfo' scopeInfo m') msgMeta `catchChatError` \_ -> pure ()
|
||||
forM_ msgRcpts $ \MsgReceipt {agentMsgId, msgRcptStatus} -> do
|
||||
withStore' $ \db -> updateSndMsgDeliveryStatus db connId agentMsgId $ MDSSndRcvd msgRcptStatus
|
||||
|
||||
@@ -321,7 +321,7 @@ getGroupAndMember db User {userId, userContactId} groupMemberId vr = do
|
||||
-- | creates completely new group with a single member - the current user
|
||||
createNewGroup :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupProfile -> Maybe Profile -> ExceptT StoreError IO GroupInfo
|
||||
createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = ExceptT $ do
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
||||
currentTs <- getCurrentTime
|
||||
customUserProfileId <- mapM (createIncognitoProfile_ db userId currentTs) incognitoProfile
|
||||
@@ -329,8 +329,8 @@ createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = Exc
|
||||
groupId <- liftIO $ do
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||
profileId <- insertedRowId db
|
||||
DB.execute
|
||||
db
|
||||
@@ -390,7 +390,7 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
|
||||
DB.query db "SELECT group_id FROM groups WHERE inv_queue_info = ? AND user_id = ? LIMIT 1" (connRequest, userId)
|
||||
createGroupInvitation_ :: ExceptT StoreError IO (GroupInfo, GroupMemberId)
|
||||
createGroupInvitation_ = do
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
||||
ExceptT $
|
||||
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
||||
@@ -398,8 +398,8 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
|
||||
groupId <- liftIO $ do
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||
profileId <- insertedRowId db
|
||||
DB.execute
|
||||
db
|
||||
@@ -558,13 +558,13 @@ createGroupViaLink'
|
||||
(,) <$> getGroupInfo db vr user groupId <*> getGroupMemberById db vr user hostMemberId
|
||||
where
|
||||
insertGroup_ currentTs = ExceptT $ do
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
||||
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
||||
liftIO $ do
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||
profileId <- insertedRowId db
|
||||
DB.execute
|
||||
db
|
||||
|
||||
@@ -37,6 +37,7 @@ module Simplex.Chat.Store.Messages
|
||||
deleteOldMessages,
|
||||
MemberAttention (..),
|
||||
updateChatTsStats,
|
||||
setSupportChatTs,
|
||||
createNewSndChatItem,
|
||||
createNewRcvChatItem,
|
||||
createNewChatItemNoMsg,
|
||||
@@ -419,6 +420,10 @@ updateChatTsStats db User {userId} chatDirection chatTs chatStats_ = case toChat
|
||||
(chatTs, userId, noteFolderId)
|
||||
_ -> pure ()
|
||||
|
||||
setSupportChatTs :: DB.Connection -> GroupMemberId -> UTCTime -> IO ()
|
||||
setSupportChatTs db groupMemberId chatTs =
|
||||
DB.execute db "UPDATE group_members SET support_chat_ts = ? WHERE group_member_id = ?" (chatTs, groupMemberId)
|
||||
|
||||
createNewSndChatItem :: DB.Connection -> User -> ChatDirection c 'MDSnd -> SndMessage -> CIContent 'MDSnd -> Maybe (CIQuote c) -> Maybe CIForwardedFrom -> Maybe CITimed -> Bool -> UTCTime -> IO ChatItemId
|
||||
createNewSndChatItem db user chatDirection SndMessage {msgId, sharedMsgId} ciContent quotedItem itemForwarded timed live createdAt =
|
||||
createNewChatItem_ db user chatDirection createdByMsgId (Just sharedMsgId) ciContent quoteRow itemForwarded timed live False createdAt Nothing createdAt
|
||||
@@ -750,7 +755,7 @@ findGroupChatPreviews_ db User {userId} pagination clq =
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -1812,14 +1817,22 @@ getLocalNavInfo_ db User {userId} NoteFolder {noteFolderId} afterCI = do
|
||||
:. (userId, noteFolderId, ciCreatedAt afterCI, cChatItemId afterCI)
|
||||
)
|
||||
|
||||
toChatItemRef :: (ChatItemId, Maybe Int64, Maybe Int64, Maybe Int64) -> Either StoreError (ChatRef, ChatItemId)
|
||||
toChatItemRef ::
|
||||
(ChatItemId, Maybe ContactId, Maybe GroupId, Maybe GroupChatScopeTag, Maybe GroupMemberId, Maybe NoteFolderId) ->
|
||||
Either StoreError (ChatRef, ChatItemId)
|
||||
toChatItemRef = \case
|
||||
(itemId, Just contactId, Nothing, Nothing) -> Right (ChatRef CTDirect contactId Nothing, itemId)
|
||||
-- For "chat item refs" we don't care about scope, as they are only used for getting item by id (via getAChatItem).
|
||||
-- To get the scope without joining group_members, we could additionally store group scope "tag" to differentiate member support chats.
|
||||
(itemId, Nothing, Just groupId, Nothing) -> Right (ChatRef CTGroup groupId Nothing, itemId)
|
||||
(itemId, Nothing, Nothing, Just folderId) -> Right (ChatRef CTLocal folderId Nothing, itemId)
|
||||
(itemId, _, _, _) -> Left $ SEBadChatItem itemId Nothing
|
||||
(itemId, Just contactId, Nothing, Nothing, Nothing, Nothing) ->
|
||||
Right (ChatRef CTDirect contactId Nothing, itemId)
|
||||
(itemId, Nothing, Just groupId, Nothing, Nothing, Nothing) ->
|
||||
Right (ChatRef CTGroup groupId Nothing, itemId)
|
||||
(itemId, Nothing, Just groupId, Just GCSTMemberSupport_, Nothing, Nothing) ->
|
||||
Right (ChatRef CTGroup groupId (Just (GCSMemberSupport Nothing)), itemId)
|
||||
(itemId, Nothing, Just groupId, Just GCSTMemberSupport_, Just scopeGMId, Nothing) ->
|
||||
Right (ChatRef CTGroup groupId (Just (GCSMemberSupport $ Just scopeGMId)), itemId)
|
||||
(itemId, Nothing, Nothing, Nothing, Nothing, Just folderId) ->
|
||||
Right (ChatRef CTLocal folderId Nothing, itemId)
|
||||
(itemId, _, _, _, _, _) ->
|
||||
Left $ SEBadChatItem itemId Nothing
|
||||
|
||||
updateDirectChatItemsRead :: DB.Connection -> User -> ContactId -> IO ()
|
||||
updateDirectChatItemsRead db User {userId} contactId = do
|
||||
@@ -2170,7 +2183,7 @@ getAllChatItems db vr user@User {userId} pagination search_ = do
|
||||
<$> DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
ORDER BY item_ts DESC, chat_item_id DESC
|
||||
@@ -2181,7 +2194,7 @@ getAllChatItems db vr user@User {userId} pagination search_ = do
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
AND (item_ts > ? OR (item_ts = ? AND chat_item_id > ?))
|
||||
@@ -2194,7 +2207,7 @@ getAllChatItems db vr user@User {userId} pagination search_ = do
|
||||
<$> DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
AND (item_ts < ? OR (item_ts = ? AND chat_item_id < ?))
|
||||
@@ -2206,7 +2219,7 @@ getAllChatItems db vr user@User {userId} pagination search_ = do
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE chat_item_id = ?
|
||||
|]
|
||||
@@ -2952,7 +2965,7 @@ getChatItemByFileId db vr user@User {userId} fileId = do
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.note_folder_id
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.group_scope_tag, i.group_scope_group_member_id, i.note_folder_id
|
||||
FROM chat_items i
|
||||
JOIN files f ON f.chat_item_id = i.chat_item_id
|
||||
WHERE f.user_id = ? AND f.file_id = ?
|
||||
@@ -2974,7 +2987,7 @@ getChatItemByGroupId db vr user@User {userId} groupId = do
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.note_folder_id
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.group_scope_tag, i.group_scope_group_member_id, i.note_folder_id
|
||||
FROM chat_items i
|
||||
JOIN groups g ON g.chat_item_id = i.chat_item_id
|
||||
WHERE g.user_id = ? AND g.group_id = ?
|
||||
|
||||
@@ -462,7 +462,7 @@ SEARCH uc USING INDEX sqlite_autoindex_user_contact_links_1 (user_id=? AND local
|
||||
SEARCH c USING INDEX idx_connections_user_contact_link_id (user_contact_link_id=?)
|
||||
|
||||
Query:
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
AND (item_ts < ? OR (item_ts = ? AND chat_item_id < ?))
|
||||
@@ -474,7 +474,7 @@ SEARCH chat_items USING INDEX idx_chat_items_group_scope_item_ts (user_id=?)
|
||||
USE TEMP B-TREE FOR ORDER BY
|
||||
|
||||
Query:
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
ORDER BY item_ts DESC, chat_item_id DESC
|
||||
@@ -578,7 +578,7 @@ SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH i USING COVERING INDEX idx_chat_items_group_shared_msg_id (user_id=? AND group_id=? AND group_member_id=? AND shared_msg_id=?) LEFT-JOIN
|
||||
|
||||
Query:
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.note_folder_id
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.group_scope_tag, i.group_scope_group_member_id, i.note_folder_id
|
||||
FROM chat_items i
|
||||
JOIN files f ON f.chat_item_id = i.chat_item_id
|
||||
WHERE f.user_id = ? AND f.file_id = ?
|
||||
@@ -1014,7 +1014,7 @@ Plan:
|
||||
SEARCH chat_items USING INDEX idx_chat_items_group_id (group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE chat_item_id = ?
|
||||
|
||||
@@ -1022,7 +1022,7 @@ Plan:
|
||||
SEARCH chat_items USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT chat_item_id, contact_id, group_id, note_folder_id
|
||||
SELECT chat_item_id, contact_id, group_id, group_scope_tag, group_scope_group_member_id, note_folder_id
|
||||
FROM chat_items
|
||||
WHERE user_id = ? AND LOWER(item_text) LIKE '%' || LOWER(?) || '%'
|
||||
AND (item_ts > ? OR (item_ts = ? AND chat_item_id > ?))
|
||||
@@ -1179,7 +1179,7 @@ SEARCH i USING INDEX idx_chat_items_group_id (group_id=?)
|
||||
SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.note_folder_id
|
||||
SELECT i.chat_item_id, i.contact_id, i.group_id, i.group_scope_tag, i.group_scope_group_member_id, i.note_folder_id
|
||||
FROM chat_items i
|
||||
JOIN groups g ON g.chat_item_id = i.chat_item_id
|
||||
WHERE g.user_id = ? AND g.group_id = ?
|
||||
@@ -1952,7 +1952,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -1995,7 +1995,7 @@ SEARCH gp USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2004,7 +2004,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2041,7 +2041,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2050,7 +2050,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2086,7 +2086,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2095,7 +2095,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2131,7 +2131,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2140,7 +2140,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2176,7 +2176,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2185,7 +2185,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2221,7 +2221,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2230,7 +2230,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2266,7 +2266,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2275,7 +2275,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2311,7 +2311,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2320,7 +2320,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2353,7 +2353,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts<?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2362,7 +2362,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2395,7 +2395,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=? AND chat_ts>?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -2404,7 +2404,7 @@ Query:
|
||||
(
|
||||
SELECT chat_item_id
|
||||
FROM chat_items ci
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id
|
||||
WHERE ci.user_id = ? AND ci.group_id = g.group_id AND ci.group_scope_tag IS NULL
|
||||
ORDER BY ci.item_ts DESC
|
||||
LIMIT 1
|
||||
) AS chat_item_id,
|
||||
@@ -2437,7 +2437,7 @@ SEARCH g USING INDEX idx_groups_chat_ts (user_id=?)
|
||||
SEARCH ChatStats USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
SEARCH ReportCount USING AUTOMATIC COVERING INDEX (group_id=?) LEFT-JOIN
|
||||
CORRELATED SCALAR SUBQUERY 1
|
||||
SEARCH ci USING COVERING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
SEARCH ci USING INDEX idx_chat_items_groups_item_ts (user_id=? AND group_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
@@ -5460,7 +5460,7 @@ Plan:
|
||||
Query: INSERT INTO files (user_id, group_id, file_name, file_size, chunk_size, file_inline, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
|
||||
Query: INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)
|
||||
Query: INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
|
||||
Query: INSERT INTO group_profiles (display_name, full_name, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?)
|
||||
|
||||
@@ -1858,7 +1858,7 @@ $(JQ.deriveJSON defaultJSON ''LocalProfile)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''UserContactRequest)
|
||||
|
||||
$(JQ.deriveJSON (enumJSON $ dropPrefix "MC") ''MemberCriteria)
|
||||
$(JQ.deriveJSON (enumJSON $ dropPrefix "MC") {J.tagSingleConstructors = True} ''MemberCriteria)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''GroupMemberAdmission)
|
||||
|
||||
|
||||
Reference in new issue
Block a user