[SDK] Remove @atproto/api (#11386)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-08-13 22:26:22 +03:00
committed by GitHub
parent 54da80dfb0
commit 9fe0084874
391 changed files with 3130 additions and 3589 deletions
+10 -12
View File
@@ -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,6 @@
import {useCallback, useMemo, useState} from 'react'
import {View} from 'react-native'
import {AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {TRENDING_HANDLE} from '#/lib/constants'
+2 -2
View File
@@ -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'
@@ -39,6 +38,7 @@ import {EditBig_Stroke2_Corner2_Rounded as EditBigIcon} from '#/components/icons
import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag'
import * as Layout from '#/components/Layout'
import {IS_NATIVE} from '#/env'
import {app} from '#/lexicons'
import {
CustomFeedHeader,
CustomFeedHeaderSkeleton,
@@ -175,7 +175,7 @@ export function CustomFeedScreenInner({
const isVideoFeed = useMemo(() => {
const isBskyVideoFeed = VIDEO_FEED_URIS.includes(feedInfo.uri)
const feedIsVideoMode =
feedInfo.contentMode === AppBskyFeedDefs.CONTENTMODEVIDEO
feedInfo.contentMode === app.bsky.feed.defs.contentModeVideo.value
const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode
return IS_NATIVE && _isVideoFeed
}, [feedInfo])
+5 -3
View File
@@ -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}`
}
+3 -3
View File
@@ -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 {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.value
const [isProcessing, setIsProcessing] = useState(false)
const listBlockMutation = useListBlockMutation()
+2 -2
View File
@@ -1,6 +1,5 @@
import {useRef, useState} from 'react'
import {Keyboard, type TextInput, View} from 'react-native'
import {type ComAtprotoServerDescribeServer} from '@atproto/api'
import {LexAuthFactorError} from '@atproto/lex-password-session'
import {Trans, useLingui} from '@lingui/react/macro'
@@ -33,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,
+3 -3
View File
@@ -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
}
+5 -3
View File
@@ -1,11 +1,11 @@
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,
} from '@bsky.app/expo-scroll-edge-effect'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {
type RouteProp,
@@ -18,7 +18,6 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {useViewportZoomLock} from '#/lib/hooks/useViewportZoomLock'
import {moderateProfile} from '#/lib/moderation/subjects'
import {
type CommonNavigatorParams,
type NavigationProp,
@@ -46,6 +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 {chat} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {ChatDisabled} from './components/ChatDisabled'
import {ChatEnded} from './components/ChatEnded'
import {ChatLocked} from './components/ChatLocked'
@@ -179,7 +180,8 @@ function InnerReady({
const emailDialogControl = useEmailDialogControl()
const unreadRequestCount =
convo?.kind === 'group' && ChatBskyConvoDefs.isGroupConvo(convo.view.kind)
convo?.kind === 'group' &&
bsky.isType(chat.bsky.convo.defs.groupConvo, convo.view.kind)
? (convo.view.kind.unreadJoinRequestCount ?? 0)
: 0
const {mutate: markJoinRequestsRead} = useMarkJoinRequestsRead(convo?.view.id)
@@ -1,9 +1,9 @@
import {View} from 'react-native'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {logger} from '#/logger'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -1,6 +1,5 @@
import {useEffect, useState} from 'react'
import {Pressable, View} from 'react-native'
import {ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
@@ -171,15 +170,12 @@ function keyExtractor(item: Item) {
}
function isGroupMember(
member: ChatBskyActorDefs.ProfileViewBasic,
member: chat.bsky.actor.defs.ProfileViewBasic,
): member is GroupConvoMember {
// Kind is missing when the account has been deleted.
return (
member.kind === undefined ||
bsky.dangerousIsType<ChatBskyActorDefs.GroupConvoMember>(
member.kind,
ChatBskyActorDefs.isGroupConvoMember,
)
bsky.isType(chat.bsky.actor.defs.groupConvoMember, member.kind)
)
}
@@ -415,7 +411,7 @@ function SettingsHeader({
isPending: isLocking,
} = useLockConvo(convoId, {
onSuccess: (data, {silent}) => {
if (!ChatBskyConvoDefs.isGroupConvo(data.convo.kind)) return
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, data.convo.kind)) return
if (silent) return
if (data.convo.kind.lockStatus === 'locked') {
ax.metric('groupchat:owner:lock', {convoId})
+9 -10
View File
@@ -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[]
+11 -4
View File
@@ -1,12 +1,11 @@
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'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useJoinLinkPreviewsQuery} from '#/state/queries/join-links'
@@ -21,6 +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 {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')
@@ -84,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
@@ -101,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]}
+1 -2
View File
@@ -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'
@@ -140,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, useState} from 'react'
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {ToolsOzoneReportDefs} from '@atproto/api'
import {type DidString} from '@atproto/syntax'
import {Trans, useLingui} from '@lingui/react/macro'
import {useMutation} from '@tanstack/react-query'
@@ -15,7 +14,7 @@ import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons
import {Loader} from '#/components/Loader'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {com} from '#/lexicons'
import {com, tools} from '#/lexicons'
export function ChatDisabled({
shape = 'pill',
@@ -104,7 +103,7 @@ function DialogInner() {
await client.call(
com.atproto.moderation.createReport,
{
reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
reasonType: tools.ozone.report.defs.reasonAppeal.value,
subject: {
$type: 'com.atproto.admin.defs#repoRef',
// the persisted account did is already resolved
@@ -1,7 +1,7 @@
import {useCallback, useMemo, useState} from 'react'
import {type GestureResponderEvent, View} from 'react-native'
import {ChatBskyConvoDefs} from '@atproto/api'
import {
moderateProfile,
type ModerationDecision,
type ModerationOpts,
} from '@bsky.app/sdk/moderation'
@@ -12,7 +12,6 @@ import {useQueryClient} from '@tanstack/react-query'
import {GestureActionView} from '#/lib/custom-animations/GestureActionView'
import {useHaptics} from '#/lib/haptics'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {decrementBadgeCount} from '#/lib/notifications/notifications'
import {sanitizeHandle} from '#/lib/strings/handles'
import {
@@ -53,7 +52,8 @@ import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'
import type * as bsky from '#/types/bsky'
import {chat} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {useIsWithinSplitView} from './splitView/context'
export const ChatListItemPortal = createPortalGroup()
@@ -64,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
@@ -314,7 +314,12 @@ function BaseChatItem({
let lastMessageSentAt: string | null = null
// Deleted message
if (ChatBskyConvoDefs.isDeletedMessageView(convo.view.lastMessage)) {
if (
bsky.isType(
chat.bsky.convo.defs.deletedMessageView,
convo.view.lastMessage,
)
) {
lastMessageSentAt = convo.view.lastMessage.sentAt
lastMessage = isDeletedAccount
@@ -323,7 +328,7 @@ function BaseChatItem({
}
// Message
if (ChatBskyConvoDefs.isMessageView(convo.view.lastMessage)) {
if (bsky.isType(chat.bsky.convo.defs.messageView, convo.view.lastMessage)) {
const info = getMessageInfo({
convo: convo.view,
currentAccountDid: currentAccount?.did,
@@ -339,7 +344,12 @@ function BaseChatItem({
}
// Reaction
if (ChatBskyConvoDefs.isMessageAndReactionView(convo.view.lastReaction)) {
if (
bsky.isType(
chat.bsky.convo.defs.messageAndReactionView,
convo.view.lastReaction,
)
) {
const info = getReactionInfo({
convo: convo.view,
currentAccountDid: currentAccount?.did,
@@ -358,7 +368,12 @@ function BaseChatItem({
}
// System message
if (ChatBskyConvoDefs.isSystemMessageView(convo.view.lastMessage)) {
if (
bsky.isType(
chat.bsky.convo.defs.systemMessageView,
convo.view.lastMessage,
)
) {
const info = getSystemMessageInfo(
convo.view.lastMessage.data,
new Map(convo.view.members.map(m => [m.did, m])),
@@ -1,10 +1,10 @@
import {useCallback, useMemo} from 'react'
import {View} from 'react-native'
import {LinearGradient} from 'expo-linear-gradient'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {type ActiveConvoStates} from '#/state/messages/convo'
@@ -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,13 +1,11 @@
import {useState} from 'react'
import {View} from 'react-native'
import {Image} from 'expo-image'
import {type ChatBskyGroupDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {moderateProfile, type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {shareUrl} from '#/lib/sharing'
import {useCreateJoinLink} from '#/state/queries/messages/create-join-link'
import {useDisableJoinLink} from '#/state/queries/messages/disable-join-link'
@@ -35,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 {CopyTextButton} from './CopyTextButton'
import {EditTextButton} from './EditTextButton'
@@ -560,13 +559,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,
@@ -13,7 +13,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {scheduleOnRN} from 'react-native-worklets'
import {GlassContainer} from 'expo-glass-effect'
import {LinearGradient} from 'expo-linear-gradient'
import {type $Typed, type ChatBskyConvoDefs} from '@atproto/api'
import {type $Typed} from '@atproto/lex'
import {ScrollEdgeEffect} from '@bsky.app/expo-scroll-edge-effect'
import {useLingui} from '@lingui/react/macro'
import {countGraphemes} from 'unicode-segmenter/grapheme'
@@ -37,6 +37,7 @@ import {PaperPlaneVertical_Filled_Stroke2_Corner1_Rounded as PaperPlaneIcon} fro
import {Loader} from '#/components/Loader'
import * as Toast from '#/components/Toast'
import {IS_ANDROID, IS_IOS, IS_LIQUID_GLASS, IS_NATIVE, IS_WEB} from '#/env'
import {type chat} from '#/lexicons'
import {type MessageEmbedState} from './MessageInputEmbed'
const MIN_HEIGHT = 40
@@ -53,7 +54,7 @@ export function MessageComposer({
onSendMessage: (
message: string,
embed?: MessageEmbedState,
replyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
replyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
) => void
messageEmbed: MessageEmbedState | undefined
setEmbed: (embedUrl: string | undefined) => void
@@ -106,7 +107,7 @@ export function MessageComposer({
const onSubmit = (
message: string,
embed: MessageEmbedState | undefined,
replyTo: ChatBskyConvoDefs.MessageView | null,
replyTo: chat.bsky.convo.defs.MessageView | null,
) => {
if (!editable) return
if (!embed && message.trim() === '') return
@@ -1,18 +1,17 @@
import {useCallback, useEffect, useMemo, useState} from 'react'
import {LayoutAnimation, View} from 'react-native'
import {AppBskyFeedPost, AtUri} 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'
import {HITSLOP_20} from '#/lib/constants'
import {moderatePost} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {
type CommonNavigatorParams,
type NavigationProp,
} from '#/lib/routes/types'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {
convertBskyAppUrlIfNeeded,
getChatInviteCodeFromUrl,
@@ -164,17 +163,11 @@ function MessageInputPostEmbed({
)
const {rt, record} = useMemo(() => {
if (
post &&
bsky.dangerousIsType<AppBskyFeedPost.Record>(
post.record,
AppBskyFeedPost.isRecord,
)
) {
if (post && bsky.isType(app.bsky.feed.post, post.record)) {
return {
rt: new RichTextAPI({
text: post.record.text,
facets: asSdkFacets(post.record.facets),
facets: post.record.facets,
}),
record: post.record,
}
@@ -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()
@@ -22,13 +22,7 @@ import Animated, {
} from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {scheduleOnRN} from 'react-native-worklets'
import {
type $Typed,
type AppBskyEmbedRecord,
ChatBskyConvoDefs,
type ChatBskyEmbedJoinLink,
ChatBskyGroupDefs,
} from '@atproto/api'
import {type $Typed} from '@atproto/lex'
import {useScrollEdgeEffectRef} from '@bsky.app/expo-scroll-edge-effect'
import {RichText} from '@bsky.app/sdk/richtext'
@@ -70,7 +64,7 @@ import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_ANDROID, IS_NATIVE, IS_WEB} from '#/env'
import {app, type chat, type com} from '#/lexicons'
import {app, chat} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {ChatStatusInfo} from './ChatStatusInfo'
import {groupSystemMessages, type RenderItem} from './groupSystemMessages'
@@ -117,8 +111,8 @@ function getNeighborMessage(
neighbor.type === 'deleted-message'
) {
if (
ChatBskyConvoDefs.isMessageView(neighbor.message) ||
ChatBskyConvoDefs.isDeletedMessageView(neighbor.message)
bsky.isType(chat.bsky.convo.defs.messageView, neighbor.message) ||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, neighbor.message)
) {
return neighbor.message
}
@@ -525,7 +519,7 @@ export function MessagesList({
async (
text: string,
embedState?: MessageEmbedState,
reply?: $Typed<ChatBskyConvoDefs.MessageView>,
reply?: $Typed<chat.bsky.convo.defs.MessageView>,
) => {
let rt = new RichText({text: text.trimEnd()}, {cleanNewlines: true})
@@ -539,10 +533,10 @@ export function MessagesList({
let embed: chat.bsky.convo.defs.MessageInput['embed']
let embedView:
| $Typed<AppBskyEmbedRecord.View>
| $Typed<ChatBskyEmbedJoinLink.View>
| $Typed<app.bsky.embed.record.View>
| $Typed<chat.bsky.embed.joinLink.View>
| undefined
let replyTo: ChatBskyConvoDefs.ReplyRef | undefined
let replyTo: chat.bsky.convo.defs.ReplyRef | undefined
/**
* Find the embedded link facet and, if it's at the start or end of the
@@ -574,14 +568,13 @@ export function MessagesList({
embed = {
$type: 'app.bsky.embed.record',
/*
* `getPost` still returns an `@atproto/api` view, whose `uri` and
* `cid` are plain strings rather than the branded syntax types
* the lexicon input declares.
* `getPost` hands back `uri` and `cid` as plain strings rather
* than the branded syntax types the lexicon input declares.
*/
record: {
uri: post.uri,
cid: post.cid,
} as com.atproto.repo.strongRef.Main,
},
}
embedView = {
@@ -666,7 +659,10 @@ export function MessagesList({
}
if (
embedView?.$type === 'chat.bsky.embed.joinLink#view' &&
ChatBskyGroupDefs.isJoinLinkPreviewView(embedView.joinLinkPreview)
bsky.isType(
chat.bsky.group.defs.joinLinkPreviewView,
embedView.joinLinkPreview,
)
) {
ax.metric('groupchat:inviteLink:shared', {
convoId: embedView.joinLinkPreview.convoId,
@@ -904,7 +900,7 @@ function Composer({
onSendMessage: (
message: string,
embed?: MessageEmbedState,
replyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
replyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
) => Promise<void>
messageEmbed: MessageEmbedState | undefined
setEmbed: (embedUrl: string | undefined) => void
@@ -914,7 +910,7 @@ function Composer({
(
message: string,
embed?: MessageEmbedState,
replyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
replyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
) => {
void onSendMessage(message, embed, replyTo)
},
@@ -1,9 +1,9 @@
import {View} from 'react-native'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
import {moderateProfile} from '#/lib/moderation/subjects'
import {type NavigationProp} from '#/lib/routes/types'
import {isInvalidHandle, sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -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'
@@ -17,7 +16,7 @@ import {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'
@@ -41,6 +40,7 @@ import {Loader} from '#/components/Loader'
import * as Menu from '#/components/Menu'
import {ReportDialog} from '#/components/moderation/ReportDialog'
import * as Toast from '#/components/Toast'
import {type chat} from '#/lexicons'
export function RejectMenu({
convo,
@@ -56,7 +56,7 @@ export function RejectMenu({
label?: string
icon?: boolean
convo: ConvoWithDetails
profile: ChatBskyActorDefs.ProfileViewBasic
profile: chat.bsky.actor.defs.ProfileViewBasic
showDeleteConvo?: boolean
currentScreen: 'list' | 'conversation'
}) {
@@ -214,7 +214,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'
}) {
@@ -301,7 +301,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,7 +1,5 @@
import {useState} from 'react'
import {View} from 'react-native'
import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
import {type AtUriString} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -22,6 +20,7 @@ import {Loader} from '#/components/Loader'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp'
@@ -29,7 +28,7 @@ const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp'
export function StarterPackCard({
view,
}: {
view: AppBskyGraphDefs.StarterPackView
view: app.bsky.graph.defs.StarterPackView
}) {
const t = useTheme()
const {_} = useLingui()
@@ -48,7 +47,7 @@ export function StarterPackCard({
setIsProcessing(true)
let listItems: AppBskyGraphDefs.ListItemView[] = []
let listItems: app.bsky.graph.defs.ListItemView[] = []
try {
listItems = await getAllListMembers(appviewClient, view.list.uri)
} catch (e) {
@@ -77,7 +76,7 @@ export function StarterPackCard({
try {
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
// the starter pack view is still legacy-typed
uri: view.uri as AtUriString,
uri: view.uri,
cid: view.cid,
})
} catch (e) {
@@ -105,12 +104,7 @@ export function StarterPackCard({
})
}
if (
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
record,
AppBskyGraphStarterpack.isRecord,
)
) {
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
return null
}
@@ -1,8 +1,8 @@
import {View} from 'react-native'
import {type AppBskyFeedDefs, AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -15,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'
const AVI_SIZE = 20
@@ -22,7 +23,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()
@@ -62,7 +63,7 @@ export function LikesStat({post}: {post: AppBskyFeedDefs.PostView}) {
* likes, the API max per page), so they are a sample of the most recent
* likers, not an exhaustive list.
*/
export function KnownLikers({post}: {post: AppBskyFeedDefs.PostView}) {
export function KnownLikers({post}: {post: app.bsky.feed.defs.PostView}) {
const t = useTheme()
const {t: l} = useLingui()
const {hasSession, currentAccount} = useSession()
@@ -1,11 +1,6 @@
import {memo, useMemo} from 'react'
import {Text as RNText, View} from 'react-native'
import {
AppBskyFeedDefs,
AppBskyFeedPost,
type AppBskyFeedThreadgate,
AtUri,
} 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'
@@ -14,7 +9,6 @@ import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {niceDate} from '#/lib/strings/time'
import {
POST_TOMBSTONE,
@@ -65,6 +59,7 @@ import {Text} from '#/components/Typography'
import {WhoCanReply} from '#/components/WhoCanReply'
import {useAnalytics} from '#/analytics'
import {useActorStatus} from '#/features/liveNow'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
export function ThreadItemAnchor({
@@ -75,7 +70,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)
@@ -176,9 +171,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()
@@ -200,7 +195,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({
() =>
new RichTextAPI({
text: record.text,
facets: asSdkFacets(record.facets),
facets: record.facets,
}),
[record],
)
@@ -244,7 +239,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,
@@ -574,16 +573,13 @@ 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()
const indexedAt = new Date(post.indexedAt)
const createdAt = bsky.dangerousIsType<AppBskyFeedPost.Record>(
post.record,
AppBskyFeedPost.isRecord,
)
const createdAt = bsky.isType(app.bsky.feed.post, post.record)
? new Date(post.record.createdAt)
: new Date(post.indexedAt)
@@ -664,8 +660,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,10 +1,6 @@
import {memo, type ReactNode, useCallback, useMemo, useState} from 'react'
import {View} from 'react-native'
import {
type AppBskyFeedDefs,
type AppBskyFeedThreadgate,
AtUri,
} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
import {Trans} from '@lingui/react/macro'
@@ -12,7 +8,6 @@ import {MAX_POST_LINES} from '#/lib/constants'
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {makeProfileLink} from '#/lib/routes/links'
import {countLines} from '#/lib/strings/helpers'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {
POST_TOMBSTONE,
type Shadow,
@@ -55,6 +50,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'}>
@@ -63,7 +59,7 @@ export type ThreadItemPostProps = {
topBorder?: boolean
}
onPostSuccess?: (data: OnPostSuccessData) => void
threadgateRecord?: AppBskyFeedThreadgate.Record
threadgateRecord?: app.bsky.feed.threadgate.Main
}
export function ThreadItemPost({
@@ -197,7 +193,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()
@@ -212,7 +208,7 @@ const ThreadItemPostInner = memo(function ThreadItemPostInner({
() =>
new RichTextAPI({
text: record.text,
facets: asSdkFacets(record.facets),
facets: record.facets,
}),
[record],
)
@@ -1,9 +1,9 @@
import {Text, View} from 'react-native'
import {type AppBskyUnspeccedDefs} from '@atproto/api'
import {Trans, useLingui} from '@lingui/react/macro'
import {atoms as a, ios, platform, useTheme} from '#/alf'
import {useAnalytics} from '#/analytics'
import {type app} from '#/lexicons'
/**
* How far the inline badge is nudged below the text baseline. Android's
@@ -12,7 +12,7 @@ import {useAnalytics} from '#/analytics'
export const POST_NUMBER_INLINE_OFFSET = 6
export function useHasThreadItemPostNumber(
value: AppBskyUnspeccedDefs.ThreadItemPost,
value: app.bsky.unspecced.defs.ThreadItemPost,
) {
const ax = useAnalytics()
const index = value.opThreadPostIndex
@@ -32,7 +32,7 @@ export function ThreadItemPostNumber({
value,
inline = true,
}: {
value: AppBskyUnspeccedDefs.ThreadItemPost
value: app.bsky.unspecced.defs.ThreadItemPost
inline?: boolean
}) {
const t = useTheme()
@@ -1,10 +1,6 @@
import {memo, useCallback, useMemo, useState} from 'react'
import {View} from 'react-native'
import {
type AppBskyFeedDefs,
type AppBskyFeedThreadgate,
AtUri,
} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
import {Trans} from '@lingui/react/macro'
@@ -12,7 +8,6 @@ import {MAX_POST_LINES} from '#/lib/constants'
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {makeProfileLink} from '#/lib/routes/links'
import {countLines} from '#/lib/strings/helpers'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {
POST_TOMBSTONE,
type Shadow,
@@ -51,6 +46,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
@@ -69,7 +65,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)
@@ -252,13 +248,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()
@@ -272,7 +268,7 @@ const ThreadItemTreePostInner = memo(function ThreadItemTreePostInner({
() =>
new RichTextAPI({
text: record.text,
facets: asSdkFacets(record.facets),
facets: record.facets,
}),
[record],
)
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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()
+2 -2
View File
@@ -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,7 +1,6 @@
import {memo, useCallback, useMemo, useState} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
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'
import {useLingui} from '@lingui/react'
@@ -11,7 +10,6 @@ import {Plural, Trans} from '@lingui/react/macro'
import {MAX_LABELERS} from '#/lib/constants'
import {useHaptics} from '#/lib/haptics'
import {isAppLabeler} from '#/lib/moderation'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {type Shadow} from '#/state/cache/types'
import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
@@ -42,7 +40,7 @@ import {ProfileHeaderMetrics} from './Metrics'
import {ProfileHeaderShell} from './Shell'
interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed
profile: app.bsky.actor.defs.ProfileViewDetailed
labeler: app.bsky.labeler.defs.LabelerViewDetailed
descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts
@@ -58,7 +56,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()
@@ -232,7 +230,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,7 +1,7 @@
import {memo, useMemo, useState} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs} from '@atproto/api'
import {
moderateProfile,
type ModerationDecision,
type ModerationOpts,
} from '@bsky.app/sdk/moderation'
@@ -11,7 +11,6 @@ import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {useHaptics} from '#/lib/haptics'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {logger} from '#/logger'
import {type Shadow, useProfileShadow} from '#/state/cache/profile-shadow'
@@ -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 {GermButton} from '../components/GermButton'
import {ProfileHeaderDisplayName} from './DisplayName'
import {EditProfileDialog} from './EditProfileDialog'
@@ -49,7 +49,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
@@ -64,7 +64,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(
@@ -213,7 +213,7 @@ export function HeaderStandardButtons({
onUnfollow,
minimal,
}: {
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>
profile: Shadow<app.bsky.actor.defs.ProfileViewDetailed>
moderation: ModerationDecision
moderationOpts: ModerationOpts
onFollow?: () => void
+2 -2
View File
@@ -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
+3 -5
View File
@@ -7,12 +7,10 @@ import Animated, {
} from 'react-native-reanimated'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {scheduleOnRN} from 'react-native-worklets'
import {type AppBskyActorDefs} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
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'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -58,7 +56,7 @@ ProfileHeaderLoading = memo(ProfileHeaderLoading)
export {ProfileHeaderLoading}
interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed
profile: app.bsky.actor.defs.ProfileViewDetailed
labeler: app.bsky.labeler.defs.LabelerViewDetailed | undefined
descriptionRT: RichTextAPI | null
moderationOpts: ModerationOpts
@@ -103,7 +101,7 @@ const MinimalHeader = memo(function MinimalHeader({
hideBackButton = false,
}: {
onLayout: (e: LayoutChangeEvent) => void
profile: AppBskyActorDefs.ProfileViewDetailed
profile: app.bsky.actor.defs.ProfileViewDetailed
labeler?: app.bsky.labeler.defs.LabelerViewDetailed
hideBackButton?: boolean
}) {
+3 -3
View File
@@ -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 {Platform, View} from 'react-native'
import {Image} from 'expo-image'
import {type AppBskyActorDefs} from '@atproto/api'
import {type Client} from '@atproto/lex'
import {type DidString} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
@@ -29,7 +28,7 @@ export function GermButton({
germ,
profile,
}: {
germ: AppBskyActorDefs.ProfileAssociatedGerm
germ: app.bsky.actor.defs.ProfileAssociatedGerm
profile: bsky.profile.AnyProfileView
}) {
const t = useTheme()
@@ -279,7 +278,7 @@ function GermSelfButton({did}: {did: string}) {
}
function constructGermUrl(
declaration: AppBskyActorDefs.ProfileAssociatedGerm,
declaration: app.bsky.actor.defs.ProfileAssociatedGerm,
profile: bsky.profile.AnyProfileView,
viewerDid?: string,
) {
+2 -2
View File
@@ -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'
@@ -8,7 +7,6 @@ import {Trans} from '@lingui/react/macro'
import {useHaptics} from '#/lib/haptics'
import {makeListLink} from '#/lib/routes/links'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {logger} from '#/logger'
import {useListBlockMutation, useListMuteMutation} from '#/state/queries/list'
import {
@@ -25,6 +23,7 @@ import {Loader} from '#/components/Loader'
import {RichText} from '#/components/RichText'
import * as Toast from '#/components/Toast'
import {useAnalytics} from '#/analytics'
import {app} from '#/lexicons'
import {MoreOptionsMenu} from './MoreOptionsMenu'
import {SubscribeMenu} from './SubscribeMenu'
@@ -34,14 +33,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.value
const isModList = list.purpose === app.bsky.graph.defs.modlist.value
const isBlocking = !!list.viewer?.blocked
const isMuting = !!list.viewer?.muted
const playHaptic = useHaptics()
@@ -130,7 +129,7 @@ export function Header({
list.description
? new RichTextAPI({
text: list.description,
facets: asSdkFacets(list.descriptionFacets),
facets: list.descriptionFacets,
})
: undefined,
[list],
@@ -1,4 +1,4 @@
import {type AppBskyActorDefs, AppBskyGraphDefs, AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -36,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 {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()
@@ -57,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.value
const isModList = list.purpose === app.bsky.graph.defs.modlist.value
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()
+5 -5
View File
@@ -1,8 +1,8 @@
import {useCallback, useMemo, useRef, useState} from 'react'
import {View} from 'react-native'
import {useAnimatedRef} from 'react-native-reanimated'
import {AppBskyGraphDefs, AtUri} from '@atproto/api'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {AtUri} from '@atproto/syntax'
import {moderateUserList, type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -11,7 +11,6 @@ import {useQueryClient} from '@tanstack/react-query'
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
import {useSetTitle} from '#/lib/hooks/useSetTitle'
import {moderateUserList} from '#/lib/moderation/subjects'
import {
type CommonNavigatorParams,
type NativeStackScreenProps,
@@ -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 {app} from '#/lexicons'
import {AboutSection} from './AboutSection'
import {ErrorScreen} from './components/ErrorScreen'
import {Header} from './components/Header'
@@ -143,7 +143,7 @@ function ProfileListScreenLoaded({
preferences,
}: Props & {
uri: string
list: AppBskyGraphDefs.ListView
list: app.bsky.graph.defs.ListView
moderationOpts: ModerationOpts
preferences: UsePreferencesQueryResponse
}) {
@@ -155,7 +155,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.value
const isScreenFocused = useIsFocused()
const isHidden = list.labels?.findIndex(l => l.val === '!hide') !== -1
const isOwner = currentAccount?.did === list.creator.did
+7 -7
View File
@@ -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()
+4 -8
View File
@@ -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'
+9 -9
View File
@@ -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,6 @@
import {useMemo} from 'react'
import {View} from 'react-native'
import {type AppBskyFeedDefs, AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {makeCustomFeedLink} from '#/lib/routes/links'
@@ -14,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,
@@ -46,7 +47,7 @@ export function FeedLink({
feed,
children,
}: {
feed: AppBskyFeedDefs.GeneratorView
feed: app.bsky.feed.defs.GeneratorView
children?: React.ReactNode
}) {
const t = useTheme()
@@ -75,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} />
}
@@ -178,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,9 +1,8 @@
import {ScrollView, View} from 'react-native'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {moderateProfile, type ModerationOpts} from '@bsky.app/sdk/moderation'
import {Plural, Trans, useLingui} from '@lingui/react/macro'
import {createHitslop} from '#/lib/constants'
import {moderateProfile} from '#/lib/moderation/subjects'
import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
@@ -1,11 +1,10 @@
import {useState} from 'react'
import {View} from 'react-native'
import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {moderateProfile} from '#/lib/moderation/subjects'
import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
@@ -19,13 +18,14 @@ import {MediaInsetBorder} from '#/components/MediaInsetBorder'
import {useStarterPackLink} from '#/components/StarterPack/StarterPackCard'
import {SubtleHover} from '#/components/SubtleHover'
import {Text} from '#/components/Typography'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
export function StarterPackCard({
view,
onPress,
}: {
view: AppBskyGraphDefs.StarterPackView
view: app.bsky.graph.defs.StarterPackView
onPress?: () => void
}) {
const t = useTheme()
@@ -35,12 +35,7 @@ export function StarterPackCard({
const link = useStarterPackLink({view})
const record = view.record
if (
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
record,
AppBskyGraphStarterpack.isRecord,
)
) {
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
return null
}
@@ -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,11 +1,10 @@
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'
import {moderateProfile} from '#/lib/moderation/subjects'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {
useTrendingSettings,
@@ -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'
const IMAGE_SIZE = 56
@@ -118,7 +118,7 @@ export function TrendRow({
children,
onPress,
}: ViewStyleProp & {
trend: AppBskyUnspeccedDefs.TrendView
trend: app.bsky.unspecced.defs.TrendView
rank: number
recId?: string
children?: React.ReactNode
@@ -229,7 +229,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()
@@ -297,7 +297,7 @@ export function TrendingTopicRowSkeleton() {
}
function useModerateTrendingActors(
actors: AppBskyUnspeccedDefs.TrendView['actors'],
actors: app.bsky.unspecced.defs.TrendView['actors'],
) {
const moderationOpts = useModerationOpts()
@@ -1,6 +1,6 @@
import {useMemo} from 'react'
import {ScrollView, View} from 'react-native'
import {AppBskyEmbedVideo, AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -21,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
@@ -158,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()
@@ -1,5 +1,5 @@
import {View} from 'react-native'
import {type $Typed, 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'
@@ -22,6 +22,7 @@ import {Text} from '#/components/Typography'
import {useSimpleVerificationState} from '#/components/verification'
import {VerificationCheck} from '#/components/verification/VerificationCheck'
import {useAnalytics} from '#/analytics'
import {com} from '#/lexicons'
import * as bsky from '#/types/bsky'
type Props = NativeStackScreenProps<
@@ -53,15 +54,13 @@ export function AutomationLabelSettingsScreen({}: Props) {
{
profile,
updates: existing => {
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.validate(
existing.labels,
ComAtprotoLabelDefs.validateSelfLabels,
)
? 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) {
@@ -80,8 +79,8 @@ export function AutomationLabelSettingsScreen({}: Props) {
return existing
},
checkCommitted: res => {
const exists = !!res.data.labels?.some(l => l.val === 'bot')
checkCommitted: profile => {
const exists = !!profile.labels?.some(l => l.val === 'bot')
return exists === wasAdded
},
},
@@ -1,7 +1,6 @@
import {useCallback, useEffect, useState} from 'react'
import {type ListRenderItemInfo, View} from 'react-native'
import * as Contacts from 'expo-contacts'
import {type AppBskyContactDefs} from '@atproto/api'
import {type DidString} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
@@ -189,7 +188,7 @@ function SyncStatus({
info,
refetchStatus,
}: {
info: AppBskyContactDefs.SyncStatus
info: app.bsky.contact.defs.SyncStatus
refetchStatus: () => Promise<any>
}) {
const ax = useAnalytics()
@@ -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
}) {
+4 -4
View File
@@ -1,8 +1,8 @@
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 {removeNuxs} from '@bsky.app/sdk'
import {moderateProfile} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
@@ -10,7 +10,6 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {HELP_DESK_URL, HITSLOP_10} from '#/lib/constants'
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
import {useApplyPullRequestOTAUpdate} from '#/lib/hooks/useOTAUpdates'
import {moderateProfile} from '#/lib/moderation/subjects'
import {
type CommonNavigatorParams,
type NavigationProp,
@@ -69,6 +68,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'
@@ -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()
@@ -608,7 +608,7 @@ function AccountRow({
pendingDid,
onPressSwitchAccount,
}: {
profile?: AppBskyActorDefs.ProfileViewDetailed
profile?: app.bsky.actor.defs.ProfileViewDetailed
account: SessionAccount
pendingDid: string | null
onPressSwitchAccount: (
@@ -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()
@@ -1,6 +1,6 @@
import {useCallback} from 'react'
import {View} from 'react-native'
import {type $Typed, 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'
@@ -13,6 +13,7 @@ import {useSession} from '#/state/session'
import {atoms as a, useTheme} from '#/alf'
import * as Toggle from '#/components/forms/Toggle'
import {Text} from '#/components/Typography'
import {com} from '#/lexicons'
import * as bsky from '#/types/bsky'
export function PwiOptOut() {
@@ -35,9 +36,9 @@ export function PwiOptOut() {
profile,
updates: existing => {
// create labels attr if needed
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.validate(
const labels: $Typed<com.atproto.label.defs.SelfLabels> = bsky.matches(
com.atproto.label.defs.selfLabels,
existing.labels,
ComAtprotoLabelDefs.validateSelfLabels,
)
? existing.labels
: {
@@ -68,8 +69,8 @@ export function PwiOptOut() {
return existing
},
checkCommitted: res => {
const exists = !!res.data.labels?.some(
checkCommitted: profile => {
const exists = !!profile.labels?.some(
l => l.val === '!no-unauthenticated',
)
return exists === wasAdded
@@ -1,13 +1,13 @@
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 com} from '#/lexicons'
import {type HandleSuggestionsProps} from './shared'
type Suggestion = ComAtprotoTempCheckHandleAvailability.Suggestion & {
type Suggestion = com.atproto.temp.checkHandleAvailability.Suggestion & {
key: string
}
@@ -1,10 +1,11 @@
import {type ComAtprotoTempCheckHandleAvailability} from '@atproto/api'
import {type UseSiftReturn} from '@bsky.app/sift'
import {type com} from '#/lexicons'
export type HandleSuggestionsProps = {
suggestions: ComAtprotoTempCheckHandleAvailability.Suggestion[]
suggestions: com.atproto.temp.checkHandleAvailability.Suggestion[]
onSelect: (
suggestion: ComAtprotoTempCheckHandleAvailability.Suggestion,
suggestion: com.atproto.temp.checkHandleAvailability.Suggestion,
) => void
/**
* Web only: the Sift instance shared with the handle input. It carries the
+2 -2
View File
@@ -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()
+2 -5
View File
@@ -3,7 +3,6 @@ import {AppState, type AppStateStatus, View} from 'react-native'
import ReactNativeDeviceAttest from 'react-native-device-attest'
import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
import Animated, {FadeIn, LayoutAnimationConfig} from 'react-native-reanimated'
import {AppBskyGraphStarterpack} from '@atproto/api'
import {tokens} from '@bsky.app/alf'
import {Trans, useLingui} from '@lingui/react/macro'
@@ -32,6 +31,7 @@ import {ScreenTransition} from '#/components/ScreenTransition'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {GCP_PROJECT_ID, IS_ANDROID} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
export function Signup({onPressBack}: {onPressBack: () => void}) {
@@ -141,10 +141,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
scrollable>
<View testID="createAccount" style={a.flex_1}>
{showStarterPackCard &&
bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
starterPack.record,
AppBskyGraphStarterpack.isRecord,
) ? (
bsky.isType(app.bsky.graph.starterpack, starterPack.record) ? (
<Animated.View
entering={!isFetchedAtMount ? FadeIn : undefined}>
<LinearGradientBackground
+1 -2
View File
@@ -1,6 +1,5 @@
import {createContext, useCallback, useContext} from 'react'
import {LayoutAnimation} from 'react-native'
import {type ComAtprotoServerDescribeServer} from '@atproto/api'
import {useLingui} from '@lingui/react/macro'
import * as EmailValidator from 'email-validator'
@@ -14,7 +13,7 @@ import {useOnboardingDispatch} from '#/state/shell'
import {type AnalyticsContextType, useAnalytics} from '#/analytics'
import {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
@@ -1,7 +1,7 @@
import {useEffect, useState} from 'react'
import {Pressable, View} from 'react-native'
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
import {AppBskyGraphDefs, AppBskyGraphStarterpack, AtUri} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -34,6 +34,7 @@ import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_WEB, IS_WEB_MOBILE_ANDROID} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
@@ -68,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)) {
@@ -82,12 +83,7 @@ export function LandingScreen({
}
// Just for types, this cannot be hit
if (
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
starterPack.record,
AppBskyGraphStarterpack.isRecord,
)
) {
if (!bsky.isType(app.bsky.graph.starterpack, starterPack.record)) {
return null
}
@@ -109,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
}) {
+11 -17
View File
@@ -1,8 +1,7 @@
import {useCallback, useEffect, useState} from 'react'
import {View} from 'react-native'
import {Image} from 'expo-image'
import {AppBskyGraphDefs, AppBskyGraphStarterpack, AtUri} from '@atproto/api'
import {type AtUriString} from '@atproto/syntax'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
import {msg} from '@lingui/core/macro'
@@ -21,7 +20,6 @@ import {
type NavigationProp,
} from '#/lib/routes/types'
import {cleanError} from '#/lib/strings/errors'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
import {logger} from '#/logger'
import {updateProfileShadow} from '#/state/cache/profile-shadow'
@@ -75,6 +73,7 @@ import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_WEB} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
type StarterPackScreeProps = NativeStackScreenProps<
@@ -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,7 +300,7 @@ function Header({
routeParams,
onOpenShareDialog,
}: {
starterPack: AppBskyGraphDefs.StarterPackView
starterPack: app.bsky.graph.defs.StarterPackView
routeParams: StarterPackScreeProps['route']['params']
onOpenShareDialog: () => void
}) {
@@ -350,7 +349,7 @@ function Header({
setIsProcessing(true)
let listItems: AppBskyGraphDefs.ListItemView[] = []
let listItems: app.bsky.graph.defs.ListItemView[] = []
try {
listItems = await getAllListMembers(appviewClient, starterPack.list.uri)
} catch (e) {
@@ -378,7 +377,7 @@ function Header({
try {
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
// the starter pack view is still legacy-typed
uri: starterPack.uri as AtUriString,
uri: starterPack.uri,
cid: starterPack.cid,
})
} catch (e) {
@@ -406,19 +405,14 @@ function Header({
})
}
if (
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
record,
AppBskyGraphStarterpack.isRecord,
)
) {
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
return null
}
const richText = record.description
? new RichTextAPI({
text: record.description,
facets: asSdkFacets(record.descriptionFacets),
facets: record.descriptionFacets,
})
: undefined
@@ -522,7 +516,7 @@ function OverflowMenu({
routeParams,
onOpenShareDialog,
}: {
starterPack: AppBskyGraphDefs.StarterPackView
starterPack: app.bsky.graph.defs.StarterPackView
routeParams: StarterPackScreeProps['route']['params']
onOpenShareDialog: () => void
}) {
+6 -10
View File
@@ -1,13 +1,9 @@
import {createContext, useContext, useReducer} from 'react'
import {
type AppBskyFeedDefs,
type AppBskyGraphDefs,
AppBskyGraphStarterpack,
} from '@atproto/api'
import {msg, plural} from '@lingui/core/macro'
import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
import * as Toast from '#/components/Toast'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
const steps = ['Details', 'Profiles', 'Feeds'] as const
@@ -21,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}
@@ -32,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'
@@ -125,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
}) {
@@ -135,7 +131,7 @@ export function Provider({
if (
starterPack &&
bsky.validate(starterPack.record, AppBskyGraphStarterpack.validateRecord)
bsky.matches(app.bsky.graph.starterpack, starterPack.record)
) {
return {
canNext: true,
+4 -4
View File
@@ -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}
+6 -10
View File
@@ -3,12 +3,7 @@ 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,
AtUri,
} from '@atproto/api'
import {AtUri} from '@atproto/syntax'
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -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)
+2 -3
View File
@@ -2,7 +2,6 @@ import {useState} from 'react'
import {View} from 'react-native'
import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {ToolsOzoneReportDefs} from '@atproto/api'
import {type DidString} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -25,7 +24,7 @@ import {SimpleInlineLinkText} from '#/components/Link'
import {Loader} from '#/components/Loader'
import {P, Text} from '#/components/Typography'
import {IS_WEB} from '#/env'
import {com} from '#/lexicons'
import {com, tools} from '#/lexicons'
const COL_WIDTH = 400
@@ -55,7 +54,7 @@ export function Takendown() {
await client.call(
com.atproto.moderation.createReport,
{
reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
reasonType: tools.ozone.report.defs.reasonAppeal.value,
subject: {
$type: 'com.atproto.admin.defs#repoRef',
// the persisted account did is already resolved
+5 -3
View File
@@ -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}`
}
+26 -29
View File
@@ -25,12 +25,7 @@ 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,
AppBskyFeedPost,
AtUri,
} 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'
import {Trans, useLingui} from '@lingui/react/macro'
@@ -58,7 +53,6 @@ import {
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {cleanError} from '#/lib/strings/errors'
import {sanitizeHandle} from '#/lib/strings/handles'
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
import {logger} from '#/logger'
import {useA11y} from '#/state/a11y'
import {
@@ -104,6 +98,7 @@ import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_ANDROID} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {Scrubber, VIDEO_PLAYER_BOTTOM_INSET} from './components/Scrubber'
@@ -177,8 +172,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
}
@@ -216,8 +211,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
}[] = []
@@ -225,7 +220,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,
@@ -294,14 +292,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
@@ -309,7 +307,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
@@ -479,8 +477,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
@@ -590,7 +588,7 @@ function VideoItemInner({
active,
}: {
player: VideoPlayer
embed: AppBskyEmbedVideo.View
embed: app.bsky.embed.video.View
active: boolean
}) {
const {bottom} = useSafeAreaInsets()
@@ -707,7 +705,7 @@ function ModerationOverlay({
embed,
onPressShow,
}: {
embed: AppBskyEmbedVideo.View
embed: app.bsky.embed.video.View
onPressShow: () => void
}) {
const {t: l} = useLingui()
@@ -805,8 +803,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
@@ -827,15 +825,12 @@ function Overlay({
)
const rkey = new AtUri(post.uri).rkey
const record = bsky.dangerousIsType<AppBskyFeedPost.Record>(
post.record,
AppBskyFeedPost.isRecord,
)
const record = bsky.isType(app.bsky.feed.post, post.record)
? post.record
: undefined
const richText = new RichTextAPI({
text: record?.text || '',
facets: asSdkFacets(record?.facets),
facets: record?.facets,
})
const handle = sanitizeHandle(post.author.handle, '@')
@@ -1090,7 +1085,7 @@ function VideoItemPlaceholder({
style,
blur,
}: {
embed: AppBskyEmbedVideo.View
embed: app.bsky.embed.video.View
style?: ImageStyle
blur?: boolean
}) {
@@ -1131,7 +1126,7 @@ function PlayPauseTapArea({
reqId,
}: {
player: VideoPlayer
post: Shadow<AppBskyFeedDefs.PostView>
post: Shadow<app.bsky.feed.defs.PostView>
feedContext: string | undefined
reqId: string | undefined
}) {
@@ -1273,7 +1268,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