From cd28ba62a1f5f9d2f11d2467f8b373e592e58bcf Mon Sep 17 00:00:00 2001 From: JRoberts <8711996+jr-simplex@users.noreply.github.com> Date: Mon, 8 Aug 2022 14:13:51 +0400 Subject: [PATCH] core: fix chat pagination filtering (#911) --- src/Simplex/Chat/Store.hs | 92 ++++++++++++--------------------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/src/Simplex/Chat/Store.hs b/src/Simplex/Chat/Store.hs index dfb2a6a7db..f04bfeca09 100644 --- a/src/Simplex/Chat/Store.hs +++ b/src/Simplex/Chat/Store.hs @@ -2956,7 +2956,7 @@ getGroupChatLast_ db user@User {userId} groupId count = do pure $ Chat (GroupChat groupInfo) (reverse chatItems) stats where getGroupChatItemIdsLast_ :: IO [ChatItemId] - getGroupChatItemIdsLast_ = do + getGroupChatItemIdsLast_ = map fromOnly <$> DB.query db @@ -2970,90 +2970,52 @@ getGroupChatLast_ db user@User {userId} groupId count = do (userId, groupId, count) getGroupChatAfter_ :: DB.Connection -> User -> Int64 -> ChatItemId -> Int -> ExceptT StoreError IO (Chat 'CTGroup) -getGroupChatAfter_ db user@User {userId, userContactId} groupId afterChatItemId count = do +getGroupChatAfter_ db user@User {userId} groupId afterChatItemId count = do groupInfo <- getGroupInfo db user groupId stats <- liftIO $ getGroupChatStats_ db userId groupId - chatItems <- ExceptT getGroupChatItemsAfter_ + afterChatItem <- getGroupChatItem db user groupId afterChatItemId + chatItemIds <- liftIO $ getGroupChatItemIdsAfter_ (chatItemTs afterChatItem) + chatItems <- mapM (getGroupChatItem db user groupId) chatItemIds pure $ Chat (GroupChat groupInfo) chatItems stats where - getGroupChatItemsAfter_ :: IO (Either StoreError [CChatItem 'CTGroup]) - getGroupChatItemsAfter_ = do - tz <- getCurrentTimeZone - currentTs <- getCurrentTime - mapM (toGroupChatItem tz currentTs userContactId) + getGroupChatItemIdsAfter_ :: UTCTime -> IO [ChatItemId] + getGroupChatItemIdsAfter_ afterChatItemTs = + map fromOnly <$> DB.query db [sql| - SELECT - -- ChatItem - i.chat_item_id, i.item_ts, i.item_content, i.item_text, i.item_status, i.shared_msg_id, i.item_deleted, i.item_edited, i.created_at, i.updated_at, - -- CIFile - f.file_id, f.file_name, f.file_size, f.file_path, f.ci_file_status, - -- GroupMember - m.group_member_id, m.group_id, m.member_id, m.member_role, m.member_category, - m.member_status, m.invited_by, m.local_display_name, m.contact_id, - p.display_name, p.full_name, p.image, - -- quoted ChatItem - ri.chat_item_id, i.quoted_shared_msg_id, i.quoted_sent_at, i.quoted_content, i.quoted_sent, - -- quoted GroupMember - rm.group_member_id, rm.group_id, rm.member_id, rm.member_role, rm.member_category, - rm.member_status, rm.invited_by, rm.local_display_name, rm.contact_id, - rp.display_name, rp.full_name, rp.image - FROM chat_items i - LEFT JOIN files f ON f.chat_item_id = i.chat_item_id - LEFT JOIN group_members m ON m.group_member_id = i.group_member_id - LEFT JOIN contact_profiles p ON p.contact_profile_id = m.contact_profile_id - LEFT JOIN chat_items ri ON i.quoted_shared_msg_id = ri.shared_msg_id - LEFT JOIN group_members rm ON rm.group_member_id = ri.group_member_id - LEFT JOIN contact_profiles rp ON rp.contact_profile_id = rm.contact_profile_id - WHERE i.user_id = ? AND i.group_id = ? AND i.chat_item_id > ? AND i.item_deleted != 1 - ORDER BY i.item_ts ASC, i.chat_item_id ASC + SELECT chat_item_id + FROM chat_items + WHERE user_id = ? AND group_id = ? AND item_deleted != 1 + AND (item_ts > ? OR (item_ts = ? AND chat_item_id > ?)) + ORDER BY item_ts ASC, chat_item_id ASC LIMIT ? |] - (userId, groupId, afterChatItemId, count) + (userId, groupId, afterChatItemTs, afterChatItemTs, afterChatItemId, count) getGroupChatBefore_ :: DB.Connection -> User -> Int64 -> ChatItemId -> Int -> ExceptT StoreError IO (Chat 'CTGroup) -getGroupChatBefore_ db user@User {userId, userContactId} groupId beforeChatItemId count = do +getGroupChatBefore_ db user@User {userId} groupId beforeChatItemId count = do groupInfo <- getGroupInfo db user groupId stats <- liftIO $ getGroupChatStats_ db userId groupId - chatItems <- ExceptT getGroupChatItemsBefore_ + beforeChatItem <- getGroupChatItem db user groupId beforeChatItemId + chatItemIds <- liftIO $ getGroupChatItemIdsBefore_ (chatItemTs beforeChatItem) + chatItems <- mapM (getGroupChatItem db user groupId) chatItemIds pure $ Chat (GroupChat groupInfo) (reverse chatItems) stats where - getGroupChatItemsBefore_ :: IO (Either StoreError [CChatItem 'CTGroup]) - getGroupChatItemsBefore_ = do - tz <- getCurrentTimeZone - currentTs <- getCurrentTime - mapM (toGroupChatItem tz currentTs userContactId) + getGroupChatItemIdsBefore_ :: UTCTime -> IO [ChatItemId] + getGroupChatItemIdsBefore_ beforeChatItemTs = + map fromOnly <$> DB.query db [sql| - SELECT - -- ChatItem - i.chat_item_id, i.item_ts, i.item_content, i.item_text, i.item_status, i.shared_msg_id, i.item_deleted, i.item_edited, i.created_at, i.updated_at, - -- CIFile - f.file_id, f.file_name, f.file_size, f.file_path, f.ci_file_status, - -- GroupMember - m.group_member_id, m.group_id, m.member_id, m.member_role, m.member_category, - m.member_status, m.invited_by, m.local_display_name, m.contact_id, - p.display_name, p.full_name, p.image, - -- quoted ChatItem - ri.chat_item_id, i.quoted_shared_msg_id, i.quoted_sent_at, i.quoted_content, i.quoted_sent, - -- quoted GroupMember - rm.group_member_id, rm.group_id, rm.member_id, rm.member_role, rm.member_category, - rm.member_status, rm.invited_by, rm.local_display_name, rm.contact_id, - rp.display_name, rp.full_name, rp.image - FROM chat_items i - LEFT JOIN files f ON f.chat_item_id = i.chat_item_id - LEFT JOIN group_members m ON m.group_member_id = i.group_member_id - LEFT JOIN contact_profiles p ON p.contact_profile_id = m.contact_profile_id - LEFT JOIN chat_items ri ON i.quoted_shared_msg_id = ri.shared_msg_id - LEFT JOIN group_members rm ON rm.group_member_id = ri.group_member_id - LEFT JOIN contact_profiles rp ON rp.contact_profile_id = rm.contact_profile_id - WHERE i.user_id = ? AND i.group_id = ? AND i.chat_item_id < ? AND i.item_deleted != 1 - ORDER BY i.item_ts DESC, i.chat_item_id DESC + SELECT chat_item_id + FROM chat_items + WHERE user_id = ? AND group_id = ? AND item_deleted != 1 + AND (item_ts < ? OR (item_ts = ? AND chat_item_id < ?)) + ORDER BY item_ts DESC, chat_item_id DESC LIMIT ? |] - (userId, groupId, beforeChatItemId, count) + (userId, groupId, beforeChatItemTs, beforeChatItemTs, beforeChatItemId, count) getGroupChatStats_ :: DB.Connection -> UserId -> Int64 -> IO ChatStats getGroupChatStats_ db userId groupId =