Update handling of join link previews (#10798)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {
|
||||
type ChatInvitePreview,
|
||||
isKnownJoinLinkPreview,
|
||||
} from '#/state/queries/join-links'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import * as ChatInvite from '#/components/dms/ChatInvite'
|
||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||
@@ -23,11 +27,12 @@ export function JoinRequestEmbed({
|
||||
onOpen,
|
||||
}: {
|
||||
code?: string
|
||||
preview?: ChatBskyGroupDefs.JoinLinkPreviewView
|
||||
preview?: ChatInvitePreview
|
||||
style?: StyleProp<ViewStyle>
|
||||
onOpen?: () => void
|
||||
}) {
|
||||
const resolvedCode = code ?? preview?.code
|
||||
const resolvedCode =
|
||||
code ?? (isKnownJoinLinkPreview(preview) ? preview.code : undefined)
|
||||
if (!resolvedCode) return null
|
||||
|
||||
return (
|
||||
@@ -73,7 +78,7 @@ export function JoinRequestEmbedBody({
|
||||
)
|
||||
}
|
||||
|
||||
if (!preview) {
|
||||
if (!ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {View} from 'react-native'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {Plural, Trans} from '@lingui/react/macro'
|
||||
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
@@ -20,7 +21,7 @@ export function Card({size}: {size: 'large' | 'small'}) {
|
||||
const t = useTheme()
|
||||
const {preview, hasFixedHeight} = useChatInvite()
|
||||
|
||||
if (!preview) return null
|
||||
if (!ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) return null
|
||||
|
||||
const ownerDisplayName = createSanitizedDisplayName(preview.owner)
|
||||
const ownerHandle = sanitizeHandle(preview.owner.handle, '@')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {createContext, useContext} from 'react'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
|
||||
import {type ChatInvitePreview} from '#/state/queries/join-links'
|
||||
import {type ButtonColor} from '#/components/Button'
|
||||
import {type Props as SVGIconProps} from '#/components/icons/common'
|
||||
|
||||
@@ -26,7 +26,7 @@ export type ChatInviteContextValue = {
|
||||
code: string
|
||||
loading: boolean
|
||||
error: boolean
|
||||
preview: ChatBskyGroupDefs.JoinLinkPreviewView | undefined
|
||||
preview: ChatInvitePreview | undefined
|
||||
/**
|
||||
* The derived action descriptor. Undefined while loading or when there's no
|
||||
* preview to act on.
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import {setStringAsync} from 'expo-clipboard'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {useJoinLinkPreviewsQuery} from '#/state/queries/join-links'
|
||||
import {
|
||||
type ChatInvitePreview,
|
||||
useJoinLinkPreviewsQuery,
|
||||
} from '#/state/queries/join-links'
|
||||
import {useSession} from '#/state/session'
|
||||
import {type ButtonColor} from '#/components/Button'
|
||||
import {ArrowRight_Stroke2_Corner0_Rounded as ArrowRightIcon} from '#/components/icons/Arrow'
|
||||
@@ -13,7 +16,6 @@ import {ChainLink_Stroke2_Corner0_Rounded as LinkIcon} from '#/components/icons/
|
||||
import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
|
||||
import {type Props as SVGIconProps} from '#/components/icons/common'
|
||||
import {RaisingHand4Finger_Stroke2_Corner2_Rounded as HandIcon} from '#/components/icons/RaisingHand'
|
||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||
import {useIntentDialogs} from '#/components/intents/IntentDialogs'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {type ChatInviteAction, ChatInviteProvider} from './Context'
|
||||
@@ -34,7 +36,7 @@ export function Root({
|
||||
children,
|
||||
}: {
|
||||
code: string
|
||||
initialPreview?: ChatBskyGroupDefs.JoinLinkPreviewView
|
||||
initialPreview?: ChatInvitePreview
|
||||
/**
|
||||
* The convo this invite is being viewed within, if any. When the invite
|
||||
* links to the same chat, the action becomes "Copy link" instead of
|
||||
@@ -62,7 +64,7 @@ export function Root({
|
||||
const loading = isPending && !preview
|
||||
|
||||
let action: ChatInviteAction | undefined
|
||||
if (preview) {
|
||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
||||
const convoId = preview.convo?.id
|
||||
const isFollowing = preview.owner.viewer?.following ?? false
|
||||
const hasRequested = !convoId && preview.viewer?.requestedAt != null
|
||||
@@ -99,12 +101,7 @@ export function Root({
|
||||
let icon: React.ComponentType<SVGIconProps> = JoinIcon
|
||||
let label = preview.requireApproval ? l`Request to join` : l`Join`
|
||||
let color: ButtonColor = 'primary'
|
||||
if (preview.enabledStatus !== 'enabled') {
|
||||
canJoin = false
|
||||
icon = WarningIcon
|
||||
label = l`Chat invite link no longer available`
|
||||
color = 'secondary'
|
||||
} else if (preview.memberCount >= preview.memberLimit) {
|
||||
if (preview.memberCount >= preview.memberLimit) {
|
||||
canJoin = false
|
||||
icon = HandIcon
|
||||
label = l`This chat is full`
|
||||
|
||||
@@ -3,6 +3,7 @@ import {useWindowDimensions, View} from 'react-native'
|
||||
import {type $Typed, type ChatBskyEmbedJoinLink} from '@atproto/api'
|
||||
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {isKnownJoinLinkPreview} from '#/state/queries/join-links'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
import * as ChatInvite from '#/components/dms/ChatInvite'
|
||||
import {MessageContextProvider} from './MessageContext'
|
||||
@@ -27,6 +28,11 @@ let MessageItemInviteEmbed = ({
|
||||
const screen = useWindowDimensions()
|
||||
const convo = useConvoActive()
|
||||
|
||||
const code = isKnownJoinLinkPreview(embed.joinLinkPreview)
|
||||
? embed.joinLinkPreview.code
|
||||
: undefined
|
||||
if (!code) return null
|
||||
|
||||
return (
|
||||
<MessageContextProvider>
|
||||
<View
|
||||
@@ -72,7 +78,7 @@ let MessageItemInviteEmbed = ({
|
||||
},
|
||||
]}>
|
||||
<ChatInvite.Root
|
||||
code={embed.joinLinkPreview.code}
|
||||
code={code}
|
||||
initialPreview={embed.joinLinkPreview}
|
||||
currentConvoId={convo.convo.view.id}
|
||||
hasFixedHeight={false}>
|
||||
|
||||
@@ -121,7 +121,8 @@ function ProfileHeaderReady({
|
||||
<View style={[a.flex_row, a.align_center, a.flex_1, web(a.mb_2xs)]}>
|
||||
<Text
|
||||
style={[a.text_lg, a.font_semi_bold, a.flex_shrink]}
|
||||
numberOfLines={1}>
|
||||
numberOfLines={1}
|
||||
emoji>
|
||||
{displayName}
|
||||
</Text>
|
||||
<ProfileBadges profile={profile} size="md" style={[a.pl_xs]} />
|
||||
@@ -185,7 +186,8 @@ function GroupHeaderReady({
|
||||
<View style={[a.flex_row, a.flex_1, a.align_center]}>
|
||||
<Text
|
||||
style={[a.text_lg, a.font_semi_bold, a.flex_shrink]}
|
||||
numberOfLines={1}>
|
||||
numberOfLines={1}
|
||||
emoji>
|
||||
{convo.details.name}
|
||||
</Text>
|
||||
<MuteStatus muted={convo.view.muted} />
|
||||
|
||||
@@ -45,7 +45,8 @@ export function SystemMessageItem({
|
||||
a.text_center,
|
||||
t.atoms.text_contrast_medium,
|
||||
{includeFontPadding: false, textAlignVertical: 'center'},
|
||||
]}>
|
||||
]}
|
||||
emoji>
|
||||
{text}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
ChatBskyGroupDefs,
|
||||
ChatBskyGroupRequestJoin,
|
||||
ChatBskyGroupWithdrawJoinRequest,
|
||||
moderateProfile,
|
||||
@@ -211,7 +212,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
|
||||
const joinLinkPreview = data.joinLinkPreviews[0]
|
||||
|
||||
if (!joinLinkPreview) {
|
||||
if (!ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) {
|
||||
return (
|
||||
<>
|
||||
<View style={[a.py_lg, a.align_center]}>
|
||||
@@ -253,12 +254,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
? l`Request to join`
|
||||
: l`Join`
|
||||
let buttonColor: ButtonColor = 'primary'
|
||||
if (joinLinkPreview.enabledStatus !== 'enabled') {
|
||||
canJoin = false
|
||||
ButtonIconImage = WarningIcon
|
||||
buttonText = l`Chat invite link no longer available`
|
||||
buttonColor = 'secondary'
|
||||
} else if (joinLinkPreview.memberCount >= joinLinkPreview.memberLimit) {
|
||||
if (joinLinkPreview.memberCount >= joinLinkPreview.memberLimit) {
|
||||
canJoin = false
|
||||
ButtonIconImage = HandIcon
|
||||
buttonText = l`This chat is full`
|
||||
@@ -311,10 +307,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
</Trans>
|
||||
</Text>
|
||||
<View style={[a.flex_row, a.ml_md]}>
|
||||
<PersonGroupIcon
|
||||
size="xs"
|
||||
style={[a.mr_xs, t.atoms.text, {marginTop: -2}]}
|
||||
/>
|
||||
<PersonGroupIcon size="xs" style={[a.mr_xs, t.atoms.text]} />
|
||||
</View>
|
||||
<Text
|
||||
style={[a.text_center, a.text_xs, a.leading_snug, t.atoms.text]}>
|
||||
@@ -371,7 +364,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
</InlineLinkText>
|
||||
</Text>
|
||||
<ProfileBadges
|
||||
profile={data.joinLinkPreviews[0].owner}
|
||||
profile={joinLinkPreview.owner}
|
||||
size="sm"
|
||||
style={{marginTop: -3}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user