This commit is contained in:
spaced4ndy
2026-05-14 19:25:27 +04:00
parent 72b9b923f3
commit 46dec681f0
2 changed files with 170 additions and 62 deletions
+29 -19
View File
@@ -1579,6 +1579,12 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
| memberRole >= GRAuthor || memberPending m -> a
| otherwise -> messageError "member is not allowed to send messages" $> Nothing
memberCanComment :: Maybe GroupMember -> CM (Maybe a) -> CM (Maybe a)
memberCanComment Nothing a = a -- channel post from owner via relay - role precheck on the relay
memberCanComment (Just GroupMember {memberRole}) a
| memberRole >= GRCommenter = a
| otherwise = messageError "member is not allowed to comment" $> Nothing
processConnMERR :: ConnectionEntity -> Connection -> AgentErrorType -> CM ()
processConnMERR connEntity conn err = do
case err of
@@ -2020,25 +2026,29 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
Just m@GroupMember {memberId} -> do
(gInfo', m', scopeInfo) <- mkGetMessageChatScope vr user gInfo m content msgScope_
channelMsgInfo_ <- resolveCommentParent gInfo' parent_
if blockedByAdmin m'
then createBlockedByAdmin gInfo' (Just m') scopeInfo $> Nothing
else case prohibitedGroupContent gInfo' m' scopeInfo channelMsgInfo_ content ft_ fInv_ False of
Just GFComments
| not forwarded -> messageError "channel comment prohibited" $> Nothing
Just f -> rejected gInfo' (Just m') scopeInfo f $> Nothing
Nothing -> do
now <- liftIO getCurrentTime
if commentsClosed gInfo' channelMsgInfo_ now
then messageError "channel post comments are closed" $> Nothing
else
withStore' (\db -> getCIModeration db vr user gInfo' memberId sharedMsgId_) >>= \case
Just ciModeration -> do
applyModeration gInfo' m' scopeInfo ciModeration
withStore' $ \db -> deleteCIModeration db gInfo' memberId sharedMsgId_
pure Nothing
Nothing -> do
createContentItem gInfo' (Just m') scopeInfo channelMsgInfo_
pure $ Just $ infoToDeliveryContext gInfo' scopeInfo sentAsGroup
let withCommentRoleCheck = case channelMsgInfo_ of
Just _ -> memberCanComment (Just m')
Nothing -> id
withCommentRoleCheck $
if blockedByAdmin m'
then createBlockedByAdmin gInfo' (Just m') scopeInfo $> Nothing
else case prohibitedGroupContent gInfo' m' scopeInfo channelMsgInfo_ content ft_ fInv_ False of
Just GFComments
| not forwarded -> messageError "channel comment prohibited" $> Nothing
Just f -> rejected gInfo' (Just m') scopeInfo f $> Nothing
Nothing -> do
now <- liftIO getCurrentTime
if commentsClosed gInfo' channelMsgInfo_ now
then messageError "channel post comments are closed" $> Nothing
else
withStore' (\db -> getCIModeration db vr user gInfo' memberId sharedMsgId_) >>= \case
Just ciModeration -> do
applyModeration gInfo' m' scopeInfo ciModeration
withStore' $ \db -> deleteCIModeration db gInfo' memberId sharedMsgId_
pure Nothing
Nothing -> do
createContentItem gInfo' (Just m') scopeInfo channelMsgInfo_
pure $ Just $ infoToDeliveryContext gInfo' scopeInfo sentAsGroup
where
rejected gInfo' m' scopeInfo f = newChatItem gInfo' m' scopeInfo Nothing (ciContentNoParse $ CIRcvGroupFeatureRejected f) Nothing Nothing False
timed_ gInfo' = if forwarded then rcvCITimed_ (Just Nothing) itemTTL else rcvGroupCITimed gInfo' itemTTL
+141 -43
View File
@@ -1776,7 +1776,7 @@ getGroupChatAround' db user g scopeInfo parentChatItemId_ contentFilter aroundId
where
getNavInfo cis_ = case cis_ of
[] -> pure $ NavigationInfo 0 0
cis -> getGroupNavInfo_ db user g (last cis)
cis -> getGroupNavInfo_ db user g scopeInfo parentChatItemId_ (last cis)
getGroupChatInitial_ :: DB.Connection -> User -> GroupInfo -> Maybe GroupChatScopeInfo -> Maybe ChatItemId -> Maybe MsgContentTag -> Int -> ExceptT StoreError IO (Chat 'CTGroup, Maybe NavigationInfo)
getGroupChatInitial_ db user g scopeInfo_ parentChatItemId_ contentFilter count = do
@@ -1862,56 +1862,154 @@ queryUnreadGroupItems db User {userId} GroupInfo {groupId} scopeInfo_ contentFil
(Just _scope, Just _mcTag) ->
throwError $ SEInternalError "group scope and content filter are not supported together"
getGroupNavInfo_ :: DB.Connection -> User -> GroupInfo -> CChatItem 'CTGroup -> IO NavigationInfo
getGroupNavInfo_ db User {userId} GroupInfo {groupId} afterCI = do
getGroupNavInfo_ :: DB.Connection -> User -> GroupInfo -> Maybe GroupChatScopeInfo -> Maybe ChatItemId -> CChatItem 'CTGroup -> IO NavigationInfo
getGroupNavInfo_ db User {userId} GroupInfo {groupId} scopeInfo_ parentChatItemId_ afterCI = do
afterUnread <- getAfterUnreadCount
afterTotal <- getAfterTotalCount
pure NavigationInfo {afterUnread, afterTotal}
where
getAfterUnreadCount :: IO Int
getAfterUnreadCount =
fromOnly . head
<$> DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts > ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts = ? AND chat_item_id > ?
) ci
|]
( (userId, groupId, CISRcvNew, chatItemTs afterCI)
:. (userId, groupId, CISRcvNew, chatItemTs afterCI, cChatItemId afterCI)
)
fromOnly . head <$> case (scopeInfo_, parentChatItemId_) of
(Just _, Just _) ->
error "getGroupNavInfo_: scope and parent are mutually exclusive"
(Nothing, Just pId) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts > ?
AND parent_chat_item_id = ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id = ?
) ci
|]
( (userId, groupId, CISRcvNew, chatItemTs afterCI, pId)
:. (userId, groupId, CISRcvNew, chatItemTs afterCI, cChatItemId afterCI, pId)
)
(Nothing, Nothing) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts > ?
AND parent_chat_item_id IS NULL AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id IS NULL AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL
) ci
|]
( (userId, groupId, CISRcvNew, chatItemTs afterCI)
:. (userId, groupId, CISRcvNew, chatItemTs afterCI, cChatItemId afterCI)
)
(Just GCSIMemberSupport {groupMember_ = m}, Nothing) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts > ?
AND parent_chat_item_id IS NULL AND group_scope_tag = ? AND group_scope_group_member_id IS NOT DISTINCT FROM ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ? AND item_status = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id IS NULL AND group_scope_tag = ? AND group_scope_group_member_id IS NOT DISTINCT FROM ?
) ci
|]
( (userId, groupId, CISRcvNew, chatItemTs afterCI, GCSTMemberSupport_, groupMemberId' <$> m)
:. (userId, groupId, CISRcvNew, chatItemTs afterCI, cChatItemId afterCI, GCSTMemberSupport_, groupMemberId' <$> m)
)
getAfterTotalCount :: IO Int
getAfterTotalCount =
fromOnly . head
<$> DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts > ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts = ? AND chat_item_id > ?
) ci
|]
( (userId, groupId, chatItemTs afterCI)
:. (userId, groupId, chatItemTs afterCI, cChatItemId afterCI)
)
fromOnly . head <$> case (scopeInfo_, parentChatItemId_) of
(Just _, Just _) ->
error "getGroupNavInfo_: scope and parent are mutually exclusive"
(Nothing, Just pId) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts > ?
AND parent_chat_item_id = ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id = ?
) ci
|]
( (userId, groupId, chatItemTs afterCI, pId)
:. (userId, groupId, chatItemTs afterCI, cChatItemId afterCI, pId)
)
(Nothing, Nothing) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts > ?
AND parent_chat_item_id IS NULL AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id IS NULL AND group_scope_tag IS NULL AND group_scope_group_member_id IS NULL
) ci
|]
( (userId, groupId, chatItemTs afterCI)
:. (userId, groupId, chatItemTs afterCI, cChatItemId afterCI)
)
(Just GCSIMemberSupport {groupMember_ = m}, Nothing) ->
DB.query
db
[sql|
SELECT COUNT(1)
FROM (
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts > ?
AND parent_chat_item_id IS NULL AND group_scope_tag = ? AND group_scope_group_member_id IS NOT DISTINCT FROM ?
UNION ALL
SELECT 1
FROM chat_items
WHERE user_id = ? AND group_id = ?
AND item_ts = ? AND chat_item_id > ?
AND parent_chat_item_id IS NULL AND group_scope_tag = ? AND group_scope_group_member_id IS NOT DISTINCT FROM ?
) ci
|]
( (userId, groupId, chatItemTs afterCI, GCSTMemberSupport_, groupMemberId' <$> m)
:. (userId, groupId, chatItemTs afterCI, cChatItemId afterCI, GCSTMemberSupport_, groupMemberId' <$> m)
)
getLocalChat :: DB.Connection -> User -> Int64 -> Maybe MsgContentTag -> ChatPagination -> Maybe Text -> ExceptT StoreError IO (Chat 'CTLocal, Maybe NavigationInfo)
getLocalChat db user folderId contentFilter pagination search_ = do