mirror of
https://github.com/hanzo-io/chat.git
synced 2026-10-30 18:57:58 +00:00
184 lines
6.5 KiB
TypeScript
184 lines
6.5 KiB
TypeScript
import { TouchableOpacity } from 'react-native'
|
|
import ThreeHorizontalDots from '@assets/icons/ThreeHorizontalDots.svg'
|
|
import * as DropdownMenu from 'zeego/dropdown-menu'
|
|
import { Member } from '@raven/lib/hooks/useFetchChannelMembers';
|
|
import { Alert } from 'react-native'
|
|
import { useFrappeDeleteDoc, useFrappePostCall, useSWRConfig } from 'frappe-react-sdk';
|
|
import { toast } from 'sonner-native';
|
|
import { router } from 'expo-router';
|
|
import { useColorScheme } from '@hooks/useColorScheme';
|
|
|
|
const ActionsDropdownMenu = ({ threadID, channelMember }: { threadID: string, channelMember: Member }) => {
|
|
|
|
const { colors } = useColorScheme()
|
|
|
|
const onToggleThreadNotifications = useToggleThreadNotifications(threadID, channelMember)
|
|
|
|
const onLeaveThread = useLeaveThread(threadID)
|
|
const showLeaveThreadAlert = () =>
|
|
Alert.alert(
|
|
'Leave thread?',
|
|
`Are you sure you want to leave this thread?`,
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
style: 'cancel',
|
|
},
|
|
{
|
|
text: 'Leave',
|
|
style: 'destructive',
|
|
onPress: onLeaveThread
|
|
},
|
|
]
|
|
)
|
|
|
|
const onDeleteThread = useDeleteThread(threadID)
|
|
const showDeleteThreadAlert = () =>
|
|
Alert.alert(
|
|
'Delete thread?',
|
|
`Are you sure you want to delete this thread?`,
|
|
[
|
|
{
|
|
text: 'Cancel',
|
|
style: 'cancel',
|
|
},
|
|
{
|
|
text: 'Delete',
|
|
style: 'destructive',
|
|
onPress: onDeleteThread
|
|
},
|
|
]
|
|
)
|
|
|
|
return (
|
|
<DropdownMenu.Root>
|
|
<DropdownMenu.Trigger>
|
|
<TouchableOpacity hitSlop={10} >
|
|
<ThreeHorizontalDots height={20} width={20} color={colors.foreground} />
|
|
</TouchableOpacity>
|
|
</DropdownMenu.Trigger>
|
|
<DropdownMenu.Content>
|
|
<DropdownMenu.Item key="disable-notifications" onSelect={onToggleThreadNotifications}>
|
|
<DropdownMenu.ItemIcon ios={{
|
|
name: channelMember?.allow_notifications ? 'bell.slash' : 'bell',
|
|
pointSize: 16,
|
|
scale: 'medium',
|
|
hierarchicalColor: {
|
|
dark: 'white',
|
|
light: 'black',
|
|
},
|
|
}} />
|
|
<DropdownMenu.ItemTitle>
|
|
{channelMember?.allow_notifications ? 'Unmute' : 'Mute'}
|
|
</DropdownMenu.ItemTitle>
|
|
</DropdownMenu.Item>
|
|
<DropdownMenu.Item key="leave-thread" onSelect={showLeaveThreadAlert}>
|
|
<DropdownMenu.ItemIcon ios={{
|
|
name: 'rectangle.portrait.and.arrow.right',
|
|
pointSize: 14,
|
|
scale: 'medium',
|
|
hierarchicalColor: {
|
|
dark: 'red',
|
|
light: 'red',
|
|
},
|
|
}} />
|
|
<DropdownMenu.ItemTitle >Leave</DropdownMenu.ItemTitle>
|
|
</DropdownMenu.Item>
|
|
{/* Only admins can delete threads */}
|
|
{channelMember.is_admin && <DropdownMenu.Item key="delete-thread" onSelect={showDeleteThreadAlert}>
|
|
<DropdownMenu.ItemIcon ios={{
|
|
name: 'trash',
|
|
pointSize: 14,
|
|
scale: 'medium',
|
|
hierarchicalColor: {
|
|
dark: 'red',
|
|
light: 'red',
|
|
},
|
|
}} />
|
|
<DropdownMenu.ItemTitle>Delete</DropdownMenu.ItemTitle>
|
|
</DropdownMenu.Item>}
|
|
</DropdownMenu.Content>
|
|
</DropdownMenu.Root>
|
|
)
|
|
}
|
|
|
|
const useToggleThreadNotifications = (threadID: string, channelMember: Member) => {
|
|
|
|
const { mutate } = useSWRConfig()
|
|
const { call, error } = useFrappePostCall('raven.api.notification.toggle_push_notification_for_channel')
|
|
|
|
const onToggle = async () => {
|
|
return call({
|
|
member: channelMember?.channel_member_name,
|
|
allow_notifications: channelMember?.allow_notifications ? 0 : 1
|
|
}).then((res) => {
|
|
if (res && res.message) {
|
|
mutate(["channel_members", threadID], (existingMembers: any) => {
|
|
return {
|
|
message: {
|
|
...existingMembers.message,
|
|
[channelMember.name]: {
|
|
...existingMembers.message[channelMember.name],
|
|
allow_notifications: res.message.allow_notifications
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
revalidate: false
|
|
})
|
|
}
|
|
|
|
toast.success(`Thread ${channelMember?.allow_notifications ? 'unmuted' : 'muted'}`)
|
|
}).catch(() => {
|
|
toast.error('Could not toggle thread notifications', {
|
|
description: error?.httpStatusText
|
|
})
|
|
})
|
|
}
|
|
|
|
return onToggle
|
|
}
|
|
|
|
const useLeaveThread = (threadID: string) => {
|
|
|
|
const { call, error } = useFrappePostCall('raven.api.raven_channel.leave_channel')
|
|
const { mutate } = useSWRConfig()
|
|
|
|
const onLeaveThread = async () => {
|
|
return call({ channel_id: threadID })
|
|
.then(() => {
|
|
toast.success(`You have left the thread`)
|
|
router.back()
|
|
mutate(["channel_members", threadID])
|
|
})
|
|
.catch(() => {
|
|
toast.error('Could not leave thread', {
|
|
description: error?.httpStatusText
|
|
})
|
|
})
|
|
}
|
|
|
|
return onLeaveThread
|
|
}
|
|
|
|
const useDeleteThread = (threadID: string) => {
|
|
|
|
const { deleteDoc, error } = useFrappeDeleteDoc()
|
|
|
|
const onDeleteThread = async () => {
|
|
return deleteDoc('Raven Channel', threadID)
|
|
.then(() => {
|
|
toast.success(`Thread has been deleted.`)
|
|
router.back()
|
|
})
|
|
.catch(() => {
|
|
toast.error('Could not delete thread', {
|
|
description: error?.httpStatusText
|
|
})
|
|
})
|
|
}
|
|
|
|
return onDeleteThread
|
|
}
|
|
|
|
export default ActionsDropdownMenu |