diff --git a/src/App.native.tsx b/src/App.native.tsx
index 796666f316..30a5e81296 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -3,7 +3,6 @@ import '#/logger/bitdrift/setup'
import '#/view/icons'
import React, {useEffect, useState} from 'react'
-import {View} from 'react-native'
import {GestureHandlerRootView} from 'react-native-gesture-handler'
import {
initialWindowMetrics,
@@ -61,26 +60,22 @@ import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies'
+import {TestCtrls} from '#/view/com/testing/TestCtrls'
import * as Toast from '#/view/com/util/Toast'
-import {atoms as a, ThemeProvider as Alf} from '#/alf'
+import {Shell} from '#/view/shell'
+import {ThemeProvider as Alf} from '#/alf'
import {useColorModeTheme} from '#/alf/util/useColorModeTheme'
-import {Button, ButtonText} from '#/components/Button'
import {Provider as ContextMenuProvider} from '#/components/ContextMenu'
-import * as Dialog from '#/components/Dialog'
+import {NuxDialogs} from '#/components/dialogs/nuxs'
import {useStarterPackEntry} from '#/components/hooks/useStarterPackEntry'
import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialogs'
import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay'
-import {Outlet as PortalOutlet} from '#/components/Portal'
import {Provider as PortalProvider} from '#/components/Portal'
import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
import {ToastOutlet} from '#/components/Toast'
import {Splash} from '#/Splash'
-import {BottomSheetOutlet} from '../modules/bottom-sheet'
import {BottomSheetProvider} from '../modules/bottom-sheet'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
-import {useApplyPullRequestOTAUpdate} from './lib/hooks/useOTAUpdates'
-import {RequestListItem} from './screens/Messages/components/RequestListItem'
-import {List} from './view/com/util/List'
SplashScreen.preventAutoHideAsync()
if (isIOS) {
@@ -169,10 +164,10 @@ function InnerApp() {
style={s.h100pct}>
-
+
+
+
-
-
@@ -257,104 +252,3 @@ function App() {
}
export default Sentry.wrap(App)
-
-function Testbed() {
- const control = Dialog.useDialogControl()
- const [showItem, setShowItem] = useState(true)
-
- const {revertToEmbedded} = useApplyPullRequestOTAUpdate()
-
- return (
-
-
-
- (
-
- )}
- />
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/screens/Messages/components/ChatListItem.tsx b/src/screens/Messages/components/ChatListItem.tsx
index 1b260c1c42..f4e7863679 100644
--- a/src/screens/Messages/components/ChatListItem.tsx
+++ b/src/screens/Messages/components/ChatListItem.tsx
@@ -30,14 +30,16 @@ import {
import {precacheProfile} from '#/state/queries/profile'
import {useSession} from '#/state/session'
import {TimeElapsed} from '#/view/com/util/TimeElapsed'
-import {UserAvatar} from '#/view/com/util/UserAvatar'
-import {atoms as a, useTheme, web} from '#/alf'
+import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
+import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
import * as tokens from '#/alf/tokens'
-import {Button} from '#/components/Button'
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 {Envelope_Open_Stroke2_Corner0_Rounded as EnvelopeOpen} from '#/components/icons/EnveopeOpen'
import {Trash_Stroke2_Corner0_Rounded} from '#/components/icons/Trash'
+import {Link} from '#/components/Link'
import {useMenuControl} from '#/components/Menu'
import {PostAlerts} from '#/components/moderation/PostAlerts'
import {createPortalGroup} from '#/components/Portal'
@@ -85,6 +87,7 @@ function ChatListItemReady({
convo,
profile: profileUnshadowed,
moderationOpts,
+ showMenu,
children,
}: {
convo: ChatBskyConvoDefs.ConvoView
@@ -98,6 +101,7 @@ function ChatListItemReady({
const {currentAccount} = useSession()
const menuControl = useMenuControl()
const leaveConvoControl = useDialogControl()
+ const {gtMobile} = useBreakpoints()
const profile = useProfileShadow(profileUnshadowed)
const {mutate: markAsRead} = useMarkAsReadMutation()
const moderation = React.useMemo(
@@ -111,6 +115,17 @@ function ChatListItemReady({
profile,
})
+ 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')
+ const userBlock = blocks.find(alert => alert.source.type === 'user')
+ return {
+ listBlocks,
+ userBlock,
+ }
+ }, [moderation])
+
const isDeletedAccount = profile.handle === 'missing.invalid'
const displayName = isDeletedAccount
? _(msg`Deleted Account`)
@@ -121,134 +136,137 @@ function ChatListItemReady({
const isDimStyle = convo.muted || moderation.blocked || isDeletedAccount
- const {lastMessage, lastMessageSentAt} = useMemo(() => {
- // eslint-disable-next-line @typescript-eslint/no-shadow
- let lastMessage = _(msg`No messages yet`)
- // eslint-disable-next-line @typescript-eslint/no-shadow
- let lastMessageSentAt: string | null = null
+ const {lastMessage, lastMessageSentAt, latestReportableMessage} =
+ useMemo(() => {
+ // eslint-disable-next-line @typescript-eslint/no-shadow
+ let lastMessage = _(msg`No messages yet`)
+ // eslint-disable-next-line @typescript-eslint/no-shadow
+ let lastMessageSentAt: string | null = null
+ // eslint-disable-next-line @typescript-eslint/no-shadow
+ let latestReportableMessage: ChatBskyConvoDefs.MessageView | undefined
- let latestReportableMessage: ChatBskyConvoDefs.MessageView | undefined
+ if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
+ const isFromMe = convo.lastMessage.sender?.did === currentAccount?.did
- if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
- const isFromMe = convo.lastMessage.sender?.did === currentAccount?.did
-
- if (!isFromMe) {
- latestReportableMessage = convo.lastMessage
- }
-
- if (convo.lastMessage.text) {
- if (isFromMe) {
- lastMessage = _(msg`You: ${convo.lastMessage.text}`)
- } else {
- lastMessage = convo.lastMessage.text
+ if (!isFromMe) {
+ latestReportableMessage = convo.lastMessage
}
- } else if (convo.lastMessage.embed) {
- const defaultEmbeddedContentMessage = _(
- msg`(contains embedded content)`,
- )
- if (AppBskyEmbedRecord.isView(convo.lastMessage.embed)) {
- const embed = convo.lastMessage.embed
+ if (convo.lastMessage.text) {
+ if (isFromMe) {
+ lastMessage = _(msg`You: ${convo.lastMessage.text}`)
+ } else {
+ lastMessage = convo.lastMessage.text
+ }
+ } else if (convo.lastMessage.embed) {
+ const defaultEmbeddedContentMessage = _(
+ msg`(contains embedded content)`,
+ )
- if (AppBskyEmbedRecord.isViewRecord(embed.record)) {
- const record = embed.record
- const path = postUriToRelativePath(record.uri, {
- handle: record.author.handle,
- })
- const href = path ? toBskyAppUrl(path) : undefined
- const short = href
- ? toShortUrl(href)
- : defaultEmbeddedContentMessage
+ if (AppBskyEmbedRecord.isView(convo.lastMessage.embed)) {
+ const embed = convo.lastMessage.embed
+
+ if (AppBskyEmbedRecord.isViewRecord(embed.record)) {
+ const record = embed.record
+ const path = postUriToRelativePath(record.uri, {
+ handle: record.author.handle,
+ })
+ const href = path ? toBskyAppUrl(path) : undefined
+ const short = href
+ ? toShortUrl(href)
+ : defaultEmbeddedContentMessage
+ if (isFromMe) {
+ lastMessage = _(msg`You: ${short}`)
+ } else {
+ lastMessage = short
+ }
+ }
+ } else {
if (isFromMe) {
- lastMessage = _(msg`You: ${short}`)
+ lastMessage = _(msg`You: ${defaultEmbeddedContentMessage}`)
} else {
- lastMessage = short
+ lastMessage = defaultEmbeddedContentMessage
}
}
- } else {
- if (isFromMe) {
- lastMessage = _(msg`You: ${defaultEmbeddedContentMessage}`)
- } else {
- lastMessage = defaultEmbeddedContentMessage
- }
}
+
+ lastMessageSentAt = convo.lastMessage.sentAt
+ }
+ if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) {
+ lastMessageSentAt = convo.lastMessage.sentAt
+
+ lastMessage = isDeletedAccount
+ ? _(msg`Conversation deleted`)
+ : _(msg`Message deleted`)
}
- lastMessageSentAt = convo.lastMessage.sentAt
- }
- if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) {
- lastMessageSentAt = convo.lastMessage.sentAt
-
- lastMessage = isDeletedAccount
- ? _(msg`Conversation deleted`)
- : _(msg`Message deleted`)
- }
-
- if (ChatBskyConvoDefs.isMessageAndReactionView(convo.lastReaction)) {
- if (
- !lastMessageSentAt ||
- new Date(lastMessageSentAt) <
- new Date(convo.lastReaction.reaction.createdAt)
- ) {
- const isFromMe =
- convo.lastReaction.reaction.sender.did === currentAccount?.did
- const lastMessageText = convo.lastReaction.message.text
- const fallbackMessage = _(
- msg({
- message: 'a message',
- comment: `If last message does not contain text, fall back to "{user} reacted to {a message}"`,
- }),
- )
-
- if (isFromMe) {
- lastMessage = _(
- msg`You reacted ${convo.lastReaction.reaction.value} to ${
- lastMessageText
- ? `"${convo.lastReaction.message.text}"`
- : fallbackMessage
- }`,
+ if (ChatBskyConvoDefs.isMessageAndReactionView(convo.lastReaction)) {
+ if (
+ !lastMessageSentAt ||
+ new Date(lastMessageSentAt) <
+ new Date(convo.lastReaction.reaction.createdAt)
+ ) {
+ const isFromMe =
+ convo.lastReaction.reaction.sender.did === currentAccount?.did
+ const lastMessageText = convo.lastReaction.message.text
+ const fallbackMessage = _(
+ msg({
+ message: 'a message',
+ comment: `If last message does not contain text, fall back to "{user} reacted to {a message}"`,
+ }),
)
- } else {
- const senderDid = convo.lastReaction.reaction.sender.did
- const sender = convo.members.find(member => member.did === senderDid)
- if (sender) {
+
+ if (isFromMe) {
lastMessage = _(
- msg`${sanitizeDisplayName(
- sender.displayName || sender.handle,
- )} reacted ${convo.lastReaction.reaction.value} to ${
+ msg`You reacted ${convo.lastReaction.reaction.value} to ${
lastMessageText
? `"${convo.lastReaction.message.text}"`
: fallbackMessage
}`,
)
} else {
- lastMessage = _(
- msg`Someone reacted ${convo.lastReaction.reaction.value} to ${
- lastMessageText
- ? `"${convo.lastReaction.message.text}"`
- : fallbackMessage
- }`,
+ const senderDid = convo.lastReaction.reaction.sender.did
+ const sender = convo.members.find(
+ member => member.did === senderDid,
)
+ if (sender) {
+ lastMessage = _(
+ msg`${sanitizeDisplayName(
+ sender.displayName || sender.handle,
+ )} reacted ${convo.lastReaction.reaction.value} to ${
+ lastMessageText
+ ? `"${convo.lastReaction.message.text}"`
+ : fallbackMessage
+ }`,
+ )
+ } else {
+ lastMessage = _(
+ msg`Someone reacted ${convo.lastReaction.reaction.value} to ${
+ lastMessageText
+ ? `"${convo.lastReaction.message.text}"`
+ : fallbackMessage
+ }`,
+ )
+ }
}
}
}
- }
- return {
- lastMessage,
- lastMessageSentAt,
- latestReportableMessage,
- }
- }, [
- _,
- convo.lastMessage,
- convo.lastReaction,
- currentAccount?.did,
- isDeletedAccount,
- convo.members,
- ])
+ return {
+ lastMessage,
+ lastMessageSentAt,
+ latestReportableMessage,
+ }
+ }, [
+ _,
+ convo.lastMessage,
+ convo.lastReaction,
+ currentAccount?.did,
+ isDeletedAccount,
+ convo.members,
+ ])
- const [_showActions, setShowActions] = useState(false)
+ const [showActions, setShowActions] = useState(false)
const onMouseEnter = useCallback(() => {
setShowActions(true)
@@ -331,14 +349,15 @@ function ChatListItemReady({
a.absolute,
{top: tokens.space.md, left: tokens.space.lg},
]}>
-
-
+
- {/*
+
{showMenu && (
- )}*/}
- {/**/}
+ />
diff --git a/src/screens/Messages/components/RequestButtons.tsx b/src/screens/Messages/components/RequestButtons.tsx
index 1d722e9846..4437a9a43f 100644
--- a/src/screens/Messages/components/RequestButtons.tsx
+++ b/src/screens/Messages/components/RequestButtons.tsx
@@ -2,8 +2,10 @@ import {useCallback} from 'react'
import {type ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
+import {StackActions, useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
+import {type NavigationProp} from '#/lib/routes/types'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useEmail} from '#/state/email-verification'
import {useAcceptConversation} from '#/state/queries/messages/accept-conversation'
@@ -48,11 +50,11 @@ export function RejectMenu({
}) {
const {_} = useLingui()
const shadowedProfile = useProfileShadow(profile)
- // const navigation = useNavigation()
+ const navigation = useNavigation()
const {mutate: leaveConvo} = useLeaveConvo(convo.id, {
onMutate: () => {
if (currentScreen === 'conversation') {
- // navigation.dispatch(StackActions.pop())
+ navigation.dispatch(StackActions.pop())
}
},
onError: () => {
@@ -190,7 +192,7 @@ export function AcceptChatButton({
}) {
const {_} = useLingui()
const queryClient = useQueryClient()
- // const navigation = useNavigation()
+ const navigation = useNavigation()
const {needsEmailVerification} = useEmail()
const emailDialogControl = useEmailDialogControl()
@@ -199,10 +201,10 @@ export function AcceptChatButton({
onAcceptConvo?.()
if (currentScreen === 'list') {
precacheConvoQuery(queryClient, {...convo, status: 'accepted'})
- // navigation.navigate('MessagesConversation', {
- // conversation: convo.id,
- // accept: true,
- // })
+ navigation.navigate('MessagesConversation', {
+ conversation: convo.id,
+ accept: true,
+ })
}
},
onError: () => {
@@ -270,12 +272,12 @@ export function DeleteChatButton({
currentScreen: 'list' | 'conversation'
}) {
const {_} = useLingui()
- // const navigation = useNavigation()
+ const navigation = useNavigation()
const {mutate: leaveConvo} = useLeaveConvo(convo.id, {
onMutate: () => {
if (currentScreen === 'conversation') {
- // navigation.dispatch(StackActions.pop())
+ navigation.dispatch(StackActions.pop())
}
},
onError: () => {
diff --git a/src/screens/Messages/components/RequestListItem.tsx b/src/screens/Messages/components/RequestListItem.tsx
index 0276690cc7..1f23b88823 100644
--- a/src/screens/Messages/components/RequestListItem.tsx
+++ b/src/screens/Messages/components/RequestListItem.tsx
@@ -5,6 +5,7 @@ import {Trans} from '@lingui/macro'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
import {atoms as a, tokens} from '#/alf'
+import {KnownFollowers} from '#/components/KnownFollowers'
import {Text} from '#/components/Typography'
import {ChatListItem, ChatListItemPortal} from './ChatListItem'
import {AcceptChatButton, DeleteChatButton, RejectMenu} from './RequestButtons'
@@ -26,6 +27,14 @@ export function RequestListItem({convo}: {convo: ChatBskyConvoDefs.ConvoView}) {
return (
+
+
+
{/* spacer, since you can't nest pressables */}
{/* Placeholder text so that it responds to the font height */}