finish phase 3: type-only codemod and zero non-bridge @atproto/api imports
Task 8: codemod repointed 150 namespace-type files to #/lexicons (AppBskyFeedDefs.PostView -> app.bsky.feed.defs.PostView, .Record -> .Main) plus ~105 hand-fixed consumers (composer/video state, DebugMod, Profile, onboarding, dialogs). DM_SERVICE_HEADERS deleted; last chat call sites on the chat client. RichText.tsx flipped to SDK-only. Remaining @atproto/api importers: the three session bridge files, the deliberate dual-world matcher in lib/xrpc-error.ts, and test fixtures. toLex boundary casts are TODO(phase4)-tagged for bridge removal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+10
-12
@@ -1,10 +1,6 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyBookmarkDefs,
|
||||
AppBskyFeedDefs,
|
||||
} from '@atproto/api'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -38,6 +34,8 @@ import * as toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Bookmarks'>
|
||||
|
||||
@@ -78,15 +76,15 @@ type ListItem =
|
||||
| {
|
||||
type: 'bookmark'
|
||||
key: string
|
||||
bookmark: Omit<AppBskyBookmarkDefs.BookmarkView, 'item'> & {
|
||||
item: $Typed<AppBskyFeedDefs.PostView>
|
||||
bookmark: Omit<app.bsky.bookmark.defs.BookmarkView, 'item'> & {
|
||||
item: $Typed<app.bsky.feed.defs.PostView>
|
||||
}
|
||||
}
|
||||
| {
|
||||
type: 'bookmarkNotFound'
|
||||
key: string
|
||||
bookmark: Omit<AppBskyBookmarkDefs.BookmarkView, 'item'> & {
|
||||
item: $Typed<AppBskyFeedDefs.NotFoundPost>
|
||||
bookmark: Omit<app.bsky.bookmark.defs.BookmarkView, 'item'> & {
|
||||
item: $Typed<app.bsky.feed.defs.NotFoundPost>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +130,7 @@ function BookmarksInner() {
|
||||
|
||||
if (bookmarks.length > 0) {
|
||||
for (const bookmark of bookmarks) {
|
||||
if (AppBskyFeedDefs.isNotFoundPost(bookmark.item)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.notFoundPost, bookmark.item)) {
|
||||
i.push({
|
||||
type: 'bookmarkNotFound',
|
||||
key: bookmark.item.uri,
|
||||
@@ -142,7 +140,7 @@ function BookmarksInner() {
|
||||
},
|
||||
})
|
||||
}
|
||||
if (AppBskyFeedDefs.isPostView(bookmark.item)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, bookmark.item)) {
|
||||
i.push({
|
||||
type: 'bookmark',
|
||||
key: bookmark.item.uri,
|
||||
@@ -199,7 +197,7 @@ function BookmarkNotFound({
|
||||
post,
|
||||
}: {
|
||||
hideTopBorder: boolean
|
||||
post: $Typed<AppBskyFeedDefs.NotFoundPost>
|
||||
post: $Typed<app.bsky.feed.defs.NotFoundPost>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
@@ -28,12 +27,15 @@ import {InlineLinkText} from '#/components/Link'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {SearchError} from '#/components/SearchError'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
const renderItem = ({item}: ListRenderItemInfo<AppBskyFeedDefs.PostView>) => {
|
||||
const renderItem = ({
|
||||
item,
|
||||
}: ListRenderItemInfo<app.bsky.feed.defs.PostView>) => {
|
||||
return <Post post={item} />
|
||||
}
|
||||
|
||||
const keyExtractor = (item: AppBskyFeedDefs.PostView, index: number) => {
|
||||
const keyExtractor = (item: app.bsky.feed.defs.PostView, index: number) => {
|
||||
return `${item.uri}-${index}`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -27,12 +26,13 @@ import {Loader} from '#/components/Loader'
|
||||
import {useHider} from '#/components/moderation/Hider'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function ListHiddenScreen({
|
||||
list,
|
||||
preferences,
|
||||
}: {
|
||||
list: AppBskyGraphDefs.ListView
|
||||
list: app.bsky.graph.defs.ListView
|
||||
preferences: UsePreferencesQueryResponse
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
@@ -43,7 +43,7 @@ export function ListHiddenScreen({
|
||||
const goBack = useGoBack()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const isModList = list.purpose === AppBskyGraphDefs.MODLIST
|
||||
const isModList = list.purpose === 'app.bsky.graph.defs#modlist'
|
||||
|
||||
const [isProcessing, setIsProcessing] = useState(false)
|
||||
const listBlockMutation = useListBlockMutation()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useState} from 'react'
|
||||
import {Keyboard, View} from 'react-native'
|
||||
import {type ComAtprotoServerDescribeServer} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import * as EmailValidator from 'email-validator'
|
||||
|
||||
@@ -16,9 +15,10 @@ import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type com} from '#/lexicons'
|
||||
import {FormContainer} from './FormContainer'
|
||||
|
||||
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
|
||||
type ServiceDescription = com.atproto.server.describeServer.$OutputBody
|
||||
|
||||
export const ForgotPasswordForm = ({
|
||||
error,
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import {useRef, useState} from 'react'
|
||||
import {Keyboard, type TextInput, View} from 'react-native'
|
||||
import {
|
||||
ComAtprotoServerCreateSession,
|
||||
type ComAtprotoServerDescribeServer,
|
||||
} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {DEFAULT_SERVICE, HITSLOP_10, HITSLOP_20} from '#/lib/constants'
|
||||
@@ -11,6 +7,7 @@ import {useRequestNotificationsPermission} from '#/lib/notifications/notificatio
|
||||
import {cleanError, isNetworkError} from '#/lib/strings/errors'
|
||||
import {createFullHandle} from '#/lib/strings/handles'
|
||||
import {isBlueskyHostedUrl, toNiceHostingUrl} from '#/lib/strings/url-helpers'
|
||||
import {getErrorName} from '#/lib/xrpc-error'
|
||||
import {logger} from '#/logger'
|
||||
import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs'
|
||||
import {
|
||||
@@ -35,11 +32,12 @@ import {createStaticClick, InlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS, IS_NATIVE} from '#/env'
|
||||
import {type com} from '#/lexicons'
|
||||
import {ConfirmHostingProviderDialog} from './components/ConfirmHostingProviderDialog'
|
||||
import {HostingProviderDialog} from './components/HostingProviderDialog'
|
||||
import {FormContainer} from './FormContainer'
|
||||
|
||||
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
|
||||
type ServiceDescription = com.atproto.server.describeServer.$OutputBody
|
||||
|
||||
export const LoginForm = ({
|
||||
error,
|
||||
@@ -142,10 +140,7 @@ export const LoginForm = ({
|
||||
} catch (err) {
|
||||
const errMsg = String(err)
|
||||
setIsProcessing(false)
|
||||
if (
|
||||
err instanceof
|
||||
ComAtprotoServerCreateSession.AuthFactorTokenRequiredError
|
||||
) {
|
||||
if (getErrorName(err) === 'AuthFactorTokenRequired') {
|
||||
setIsAuthFactorTokenNeeded(true)
|
||||
} else {
|
||||
onAttemptFailed()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyActorGetStatus, type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {
|
||||
useFocusEffect,
|
||||
@@ -57,17 +56,18 @@ import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||
import {type chat} from '#/lexicons'
|
||||
import {ChatDisabled} from './components/ChatDisabled'
|
||||
import {ChatListItem} from './components/ChatListItem'
|
||||
import {InboxRequests} from './components/InboxRequests'
|
||||
import {useIsWithinSplitView} from './components/splitView/context'
|
||||
import {splitViewLeftScroll} from './components/splitView/leftColumnScroll'
|
||||
|
||||
type ChatStatus = ChatBskyActorGetStatus.OutputSchema
|
||||
type ChatStatus = chat.bsky.actor.getStatus.$OutputBody
|
||||
|
||||
type ListItem = {
|
||||
type: 'CONVERSATION'
|
||||
conversation: ChatBskyConvoDefs.ConvoView
|
||||
conversation: chat.bsky.convo.defs.ConvoView
|
||||
selected: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||
import {type LayoutChangeEvent, View} from 'react-native'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {
|
||||
ScrollEdgeEffect,
|
||||
ScrollEdgeEffectProvider,
|
||||
@@ -46,7 +45,8 @@ import {type ConvoWithDetails, parseConvoView} from '#/components/dms/util'
|
||||
import {Error} from '#/components/Error'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {IS_LIQUID_GLASS} from '#/env'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import {isType, toLex} from '#/types/bsky'
|
||||
import {ChatDisabled} from './components/ChatDisabled'
|
||||
import {ChatEnded} from './components/ChatEnded'
|
||||
import {ChatLocked} from './components/ChatLocked'
|
||||
@@ -180,7 +180,8 @@ function InnerReady({
|
||||
const emailDialogControl = useEmailDialogControl()
|
||||
|
||||
const unreadRequestCount =
|
||||
convo?.kind === 'group' && ChatBskyConvoDefs.isGroupConvo(convo.view.kind)
|
||||
convo?.kind === 'group' &&
|
||||
isType(chat.bsky.convo.defs.groupConvo, convo.view.kind)
|
||||
? (convo.view.kind.unreadJoinRequestCount ?? 0)
|
||||
: 0
|
||||
const {mutate: markJoinRequestsRead} = useMarkJoinRequestsRead(convo?.view.id)
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvoRequests,
|
||||
ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||
import {
|
||||
@@ -44,6 +39,8 @@ import {ListFooter} from '#/components/Lists'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {chat} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {IncomingRequestListItem} from './components/IncomingRequestListItem'
|
||||
import {OutgoingRequestListItem} from './components/OutgoingRequestListItem'
|
||||
import {useIsWithinSplitView} from './components/splitView/context'
|
||||
@@ -51,8 +48,8 @@ import {useIsWithinSplitView} from './components/splitView/context'
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'MessagesInbox'>
|
||||
|
||||
type RequestItem =
|
||||
| {type: 'incoming'; view: ChatBskyConvoDefs.ConvoView}
|
||||
| {type: 'outgoing'; view: ChatBskyGroupDefs.JoinRequestConvoView}
|
||||
| {type: 'incoming'; view: chat.bsky.convo.defs.ConvoView}
|
||||
| {type: 'outgoing'; view: chat.bsky.group.defs.JoinRequestConvoView}
|
||||
|
||||
export function MessagesInboxScreen(props: Props) {
|
||||
const {t: l} = useLingui()
|
||||
@@ -75,9 +72,11 @@ export function MessagesInboxScreenInner({}: Props) {
|
||||
const items: RequestItem[] = []
|
||||
for (const page of data.pages) {
|
||||
for (const item of page.requests) {
|
||||
if (ChatBskyConvoDefs.isConvoView(item)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.convoView, item)) {
|
||||
items.push({type: 'incoming', view: item})
|
||||
} else if (ChatBskyGroupDefs.isJoinRequestConvoView(item)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item)
|
||||
) {
|
||||
items.push({type: 'outgoing', view: item})
|
||||
}
|
||||
}
|
||||
@@ -112,7 +111,7 @@ function RequestList({
|
||||
conversations,
|
||||
}: {
|
||||
listConvosQuery: UseInfiniteQueryResult<
|
||||
InfiniteData<ChatBskyConvoListConvoRequests.OutputSchema>,
|
||||
InfiniteData<chat.bsky.convo.listConvoRequests.$OutputBody>,
|
||||
Error
|
||||
>
|
||||
conversations: RequestItem[]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useEffect} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {ImageBackground} from 'expo-image'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {type ThemeName} from '@bsky.app/alf'
|
||||
import {moderateProfile} from '@bsky.app/sdk/moderation'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
@@ -21,7 +20,8 @@ import {PersonGroup_Stroke2_Corner2_Rounded as PersonGroupIcon} from '#/componen
|
||||
import {ProfileBadges} from '#/components/ProfileBadges'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
const desktopDarkBg = require('../../../assets/images/chat-desktop-bg-dark.webp')
|
||||
const desktopDimBg = require('../../../assets/images/chat-desktop-bg-dim.webp')
|
||||
@@ -85,7 +85,10 @@ export function JoinRequest({setScreenState}: Props) {
|
||||
]}>
|
||||
{error ||
|
||||
(data &&
|
||||
!ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) ? (
|
||||
!bsky.isType(
|
||||
chat.bsky.group.defs.joinLinkPreviewView,
|
||||
joinLinkPreview,
|
||||
)) ? (
|
||||
<Wrapper>
|
||||
<ChainLinkBrokenIcon fill={t.palette.primary_500} size="3xl" />
|
||||
<Text
|
||||
@@ -102,7 +105,10 @@ export function JoinRequest({setScreenState}: Props) {
|
||||
</Wrapper>
|
||||
) : data &&
|
||||
moderationOpts &&
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview) ? (
|
||||
bsky.isType(
|
||||
chat.bsky.group.defs.joinLinkPreviewView,
|
||||
joinLinkPreview,
|
||||
) ? (
|
||||
<Wrapper>
|
||||
<AvatarBubbles
|
||||
profiles={[joinLinkPreview.owner]}
|
||||
@@ -183,7 +189,7 @@ export function JoinRequest({setScreenState}: Props) {
|
||||
true,
|
||||
// TODO(phase4): drop toLex once join link preview emits #/lexicons views
|
||||
moderateProfile(
|
||||
toLex(joinLinkPreview.owner),
|
||||
bsky.toLex(joinLinkPreview.owner),
|
||||
moderationOpts,
|
||||
).ui('displayName'),
|
||||
)}
|
||||
@@ -223,7 +229,7 @@ export function JoinRequest({setScreenState}: Props) {
|
||||
joinLinkPreview.owner,
|
||||
true,
|
||||
moderateProfile(
|
||||
toLex(joinLinkPreview.owner),
|
||||
bsky.toLex(joinLinkPreview.owner),
|
||||
moderationOpts,
|
||||
).ui('displayName'),
|
||||
)} follows can join.`}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyGroupListJoinRequests} from '@atproto/api'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {type InfiniteData, useQueryClient} from '@tanstack/react-query'
|
||||
@@ -40,6 +39,7 @@ import * as ProfileCard from '#/components/ProfileCard'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type chat} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {InviteLinkDialog} from './components/InviteLinkDialog'
|
||||
|
||||
@@ -139,7 +139,7 @@ function JoinRequestsList({
|
||||
|
||||
const getRemainingRequestCount = () => {
|
||||
const data = queryClient.getQueryData<
|
||||
InfiniteData<ChatBskyGroupListJoinRequests.OutputSchema>
|
||||
InfiniteData<chat.bsky.group.listJoinRequests.$OutputBody>
|
||||
>(createListJoinRequestsQueryKey({convoId}))
|
||||
return data?.pages.reduce((sum, page) => sum + page.requests.length, 0) ?? 0
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {type GestureResponderEvent, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {
|
||||
moderateProfile,
|
||||
type ModerationDecision,
|
||||
@@ -65,7 +64,7 @@ export function ChatListItem({
|
||||
selected = false,
|
||||
children,
|
||||
}: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
showMenu?: boolean
|
||||
selected?: boolean
|
||||
children?: React.ReactNode
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
@@ -8,13 +7,14 @@ import {atoms as a, tokens} from '#/alf'
|
||||
import {parseConvoView} from '#/components/dms/util'
|
||||
import {KnownFollowers} from '#/components/KnownFollowers'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type chat} from '#/lexicons'
|
||||
import {ChatListItem, ChatListItemPortal} from './ChatListItem'
|
||||
import {AcceptChatButton, DeleteChatButton, RejectMenu} from './RequestButtons'
|
||||
|
||||
export function IncomingRequestListItem({
|
||||
convo: convoView,
|
||||
}: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
}) {
|
||||
const {currentAccount} = useSession()
|
||||
const moderationOpts = useModerationOpts()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {Image} from 'expo-image'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {moderateProfile, type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
@@ -34,6 +33,7 @@ import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type chat} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {CopyTextButton} from './CopyTextButton'
|
||||
import {EditTextButton} from './EditTextButton'
|
||||
@@ -561,13 +561,13 @@ export function InviteLinkDialog({
|
||||
)
|
||||
}
|
||||
|
||||
function joinLinkToKey(joinLink: ChatBskyGroupDefs.JoinLinkView): string {
|
||||
function joinLinkToKey(joinLink: chat.bsky.group.defs.JoinLinkView): string {
|
||||
return `${joinLink.joinRule}${joinLink.requireApproval ? ':requireApproval' : ''}`
|
||||
}
|
||||
|
||||
function keyToJoinLink(
|
||||
key: string,
|
||||
): Pick<ChatBskyGroupDefs.JoinLinkView, 'joinRule' | 'requireApproval'> {
|
||||
): Pick<chat.bsky.group.defs.JoinLinkView, 'joinRule' | 'requireApproval'> {
|
||||
const [joinRule, requireApproval] = key.split(':')
|
||||
return {
|
||||
joinRule,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||
import {LayoutAnimation, View} from 'react-native'
|
||||
import {AppBskyRichtextFacet, RichText as RichTextAPI} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {moderatePost} from '@bsky.app/sdk/moderation'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {type RouteProp, useNavigation, useRoute} from '@react-navigation/native'
|
||||
|
||||
@@ -103,7 +103,7 @@ export function useExtractEmbedFromFacets(
|
||||
for (const facet of rt.facets ?? []) {
|
||||
for (const feature of facet.features) {
|
||||
if (
|
||||
AppBskyRichtextFacet.isLink(feature) &&
|
||||
bsky.isType(app.bsky.richtext.facet.link, feature) &&
|
||||
(isBskyPostUrl(feature.uri) || isBskyChatInviteUrl(feature.uri))
|
||||
) {
|
||||
uriFromFacet = feature.uri
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {LayoutAnimation, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {HITSLOP_20} from '#/lib/constants'
|
||||
@@ -11,6 +10,7 @@ import {useMessageReplies} from '#/components/dms/MessageReplies'
|
||||
import {useReplyPreviewText} from '#/components/dms/replyPreview'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type chat} from '#/lexicons'
|
||||
|
||||
/**
|
||||
* The reply staged in the message composer. Renders a preview of the message
|
||||
@@ -29,7 +29,7 @@ export function MessageInputReply() {
|
||||
function MessageInputReplyInner({
|
||||
replyTo,
|
||||
}: {
|
||||
replyTo: ChatBskyConvoDefs.MessageView
|
||||
replyTo: chat.bsky.convo.defs.MessageView
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
@@ -12,11 +11,12 @@ import {createStaticClick, Link} from '#/components/Link'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type chat} from '#/lexicons'
|
||||
|
||||
export function OutgoingRequestListItem({
|
||||
convo: convoView,
|
||||
}: {
|
||||
convo: ChatBskyGroupDefs.JoinRequestConvoView
|
||||
convo: chat.bsky.group.defs.JoinRequestConvoView
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback} from 'react'
|
||||
import {type ChatBskyActorDefs, type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
@@ -58,7 +57,7 @@ export function RejectMenu({
|
||||
label?: string
|
||||
icon?: boolean
|
||||
convo: ConvoWithDetails
|
||||
profile: ChatBskyActorDefs.ProfileViewBasic
|
||||
profile: chat.bsky.actor.defs.ProfileViewBasic
|
||||
showDeleteConvo?: boolean
|
||||
currentScreen: 'list' | 'conversation'
|
||||
}) {
|
||||
@@ -216,7 +215,7 @@ export function AcceptChatButton({
|
||||
}: Omit<ButtonProps, 'onPress' | 'children' | 'label'> & {
|
||||
label?: string
|
||||
icon?: boolean
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
onAcceptConvo?: () => void
|
||||
currentScreen: 'list' | 'conversation'
|
||||
}) {
|
||||
@@ -314,7 +313,7 @@ export function DeleteChatButton({
|
||||
}: Omit<ButtonProps, 'children' | 'label'> & {
|
||||
label?: string
|
||||
icon?: boolean
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
currentScreen: 'list' | 'conversation'
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -68,8 +69,8 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
||||
const allowUI = useMemo(() => {
|
||||
return threadgateRecordToAllowUISetting({
|
||||
$type: 'app.bsky.feed.threadgate',
|
||||
post: '',
|
||||
createdAt: new Date().toString(),
|
||||
post: '' as AtUriString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
allow: preferences.postInteractionSettings.threadgateAllowRules,
|
||||
})
|
||||
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {useCallback, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyActorProfile,
|
||||
type AppBskyGraphDefs,
|
||||
type Un$Typed,
|
||||
} from '@atproto/api'
|
||||
import {TID} from '@atproto/common-web'
|
||||
import {type Un$Typed} from '@atproto/lex'
|
||||
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
|
||||
import {
|
||||
overwriteSavedFeeds,
|
||||
setInterestsPref,
|
||||
upsertProfile,
|
||||
} from '@bsky.app/sdk'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -25,7 +26,7 @@ import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-p
|
||||
import {getAllListMembers} from '#/state/queries/list-members'
|
||||
import {preferencesQueryKey} from '#/state/queries/preferences'
|
||||
import {RQKEY as profileRQKey} from '#/state/queries/profile'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useAppviewClient, usePdsClient} from '#/state/session'
|
||||
import {useOnboardingDispatch} from '#/state/shell'
|
||||
import {
|
||||
useActiveStarterPack,
|
||||
@@ -57,7 +58,8 @@ export function StepFinished() {
|
||||
const onboardDispatch = useOnboardingDispatch()
|
||||
const [saving, setSaving] = useState(false)
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const pdsClient = usePdsClient()
|
||||
const appviewClient = useAppviewClient()
|
||||
const requestNotificationsPermission = useRequestNotificationsPermission()
|
||||
const activeStarterPack = useActiveStarterPack()
|
||||
const setActiveStarterPack = useSetActiveStarterPack()
|
||||
@@ -67,22 +69,25 @@ export function StepFinished() {
|
||||
const finishOnboarding = useCallback(async () => {
|
||||
setSaving(true)
|
||||
|
||||
let starterPack: AppBskyGraphDefs.StarterPackView | undefined
|
||||
let listItems: AppBskyGraphDefs.ListItemView[] | undefined
|
||||
let starterPack: app.bsky.graph.defs.StarterPackView | undefined
|
||||
let listItems: app.bsky.graph.defs.ListItemView[] | undefined
|
||||
|
||||
if (activeStarterPack?.uri) {
|
||||
try {
|
||||
const spRes = await agent.app.bsky.graph.getStarterPack({
|
||||
starterPack: activeStarterPack.uri,
|
||||
const spRes = await appviewClient.call(app.bsky.graph.getStarterPack, {
|
||||
starterPack: activeStarterPack.uri as AtUriString,
|
||||
})
|
||||
starterPack = spRes.data.starterPack
|
||||
starterPack = spRes.starterPack
|
||||
} catch (e) {
|
||||
logger.error('Failed to fetch starter pack', {safeMessage: e})
|
||||
// don't tell the user, just get them through onboarding.
|
||||
}
|
||||
try {
|
||||
if (starterPack?.list) {
|
||||
listItems = await getAllListMembers(agent, starterPack.list.uri)
|
||||
listItems = await getAllListMembers(
|
||||
appviewClient,
|
||||
starterPack.list.uri,
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Failed to fetch starter pack list items', {
|
||||
@@ -98,7 +103,8 @@ export function StepFinished() {
|
||||
|
||||
await Promise.all([
|
||||
bulkWriteFollows(
|
||||
agent,
|
||||
pdsClient,
|
||||
appviewClient,
|
||||
[BSKY_APP_ACCOUNT_DID, ...(listItems?.map(i => i.subject.did) ?? [])],
|
||||
starterPack
|
||||
? {uri: starterPack.uri, cid: starterPack.cid}
|
||||
@@ -106,10 +112,10 @@ export function StepFinished() {
|
||||
),
|
||||
(async () => {
|
||||
// Interests need to get saved first, then we can write the feeds to prefs
|
||||
await agent.setInterestsPref({tags: selectedInterests})
|
||||
await pdsClient.call(setInterestsPref, {tags: selectedInterests})
|
||||
|
||||
// Default feeds that every user should have pinned when landing in the app
|
||||
const feedsToSave: AppBskyActorDefs.SavedFeed[] = [
|
||||
const feedsToSave: app.bsky.actor.defs.SavedFeed[] = [
|
||||
{
|
||||
...DISCOVER_SAVED_FEED,
|
||||
id: TID.nextStr(),
|
||||
@@ -128,7 +134,7 @@ export function StepFinished() {
|
||||
if (starterPack && starterPack.feeds?.length) {
|
||||
feedsToSave.push(
|
||||
...starterPack.feeds.map(f => ({
|
||||
type: 'feed',
|
||||
type: 'feed' as const,
|
||||
value: f.uri,
|
||||
pinned: true,
|
||||
id: TID.nextStr(),
|
||||
@@ -136,22 +142,22 @@ export function StepFinished() {
|
||||
)
|
||||
}
|
||||
|
||||
await agent.overwriteSavedFeeds(feedsToSave)
|
||||
await pdsClient.call(overwriteSavedFeeds, feedsToSave)
|
||||
})(),
|
||||
(async () => {
|
||||
const {imageUri, imageMime} = profileStepResults
|
||||
const blobPromise =
|
||||
imageUri && imageMime
|
||||
? uploadBlob(agent, imageUri, imageMime)
|
||||
? uploadBlob(pdsClient, imageUri, imageMime)
|
||||
: undefined
|
||||
|
||||
await agent.upsertProfile(async existing => {
|
||||
let next: Un$Typed<AppBskyActorProfile.Record> = existing ?? {}
|
||||
await pdsClient.call(upsertProfile, async existing => {
|
||||
let next: Un$Typed<app.bsky.actor.profile.Main> = existing ?? {}
|
||||
|
||||
if (blobPromise) {
|
||||
const res = await blobPromise
|
||||
if (res.data.blob) {
|
||||
next.avatar = res.data.blob
|
||||
if (res.blob) {
|
||||
next.avatar = res.blob
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +171,7 @@ export function StepFinished() {
|
||||
next.displayName = ''
|
||||
|
||||
if (!next.createdAt) {
|
||||
next.createdAt = new Date().toISOString()
|
||||
next.createdAt = toDatetimeString(new Date())
|
||||
}
|
||||
return next
|
||||
})
|
||||
@@ -192,7 +198,7 @@ export function StepFinished() {
|
||||
queryKey: preferencesQueryKey,
|
||||
}),
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: profileRQKey(agent.session?.did ?? ''),
|
||||
queryKey: profileRQKey(pdsClient.did ?? ''),
|
||||
}),
|
||||
]).catch(e => {
|
||||
logger.error(e)
|
||||
@@ -227,7 +233,8 @@ export function StepFinished() {
|
||||
}, [
|
||||
ax,
|
||||
queryClient,
|
||||
agent,
|
||||
pdsClient,
|
||||
appviewClient,
|
||||
dispatch,
|
||||
onboardDispatch,
|
||||
activeStarterPack,
|
||||
|
||||
@@ -14,7 +14,7 @@ import {logger} from '#/logger'
|
||||
import {updateProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useLanguagePrefs} from '#/state/preferences'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useAppviewClient, usePdsClient, useSession} from '#/state/session'
|
||||
import {
|
||||
OnboardingControls,
|
||||
OnboardingPosition,
|
||||
@@ -42,7 +42,8 @@ export function StepSuggestedAccounts() {
|
||||
const t = useTheme()
|
||||
const {gtMobile} = useBreakpoints()
|
||||
const moderationOpts = useModerationOpts()
|
||||
const agent = useAgent()
|
||||
const pdsClient = usePdsClient()
|
||||
const appviewClient = useAppviewClient()
|
||||
const {currentAccount} = useSession()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
@@ -119,7 +120,10 @@ export function StepSuggestedAccounts() {
|
||||
followingUri: 'pending',
|
||||
})
|
||||
}
|
||||
const uris = await wait(1e3, bulkWriteFollows(agent, followableDids))
|
||||
const uris = await wait(
|
||||
1e3,
|
||||
bulkWriteFollows(pdsClient, appviewClient, followableDids),
|
||||
)
|
||||
for (const did of followableDids) {
|
||||
const uri = uris.get(did)
|
||||
updateProfileShadow(queryClient, did, {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -11,7 +10,7 @@ import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted'
|
||||
import {logger} from '#/logger'
|
||||
import {updateProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {getAllListMembers} from '#/state/queries/list-members'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useAppviewClient, usePdsClient, useSession} from '#/state/session'
|
||||
import {bulkWriteFollows} from '#/screens/Onboarding/util'
|
||||
import {AvatarStack} from '#/screens/Search/components/StarterPackCard'
|
||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||
@@ -29,14 +28,15 @@ const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp'
|
||||
export function StarterPackCard({
|
||||
view,
|
||||
}: {
|
||||
view: AppBskyGraphDefs.StarterPackView
|
||||
view: app.bsky.graph.defs.StarterPackView
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
const {currentAccount} = useSession()
|
||||
const {gtPhone} = useBreakpoints()
|
||||
const agent = useAgent()
|
||||
const pdsClient = usePdsClient()
|
||||
const appviewClient = useAppviewClient()
|
||||
const queryClient = useQueryClient()
|
||||
const record = view.record
|
||||
const [isProcessing, setIsProcessing] = useState(false)
|
||||
@@ -47,9 +47,9 @@ export function StarterPackCard({
|
||||
|
||||
setIsProcessing(true)
|
||||
|
||||
let listItems: AppBskyGraphDefs.ListItemView[] = []
|
||||
let listItems: app.bsky.graph.defs.ListItemView[] = []
|
||||
try {
|
||||
listItems = await getAllListMembers(agent, view.list.uri)
|
||||
listItems = await getAllListMembers(appviewClient, view.list.uri)
|
||||
} catch (e) {
|
||||
setIsProcessing(false)
|
||||
Toast.show(_(msg`An error occurred while trying to follow all`), {
|
||||
@@ -74,7 +74,7 @@ export function StarterPackCard({
|
||||
|
||||
let followUris: Map<string, string>
|
||||
try {
|
||||
followUris = await bulkWriteFollows(agent, dids, {
|
||||
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
|
||||
uri: view.uri,
|
||||
cid: view.cid,
|
||||
})
|
||||
|
||||
@@ -1,37 +1,34 @@
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyGraphFollow,
|
||||
type AppBskyGraphGetFollows,
|
||||
type ComAtprotoRepoApplyWrites,
|
||||
type ComAtprotoRepoStrongRef,
|
||||
} from '@atproto/api'
|
||||
import {TID} from '@atproto/common-web'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {type Client} from '@atproto/lex-client'
|
||||
import {
|
||||
type AtIdentifierString,
|
||||
type DidString,
|
||||
toDatetimeString,
|
||||
} from '@atproto/syntax'
|
||||
import chunk from 'lodash.chunk'
|
||||
|
||||
import {until} from '#/lib/async/until'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {app, com} from '#/lexicons'
|
||||
|
||||
export async function bulkWriteFollows(
|
||||
agent: SessionAgent,
|
||||
pdsClient: Client,
|
||||
appviewClient: Client,
|
||||
dids: string[],
|
||||
via?: ComAtprotoRepoStrongRef.Main,
|
||||
via?: com.atproto.repo.strongRef.Main,
|
||||
) {
|
||||
const session = agent.session
|
||||
const did = pdsClient.assertDid
|
||||
|
||||
if (!session) {
|
||||
throw new Error(`bulkWriteFollows failed: no session`)
|
||||
}
|
||||
|
||||
const followRecords: $Typed<AppBskyGraphFollow.Record>[] = dids.map(did => {
|
||||
const followRecords: $Typed<app.bsky.graph.follow.Main>[] = dids.map(did => {
|
||||
return {
|
||||
$type: 'app.bsky.graph.follow',
|
||||
subject: did,
|
||||
createdAt: new Date().toISOString(),
|
||||
subject: did as DidString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
via,
|
||||
}
|
||||
})
|
||||
|
||||
const followWrites: $Typed<ComAtprotoRepoApplyWrites.Create>[] =
|
||||
const followWrites: $Typed<com.atproto.repo.applyWrites.Create>[] =
|
||||
followRecords.map(r => ({
|
||||
$type: 'com.atproto.repo.applyWrites#create',
|
||||
collection: 'app.bsky.graph.follow',
|
||||
@@ -41,35 +38,35 @@ export async function bulkWriteFollows(
|
||||
|
||||
const chunks = chunk(followWrites, 50)
|
||||
for (const chunk of chunks) {
|
||||
await agent.com.atproto.repo.applyWrites({
|
||||
repo: session.did,
|
||||
await pdsClient.call(com.atproto.repo.applyWrites, {
|
||||
repo: did,
|
||||
writes: chunk,
|
||||
})
|
||||
}
|
||||
await whenFollowsIndexed(agent, session.did, res => !!res.data.follows.length)
|
||||
await whenFollowsIndexed(appviewClient, did, res => !!res.follows.length)
|
||||
|
||||
const followUris = new Map<string, string>()
|
||||
for (const r of followWrites) {
|
||||
followUris.set(
|
||||
r.value.subject as string,
|
||||
`at://${session.did}/app.bsky.graph.follow/${r.rkey}`,
|
||||
`at://${did}/app.bsky.graph.follow/${r.rkey}`,
|
||||
)
|
||||
}
|
||||
return followUris
|
||||
}
|
||||
|
||||
async function whenFollowsIndexed(
|
||||
agent: SessionAgent,
|
||||
appviewClient: Client,
|
||||
actor: string,
|
||||
fn: (res: AppBskyGraphGetFollows.Response) => boolean,
|
||||
fn: (res: app.bsky.graph.getFollows.$OutputBody) => boolean,
|
||||
) {
|
||||
await until(
|
||||
5, // 5 tries
|
||||
1e3, // 1s delay between tries
|
||||
fn,
|
||||
() =>
|
||||
agent.app.bsky.graph.getFollows({
|
||||
actor,
|
||||
appviewClient.call(app.bsky.graph.getFollows, {
|
||||
actor: actor as AtIdentifierString,
|
||||
limit: 1,
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {moderateProfile} from '@bsky.app/sdk/moderation'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
@@ -16,6 +15,7 @@ import {useFormatPostStatCount} from '#/components/PostControls/util'
|
||||
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
|
||||
const AVI_SIZE = 20
|
||||
@@ -24,7 +24,7 @@ const AVI_SIZE = 20
|
||||
* The plain "N likes" stat for the expanded anchor post, linking to the likes
|
||||
* list. Renders nothing when the post has no likes.
|
||||
*/
|
||||
export function LikesStat({post}: {post: AppBskyFeedDefs.PostView}) {
|
||||
export function LikesStat({post}: {post: app.bsky.feed.defs.PostView}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
const formatPostStatCount = useFormatPostStatCount()
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import {memo, useMemo} from 'react'
|
||||
import {Text as RNText, View} from 'react-native'
|
||||
import {
|
||||
AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
type AppBskyFeedThreadgate,
|
||||
} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
@@ -69,7 +64,7 @@ export function ThreadItemAnchor({
|
||||
}: {
|
||||
item: Extract<ThreadItem, {type: 'threadPost'}>
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
postSource?: PostSource
|
||||
}) {
|
||||
const postShadow = usePostShadow(item.value.post)
|
||||
@@ -170,9 +165,9 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
||||
}: {
|
||||
item: Extract<ThreadItem, {type: 'threadPost'}>
|
||||
isRoot: boolean
|
||||
postShadow: Shadow<AppBskyFeedDefs.PostView>
|
||||
postShadow: Shadow<app.bsky.feed.defs.PostView>
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
postSource?: PostSource
|
||||
}) {
|
||||
const t = useTheme()
|
||||
@@ -236,7 +231,11 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
|
||||
const viaRepost = useMemo(() => {
|
||||
const reason = postSource?.post.reason
|
||||
|
||||
if (AppBskyFeedDefs.isReasonRepost(reason) && reason.uri && reason.cid) {
|
||||
if (
|
||||
bsky.isType(app.bsky.feed.defs.reasonRepost, reason) &&
|
||||
reason.uri &&
|
||||
reason.cid
|
||||
) {
|
||||
return {
|
||||
uri: reason.uri,
|
||||
cid: reason.cid,
|
||||
@@ -558,7 +557,7 @@ function ExpandedPostDetails({
|
||||
)
|
||||
}
|
||||
|
||||
function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
|
||||
function BackdatedPostIndicator({post}: {post: app.bsky.feed.defs.PostView}) {
|
||||
const t = useTheme()
|
||||
const {t: l, i18n} = useLingui()
|
||||
const control = Prompt.usePromptControl()
|
||||
@@ -645,8 +644,8 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
|
||||
}
|
||||
|
||||
function getThreadAuthor(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
record: AppBskyFeedPost.Record,
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
record: app.bsky.feed.post.Main,
|
||||
): string {
|
||||
if (!record.reply) {
|
||||
return post.author.did
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -18,6 +17,7 @@ import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Che
|
||||
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import {GrowthHack} from './GrowthHack'
|
||||
|
||||
export function ThreadItemAnchorFollowButton({
|
||||
@@ -57,7 +57,7 @@ export function ThreadItemAnchorFollowButtonInner({
|
||||
function PostThreadFollowBtnLoaded({
|
||||
profile: profileUnshadowed,
|
||||
}: {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
}) {
|
||||
const navigation = useNavigation()
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, type ReactNode, useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyFeedDefs, type AppBskyFeedThreadgate} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -45,6 +44,7 @@ import * as Skele from '#/components/Skeleton'
|
||||
import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useActorStatus} from '#/features/liveNow'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export type ThreadItemPostProps = {
|
||||
item: Extract<ThreadItem, {type: 'threadPost'}>
|
||||
@@ -53,7 +53,7 @@ export type ThreadItemPostProps = {
|
||||
topBorder?: boolean
|
||||
}
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
}
|
||||
|
||||
export function ThreadItemPost({
|
||||
@@ -185,7 +185,7 @@ const ThreadItemPostInner = memo(function ThreadItemPostInner({
|
||||
onPostSuccess,
|
||||
threadgateRecord,
|
||||
}: ThreadItemPostProps & {
|
||||
postShadow: Shadow<AppBskyFeedDefs.PostView>
|
||||
postShadow: Shadow<app.bsky.feed.defs.PostView>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {openComposer} = useOpenComposer()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyFeedDefs, type AppBskyFeedThreadgate} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -41,6 +40,7 @@ import {RichText} from '#/components/RichText'
|
||||
import * as Skele from '#/components/Skeleton'
|
||||
import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
/**
|
||||
* Mimic the space in PostMeta
|
||||
@@ -59,7 +59,7 @@ export function ThreadItemTreePost({
|
||||
topBorder?: boolean
|
||||
}
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
}) {
|
||||
const postShadow = usePostShadow(item.value.post)
|
||||
|
||||
@@ -242,13 +242,13 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({
|
||||
threadgateRecord,
|
||||
}: {
|
||||
item: Extract<ThreadItem, {type: 'threadPost'}>
|
||||
postShadow: Shadow<AppBskyFeedDefs.PostView>
|
||||
postShadow: Shadow<app.bsky.feed.defs.PostView>
|
||||
overrides?: {
|
||||
moderation?: boolean
|
||||
topBorder?: boolean
|
||||
}
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
}): React.ReactNode {
|
||||
const {openComposer} = useOpenComposer()
|
||||
const {currentAccount} = useSession()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
@@ -8,12 +7,13 @@ import {type Shadow} from '#/state/cache/types'
|
||||
import {atoms as a, platform, useBreakpoints, useTheme} from '#/alf'
|
||||
import {ProfileBadges} from '#/components/ProfileBadges'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function ProfileHeaderDisplayName({
|
||||
profile,
|
||||
moderation,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
moderation: ModerationDecision
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useEffect, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Plural, Trans} from '@lingui/react/macro'
|
||||
@@ -25,13 +24,14 @@ import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useSimpleVerificationState} from '#/components/verification'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function EditProfileDialog({
|
||||
profile,
|
||||
control,
|
||||
onUpdate,
|
||||
}: {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
control: Dialog.DialogControlProps
|
||||
onUpdate?: () => void
|
||||
}) {
|
||||
@@ -89,7 +89,7 @@ function DialogInner({
|
||||
setDirty,
|
||||
onPressCancel,
|
||||
}: {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
onUpdate?: () => void
|
||||
setDirty: (dirty: boolean) => void
|
||||
onPressCancel: () => void
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -10,12 +9,13 @@ import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {NewskieDialog} from '#/components/NewskieDialog'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS, IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function ProfileHeaderHandle({
|
||||
profile,
|
||||
disableTaps,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
disableTaps?: boolean
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg, plural} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
@@ -9,11 +8,12 @@ import {formatCount} from '#/view/com/util/numeric/format'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function ProfileHeaderMetrics({
|
||||
profile,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_, i18n} = useLingui()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, useCallback, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs, type AppBskyLabelerDefs} from '@atproto/api'
|
||||
import {moderateProfile, type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {msg, plural} from '@lingui/core/macro'
|
||||
@@ -33,6 +32,7 @@ import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_IOS} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {ProfileHeaderDisplayName} from './DisplayName'
|
||||
import {EditProfileDialog} from './EditProfileDialog'
|
||||
@@ -41,8 +41,8 @@ import {ProfileHeaderMetrics} from './Metrics'
|
||||
import {ProfileHeaderShell} from './Shell'
|
||||
|
||||
interface Props {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
labeler: AppBskyLabelerDefs.LabelerViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
labeler: app.bsky.labeler.defs.LabelerViewDetailed
|
||||
descriptionRT: RichTextAPI | null
|
||||
moderationOpts: ModerationOpts
|
||||
hideBackButton?: boolean
|
||||
@@ -57,7 +57,7 @@ let ProfileHeaderLabeler = ({
|
||||
hideBackButton = false,
|
||||
isPlaceholderProfile,
|
||||
}: Props): React.ReactNode => {
|
||||
const profile: Shadow<AppBskyActorDefs.ProfileViewDetailed> =
|
||||
const profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed> =
|
||||
useProfileShadow(profileUnshadowed)
|
||||
const t = useTheme()
|
||||
const ax = useAnalytics()
|
||||
@@ -231,7 +231,7 @@ export function HeaderLabelerButtons({
|
||||
profile,
|
||||
minimal = false,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
/** disable the subscribe button */
|
||||
minimal?: boolean
|
||||
}) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, useMemo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {
|
||||
moderateProfile,
|
||||
type ModerationDecision,
|
||||
@@ -40,6 +39,7 @@ import {useAnalytics} from '#/analytics'
|
||||
import {IS_IOS, IS_NATIVE} from '#/env'
|
||||
import {InviteFriendsDialog} from '#/features/inviteFriends'
|
||||
import {useActorStatus} from '#/features/liveNow'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {GermButton} from '../components/GermButton'
|
||||
import {ProfileHeaderDisplayName} from './DisplayName'
|
||||
@@ -50,7 +50,7 @@ import {ProfileHeaderShell} from './Shell'
|
||||
import {ProfileHeaderSuggestedFollows} from './SuggestedFollows'
|
||||
|
||||
interface Props {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
descriptionRT: RichTextAPI | null
|
||||
moderationOpts: ModerationOpts
|
||||
hideBackButton?: boolean
|
||||
@@ -65,7 +65,7 @@ let ProfileHeaderStandard = ({
|
||||
isPlaceholderProfile,
|
||||
}: Props): React.ReactNode => {
|
||||
const profile =
|
||||
useProfileShadow<AppBskyActorDefs.ProfileViewDetailed>(profileUnshadowed)
|
||||
useProfileShadow<app.bsky.actor.defs.ProfileViewDetailed>(profileUnshadowed)
|
||||
const {currentAccount} = useSession()
|
||||
const {_} = useLingui()
|
||||
const moderation = useMemo(
|
||||
@@ -214,7 +214,7 @@ export function HeaderStandardButtons({
|
||||
onUnfollow,
|
||||
minimal,
|
||||
}: {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
moderation: ModerationDecision
|
||||
moderationOpts: ModerationOpts
|
||||
onFollow?: () => void
|
||||
|
||||
@@ -5,7 +5,6 @@ import Animated, {
|
||||
useAnimatedRef,
|
||||
} from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {utils} from '@bsky.app/alf'
|
||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
@@ -32,12 +31,13 @@ import {useActorStatus} from '#/features/liveNow'
|
||||
import {EditLiveDialog} from '#/features/liveNow/components/EditLiveDialog'
|
||||
import {LiveIndicator} from '#/features/liveNow/components/LiveIndicator'
|
||||
import {LiveStatusDialog} from '#/features/liveNow/components/LiveStatusDialog'
|
||||
import {type app} from '#/lexicons'
|
||||
import {GrowableAvatar} from './GrowableAvatar'
|
||||
import {GrowableBanner} from './GrowableBanner'
|
||||
import {StatusBarShadow} from './StatusBarShadow'
|
||||
|
||||
interface Props {
|
||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
|
||||
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
|
||||
moderation: ModerationDecision
|
||||
hideBackButton?: boolean
|
||||
isPlaceholderProfile?: boolean
|
||||
|
||||
@@ -7,7 +7,6 @@ import Animated, {
|
||||
} from 'react-native-reanimated'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {scheduleOnRN} from 'react-native-worklets'
|
||||
import {type AppBskyActorDefs, type AppBskyLabelerDefs} from '@atproto/api'
|
||||
import {moderateProfile, type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {useIsFocused} from '@react-navigation/native'
|
||||
@@ -22,6 +21,7 @@ import {atoms as a, useTheme} from '#/alf'
|
||||
import {Header} from '#/components/Layout'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {
|
||||
HeaderLabelerButtons,
|
||||
@@ -57,8 +57,8 @@ ProfileHeaderLoading = memo(ProfileHeaderLoading)
|
||||
export {ProfileHeaderLoading}
|
||||
|
||||
interface Props {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
labeler: app.bsky.labeler.defs.LabelerViewDetailed | undefined
|
||||
descriptionRT: RichTextAPI | null
|
||||
moderationOpts: ModerationOpts
|
||||
hideBackButton?: boolean
|
||||
@@ -102,8 +102,8 @@ const MinimalHeader = memo(function MinimalHeader({
|
||||
hideBackButton = false,
|
||||
}: {
|
||||
onLayout: (e: LayoutChangeEvent) => void
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
labeler?: AppBskyLabelerDefs.LabelerViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
labeler?: app.bsky.labeler.defs.LabelerViewDetailed
|
||||
hideBackButton?: boolean
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
@@ -17,12 +16,13 @@ import {List} from '#/view/com/util/List'
|
||||
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
function renderItem({
|
||||
item,
|
||||
index,
|
||||
}: {
|
||||
item: AppBskyActorDefs.ProfileView
|
||||
item: app.bsky.actor.defs.ProfileView
|
||||
index: number
|
||||
}) {
|
||||
return (
|
||||
@@ -34,7 +34,7 @@ function renderItem({
|
||||
)
|
||||
}
|
||||
|
||||
function keyExtractor(item: AppBskyActorDefs.ProfileView) {
|
||||
function keyExtractor(item: app.bsky.actor.defs.ProfileView) {
|
||||
return item.did
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||
import {useAnimatedRef} from 'react-native-reanimated'
|
||||
import {AppBskyFeedDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useIsFocused} from '@react-navigation/native'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
@@ -175,7 +174,7 @@ export function ProfileFeedScreenInner({
|
||||
const isVideoFeed = useMemo(() => {
|
||||
const isBskyVideoFeed = VIDEO_FEED_URIS.includes(feedInfo.uri)
|
||||
const feedIsVideoMode =
|
||||
feedInfo.contentMode === AppBskyFeedDefs.CONTENTMODEVIDEO
|
||||
feedInfo.contentMode === 'app.bsky.feed.defs#contentModeVideo'
|
||||
const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode
|
||||
return IS_NATIVE && _isVideoFeed
|
||||
}, [feedInfo])
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useEffect, useImperativeHandle, useMemo} from 'react'
|
||||
import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import {type AppBskyLabelerDefs} from '@atproto/api'
|
||||
import {
|
||||
type InterpretedLabelValueDefinition,
|
||||
interpretLabelValueDefinitions,
|
||||
@@ -21,13 +20,14 @@ import {Loader} from '#/components/Loader'
|
||||
import {LabelerLabelPreference} from '#/components/moderation/LabelPreference'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_IOS, IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import {ErrorState} from '../ErrorState'
|
||||
import {type SectionRef} from './types'
|
||||
|
||||
interface LabelsSectionProps {
|
||||
ref: React.Ref<SectionRef>
|
||||
isLabelerLoading: boolean
|
||||
labelerInfo: AppBskyLabelerDefs.LabelerViewDetailed | undefined
|
||||
labelerInfo: app.bsky.labeler.defs.LabelerViewDetailed | undefined
|
||||
labelerError: Error | null
|
||||
moderationOpts: ModerationOpts
|
||||
scrollElRef: ListRef
|
||||
@@ -161,7 +161,7 @@ export function LabelerListHeader({
|
||||
}: {
|
||||
isLabelerLoading: boolean
|
||||
labelerError?: Error | null
|
||||
labelerInfo?: AppBskyLabelerDefs.LabelerViewDetailed
|
||||
labelerInfo?: app.bsky.labeler.defs.LabelerViewDetailed
|
||||
hasValues: boolean
|
||||
isSubscribed: boolean
|
||||
}) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useImperativeHandle, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -15,6 +14,7 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {BulletList_Stroke1_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList'
|
||||
import {PersonPlus_Stroke2_Corner0_Rounded as PersonPlusIcon} from '#/components/icons/Person'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
interface SectionRef {
|
||||
scrollToTop: () => void
|
||||
@@ -22,7 +22,7 @@ interface SectionRef {
|
||||
|
||||
interface AboutSectionProps {
|
||||
ref?: React.Ref<SectionRef>
|
||||
list: AppBskyGraphDefs.ListView
|
||||
list: app.bsky.graph.defs.ListView
|
||||
onPressAddUser: () => void
|
||||
headerHeight: number
|
||||
scrollElRef: ListRef
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useMemo} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {AppBskyGraphDefs} from '@atproto/api'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -24,6 +23,7 @@ import {Loader} from '#/components/Loader'
|
||||
import {RichText} from '#/components/RichText'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {MoreOptionsMenu} from './MoreOptionsMenu'
|
||||
import {SubscribeMenu} from './SubscribeMenu'
|
||||
@@ -34,14 +34,14 @@ export function Header({
|
||||
preferences,
|
||||
}: {
|
||||
rkey: string
|
||||
list: AppBskyGraphDefs.ListView
|
||||
list: app.bsky.graph.defs.ListView
|
||||
preferences: UsePreferencesQueryResponse
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
const {currentAccount} = useSession()
|
||||
const isCurateList = list.purpose === AppBskyGraphDefs.CURATELIST
|
||||
const isModList = list.purpose === AppBskyGraphDefs.MODLIST
|
||||
const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
|
||||
const isModList = list.purpose === 'app.bsky.graph.defs#modlist'
|
||||
const isBlocking = !!list.viewer?.blocked
|
||||
const isMuting = !!list.viewer?.muted
|
||||
const playHaptic = useHaptics()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -37,13 +36,14 @@ import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function MoreOptionsMenu({
|
||||
list,
|
||||
savedFeedConfig,
|
||||
}: {
|
||||
list: AppBskyGraphDefs.ListView
|
||||
savedFeedConfig?: AppBskyActorDefs.SavedFeed
|
||||
list: app.bsky.graph.defs.ListView
|
||||
savedFeedConfig?: app.bsky.actor.defs.SavedFeed
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
@@ -58,8 +58,8 @@ export function MoreOptionsMenu({
|
||||
const {mutateAsync: muteList} = useListMuteMutation()
|
||||
const {mutateAsync: blockList} = useListBlockMutation()
|
||||
|
||||
const isCurateList = list.purpose === AppBskyGraphDefs.CURATELIST
|
||||
const isModList = list.purpose === AppBskyGraphDefs.MODLIST
|
||||
const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
|
||||
const isModList = list.purpose === 'app.bsky.graph.defs#modlist'
|
||||
const isBlocking = !!list.viewer?.blocked
|
||||
const isMuting = !!list.viewer?.muted
|
||||
const isPinned = Boolean(savedFeedConfig?.pinned)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -13,8 +12,9 @@ import * as Menu from '#/components/Menu'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function SubscribeMenu({list}: {list: AppBskyGraphDefs.ListView}) {
|
||||
export function SubscribeMenu({list}: {list: app.bsky.graph.defs.ListView}) {
|
||||
const {_} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
const subscribeMutePromptControl = Prompt.usePromptControl()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {useAnimatedRef} from 'react-native-reanimated'
|
||||
import {AppBskyGraphDefs} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {moderateUserList, type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
@@ -39,6 +38,7 @@ import * as Layout from '#/components/Layout'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Hider from '#/components/moderation/Hider'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import {toLex} from '#/types/bsky'
|
||||
import {AboutSection} from './AboutSection'
|
||||
import {ErrorScreen} from './components/ErrorScreen'
|
||||
@@ -144,7 +144,7 @@ function ProfileListScreenLoaded({
|
||||
preferences,
|
||||
}: Props & {
|
||||
uri: string
|
||||
list: AppBskyGraphDefs.ListView
|
||||
list: app.bsky.graph.defs.ListView
|
||||
moderationOpts: ModerationOpts
|
||||
preferences: UsePreferencesQueryResponse
|
||||
}) {
|
||||
@@ -156,7 +156,7 @@ function ProfileListScreenLoaded({
|
||||
const {rkey} = route.params
|
||||
const feedSectionRef = useRef<SectionRef>(null)
|
||||
const aboutSectionRef = useRef<SectionRef>(null)
|
||||
const isCurateList = list.purpose === AppBskyGraphDefs.CURATELIST
|
||||
const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
|
||||
const isScreenFocused = useIsFocused()
|
||||
const isHidden = list.labels?.findIndex(l => l.val === '!hide') !== -1
|
||||
const isOwner = currentAccount?.did === list.creator.did
|
||||
|
||||
@@ -2,7 +2,6 @@ import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import type Animated from 'react-native-reanimated'
|
||||
import {useAnimatedRef, useScrollOffset} from 'react-native-reanimated'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {TID} from '@atproto/common-web'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -43,6 +42,7 @@ import {InlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
|
||||
export function SavedFeeds({}: Props) {
|
||||
@@ -424,10 +424,10 @@ function PinnedFeedItem({
|
||||
onMoveUp,
|
||||
onMoveDown,
|
||||
}: {
|
||||
feed: AppBskyActorDefs.SavedFeed
|
||||
currentFeeds: AppBskyActorDefs.SavedFeed[]
|
||||
feed: app.bsky.actor.defs.SavedFeed
|
||||
currentFeeds: app.bsky.actor.defs.SavedFeed[]
|
||||
setCurrentFeeds: React.Dispatch<
|
||||
React.SetStateAction<AppBskyActorDefs.SavedFeed[]>
|
||||
React.SetStateAction<app.bsky.actor.defs.SavedFeed[]>
|
||||
>
|
||||
dragHandle?: React.ReactNode
|
||||
index?: number
|
||||
@@ -507,10 +507,10 @@ function UnpinnedFeedItem({
|
||||
currentFeeds,
|
||||
setCurrentFeeds,
|
||||
}: {
|
||||
feed: AppBskyActorDefs.SavedFeed
|
||||
currentFeeds: AppBskyActorDefs.SavedFeed[]
|
||||
feed: app.bsky.actor.defs.SavedFeed
|
||||
currentFeeds: app.bsky.actor.defs.SavedFeed[]
|
||||
setCurrentFeeds: React.Dispatch<
|
||||
React.SetStateAction<AppBskyActorDefs.SavedFeed[]>
|
||||
React.SetStateAction<app.bsky.actor.defs.SavedFeed[]>
|
||||
>
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||
import {View, type ViewabilityConfig} from 'react-native'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
import * as bcp47Match from 'bcp-47-match'
|
||||
@@ -68,6 +63,7 @@ import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type Metrics, useAnalytics} from '#/analytics'
|
||||
import {ExploreScreenLiveEventFeedsBanner} from '#/features/liveEvents/components/ExploreScreenLiveEventFeedsBanner'
|
||||
import {type app} from '#/lexicons'
|
||||
import * as ModuleHeader from './components/ModuleHeader'
|
||||
import {
|
||||
SuggestedAccountsTabBar,
|
||||
@@ -155,7 +151,7 @@ type ExploreScreenItems =
|
||||
| {
|
||||
type: 'profile'
|
||||
key: string
|
||||
profile: AppBskyActorDefs.ProfileView
|
||||
profile: app.bsky.actor.defs.ProfileView
|
||||
recId?: string
|
||||
}
|
||||
| {
|
||||
@@ -165,7 +161,7 @@ type ExploreScreenItems =
|
||||
| {
|
||||
type: 'feed'
|
||||
key: string
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
}
|
||||
| {
|
||||
type: 'loadMore'
|
||||
@@ -191,7 +187,7 @@ type ExploreScreenItems =
|
||||
| {
|
||||
type: 'starterPack'
|
||||
key: string
|
||||
view: AppBskyGraphDefs.StarterPackView
|
||||
view: app.bsky.graph.defs.StarterPackView
|
||||
}
|
||||
| {
|
||||
type: 'starterPackSkeleton'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, useCallback, useMemo, useState} from 'react'
|
||||
import {ActivityIndicator, View} from 'react-native'
|
||||
import {type AppBskyFeedDefs, type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {urls} from '#/lib/constants'
|
||||
@@ -37,6 +36,7 @@ import {ListFooter} from '#/components/Lists'
|
||||
import {SearchError} from '#/components/SearchError'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type Metrics, useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
let SearchResults = ({
|
||||
@@ -292,7 +292,7 @@ type SearchResultSlice =
|
||||
| {
|
||||
type: 'post'
|
||||
key: string
|
||||
post: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
}
|
||||
| {
|
||||
type: 'loadingMore'
|
||||
@@ -504,7 +504,7 @@ function SearchPost({
|
||||
}: {
|
||||
from: Metrics['search:result:press']['tab']
|
||||
position: Metrics['search:result:press']['position']
|
||||
post: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
}) {
|
||||
const ax = useAnalytics()
|
||||
|
||||
@@ -672,7 +672,7 @@ let SearchScreenFeedsResults = ({
|
||||
item,
|
||||
index,
|
||||
}: {
|
||||
item: AppBskyFeedDefs.GeneratorView
|
||||
item: app.bsky.feed.defs.GeneratorView
|
||||
index: number
|
||||
}) => (
|
||||
<View
|
||||
@@ -685,7 +685,7 @@ let SearchScreenFeedsResults = ({
|
||||
<SearchFeedCard position={index} view={item} />
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={(item: AppBskyFeedDefs.GeneratorView) => item.uri}
|
||||
keyExtractor={(item: app.bsky.feed.defs.GeneratorView) => item.uri}
|
||||
desktopFixedHeight
|
||||
ListFooterComponent={<ListFooter />}
|
||||
/>
|
||||
@@ -704,7 +704,7 @@ function SearchFeedCard({
|
||||
view,
|
||||
}: {
|
||||
position: number
|
||||
view: AppBskyFeedDefs.GeneratorView
|
||||
view: app.bsky.feed.defs.GeneratorView
|
||||
}) {
|
||||
const ax = useAnalytics()
|
||||
|
||||
@@ -790,14 +790,14 @@ let SearchScreenStarterPackResults = ({
|
||||
item,
|
||||
index,
|
||||
}: {
|
||||
item: AppBskyGraphDefs.StarterPackView
|
||||
item: app.bsky.graph.defs.StarterPackView
|
||||
index: number
|
||||
}) => (
|
||||
<View style={[a.px_lg, a.pb_lg, index === 0 && a.pt_lg]}>
|
||||
<SearchStarterPack position={index} view={item} />
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={(item: AppBskyGraphDefs.StarterPackView) => item.uri}
|
||||
keyExtractor={(item: app.bsky.graph.defs.StarterPackView) => item.uri}
|
||||
refreshing={isPTR}
|
||||
onRefresh={() => void onPullToRefresh()}
|
||||
onEndReached={onEndReached}
|
||||
@@ -824,7 +824,7 @@ function SearchStarterPack({
|
||||
view,
|
||||
}: {
|
||||
position: number
|
||||
view: AppBskyGraphDefs.StarterPackView
|
||||
view: app.bsky.graph.defs.StarterPackView
|
||||
}) {
|
||||
const ax = useAnalytics()
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useMemo} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
|
||||
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
||||
@@ -15,6 +14,7 @@ import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/component
|
||||
import {Link} from '#/components/Link'
|
||||
import {Text, type TextProps} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function Container({
|
||||
style,
|
||||
@@ -47,7 +47,7 @@ export function FeedLink({
|
||||
feed,
|
||||
children,
|
||||
}: {
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
children?: React.ReactNode
|
||||
}) {
|
||||
const t = useTheme()
|
||||
@@ -76,7 +76,7 @@ export function FeedLink({
|
||||
)
|
||||
}
|
||||
|
||||
export function FeedAvatar({feed}: {feed: AppBskyFeedDefs.GeneratorView}) {
|
||||
export function FeedAvatar({feed}: {feed: app.bsky.feed.defs.GeneratorView}) {
|
||||
return <UserAvatar type="algo" size={38} avatar={feed.avatar} />
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export function EllipsisButton({
|
||||
)
|
||||
}
|
||||
|
||||
export function PinButton({feed}: {feed: AppBskyFeedDefs.GeneratorView}) {
|
||||
export function PinButton({feed}: {feed: app.bsky.feed.defs.GeneratorView}) {
|
||||
return (
|
||||
<View style={[a.z_20, {marginRight: -6}]}>
|
||||
<FeedCard.SaveButton
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {moderateProfile} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -26,7 +25,7 @@ export function StarterPackCard({
|
||||
view,
|
||||
onPress,
|
||||
}: {
|
||||
view: AppBskyGraphDefs.StarterPackView
|
||||
view: app.bsky.graph.defs.StarterPackView
|
||||
onPress?: () => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {memo, useEffect} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorSearchActors} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -14,6 +13,7 @@ import {boostInterests, InterestTabs} from '#/components/InterestTabs'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export function useLoadEnoughProfiles({
|
||||
@@ -25,7 +25,7 @@ export function useLoadEnoughProfiles({
|
||||
fetchNextPage,
|
||||
}: {
|
||||
interest: string | null
|
||||
data?: InfiniteData<AppBskyActorSearchActors.OutputSchema>
|
||||
data?: InfiniteData<app.bsky.actor.searchActors.$OutputBody>
|
||||
isLoading: boolean
|
||||
isFetchingNextPage: boolean
|
||||
hasNextPage: boolean
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useMemo} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import {Image} from 'expo-image'
|
||||
import {type AppBskyUnspeccedDefs} from '@atproto/api'
|
||||
import {moderateProfile} from '@bsky.app/sdk/moderation'
|
||||
import {RichText as RichTextApi} from '@bsky.app/sdk/richtext'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
@@ -28,6 +27,7 @@ import {SubtleHover} from '#/components/SubtleHover'
|
||||
import {useTrendingTopicSeen} from '#/components/TrendingTopics'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type app} from '#/lexicons'
|
||||
import * as ModuleHeader from '../components/ModuleHeader'
|
||||
import {toLex} from '#/types/bsky'
|
||||
|
||||
@@ -119,7 +119,7 @@ export function TrendRow({
|
||||
children,
|
||||
onPress,
|
||||
}: ViewStyleProp & {
|
||||
trend: AppBskyUnspeccedDefs.TrendView
|
||||
trend: app.bsky.unspecced.defs.TrendView
|
||||
rank: number
|
||||
recId?: string
|
||||
children?: React.ReactNode
|
||||
@@ -230,7 +230,7 @@ export function TrendRow({
|
||||
|
||||
// Unused atm, but leaving here so we don't lose localization. -dsb
|
||||
export function useCategoryDisplayName(
|
||||
category: AppBskyUnspeccedDefs.TrendView['category'],
|
||||
category: app.bsky.unspecced.defs.TrendView['category'],
|
||||
) {
|
||||
const {t: l} = useLingui()
|
||||
|
||||
@@ -298,7 +298,7 @@ export function TrendingTopicRowSkeleton() {
|
||||
}
|
||||
|
||||
function useModerateTrendingActors(
|
||||
actors: AppBskyUnspeccedDefs.TrendView['actors'],
|
||||
actors: app.bsky.unspecced.defs.TrendView['actors'],
|
||||
) {
|
||||
const moderationOpts = useModerationOpts()
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useMemo} from 'react'
|
||||
import {ScrollView, View} from 'react-native'
|
||||
import {AppBskyEmbedVideo} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -22,6 +21,8 @@ import {
|
||||
CompactVideoPostCardPlaceholder,
|
||||
} from '#/components/VideoPostCard'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
const CARD_WIDTH = 100
|
||||
|
||||
@@ -159,7 +160,7 @@ function VideoCards({
|
||||
.flatMap(page => page.slices)
|
||||
.map(slice => slice.items[0])
|
||||
.filter(Boolean)
|
||||
.filter(item => AppBskyEmbedVideo.isView(item.post.embed))
|
||||
.filter(item => bsky.isType(app.bsky.embed.video.view, item.post.embed))
|
||||
.slice(0, 8)
|
||||
}, [data])
|
||||
const href = useMemo(() => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyNotificationDeclaration} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -18,6 +17,7 @@ import * as Toggle from '#/components/forms/Toggle'
|
||||
import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {type app} from '#/lexicons'
|
||||
import * as SettingsList from './components/SettingsList'
|
||||
import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle'
|
||||
|
||||
@@ -85,7 +85,7 @@ export function Inner({
|
||||
notificationDeclaration: {
|
||||
uri?: string
|
||||
cid?: string
|
||||
value: AppBskyNotificationDeclaration.Record
|
||||
value: app.bsky.notification.declaration.Main
|
||||
}
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -6,7 +6,6 @@ import Animated, {
|
||||
LayoutAnimationConfig,
|
||||
LinearTransition,
|
||||
} from 'react-native-reanimated'
|
||||
import {type ComAtprotoServerListAppPasswords} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -33,6 +32,7 @@ import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type com} from '#/lexicons'
|
||||
import {AddAppPasswordDialog} from './components/AddAppPasswordDialog'
|
||||
import * as SettingsList from './components/SettingsList'
|
||||
|
||||
@@ -135,7 +135,7 @@ export function AppPasswordsScreen({}: Props) {
|
||||
function AppPasswordCard({
|
||||
appPassword,
|
||||
}: {
|
||||
appPassword: ComAtprotoServerListAppPasswords.AppPassword
|
||||
appPassword: com.atproto.server.listAppPasswords.AppPassword
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {i18n, _} = useLingui()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {View} from 'react-native'
|
||||
import {type $Typed, type ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
@@ -54,15 +54,13 @@ export function AutomationLabelSettingsScreen({}: Props) {
|
||||
{
|
||||
profile,
|
||||
updates: existing => {
|
||||
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.matches(
|
||||
com.atproto.label.defs.selfLabels,
|
||||
existing.labels,
|
||||
)
|
||||
? existing.labels
|
||||
: {
|
||||
$type: 'com.atproto.label.defs#selfLabels',
|
||||
values: [],
|
||||
}
|
||||
const labels: $Typed<com.atproto.label.defs.SelfLabels> =
|
||||
bsky.matches(com.atproto.label.defs.selfLabels, existing.labels)
|
||||
? existing.labels
|
||||
: {
|
||||
$type: 'com.atproto.label.defs#selfLabels',
|
||||
values: [],
|
||||
}
|
||||
|
||||
const hasLabel = labels.values.some(l => l.val === 'bot')
|
||||
if (hasLabel) {
|
||||
@@ -82,7 +80,7 @@ export function AutomationLabelSettingsScreen({}: Props) {
|
||||
return existing
|
||||
},
|
||||
checkCommitted: res => {
|
||||
const exists = !!res.data.labels?.some(l => l.val === 'bot')
|
||||
const exists = !!res.labels?.some(l => l.val === 'bot')
|
||||
return exists === wasAdded
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import {useCallback, useEffect, useState} from 'react'
|
||||
import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import * as Contacts from 'expo-contacts'
|
||||
import {
|
||||
type AppBskyContactDefs,
|
||||
type AppBskyContactGetSyncStatus,
|
||||
} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -32,7 +28,12 @@ import {
|
||||
useContactsMatchesQuery,
|
||||
useContactsSyncStatusQuery,
|
||||
} from '#/state/queries/find-contacts'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {
|
||||
useAgent,
|
||||
useAppviewClient,
|
||||
usePdsClient,
|
||||
useSession,
|
||||
} from '#/state/session'
|
||||
import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
|
||||
import {List} from '#/view/com/util/List'
|
||||
import {atoms as a, tokens, useGutters, useTheme} from '#/alf'
|
||||
@@ -52,6 +53,7 @@ import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {InviteFriendsDialog} from '#/features/inviteFriends'
|
||||
import {app} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {bulkWriteFollows} from '../Onboarding/util'
|
||||
|
||||
@@ -190,7 +192,7 @@ function SyncStatus({
|
||||
info,
|
||||
refetchStatus,
|
||||
}: {
|
||||
info: AppBskyContactDefs.SyncStatus
|
||||
info: app.bsky.contact.defs.SyncStatus
|
||||
refetchStatus: () => Promise<any>
|
||||
}) {
|
||||
const ax = useAnalytics()
|
||||
@@ -370,7 +372,8 @@ function StatusHeader({
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
const agent = useAgent()
|
||||
const pdsClient = usePdsClient()
|
||||
const appviewClient = useAppviewClient()
|
||||
const queryClient = useQueryClient()
|
||||
const {currentAccount} = useSession()
|
||||
|
||||
@@ -384,12 +387,12 @@ function StatusHeader({
|
||||
|
||||
let cursor: string | undefined
|
||||
do {
|
||||
const page = await agent.app.bsky.contact.getMatches({
|
||||
const page = await appviewClient.call(app.bsky.contact.getMatches, {
|
||||
limit: 100,
|
||||
cursor,
|
||||
})
|
||||
cursor = page.data.cursor
|
||||
for (const profile of page.data.matches) {
|
||||
cursor = page.cursor
|
||||
for (const profile of page.matches) {
|
||||
if (
|
||||
profile.did !== currentAccount?.did &&
|
||||
!isBlockedOrBlocking(profile) &&
|
||||
@@ -405,7 +408,10 @@ function StatusHeader({
|
||||
followCount: didsToFollow.length,
|
||||
})
|
||||
|
||||
const uris = await wait(500, bulkWriteFollows(agent, didsToFollow))
|
||||
const uris = await wait(
|
||||
500,
|
||||
bulkWriteFollows(pdsClient, appviewClient, didsToFollow),
|
||||
)
|
||||
|
||||
for (const did of didsToFollow) {
|
||||
const uri = uris.get(did)
|
||||
@@ -497,7 +503,7 @@ function StatusFooter({syncedAt}: {syncedAt: string}) {
|
||||
onMutate: () => ax.metric('contacts:settings:removeData', {}),
|
||||
onSuccess: () => {
|
||||
Toast.show(_(msg`Contacts removed`))
|
||||
queryClient.setQueryData<AppBskyContactGetSyncStatus.OutputSchema>(
|
||||
queryClient.setQueryData<app.bsky.contact.getSyncStatus.$OutputBody>(
|
||||
findContactsStatusQueryKey,
|
||||
{syncStatus: undefined},
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyNotificationDeclaration} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -17,6 +16,7 @@ import {Key_Stroke2_Corner2_Rounded as KeyIcon} from '#/components/icons/Key'
|
||||
import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {type app} from '#/lexicons'
|
||||
import {Email2FAToggle} from './components/Email2FAToggle'
|
||||
import {PwiOptOut} from './components/PwiOptOut'
|
||||
import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle'
|
||||
@@ -146,7 +146,7 @@ function NotificationDeclaration({
|
||||
isError,
|
||||
}: {
|
||||
data?: {
|
||||
value: AppBskyNotificationDeclaration.Record
|
||||
value: app.bsky.notification.declaration.Main
|
||||
}
|
||||
isError?: boolean
|
||||
}) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useState} from 'react'
|
||||
import {Alert, LayoutAnimation, Linking, Pressable, View} from 'react-native'
|
||||
import {useReducedMotion} from 'react-native-reanimated'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {moderateProfile} from '@bsky.app/sdk/moderation'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
@@ -68,6 +67,7 @@ import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env'
|
||||
import {useActorStatus} from '#/features/liveNow'
|
||||
import {type app} from '#/lexicons'
|
||||
import {device, useStorage} from '#/storage'
|
||||
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
|
||||
import {toLex} from '#/types/bsky'
|
||||
@@ -321,7 +321,7 @@ export function SettingsScreen({}: Props) {
|
||||
function ProfilePreview({
|
||||
profile,
|
||||
}: {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {gtMobile} = useBreakpoints()
|
||||
@@ -609,7 +609,7 @@ function AccountRow({
|
||||
pendingDid,
|
||||
onPressSwitchAccount,
|
||||
}: {
|
||||
profile?: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile?: app.bsky.actor.defs.ProfileViewDetailed
|
||||
account: SessionAccount
|
||||
pendingDid: string | null
|
||||
onPressSwitchAccount: (
|
||||
|
||||
@@ -8,7 +8,6 @@ import Animated, {
|
||||
SlideInRight,
|
||||
SlideOutLeft,
|
||||
} from 'react-native-reanimated'
|
||||
import {type ComAtprotoServerCreateAppPassword} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -25,6 +24,7 @@ import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components
|
||||
import {SquareBehindSquare4_Stroke2_Corner0_Rounded as CopyIcon} from '#/components/icons/SquareBehindSquare4'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_WEB} from '#/env'
|
||||
import {type com} from '#/lexicons'
|
||||
import {CopyButton} from './CopyButton'
|
||||
|
||||
export function AddAppPasswordDialog({
|
||||
@@ -70,7 +70,7 @@ function CreateDialogInner({passwords}: {passwords: string[]}) {
|
||||
error: validationError,
|
||||
isPending,
|
||||
} = useMutation<
|
||||
ComAtprotoServerCreateAppPassword.AppPassword,
|
||||
com.atproto.server.createAppPassword.AppPassword,
|
||||
Error | DisplayableError
|
||||
>({
|
||||
mutationFn: async () => {
|
||||
|
||||
@@ -10,7 +10,6 @@ import Animated, {
|
||||
SlideOutLeft,
|
||||
SlideOutRight,
|
||||
} from 'react-native-reanimated'
|
||||
import {type ComAtprotoServerDescribeServer} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -46,6 +45,7 @@ import {InlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useSimpleVerificationState} from '#/components/verification'
|
||||
import {type com} from '#/lexicons'
|
||||
import {CopyButton} from './CopyButton'
|
||||
|
||||
export function ChangeHandleDialog({
|
||||
@@ -147,7 +147,7 @@ function ProvidedHandlePage({
|
||||
serviceInfo,
|
||||
goToOwnHandle,
|
||||
}: {
|
||||
serviceInfo: ComAtprotoServerDescribeServer.OutputSchema
|
||||
serviceInfo: com.atproto.server.describeServer.$OutputBody
|
||||
goToOwnHandle: () => void
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -4,11 +4,15 @@ import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent, useSession, useSessionApi} from '#/state/session'
|
||||
import {
|
||||
useAgent,
|
||||
useChatClient,
|
||||
useSession,
|
||||
useSessionApi,
|
||||
} from '#/state/session'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {type DialogOuterProps} from '#/components/Dialog'
|
||||
@@ -24,6 +28,7 @@ import {Loader} from '#/components/Loader'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as toast from '#/components/Toast'
|
||||
import {Span, Text} from '#/components/Typography'
|
||||
import {chat} from '#/lexicons'
|
||||
import {resetToTab} from '#/Navigation'
|
||||
|
||||
const WHITESPACE_RE = /\s/gu
|
||||
@@ -73,6 +78,7 @@ function DeleteAccountDialogInner({
|
||||
const {_} = useLingui()
|
||||
const cleanError = useCleanError()
|
||||
const agent = useAgent()
|
||||
const chatClient = useChatClient()
|
||||
const {currentAccount} = useSession()
|
||||
const {removeAccount} = useSessionApi()
|
||||
|
||||
@@ -112,13 +118,9 @@ function DeleteAccountDialogInner({
|
||||
throw new Error('Invalid did')
|
||||
}
|
||||
const token = confirmCode.replace(WHITESPACE_RE, '')
|
||||
// Inform chat service of intent to delete account.
|
||||
const {success} = await agent.chat.bsky.actor.deleteAccount(undefined, {
|
||||
headers: DM_SERVICE_HEADERS,
|
||||
})
|
||||
if (!success) {
|
||||
throw new Error('Failed to inform chat service of account deletion')
|
||||
}
|
||||
// Inform chat service of intent to delete account. The chat client is
|
||||
// proxied to the chat service; a failure throws.
|
||||
await chatClient.call(chat.bsky.actor.deleteAccount)
|
||||
await agent.com.atproto.server.deleteAccount({
|
||||
did: currentAccount.did,
|
||||
password,
|
||||
|
||||
@@ -2,7 +2,6 @@ import {useCallback, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {saveBytesToDisk} from '#/lib/media/manip'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
@@ -14,6 +13,7 @@ import {InlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {CHAT_PROXY_DID} from '#/env'
|
||||
|
||||
export function ExportCarDialog({
|
||||
control,
|
||||
@@ -58,9 +58,11 @@ export function ExportCarDialog({
|
||||
setLoading('chat')
|
||||
// Using raw fetch because the XRPC client incorrectly tries to JSON-parse
|
||||
// application/jsonl responses (substring match on application/json).
|
||||
// The chat-service proxy header is inlined here (the endpoint is proxied
|
||||
// to `did:web:api.bsky.chat`); this raw path bypasses the lex client.
|
||||
const res = await agent.sessionManager.fetchHandler(
|
||||
'/xrpc/chat.bsky.actor.exportAccountData',
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
{headers: {'atproto-proxy': `${CHAT_PROXY_DID}#bsky_chat`}},
|
||||
)
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {useCallback} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type $Typed, type ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -36,7 +36,7 @@ export function PwiOptOut() {
|
||||
profile,
|
||||
updates: existing => {
|
||||
// create labels attr if needed
|
||||
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.matches(
|
||||
const labels: $Typed<com.atproto.label.defs.SelfLabels> = bsky.matches(
|
||||
com.atproto.label.defs.selfLabels,
|
||||
existing.labels,
|
||||
)
|
||||
@@ -70,9 +70,7 @@ export function PwiOptOut() {
|
||||
return existing
|
||||
},
|
||||
checkCommitted: res => {
|
||||
const exists = !!res.data.labels?.some(
|
||||
l => l.val === '!no-unauthenticated',
|
||||
)
|
||||
const exists = !!res.labels?.some(l => l.val === '!no-unauthenticated')
|
||||
return exists === wasAdded
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import {type ComAtprotoTempCheckHandleAvailability} from '@atproto/api'
|
||||
import {Sift, SiftItem} from '@bsky.app/sift'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Portal} from '#/components/Portal'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type HandleSuggestionsProps} from './shared'
|
||||
import {type HandleSuggestion, type HandleSuggestionsProps} from './shared'
|
||||
|
||||
type Suggestion = ComAtprotoTempCheckHandleAvailability.Suggestion & {
|
||||
type Suggestion = HandleSuggestion & {
|
||||
key: string
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
import {type ComAtprotoTempCheckHandleAvailability} from '@atproto/api'
|
||||
import {type UseSiftReturn} from '@bsky.app/sift'
|
||||
|
||||
/**
|
||||
* A handle suggestion from `com.atproto.temp.checkHandleAvailability`. The
|
||||
* unspecced temp lexicon isn't generated into `#/lexicons`, so we describe the
|
||||
* shape locally (mirrors `#/state/queries/handle-availability`).
|
||||
*/
|
||||
export type HandleSuggestion = {
|
||||
$type?: 'com.atproto.temp.checkHandleAvailability#suggestion'
|
||||
handle: string
|
||||
/**
|
||||
* Method used to build this suggestion. Should be considered opaque to
|
||||
* clients. Can be used for metrics.
|
||||
*/
|
||||
method: string
|
||||
}
|
||||
|
||||
export type HandleSuggestionsProps = {
|
||||
suggestions: ComAtprotoTempCheckHandleAvailability.Suggestion[]
|
||||
onSelect: (
|
||||
suggestion: ComAtprotoTempCheckHandleAvailability.Suggestion,
|
||||
) => void
|
||||
suggestions: HandleSuggestion[]
|
||||
onSelect: (suggestion: HandleSuggestion) => void
|
||||
/**
|
||||
* Web only: the Sift instance shared with the handle input. It carries the
|
||||
* anchor/positioning refs and keyboard bindings for the floating dropdown.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {type ReactElement} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type ComAtprotoServerDescribeServer} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -9,11 +8,12 @@ import {atoms as a, useTheme} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type com} from '#/lexicons'
|
||||
|
||||
export const Policies = ({
|
||||
serviceDescription,
|
||||
}: {
|
||||
serviceDescription: ComAtprotoServerDescribeServer.OutputSchema
|
||||
serviceDescription: com.atproto.server.describeServer.$OutputBody
|
||||
}) => {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import {createContext, useCallback, useContext} from 'react'
|
||||
import {LayoutAnimation} from 'react-native'
|
||||
import {
|
||||
ComAtprotoServerCreateAccount,
|
||||
type ComAtprotoServerDescribeServer,
|
||||
} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import * as EmailValidator from 'email-validator'
|
||||
|
||||
@@ -11,11 +7,13 @@ import {DEFAULT_SERVICE} from '#/lib/constants'
|
||||
import {cleanError, isNetworkError} from '#/lib/strings/errors'
|
||||
import {createFullHandle} from '#/lib/strings/handles'
|
||||
import {getAge} from '#/lib/strings/time'
|
||||
import {getErrorName} from '#/lib/xrpc-error'
|
||||
import {useSessionApi} from '#/state/session'
|
||||
import {useOnboardingDispatch} from '#/state/shell'
|
||||
import {type AnalyticsContextType, useAnalytics} from '#/analytics'
|
||||
import {type com} from '#/lexicons'
|
||||
|
||||
export type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
|
||||
export type ServiceDescription = com.atproto.server.describeServer.$OutputBody
|
||||
|
||||
const date = new Date()
|
||||
date.setFullYear(date.getFullYear() - 20) // default to 20 years ago
|
||||
@@ -357,7 +355,7 @@ export function useSubmitSignup() {
|
||||
} catch (err) {
|
||||
const e = err as Error
|
||||
let errMsg = e.toString()
|
||||
if (e instanceof ComAtprotoServerCreateAccount.InvalidInviteCodeError) {
|
||||
if (getErrorName(e) === 'InvalidInviteCode') {
|
||||
dispatch({
|
||||
type: 'setError',
|
||||
value: l`Invite code not accepted. Check that you input it correctly and try again.`,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
|
||||
import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
@@ -70,8 +69,8 @@ export function LandingScreen({
|
||||
const isValid =
|
||||
starterPack &&
|
||||
starterPack.list &&
|
||||
AppBskyGraphDefs.validateStarterPackView(starterPack) &&
|
||||
AppBskyGraphStarterpack.validateRecord(starterPack.record)
|
||||
bsky.matches(app.bsky.graph.defs.starterPackView, starterPack) &&
|
||||
bsky.matches(app.bsky.graph.starterpack, starterPack.record)
|
||||
|
||||
useEffect(() => {
|
||||
if (isErrorStarterPack || (starterPack && !isValid)) {
|
||||
@@ -106,8 +105,8 @@ function LandingScreenLoaded({
|
||||
|
||||
moderationOpts,
|
||||
}: {
|
||||
starterPack: AppBskyGraphDefs.StarterPackView
|
||||
starterPackRecord: AppBskyGraphStarterpack.Record
|
||||
starterPack: app.bsky.graph.defs.StarterPackView
|
||||
starterPackRecord: app.bsky.graph.starterpack.Main
|
||||
setScreenState: (state: LoggedOutScreenState) => void
|
||||
moderationOpts: ModerationOpts
|
||||
}) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useCallback, useEffect, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {Image} from 'expo-image'
|
||||
import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
@@ -33,7 +32,7 @@ import {
|
||||
useDeleteStarterPackMutation,
|
||||
useStarterPackQuery,
|
||||
} from '#/state/queries/starter-packs'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useAppviewClient, usePdsClient, useSession} from '#/state/session'
|
||||
import {useSetActiveStarterPack} from '#/state/shell/landing'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {
|
||||
@@ -147,8 +146,8 @@ export function StarterPackScreenInner({
|
||||
const isValid =
|
||||
starterPack &&
|
||||
(starterPack.list || starterPack?.creator?.did === currentAccount?.did) &&
|
||||
AppBskyGraphDefs.validateStarterPackView(starterPack) &&
|
||||
AppBskyGraphStarterpack.validateRecord(starterPack.record)
|
||||
bsky.matches(app.bsky.graph.defs.starterPackView, starterPack) &&
|
||||
bsky.matches(app.bsky.graph.starterpack, starterPack.record)
|
||||
|
||||
if (!did || !starterPack || !isValid || !moderationOpts) {
|
||||
return (
|
||||
@@ -179,7 +178,7 @@ function StarterPackScreenLoaded({
|
||||
routeParams,
|
||||
moderationOpts,
|
||||
}: {
|
||||
starterPack: AppBskyGraphDefs.StarterPackView
|
||||
starterPack: app.bsky.graph.defs.StarterPackView
|
||||
routeParams: StarterPackScreeProps['route']['params']
|
||||
moderationOpts: ModerationOpts
|
||||
}) {
|
||||
@@ -301,14 +300,15 @@ function Header({
|
||||
routeParams,
|
||||
onOpenShareDialog,
|
||||
}: {
|
||||
starterPack: AppBskyGraphDefs.StarterPackView
|
||||
starterPack: app.bsky.graph.defs.StarterPackView
|
||||
routeParams: StarterPackScreeProps['route']['params']
|
||||
onOpenShareDialog: () => void
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
const {currentAccount, hasSession} = useSession()
|
||||
const agent = useAgent()
|
||||
const pdsClient = usePdsClient()
|
||||
const appviewClient = useAppviewClient()
|
||||
const queryClient = useQueryClient()
|
||||
const setActiveStarterPack = useSetActiveStarterPack()
|
||||
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
||||
@@ -349,9 +349,9 @@ function Header({
|
||||
|
||||
setIsProcessing(true)
|
||||
|
||||
let listItems: AppBskyGraphDefs.ListItemView[] = []
|
||||
let listItems: app.bsky.graph.defs.ListItemView[] = []
|
||||
try {
|
||||
listItems = await getAllListMembers(agent, starterPack.list.uri)
|
||||
listItems = await getAllListMembers(appviewClient, starterPack.list.uri)
|
||||
} catch (e) {
|
||||
setIsProcessing(false)
|
||||
Toast.show(_(msg`An error occurred while trying to follow all`), {
|
||||
@@ -375,7 +375,7 @@ function Header({
|
||||
|
||||
let followUris: Map<string, string>
|
||||
try {
|
||||
followUris = await bulkWriteFollows(agent, dids, {
|
||||
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
|
||||
uri: starterPack.uri,
|
||||
cid: starterPack.cid,
|
||||
})
|
||||
@@ -516,7 +516,7 @@ function OverflowMenu({
|
||||
routeParams,
|
||||
onOpenShareDialog,
|
||||
}: {
|
||||
starterPack: AppBskyGraphDefs.StarterPackView
|
||||
starterPack: app.bsky.graph.defs.StarterPackView
|
||||
routeParams: StarterPackScreeProps['route']['params']
|
||||
onOpenShareDialog: () => void
|
||||
}) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {createContext, useContext, useReducer} from 'react'
|
||||
import {type AppBskyFeedDefs, type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {msg, plural} from '@lingui/core/macro'
|
||||
|
||||
import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||
@@ -18,7 +17,7 @@ type Action =
|
||||
| {type: 'SetDescription'; description: string}
|
||||
| {type: 'AddProfile'; profile: bsky.profile.AnyProfileView}
|
||||
| {type: 'RemoveProfile'; profileDid: string}
|
||||
| {type: 'AddFeed'; feed: AppBskyFeedDefs.GeneratorView}
|
||||
| {type: 'AddFeed'; feed: app.bsky.feed.defs.GeneratorView}
|
||||
| {type: 'RemoveFeed'; feedUri: string}
|
||||
| {type: 'SetProcessing'; processing: boolean}
|
||||
| {type: 'SetError'; error: string}
|
||||
@@ -29,7 +28,7 @@ interface State {
|
||||
name?: string
|
||||
description?: string
|
||||
profiles: bsky.profile.AnyProfileView[]
|
||||
feeds: AppBskyFeedDefs.GeneratorView[]
|
||||
feeds: app.bsky.feed.defs.GeneratorView[]
|
||||
processing: boolean
|
||||
error?: string
|
||||
transitionDirection: 'Backward' | 'Forward'
|
||||
@@ -122,8 +121,8 @@ export function Provider({
|
||||
targetProfile,
|
||||
children,
|
||||
}: {
|
||||
starterPack?: AppBskyGraphDefs.StarterPackView
|
||||
listItems?: AppBskyGraphDefs.ListItemView[]
|
||||
starterPack?: app.bsky.graph.defs.StarterPackView
|
||||
listItems?: app.bsky.graph.defs.ListItemView[]
|
||||
targetProfile: bsky.profile.AnyProfileView
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {useState} from 'react'
|
||||
import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
@@ -21,8 +20,9 @@ import {Loader} from '#/components/Loader'
|
||||
import {ScreenTransition} from '#/components/ScreenTransition'
|
||||
import {WizardFeedCard} from '#/components/StarterPack/Wizard/WizardListCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
function keyExtractor(item: AppBskyFeedDefs.GeneratorView) {
|
||||
function keyExtractor(item: app.bsky.feed.defs.GeneratorView) {
|
||||
return item.uri
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) {
|
||||
useSavedFeeds()
|
||||
const savedFeeds = savedFeedsAndLists?.feeds
|
||||
.filter(f => f.type === 'feed' && f.view.uri !== DISCOVER_FEED_URI)
|
||||
.map(f => f.view) as AppBskyFeedDefs.GeneratorView[]
|
||||
.map(f => f.view) as app.bsky.feed.defs.GeneratorView[]
|
||||
|
||||
const {
|
||||
data: popularFeedsPages,
|
||||
@@ -67,7 +67,7 @@ export function StepFeeds({moderationOpts}: {moderationOpts: ModerationOpts}) {
|
||||
|
||||
const renderItem = ({
|
||||
item,
|
||||
}: ListRenderItemInfo<AppBskyFeedDefs.GeneratorView>) => {
|
||||
}: ListRenderItemInfo<app.bsky.feed.defs.GeneratorView>) => {
|
||||
return (
|
||||
<WizardFeedCard
|
||||
generator={item}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {ScreenTransition} from '#/components/ScreenTransition'
|
||||
import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
function keyExtractor(item: bsky.profile.AnyProfileView) {
|
||||
|
||||
@@ -3,11 +3,6 @@ import {Keyboard, View} from 'react-native'
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||
import {Image} from 'expo-image'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
@@ -58,6 +53,7 @@ import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {type app} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {Provider} from './State'
|
||||
|
||||
@@ -159,9 +155,9 @@ function WizardInner({
|
||||
fromDialog,
|
||||
onSuccess,
|
||||
}: {
|
||||
currentStarterPack?: AppBskyGraphDefs.StarterPackView
|
||||
currentListItems?: AppBskyGraphDefs.ListItemView[]
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
currentStarterPack?: app.bsky.graph.defs.StarterPackView
|
||||
currentListItems?: app.bsky.graph.defs.ListItemView[]
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
moderationOpts: ModerationOpts
|
||||
fromDialog?: boolean
|
||||
onSuccess?: () => void
|
||||
@@ -625,7 +621,7 @@ function Footer({
|
||||
}
|
||||
|
||||
function getName(
|
||||
item: bsky.profile.AnyProfileView | AppBskyFeedDefs.GeneratorView,
|
||||
item: bsky.profile.AnyProfileView | app.bsky.feed.defs.GeneratorView,
|
||||
) {
|
||||
if (typeof item.displayName === 'string') {
|
||||
return enforceLen(sanitizeDisplayName(item.displayName), 28, true)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {type ListRenderItemInfo, View} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
@@ -21,12 +20,15 @@ import {Button, ButtonIcon} from '#/components/Button'
|
||||
import {ArrowOutOfBoxModified_Stroke2_Corner2_Rounded as Share} from '#/components/icons/ArrowOutOfBox'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
const renderItem = ({item}: ListRenderItemInfo<AppBskyFeedDefs.PostView>) => {
|
||||
const renderItem = ({
|
||||
item,
|
||||
}: ListRenderItemInfo<app.bsky.feed.defs.PostView>) => {
|
||||
return <Post post={item} />
|
||||
}
|
||||
|
||||
const keyExtractor = (item: AppBskyFeedDefs.PostView, index: number) => {
|
||||
const keyExtractor = (item: app.bsky.feed.defs.PostView, index: number) => {
|
||||
return `${item.uri}-${index}`
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import {useEvent, useEventListener} from 'expo'
|
||||
import {Image, type ImageStyle} from 'expo-image'
|
||||
import {LinearGradient} from 'expo-linear-gradient'
|
||||
import {createVideoPlayer, type VideoPlayer, VideoView} from 'expo-video'
|
||||
import {AppBskyEmbedVideo, type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
@@ -172,8 +171,8 @@ type CurrentSource = {
|
||||
|
||||
type VideoItem = {
|
||||
moderation: ModerationDecision
|
||||
post: AppBskyFeedDefs.PostView
|
||||
video: AppBskyEmbedVideo.View
|
||||
post: app.bsky.feed.defs.PostView
|
||||
video: app.bsky.embed.video.View
|
||||
feedContext: string | undefined
|
||||
reqId: string | undefined
|
||||
}
|
||||
@@ -211,8 +210,8 @@ function Feed() {
|
||||
const items: {
|
||||
_reactKey: string
|
||||
moderation: ModerationDecision
|
||||
post: AppBskyFeedDefs.PostView
|
||||
video: AppBskyEmbedVideo.View
|
||||
post: app.bsky.feed.defs.PostView
|
||||
video: app.bsky.embed.video.View
|
||||
feedContext: string | undefined
|
||||
reqId: string | undefined
|
||||
}[] = []
|
||||
@@ -220,7 +219,10 @@ function Feed() {
|
||||
const feedPost = slice.items.find(
|
||||
item => item.uri === slice.feedPostUri,
|
||||
)
|
||||
if (feedPost && AppBskyEmbedVideo.isView(feedPost.post.embed)) {
|
||||
if (
|
||||
feedPost &&
|
||||
bsky.isType(app.bsky.embed.video.view, feedPost.post.embed)
|
||||
) {
|
||||
items.push({
|
||||
_reactKey: feedPost._reactKey,
|
||||
moderation: feedPost.moderation,
|
||||
@@ -289,14 +291,14 @@ function Feed() {
|
||||
const prevPost = prevSlice?.post
|
||||
const prevEmbed = prevPost?.embed
|
||||
const prevVideo =
|
||||
prevEmbed && AppBskyEmbedVideo.isView(prevEmbed)
|
||||
prevEmbed && bsky.isType(app.bsky.embed.video.view, prevEmbed)
|
||||
? prevEmbed.playlist
|
||||
: null
|
||||
const currSlice = videos.at(index)
|
||||
const currPost = currSlice?.post
|
||||
const currEmbed = currPost?.embed
|
||||
const currVideo =
|
||||
currEmbed && AppBskyEmbedVideo.isView(currEmbed)
|
||||
currEmbed && bsky.isType(app.bsky.embed.video.view, currEmbed)
|
||||
? currEmbed.playlist
|
||||
: null
|
||||
const currVideoModeration = currSlice?.moderation
|
||||
@@ -304,7 +306,7 @@ function Feed() {
|
||||
const nextPost = nextSlice?.post
|
||||
const nextEmbed = nextPost?.embed
|
||||
const nextVideo =
|
||||
nextEmbed && AppBskyEmbedVideo.isView(nextEmbed)
|
||||
nextEmbed && bsky.isType(app.bsky.embed.video.view, nextEmbed)
|
||||
? nextEmbed.playlist
|
||||
: null
|
||||
|
||||
@@ -474,8 +476,8 @@ let VideoItem = ({
|
||||
reqId,
|
||||
}: {
|
||||
player?: VideoPlayer
|
||||
post: AppBskyFeedDefs.PostView
|
||||
embed: AppBskyEmbedVideo.View
|
||||
post: app.bsky.feed.defs.PostView
|
||||
embed: app.bsky.embed.video.View
|
||||
active: boolean
|
||||
adjacent: boolean
|
||||
scrollGesture: NativeGesture
|
||||
@@ -579,7 +581,7 @@ function VideoItemInner({
|
||||
active,
|
||||
}: {
|
||||
player: VideoPlayer
|
||||
embed: AppBskyEmbedVideo.View
|
||||
embed: app.bsky.embed.video.View
|
||||
active: boolean
|
||||
}) {
|
||||
const {bottom} = useSafeAreaInsets()
|
||||
@@ -681,7 +683,7 @@ function ModerationOverlay({
|
||||
embed,
|
||||
onPressShow,
|
||||
}: {
|
||||
embed: AppBskyEmbedVideo.View
|
||||
embed: app.bsky.embed.video.View
|
||||
onPressShow: () => void
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
@@ -779,8 +781,8 @@ function Overlay({
|
||||
reqId,
|
||||
}: {
|
||||
player?: VideoPlayer
|
||||
post: Shadow<AppBskyFeedDefs.PostView>
|
||||
embed: AppBskyEmbedVideo.View
|
||||
post: Shadow<app.bsky.feed.defs.PostView>
|
||||
embed: app.bsky.embed.video.View
|
||||
active: boolean
|
||||
scrollGesture: NativeGesture
|
||||
moderation: ModerationDecision
|
||||
@@ -1062,7 +1064,7 @@ function VideoItemPlaceholder({
|
||||
style,
|
||||
blur,
|
||||
}: {
|
||||
embed: AppBskyEmbedVideo.View
|
||||
embed: app.bsky.embed.video.View
|
||||
style?: ImageStyle
|
||||
blur?: boolean
|
||||
}) {
|
||||
@@ -1103,7 +1105,7 @@ function PlayPauseTapArea({
|
||||
reqId,
|
||||
}: {
|
||||
player: VideoPlayer
|
||||
post: Shadow<AppBskyFeedDefs.PostView>
|
||||
post: Shadow<app.bsky.feed.defs.PostView>
|
||||
feedContext: string | undefined
|
||||
reqId: string | undefined
|
||||
}) {
|
||||
@@ -1245,7 +1247,9 @@ function EndMessage() {
|
||||
/*
|
||||
* If the video is taller than 9:16
|
||||
*/
|
||||
function isTallAspectRatio(aspectRatio: AppBskyEmbedVideo.View['aspectRatio']) {
|
||||
function isTallAspectRatio(
|
||||
aspectRatio: app.bsky.embed.video.View['aspectRatio'],
|
||||
) {
|
||||
const videoAspectRatio =
|
||||
(aspectRatio?.width ?? 1) / (aspectRatio?.height ?? 1)
|
||||
return videoAspectRatio <= 9 / 16
|
||||
|
||||
Reference in New Issue
Block a user