[Chat] Handle moderation lock override in group chats (#10835)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-06-10 21:57:12 +03:00
committed by GitHub
parent 3b5ede37f7
commit 8db30c7d31
8 changed files with 62 additions and 16 deletions
@@ -3,6 +3,7 @@ import {Pressable, View} from 'react-native'
import {
ChatBskyActorDefs,
ChatBskyConvoDefs,
ChatBskyConvoUnlockConvo,
type ModerationOpts,
} from '@atproto/api'
import {Trans, useLingui} from '@lingui/react/macro'
@@ -417,6 +418,12 @@ function SettingsHeader({
if (lock) {
logger.error('Failed to lock group chat', {message: e})
Toast.show(l`Failed to lock group chat`, {type: 'error'})
} else if (
e instanceof ChatBskyConvoUnlockConvo.ConvoLockedByModerationError
) {
Toast.show(l`This chat is locked by a moderation action`, {
type: 'error',
})
} else {
logger.error('Failed to unlock group chat', {message: e})
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
@@ -447,7 +454,11 @@ function SettingsHeader({
const createdAt = new Date(convo.details.createdAt)
const canLockGroupChat = isOwner && lockStatus !== 'locked-permanently'
// A lock forced by a moderation action cannot be undone by the owner.
const canLockGroupChat =
isOwner &&
lockStatus !== 'locked-permanently' &&
!convo.details.lockStatusModerationOverride
const groupNameComponent = (
<Text
@@ -31,6 +31,7 @@ export function ChatFooter({
style={[
a.flex_row,
a.align_center,
a.flex_1,
{
minHeight: 32,
},
@@ -40,7 +41,7 @@ export function ChatFooter({
fill={t.atoms.text_contrast_medium.color}
style={[a.mr_sm]}
/>
<View>
<View style={[a.flex_1]}>
<Text
numberOfLines={1}
style={[
@@ -52,7 +53,7 @@ export function ChatFooter({
</Text>
{subheading ? (
<Text
numberOfLines={1}
numberOfLines={2}
style={[
a.text_xs,
a.leading_snug,
+16 -3
View File
@@ -1,4 +1,5 @@
import {Pressable} from 'react-native'
import {ChatBskyConvoUnlockConvo} from '@atproto/api'
import {Trans, useLingui} from '@lingui/react/macro'
import {StackActions, useNavigation} from '@react-navigation/native'
@@ -32,12 +33,20 @@ export function ChatLocked({
const primaryMember = convo?.primaryMember
const isOwner = !!primaryMember && primaryMember.did === currentAccount?.did
// The lock is forced by a moderation action, so the owner cannot undo it.
const isModerationLock = convo.details.lockStatusModerationOverride
const {mutate: lockConvo} = useLockConvo(convo.view.id, {
onSuccess: () => {
Toast.show(l({message: 'Group chat unlocked', context: 'toast'}))
},
onError: e => {
if (e instanceof ChatBskyConvoUnlockConvo.ConvoLockedByModerationError) {
Toast.show(l`This chat is locked by a moderation action`, {
type: 'error',
})
return
}
logger.error('Failed to unlock group chat', {message: e})
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
},
@@ -59,10 +68,14 @@ export function ChatLocked({
return (
<ChatFooter
heading={l`This chat is locked`}
subheading={l`No one can send messages`}
subheading={
isModerationLock
? l`This group is locked by a moderation action on the owner`
: l`No one can send messages`
}
icon={LockIcon}>
{isOwner ? (
<>
isModerationLock ? null : (
<Pressable
accessibilityRole="button"
hitSlop={HITSLOP_10}
@@ -79,7 +92,7 @@ export function ChatLocked({
<Trans>Unlock chat</Trans>
</Text>
</Pressable>
</>
)
) : (
<>
<Pressable