import {useEffect} from 'react' import {View} from 'react-native' import {ImageBackground} from 'expo-image' import {ChatBskyGroupDefs, moderateProfile} from '@atproto/api' import {type ThemeName} from '@bsky.app/alf' import {Trans, useLingui} from '@lingui/react/macro' import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' import {sanitizeHandle} from '#/lib/strings/handles' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useJoinLinkPreviewsQuery} from '#/state/queries/join-links' import {useActiveGroupChatJoinRequest} from '#/state/shell/landing' import {LoggedOutScreenState} from '#/view/com/auth/LoggedOut' import {LogomarkWithType} from '#/view/icons/LogomarkWithType' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {AvatarBubbles} from '#/components/AvatarBubbles' import {Button, ButtonText} from '#/components/Button' import {ChainLinkBroken_Stroke2_Corner0_Rounded as ChainLinkBrokenIcon} from '#/components/icons/ChainLink' import {PersonGroup_Stroke2_Corner2_Rounded as PersonGroupIcon} from '#/components/icons/Person' import {ProfileBadges} from '#/components/ProfileBadges' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' const desktopDarkBg = require('../../../assets/images/chat-desktop-bg-dark.webp') const desktopDimBg = require('../../../assets/images/chat-desktop-bg-dim.webp') const desktopLightBg = require('../../../assets/images/chat-desktop-bg-light.webp') const mobileDarkBg = require('../../../assets/images/chat-mobile-bg-dark.webp') const mobileDimBg = require('../../../assets/images/chat-mobile-bg-dim.webp') const mobileLightBg = require('../../../assets/images/chat-mobile-bg-light.webp') function getBackgroundImage(themeName: ThemeName, gtMobile: boolean) { switch (themeName) { case 'dark': return gtMobile ? desktopDarkBg : mobileDarkBg case 'dim': return gtMobile ? desktopDimBg : mobileDimBg default: return gtMobile ? desktopLightBg : mobileLightBg } } type Props = { setScreenState: (state: LoggedOutScreenState) => void } export function JoinRequest({setScreenState}: Props) { const t = useTheme() const {t: l} = useLingui() const ax = useAnalytics() const {gtMobile, gtTablet} = useBreakpoints() const moderationOpts = useModerationOpts() useEffect(() => { ax.metric('groupchat:landingPage:view', {hasSession: false}) }, [ax]) // Get code from context (logged-out only) const contextJoinRequest = useActiveGroupChatJoinRequest() const code = contextJoinRequest?.code const {data, error} = useJoinLinkPreviewsQuery({ codes: code ? [code] : undefined, hasSession: false, }) const background = getBackgroundImage(t.name, gtMobile) const joinLinkPreview = data?.joinLinkPreviews[0] return ( {error || (data && !ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) ? ( Chat invite link no longer available ) : data && moderationOpts && ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview) ? ( Group chat {joinLinkPreview.memberCount}/ {joinLinkPreview.memberLimit} {joinLinkPreview.name} By{' '} {createSanitizedDisplayName( joinLinkPreview.owner, true, moderateProfile( joinLinkPreview.owner, moderationOpts, ).ui('displayName'), )} {sanitizeHandle(joinLinkPreview.owner.handle, '@')} {joinLinkPreview.requireApproval ? l`Sign in to request access to this group chat.` : l`Sign in to accept invite.`}{' '} {joinLinkPreview.joinRule === 'followedByOwner' && l`Only people ${createSanitizedDisplayName( joinLinkPreview.owner, true, moderateProfile(joinLinkPreview.owner, moderationOpts).ui( 'displayName', ), )} follows can join.`} ) : null} ) } function Wrapper({children}: React.PropsWithChildren) { const t = useTheme() const isDarkMode = t.name !== 'light' return ( <> {children} ) } function ActionButtons({ setScreenState, }: { setScreenState: (state: LoggedOutScreenState) => void }) { const t = useTheme() const {t: l} = useLingui() const isDarkMode = t.name !== 'light' return ( ) }