fix mark read

This commit is contained in:
spaced4ndy
2025-09-05 14:46:58 +04:00
parent 59e8748be4
commit ad78155479
6 changed files with 72 additions and 34 deletions
+1
View File
@@ -162,6 +162,7 @@ undocumentedResponses =
"CRGroupUserChanged",
"CRItemsReadForChat",
"CRJoinedGroupMember",
"CRMemberSupportChatRead",
"CRMemberSupportChatDeleted",
"CRMemberSupportChats",
"CRNetworkConfig",
+1
View File
@@ -726,6 +726,7 @@ data ChatResponse
| CRNetworkStatuses {user_ :: Maybe User, networkStatuses :: [ConnNetworkStatus]}
| CRJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
| CRMemberAccepted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
| CRMemberSupportChatRead {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
| CRMemberSupportChatDeleted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
| CRMembersRoleUser {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], toRole :: GroupMemberRole}
| CRMembersBlockedForAllUser {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], blocked :: Bool}
+17 -6
View File
@@ -1042,12 +1042,23 @@ processChatCommand vr nm = \case
gInfo <- getGroupInfo db vr user chatId
pure (user, gInfo)
ts <- liftIO getCurrentTime
timedItems <- withFastStore' $ \db -> do
timedItems <- getGroupUnreadTimedItems db user chatId scope
updateGroupChatItemsRead db user gInfo scope
setGroupChatItemsDeleteAt db user chatId timedItems ts
forM_ timedItems $ \(itemId, deleteAt) -> startProximateTimedItemThread user (chatRef, itemId) deleteAt
ok user
chatScopeInfo <- mapM (getChatScopeInfo vr user) scope
case chatScopeInfo of
Nothing -> do
timedItems <- withFastStore' $ \db -> do
timedItems <- getGroupUnreadTimedItems db user chatId scope
updateGroupChatItemsRead db user gInfo
setGroupChatItemsDeleteAt db user chatId timedItems ts
forM_ timedItems $ \(itemId, deleteAt) -> startProximateTimedItemThread user (chatRef, itemId) deleteAt
ok user
Just scopeInfo -> do
(gInfo', m', timedItems) <- withFastStore' $ \db -> do
timedItems <- getGroupUnreadTimedItems db user chatId scope
(gInfo', m') <- updateSupportChatItemsRead db vr user gInfo scopeInfo
timedItems' <- setGroupChatItemsDeleteAt db user chatId timedItems ts
pure (gInfo', m', timedItems')
forM_ timedItems $ \(itemId, deleteAt) -> startProximateTimedItemThread user (chatRef, itemId) deleteAt
pure $ CRMemberSupportChatRead user gInfo' m'
CTLocal -> do
user <- withFastStore $ \db -> getUserByNoteFolderId db chatId
withFastStore' $ \db -> updateLocalChatItemsRead db user chatId
+35 -16
View File
@@ -80,6 +80,7 @@ module Simplex.Chat.Store.Messages
setDirectChatItemRead,
setDirectChatItemsDeleteAt,
updateGroupChatItemsRead,
updateSupportChatItemsRead,
getGroupUnreadTimedItems,
updateGroupChatItemsReadList,
updateGroupScopeUnreadStats,
@@ -2018,20 +2019,23 @@ setDirectChatItemsDeleteAt db User {userId} contactId itemIds currentTs = forM i
(deleteAt, userId, contactId, chatItemId)
pure (chatItemId, deleteAt)
updateGroupChatItemsRead :: DB.Connection -> User -> GroupInfo -> Maybe GroupChatScope -> IO ()
updateGroupChatItemsRead db User {userId} GroupInfo {groupId, membership} scope = do
updateGroupChatItemsRead :: DB.Connection -> User -> GroupInfo -> IO ()
updateGroupChatItemsRead db User {userId} GroupInfo {groupId, membership} = do
currentTs <- getCurrentTime
case scope of
Nothing ->
DB.execute
db
[sql|
UPDATE chat_items SET item_status = ?, updated_at = ?
WHERE user_id = ? AND group_id = ?
AND item_status = ?
|]
(CISRcvRead, currentTs, userId, groupId, CISRcvNew)
Just GCSMemberSupport {groupMemberId_} -> do
DB.execute
db
[sql|
UPDATE chat_items SET item_status = ?, updated_at = ?
WHERE user_id = ? AND group_id = ?
AND item_status = ?
|]
(CISRcvRead, currentTs, userId, groupId, CISRcvNew)
updateSupportChatItemsRead :: DB.Connection -> VersionRangeChat -> User -> GroupInfo -> GroupChatScopeInfo -> IO (GroupInfo, GroupMember)
updateSupportChatItemsRead db vr user@User {userId} g@GroupInfo {groupId, membership} scopeInfo = do
currentTs <- getCurrentTime
case scopeInfo of
GCSIMemberSupport {groupMember_} -> do
DB.execute
db
[sql|
@@ -2040,8 +2044,21 @@ updateGroupChatItemsRead db User {userId} GroupInfo {groupId, membership} scope
AND group_scope_tag = ? AND group_scope_group_member_id IS NOT DISTINCT FROM ?
AND item_status = ?
|]
(CISRcvRead, currentTs, userId, groupId, GCSTMemberSupport_, groupMemberId_, CISRcvNew)
let gmId = fromMaybe (groupMemberId' membership) groupMemberId_
(CISRcvRead, currentTs, userId, groupId, GCSTMemberSupport_, groupMemberId' <$> groupMember_, CISRcvNew)
case groupMember_ of
Nothing -> do
membership' <- updateGMStats membership
pure (g {membership = membership'}, membership')
Just member -> do
member' <- updateGMStats member
let didRequire = gmRequiresAttention member
nowRequires = gmRequiresAttention member'
if (not nowRequires && didRequire)
then (,member') <$> decreaseGroupMembersRequireAttention db user g
else pure (g, member')
where
updateGMStats m@GroupMember {groupMemberId} = do
currentTs <- getCurrentTime
DB.execute
db
[sql|
@@ -2051,7 +2068,9 @@ updateGroupChatItemsRead db User {userId} GroupInfo {groupId, membership} scope
support_chat_items_mentions = 0
WHERE group_member_id = ?
|]
(Only gmId)
(Only groupMemberId)
m_ <- runExceptT $ getGroupMemberById db vr user groupMemberId
pure $ either (const m) id m_ -- Left shouldn't happen, but types require it
getGroupUnreadTimedItems :: DB.Connection -> User -> GroupId -> Maybe GroupChatScope -> IO [(ChatItemId, Int)]
getGroupUnreadTimedItems db User {userId} groupId scope =
+1
View File
@@ -231,6 +231,7 @@ chatResponseToView hu cfg@ChatConfig {logLevel, showReactions, testView} liveIte
CRNetworkStatuses u statuses -> if testView then ttyUser' u $ viewNetworkStatuses statuses else []
CRJoinedGroupMember u g m -> ttyUser u $ viewJoinedGroupMember g m
CRMemberAccepted u g m -> ttyUser u $ viewMemberAccepted g m
CRMemberSupportChatRead u g m -> ttyUser u [ttyGroup' g <> ": " <> ttyMember m <> " support chat read"]
CRMemberSupportChatDeleted u g m -> ttyUser u [ttyGroup' g <> ": " <> ttyMember m <> " support chat deleted"]
CRMembersRoleUser u g members r' -> ttyUser u $ viewMemberRoleUserChanged g members r'
CRMembersBlockedForAllUser u g members blocked -> ttyUser u $ viewMembersBlockedForAllUser g members blocked
+17 -12
View File
@@ -220,7 +220,7 @@ chatGroupTests = do
it "should send messages to admins and members" testSupportCLISendCommand
it "should correctly maintain unread stats for support chats on reading chat items" testScopedSupportUnreadStatsOnRead
it "should correctly maintain unread stats for support chats on deleting chat items" testScopedSupportUnreadStatsOnDelete
fit "should correct member attention stat for support chat on opening it" testScopedSupportUnreadStatsCorrectOnOpen
it "should correct member attention stat for support chat on opening it" testScopedSupportUnreadStatsCorrectOnOpen
testGroupCheckMessages :: HasCallStack => TestParams -> IO ()
testGroupCheckMessages =
@@ -8008,19 +8008,22 @@ testScopedSupportUnreadStatsOnRead =
bob ##> "/member support chats #team"
bob <## "support: unread: 4, require attention: 0, mentions: 1"
alice #$> ("/_read chat #1(_support:2)", id, "ok")
alice ##> "/_read chat #1(_support:2)"
alice <## "#team: bob support chat read"
alice ##> "/member support chats #team"
alice <## "members require attention: 0"
alice <## "bob (Bob) (id 2): unread: 0, require attention: 0, mentions: 0"
dan #$> ("/_read chat #1(_support:3)", id, "ok")
dan ##> "/_read chat #1(_support:3)"
dan <## "#team: bob support chat read"
dan ##> "/member support chats #team"
dan <## "members require attention: 1" -- TODO fix mark read: 0
dan <## "members require attention: 0"
dan <## "bob (Bob) (id 3): unread: 0, require attention: 0, mentions: 0"
bob #$> ("/_read chat #1(_support)", id, "ok")
bob ##> "/_read chat #1(_support)"
bob <## "#team: bob support chat read"
bob ##> "/member support chats #team"
bob <## "support: unread: 0, require attention: 0, mentions: 0"
@@ -8081,10 +8084,11 @@ testScopedSupportUnreadStatsCorrectOnOpen =
alice <## "members require attention: 1"
alice <## "bob (Bob) (id 2): unread: 2, require attention: 2, mentions: 0"
alice #$> ("/_read chat #1(_support:2)", id, "ok")
alice ##> "/_read chat #1(_support:2)"
alice <## "#team: bob support chat read"
alice ##> "/member support chats #team"
alice <## "members require attention: 1" -- TODO fix mark read: 0
alice <## "members require attention: 0"
alice <## "bob (Bob) (id 2): unread: 0, require attention: 0, mentions: 0"
bob #> "#team (support) 3"
@@ -8097,26 +8101,27 @@ testScopedSupportUnreadStatsCorrectOnOpen =
alice <# "#team (support: bob) bob> 5"
alice ##> "/member support chats #team"
alice <## "members require attention: 2" -- TODO fix mark read: 1
alice <## "members require attention: 1"
alice <## "bob (Bob) (id 2): unread: 3, require attention: 3, mentions: 0"
void $ withCCTransaction alice $ \db ->
DB.execute db "UPDATE group_members SET support_chat_items_member_attention=100 WHERE group_member_id=?" (Only (2 :: Int64))
alice ##> "/member support chats #team"
alice <## "members require attention: 2" -- TODO fix mark read: 1
alice <## "members require attention: 1"
alice <## "bob (Bob) (id 2): unread: 3, require attention: 100, mentions: 0"
alice #$> ("/_get chat #1(_support:2) count=100", chat, [(0, "1"), (0, "2"), (0, "3"), (0, "4"), (0, "5")])
alice ##> "/member support chats #team"
alice <## "members require attention: 2" -- TODO fix mark read: 1
alice <## "members require attention: 1"
alice <## "bob (Bob) (id 2): unread: 3, require attention: 3, mentions: 0"
alice #$> ("/_read chat #1(_support:2)", id, "ok")
alice ##> "/_read chat #1(_support:2)"
alice <## "#team: bob support chat read"
alice ##> "/member support chats #team"
alice <## "members require attention: 2" -- TODO fix mark read: 0
alice <## "members require attention: 0"
alice <## "bob (Bob) (id 2): unread: 0, require attention: 0, mentions: 0"
where
opts =