[🐴] Chat muted state (#3988)
* separate out chatlistitem and add muted icon * move bell icon to the right of the timeelapsedzio/stable
parent
9173be686c
commit
bffb9b5906
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="m19.785 8.815 1.034 7.761L7.595 3.352a7.853 7.853 0 0 1 12.19 5.463ZM4 19h3.354c.904 1.748 2.607 3 4.646 3 2.038 0 3.742-1.252 4.646-3h.94l2.707 2.707a1 1 0 0 0 1.414-1.414l-18-18a1 1 0 0 0-1.414 1.414l2.666 2.666a7.842 7.842 0 0 0-.743 2.442l-1.207 9.053A1 1 0 0 0 4 19Zm8 1c-.823 0-1.613-.363-2.222-1h4.443c-.608.637-1.398 1-2.221 1Z" clip-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 478 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M2.293 2.293a1 1 0 0 1 1.414 0l18 18a1 1 0 0 1-1.414 1.414L17.586 19h-.94c-.904 1.748-2.607 3-4.646 3-2.039 0-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053c.116-.87.372-1.69.743-2.442L2.293 3.707a1 1 0 0 1 0-1.414Zm4.19 5.604c-.134.376-.23.772-.285 1.183L5.142 17h10.444L6.483 7.897ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM8.834 2.666a7.853 7.853 0 0 1 10.95 6.15l.645 4.832a1 1 0 0 1-1.983.265l-.644-4.833A5.853 5.853 0 0 0 9.64 4.495a1 1 0 0 1-.807-1.83Z" clip-rule="evenodd"/></svg>
|
After Width: | Height: | Size: 628 B |
|
@ -7,3 +7,11 @@ export const Bell2_Stroke2_Corner0_Rounded = createSinglePathSVG({
|
||||||
export const Bell2_Filled_Corner0_Rounded = createSinglePathSVG({
|
export const Bell2_Filled_Corner0_Rounded = createSinglePathSVG({
|
||||||
path: 'M12 2a7.307 7.307 0 0 0-7.298 6.943l-.19 3.798-1.321 2.641A1.809 1.809 0 0 0 4.809 18H7.1a5.002 5.002 0 0 0 9.8 0h2.291a1.809 1.809 0 0 0 1.618-2.618l-1.32-2.641-.19-3.798A7.308 7.308 0 0 0 12 2Zm0 18a3.001 3.001 0 0 1-2.83-2h5.66A3.001 3.001 0 0 1 12 20Z',
|
path: 'M12 2a7.307 7.307 0 0 0-7.298 6.943l-.19 3.798-1.321 2.641A1.809 1.809 0 0 0 4.809 18H7.1a5.002 5.002 0 0 0 9.8 0h2.291a1.809 1.809 0 0 0 1.618-2.618l-1.32-2.641-.19-3.798A7.308 7.308 0 0 0 12 2Zm0 18a3.001 3.001 0 0 1-2.83-2h5.66A3.001 3.001 0 0 1 12 20Z',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const Bell2Off_Stroke2_Corner0_Rounded = createSinglePathSVG({
|
||||||
|
path: 'M2.293 2.293a1 1 0 0 1 1.414 0l18 18a1 1 0 0 1-1.414 1.414L17.586 19h-.94c-.904 1.748-2.607 3-4.646 3-2.039 0-3.742-1.252-4.646-3H4a1 1 0 0 1-.991-1.132l1.207-9.053c.116-.87.372-1.69.743-2.442L2.293 3.707a1 1 0 0 1 0-1.414Zm4.19 5.604c-.134.376-.23.772-.285 1.183L5.142 17h10.444L6.483 7.897ZM9.778 19c.61.637 1.399 1 2.222 1s1.613-.363 2.222-1H9.778ZM8.834 2.666a7.853 7.853 0 0 1 10.95 6.15l.645 4.832a1 1 0 0 1-1.983.265l-.644-4.833A5.853 5.853 0 0 0 9.64 4.495a1 1 0 0 1-.807-1.83Z',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const Bell2Off_Filled_Corner0_Rounded = createSinglePathSVG({
|
||||||
|
path: 'm19.785 8.815 1.034 7.761L7.595 3.352a7.853 7.853 0 0 1 12.19 5.463ZM4 19h3.354c.904 1.748 2.607 3 4.646 3 2.038 0 3.742-1.252 4.646-3h.94l2.707 2.707a1 1 0 0 0 1.414-1.414l-18-18a1 1 0 0 0-1.414 1.414l2.666 2.666a7.842 7.842 0 0 0-.743 2.442l-1.207 9.053A1 1 0 0 0 4 19Zm8 1c-.823 0-1.613-.363-2.222-1h4.443c-.608.637-1.398 1-2.221 1Z',
|
||||||
|
})
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import {ChatBskyConvoDefs} from '@atproto-labs/api'
|
||||||
|
import {msg} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
|
import {isNative} from '#/platform/detection'
|
||||||
|
import {useSession} from '#/state/session'
|
||||||
|
import {TimeElapsed} from '#/view/com/util/TimeElapsed'
|
||||||
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
|
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||||
|
import {Button} from '#/components/Button'
|
||||||
|
import {ConvoMenu} from '#/components/dms/ConvoMenu'
|
||||||
|
import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/Bell2'
|
||||||
|
import {useMenuControl} from '#/components/Menu'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
|
export function ChatListItem({
|
||||||
|
convo,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
convo: ChatBskyConvoDefs.ConvoView
|
||||||
|
index: number
|
||||||
|
}) {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
const {currentAccount} = useSession()
|
||||||
|
const menuControl = useMenuControl()
|
||||||
|
const {gtMobile} = useBreakpoints()
|
||||||
|
|
||||||
|
let lastMessage = _(msg`No messages yet`)
|
||||||
|
let lastMessageSentAt: string | null = null
|
||||||
|
if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
|
||||||
|
if (convo.lastMessage.sender?.did === currentAccount?.did) {
|
||||||
|
lastMessage = _(msg`You: ${convo.lastMessage.text}`)
|
||||||
|
} else {
|
||||||
|
lastMessage = convo.lastMessage.text
|
||||||
|
}
|
||||||
|
lastMessageSentAt = convo.lastMessage.sentAt
|
||||||
|
}
|
||||||
|
if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) {
|
||||||
|
lastMessage = _(msg`Message deleted`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const otherUser = convo.members.find(
|
||||||
|
member => member.did !== currentAccount?.did,
|
||||||
|
)
|
||||||
|
|
||||||
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
const [showActions, setShowActions] = React.useState(false)
|
||||||
|
|
||||||
|
const onMouseEnter = React.useCallback(() => {
|
||||||
|
setShowActions(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onMouseLeave = React.useCallback(() => {
|
||||||
|
setShowActions(false)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onFocus = React.useCallback<React.FocusEventHandler>(e => {
|
||||||
|
if (e.nativeEvent.relatedTarget == null) return
|
||||||
|
setShowActions(true)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onPress = React.useCallback(() => {
|
||||||
|
navigation.push('MessagesConversation', {
|
||||||
|
conversation: convo.id,
|
||||||
|
})
|
||||||
|
}, [convo.id, navigation])
|
||||||
|
|
||||||
|
if (!otherUser) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
// @ts-expect-error web only
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
onMouseLeave={onMouseLeave}
|
||||||
|
onFocus={onFocus}
|
||||||
|
onBlur={onMouseLeave}>
|
||||||
|
<Button
|
||||||
|
label={otherUser.displayName || otherUser.handle}
|
||||||
|
onPress={onPress}
|
||||||
|
style={a.flex_1}
|
||||||
|
onLongPress={isNative ? menuControl.open : undefined}>
|
||||||
|
{({hovered, pressed}) => (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.flex_1,
|
||||||
|
a.px_lg,
|
||||||
|
a.py_md,
|
||||||
|
a.gap_md,
|
||||||
|
(hovered || pressed) && t.atoms.bg_contrast_25,
|
||||||
|
index === 0 && [a.border_t, a.pt_lg],
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
]}>
|
||||||
|
<UserAvatar avatar={otherUser?.avatar} size={52} />
|
||||||
|
<View style={[a.flex_1, a.flex_row, a.align_center]}>
|
||||||
|
<View style={[a.flex_1]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_1,
|
||||||
|
a.flex_row,
|
||||||
|
a.align_end,
|
||||||
|
a.pb_2xs,
|
||||||
|
web([{marginTop: -2}]),
|
||||||
|
]}>
|
||||||
|
<Text
|
||||||
|
numberOfLines={1}
|
||||||
|
style={[{maxWidth: '85%'}, web([a.leading_normal])]}>
|
||||||
|
<Text style={[a.text_md, t.atoms.text, a.font_bold]}>
|
||||||
|
{otherUser.displayName || otherUser.handle}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
{lastMessageSentAt && (
|
||||||
|
<TimeElapsed timestamp={lastMessageSentAt}>
|
||||||
|
{({timeElapsed}) => (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_sm,
|
||||||
|
web([a.leading_normal, {whiteSpace: 'pre'}]),
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
{' '}
|
||||||
|
· {timeElapsed}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</TimeElapsed>
|
||||||
|
)}
|
||||||
|
{convo.muted && (
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_sm,
|
||||||
|
web([a.leading_normal, {whiteSpace: 'pre'}]),
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
{' '}
|
||||||
|
·{' '}
|
||||||
|
<BellStroke
|
||||||
|
size="xs"
|
||||||
|
style={t.atoms.text_contrast_medium}
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
numberOfLines={1}
|
||||||
|
style={[a.text_sm, t.atoms.text_contrast_medium, a.pb_xs]}>
|
||||||
|
@{otherUser.handle}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
numberOfLines={2}
|
||||||
|
style={[
|
||||||
|
a.text_sm,
|
||||||
|
a.leading_snug,
|
||||||
|
convo.unreadCount > 0
|
||||||
|
? a.font_bold
|
||||||
|
: t.atoms.text_contrast_high,
|
||||||
|
convo.muted && t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
{lastMessage}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
{convo.unreadCount > 0 && (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.absolute,
|
||||||
|
a.rounded_full,
|
||||||
|
{
|
||||||
|
backgroundColor: convo.muted
|
||||||
|
? t.palette.contrast_200
|
||||||
|
: t.palette.primary_500,
|
||||||
|
height: 7,
|
||||||
|
width: 7,
|
||||||
|
},
|
||||||
|
isNative
|
||||||
|
? {
|
||||||
|
top: 15,
|
||||||
|
right: 12,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<ConvoMenu
|
||||||
|
convo={convo}
|
||||||
|
profile={otherUser}
|
||||||
|
control={menuControl}
|
||||||
|
currentScreen="list"
|
||||||
|
showMarkAsRead={convo.unreadCount > 0}
|
||||||
|
hideTrigger={isNative}
|
||||||
|
triggerOpacity={
|
||||||
|
!gtMobile || showActions || menuControl.isOpen ? 1 : 0
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,28 +3,22 @@ import {View} from 'react-native'
|
||||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
import {sha256} from 'js-sha256'
|
import {sha256} from 'js-sha256'
|
||||||
|
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {MessagesTabNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
import {MessagesTabNavigatorParams} from '#/lib/routes/types'
|
||||||
import {useGate} from '#/lib/statsig/statsig'
|
import {useGate} from '#/lib/statsig/statsig'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isNative} from '#/platform/detection'
|
|
||||||
import {useListConvos} from '#/state/queries/messages/list-converations'
|
import {useListConvos} from '#/state/queries/messages/list-converations'
|
||||||
import {useSession} from '#/state/session'
|
|
||||||
import {List} from '#/view/com/util/List'
|
import {List} from '#/view/com/util/List'
|
||||||
import {TimeElapsed} from '#/view/com/util/TimeElapsed'
|
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
|
||||||
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
||||||
import {CenteredView} from '#/view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {ScrollView} from '#/view/com/util/Views'
|
import {ScrollView} from '#/view/com/util/Views'
|
||||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {DialogControlProps, useDialogControl} from '#/components/Dialog'
|
import {DialogControlProps, useDialogControl} from '#/components/Dialog'
|
||||||
import {ConvoMenu} from '#/components/dms/ConvoMenu'
|
|
||||||
import {NewChat} from '#/components/dms/NewChat'
|
import {NewChat} from '#/components/dms/NewChat'
|
||||||
import * as TextField from '#/components/forms/TextField'
|
import * as TextField from '#/components/forms/TextField'
|
||||||
import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus'
|
import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus'
|
||||||
|
@ -32,10 +26,10 @@ import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus
|
||||||
import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider'
|
import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider'
|
||||||
import {Link} from '#/components/Link'
|
import {Link} from '#/components/Link'
|
||||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||||
import {useMenuControl} from '#/components/Menu'
|
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {ClipClopGate} from '../gate'
|
import {ClipClopGate} from '../gate'
|
||||||
import {useDmServiceUrlStorage} from '../Temp/useDmServiceUrlStorage'
|
import {useDmServiceUrlStorage} from '../Temp/useDmServiceUrlStorage'
|
||||||
|
import {ChatListItem} from './ChatListItem'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<MessagesTabNavigatorParams, 'Messages'>
|
type Props = NativeStackScreenProps<MessagesTabNavigatorParams, 'Messages'>
|
||||||
|
|
||||||
|
@ -255,181 +249,6 @@ export function MessagesScreen({navigation, route}: Props) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ChatListItem({
|
|
||||||
convo,
|
|
||||||
index,
|
|
||||||
}: {
|
|
||||||
convo: ChatBskyConvoDefs.ConvoView
|
|
||||||
index: number
|
|
||||||
}) {
|
|
||||||
const t = useTheme()
|
|
||||||
const {_} = useLingui()
|
|
||||||
const {currentAccount} = useSession()
|
|
||||||
const menuControl = useMenuControl()
|
|
||||||
const {gtMobile} = useBreakpoints()
|
|
||||||
|
|
||||||
let lastMessage = _(msg`No messages yet`)
|
|
||||||
let lastMessageSentAt: string | null = null
|
|
||||||
if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
|
|
||||||
if (convo.lastMessage.sender?.did === currentAccount?.did) {
|
|
||||||
lastMessage = _(msg`You: ${convo.lastMessage.text}`)
|
|
||||||
} else {
|
|
||||||
lastMessage = convo.lastMessage.text
|
|
||||||
}
|
|
||||||
lastMessageSentAt = convo.lastMessage.sentAt
|
|
||||||
}
|
|
||||||
if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) {
|
|
||||||
lastMessage = _(msg`Message deleted`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const otherUser = convo.members.find(
|
|
||||||
member => member.did !== currentAccount?.did,
|
|
||||||
)
|
|
||||||
|
|
||||||
const navigation = useNavigation<NavigationProp>()
|
|
||||||
const [showActions, setShowActions] = React.useState(false)
|
|
||||||
|
|
||||||
const onMouseEnter = React.useCallback(() => {
|
|
||||||
setShowActions(true)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onMouseLeave = React.useCallback(() => {
|
|
||||||
setShowActions(false)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onFocus = React.useCallback<React.FocusEventHandler>(e => {
|
|
||||||
if (e.nativeEvent.relatedTarget == null) return
|
|
||||||
setShowActions(true)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onPress = React.useCallback(() => {
|
|
||||||
navigation.push('MessagesConversation', {
|
|
||||||
conversation: convo.id,
|
|
||||||
})
|
|
||||||
}, [convo.id, navigation])
|
|
||||||
|
|
||||||
if (!otherUser) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
// @ts-expect-error web only
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
onFocus={onFocus}
|
|
||||||
onBlur={onMouseLeave}>
|
|
||||||
<Button
|
|
||||||
label={otherUser.displayName || otherUser.handle}
|
|
||||||
onPress={onPress}
|
|
||||||
style={a.flex_1}
|
|
||||||
onLongPress={isNative ? menuControl.open : undefined}>
|
|
||||||
{({hovered, pressed}) => (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
a.flex_row,
|
|
||||||
a.flex_1,
|
|
||||||
a.px_lg,
|
|
||||||
a.py_md,
|
|
||||||
a.gap_md,
|
|
||||||
(hovered || pressed) && t.atoms.bg_contrast_25,
|
|
||||||
index === 0 && [a.border_t, a.pt_lg],
|
|
||||||
t.atoms.border_contrast_low,
|
|
||||||
]}>
|
|
||||||
<UserAvatar avatar={otherUser?.avatar} size={52} />
|
|
||||||
<View style={[a.flex_1, a.flex_row, a.align_center]}>
|
|
||||||
<View style={[a.flex_1]}>
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
a.flex_1,
|
|
||||||
a.flex_row,
|
|
||||||
a.align_end,
|
|
||||||
a.pb_2xs,
|
|
||||||
web([{marginTop: -2}]),
|
|
||||||
]}>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={[{maxWidth: '85%'}, web([a.leading_normal])]}>
|
|
||||||
<Text style={[a.text_md, t.atoms.text, a.font_bold]}>
|
|
||||||
{otherUser.displayName || otherUser.handle}
|
|
||||||
</Text>
|
|
||||||
</Text>
|
|
||||||
{lastMessageSentAt && (
|
|
||||||
<TimeElapsed timestamp={lastMessageSentAt}>
|
|
||||||
{({timeElapsed}) => (
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
a.text_sm,
|
|
||||||
web([a.leading_normal]),
|
|
||||||
t.atoms.text_contrast_medium,
|
|
||||||
]}>
|
|
||||||
{' '}
|
|
||||||
· {timeElapsed}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</TimeElapsed>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={[a.text_sm, t.atoms.text_contrast_medium, a.pb_xs]}>
|
|
||||||
@{otherUser.handle}
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
numberOfLines={2}
|
|
||||||
style={[
|
|
||||||
a.text_sm,
|
|
||||||
a.leading_snug,
|
|
||||||
convo.unreadCount > 0
|
|
||||||
? a.font_bold
|
|
||||||
: t.atoms.text_contrast_high,
|
|
||||||
]}>
|
|
||||||
{lastMessage}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
{convo.unreadCount > 0 && (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
a.absolute,
|
|
||||||
a.rounded_full,
|
|
||||||
{
|
|
||||||
backgroundColor: convo.muted
|
|
||||||
? t.palette.contrast_200
|
|
||||||
: t.palette.primary_500,
|
|
||||||
height: 7,
|
|
||||||
width: 7,
|
|
||||||
},
|
|
||||||
isNative
|
|
||||||
? {
|
|
||||||
top: 15,
|
|
||||||
right: 12,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
top: 0,
|
|
||||||
right: 0,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<ConvoMenu
|
|
||||||
convo={convo}
|
|
||||||
profile={otherUser}
|
|
||||||
control={menuControl}
|
|
||||||
currentScreen="list"
|
|
||||||
showMarkAsRead={convo.unreadCount > 0}
|
|
||||||
hideTrigger={isNative}
|
|
||||||
triggerOpacity={
|
|
||||||
!gtMobile || showActions || menuControl.isOpen ? 1 : 0
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function DesktopHeader({
|
function DesktopHeader({
|
||||||
newChatControl,
|
newChatControl,
|
||||||
onNavigateToSettings,
|
onNavigateToSettings,
|
||||||
|
|
Loading…
Reference in New Issue