swipe action to leave chat

This commit is contained in:
Samuel Newman
2024-10-02 23:37:36 +03:00
parent 00486e9499
commit cef17f1a0a
3 changed files with 228 additions and 170 deletions
@@ -1,4 +1,4 @@
import React, {useCallback, useState} from 'react'
import React, {useCallback, useMemo, useState} from 'react'
import {GestureResponderEvent, View} from 'react-native'
import {
AppBskyActorDefs,
@@ -27,12 +27,15 @@ import {TimeElapsed} from '#/view/com/util/TimeElapsed'
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
import * as tokens from '#/alf/tokens'
import {useDialogControl} from '#/components/Dialog'
import {ConvoMenu} from '#/components/dms/ConvoMenu'
import {LeaveConvoPrompt} from '#/components/dms/LeaveConvoPrompt'
import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/Bell2'
import {Link} from '#/components/Link'
import {useMenuControl} from '#/components/Menu'
import {PostAlerts} from '#/components/moderation/PostAlerts'
import {Text} from '#/components/Typography'
import {SwipeableRow} from './SwipeableRow'
export let ChatListItem = ({
convo,
@@ -74,6 +77,7 @@ function ChatListItemReady({
const {_} = useLingui()
const {currentAccount} = useSession()
const menuControl = useMenuControl()
const leaveConvoControl = useDialogControl()
const {gtMobile} = useBreakpoints()
const profile = useProfileShadow(profileUnshadowed)
const moderation = React.useMemo(
@@ -82,7 +86,7 @@ function ChatListItemReady({
)
const playHaptic = useHaptics()
const blockInfo = React.useMemo(() => {
const blockInfo = useMemo(() => {
const modui = moderation.ui('profileView')
const blocks = modui.alerts.filter(alert => alert.type === 'blocking')
const listBlocks = blocks.filter(alert => alert.source.type === 'list')
@@ -103,7 +107,7 @@ function ChatListItemReady({
const isDimStyle = convo.muted || moderation.blocked || isDeletedAccount
const {lastMessage, lastMessageSentAt} = React.useMemo(() => {
const {lastMessage, lastMessageSentAt} = useMemo(() => {
let lastMessage = _(msg`No messages yet`)
let lastMessageSentAt: string | null = null
@@ -197,13 +201,14 @@ function ChatListItemReady({
}, [playHaptic, menuControl])
return (
<SwipeableRow onDelete={leaveConvoControl.open}>
<View
// @ts-expect-error web only
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onFocus={onFocus}
onBlur={onMouseLeave}
style={[a.relative]}>
style={[a.relative, t.atoms.bg]}>
<View
style={[
a.z_10,
@@ -253,7 +258,8 @@ function ChatListItemReady({
{/* Avatar goes here */}
<View style={{width: 52, height: 52}} />
<View style={[a.flex_1, a.justify_center, web({paddingRight: 45})]}>
<View
style={[a.flex_1, a.justify_center, web({paddingRight: 45})]}>
<View style={[a.w_full, a.flex_row, a.align_end, a.pb_2xs]}>
<Text
numberOfLines={1}
@@ -373,6 +379,12 @@ function ChatListItemReady({
},
]}
/>
<LeaveConvoPrompt
control={leaveConvoControl}
convoId={convo.id}
currentScreen="list"
/>
</View>
</SwipeableRow>
)
}
@@ -0,0 +1,45 @@
import React, {useCallback} from 'react'
import {View} from 'react-native'
// TODO: replace with ReanimatedSwipeable when we next upgrade RNGH -sfn
import Swipeable from 'react-native-gesture-handler/Swipeable'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
import {Trash_Stroke2_Corner2_Rounded as TrashIcon} from '#/components/icons/Trash'
export function SwipeableRow({
children,
onDelete,
}: {
children: React.ReactNode
onDelete: () => void
}) {
const {_} = useLingui()
const t = useTheme()
const renderActions = useCallback(() => {
return (
<Button label={_(msg`Delete chat`)} onPress={onDelete} style={[a.px_lg]}>
<View
style={[
{height: 50, width: 50, backgroundColor: t.palette.negative_400},
a.rounded_full,
a.align_center,
a.justify_center,
]}>
<TrashIcon fill={t.palette.white} size="xl" />
</View>
</Button>
)
}, [_, t, onDelete])
return (
<Swipeable
renderRightActions={renderActions}
containerStyle={[{backgroundColor: t.palette.negative_25}]}>
{children}
</Swipeable>
)
}
@@ -0,0 +1 @@
export {View as SwipeableRow} from 'react-native'