core: api to differentiate contacts and conversations (#4111)

This commit is contained in:
spaced4ndy
2024-05-13 16:51:54 +04:00
committed by GitHub
parent 06d61ea73e
commit f40ba6f04d
15 changed files with 164 additions and 46 deletions
+39 -19
View File
@@ -1022,22 +1022,41 @@ processChatCommand' vr = \case
liftIO $ updateNoteFolderUnreadChat db user nf unreadChat
ok user
_ -> pure $ chatCmdError (Just user) "not supported"
APIDeleteChat (ChatRef cType chatId) notify -> withUser $ \user@User {userId} -> case cType of
APIDeleteChat cRef@(ChatRef cType chatId) chatDeleteMode -> withUser $ \user@User {userId} -> case cType of
CTDirect -> do
ct <- withStore $ \db -> getContact db vr user chatId
filesInfo <- withStore' $ \db -> getContactFileInfo db user ct
withContactLock "deleteChat direct" chatId . procCmd $ do
cancelFilesInProgress user filesInfo
deleteFilesLocally filesInfo
let doSendDel = contactReady ct && contactActive ct && notify
when doSendDel $ void (sendDirectContactMessage user ct XDirectDel) `catchChatError` const (pure ())
contactConnIds <- map aConnId <$> withStore' (\db -> getContactConnections db vr userId ct)
deleteAgentConnectionsAsync' user contactConnIds doSendDel
-- functions below are called in separate transactions to prevent crashes on android
-- (possibly, race condition on integrity check?)
withStore' $ \db -> deleteContactConnectionsAndFiles db userId ct
withStore $ \db -> deleteContact db user ct
pure $ CRContactDeleted user ct
withContactLock "deleteChat direct" chatId . procCmd $
case chatDeleteMode of
CDMFull notify -> do
cancelFilesInProgress user filesInfo
deleteFilesLocally filesInfo
sendDelDeleteConns ct notify
-- functions below are called in separate transactions to prevent crashes on android
-- (possibly, race condition on integrity check?)
withStore' $ \db -> do
deleteContactConnections db user ct
deleteContactFiles db user ct
withStore $ \db -> deleteContact db user ct
pure $ CRContactDeleted user ct
CDMEntity notify -> do
cancelFilesInProgress user filesInfo
sendDelDeleteConns ct notify
ct' <- withStore $ \db -> do
liftIO $ deleteContactConnections db user ct
liftIO $ void $ updateContactStatus db user ct CSDeletedByUser
getContact db vr user chatId
pure $ CRContactDeleted user ct'
CDMMessages -> do
void $ processChatCommand $ APIClearChat cRef
withStore' $ \db -> setContactChatDeleted db user ct True
pure $ CRContactDeleted user ct {chatDeleted = True}
where
sendDelDeleteConns ct notify = do
let doSendDel = contactReady ct && contactActive ct && notify
when doSendDel $ void (sendDirectContactMessage user ct XDirectDel) `catchChatError` const (pure ())
contactConnIds <- map aConnId <$> withStore' (\db -> getContactConnections db vr userId ct)
deleteAgentConnectionsAsync' user contactConnIds doSendDel
CTContactConnection -> withConnectionLock "deleteChat contactConnection" chatId . procCmd $ do
conn@PendingContactConnection {pccAgentConnId = AgentConnId acId} <- withStore $ \db -> getPendingContactConnection db userId chatId
deleteAgentConnectionAsync user acId
@@ -1554,7 +1573,7 @@ processChatCommand' vr = \case
CPContactAddress (CAPContactViaAddress Contact {contactId}) ->
processChatCommand $ APIConnectContactViaAddress userId incognito contactId
_ -> processChatCommand $ APIConnect userId incognito (Just cReqUri)
DeleteContact cName -> withContactName cName $ \ctId -> APIDeleteChat (ChatRef CTDirect ctId) True
DeleteContact cName -> withContactName cName $ \ctId -> APIDeleteChat (ChatRef CTDirect ctId) (CDMFull True)
ClearContact cName -> withContactName cName $ APIClearChat . ChatRef CTDirect
APIListContacts userId -> withUserId userId $ \user ->
CRContactsList user <$> withStore' (\db -> getUserContacts db vr user)
@@ -1889,7 +1908,7 @@ processChatCommand' vr = \case
processChatCommand $ APILeaveGroup groupId
DeleteGroup gName -> withUser $ \user -> do
groupId <- withStore $ \db -> getGroupIdByName db user gName
processChatCommand $ APIDeleteChat (ChatRef CTGroup groupId) True
processChatCommand $ APIDeleteChat (ChatRef CTGroup groupId) (CDMFull True)
ClearGroup gName -> withUser $ \user -> do
groupId <- withStore $ \db -> getGroupIdByName db user gName
processChatCommand $ APIClearChat (ChatRef CTGroup groupId)
@@ -6676,7 +6695,7 @@ saveSndChatItem' :: ChatTypeI c => User -> ChatDirection c 'MDSnd -> SndMessage
saveSndChatItem' user cd msg@SndMessage {sharedMsgId} content ciFile quotedItem itemForwarded itemTimed live = do
createdAt <- liftIO getCurrentTime
ciId <- withStore' $ \db -> do
when (ciRequiresAttention content) $ updateChatTs db user cd createdAt
when (ciRequiresAttention content || contactChatDeleted cd) $ updateChatTs db user cd createdAt
ciId <- createNewSndChatItem db user cd msg content quotedItem itemForwarded itemTimed live createdAt
forM_ ciFile $ \CIFile {fileId} -> updateFileTransferChatItemId db fileId ciId createdAt
pure ciId
@@ -6690,7 +6709,7 @@ saveRcvChatItem' :: (ChatTypeI c, ChatTypeQuotable c) => User -> ChatDirection c
saveRcvChatItem' user cd msg@RcvMessage {forwardedByMember} sharedMsgId_ brokerTs content ciFile itemTimed live = do
createdAt <- liftIO getCurrentTime
(ciId, quotedItem, itemForwarded) <- withStore' $ \db -> do
when (ciRequiresAttention content) $ updateChatTs db user cd createdAt
when (ciRequiresAttention content || contactChatDeleted cd) $ updateChatTs db user cd createdAt
r@(ciId, _, _) <- createNewRcvChatItem db user cd msg sharedMsgId_ content itemTimed live brokerTs createdAt
forM_ ciFile $ \CIFile {fileId} -> updateFileTransferChatItemId db fileId ciId createdAt
pure r
@@ -6956,7 +6975,7 @@ createInternalItemsForChats user itemTs_ dirsCIContents = do
where
updateChat :: DB.Connection -> UTCTime -> ChatDirection c d -> [CIContent d] -> IO ()
updateChat db createdAt cd contents
| any ciRequiresAttention contents = updateChatTs db user cd createdAt
| any ciRequiresAttention contents || contactChatDeleted cd = updateChatTs db user cd createdAt
| otherwise = pure ()
createACIs :: DB.Connection -> UTCTime -> UTCTime -> ChatDirection c d -> [CIContent d] -> [IO AChatItem]
createACIs db itemTs createdAt cd = map $ \content -> do
@@ -7104,7 +7123,8 @@ chatCommandP =
"/read user" $> UserRead,
"/_read chat " *> (APIChatRead <$> chatRefP <*> optional (A.space *> ((,) <$> ("from=" *> A.decimal) <* A.space <*> ("to=" *> A.decimal)))),
"/_unread chat " *> (APIChatUnread <$> chatRefP <* A.space <*> onOffP),
"/_delete " *> (APIDeleteChat <$> chatRefP <*> (A.space *> "notify=" *> onOffP <|> pure True)),
"/_delete " *> (APIDeleteChat <$> chatRefP <* A.space <*> jsonP),
"/_delete " *> (APIDeleteChat <$> chatRefP <*> (CDMFull <$> (A.space *> "notify=" *> onOffP <|> pure True))),
"/_clear chat " *> (APIClearChat <$> chatRefP),
"/_accept" *> (APIAcceptContact <$> incognitoOnOffP <* A.space <*> A.decimal),
"/_reject " *> (APIRejectContact <$> A.decimal),