Add Leave chat button to settings for chat owners (#10764)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -58,7 +58,12 @@ import {InviteLinkDialog} from '../components/InviteLinkDialog'
|
|||||||
import {AddMembersLink} from './AddMembersLink'
|
import {AddMembersLink} from './AddMembersLink'
|
||||||
import {Member, MemberPlaceholder} from './Member'
|
import {Member, MemberPlaceholder} from './Member'
|
||||||
import {MembersAndRequests} from './MembersAndRequests'
|
import {MembersAndRequests} from './MembersAndRequests'
|
||||||
import {EditNamePrompt, LeaveChatPrompt, LockChatPrompt} from './prompts'
|
import {
|
||||||
|
EditNamePrompt,
|
||||||
|
LeaveAndLockChatPrompt,
|
||||||
|
LeaveChatPrompt,
|
||||||
|
LockChatPrompt,
|
||||||
|
} from './prompts'
|
||||||
|
|
||||||
type Item =
|
type Item =
|
||||||
| {type: 'MEMBERS_AND_REQUESTS'; key: string}
|
| {type: 'MEMBERS_AND_REQUESTS'; key: string}
|
||||||
@@ -374,33 +379,49 @@ function SettingsHeader({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const {mutate: lockConvo, isPending: isLocking} = useLockConvo(
|
const {
|
||||||
convo.view.id,
|
mutate: lockConvo,
|
||||||
{
|
mutateAsync: lockConvoAsync,
|
||||||
onSuccess: data => {
|
isPending: isLocking,
|
||||||
if (!ChatBskyConvoDefs.isGroupConvo(data.convo.kind)) return
|
} = useLockConvo(convo.view.id, {
|
||||||
if (data.convo.kind.lockStatus === 'locked') {
|
onSuccess: (data, {silent}) => {
|
||||||
Toast.show(l({message: 'Group chat locked', context: 'toast'}))
|
if (!ChatBskyConvoDefs.isGroupConvo(data.convo.kind)) return
|
||||||
} else {
|
if (silent) return
|
||||||
Toast.show(l({message: 'Group chat unlocked', context: 'toast'}))
|
if (data.convo.kind.lockStatus === 'locked') {
|
||||||
}
|
Toast.show(l({message: 'Group chat locked', context: 'toast'}))
|
||||||
},
|
} else {
|
||||||
onError: (e, {lock}) => {
|
Toast.show(l({message: 'Group chat unlocked', context: 'toast'}))
|
||||||
if (lock) {
|
}
|
||||||
logger.error('Failed to lock group chat', {message: e})
|
|
||||||
Toast.show(l`Failed to lock group chat`, {type: 'error'})
|
|
||||||
} else {
|
|
||||||
logger.error('Failed to unlock group chat', {message: e})
|
|
||||||
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
onError: (e, {lock}) => {
|
||||||
|
if (lock) {
|
||||||
|
logger.error('Failed to lock group chat', {message: e})
|
||||||
|
Toast.show(l`Failed to lock group chat`, {type: 'error'})
|
||||||
|
} else {
|
||||||
|
logger.error('Failed to unlock group chat', {message: e})
|
||||||
|
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const leaveAndLockConvo = async () => {
|
||||||
|
try {
|
||||||
|
if (lockStatus === 'unlocked') {
|
||||||
|
await lockConvoAsync({lock: true, silent: true})
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Handled by onError in useLockConvo
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Owners can only leave a locked chat
|
||||||
|
leaveConvo()
|
||||||
|
}
|
||||||
|
|
||||||
const inviteLinkDialog = Dialog.useDialogControl()
|
const inviteLinkDialog = Dialog.useDialogControl()
|
||||||
const editNamePrompt = Prompt.usePromptControl()
|
const editNamePrompt = Prompt.usePromptControl()
|
||||||
const lockChatPrompt = Prompt.usePromptControl()
|
const lockChatPrompt = Prompt.usePromptControl()
|
||||||
const leaveChatPrompt = Prompt.usePromptControl()
|
const leaveChatPrompt = Prompt.usePromptControl()
|
||||||
|
const leaveAndLockChatPrompt = Prompt.usePromptControl()
|
||||||
const reportControl = Prompt.usePromptControl()
|
const reportControl = Prompt.usePromptControl()
|
||||||
const deleteControl = Prompt.usePromptControl()
|
const deleteControl = Prompt.usePromptControl()
|
||||||
|
|
||||||
@@ -452,6 +473,7 @@ function SettingsHeader({
|
|||||||
a.justify_center,
|
a.justify_center,
|
||||||
a.gap_2xl,
|
a.gap_2xl,
|
||||||
a.pt_2xl,
|
a.pt_2xl,
|
||||||
|
a.flex_wrap,
|
||||||
]}>
|
]}>
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
color={convo.view.muted ? 'negative_subtle' : 'secondary'}
|
color={convo.view.muted ? 'negative_subtle' : 'secondary'}
|
||||||
@@ -517,15 +539,15 @@ function SettingsHeader({
|
|||||||
onPress={reportControl.open}
|
onPress={reportControl.open}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{!isOwner ? (
|
<SettingsButton
|
||||||
<SettingsButton
|
disabled={!isReady || isLeaving || (isOwner && isLocking)}
|
||||||
disabled={!isReady || isLeaving}
|
icon={ArrowBoxLeftIcon}
|
||||||
icon={ArrowBoxLeftIcon}
|
label={l`Leave this group chat`}
|
||||||
label={l`Leave this group chat`}
|
text={l`Leave`}
|
||||||
text={l`Leave`}
|
onPress={
|
||||||
onPress={leaveChatPrompt.open}
|
isOwner ? leaveAndLockChatPrompt.open : leaveChatPrompt.open
|
||||||
/>
|
}
|
||||||
) : null}
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<EditNamePrompt
|
<EditNamePrompt
|
||||||
@@ -552,6 +574,13 @@ function SettingsHeader({
|
|||||||
groupName={groupName}
|
groupName={groupName}
|
||||||
onConfirm={leaveConvo}
|
onConfirm={leaveConvo}
|
||||||
/>
|
/>
|
||||||
|
<LeaveAndLockChatPrompt
|
||||||
|
control={leaveAndLockChatPrompt}
|
||||||
|
groupName={groupName}
|
||||||
|
onConfirm={() => {
|
||||||
|
void leaveAndLockConvo()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{reportSubjectDid ? (
|
{reportSubjectDid ? (
|
||||||
<>
|
<>
|
||||||
<ReportConversationDialog
|
<ReportConversationDialog
|
||||||
@@ -610,6 +639,7 @@ function SettingsButton({
|
|||||||
</Button>
|
</Button>
|
||||||
<Text
|
<Text
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
|
maxFontSizeMultiplier={2.5}
|
||||||
style={[
|
style={[
|
||||||
a.text_xs,
|
a.text_xs,
|
||||||
a.font_medium,
|
a.font_medium,
|
||||||
|
|||||||
@@ -127,6 +127,30 @@ export function LeaveChatPrompt({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function LeaveAndLockChatPrompt({
|
||||||
|
control,
|
||||||
|
groupName,
|
||||||
|
onConfirm,
|
||||||
|
}: {
|
||||||
|
control: Dialog.DialogOuterProps['control']
|
||||||
|
groupName: string
|
||||||
|
onConfirm: () => void
|
||||||
|
}) {
|
||||||
|
const {t: l} = useLingui()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Prompt.Basic
|
||||||
|
control={control}
|
||||||
|
title={l`Are you sure you want to leave ${groupName}?`}
|
||||||
|
description={l`Leaving this chat will lock it permanently and you won’t be able to rejoin.`}
|
||||||
|
confirmButtonCta={l`Leave group chat`}
|
||||||
|
confirmButtonColor="negative"
|
||||||
|
cancelButtonCta={l`Cancel`}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function BlockMemberPrompt({
|
export function BlockMemberPrompt({
|
||||||
control,
|
control,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
|
|||||||
@@ -14,15 +14,21 @@ export function useLockConvo(
|
|||||||
onSuccess,
|
onSuccess,
|
||||||
onError,
|
onError,
|
||||||
}: {
|
}: {
|
||||||
onSuccess?: (data: ChatBskyConvoLockConvo.OutputSchema) => void
|
onSuccess?: (
|
||||||
onError?: (error: Error, variables: {lock: boolean}) => void
|
data: ChatBskyConvoLockConvo.OutputSchema,
|
||||||
|
variables: {lock: boolean; silent?: boolean},
|
||||||
|
) => void
|
||||||
|
onError?: (
|
||||||
|
error: Error,
|
||||||
|
variables: {lock: boolean; silent?: boolean},
|
||||||
|
) => void
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async ({lock}: {lock: boolean}) => {
|
mutationFn: async ({lock}: {lock: boolean; silent?: boolean}) => {
|
||||||
if (!convoId) throw new Error('No convoId provided')
|
if (!convoId) throw new Error('No convoId provided')
|
||||||
if (lock) {
|
if (lock) {
|
||||||
const {data} = await agent.chat.bsky.convo.lockConvo(
|
const {data} = await agent.chat.bsky.convo.lockConvo(
|
||||||
@@ -51,8 +57,8 @@ export function useLockConvo(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onSuccess: data => {
|
onSuccess: (data, variables) => {
|
||||||
onSuccess?.(data)
|
onSuccess?.(data, variables)
|
||||||
},
|
},
|
||||||
onError: (e, variables, context) => {
|
onError: (e, variables, context) => {
|
||||||
if (convoId && context) {
|
if (convoId && context) {
|
||||||
|
|||||||
Reference in New Issue
Block a user