[Chat] NUX (#10848)
Co-authored-by: DS Boyce <260543580+ds-boyce@users.noreply.github.com> Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
@@ -8,6 +8,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
import {useAppState} from '#/lib/appState'
|
||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||
import {type MessagesTabNavigatorParams} from '#/lib/routes/types'
|
||||
import {cleanError} from '#/lib/strings/errors'
|
||||
@@ -41,7 +42,7 @@ import {Link} from '#/components/Link'
|
||||
import {ListFooter} from '#/components/Lists'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {ChatDisabled} from './components/ChatDisabled'
|
||||
import {ChatListItem} from './components/ChatListItem'
|
||||
import {InboxRequests} from './components/InboxRequests'
|
||||
@@ -100,6 +101,12 @@ export function MessagesScreenInner({navigation, route}: Props) {
|
||||
const newChatControl = useDialogControl()
|
||||
const {data: chatStatus} = useChatActorStatusQuery()
|
||||
const pushToConversation = route.params?.pushToConversation
|
||||
const pushToNewGroupChat = route.params?.pushToNewGroupChat
|
||||
// Tracks whether the next new-chat dialog open should start directly on the
|
||||
// group-chat creation step. Set when deep-linked via `pushToNewGroupChat`,
|
||||
// and reset to `false` whenever the dialog is opened through the normal FAB/
|
||||
// button path so it never gets stuck in group mode.
|
||||
const [startNewChatInGroupChat, setStartNewChatInGroupChat] = useState(false)
|
||||
|
||||
// Whenever we have `pushToConversation` set, it means we pressed a notification for a chat without being on
|
||||
// this tab. We should immediately push to the conversation after pressing the notification.
|
||||
@@ -137,6 +144,7 @@ export function MessagesScreenInner({navigation, route}: Props) {
|
||||
)
|
||||
|
||||
const openChatControl = useCallback(() => {
|
||||
setStartNewChatInGroupChat(false)
|
||||
newChatControl.open()
|
||||
}, [newChatControl])
|
||||
|
||||
@@ -149,6 +157,50 @@ export function MessagesScreenInner({navigation, route}: Props) {
|
||||
],
|
||||
})
|
||||
|
||||
// Deep link into the group-chat creation step of the new-chat dialog. Mirrors
|
||||
// the `pushToConversation` pattern: open the dialog (respecting the same
|
||||
// email-verification gating as the normal new-chat button) starting directly
|
||||
// in group mode, then clear the param so it can fire again later.
|
||||
const openGroupChatControl = useCallback(() => {
|
||||
setStartNewChatInGroupChat(true)
|
||||
newChatControl.open()
|
||||
}, [newChatControl])
|
||||
const wrappedOpenGroupChatControl = requireEmailVerification(
|
||||
openGroupChatControl,
|
||||
{
|
||||
instructions: [
|
||||
<Trans key="new-group-chat">
|
||||
Before you can message another user, you must first verify your email.
|
||||
</Trans>,
|
||||
],
|
||||
},
|
||||
)
|
||||
// Stable reference to the (otherwise per-render) opener so the effect below
|
||||
// doesn't list it as a dependency - if it did, clearing the param would
|
||||
// re-run the effect and its cleanup would cancel the pending open.
|
||||
const openGroupChat = useNonReactiveCallback(wrappedOpenGroupChatControl)
|
||||
// Deep link into the group-chat creation step of the new-chat dialog. The
|
||||
// dialog control isn't attached synchronously when navigating onto this
|
||||
// screen, so defer the open by a tick. We clear the param *after* opening
|
||||
// (inside the timeout) so clearing doesn't cancel the pending open.
|
||||
useEffect(() => {
|
||||
if (!pushToNewGroupChat) return
|
||||
const timeout = setTimeout(() => {
|
||||
openGroupChat()
|
||||
if (IS_WEB) {
|
||||
// `navigation.setParams({pushToNewGroupChat: undefined})` serializes the
|
||||
// literal string "undefined" into the query on web (see router build()),
|
||||
// so strip the param with the history API instead.
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.delete('pushToNewGroupChat')
|
||||
history.replaceState(null, '', url.pathname + url.search + url.hash)
|
||||
} else {
|
||||
navigation.setParams({pushToNewGroupChat: undefined})
|
||||
}
|
||||
}, 100)
|
||||
return () => clearTimeout(timeout)
|
||||
}, [navigation, pushToNewGroupChat, openGroupChat])
|
||||
|
||||
if (isWithinSplitView) {
|
||||
return (
|
||||
<>
|
||||
@@ -172,7 +224,12 @@ export function MessagesScreenInner({navigation, route}: Props) {
|
||||
}
|
||||
style={[a.h_full, a.justify_center, a.pb_5xl]}
|
||||
/>
|
||||
<NewChat onNewChat={onNewChat} control={newChatControl} />
|
||||
<NewChat
|
||||
onNewChat={onNewChat}
|
||||
control={newChatControl}
|
||||
startInGroupChat={startNewChatInGroupChat}
|
||||
onClose={() => setStartNewChatInGroupChat(false)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -181,7 +238,12 @@ export function MessagesScreenInner({navigation, route}: Props) {
|
||||
<Layout.Screen testID="messagesScreen">
|
||||
<Header newChatControl={newChatControl} chatStatus={chatStatus} />
|
||||
<ChatList newChatControl={newChatControl} chatStatus={chatStatus} />
|
||||
<NewChat onNewChat={onNewChat} control={newChatControl} />
|
||||
<NewChat
|
||||
onNewChat={onNewChat}
|
||||
control={newChatControl}
|
||||
startInGroupChat={startNewChatInGroupChat}
|
||||
onClose={() => setStartNewChatInGroupChat(false)}
|
||||
/>
|
||||
</Layout.Screen>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user