mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-25 09:54:22 +00:00
core, ui: chat banner (#6089)
* core: create banner item
* filter deletions
* fix query
* ios
* fixes
* remove comment
* revert diff
* refactor
* fix most tests
* fix tests
* spacer
* plans
* create banner for 1-time link initiator
* style in progress
* change background
* ui
* remove bio length limit
* ui
* create banner for client chat
* rename
* more contexts
* fix tests
* move
* fixed image size
* plans
* remove diff
* kotlin
* copy
* paddings
* paddings
* comment
* layout, messages
* fonts
* texts, icons
* kotlin refactor
* kotlin texts
* fix date
* Revert "fix date"
This reverts commit abbd48b334.
* date
* fix texts
* kotlin date
* color and corners
* kotlin
* color
* update banner, context menu in ios
* update texts, do not show epoch timestamp for banner
* fix texts
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
@@ -1766,6 +1766,7 @@ processChatCommand vr nm = \case
|
||||
groupPreferences = maybe defaultBusinessGroupPrefs businessGroupPrefs preferences
|
||||
groupProfile = businessGroupProfile profile groupPreferences
|
||||
(gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user groupProfile True ccLink welcomeSharedMsgId
|
||||
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
|
||||
let cd = CDGroupRcv gInfo Nothing hostMember
|
||||
createItem sharedMsgId content = createChatItem user cd True content sharedMsgId Nothing
|
||||
cInfo = GroupChat gInfo Nothing
|
||||
@@ -1777,7 +1778,9 @@ processChatCommand vr nm = \case
|
||||
pure $ CRNewPreparedChat user $ AChat SCTGroup chat
|
||||
ACCL _ (CCLink cReq _) -> do
|
||||
ct <- withStore $ \db -> createPreparedContact db user profile accLink welcomeSharedMsgId
|
||||
let createItem sharedMsgId content = createChatItem user (CDDirectRcv ct) False content sharedMsgId Nothing
|
||||
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
|
||||
let cd = CDDirectRcv ct
|
||||
createItem sharedMsgId content = createChatItem user cd False content sharedMsgId Nothing
|
||||
cInfo = DirectChat ct
|
||||
void $ createItem Nothing $ CIRcvDirectE2EEInfo $ E2EInfo $ connRequestPQEncryption cReq
|
||||
void $ createFeatureEnabledItems_ user ct
|
||||
@@ -1790,6 +1793,7 @@ processChatCommand vr nm = \case
|
||||
let GroupShortLinkData {groupProfile = gp@GroupProfile {description}} = groupSLinkData
|
||||
welcomeSharedMsgId <- forM description $ \_ -> getSharedMsgId
|
||||
(gInfo, hostMember) <- withStore $ \db -> createPreparedGroup db vr user gp False ccLink welcomeSharedMsgId
|
||||
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
|
||||
let cd = CDGroupRcv gInfo Nothing hostMember
|
||||
cInfo = GroupChat gInfo Nothing
|
||||
void $ createGroupFeatureItems_ user cd True CIRcvGroupFeature gInfo
|
||||
@@ -2111,6 +2115,7 @@ processChatCommand vr nm = \case
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
gInfo <- withFastStore $ \db -> createNewGroup db vr gVar user gProfile incognitoProfile
|
||||
let cd = CDGroupSnd gInfo Nothing
|
||||
createInternalChatItem user cd CIChatBanner (Just epochStart)
|
||||
createInternalChatItem user cd (CISndGroupE2EEInfo E2EInfo {pqEnabled = Just PQEncOff}) Nothing
|
||||
createGroupFeatureItems user cd CISndGroupFeature gInfo
|
||||
pure $ CRGroupCreated user gInfo
|
||||
@@ -2565,6 +2570,7 @@ processChatCommand vr nm = \case
|
||||
(connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True SCMInvitation Nothing Nothing IKPQOff subMode
|
||||
-- [incognito] reuse membership incognito profile
|
||||
ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode
|
||||
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
|
||||
-- TODO not sure it is correct to set connections status here?
|
||||
lift $ setContactNetworkStatus ct NSConnected
|
||||
pure $ CRNewMemberContact user ct g m
|
||||
|
||||
@@ -48,7 +48,8 @@ import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import Data.Text.Encoding (encodeUtf8)
|
||||
import Data.Time (addUTCTime)
|
||||
import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime, nominalDiffTimeToSeconds)
|
||||
import Data.Time.Calendar (fromGregorian)
|
||||
import Data.Time.Clock (UTCTime (..), diffUTCTime, getCurrentTime, nominalDiffTimeToSeconds, secondsToDiffTime)
|
||||
import Simplex.Chat.Call
|
||||
import Simplex.Chat.Controller
|
||||
import Simplex.Chat.Files
|
||||
@@ -2529,3 +2530,6 @@ timeItToView s action = do
|
||||
let diff = diffToMilliseconds $ diffUTCTime t2 t1
|
||||
toView' $ CEvtTimedAction s diff
|
||||
pure a
|
||||
|
||||
epochStart :: UTCTime
|
||||
epochStart = UTCTime (fromGregorian 1970 1 1) (secondsToDiffTime 0)
|
||||
|
||||
@@ -577,6 +577,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
-- TODO [short links] get contact request by contactRequestId, check encryption (UserContactRequest.pqSupport)?
|
||||
when (directOrUsed ct') $ case (preparedContact ct', contactRequestId' ct') of
|
||||
(Nothing, Nothing) -> do
|
||||
createInternalChatItem user (CDDirectSnd ct') CIChatBanner (Just epochStart)
|
||||
createE2EItem
|
||||
createFeatureEnabledItems user ct'
|
||||
(Just PreparedContact {connLinkToConnect = ACCL _ (CCLink cReq _)}, _) ->
|
||||
@@ -1337,6 +1338,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
-- they will be updated after connection is accepted.
|
||||
upsertDirectRequestItem cd (requestMsg_, prevSharedMsgId_)
|
||||
Nothing -> do
|
||||
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
|
||||
let e2eContent = CIRcvDirectE2EEInfo $ E2EInfo $ Just $ CR.pqSupportToEnc $ reqPQSup
|
||||
void $ createChatItem user cd False e2eContent Nothing Nothing
|
||||
void $ createFeatureEnabledItems_ user ct
|
||||
@@ -1366,6 +1368,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
-- they will be updated after connection is accepted.
|
||||
upsertBusinessRequestItem cd (requestMsg_, prevSharedMsgId_)
|
||||
Nothing -> do
|
||||
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
|
||||
-- TODO [short links] possibly, we can just keep them created where they are created on the business side due to auto-accept
|
||||
-- let e2eContent = CIRcvGroupE2EEInfo $ E2EInfo $ Just False -- no PQ encryption in groups
|
||||
-- void $ createChatItem user cd False e2eContent Nothing Nothing
|
||||
@@ -2249,6 +2252,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
when (fromMemId == memId) $ throwChatError CEGroupDuplicateMemberId
|
||||
-- [incognito] if direct connection with host is incognito, create membership using the same incognito profile
|
||||
(gInfo@GroupInfo {groupId, localDisplayName, groupProfile, membership}, hostId) <- withStore $ \db -> createGroupInvitation db vr user ct inv customUserProfileId
|
||||
void $ createChatItem user (CDGroupSnd gInfo Nothing) False CIChatBanner Nothing (Just epochStart)
|
||||
let GroupMember {groupMemberId, memberId = membershipMemId} = membership
|
||||
if sameGroupLinkId groupLinkId groupLinkId'
|
||||
then do
|
||||
@@ -3089,6 +3093,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
dm <- encodeConnInfo $ XInfo p
|
||||
joinAgentConnectionAsync user True connReq dm subMode
|
||||
createItems mCt' m' = do
|
||||
createInternalChatItem user (CDDirectSnd mCt') CIChatBanner (Just epochStart)
|
||||
(g', m'', scopeInfo) <- mkGroupChatScope g m'
|
||||
createInternalChatItem user (CDGroupRcv g' scopeInfo m'') (CIRcvGroupEvent RGEMemberCreatedContact) Nothing
|
||||
toView $ CEvtNewMemberContactReceivedInv user mCt' g' m''
|
||||
|
||||
@@ -165,6 +165,7 @@ data CIContent (d :: MsgDirection) where
|
||||
CIRcvDirectE2EEInfo :: E2EInfo -> CIContent 'MDRcv
|
||||
CISndGroupE2EEInfo :: E2EInfo -> CIContent 'MDSnd -- when new group is created
|
||||
CIRcvGroupE2EEInfo :: E2EInfo -> CIContent 'MDRcv -- when enabled with some member
|
||||
CIChatBanner :: CIContent 'MDSnd
|
||||
CIInvalidJSON :: Text -> CIContent d -- this is also used for logical database errors, e.g. SEBadChatItem
|
||||
|
||||
-- ^ This type is used both in API and in DB, so we use different JSON encodings for the database and for the API
|
||||
@@ -292,6 +293,7 @@ ciContentToText = \case
|
||||
CIRcvDirectE2EEInfo e2eeInfo -> directE2EInfoToText e2eeInfo
|
||||
CISndGroupE2EEInfo e2eeInfo -> groupE2EInfoToText e2eeInfo
|
||||
CIRcvGroupE2EEInfo e2eeInfo -> groupE2EInfoToText e2eeInfo
|
||||
CIChatBanner -> "chat banner"
|
||||
CIInvalidJSON _ -> "invalid content JSON"
|
||||
|
||||
directE2EInfoToText :: E2EInfo -> Text
|
||||
@@ -471,6 +473,7 @@ data JSONCIContent
|
||||
| JCIRcvDirectE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| JCISndGroupE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| JCIRcvGroupE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| JCIChatBanner
|
||||
| JCIInvalidJSON {direction :: MsgDirection, json :: Text}
|
||||
|
||||
jsonCIContent :: forall d. MsgDirectionI d => CIContent d -> JSONCIContent
|
||||
@@ -505,6 +508,7 @@ jsonCIContent = \case
|
||||
CIRcvDirectE2EEInfo e2eeInfo -> JCIRcvDirectE2EEInfo e2eeInfo
|
||||
CISndGroupE2EEInfo e2eeInfo -> JCISndGroupE2EEInfo e2eeInfo
|
||||
CIRcvGroupE2EEInfo e2eeInfo -> JCIRcvGroupE2EEInfo e2eeInfo
|
||||
CIChatBanner -> JCIChatBanner
|
||||
CIInvalidJSON json -> JCIInvalidJSON (toMsgDirection $ msgDirection @d) json
|
||||
|
||||
aciContentJSON :: JSONCIContent -> ACIContent
|
||||
@@ -539,6 +543,7 @@ aciContentJSON = \case
|
||||
JCIRcvDirectE2EEInfo {e2eeInfo} -> ACIContent SMDRcv $ CIRcvDirectE2EEInfo e2eeInfo
|
||||
JCISndGroupE2EEInfo {e2eeInfo} -> ACIContent SMDSnd $ CISndGroupE2EEInfo e2eeInfo
|
||||
JCIRcvGroupE2EEInfo {e2eeInfo} -> ACIContent SMDRcv $ CIRcvGroupE2EEInfo e2eeInfo
|
||||
JCIChatBanner -> ACIContent SMDSnd CIChatBanner
|
||||
JCIInvalidJSON dir json -> case fromMsgDirection dir of
|
||||
AMsgDirection d -> ACIContent d $ CIInvalidJSON json
|
||||
|
||||
@@ -574,6 +579,7 @@ data DBJSONCIContent
|
||||
| DBJCIRcvDirectE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| DBJCISndGroupE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| DBJCIRcvGroupE2EEInfo {e2eeInfo :: E2EInfo}
|
||||
| DBJCIChatBanner
|
||||
| DBJCIInvalidJSON {direction :: MsgDirection, json :: Text}
|
||||
|
||||
dbJsonCIContent :: forall d. MsgDirectionI d => CIContent d -> DBJSONCIContent
|
||||
@@ -608,6 +614,7 @@ dbJsonCIContent = \case
|
||||
CIRcvDirectE2EEInfo e2eeInfo -> DBJCIRcvDirectE2EEInfo e2eeInfo
|
||||
CISndGroupE2EEInfo e2eeInfo -> DBJCISndGroupE2EEInfo e2eeInfo
|
||||
CIRcvGroupE2EEInfo e2eeInfo -> DBJCIRcvGroupE2EEInfo e2eeInfo
|
||||
CIChatBanner -> DBJCIChatBanner
|
||||
CIInvalidJSON json -> DBJCIInvalidJSON (toMsgDirection $ msgDirection @d) json
|
||||
|
||||
aciContentDBJSON :: DBJSONCIContent -> ACIContent
|
||||
@@ -642,6 +649,7 @@ aciContentDBJSON = \case
|
||||
DBJCIRcvDirectE2EEInfo e2eeInfo -> ACIContent SMDRcv $ CIRcvDirectE2EEInfo e2eeInfo
|
||||
DBJCISndGroupE2EEInfo e2eeInfo -> ACIContent SMDSnd $ CISndGroupE2EEInfo e2eeInfo
|
||||
DBJCIRcvGroupE2EEInfo e2eeInfo -> ACIContent SMDRcv $ CIRcvGroupE2EEInfo e2eeInfo
|
||||
DBJCIChatBanner -> ACIContent SMDSnd CIChatBanner
|
||||
DBJCIInvalidJSON dir json -> case fromMsgDirection dir of
|
||||
AMsgDirection d -> ACIContent d $ CIInvalidJSON json
|
||||
|
||||
@@ -749,4 +757,5 @@ toCIContentTag ciContent = case ciContent of
|
||||
CIRcvDirectE2EEInfo _ -> "rcvDirectE2EEInfo"
|
||||
CISndGroupE2EEInfo _ -> "sndGroupE2EEInfo"
|
||||
CIRcvGroupE2EEInfo _ -> "rcvGroupE2EEInfo"
|
||||
CIChatBanner -> "chatBanner"
|
||||
CIInvalidJSON _ -> "invalidJSON"
|
||||
|
||||
@@ -191,7 +191,7 @@ deleteContactCIs db user@User {userId} ct@Contact {contactId} = do
|
||||
forM_ connIds $ \connId ->
|
||||
DB.execute db "DELETE FROM messages WHERE connection_id = ?" (Only connId)
|
||||
DB.execute db "DELETE FROM chat_item_reactions WHERE contact_id = ?" (Only contactId)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND contact_id = ?" (userId, contactId)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND item_content_tag != 'chatBanner'" (userId, contactId)
|
||||
|
||||
getContactConnIds_ :: DB.Connection -> User -> Contact -> IO [Int64]
|
||||
getContactConnIds_ db User {userId} Contact {contactId} =
|
||||
@@ -212,7 +212,7 @@ deleteGroupChatItemsMessages :: DB.Connection -> User -> GroupInfo -> IO ()
|
||||
deleteGroupChatItemsMessages db User {userId} GroupInfo {groupId} = do
|
||||
DB.execute db "DELETE FROM messages WHERE group_id = ?" (Only groupId)
|
||||
DB.execute db "DELETE FROM chat_item_reactions WHERE group_id = ?" (Only groupId)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ?" (userId, groupId)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND item_content_tag != 'chatBanner'" (userId, groupId)
|
||||
|
||||
createNewSndMessage :: MsgEncodingI e => DB.Connection -> TVar ChaChaDRG -> ConnOrGroupId -> ChatMsgEvent e -> (SharedMsgId -> EncodedChatMessage) -> ExceptT StoreError IO SndMessage
|
||||
createNewSndMessage db gVar connOrGroupId chatMsgEvent encodeMessage =
|
||||
@@ -3416,7 +3416,7 @@ deleteContactExpiredCIs db user@User {userId} ct@Contact {contactId} expirationD
|
||||
forM_ connIds $ \connId ->
|
||||
DB.execute db "DELETE FROM messages WHERE connection_id = ? AND created_at <= ?" (connId, expirationDate)
|
||||
DB.execute db "DELETE FROM chat_item_reactions WHERE contact_id = ? AND created_at <= ?" (contactId, expirationDate)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ?" (userId, contactId, expirationDate)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ? AND item_content_tag != 'chatBanner'" (userId, contactId, expirationDate)
|
||||
|
||||
getGroupExpiredFileInfo :: DB.Connection -> User -> GroupInfo -> UTCTime -> UTCTime -> IO [CIFileInfo]
|
||||
getGroupExpiredFileInfo db User {userId} GroupInfo {groupId} expirationDate createdAtCutoff =
|
||||
@@ -3430,7 +3430,7 @@ deleteGroupExpiredCIs :: DB.Connection -> User -> GroupInfo -> UTCTime -> UTCTim
|
||||
deleteGroupExpiredCIs db User {userId} GroupInfo {groupId} expirationDate createdAtCutoff = do
|
||||
DB.execute db "DELETE FROM messages WHERE group_id = ? AND created_at <= ?" (groupId, min expirationDate createdAtCutoff)
|
||||
DB.execute db "DELETE FROM chat_item_reactions WHERE group_id = ? AND reaction_ts <= ? AND created_at <= ?" (groupId, expirationDate, createdAtCutoff)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND item_ts <= ? AND created_at <= ?" (userId, groupId, expirationDate, createdAtCutoff)
|
||||
DB.execute db "DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND item_ts <= ? AND created_at <= ? AND item_content_tag != 'chatBanner'" (userId, groupId, expirationDate, createdAtCutoff)
|
||||
|
||||
createCIModeration :: DB.Connection -> GroupInfo -> GroupMember -> MemberId -> SharedMsgId -> MessageId -> UTCTime -> IO ()
|
||||
createCIModeration db GroupInfo {groupId} moderatorMember itemMemberId itemSharedMId msgId moderatedAtTs =
|
||||
|
||||
@@ -555,8 +555,9 @@ Query:
|
||||
INSERT INTO rcv_queues
|
||||
( host, port, rcv_id, conn_id, rcv_private_key, rcv_dh_secret, e2e_priv_key, e2e_dh_secret,
|
||||
snd_id, queue_mode, status, rcv_queue_id, rcv_primary, replace_rcv_queue_id, smp_client_version, server_key_hash,
|
||||
link_id, link_key, link_priv_sig_key, link_enc_fixed_data
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
|
||||
link_id, link_key, link_priv_sig_key, link_enc_fixed_data,
|
||||
ntf_public_key, ntf_private_key, ntf_id, rcv_ntf_dh_secret
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
|
||||
|
||||
Plan:
|
||||
|
||||
@@ -951,6 +952,10 @@ Plan:
|
||||
Query: INSERT INTO xftp_servers (xftp_host, xftp_port, xftp_key_hash) VALUES (?,?,?)
|
||||
Plan:
|
||||
|
||||
Query: SELECT 1 FROM connections WHERE conn_id = ? AND deleted_at_wait_delivery < ? LIMIT 1
|
||||
Plan:
|
||||
SEARCH connections USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query: SELECT 1 FROM encrypted_rcv_message_hashes WHERE conn_id = ? AND hash = ? LIMIT 1
|
||||
Plan:
|
||||
SEARCH encrypted_rcv_message_hashes USING COVERING INDEX idx_encrypted_rcv_message_hashes_hash (conn_id=? AND hash=?)
|
||||
|
||||
@@ -5358,9 +5358,21 @@ SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_chat_item_id (fwd
|
||||
SEARCH files USING COVERING INDEX idx_files_chat_item_id (chat_item_id=?)
|
||||
SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query: DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ?
|
||||
Query: DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND created_at <= ? AND item_content_tag != 'chatBanner'
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_contacts_created_at (user_id=? AND contact_id=? AND created_at<?)
|
||||
SEARCH chat_items USING INDEX idx_chat_items_contacts_created_at (user_id=? AND contact_id=? AND created_at<?)
|
||||
SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?)
|
||||
SEARCH group_snd_item_statuses USING COVERING INDEX idx_group_snd_item_statuses_chat_item_id (chat_item_id=?)
|
||||
SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?)
|
||||
SEARCH calls USING COVERING INDEX idx_calls_chat_item_id (chat_item_id=?)
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_2 (chat_item_id=?)
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_chat_item_id (fwd_from_chat_item_id=?)
|
||||
SEARCH files USING COVERING INDEX idx_files_chat_item_id (chat_item_id=?)
|
||||
SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query: DELETE FROM chat_items WHERE user_id = ? AND contact_id = ? AND item_content_tag != 'chatBanner'
|
||||
Plan:
|
||||
SEARCH chat_items USING INDEX idx_chat_items_contacts_created_at (user_id=? AND contact_id=?)
|
||||
SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?)
|
||||
SEARCH group_snd_item_statuses USING COVERING INDEX idx_group_snd_item_statuses_chat_item_id (chat_item_id=?)
|
||||
SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?)
|
||||
@@ -5394,6 +5406,18 @@ SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_chat_item_id (fwd
|
||||
SEARCH files USING COVERING INDEX idx_files_chat_item_id (chat_item_id=?)
|
||||
SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query: DELETE FROM chat_items WHERE user_id = ? AND group_id = ? AND item_content_tag != 'chatBanner'
|
||||
Plan:
|
||||
SEARCH chat_items USING INDEX idx_chat_items_groups_user_mention (user_id=? AND group_id=?)
|
||||
SEARCH chat_item_mentions USING COVERING INDEX idx_chat_item_mentions_chat_item_id (chat_item_id=?)
|
||||
SEARCH group_snd_item_statuses USING COVERING INDEX idx_group_snd_item_statuses_chat_item_id (chat_item_id=?)
|
||||
SEARCH chat_item_versions USING COVERING INDEX idx_chat_item_versions_chat_item_id (chat_item_id=?)
|
||||
SEARCH calls USING COVERING INDEX idx_calls_chat_item_id (chat_item_id=?)
|
||||
SEARCH chat_item_messages USING COVERING INDEX sqlite_autoindex_chat_item_messages_2 (chat_item_id=?)
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_fwd_from_chat_item_id (fwd_from_chat_item_id=?)
|
||||
SEARCH files USING COVERING INDEX idx_files_chat_item_id (chat_item_id=?)
|
||||
SEARCH groups USING COVERING INDEX idx_groups_chat_item_id (chat_item_id=?)
|
||||
|
||||
Query: DELETE FROM chat_items WHERE user_id = ? AND note_folder_id = ?
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_notes_created_at (user_id=? AND note_folder_id=?)
|
||||
|
||||
Reference in New Issue
Block a user