diff --git a/assets/icons/bellOff_filled_corner0_rounded.svg b/assets/icons/bellOff_filled_corner0_rounded.svg
new file mode 100644
index 00000000..4c6997a7
--- /dev/null
+++ b/assets/icons/bellOff_filled_corner0_rounded.svg
@@ -0,0 +1 @@
+
diff --git a/assets/icons/bellOff_stroke2_corner0_rounded.svg b/assets/icons/bellOff_stroke2_corner0_rounded.svg
new file mode 100644
index 00000000..0ed4910d
--- /dev/null
+++ b/assets/icons/bellOff_stroke2_corner0_rounded.svg
@@ -0,0 +1 @@
+
diff --git a/src/components/icons/Bell2.tsx b/src/components/icons/Bell2.tsx
index 084445b1..f3d46d09 100644
--- a/src/components/icons/Bell2.tsx
+++ b/src/components/icons/Bell2.tsx
@@ -7,3 +7,11 @@ export const Bell2_Stroke2_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',
})
+
+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',
+})
diff --git a/src/screens/Messages/List/ChatListItem.tsx b/src/screens/Messages/List/ChatListItem.tsx
new file mode 100644
index 00000000..13706472
--- /dev/null
+++ b/src/screens/Messages/List/ChatListItem.tsx
@@ -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()
+ const [showActions, setShowActions] = React.useState(false)
+
+ const onMouseEnter = React.useCallback(() => {
+ setShowActions(true)
+ }, [])
+
+ const onMouseLeave = React.useCallback(() => {
+ setShowActions(false)
+ }, [])
+
+ const onFocus = React.useCallback(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 (
+
+
+
+ )
+}
diff --git a/src/screens/Messages/List/index.tsx b/src/screens/Messages/List/index.tsx
index b9ce8f25..05559b7d 100644
--- a/src/screens/Messages/List/index.tsx
+++ b/src/screens/Messages/List/index.tsx
@@ -3,28 +3,22 @@ import {View} from 'react-native'
import {ChatBskyConvoDefs} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {useNavigation} from '@react-navigation/native'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
import {sha256} from 'js-sha256'
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 {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger'
-import {isNative} from '#/platform/detection'
import {useListConvos} from '#/state/queries/messages/list-converations'
-import {useSession} from '#/state/session'
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 {CenteredView} 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 {DialogControlProps, useDialogControl} from '#/components/Dialog'
-import {ConvoMenu} from '#/components/dms/ConvoMenu'
import {NewChat} from '#/components/dms/NewChat'
import * as TextField from '#/components/forms/TextField'
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 {Link} from '#/components/Link'
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
-import {useMenuControl} from '#/components/Menu'
import {Text} from '#/components/Typography'
import {ClipClopGate} from '../gate'
import {useDmServiceUrlStorage} from '../Temp/useDmServiceUrlStorage'
+import {ChatListItem} from './ChatListItem'
type Props = NativeStackScreenProps
@@ -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()
- const [showActions, setShowActions] = React.useState(false)
-
- const onMouseEnter = React.useCallback(() => {
- setShowActions(true)
- }, [])
-
- const onMouseLeave = React.useCallback(() => {
- setShowActions(false)
- }, [])
-
- const onFocus = React.useCallback(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 (
-
-
-
- )
-}
-
function DesktopHeader({
newChatControl,
onNavigateToSettings,