From cb3245e8e85cdc3c64256a73154665dd981e8f26 Mon Sep 17 00:00:00 2001 From: Oleksii Bulenok Date: Thu, 20 Aug 2026 15:49:04 +0200 Subject: [PATCH] rework imports --- src/ageAssurance/const.ts | 8 +- src/ageAssurance/data.tsx | 40 +-- src/ageAssurance/debug.ts | 95 ++++---- src/ageAssurance/useBeginAgeAssurance.ts | 9 +- src/ageAssurance/util.ts | 26 +- .../Autocomplete/useAutocomplete/index.ts | 4 +- src/components/MediaPreview.tsx | 14 +- src/components/Post/Embed/ImageEmbed.tsx | 7 +- src/components/Post/Embed/index.tsx | 7 +- src/components/Post/Translated/index.tsx | 11 +- src/components/RichText.tsx | 8 +- src/components/StarterPack/QrCode.tsx | 7 +- src/components/StarterPack/QrCodeDialog.tsx | 7 +- .../StarterPack/StarterPackCard.tsx | 8 +- src/components/VideoPostCard.tsx | 17 +- src/components/WhoCanReply.tsx | 16 +- .../SubscribeProfileDialog.tsx | 14 +- .../ageAssurance/AgeAssuranceAppealDialog.tsx | 7 +- .../ageAssurance/AgeAssuranceInitDialog.tsx | 4 +- .../contacts/screens/GetContacts.tsx | 9 +- .../contacts/screens/PhoneInput.tsx | 6 +- .../contacts/screens/VerifyNumber.tsx | 11 +- .../contacts/screens/ViewMatches.tsx | 4 +- .../EmailDialog/data/useConfirmEmail.ts | 4 +- .../EmailDialog/data/useManageEmail2FA.ts | 4 +- .../EmailDialog/data/useRequestEmailUpdate.ts | 4 +- .../data/useRequestEmailVerification.ts | 4 +- .../EmailDialog/data/useUpdateEmail.ts | 4 +- src/components/dialogs/StarterPackDialog.tsx | 7 +- .../lists/CreateListFromStarterPackDialog.tsx | 18 +- src/components/dms/ChatInvite/Card.tsx | 5 +- src/components/dms/ChatInvite/Root.tsx | 6 +- src/components/dms/LeaveConvoPrompt.tsx | 4 +- src/components/dms/MessageItem.tsx | 84 +++---- src/components/dms/dialogs/NewChatDialog.tsx | 7 +- .../dms/dialogs/ShareViaChatDialog.tsx | 7 +- src/components/dms/getMessageInfo.ts | 21 +- src/components/dms/getReactionInfo.ts | 9 +- src/components/dms/getSystemMessageInfo.ts | 46 ++-- src/components/dms/replyPreview.ts | 28 ++- src/components/dms/util.ts | 37 +-- src/components/feeds/PostFeedVideoGridRow.tsx | 4 +- .../Gallery/maybeApplyGalleryOffsetStyles.ts | 21 +- .../intents/GroupChatJoinDialog.tsx | 15 +- .../intents/VerifyEmailIntentDialog.tsx | 4 +- .../interstitials/TrendingVideos.tsx | 4 +- src/components/moderation/AppealForm.tsx | 10 +- src/components/moderation/BlockDialog.tsx | 12 +- .../moderation/ReportDialog/action.ts | 6 +- .../moderation/ReportDialog/const.ts | 230 +++++++++--------- .../moderation/ReportDialog/errors.test.ts | 4 +- .../moderation/ReportDialog/state.test.ts | 7 +- .../moderation/ReportDialog/state.ts | 5 +- .../ReportDialog/utils/parseReportSubject.ts | 23 +- .../ReportDialog/utils/useReportOptions.ts | 83 ++++--- .../components/GoLiveDisabledDialog.tsx | 8 +- src/features/liveNow/index.tsx | 32 +-- src/features/liveNow/utils.ts | 9 +- src/lib/__tests__/xrpc-error.test.ts | 7 +- src/lib/api/feed-manip.ts | 83 +++---- src/lib/api/feed/author.ts | 26 +- src/lib/api/feed/custom.ts | 23 +- src/lib/api/feed/following.ts | 9 +- src/lib/api/feed/likes.ts | 11 +- src/lib/api/feed/list.ts | 13 +- src/lib/api/feed/merge.ts | 22 +- src/lib/api/feed/posts.ts | 11 +- src/lib/api/index.ts | 51 ++-- src/lib/api/resolve.ts | 50 ++-- src/lib/generate-starterpack.ts | 31 ++- src/lib/media/video/upload.shared.ts | 7 +- src/lib/notifications/notifications.ts | 9 +- src/lib/strings/rich-text-helpers.ts | 4 +- src/lib/strings/rich-text-manip.ts | 6 +- src/lib/xrpc-error.ts | 4 +- src/locale/helpers.ts | 11 +- src/screens/Bookmarks.tsx | 17 +- src/screens/CustomFeed/index.tsx | 4 +- src/screens/Deactivated.tsx | 4 +- src/screens/List/ListHiddenScreen.tsx | 6 +- src/screens/Login/ForgotPasswordForm.tsx | 7 +- src/screens/Login/SetNewPasswordForm.tsx | 4 +- src/screens/Messages/Conversation.tsx | 4 +- .../Messages/ConversationSettings/index.tsx | 12 +- src/screens/Messages/Inbox.tsx | 16 +- src/screens/Messages/JoinRequest.tsx | 6 +- src/screens/Messages/JoinRequests.tsx | 10 +- .../Messages/components/ChatDisabled.tsx | 7 +- .../Messages/components/ChatListItem.tsx | 18 +- .../Messages/components/ChatLocked.tsx | 4 +- .../Messages/components/MessageInputEmbed.tsx | 7 +- .../Messages/components/MessagesList.tsx | 28 ++- .../components/OutgoingRequestListItem.tsx | 7 +- src/screens/Onboarding/StepFinished/index.tsx | 19 +- .../StarterPackCard.tsx | 9 +- src/screens/Onboarding/util.ts | 17 +- .../components/ThreadItemAnchor.tsx | 20 +- src/screens/Profile/components/GermButton.tsx | 18 +- src/screens/ProfileList/components/Header.tsx | 8 +- .../components/MoreOptionsMenu.tsx | 11 +- src/screens/ProfileList/index.tsx | 6 +- .../Search/components/StarterPackCard.tsx | 7 +- .../Search/modules/ExploreTrendingVideos.tsx | 4 +- .../Settings/AutomationLabelSettings.tsx | 18 +- src/screens/Settings/FindContactsSettings.tsx | 16 +- .../components/ChangePasswordDialog.tsx | 9 +- .../components/DeactivateAccountDialog.tsx | 4 +- .../components/DeleteAccountDialog.tsx | 10 +- .../components/DisableEmail2FADialog.tsx | 11 +- .../Settings/components/ExportCarDialog.tsx | 7 +- src/screens/Settings/components/PwiOptOut.tsx | 6 +- src/screens/Signup/index.tsx | 4 +- src/screens/Signup/state.ts | 9 +- src/screens/SignupQueued.tsx | 4 +- .../StarterPack/StarterPackLandingScreen.tsx | 13 +- src/screens/StarterPack/StarterPackScreen.tsx | 17 +- src/screens/StarterPack/Wizard/State.tsx | 14 +- src/screens/Takendown.tsx | 7 +- src/screens/VideoFeed/index.tsx | 42 ++-- src/state/cache/post-shadow.ts | 29 +-- src/state/cache/thread-mutes.tsx | 4 +- src/state/feed-feedback.tsx | 25 +- src/state/messages/convo/agent.ts | 157 ++++++------ src/state/messages/convo/index.tsx | 19 +- src/state/messages/events/agent.ts | 8 +- src/state/queries/activity-subscriptions.ts | 25 +- src/state/queries/actor-autocomplete.ts | 15 +- src/state/queries/actor-search.ts | 12 +- src/state/queries/actor-starter-packs.ts | 7 +- src/state/queries/app-passwords.ts | 12 +- .../queries/bookmarks/useBookmarkMutation.ts | 10 +- .../queries/bookmarks/useBookmarksQuery.ts | 28 ++- src/state/queries/content-visibility.ts | 18 +- src/state/queries/explore-feed-previews.tsx | 33 +-- src/state/queries/feed.ts | 93 ++++--- src/state/queries/find-contacts.ts | 34 +-- src/state/queries/handle-availability.ts | 11 +- src/state/queries/handle.ts | 10 +- src/state/queries/join-links.ts | 27 +- src/state/queries/known-followers.ts | 13 +- src/state/queries/labeler.ts | 18 +- src/state/queries/list-members.ts | 20 +- src/state/queries/list-memberships.ts | 16 +- src/state/queries/list.ts | 34 +-- src/state/queries/lists-with-membership.ts | 17 +- .../queries/messages/accept-conversation.ts | 11 +- .../queries/messages/actor-declaration.ts | 11 +- .../queries/messages/add-group-members.ts | 50 ++-- src/state/queries/messages/conversation.ts | 28 ++- .../queries/messages/create-group-chat.ts | 6 +- .../queries/messages/create-join-link.ts | 14 +- .../queries/messages/disable-join-link.ts | 11 +- .../queries/messages/edit-group-chat-name.ts | 9 +- src/state/queries/messages/edit-join-link.ts | 14 +- .../queries/messages/enable-join-link.ts | 11 +- .../messages/get-convo-availability.ts | 4 +- .../queries/messages/get-convo-for-members.ts | 6 +- src/state/queries/messages/get-status.ts | 4 +- .../queries/messages/get-unread-counts.ts | 4 +- src/state/queries/messages/join-requests.ts | 23 +- .../queries/messages/leave-conversation.ts | 9 +- .../messages/list-conversation-requests.tsx | 31 ++- .../queries/messages/list-conversations.tsx | 199 +++++++-------- .../queries/messages/list-convo-members.ts | 13 +- .../queries/messages/list-join-requests.ts | 11 +- .../queries/messages/list-mutual-groups.ts | 4 +- .../queries/messages/lock-conversation.ts | 12 +- .../messages/mark-join-request-read.ts | 18 +- .../queries/messages/mute-conversation.ts | 9 +- .../queries/messages/remove-from-group.ts | 30 +-- .../messages/request-join-group-chat.ts | 6 +- .../queries/messages/restrictChatSettings.ts | 6 +- src/state/queries/messages/update-all-read.ts | 15 +- .../messages/withdraw-join-group-chat.ts | 6 +- src/state/queries/my-blocked-accounts.ts | 13 +- src/state/queries/my-lists.ts | 15 +- src/state/queries/my-muted-accounts.ts | 13 +- src/state/queries/notifications/feed.ts | 13 +- src/state/queries/notifications/settings.ts | 42 ++-- src/state/queries/notifications/unread.tsx | 4 +- src/state/queries/notifications/util.ts | 34 ++- src/state/queries/pds-detection.ts | 4 +- src/state/queries/pinned-post.ts | 5 +- src/state/queries/post-feed.ts | 30 +-- src/state/queries/post-liked-by.ts | 17 +- src/state/queries/post-quotes.ts | 23 +- src/state/queries/post-reposted-by.ts | 13 +- src/state/queries/post.ts | 39 +-- src/state/queries/postgate/index.ts | 34 +-- src/state/queries/postgate/util.ts | 62 ++--- src/state/queries/preferences/index.ts | 29 +-- src/state/queries/profile-feedgens.ts | 8 +- src/state/queries/profile-followers.ts | 15 +- src/state/queries/profile-follows.ts | 15 +- src/state/queries/profile-lists.ts | 8 +- src/state/queries/profile.ts | 57 +++-- src/state/queries/resolve-uri.ts | 4 +- src/state/queries/search-posts-v2.ts | 21 +- src/state/queries/service-config.ts | 4 +- src/state/queries/service.ts | 4 +- src/state/queries/starter-pack-search.ts | 10 +- src/state/queries/starter-packs.ts | 68 +++--- src/state/queries/suggested-follows.ts | 19 +- src/state/queries/threadgate/index.ts | 32 +-- src/state/queries/threadgate/util.ts | 34 +-- .../trending/useGetSuggestedFeedsQuery.ts | 4 +- .../useGetSuggestedOnboardingUsersQuery.ts | 9 +- .../useGetSuggestedUsersForDiscoverQuery.ts | 9 +- .../useGetSuggestedUsersForExploreQuery.ts | 9 +- .../useGetSuggestedUsersForSeeMoreQuery.ts | 9 +- .../queries/trending/useGetTrendsQuery.ts | 6 +- ...useOnboardingSuggestedStarterPacksQuery.ts | 4 +- src/state/queries/usePostThread/index.ts | 7 +- src/state/queries/usePostThread/queryCache.ts | 60 ++--- src/state/queries/usePostThread/traversal.ts | 37 ++- src/state/queries/usePostThread/utils.ts | 20 +- .../queries/useSuggestedStarterPacksQuery.ts | 4 +- src/state/queries/util.ts | 26 +- .../useUpdateProfileVerificationCache.ts | 4 +- .../useVerificationCreateMutation.tsx | 9 +- .../useVerificationsRemoveMutation.tsx | 12 +- src/state/session/__tests__/clients-test.ts | 42 ++-- src/state/session/index.tsx | 4 +- src/state/session/moderation.ts | 4 +- src/types/bsky/__tests__/index.test.ts | 61 ++--- src/types/bsky/index.ts | 22 +- src/types/bsky/post.ts | 68 +++--- src/types/bsky/starterPack.ts | 12 +- src/view/com/auth/LoggedOut.tsx | 4 +- src/view/com/composer/Composer.tsx | 36 ++- src/view/com/composer/ComposerReplyTo.tsx | 36 +-- src/view/com/composer/drafts/state/api.ts | 38 ++- src/view/com/composer/drafts/state/queries.ts | 29 +-- src/view/com/composer/state/composer.ts | 19 +- src/view/com/composer/state/video.ts | 13 +- .../com/composer/text-input/TextInput.tsx | 4 +- .../com/composer/text-input/TextInput.web.tsx | 4 +- src/view/com/feeds/FeedPage.tsx | 7 +- src/view/com/feeds/FeedSourceCard.tsx | 8 +- .../notifications/NotificationFeedItem.tsx | 32 +-- src/view/com/post-thread/PostQuotes.tsx | 16 +- src/view/com/post/Post.tsx | 13 +- src/view/com/posts/PostFeed.tsx | 30 +-- src/view/com/posts/PostFeedItem.tsx | 45 ++-- src/view/com/posts/PostFeedReason.tsx | 10 +- 245 files changed, 2453 insertions(+), 2256 deletions(-) diff --git a/src/ageAssurance/const.ts b/src/ageAssurance/const.ts index 9d20a64ea6..5d12e38a90 100644 --- a/src/ageAssurance/const.ts +++ b/src/ageAssurance/const.ts @@ -6,7 +6,7 @@ import { IS_IOS, IS_WEB, } from '#/env' -import {app} from '#/lexicons' +import * as AppBskyAgeassuranceDefs from '#/lexicons/app/bsky/ageassurance/defs' /** * Minimum age required to access the app at all. @@ -40,16 +40,16 @@ export const AGE_ASSURANCE_PLATFORM: 'web' | 'ios' | 'android' = IS_WEB export const DEVICE_SIGNALS_SUPPORTED: boolean = (IS_IOS && IOS_MAJOR_VERSION >= 26) || (IS_ANDROID && ANDROID_API_LEVEL >= 23) -export const FALLBACK_REGION_CONFIG: app.bsky.ageassurance.defs.ConfigRegion = { +export const FALLBACK_REGION_CONFIG: AppBskyAgeassuranceDefs.ConfigRegion = { countryCode: '*', regionCode: undefined, minAccessAge: MIN_ACCESS_AGE, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: MIN_ACCESS_AGE, access: AgeAssuranceAccess.Full, }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: AgeAssuranceAccess.None, }), ], diff --git a/src/ageAssurance/data.tsx b/src/ageAssurance/data.tsx index 369b9eedd7..4574f78059 100644 --- a/src/ageAssurance/data.tsx +++ b/src/ageAssurance/data.tsx @@ -32,7 +32,10 @@ import { } from '#/ageAssurance/util' import {IS_DEV} from '#/env' import {useGeolocation} from '#/geolocation' -import {app, type chat} from '#/lexicons' +import {type chat} from '#/lexicons' +import type * as AppBskyAgeassuranceDefs from '#/lexicons/app/bsky/ageassurance/defs' +import * as AppBskyAgeassuranceGetConfig from '#/lexicons/app/bsky/ageassurance/getConfig' +import * as AppBskyAgeassuranceGetState from '#/lexicons/app/bsky/ageassurance/getState' import {device} from '#/storage' /** @@ -103,11 +106,11 @@ export async function getConfig() { * before there is any session (and while logged out), so it goes through the * process-wide public client rather than a bundle one. */ - return await getPublicAppviewClient().call(app.bsky.ageassurance.getConfig) + return await getPublicAppviewClient().call(AppBskyAgeassuranceGetConfig) } export function getConfigFromCache(): - app.bsky.ageassurance.getConfig.$OutputBody | undefined { - return qc.getQueryData( + AppBskyAgeassuranceGetConfig.$OutputBody | undefined { + return qc.getQueryData( configQueryKey, ) } @@ -128,7 +131,7 @@ export function prefetchConfig() { try { logger.debug(`prefetchAgeAssuranceConfig: resolving...`) const res = await networkRetry(3, () => getConfig()) - qc.setQueryData( + qc.setQueryData( configQueryKey, res, ) @@ -144,10 +147,7 @@ export function prefetchConfig() { export async function refetchConfig() { logger.debug(`refetchConfig: fetching...`) const res = await getConfig() - qc.setQueryData( - configQueryKey, - res, - ) + qc.setQueryData(configQueryKey, res) return res } export function useConfigQuery() { @@ -192,7 +192,7 @@ export async function getServerState({appviewClient}: {appviewClient: Client}) { logger.error(`getServerState: missing geolocation countryCode`) return null } - const data = await appviewClient.call(app.bsky.ageassurance.getState, { + const data = await appviewClient.call(AppBskyAgeassuranceGetState, { countryCode: geolocation.countryCode, regionCode: geolocation.regionCode, }) @@ -214,8 +214,8 @@ export function getServerStateFromCache({ did, }: { did: string -}): app.bsky.ageassurance.getState.$OutputBody | undefined { - return qc.getQueryData( +}): AppBskyAgeassuranceGetState.$OutputBody | undefined { + return qc.getQueryData( createServerStateQueryKey({did}), ) } @@ -241,7 +241,7 @@ export async function prefetchServerState({ logger.debug(`prefetchServerState: resolving...`) const res = await networkRetry(3, () => getServerState({appviewClient})) if (res) { - qc.setQueryData(qk, res) + qc.setQueryData(qk, res) } } catch (err) { const e = err as Error @@ -260,7 +260,7 @@ export async function refetchServerState({ logger.debug(`refetchServerState: fetching...`) const res = await networkRetry(3, () => getServerState({appviewClient})) if (res) { - qc.setQueryData( + qc.setQueryData( createServerStateQueryKey({did}), res, ) @@ -270,16 +270,16 @@ export async function refetchServerState({ export function usePatchServerState() { const {currentAccount} = useSession() return useCallback( - (next: app.bsky.ageassurance.defs.State) => { + (next: AppBskyAgeassuranceDefs.State) => { if (!currentAccount) return const did = currentAccount.did const prev = getServerStateFromCache({did}) - const merged: app.bsky.ageassurance.getState.$OutputBody = { + const merged: AppBskyAgeassuranceGetState.$OutputBody = { metadata: {}, ...(prev || {}), state: next, } - qc.setQueryData( + qc.setQueryData( createServerStateQueryKey({did}), merged, ) @@ -562,7 +562,7 @@ export function getDeviceSignalsFromCacheForRegion({ region, }: { did: string - region: app.bsky.ageassurance.defs.ConfigRegion + region: AppBskyAgeassuranceDefs.ConfigRegion }): AgeRange.AgeRangeResponse | undefined { const regionKey = createRegionKey(region) return getDeviceSignalsMapFromCache({did})?.[regionKey] @@ -716,11 +716,11 @@ export type AgeAssuranceServerData = { /** * The raw config from the appview. */ - config: app.bsky.ageassurance.defs.Config | undefined + config: AppBskyAgeassuranceDefs.Config | undefined /** * The raw state from the appview. Must be further processed before being useful. */ - state: app.bsky.ageassurance.defs.State | undefined + state: AppBskyAgeassuranceDefs.State | undefined metadata: AgeAssuranceMetadata | undefined /** * The native on-device age signals for the region the user is currently in, diff --git a/src/ageAssurance/debug.ts b/src/ageAssurance/debug.ts index 4b8041a9de..a470fa2131 100644 --- a/src/ageAssurance/debug.ts +++ b/src/ageAssurance/debug.ts @@ -4,7 +4,8 @@ import {toDatetimeString} from '@atproto/syntax' import {type OtherRequiredData} from '#/ageAssurance/data' import {IS_DEV, IS_E2E} from '#/env' import {type Geolocation} from '#/geolocation' -import {app} from '#/lexicons' +import * as AppBskyAgeassuranceDefs from '#/lexicons/app/bsky/ageassurance/defs' +import type * as AppBskyAgeassuranceGetState from '#/lexicons/app/bsky/ageassurance/getState' export const enabled = (IS_DEV && false) || IS_E2E @@ -28,28 +29,28 @@ export const otherRequiredData: OtherRequiredData = { } const serverStateEnabled = false || IS_E2E -export const serverState: - app.bsky.ageassurance.getState.$OutputBody | undefined = serverStateEnabled - ? { - state: { - lastInitiatedAt: undefined, // new Date(2025, 1, 1).toISOString(), - status: 'unknown', - access: 'unknown', - }, - metadata: { - accountCreatedAt: toDatetimeString(new Date(2023, 1, 1)), - }, - } - : undefined +export const serverState: AppBskyAgeassuranceGetState.$OutputBody | undefined = + serverStateEnabled + ? { + state: { + lastInitiatedAt: undefined, // new Date(2025, 1, 1).toISOString(), + status: 'unknown', + access: 'unknown', + }, + metadata: { + accountCreatedAt: toDatetimeString(new Date(2023, 1, 1)), + }, + } + : undefined -export const config: app.bsky.ageassurance.defs.Config = { +export const config: AppBskyAgeassuranceDefs.Config = { regions: [ { countryCode: 'AA', regionCode: undefined, minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'full', }), ], @@ -64,11 +65,11 @@ export const config: app.bsky.ageassurance.defs.Config = { minAccessAge: 18, additionalVerificationMethods: ['device'], rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -77,15 +78,15 @@ export const config: app.bsky.ageassurance.defs.Config = { countryCode: 'GB', minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 13, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -94,23 +95,23 @@ export const config: app.bsky.ageassurance.defs.Config = { countryCode: 'AU', minAccessAge: 16, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAccountNewerThan.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAccountNewerThan.build({ date: '2025-12-10T00:00:00Z', access: 'none', }), - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 16, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 16, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -120,15 +121,15 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'SD', minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 13, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -138,15 +139,15 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'WY', minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 13, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -156,15 +157,15 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'OH', minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 13, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -174,11 +175,11 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'MS', minAccessAge: 18, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -188,15 +189,15 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'VA', minAccessAge: 16, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 16, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 16, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -206,15 +207,15 @@ export const config: app.bsky.ageassurance.defs.Config = { regionCode: 'TN', minAccessAge: 18, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], @@ -223,19 +224,19 @@ export const config: app.bsky.ageassurance.defs.Config = { countryCode: 'BR', minAccessAge: 13, rules: [ - app.bsky.ageassurance.defs.configRegionRuleIfAssuredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfAssuredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 18, access: 'full', }), - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge.build({ + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge.build({ age: 13, access: 'safe', }), - app.bsky.ageassurance.defs.configRegionRuleDefault.build({ + AppBskyAgeassuranceDefs.configRegionRuleDefault.build({ access: 'none', }), ], diff --git a/src/ageAssurance/useBeginAgeAssurance.ts b/src/ageAssurance/useBeginAgeAssurance.ts index e6e79e348d..147d7d198b 100644 --- a/src/ageAssurance/useBeginAgeAssurance.ts +++ b/src/ageAssurance/useBeginAgeAssurance.ts @@ -15,7 +15,8 @@ import {logger} from '#/ageAssurance/logger' import {useAnalytics} from '#/analytics' import {BLUESKY_PROXY_DID} from '#/env' import {useGeolocation} from '#/geolocation' -import {app, com} from '#/lexicons' +import * as AppBskyAgeassuranceBegin from '#/lexicons/app/bsky/ageassurance/begin' +import * as ComAtprotoServerGetServiceAuth from '#/lexicons/com/atproto/server/getServiceAuth' const IS_DEV_ENV = BLUESKY_PROXY_DID !== PUBLIC_APPVIEW_DID const APPVIEW = IS_DEV_ENV ? DEV_ENV_APPVIEW : PUBLIC_APPVIEW @@ -29,7 +30,7 @@ export function useBeginAgeAssurance() { return useMutation({ async mutationFn( props: Omit< - app.bsky.ageassurance.begin.$InputBody, + AppBskyAgeassuranceBegin.$InputBody, 'countryCode' | 'regionCode' >, ) { @@ -39,7 +40,7 @@ export function useBeginAgeAssurance() { throw new Error(`Geolocation not available, cannot init age assurance.`) } - const {token} = await pdsClient.call(com.atproto.server.getServiceAuth, { + const {token} = await pdsClient.call(ComAtprotoServerGetServiceAuth, { aud: BLUESKY_PROXY_DID, lxm: `app.bsky.ageassurance.begin`, }) @@ -68,7 +69,7 @@ export function useBeginAgeAssurance() { */ const data = await wait( 2e3, - scopedClient.call(app.bsky.ageassurance.begin, { + scopedClient.call(AppBskyAgeassuranceBegin, { ...props, countryCode, regionCode, diff --git a/src/ageAssurance/util.ts b/src/ageAssurance/util.ts index d8657c157a..ce335361ef 100644 --- a/src/ageAssurance/util.ts +++ b/src/ageAssurance/util.ts @@ -24,7 +24,7 @@ import { } from '#/ageAssurance/types' import {type Geolocation, useGeolocation} from '#/geolocation' import {USRegionNameToRegionCode} from '#/geolocation/util' -import {app} from '#/lexicons' +import * as AppBskyAgeassuranceDefs from '#/lexicons/app/bsky/ageassurance/defs' import * as bsky from '#/types/bsky' /** @@ -42,9 +42,9 @@ import * as bsky from '#/types/bsky' * risk desyncing the write and read keys and silently losing grants. */ export function getAgeAssuranceRegionConfigForGeolocation( - config: app.bsky.ageassurance.defs.Config, + config: AppBskyAgeassuranceDefs.Config, geolocation: Geolocation, -): app.bsky.ageassurance.defs.ConfigRegion | undefined { +): AppBskyAgeassuranceDefs.ConfigRegion | undefined { return getAgeAssuranceRegionConfig(config, { countryCode: geolocation.countryCode ?? '', regionCode: geolocation.regionCode, @@ -60,9 +60,9 @@ export function getAgeAssuranceRegionConfigForGeolocation( * which can return undefined if the geolocation does not match any AA region. */ export function getAgeAssuranceRegionConfigWithFallback( - config: app.bsky.ageassurance.defs.Config, + config: AppBskyAgeassuranceDefs.Config, geolocation: Geolocation, -): app.bsky.ageassurance.defs.ConfigRegion { +): AppBskyAgeassuranceDefs.ConfigRegion { return ( getAgeAssuranceRegionConfigForGeolocation(config, geolocation) || FALLBACK_REGION_CONFIG @@ -75,9 +75,9 @@ export function getAgeAssuranceRegionConfigWithFallback( * historical KWS-only behavior). */ export function getRegionAdditionalVerificationMethods( - region: app.bsky.ageassurance.defs.ConfigRegion, + region: AppBskyAgeassuranceDefs.ConfigRegion, ): NonNullable< - app.bsky.ageassurance.defs.ConfigRegion['additionalVerificationMethods'] + AppBskyAgeassuranceDefs.ConfigRegion['additionalVerificationMethods'] > { return region.additionalVerificationMethods ?? [] } @@ -87,7 +87,7 @@ export function getRegionAdditionalVerificationMethods( * age APIs (Apple Declared Age Range / Google Play Age Signals). */ export function regionAllowsDeviceVerification( - region: app.bsky.ageassurance.defs.ConfigRegion, + region: AppBskyAgeassuranceDefs.ConfigRegion, ): boolean { return getRegionAdditionalVerificationMethods(region).includes('device') } @@ -123,7 +123,7 @@ export function createRegionKey(region: { * usable data. */ export function getAgeAssuranceDataFromDeviceSignals( - region: app.bsky.ageassurance.defs.ConfigRegion, + region: AppBskyAgeassuranceDefs.ConfigRegion, deviceSignals: AgeRange.AgeRangeResponse | undefined, ): { assuredAge?: number @@ -184,7 +184,7 @@ export function canBirthdateUpdateIncreaseAccess({ metadata, deviceSignals, }: { - region: app.bsky.ageassurance.defs.ConfigRegion + region: AppBskyAgeassuranceDefs.ConfigRegion metadata?: AgeAssuranceMetadata deviceSignals?: AgeRange.AgeRangeResponse }): boolean { @@ -214,11 +214,11 @@ export function canBirthdateUpdateIncreaseAccess({ for (const rule of region.rules) { if ( bsky.isType( - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredOverAge, + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredOverAge, rule, ) || bsky.isType( - app.bsky.ageassurance.defs.configRegionRuleIfDeclaredUnderAge, + AppBskyAgeassuranceDefs.configRegionRuleIfDeclaredUnderAge, rule, ) ) { @@ -310,7 +310,7 @@ export function computeAgeAssuranceFlags({ deviceSignals, }: { state: AgeAssuranceState - regionConfig: app.bsky.ageassurance.defs.ConfigRegion + regionConfig: AppBskyAgeassuranceDefs.ConfigRegion metadata?: AgeAssuranceMetadata deviceSignals?: AgeRange.AgeRangeResponse }): AgeAssuranceFlags { diff --git a/src/components/Autocomplete/useAutocomplete/index.ts b/src/components/Autocomplete/useAutocomplete/index.ts index 1834bfca67..1595a4cd56 100644 --- a/src/components/Autocomplete/useAutocomplete/index.ts +++ b/src/components/Autocomplete/useAutocomplete/index.ts @@ -13,7 +13,7 @@ import { type AutocompleteItemType, type AutocompleteProfile, } from '#/components/Autocomplete/types' -import {app} from '#/lexicons' +import * as AppBskyActorSearchActorsTypeahead from '#/lexicons/app/bsky/actor/searchActorsTypeahead' import {useEmojiSearch} from './useEmojiSearch' const DEFAULT_MOD_OPTS = { @@ -53,7 +53,7 @@ export function useAutocomplete({ // Going from "foo" to "foo." should not clear matches. q = q.toLowerCase().trim().replace(/\.$/, '') - const data = await client.call(app.bsky.actor.searchActorsTypeahead, { + const data = await client.call(AppBskyActorSearchActorsTypeahead, { q, limit: limit || 8, }) diff --git a/src/components/MediaPreview.tsx b/src/components/MediaPreview.tsx index 0763f8ee14..74d308d81c 100644 --- a/src/components/MediaPreview.tsx +++ b/src/components/MediaPreview.tsx @@ -12,7 +12,9 @@ import {MediaInsetBorder} from '#/components/MediaInsetBorder' import * as PeekMenu from '#/components/PeekMenu' import {Text} from '#/components/Typography' import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' -import {app} from '#/lexicons' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import type * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' /** @@ -23,7 +25,7 @@ export function Embed({ style, peekable = false, }: { - embed: app.bsky.feed.defs.PostView['embed'] + embed: AppBskyFeedDefs.PostView['embed'] style?: StyleProp peekable?: boolean }) { @@ -55,9 +57,9 @@ export function Embed({ const tiles: React.ReactNode[] = [] for (const item of e.view.items) { if (tiles.length >= 4) break - if (!bsky.isType(app.bsky.embed.gallery.viewImage, item)) continue + if (!bsky.isType(AppBskyEmbedGallery.viewImage, item)) continue if (peekable) { - const image: app.bsky.embed.images.ViewImage = { + const image: AppBskyEmbedImages.ViewImage = { thumb: item.thumbnail, fullsize: item.fullsize, alt: item.alt, @@ -110,7 +112,7 @@ export function Embed({ */ return ( ) @@ -208,7 +210,7 @@ export function VideoItem({ ) } -function PeekableImageItem({image}: {image: app.bsky.embed.images.ViewImage}) { +function PeekableImageItem({image}: {image: AppBskyEmbedImages.ViewImage}) { const {t: l} = useLingui() const saveImage = useSaveImageToMediaLibrary() diff --git a/src/components/Post/Embed/ImageEmbed.tsx b/src/components/Post/Embed/ImageEmbed.tsx index cc3ce6c443..acac2a8632 100644 --- a/src/components/Post/Embed/ImageEmbed.tsx +++ b/src/components/Post/Embed/ImageEmbed.tsx @@ -15,7 +15,8 @@ import {type Dimensions} from '#/components/Lightbox/types' import {ImageContextMenu} from '#/components/Post/Embed/ImageContextMenu' import {PostEmbedViewContext} from '#/components/Post/Embed/types' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import type * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' import * as bsky from '#/types/bsky' import {type EmbedType} from '#/types/bsky/post' import {type CommonProps} from './types' @@ -30,10 +31,10 @@ export function ImageEmbed({ }) { const ax = useAnalytics() const {openLightbox} = useLightboxControls() - const images: app.bsky.embed.images.ViewImage[] = + const images: AppBskyEmbedImages.ViewImage[] = embed.type === 'gallery' ? embed.view.items - .filter(item => bsky.isType(app.bsky.embed.gallery.viewImage, item)) + .filter(item => bsky.isType(AppBskyEmbedGallery.viewImage, item)) .map(item => ({ thumb: item.thumbnail, fullsize: item.fullsize, diff --git a/src/components/Post/Embed/index.tsx b/src/components/Post/Embed/index.tsx index 5e195ac2f9..74f38114d3 100644 --- a/src/components/Post/Embed/index.tsx +++ b/src/components/Post/Embed/index.tsx @@ -25,7 +25,8 @@ import {isStandardSiteEmbed} from '#/components/Post/Embed/StandardSiteEmbed/uti import {RichText} from '#/components/RichText' import {Embed as StarterPackCard} from '#/components/StarterPack/StarterPackCard' import {SubtleHover} from '#/components/SubtleHover' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import { type Embed as TEmbed, @@ -263,7 +264,7 @@ export function QuoteEmbed({ linkDisabled?: boolean }) { const moderationOpts = useModerationOpts() - const quote = useMemo<$Typed>( + const quote = useMemo<$Typed>( () => ({ ...embed.view, $type: 'app.bsky.feed.defs#postView', @@ -283,7 +284,7 @@ export function QuoteEmbed({ const itemTitle = `Post by ${quote.author.handle}` const richText = useMemo(() => { - if (!bsky.isType(app.bsky.feed.post, quote.record)) return undefined + if (!bsky.isType(AppBskyFeedPost, quote.record)) return undefined const {text, facets} = quote.record return text.trim() ? new RichTextAPI({text: text, facets: facets}) diff --git a/src/components/Post/Translated/index.tsx b/src/components/Post/Translated/index.tsx index 849222df03..7ae094be1f 100644 --- a/src/components/Post/Translated/index.tsx +++ b/src/components/Post/Translated/index.tsx @@ -27,7 +27,8 @@ import * as Select from '#/components/Select' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' const X_ICON_OFFSET = 16 @@ -38,7 +39,7 @@ export function TranslatedPost({ postTextStyle = a.text_md, }: { hideTranslateLink?: boolean - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView postTextStyle?: StyleProp }) { const langPrefs = useLanguagePrefs() @@ -46,10 +47,8 @@ export function TranslatedPost({ key: post.uri, }) - const record = useMemo(() => { - return bsky.isType(app.bsky.feed.post, post.record) - ? post.record - : undefined + const record = useMemo(() => { + return bsky.isType(AppBskyFeedPost, post.record) ? post.record : undefined }, [post]) const initialTranslationParams = useMemo(() => { return { diff --git a/src/components/RichText.tsx b/src/components/RichText.tsx index 0266dae0ce..d97a05a3ba 100644 --- a/src/components/RichText.tsx +++ b/src/components/RichText.tsx @@ -9,7 +9,7 @@ import {InlineLinkText, type LinkProps} from '#/components/Link' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {RichTextTag} from '#/components/RichTextTag' import {Text, type TextProps} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' const WORD_WRAP = {wordWrap: 1} @@ -141,7 +141,7 @@ export function RichText({ if ( mention && (disableMentionFacetValidation || - bsky.matches(app.bsky.richtext.facet.mention, mention)) && + bsky.matches(AppBskyRichtextFacet.mention, mention)) && !disableLinks ) { els.push( @@ -158,7 +158,7 @@ export function RichText({ , ) - } else if (link && bsky.matches(app.bsky.richtext.facet.link, link)) { + } else if (link && bsky.matches(AppBskyRichtextFacet.link, link)) { const isValidLink = URL_REGEX.test(link.uri) if (!isValidLink || disableLinks) { els.push(toShortUrl(segment.text)) @@ -183,7 +183,7 @@ export function RichText({ !disableLinks && enableTags && tag && - bsky.matches(app.bsky.richtext.facet.tag, tag) + bsky.matches(AppBskyRichtextFacet.tag, tag) ) { els.push( import('react-native-view-shot')) @@ -21,13 +22,13 @@ export function QrCode({ link, ref, }: { - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView link: string ref: React.Ref }) { const {record} = starterPack - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } diff --git a/src/components/StarterPack/QrCodeDialog.tsx b/src/components/StarterPack/QrCodeDialog.tsx index 5ff6213825..55616bd88e 100644 --- a/src/components/StarterPack/QrCodeDialog.tsx +++ b/src/components/StarterPack/QrCodeDialog.tsx @@ -23,7 +23,8 @@ import {QrCode} from '#/components/StarterPack/QrCode' import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {IS_NATIVE, IS_WEB} from '#/env' -import {app} from '#/lexicons' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' export function QrCodeDialog({ @@ -31,7 +32,7 @@ export function QrCodeDialog({ link, control, }: { - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView link?: string control: DialogControlProps }) { @@ -90,7 +91,7 @@ export function QrCodeDialog({ } else { setIsSaveProcessing(true) - if (!bsky.matches(app.bsky.graph.starterpack, starterPack.record)) { + if (!bsky.matches(AppBskyGraphStarterpack, starterPack.record)) { return } diff --git a/src/components/StarterPack/StarterPackCard.tsx b/src/components/StarterPack/StarterPackCard.tsx index 2f99ab0651..4f67e84efd 100644 --- a/src/components/StarterPack/StarterPackCard.tsx +++ b/src/components/StarterPack/StarterPackCard.tsx @@ -19,7 +19,7 @@ import { type LinkProps as BaseLinkProps, } from '#/components/Link' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' export function Default({ @@ -63,7 +63,7 @@ export function Card({ const t = useTheme() const {currentAccount} = useSession() - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } @@ -123,7 +123,7 @@ export function useStarterPackLink({ return { to: `/starter-pack/${handleOrDid}/${rkey}`, - label: bsky.isType(app.bsky.graph.starterpack, view.record) + label: bsky.isType(AppBskyGraphStarterpack, view.record) ? _(msg`Navigate to ${view.record.name}`) : _(msg`Navigate to starter pack`), precache, @@ -147,7 +147,7 @@ export function Link({ return {rkey, handleOrDid: creator.handle || creator.did} }, [starterPack]) - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } diff --git a/src/components/VideoPostCard.tsx b/src/components/VideoPostCard.tsx index 1005b0f49e..1a9b8d19a5 100644 --- a/src/components/VideoPostCard.tsx +++ b/src/components/VideoPostCard.tsx @@ -20,7 +20,10 @@ import {Link} from '#/components/Link' import {MediaInsetBorder} from '#/components/MediaInsetBorder' import * as Hider from '#/components/moderation/Hider' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' function getBlackColor(t: ReturnType) { @@ -37,7 +40,7 @@ export function VideoPostCard({ moderation, onInteract, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView sourceContext: VideoFeedSourceContext moderation: ModerationDecision /** @@ -70,10 +73,10 @@ export function VideoPostCard({ * Filtering should be done at a higher level, such as `PostFeed` or * `PostFeedVideoGridRow`, but we need to protect here as well. */ - if (!bsky.isType(app.bsky.embed.video.view, embed)) return null + if (!bsky.isType(AppBskyEmbedVideo.view, embed)) return null const author = post.author - const text = bsky.isType(app.bsky.feed.post, post.record) + const text = bsky.isType(AppBskyFeedPost, post.record) ? post.record?.text : '' const likeCount = post?.likeCount ?? 0 @@ -267,7 +270,7 @@ export function VideoPostCardPlaceholder() { export function VideoPostCardTextPlaceholder({ author, }: { - author?: app.bsky.actor.defs.ProfileViewBasic + author?: AppBskyActorDefs.ProfileViewBasic }) { const t = useTheme() @@ -347,7 +350,7 @@ export function CompactVideoPostCard({ moderation, onInteract, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView sourceContext: VideoFeedSourceContext moderation: ModerationDecision /** @@ -378,7 +381,7 @@ export function CompactVideoPostCard({ * Filtering should be done at a higher level, such as `PostFeed` or * `PostFeedVideoGridRow`, but we need to protect here as well. */ - if (!bsky.isType(app.bsky.embed.video.view, embed)) return null + if (!bsky.isType(AppBskyEmbedVideo.view, embed)) return null const likeCount = post?.likeCount ?? 0 const showLikeCount = false diff --git a/src/components/WhoCanReply.tsx b/src/components/WhoCanReply.tsx index 2202ed8e33..804362e4f7 100644 --- a/src/components/WhoCanReply.tsx +++ b/src/components/WhoCanReply.tsx @@ -33,11 +33,13 @@ import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' import * as bsky from '#/types/bsky' interface WhoCanReplyProps { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView isThreadAuthor: boolean style?: StyleProp } @@ -54,7 +56,7 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) { * unexpectedly, we should check to make sure it's for sure the root URI. */ const rootUri = - bsky.isType(app.bsky.feed.post, post.record) && post.record.reply?.root + bsky.isType(AppBskyFeedPost, post.record) && post.record.reply?.root ? post.record.reply.root.uri : post.uri const settings = useMemo(() => { @@ -202,7 +204,7 @@ function WhoCanReplyDialog({ embeddingDisabled, }: { control: Dialog.DialogControlProps - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView settings: ThreadgateAllowUISetting[] embeddingDisabled: boolean }) { @@ -248,7 +250,7 @@ function Rules({ settings, embeddingDisabled, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView settings: ThreadgateAllowUISetting[] embeddingDisabled: boolean }) { @@ -306,8 +308,8 @@ function Rule({ lists, }: { rule: ThreadgateAllowUISetting - post: app.bsky.feed.defs.PostView - lists: app.bsky.graph.defs.ListViewBasic[] | undefined + post: AppBskyFeedDefs.PostView + lists: AppBskyGraphDefs.ListViewBasic[] | undefined }) { if (rule.type === 'mention') { return mentioned users diff --git a/src/components/activity-notifications/SubscribeProfileDialog.tsx b/src/components/activity-notifications/SubscribeProfileDialog.tsx index 0f4b9a9ee5..eb428b7d2c 100644 --- a/src/components/activity-notifications/SubscribeProfileDialog.tsx +++ b/src/components/activity-notifications/SubscribeProfileDialog.tsx @@ -33,7 +33,9 @@ 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 type * as AppBskyNotificationDefs from '#/lexicons/app/bsky/notification/defs' +import type * as AppBskyNotificationListActivitySubscriptions from '#/lexicons/app/bsky/notification/listActivitySubscriptions' +import * as AppBskyNotificationPutActivitySubscription from '#/lexicons/app/bsky/notification/putActivitySubscription' import type * as bsky from '#/types/bsky' export function SubscribeProfileDialog({ @@ -117,9 +119,9 @@ function DialogInner({ error, } = useMutation({ mutationFn: async ( - activitySubscription: Un$Typed, + activitySubscription: Un$Typed, ) => { - await client.call(app.bsky.notification.putActivitySubscription, { + await client.call(AppBskyNotificationPutActivitySubscription, { subject: profile.did, activitySubscription, }) @@ -145,7 +147,7 @@ function DialogInner({ queryClient.setQueryData( RQKEY_getActivitySubscriptions, ( - old?: InfiniteData, + old?: InfiniteData, ) => { if (!old) return old return { @@ -305,8 +307,8 @@ function DialogInner({ } function parseActivitySubscription( - sub?: app.bsky.notification.defs.ActivitySubscription, -): Un$Typed { + sub?: AppBskyNotificationDefs.ActivitySubscription, +): Un$Typed { if (!sub) return {post: false, reply: false} const {post, reply} = sub return {post, reply} diff --git a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx index 10426d0ca6..f8987d8b28 100644 --- a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx +++ b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx @@ -16,7 +16,8 @@ import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {logger} from '#/ageAssurance' import {useAnalytics} from '#/analytics' -import {com, tools} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export function AgeAssuranceAppealDialog({ control, @@ -56,9 +57,9 @@ function Inner({control}: {control: Dialog.DialogControlProps}) { } await client.call( - com.atproto.moderation.createReport, + ComAtprotoModerationCreateReport, { - reasonType: tools.ozone.report.defs.reasonAppeal.value, + reasonType: ToolsOzoneReportDefs.reasonAppeal.value, subject: { $type: 'com.atproto.admin.defs#repoRef', did: currentAccount.did, diff --git a/src/components/ageAssurance/AgeAssuranceInitDialog.tsx b/src/components/ageAssurance/AgeAssuranceInitDialog.tsx index 052c3a4731..5a6368fc78 100644 --- a/src/components/ageAssurance/AgeAssuranceInitDialog.tsx +++ b/src/components/ageAssurance/AgeAssuranceInitDialog.tsx @@ -34,7 +34,7 @@ import {Text} from '#/components/Typography' import {useAgeAssurance} from '#/ageAssurance' import {useBeginAgeAssurance} from '#/ageAssurance/useBeginAgeAssurance' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyAgeassuranceBegin from '#/lexicons/app/bsky/ageassurance/begin' export {useDialogControl} from '#/components/Dialog/context' @@ -142,7 +142,7 @@ function Inner() { ) if (e instanceof XrpcResponseError) { - switch (matchXrpcError(e, app.bsky.ageassurance.begin)) { + switch (matchXrpcError(e, AppBskyAgeassuranceBegin)) { case 'InvalidEmail': error = _( msg`Please enter a valid, non-temporary email address. You may need to access this email in the future.`, diff --git a/src/components/contacts/screens/GetContacts.tsx b/src/components/contacts/screens/GetContacts.tsx index 534a9a708b..1070bf4e7a 100644 --- a/src/components/contacts/screens/GetContacts.tsx +++ b/src/components/contacts/screens/GetContacts.tsx @@ -29,7 +29,8 @@ 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 type * as AppBskyActorProfile from '#/lexicons/app/bsky/actor/profile' +import * as AppBskyContactImportContacts from '#/lexicons/app/bsky/contact/importContacts' import { contactsWithPhoneNumbersOnly, filterMatchedNumbers, @@ -86,7 +87,7 @@ export function GetContacts({ ) if (phoneNumbers.length > 0) { - const res = await appviewClient.call(app.bsky.contact.importContacts, { + const res = await appviewClient.call(AppBskyContactImportContacts, { token: state.token, contacts: phoneNumbers.slice(0, MAX_UPLOAD_COUNT), }) @@ -151,7 +152,7 @@ export function GetContacts({ ) return } - switch (matchXrpcError(err, app.bsky.contact.importContacts)) { + switch (matchXrpcError(err, AppBskyContactImportContacts)) { case 'TooManyContacts': Toast.show( _( @@ -341,7 +342,7 @@ async function createProfileRecord( : undefined await pdsClient.call(upsertProfile, async existing => { - let next: Un$Typed = existing ?? {} + let next: Un$Typed = existing ?? {} if (blobPromise) { const res = await blobPromise diff --git a/src/components/contacts/screens/PhoneInput.tsx b/src/components/contacts/screens/PhoneInput.tsx index 95d63055c0..5b75ce63a5 100644 --- a/src/components/contacts/screens/PhoneInput.tsx +++ b/src/components/contacts/screens/PhoneInput.tsx @@ -34,7 +34,7 @@ import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {useGeolocation} from '#/geolocation' -import {app} from '#/lexicons' +import * as AppBskyContactStartPhoneVerification from '#/lexicons/app/bsky/contact/startPhoneVerification' import {isFindContactsFeatureEnabled} from '../country-allowlist' import { constructFullPhoneNumber, @@ -79,7 +79,7 @@ export function PhoneInput({ phoneNumber: string }) => { // sends a onetime code to the user's phone number - await client.call(app.bsky.contact.startPhoneVerification, { + await client.call(AppBskyContactStartPhoneVerification, { phone: constructFullPhoneNumber(phoneCountryCode, phoneNumber), }) }, @@ -105,7 +105,7 @@ export function PhoneInput({ ) return } - switch (matchXrpcError(err, app.bsky.contact.startPhoneVerification)) { + switch (matchXrpcError(err, AppBskyContactStartPhoneVerification)) { case 'RateLimitExceeded': setError(_(msg`Rate limit exceeded. Please try again later.`)) return diff --git a/src/components/contacts/screens/VerifyNumber.tsx b/src/components/contacts/screens/VerifyNumber.tsx index 0bd5369397..57d165d6ed 100644 --- a/src/components/contacts/screens/VerifyNumber.tsx +++ b/src/components/contacts/screens/VerifyNumber.tsx @@ -22,7 +22,8 @@ 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 AppBskyContactStartPhoneVerification from '#/lexicons/app/bsky/contact/startPhoneVerification' +import * as AppBskyContactVerifyPhone from '#/lexicons/app/bsky/contact/verifyPhone' import {OTPInput} from '../components/OTPInput' import {constructFullPhoneNumber, prettyPhoneNumber} from '../phone-number' import {type Action, type State, useOnPressBackButton} from '../state' @@ -70,7 +71,7 @@ export function VerifyNumber({ isSuccess, } = useMutation({ mutationFn: async (code: string) => { - const data = await client.call(app.bsky.contact.verifyPhone, { + const data = await client.call(AppBskyContactVerifyPhone, { code, phone, }) @@ -102,7 +103,7 @@ export function VerifyNumber({ }) return } - switch (matchXrpcError(err, app.bsky.contact.verifyPhone)) { + switch (matchXrpcError(err, AppBskyContactVerifyPhone)) { case 'InvalidCode': setError({ retryable: true, @@ -140,7 +141,7 @@ export function VerifyNumber({ const {mutate: resendCode, isPending: isResendingCode} = useMutation({ mutationFn: async () => { - await client.call(app.bsky.contact.startPhoneVerification, {phone: phone}) + await client.call(AppBskyContactStartPhoneVerification, {phone: phone}) }, onSuccess: () => { dispatch({type: 'RESEND_VERIFICATION_CODE'}) @@ -161,7 +162,7 @@ export function VerifyNumber({ }) return } - switch (matchXrpcError(err, app.bsky.contact.startPhoneVerification)) { + switch (matchXrpcError(err, AppBskyContactStartPhoneVerification)) { case 'InvalidPhone': setError({ retryable: false, diff --git a/src/components/contacts/screens/ViewMatches.tsx b/src/components/contacts/screens/ViewMatches.tsx index 0d50bfdeeb..563e3c7ebe 100644 --- a/src/components/contacts/screens/ViewMatches.tsx +++ b/src/components/contacts/screens/ViewMatches.tsx @@ -42,7 +42,7 @@ import * as ProfileCard from '#/components/ProfileCard' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyContactDismissMatch from '#/lexicons/app/bsky/contact/dismissMatch' import type * as bsky from '#/types/bsky' import {InviteInfo} from '../components/InviteInfo' import {type Action, type Contact, type Match, type State} from '../state' @@ -224,7 +224,7 @@ export function ViewMatches({ const {mutate: dismissMatch} = useMutation({ mutationFn: async (did: string) => { - await client.call(app.bsky.contact.dismissMatch, { + await client.call(AppBskyContactDismissMatch, { subject: did as DidString, }) }, diff --git a/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts index 00472be52f..3152274c48 100644 --- a/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts +++ b/src/components/dialogs/EmailDialog/data/useConfirmEmail.ts @@ -1,7 +1,7 @@ import {useMutation} from '@tanstack/react-query' import {usePdsClient, useSession, useSessionApi} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoServerConfirmEmail from '#/lexicons/com/atproto/server/confirmEmail' export function useConfirmEmail({ onSuccess, @@ -17,7 +17,7 @@ export function useConfirmEmail({ throw new Error('No email found for the current account') } - await pdsClient.call(com.atproto.server.confirmEmail, { + await pdsClient.call(ComAtprotoServerConfirmEmail, { email: currentAccount.email.trim(), token: token.trim(), }) diff --git a/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts b/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts index 9f811b4818..ba3e53ce65 100644 --- a/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts +++ b/src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts @@ -1,7 +1,7 @@ import {useMutation} from '@tanstack/react-query' import {usePdsClient, useSession, useSessionApi} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoServerUpdateEmail from '#/lexicons/com/atproto/server/updateEmail' export function useManageEmail2FA() { const pdsClient = usePdsClient() @@ -18,7 +18,7 @@ export function useManageEmail2FA() { throw new Error('No email found for the current account') } - await pdsClient.call(com.atproto.server.updateEmail, { + await pdsClient.call(ComAtprotoServerUpdateEmail, { email: currentAccount.email, emailAuthFactor: enabled, token, diff --git a/src/components/dialogs/EmailDialog/data/useRequestEmailUpdate.ts b/src/components/dialogs/EmailDialog/data/useRequestEmailUpdate.ts index d6cd418444..0e2cdc343f 100644 --- a/src/components/dialogs/EmailDialog/data/useRequestEmailUpdate.ts +++ b/src/components/dialogs/EmailDialog/data/useRequestEmailUpdate.ts @@ -1,14 +1,14 @@ import {useMutation} from '@tanstack/react-query' import {usePdsClient} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoServerRequestEmailUpdate from '#/lexicons/com/atproto/server/requestEmailUpdate' export function useRequestEmailUpdate() { const client = usePdsClient() return useMutation({ mutationFn: async () => { - return await client.call(com.atproto.server.requestEmailUpdate) + return await client.call(ComAtprotoServerRequestEmailUpdate) }, }) } diff --git a/src/components/dialogs/EmailDialog/data/useRequestEmailVerification.ts b/src/components/dialogs/EmailDialog/data/useRequestEmailVerification.ts index 4152e61e58..5701119242 100644 --- a/src/components/dialogs/EmailDialog/data/useRequestEmailVerification.ts +++ b/src/components/dialogs/EmailDialog/data/useRequestEmailVerification.ts @@ -1,14 +1,14 @@ import {useMutation} from '@tanstack/react-query' import {usePdsClient} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoServerRequestEmailConfirmation from '#/lexicons/com/atproto/server/requestEmailConfirmation' export function useRequestEmailVerification() { const client = usePdsClient() return useMutation({ mutationFn: async () => { - await client.call(com.atproto.server.requestEmailConfirmation) + await client.call(ComAtprotoServerRequestEmailConfirmation) }, }) } diff --git a/src/components/dialogs/EmailDialog/data/useUpdateEmail.ts b/src/components/dialogs/EmailDialog/data/useUpdateEmail.ts index 7293227f59..e60e78e42c 100644 --- a/src/components/dialogs/EmailDialog/data/useUpdateEmail.ts +++ b/src/components/dialogs/EmailDialog/data/useUpdateEmail.ts @@ -3,7 +3,7 @@ import {useMutation} from '@tanstack/react-query' import {usePdsClient, useSessionApi} from '#/state/session' import {useRequestEmailUpdate} from '#/components/dialogs/EmailDialog/data/useRequestEmailUpdate' -import {com} from '#/lexicons' +import * as ComAtprotoServerUpdateEmail from '#/lexicons/com/atproto/server/updateEmail' async function updateEmailAndRefreshSession( pdsClient: Client, @@ -11,7 +11,7 @@ async function updateEmailAndRefreshSession( email: string, token?: string, ) { - await pdsClient.call(com.atproto.server.updateEmail, { + await pdsClient.call(ComAtprotoServerUpdateEmail, { email: email.trim(), token, }) diff --git a/src/components/dialogs/StarterPackDialog.tsx b/src/components/dialogs/StarterPackDialog.tsx index 6f9888da8c..91ef5feb70 100644 --- a/src/components/dialogs/StarterPackDialog.tsx +++ b/src/components/dialogs/StarterPackDialog.tsx @@ -29,11 +29,12 @@ 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 type * as AppBskyGraphGetStarterPacksWithMembership from '#/lexicons/app/bsky/graph/getStarterPacksWithMembership' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' type StarterPackWithMembership = - app.bsky.graph.getStarterPacksWithMembership.StarterPackWithMembership + AppBskyGraphGetStarterPacksWithMembership.StarterPackWithMembership export type StarterPackDialogProps = { control: Dialog.DialogControlProps @@ -321,7 +322,7 @@ function StarterPackItem({ const {record} = starterPack - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } diff --git a/src/components/dialogs/lists/CreateListFromStarterPackDialog.tsx b/src/components/dialogs/lists/CreateListFromStarterPackDialog.tsx index 0a528adedb..3ada5dde18 100644 --- a/src/components/dialogs/lists/CreateListFromStarterPackDialog.tsx +++ b/src/components/dialogs/lists/CreateListFromStarterPackDialog.tsx @@ -23,7 +23,11 @@ import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {app, com} from '#/lexicons' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetList from '#/lexicons/app/bsky/graph/getList' +import type * as AppBskyGraphListitem from '#/lexicons/app/bsky/graph/listitem' +import type * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' import {CreateOrEditListDialog} from './CreateOrEditListDialog' export function CreateListFromStarterPackDialog({ @@ -31,7 +35,7 @@ export function CreateListFromStarterPackDialog({ starterPack, }: { control: Dialog.DialogControlProps - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView }) { const {_} = useLingui() const t = useTheme() @@ -44,7 +48,7 @@ export function CreateListFromStarterPackDialog({ const createDialogControl = Dialog.useDialogControl() const loadingDialogControl = Dialog.useDialogControl() - const record = starterPack.record as app.bsky.graph.starterpack.Main + const record = starterPack.record as AppBskyGraphStarterpack.Main const onPressCreate = () => { control.close(() => createDialogControl.open()) @@ -75,9 +79,9 @@ export function CreateListFromStarterPackDialog({ ) if (items.length > 0) { - const listitemWrites: $Typed[] = + const listitemWrites: $Typed[] = items.map(item => { - const listitemRecord: $Typed = { + const listitemRecord: $Typed = { $type: 'app.bsky.graph.listitem', subject: item.subject.did, list: listUri as AtUriString, @@ -93,7 +97,7 @@ export function CreateListFromStarterPackDialog({ const chunks = chunk(listitemWrites, 50) for (const c of chunks) { - await pdsClient.call(com.atproto.repo.applyWrites, { + await pdsClient.call(ComAtprotoRepoApplyWrites, { repo: currentAccount.did, writes: c, }) @@ -104,7 +108,7 @@ export function CreateListFromStarterPackDialog({ 1e3, (res: {items: unknown[]}) => res.items.length > 0, () => - appviewClient.call(app.bsky.graph.getList, { + appviewClient.call(AppBskyGraphGetList, { list: listUri as AtUriString, limit: 1, }), diff --git a/src/components/dms/ChatInvite/Card.tsx b/src/components/dms/ChatInvite/Card.tsx index 177eb5d5ae..588d599a76 100644 --- a/src/components/dms/ChatInvite/Card.tsx +++ b/src/components/dms/ChatInvite/Card.tsx @@ -9,7 +9,7 @@ import {AvatarBubbles} from '#/components/AvatarBubbles' import {InlineLinkText} from '#/components/Link' import {ProfileBadges} from '#/components/ProfileBadges' import {Text} from '#/components/Typography' -import {chat} from '#/lexicons' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import {useChatInvite} from './Context' @@ -22,8 +22,7 @@ export function Card({size}: {size: 'large' | 'small'}) { const t = useTheme() const {preview, hasFixedHeight} = useChatInvite() - if (!bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) - return null + if (!bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview)) return null const ownerDisplayName = createSanitizedDisplayName(preview.owner) const ownerHandle = sanitizeHandle(preview.owner.handle, '@') diff --git a/src/components/dms/ChatInvite/Root.tsx b/src/components/dms/ChatInvite/Root.tsx index 83796e1e61..58168a4233 100644 --- a/src/components/dms/ChatInvite/Root.tsx +++ b/src/components/dms/ChatInvite/Root.tsx @@ -17,7 +17,7 @@ import {type Props as SVGIconProps} from '#/components/icons/common' import {RaisingHand4Finger_Stroke2_Corner2_Rounded as HandIcon} from '#/components/icons/RaisingHand' import {useIntentDialogs} from '#/components/intents/IntentDialogs' import * as Toast from '#/components/Toast' -import {chat} from '#/lexicons' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import { type ChatInviteAction, @@ -72,7 +72,7 @@ export function Root({ status = 'loading' } else if (error) { status = 'error' - } else if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) { + } else if (bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview)) { status = 'available' } else { // Resolved to a disabled/invalid/unrecognized preview - nothing to join. @@ -80,7 +80,7 @@ export function Root({ } let action: ChatInviteAction | undefined - if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) { + if (bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview)) { const convoId = preview.convo?.id const isFollowing = preview.owner.viewer?.followedBy ?? false const hasRequested = !convoId && preview.viewer?.requestedAt != null diff --git a/src/components/dms/LeaveConvoPrompt.tsx b/src/components/dms/LeaveConvoPrompt.tsx index a69dfcf845..fd3f92fb9c 100644 --- a/src/components/dms/LeaveConvoPrompt.tsx +++ b/src/components/dms/LeaveConvoPrompt.tsx @@ -9,7 +9,7 @@ import {type DialogOuterProps} from '#/components/Dialog' import * as Prompt from '#/components/Prompt' import * as Toast from '#/components/Toast' import {IS_NATIVE} from '#/env' -import {chat} from '#/lexicons' +import * as ChatBskyConvoLeaveConvo from '#/lexicons/chat/bsky/convo/leaveConvo' export function LeaveConvoPrompt({ control, @@ -38,7 +38,7 @@ export function LeaveConvoPrompt({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.convo.leaveConvo)) { + switch (matchXrpcError(error, ChatBskyConvoLeaveConvo)) { case 'InvalidConvo': errorMessage = l`Conversation not found.` break diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index ceebea16a6..fdf669f061 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -52,7 +52,10 @@ import * as ProfileCard from '#/components/ProfileCard' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' -import {app, chat} from '#/lexicons' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyEmbedJoinLink from '#/lexicons/chat/bsky/embed/joinLink' import * as bsky from '#/types/bsky' import {DateDivider} from './DateDivider' import {MessageItemEmbed} from './MessageItemEmbed' @@ -72,17 +75,15 @@ const SQUARED_BORDER_RADIUS = 4 const DISPLAY_NAME_INSET = 20 export type MessageItemNeighbor = - | chat.bsky.convo.defs.MessageView - | chat.bsky.convo.defs.DeletedMessageView - | null + ChatBskyConvoDefs.MessageView | ChatBskyConvoDefs.DeletedMessageView | null function messageIsReply(message: MessageItemNeighbor): boolean { return ( - bsky.isType(chat.bsky.convo.defs.messageView, message) && - (bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) || + bsky.isType(ChatBskyConvoDefs.messageView, message) && + (bsky.isType(ChatBskyConvoDefs.messageView, message.replyTo) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, message.replyTo) || bsky.isType( - chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, + ChatBskyConvoDefs.messageBeforeUserJoinedGroupView, message.replyTo, )) ) @@ -96,7 +97,7 @@ function isWithinClusterBoundary({ direction, }: { isPending: boolean - message: chat.bsky.convo.defs.MessageView + message: ChatBskyConvoDefs.MessageView adjacentMessage: MessageItemNeighbor isFromSameSender: boolean direction: 'prev' | 'next' @@ -108,7 +109,7 @@ function isWithinClusterBoundary({ return true } if (!isFromSameSender) return true - if (bsky.isType(chat.bsky.convo.defs.messageView, adjacentMessage)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, adjacentMessage)) { const currentSentAt = message.sentAt const thisDate = new Date(currentSentAt) const adjDate = new Date(adjacentMessage.sentAt) @@ -135,7 +136,7 @@ let MessageItem = ({ isGroupChat?: boolean prevMessage: MessageItemNeighbor nextMessage: MessageItemNeighbor - relatedProfiles: Map + relatedProfiles: Map }): React.ReactNode => { const t = useTheme() const {currentAccount} = useSession() @@ -153,17 +154,17 @@ let MessageItem = ({ // tombstone, or a before-joined placeholder. Narrow away the open-union // fallback so we only render shapes we understand. const replyTo = - bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) || + bsky.isType(ChatBskyConvoDefs.messageView, message.replyTo) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, message.replyTo) || bsky.isType( - chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, + ChatBskyConvoDefs.messageBeforeUserJoinedGroupView, message.replyTo, ) ? message.replyTo : undefined const replyToMessageId = replyTo && - !bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo) + !bsky.isType(ChatBskyConvoDefs.messageBeforeUserJoinedGroupView, replyTo) ? replyTo.id : undefined const onPressReplyTo = replyToMessageId @@ -177,14 +178,8 @@ let MessageItem = ({ const isFromSelf = message.sender?.did != null && message.sender.did === currentAccount?.did - const prevIsMessage = bsky.isType( - chat.bsky.convo.defs.messageView, - prevMessage, - ) - const nextIsMessage = bsky.isType( - chat.bsky.convo.defs.messageView, - nextMessage, - ) + const prevIsMessage = bsky.isType(ChatBskyConvoDefs.messageView, prevMessage) + const nextIsMessage = bsky.isType(ChatBskyConvoDefs.messageView, nextMessage) const isPrevFromSameSender = prevIsMessage && @@ -212,7 +207,7 @@ let MessageItem = ({ }) const hasLargeGapFromPrev = - !bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) || + !bsky.isType(ChatBskyConvoDefs.messageView, prevMessage) || new Date(message.sentAt).getTime() - new Date(prevMessage.sentAt).getTime() > MESSAGE_GAP_THRESHOLD_MS @@ -262,8 +257,8 @@ let MessageItem = ({ const isEmojiOnly = isOnlyEmoji(message.text) const hasEmbed = - bsky.isType(app.bsky.embed.record.view, message.embed) || - bsky.isType(chat.bsky.embed.joinLink.view, message.embed) + bsky.isType(AppBskyEmbedRecord.view, message.embed) || + bsky.isType(ChatBskyEmbedJoinLink.view, message.embed) const hasEmbedAndText = hasEmbed && rt.text.length > 0 const targetBottomRadius = squaredBottomCorner @@ -524,7 +519,7 @@ let MessageItem = ({ message={message} senderProfile={profile} moderationOpts={moderationOpts}> - {bsky.isType(app.bsky.embed.record.view, message.embed) && ( + {bsky.isType(AppBskyEmbedRecord.view, message.embed) && ( )} - {bsky.isType( - chat.bsky.embed.joinLink.view, - message.embed, - ) && ( + {bsky.isType(ChatBskyEmbedJoinLink.view, message.embed) && ( + profile: Shadow style?: AnimatedStyle }) { const {t: l} = useLingui() @@ -787,13 +779,13 @@ function ReplyCaption({ onPress, }: { replyTo: - | chat.bsky.convo.defs.MessageView - | chat.bsky.convo.defs.DeletedMessageView - | chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView + | ChatBskyConvoDefs.MessageView + | ChatBskyConvoDefs.DeletedMessageView + | ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView isFromSelf: boolean isGroupChat: boolean replierDisplayName: string | null - relatedProfiles: Map + relatedProfiles: Map onPress?: () => void }) { const t = useTheme() @@ -802,8 +794,8 @@ function ReplyCaption({ let caption: string = '' if ( - bsky.isType(chat.bsky.convo.defs.messageView, replyTo) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo) + bsky.isType(ChatBskyConvoDefs.messageView, replyTo) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, replyTo) ) { const originalSenderIsSelf = replyTo.sender.did === currentAccount?.did const originalProfile = relatedProfiles.get(replyTo.sender.did) @@ -876,11 +868,11 @@ function ReplyQuote({ onPress, }: { replyTo: - | chat.bsky.convo.defs.MessageView - | chat.bsky.convo.defs.DeletedMessageView - | chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView + | ChatBskyConvoDefs.MessageView + | ChatBskyConvoDefs.DeletedMessageView + | ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView isFromSelf: boolean - relatedProfiles: Map + relatedProfiles: Map onPress?: () => void }) { const t = useTheme() @@ -888,8 +880,8 @@ function ReplyQuote({ const getReplyPreviewText = useReplyPreviewText() const senderDid = - bsky.isType(chat.bsky.convo.defs.messageView, replyTo) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo) + bsky.isType(ChatBskyConvoDefs.messageView, replyTo) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, replyTo) ? replyTo.sender.did : undefined const senderProfile = useMaybeProfileShadow( @@ -919,10 +911,10 @@ function ReplyQuote({ comment: 'A reply summary in chat', }) subtle = true - } else if (bsky.isType(chat.bsky.convo.defs.messageView, replyTo)) { + } else if (bsky.isType(ChatBskyConvoDefs.messageView, replyTo)) { ;({text, subtle} = getReplyPreviewText(replyTo)) } else if ( - bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo) + bsky.isType(ChatBskyConvoDefs.messageBeforeUserJoinedGroupView, replyTo) ) { text = l({ message: `(message sent before you joined)`, diff --git a/src/components/dms/dialogs/NewChatDialog.tsx b/src/components/dms/dialogs/NewChatDialog.tsx index 7ee103ef9b..f89dface73 100644 --- a/src/components/dms/dialogs/NewChatDialog.tsx +++ b/src/components/dms/dialogs/NewChatDialog.tsx @@ -16,7 +16,8 @@ import {InitiateChatFlow} from '#/components/dms/InitiateChatFlow' import {MessagePlus_Stroke2_Corner0_Rounded as NewChatIcon} from '#/components/icons/Message' import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetConvoForMembers from '#/lexicons/chat/bsky/convo/getConvoForMembers' +import * as ChatBskyGroupCreateGroup from '#/lexicons/chat/bsky/group/createGroup' export function NewChat({ control, @@ -53,7 +54,7 @@ export function NewChat({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.convo.getConvoForMembers)) { + switch (matchXrpcError(error, ChatBskyConvoGetConvoForMembers)) { case 'AccountSuspended': errorMessage = l`Suspended accounts cannot participate in chat.` break @@ -88,7 +89,7 @@ export function NewChat({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.group.createGroup)) { + switch (matchXrpcError(error, ChatBskyGroupCreateGroup)) { case 'AccountSuspended': errorMessage = l`Suspended accounts cannot participate in a group chat.` break diff --git a/src/components/dms/dialogs/ShareViaChatDialog.tsx b/src/components/dms/dialogs/ShareViaChatDialog.tsx index f26dd47a57..e810b1b40a 100644 --- a/src/components/dms/dialogs/ShareViaChatDialog.tsx +++ b/src/components/dms/dialogs/ShareViaChatDialog.tsx @@ -11,7 +11,8 @@ import {SearchablePeopleList} from '#/components/dialogs/SearchablePeopleList' import {InitiateChatFlow} from '#/components/dms/InitiateChatFlow' import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetConvoForMembers from '#/lexicons/chat/bsky/convo/getConvoForMembers' +import * as ChatBskyGroupCreateGroup from '#/lexicons/chat/bsky/group/createGroup' export function SendViaChatDialog({ control, @@ -68,7 +69,7 @@ function SendViaChatDialogInner({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.convo.getConvoForMembers)) { + switch (matchXrpcError(error, ChatBskyConvoGetConvoForMembers)) { case 'AccountSuspended': errorMessage = l`Suspended accounts cannot participate in chat.` break @@ -104,7 +105,7 @@ function SendViaChatDialogInner({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.group.createGroup)) { + switch (matchXrpcError(error, ChatBskyGroupCreateGroup)) { case 'AccountSuspended': errorMessage = l`Suspended accounts cannot participate in a group chat.` break diff --git a/src/components/dms/getMessageInfo.ts b/src/components/dms/getMessageInfo.ts index afe41c625e..6908ebdc37 100644 --- a/src/components/dms/getMessageInfo.ts +++ b/src/components/dms/getMessageInfo.ts @@ -8,13 +8,16 @@ import { toBskyAppUrl, toShortUrl, } from '#/lib/strings/url-helpers' -import {app, chat} from '#/lexicons' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyEmbedJoinLink from '#/lexicons/chat/bsky/embed/joinLink' import * as bsky from '#/types/bsky' export type UserMessageInfo = { message: string | null sentAt: string - reportableMessage?: chat.bsky.convo.defs.MessageView + reportableMessage?: ChatBskyConvoDefs.MessageView isBlockedMessage: boolean } @@ -31,7 +34,7 @@ export function isDidBlockedInConvo({ primaryProfile, }: { did: string | undefined - members: chat.bsky.actor.defs.ProfileViewBasic[] + members: ChatBskyActorDefs.ProfileViewBasic[] primaryProfile?: bsky.profile.AnyProfileView }): boolean { if (!did) return false @@ -48,12 +51,12 @@ export function getMessageInfo({ primaryProfile, i18n, }: { - convo: chat.bsky.convo.defs.ConvoView + convo: ChatBskyConvoDefs.ConvoView currentAccountDid: string | undefined primaryProfile?: bsky.profile.AnyProfileView i18n: I18n }): UserMessageInfo | null { - if (!bsky.isType(chat.bsky.convo.defs.messageView, convo.lastMessage)) { + if (!bsky.isType(ChatBskyConvoDefs.messageView, convo.lastMessage)) { return null } @@ -62,7 +65,7 @@ export function getMessageInfo({ const senderDid = lastMessage.sender?.did const sender = convo.members.find(m => m.did === senderDid) const name = sender ? createSanitizedDisplayName(sender) : null - const isGroup = bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind) + const isGroup = bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind) const reportableMessage = isFromMe ? undefined : lastMessage const isBlockedMessage = isDidBlockedInConvo({ @@ -100,10 +103,10 @@ export function getMessageInfo({ msg`(contains embedded content)`, ) - if (bsky.isType(app.bsky.embed.record.view, lastMessage.embed)) { + if (bsky.isType(AppBskyEmbedRecord.view, lastMessage.embed)) { const embed = lastMessage.embed - if (bsky.isType(app.bsky.embed.record.viewRecord, embed.record)) { + if (bsky.isType(AppBskyEmbedRecord.viewRecord, embed.record)) { const record = embed.record const path = postUriToRelativePath(record.uri, { handle: record.author.handle, @@ -114,7 +117,7 @@ export function getMessageInfo({ } else { message = prefix(defaultEmbeddedContentMessage) } - } else if (bsky.isType(chat.bsky.embed.joinLink.view, lastMessage.embed)) { + } else if (bsky.isType(ChatBskyEmbedJoinLink.view, lastMessage.embed)) { message = prefix(i18n._(msg`(chat invite link)`)) } else { message = prefix(defaultEmbeddedContentMessage) diff --git a/src/components/dms/getReactionInfo.ts b/src/components/dms/getReactionInfo.ts index 477c44fbc3..9eb6bd1a3c 100644 --- a/src/components/dms/getReactionInfo.ts +++ b/src/components/dms/getReactionInfo.ts @@ -3,7 +3,7 @@ import {msg} from '@lingui/core/macro' import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name' import {isDidBlockedInConvo} from '#/components/dms/getMessageInfo' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' export type UserReactionInfo = { @@ -18,16 +18,13 @@ export function getReactionInfo({ primaryProfile, i18n, }: { - convo: chat.bsky.convo.defs.ConvoView + convo: ChatBskyConvoDefs.ConvoView currentAccountDid: string | undefined primaryProfile?: bsky.profile.AnyProfileView i18n: I18n }): UserReactionInfo | null { if ( - !bsky.isType( - chat.bsky.convo.defs.messageAndReactionView, - convo.lastReaction, - ) + !bsky.isType(ChatBskyConvoDefs.messageAndReactionView, convo.lastReaction) ) { return null } diff --git a/src/components/dms/getSystemMessageInfo.ts b/src/components/dms/getSystemMessageInfo.ts index 2262a3eb22..5470ede0df 100644 --- a/src/components/dms/getSystemMessageInfo.ts +++ b/src/components/dms/getSystemMessageInfo.ts @@ -14,13 +14,14 @@ import { Unlock_Stroke2_Corner2_Rounded as UnlockIcon, } from '#/components/icons/Lock' import {PencilLine_Stroke2_Corner0_Rounded as PencilIcon} from '#/components/icons/Pencil' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' export type SystemMessageAction = | { kind: 'profile' - profile: chat.bsky.actor.defs.ProfileViewBasic + profile: ChatBskyActorDefs.ProfileViewBasic displayName: string } | {kind: 'inviteLink'} @@ -32,8 +33,8 @@ export type SystemMessageInfo = { } function getProfileAction( - user: chat.bsky.convo.defs.SystemMessageReferredUser, - relatedProfiles: Map, + user: ChatBskyConvoDefs.SystemMessageReferredUser, + relatedProfiles: Map, ): Extract | null { const profile = relatedProfiles.get(user.did) if (!profile) return null @@ -45,11 +46,11 @@ function getProfileAction( } export function getSystemMessageInfo( - data: chat.bsky.convo.defs.SystemMessageView['data'], - relatedProfiles: Map, + data: ChatBskyConvoDefs.SystemMessageView['data'], + relatedProfiles: Map, opts = {short: false}, ): SystemMessageInfo | null { - if (bsky.isType(chat.bsky.convo.defs.systemMessageDataAddMember, data)) { + if (bsky.isType(ChatBskyConvoDefs.systemMessageDataAddMember, data)) { const action = getProfileAction(data.member, relatedProfiles) return { Icon: JoinIcon, @@ -63,7 +64,7 @@ export function getSystemMessageInfo( action: action ?? undefined, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataRemoveMember, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataRemoveMember, data) ) { const action = getProfileAction(data.member, relatedProfiles) return { @@ -77,9 +78,7 @@ export function getSystemMessageInfo( : msg`Someone was removed from the group`, action: action ?? undefined, } - } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberJoin, data) - ) { + } else if (bsky.isType(ChatBskyConvoDefs.systemMessageDataMemberJoin, data)) { const action = getProfileAction(data.member, relatedProfiles) return { Icon: JoinIcon, @@ -93,7 +92,7 @@ export function getSystemMessageInfo( action: action ?? undefined, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberLeave, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataMemberLeave, data) ) { const action = getProfileAction(data.member, relatedProfiles) return { @@ -107,24 +106,17 @@ export function getSystemMessageInfo( : msg`Someone left the group`, action: action ?? undefined, } - } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataLockConvo, data) - ) { + } else if (bsky.isType(ChatBskyConvoDefs.systemMessageDataLockConvo, data)) { return {Icon: LockIcon, message: msg`Chat locked`} } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataUnlockConvo, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataUnlockConvo, data) ) { return {Icon: UnlockIcon, message: msg`Chat unlocked`} } else if ( - bsky.isType( - chat.bsky.convo.defs.systemMessageDataLockConvoPermanently, - data, - ) + bsky.isType(ChatBskyConvoDefs.systemMessageDataLockConvoPermanently, data) ) { return {Icon: LockIcon, message: msg`Chat ended`} - } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataEditGroup, data) - ) { + } else if (bsky.isType(ChatBskyConvoDefs.systemMessageDataEditGroup, data)) { return { Icon: PencilIcon, message: @@ -133,7 +125,7 @@ export function getSystemMessageInfo( : msg`Chat title changed`, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataCreateJoinLink, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataCreateJoinLink, data) ) { return { Icon: ChainLinkIcon, @@ -141,7 +133,7 @@ export function getSystemMessageInfo( action: {kind: 'inviteLink'}, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataEditJoinLink, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataEditJoinLink, data) ) { return { Icon: ChainLinkIcon, @@ -149,7 +141,7 @@ export function getSystemMessageInfo( action: {kind: 'inviteLink'}, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataEnableJoinLink, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataEnableJoinLink, data) ) { return { Icon: ChainLinkIcon, @@ -157,7 +149,7 @@ export function getSystemMessageInfo( action: {kind: 'inviteLink'}, } } else if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataDisableJoinLink, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataDisableJoinLink, data) ) { return { Icon: ChainLinkBrokenIcon, diff --git a/src/components/dms/replyPreview.ts b/src/components/dms/replyPreview.ts index 91a736f269..bd1501d0c8 100644 --- a/src/components/dms/replyPreview.ts +++ b/src/components/dms/replyPreview.ts @@ -1,7 +1,11 @@ import {useLingui} from '@lingui/react/macro' import {BSKY_APP_HOST, toShortUrl} from '#/lib/strings/url-helpers' -import {app, chat} from '#/lexicons' +import * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import type * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyEmbedJoinLink from '#/lexicons/chat/bsky/embed/joinLink' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' /** @@ -14,13 +18,13 @@ type ReplyEmbedSummary = {type: 'external'; uri: string} | {type: 'post'} | {type: 'unknown'} function summarizeReplyEmbed( - embed: chat.bsky.convo.defs.MessageView['embed'], + embed: ChatBskyConvoDefs.MessageView['embed'], ): ReplyEmbedSummary { - if (!bsky.isType(app.bsky.embed.record.view, embed)) return {type: 'unknown'} + if (!bsky.isType(AppBskyEmbedRecord.view, embed)) return {type: 'unknown'} const {record} = embed - if (bsky.isType(app.bsky.embed.record.viewRecord, record)) { + if (bsky.isType(AppBskyEmbedRecord.viewRecord, record)) { const inner = record.embeds?.[0] - if (bsky.isType(app.bsky.embed.external.view, inner)) { + if (bsky.isType(AppBskyEmbedExternal.view, inner)) { return {type: 'external', uri: inner.external.uri} } return {type: 'post'} @@ -38,21 +42,19 @@ function summarizeReplyEmbed( * callers can render it in a muted/italic style. */ export function useReplyPreviewText(): ( - message: chat.bsky.convo.defs.MessageView, + message: ChatBskyConvoDefs.MessageView, ) => {text: string; subtle: boolean} { const {t: l} = useLingui() - return (message: chat.bsky.convo.defs.MessageView) => { + return (message: ChatBskyConvoDefs.MessageView) => { const text = message.text if (text.trim()) { return {text, subtle: false} } - if (bsky.isType(chat.bsky.embed.joinLink.view, message.embed)) { + if (bsky.isType(ChatBskyEmbedJoinLink.view, message.embed)) { const {joinLinkPreview} = message.embed - if ( - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, joinLinkPreview) - ) { + if (bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, joinLinkPreview)) { return { text: `${BSKY_APP_HOST}/chat/${joinLinkPreview.code}`, subtle: true, @@ -60,7 +62,7 @@ export function useReplyPreviewText(): ( } if ( bsky.isType( - chat.bsky.group.defs.disabledJoinLinkPreviewView, + ChatBskyGroupDefs.disabledJoinLinkPreviewView, joinLinkPreview, ) ) { @@ -74,7 +76,7 @@ export function useReplyPreviewText(): ( } if ( bsky.isType( - chat.bsky.group.defs.invalidJoinLinkPreviewView, + ChatBskyGroupDefs.invalidJoinLinkPreviewView, joinLinkPreview, ) ) { diff --git a/src/components/dms/util.ts b/src/components/dms/util.ts index 2618a84db8..8c2583d7ac 100644 --- a/src/components/dms/util.ts +++ b/src/components/dms/util.ts @@ -8,7 +8,8 @@ import {type Shadow} from '#/state/cache/profile-shadow' import {type ConvoState, ConvoStatus} from '#/state/messages/convo/types' import {platform} from '#/alf' import {type ReportSubject} from '#/components/moderation/ReportDialog/types' -import {chat} from '#/lexicons' +import * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' export const MESSAGE_GAP_THRESHOLD_MS = 60 * 60 * 1000 @@ -75,7 +76,7 @@ export function localDateString(date: Date) { } export function hasAlreadyReacted( - message: chat.bsky.convo.defs.MessageView, + message: ChatBskyConvoDefs.MessageView, myDid: string | undefined, emoji: string, ): boolean { @@ -96,9 +97,9 @@ export function hasAlreadyReacted( * already render anonymously ("Someone reacted"). */ export function filterBlockedReactions( - reactions: chat.bsky.convo.defs.ReactionView[] | undefined, - relatedProfiles: Map, -): chat.bsky.convo.defs.ReactionView[] { + reactions: ChatBskyConvoDefs.ReactionView[] | undefined, + relatedProfiles: Map, +): ChatBskyConvoDefs.ReactionView[] { if (!reactions) return [] return reactions.filter(reaction => { const profile = relatedProfiles.get(reaction.sender.did) @@ -107,7 +108,7 @@ export function filterBlockedReactions( } export function hasReachedReactionLimit( - message: chat.bsky.convo.defs.MessageView, + message: ChatBskyConvoDefs.MessageView, myDid: string | undefined, ): boolean { if (!message.reactions) { @@ -168,25 +169,25 @@ export function canReact({ return true } -export type GroupConvoMember = chat.bsky.actor.defs.ProfileViewBasic & { +export type GroupConvoMember = ChatBskyActorDefs.ProfileViewBasic & { // can be missing if account deleted - kind?: $Typed + kind?: $Typed } -export type DirectConvoMember = chat.bsky.actor.defs.ProfileViewBasic & { - kind: $Typed +export type DirectConvoMember = ChatBskyActorDefs.ProfileViewBasic & { + kind: $Typed } -export type ConvoWithDetails = {view: chat.bsky.convo.defs.ConvoView} & ( +export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & ( | { kind: 'group' - details: $Typed + details: $Typed primaryMember?: GroupConvoMember // the owner - may have left, thus optional members: Array } | { kind: 'direct' - details: $Typed + details: $Typed primaryMember: DirectConvoMember // the other user members: Array } @@ -197,14 +198,14 @@ export type ConvoWithDetails = {view: chat.bsky.convo.defs.ConvoView} & ( * and enforces the correct type for convo members. */ export function parseConvoView( - convoView: chat.bsky.convo.defs.ConvoView, + convoView: ChatBskyConvoDefs.ConvoView, ownDid: string | undefined, ): ConvoWithDetails | null { - if (bsky.isType(chat.bsky.convo.defs.groupConvo, convoView.kind)) { + if (bsky.isType(ChatBskyConvoDefs.groupConvo, convoView.kind)) { let owner: GroupConvoMember | undefined = undefined for (const member of convoView.members) { - if (bsky.isType(chat.bsky.actor.defs.groupConvoMember, member.kind)) { + if (bsky.isType(ChatBskyActorDefs.groupConvoMember, member.kind)) { if (member.kind.role === 'owner') { // have to do a type assertion here // this works: {...member, kind: member.kind} @@ -226,7 +227,7 @@ export function parseConvoView( primaryMember: owner, members: convoView.members as Array, } - } else if (bsky.isType(chat.bsky.convo.defs.directConvo, convoView.kind)) { + } else if (bsky.isType(ChatBskyConvoDefs.directConvo, convoView.kind)) { const otherUser = convoView.members.find(m => m.did !== ownDid) if (!otherUser) { @@ -269,7 +270,7 @@ export function getConvoReportSubject( const lastMessage = convo.view.lastMessage const reportableMessage = - bsky.isType(chat.bsky.convo.defs.messageView, lastMessage) && + bsky.isType(ChatBskyConvoDefs.messageView, lastMessage) && lastMessage.sender?.did !== ownDid ? lastMessage : null diff --git a/src/components/feeds/PostFeedVideoGridRow.tsx b/src/components/feeds/PostFeedVideoGridRow.tsx index 54c79c0afe..0a83cfa888 100644 --- a/src/components/feeds/PostFeedVideoGridRow.tsx +++ b/src/components/feeds/PostFeedVideoGridRow.tsx @@ -9,7 +9,7 @@ import { VideoPostCardPlaceholder, } from '#/components/VideoPostCard' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' import * as bsky from '#/types/bsky' export function PostFeedVideoGridRow({ @@ -22,7 +22,7 @@ export function PostFeedVideoGridRow({ const ax = useAnalytics() const gutters = useGutters(['base', 'base', 0, 'base']) const posts = slices - .filter(slice => bsky.isType(app.bsky.embed.video.view, slice.post.embed)) + .filter(slice => bsky.isType(AppBskyEmbedVideo.view, slice.post.embed)) .map(slice => ({ post: slice.post, moderation: slice.moderation, diff --git a/src/components/images/Gallery/maybeApplyGalleryOffsetStyles.ts b/src/components/images/Gallery/maybeApplyGalleryOffsetStyles.ts index 8634c2eb6d..ac86f40bca 100644 --- a/src/components/images/Gallery/maybeApplyGalleryOffsetStyles.ts +++ b/src/components/images/Gallery/maybeApplyGalleryOffsetStyles.ts @@ -3,7 +3,11 @@ import {type ModerationCause, type ModerationUI} from '@bsky/sdk/moderation' import {unique} from '#/lib/moderation' import {type AppModerationCause} from '#/components/Pills' import {Features, features} from '#/analytics/features' -import {app} from '#/lexicons' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' export const POST_META_NO_CONTENT_OFFSET = {paddingTop: 10} @@ -16,12 +20,12 @@ export function maybeApplyGalleryOffsetStyles( modui, additionalCauses, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView modui: ModerationUI additionalCauses?: ModerationCause[] | AppModerationCause[] }, ) { - if (!bsky.isType(app.bsky.feed.post, post.record)) { + if (!bsky.isType(AppBskyFeedPost, post.record)) { return } @@ -36,11 +40,10 @@ export function maybeApplyGalleryOffsetStyles( * First check if we even have images */ const embed = post.record.embed - const isImageEmbed = embed && bsky.isType(app.bsky.embed.images.main, embed) - const isGalleryEmbed = - embed && bsky.isType(app.bsky.embed.gallery.main, embed) + const isImageEmbed = embed && bsky.isType(AppBskyEmbedImages.main, embed) + const isGalleryEmbed = embed && bsky.isType(AppBskyEmbedGallery.main, embed) const isRecordWithMedia = - embed && bsky.isType(app.bsky.embed.recordWithMedia.main, embed) + embed && bsky.isType(AppBskyEmbedRecordWithMedia.main, embed) let hasImages = false if (isImageEmbed) { if (!isPostGalleryEmbedEnabled) return @@ -54,13 +57,13 @@ export function maybeApplyGalleryOffsetStyles( hasImages = true } if (isRecordWithMedia) { - if (bsky.isType(app.bsky.embed.images.main, embed.media)) { + if (bsky.isType(AppBskyEmbedImages.main, embed.media)) { if (!isPostGalleryEmbedEnabled) return // one image, not a gallery if (embed.media.images.length === 1) return hasImages = true } - if (bsky.isType(app.bsky.embed.gallery.main, embed.media)) { + if (bsky.isType(AppBskyEmbedGallery.main, embed.media)) { // single (or empty) gallery - no offset needed if (embed.media.items.length <= 1) return hasImages = true diff --git a/src/components/intents/GroupChatJoinDialog.tsx b/src/components/intents/GroupChatJoinDialog.tsx index 9266eb7a91..e397d154a2 100644 --- a/src/components/intents/GroupChatJoinDialog.tsx +++ b/src/components/intents/GroupChatJoinDialog.tsx @@ -45,7 +45,9 @@ import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {chat} from '#/lexicons' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' +import * as ChatBskyGroupRequestJoin from '#/lexicons/chat/bsky/group/requestJoin' +import * as ChatBskyGroupWithdrawJoinRequest from '#/lexicons/chat/bsky/group/withdrawJoinRequest' import * as bsky from '#/types/bsky' import {ProfileBadges} from '../ProfileBadges' @@ -146,7 +148,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) { if (isNetworkError(error)) { errorMessage = l`There was a problem with your internet connection, please try again` } else { - switch (matchXrpcError(error, chat.bsky.group.requestJoin)) { + switch (matchXrpcError(error, ChatBskyGroupRequestJoin)) { case 'ConvoLocked': errorMessage = l`This conversation is locked.` break @@ -163,10 +165,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) { errorMessage = l`The member limit has been reached.` const preview = data?.joinLinkPreviews[0] if ( - bsky.isType( - chat.bsky.group.defs.joinLinkPreviewView, - preview, - ) && + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview) && preview.convo?.id ) { ax.metric('groupchat:join:memberLimitReached', { @@ -199,7 +198,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) { if (isNetworkError(error)) { errorMessage = l`There was a problem with your internet connection, please try again` } else if ( - matchXrpcError(error, chat.bsky.group.withdrawJoinRequest) === + matchXrpcError(error, ChatBskyGroupWithdrawJoinRequest) === 'InvalidJoinRequest' ) { errorMessage = l`Invalid rescind request.` @@ -257,7 +256,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) { const joinLinkPreview = data.joinLinkPreviews[0] - if (!bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, joinLinkPreview)) { + if (!bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, joinLinkPreview)) { return ( <> diff --git a/src/components/intents/VerifyEmailIntentDialog.tsx b/src/components/intents/VerifyEmailIntentDialog.tsx index 272804af0e..2ee336eeb1 100644 --- a/src/components/intents/VerifyEmailIntentDialog.tsx +++ b/src/components/intents/VerifyEmailIntentDialog.tsx @@ -16,7 +16,7 @@ import {useIntentDialogs} from '#/components/intents/IntentDialogs' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerRequestEmailConfirmation from '#/lexicons/com/atproto/server/requestEmailConfirmation' export function VerifyEmailIntentDialog() { const {verifyEmailDialogControl: control} = useIntentDialogs() @@ -53,7 +53,7 @@ function Inner({}: {control: DialogControlProps}) { const onPressResendEmail = async () => { setSending(true) - await client.call(com.atproto.server.requestEmailConfirmation) + await client.call(ComAtprotoServerRequestEmailConfirmation) setSending(false) setStatus('resent') } diff --git a/src/components/interstitials/TrendingVideos.tsx b/src/components/interstitials/TrendingVideos.tsx index c719f6c66c..4c2c28c990 100644 --- a/src/components/interstitials/TrendingVideos.tsx +++ b/src/components/interstitials/TrendingVideos.tsx @@ -21,7 +21,7 @@ import { CompactVideoPostCardPlaceholder, } from '#/components/VideoPostCard' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' import * as bsky from '#/types/bsky' const CARD_WIDTH = 108 @@ -155,7 +155,7 @@ function VideoCards({ .flatMap(page => page.slices) .map(slice => slice.items[0]) .filter(Boolean) - .filter(item => bsky.isType(app.bsky.embed.video.view, item.post.embed)) + .filter(item => bsky.isType(AppBskyEmbedVideo.view, item.post.embed)) .slice(0, 8) }, [data]) diff --git a/src/components/moderation/AppealForm.tsx b/src/components/moderation/AppealForm.tsx index f40740f179..042755b908 100644 --- a/src/components/moderation/AppealForm.tsx +++ b/src/components/moderation/AppealForm.tsx @@ -22,14 +22,16 @@ import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_ANDROID} from '#/env' -import {com, tools} from '#/lexicons' +import type * as ComAtprotoLabelDefs from '#/lexicons/com/atproto/label/defs' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export function AppealForm({ label, control, onPressBack, }: { - label: com.atproto.label.defs.Label + label: ComAtprotoLabelDefs.Label control: Dialog.DialogOuterProps['control'] onPressBack: () => void }) { @@ -48,9 +50,9 @@ export function AppealForm({ const {mutate, isPending} = useMutation({ mutationFn: async () => { await client.call( - com.atproto.moderation.createReport, + ComAtprotoModerationCreateReport, { - reasonType: tools.ozone.report.defs.reasonAppeal.value, + reasonType: ToolsOzoneReportDefs.reasonAppeal.value, /* * `useLabelSubject` derives one shape or the other from the label's * `cid`: an at-uri plus cid for a record, or the label's `uri` reused diff --git a/src/components/moderation/BlockDialog.tsx b/src/components/moderation/BlockDialog.tsx index b49f6444c6..06d23c5f91 100644 --- a/src/components/moderation/BlockDialog.tsx +++ b/src/components/moderation/BlockDialog.tsx @@ -23,10 +23,12 @@ import {parseConvoView} from '#/components/dms/util' import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' -import {chat} from '#/lexicons' +import type * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoLeaveConvo from '#/lexicons/chat/bsky/convo/leaveConvo' +import * as ChatBskyGroupRemoveMembers from '#/lexicons/chat/bsky/group/removeMembers' import {type AnyProfileView} from '#/types/bsky/profile' -type Item = chat.bsky.convo.defs.ConvoView +type Item = ChatBskyConvoDefs.ConvoView type BlockDialogProps = { control: DialogControlProps @@ -251,7 +253,7 @@ function MutualGroupChat({ onOptimisticallyRemoveConvo, onRestoreConvo, }: { - view: chat.bsky.convo.defs.ConvoView + view: ChatBskyConvoDefs.ConvoView profileDid: string currentConvoId?: string onOptimisticallyRemoveConvo: (convoId: string) => void @@ -280,7 +282,7 @@ function MutualGroupChat({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.convo.leaveConvo)) { + switch (matchXrpcError(error, ChatBskyConvoLeaveConvo)) { case 'InvalidConvo': errorMessage = l`Chat not found.` break @@ -309,7 +311,7 @@ function MutualGroupChat({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.group.removeMembers)) { + switch (matchXrpcError(error, ChatBskyGroupRemoveMembers)) { case 'InvalidConvo': errorMessage = l`Chat not found.` break diff --git a/src/components/moderation/ReportDialog/action.ts b/src/components/moderation/ReportDialog/action.ts index da94e5dde2..d8dfe53b07 100644 --- a/src/components/moderation/ReportDialog/action.ts +++ b/src/components/moderation/ReportDialog/action.ts @@ -6,12 +6,12 @@ import {useMutation} from '@tanstack/react-query' import {logger} from '#/logger' import {useAppviewClient} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' import {NEW_TO_OLD_REASONS_MAP, REPORT_MOD_TOOL_NAME} from './const' import {type ReportState} from './state' import {type ParsedReportSubject} from './types' -type ReportInput = com.atproto.moderation.createReport.$InputBody +type ReportInput = ComAtprotoModerationCreateReport.$InputBody export function useSubmitReportMutation() { const {_} = useLingui() @@ -144,7 +144,7 @@ export function useSubmitReportMutation() { * Reports go to the labeler the user selected rather than Bluesky's, so * the proxy target is built per call from that labeler's creator did. */ - await client.call(com.atproto.moderation.createReport, report, { + await client.call(ComAtprotoModerationCreateReport, report, { service: `${labeler.creator.did}#atproto_labeler`, }) } diff --git a/src/components/moderation/ReportDialog/const.ts b/src/components/moderation/ReportDialog/const.ts index 34f736a86a..d8581f9ccf 100644 --- a/src/components/moderation/ReportDialog/const.ts +++ b/src/components/moderation/ReportDialog/const.ts @@ -2,7 +2,8 @@ import {applicationId} from 'expo-application' import {type ParsedReportSubject} from '#/components/moderation/ReportDialog/types' import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env' -import {com, tools} from '#/lexicons' +import * as ComAtprotoModerationDefs from '#/lexicons/com/atproto/moderation/defs' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export const DMCA_LINK = 'https://bsky.social/about/support/copyright' export const SUPPORT_PAGE = 'https://bsky.social/about/support' @@ -28,96 +29,96 @@ export const NEW_TO_OLD_REASON_MAPPING: Record = {} * @see https://github.com/bluesky-social/atproto/blob/4c15fb47cec26060bff2e710e95869a90c9d7fdd/packages/ozone/src/mod-service/profile.ts#L16-L64 */ export const NEW_TO_OLD_REASONS_MAP: Record< - tools.ozone.report.defs.ReasonType, - com.atproto.moderation.defs.ReasonType + ToolsOzoneReportDefs.ReasonType, + ComAtprotoModerationDefs.ReasonType > = { - [tools.ozone.report.defs.reasonAppeal.value]: - com.atproto.moderation.defs.reasonAppeal.value, - [tools.ozone.report.defs.reasonOther.value]: - com.atproto.moderation.defs.reasonOther.value, + [ToolsOzoneReportDefs.reasonAppeal.value]: + ComAtprotoModerationDefs.reasonAppeal.value, + [ToolsOzoneReportDefs.reasonOther.value]: + ComAtprotoModerationDefs.reasonOther.value, - [tools.ozone.report.defs.reasonViolenceAnimal.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceThreats.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceGraphicContent.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceGlorification.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceExtremistContent.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceTrafficking.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonViolenceOther.value]: - com.atproto.moderation.defs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceAnimal.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceThreats.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceGraphicContent.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceGlorification.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceExtremistContent.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceTrafficking.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonViolenceOther.value]: + ComAtprotoModerationDefs.reasonViolation.value, - [tools.ozone.report.defs.reasonSexualAbuseContent.value]: - com.atproto.moderation.defs.reasonSexual.value, - [tools.ozone.report.defs.reasonSexualNCII.value]: - com.atproto.moderation.defs.reasonSexual.value, - [tools.ozone.report.defs.reasonSexualDeepfake.value]: - com.atproto.moderation.defs.reasonSexual.value, - [tools.ozone.report.defs.reasonSexualAnimal.value]: - com.atproto.moderation.defs.reasonSexual.value, - [tools.ozone.report.defs.reasonSexualUnlabeled.value]: - com.atproto.moderation.defs.reasonSexual.value, - [tools.ozone.report.defs.reasonSexualOther.value]: - com.atproto.moderation.defs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualAbuseContent.value]: + ComAtprotoModerationDefs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualNCII.value]: + ComAtprotoModerationDefs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualDeepfake.value]: + ComAtprotoModerationDefs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualAnimal.value]: + ComAtprotoModerationDefs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualUnlabeled.value]: + ComAtprotoModerationDefs.reasonSexual.value, + [ToolsOzoneReportDefs.reasonSexualOther.value]: + ComAtprotoModerationDefs.reasonSexual.value, - [tools.ozone.report.defs.reasonChildSafetyCSAM.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonChildSafetyGroom.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonChildSafetyPrivacy.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonChildSafetyHarassment.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonChildSafetyOther.value]: - com.atproto.moderation.defs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonChildSafetyCSAM.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonChildSafetyGroom.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonChildSafetyPrivacy.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonChildSafetyHarassment.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonChildSafetyOther.value]: + ComAtprotoModerationDefs.reasonViolation.value, - [tools.ozone.report.defs.reasonHarassmentTroll.value]: - com.atproto.moderation.defs.reasonRude.value, - [tools.ozone.report.defs.reasonHarassmentTargeted.value]: - com.atproto.moderation.defs.reasonRude.value, - [tools.ozone.report.defs.reasonHarassmentHateSpeech.value]: - com.atproto.moderation.defs.reasonRude.value, - [tools.ozone.report.defs.reasonHarassmentDoxxing.value]: - com.atproto.moderation.defs.reasonRude.value, - [tools.ozone.report.defs.reasonHarassmentOther.value]: - com.atproto.moderation.defs.reasonRude.value, + [ToolsOzoneReportDefs.reasonHarassmentTroll.value]: + ComAtprotoModerationDefs.reasonRude.value, + [ToolsOzoneReportDefs.reasonHarassmentTargeted.value]: + ComAtprotoModerationDefs.reasonRude.value, + [ToolsOzoneReportDefs.reasonHarassmentHateSpeech.value]: + ComAtprotoModerationDefs.reasonRude.value, + [ToolsOzoneReportDefs.reasonHarassmentDoxxing.value]: + ComAtprotoModerationDefs.reasonRude.value, + [ToolsOzoneReportDefs.reasonHarassmentOther.value]: + ComAtprotoModerationDefs.reasonRude.value, - [tools.ozone.report.defs.reasonMisleadingBot.value]: - com.atproto.moderation.defs.reasonMisleading.value, - [tools.ozone.report.defs.reasonMisleadingImpersonation.value]: - com.atproto.moderation.defs.reasonMisleading.value, - [tools.ozone.report.defs.reasonMisleadingSpam.value]: - com.atproto.moderation.defs.reasonSpam.value, - [tools.ozone.report.defs.reasonMisleadingScam.value]: - com.atproto.moderation.defs.reasonMisleading.value, - [tools.ozone.report.defs.reasonMisleadingElections.value]: - com.atproto.moderation.defs.reasonMisleading.value, - [tools.ozone.report.defs.reasonMisleadingOther.value]: - com.atproto.moderation.defs.reasonMisleading.value, + [ToolsOzoneReportDefs.reasonMisleadingBot.value]: + ComAtprotoModerationDefs.reasonMisleading.value, + [ToolsOzoneReportDefs.reasonMisleadingImpersonation.value]: + ComAtprotoModerationDefs.reasonMisleading.value, + [ToolsOzoneReportDefs.reasonMisleadingSpam.value]: + ComAtprotoModerationDefs.reasonSpam.value, + [ToolsOzoneReportDefs.reasonMisleadingScam.value]: + ComAtprotoModerationDefs.reasonMisleading.value, + [ToolsOzoneReportDefs.reasonMisleadingElections.value]: + ComAtprotoModerationDefs.reasonMisleading.value, + [ToolsOzoneReportDefs.reasonMisleadingOther.value]: + ComAtprotoModerationDefs.reasonMisleading.value, - [tools.ozone.report.defs.reasonRuleSiteSecurity.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonRuleProhibitedSales.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonRuleBanEvasion.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonRuleOther.value]: - com.atproto.moderation.defs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonRuleSiteSecurity.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonRuleProhibitedSales.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonRuleBanEvasion.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonRuleOther.value]: + ComAtprotoModerationDefs.reasonViolation.value, - [tools.ozone.report.defs.reasonSelfHarmContent.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonSelfHarmED.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonSelfHarmStunts.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonSelfHarmSubstances.value]: - com.atproto.moderation.defs.reasonViolation.value, - [tools.ozone.report.defs.reasonSelfHarmOther.value]: - com.atproto.moderation.defs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonSelfHarmContent.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonSelfHarmED.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonSelfHarmStunts.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonSelfHarmSubstances.value]: + ComAtprotoModerationDefs.reasonViolation.value, + [ToolsOzoneReportDefs.reasonSelfHarmOther.value]: + ComAtprotoModerationDefs.reasonViolation.value, } /** @@ -125,32 +126,29 @@ export const NEW_TO_OLD_REASONS_MAP: Record< * @see https://github.com/bluesky-social/proposals/tree/main/0009-mod-report-granularity#backwards-compatibility */ export const OLD_TO_NEW_REASONS_MAP: Record< - Exclude< - com.atproto.moderation.defs.ReasonType, - tools.ozone.report.defs.ReasonType - >, - tools.ozone.report.defs.ReasonType + Exclude, + ToolsOzoneReportDefs.ReasonType > = { - [com.atproto.moderation.defs.reasonSpam.value]: [ - tools.ozone.report.defs.reasonMisleadingSpam.value, + [ComAtprotoModerationDefs.reasonSpam.value]: [ + ToolsOzoneReportDefs.reasonMisleadingSpam.value, ], - [com.atproto.moderation.defs.reasonViolation.value]: [ - tools.ozone.report.defs.reasonRuleOther.value, + [ComAtprotoModerationDefs.reasonViolation.value]: [ + ToolsOzoneReportDefs.reasonRuleOther.value, ], - [com.atproto.moderation.defs.reasonMisleading.value]: [ - tools.ozone.report.defs.reasonMisleadingOther.value, + [ComAtprotoModerationDefs.reasonMisleading.value]: [ + ToolsOzoneReportDefs.reasonMisleadingOther.value, ], - [com.atproto.moderation.defs.reasonSexual.value]: [ - tools.ozone.report.defs.reasonSexualUnlabeled.value, + [ComAtprotoModerationDefs.reasonSexual.value]: [ + ToolsOzoneReportDefs.reasonSexualUnlabeled.value, ], - [com.atproto.moderation.defs.reasonRude.value]: [ - tools.ozone.report.defs.reasonHarassmentOther.value, + [ComAtprotoModerationDefs.reasonRude.value]: [ + ToolsOzoneReportDefs.reasonHarassmentOther.value, ], - [com.atproto.moderation.defs.reasonOther.value]: [ - tools.ozone.report.defs.reasonOther.value, + [ComAtprotoModerationDefs.reasonOther.value]: [ + ToolsOzoneReportDefs.reasonOther.value, ], - [com.atproto.moderation.defs.reasonAppeal.value]: [ - tools.ozone.report.defs.reasonAppeal.value, + [ComAtprotoModerationDefs.reasonAppeal.value]: [ + ToolsOzoneReportDefs.reasonAppeal.value, ], } @@ -158,27 +156,27 @@ export const OLD_TO_NEW_REASONS_MAP: Record< * Set of report reasons that should optionally include additional details from * the reporter. */ -export const OTHER_REPORT_REASONS: Set = +export const OTHER_REPORT_REASONS: Set = new Set([ - tools.ozone.report.defs.reasonViolenceOther.value, - tools.ozone.report.defs.reasonSexualOther.value, - tools.ozone.report.defs.reasonChildSafetyOther.value, - tools.ozone.report.defs.reasonHarassmentOther.value, - tools.ozone.report.defs.reasonMisleadingOther.value, - tools.ozone.report.defs.reasonRuleOther.value, - tools.ozone.report.defs.reasonSelfHarmOther.value, - tools.ozone.report.defs.reasonOther.value, + ToolsOzoneReportDefs.reasonViolenceOther.value, + ToolsOzoneReportDefs.reasonSexualOther.value, + ToolsOzoneReportDefs.reasonChildSafetyOther.value, + ToolsOzoneReportDefs.reasonHarassmentOther.value, + ToolsOzoneReportDefs.reasonMisleadingOther.value, + ToolsOzoneReportDefs.reasonRuleOther.value, + ToolsOzoneReportDefs.reasonSelfHarmOther.value, + ToolsOzoneReportDefs.reasonOther.value, ]) /** * Set of report reasons that should only be sent to Bluesky's moderation service. */ -export const BSKY_LABELER_ONLY_REPORT_REASONS: Set = +export const BSKY_LABELER_ONLY_REPORT_REASONS: Set = new Set([ - tools.ozone.report.defs.reasonChildSafetyCSAM.value, - tools.ozone.report.defs.reasonChildSafetyGroom.value, - tools.ozone.report.defs.reasonChildSafetyOther.value, - tools.ozone.report.defs.reasonViolenceExtremistContent.value, + ToolsOzoneReportDefs.reasonChildSafetyCSAM.value, + ToolsOzoneReportDefs.reasonChildSafetyGroom.value, + ToolsOzoneReportDefs.reasonChildSafetyOther.value, + ToolsOzoneReportDefs.reasonViolenceExtremistContent.value, ]) /** diff --git a/src/components/moderation/ReportDialog/errors.test.ts b/src/components/moderation/ReportDialog/errors.test.ts index bef4d2a38d..addb2ee868 100644 --- a/src/components/moderation/ReportDialog/errors.test.ts +++ b/src/components/moderation/ReportDialog/errors.test.ts @@ -1,6 +1,6 @@ import {XrpcResponseError} from '@atproto/lex' -import {com} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' import {classifyReportError} from './errors' /** @@ -9,7 +9,7 @@ import {classifyReportError} from './errors' */ function xrpcError(status: number, error: string, message: string) { return new XrpcResponseError( - com.atproto.moderation.createReport.main, + ComAtprotoModerationCreateReport.main, new Response(null, {status}), {encoding: 'application/json', body: {error, message}}, ) diff --git a/src/components/moderation/ReportDialog/state.test.ts b/src/components/moderation/ReportDialog/state.test.ts index 6f64c1a7c3..7107519ead 100644 --- a/src/components/moderation/ReportDialog/state.test.ts +++ b/src/components/moderation/ReportDialog/state.test.ts @@ -1,4 +1,5 @@ -import {type app, tools} from '#/lexicons' +import {type app} from '#/lexicons' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' import { getNciiQualificationOutcome, initialState, @@ -8,12 +9,12 @@ import { const nciiOption = { title: 'Non-consensual intimate imagery', - reason: tools.ozone.report.defs.reasonSexualNCII.value, + reason: ToolsOzoneReportDefs.reasonSexualNCII.value, } const otherOption = { title: 'Unlabeled adult content', - reason: tools.ozone.report.defs.reasonSexualUnlabeled.value, + reason: ToolsOzoneReportDefs.reasonSexualUnlabeled.value, } function selectNciiOption(state: ReportState = initialState) { diff --git a/src/components/moderation/ReportDialog/state.ts b/src/components/moderation/ReportDialog/state.ts index 9be5145ce7..685b26ae65 100644 --- a/src/components/moderation/ReportDialog/state.ts +++ b/src/components/moderation/ReportDialog/state.ts @@ -3,7 +3,8 @@ import { type ReportCategoryConfig, type ReportOption, } from '#/components/moderation/ReportDialog/utils/useReportOptions' -import {type app, tools} from '#/lexicons' +import {type app} from '#/lexicons' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export type NciiQualification = { isDepicted?: boolean @@ -124,7 +125,7 @@ export function reducer(state: ReportState, action: ReportAction): ReportState { } case 'selectOption': { const isNcii = - action.option.reason === tools.ozone.report.defs.reasonSexualNCII.value + action.option.reason === ToolsOzoneReportDefs.reasonSexualNCII.value return { ...state, selectedOption: action.option, diff --git a/src/components/moderation/ReportDialog/utils/parseReportSubject.ts b/src/components/moderation/ReportDialog/utils/parseReportSubject.ts index 8b03c7b02a..105a14ec28 100644 --- a/src/components/moderation/ReportDialog/utils/parseReportSubject.ts +++ b/src/components/moderation/ReportDialog/utils/parseReportSubject.ts @@ -2,7 +2,10 @@ import { type ParsedReportSubject, type ReportSubject, } from '#/components/moderation/ReportDialog/types' -import {app} from '#/lexicons' +import * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' import * as bsky from '#/types/bsky' export function parseReportSubject( @@ -25,16 +28,16 @@ export function parseReportSubject( } if ( - bsky.isType(app.bsky.actor.defs.profileViewBasic, subject) || - bsky.isType(app.bsky.actor.defs.profileView, subject) || - bsky.isType(app.bsky.actor.defs.profileViewDetailed, subject) + bsky.isType(AppBskyActorDefs.profileViewBasic, subject) || + bsky.isType(AppBskyActorDefs.profileView, subject) || + bsky.isType(AppBskyActorDefs.profileViewDetailed, subject) ) { return { type: 'account', did: subject.did, nsid: 'app.bsky.actor.profile', } - } else if (bsky.isType(app.bsky.actor.defs.statusView, subject)) { + } else if (bsky.isType(AppBskyActorDefs.statusView, subject)) { if (!subject.uri || !subject.cid) return return { type: 'status', @@ -42,31 +45,31 @@ export function parseReportSubject( cid: subject.cid, nsid: 'app.bsky.actor.status', } - } else if (bsky.isType(app.bsky.graph.defs.listView, subject)) { + } else if (bsky.isType(AppBskyGraphDefs.listView, subject)) { return { type: 'list', uri: subject.uri, cid: subject.cid, nsid: 'app.bsky.graph.list', } - } else if (bsky.isType(app.bsky.feed.defs.generatorView, subject)) { + } else if (bsky.isType(AppBskyFeedDefs.generatorView, subject)) { return { type: 'feed', uri: subject.uri, cid: subject.cid, nsid: 'app.bsky.feed.generator', } - } else if (bsky.isType(app.bsky.graph.defs.starterPackView, subject)) { + } else if (bsky.isType(AppBskyGraphDefs.starterPackView, subject)) { return { type: 'starterPack', uri: subject.uri, cid: subject.cid, nsid: 'app.bsky.graph.starterPack', } - } else if (bsky.isType(app.bsky.feed.defs.postView, subject)) { + } else if (bsky.isType(AppBskyFeedDefs.postView, subject)) { const record = subject.record const embed = bsky.post.parseEmbed(subject.embed) - if (bsky.isType(app.bsky.feed.post, record)) { + if (bsky.isType(AppBskyFeedPost, record)) { return { type: 'post', uri: subject.uri, diff --git a/src/components/moderation/ReportDialog/utils/useReportOptions.ts b/src/components/moderation/ReportDialog/utils/useReportOptions.ts index b4a2033780..8c843c5c04 100644 --- a/src/components/moderation/ReportDialog/utils/useReportOptions.ts +++ b/src/components/moderation/ReportDialog/utils/useReportOptions.ts @@ -2,7 +2,7 @@ import {useMemo} from 'react' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' -import {tools} from '#/lexicons' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export type ReportCategory = | 'childSafety' @@ -23,7 +23,7 @@ export type ReportCategoryConfig = { export type ReportOption = { title: string - reason: tools.ozone.report.defs.ReasonType + reason: ToolsOzoneReportDefs.ReasonType } export function useReportOptions() { @@ -38,27 +38,27 @@ export function useReportOptions() { options: [ { title: _(msg`Spam`), - reason: tools.ozone.report.defs.reasonMisleadingSpam.value, + reason: ToolsOzoneReportDefs.reasonMisleadingSpam.value, }, { title: _(msg`Scam`), - reason: tools.ozone.report.defs.reasonMisleadingScam.value, + reason: ToolsOzoneReportDefs.reasonMisleadingScam.value, }, { title: _(msg`Fake account or bot`), - reason: tools.ozone.report.defs.reasonMisleadingBot.value, + reason: ToolsOzoneReportDefs.reasonMisleadingBot.value, }, { title: _(msg`Impersonation`), - reason: tools.ozone.report.defs.reasonMisleadingImpersonation.value, + reason: ToolsOzoneReportDefs.reasonMisleadingImpersonation.value, }, { title: _(msg`False information about elections`), - reason: tools.ozone.report.defs.reasonMisleadingElections.value, + reason: ToolsOzoneReportDefs.reasonMisleadingElections.value, }, { title: _(msg`Other misleading content`), - reason: tools.ozone.report.defs.reasonMisleadingOther.value, + reason: ToolsOzoneReportDefs.reasonMisleadingOther.value, }, ], }, @@ -71,27 +71,27 @@ export function useReportOptions() { options: [ { title: _(msg`Unlabeled adult content`), - reason: tools.ozone.report.defs.reasonSexualUnlabeled.value, + reason: ToolsOzoneReportDefs.reasonSexualUnlabeled.value, }, { title: _(msg`Adult sexual abuse content`), - reason: tools.ozone.report.defs.reasonSexualAbuseContent.value, + reason: ToolsOzoneReportDefs.reasonSexualAbuseContent.value, }, { title: _(msg`Non-consensual intimate imagery`), - reason: tools.ozone.report.defs.reasonSexualNCII.value, + reason: ToolsOzoneReportDefs.reasonSexualNCII.value, }, { title: _(msg`Deepfake adult content`), - reason: tools.ozone.report.defs.reasonSexualDeepfake.value, + reason: ToolsOzoneReportDefs.reasonSexualDeepfake.value, }, { title: _(msg`Animal sexual abuse`), - reason: tools.ozone.report.defs.reasonSexualAnimal.value, + reason: ToolsOzoneReportDefs.reasonSexualAnimal.value, }, { title: _(msg`Other sexual violence content`), - reason: tools.ozone.report.defs.reasonSexualOther.value, + reason: ToolsOzoneReportDefs.reasonSexualOther.value, }, ], }, @@ -102,23 +102,23 @@ export function useReportOptions() { options: [ { title: _(msg`Trolling`), - reason: tools.ozone.report.defs.reasonHarassmentTroll.value, + reason: ToolsOzoneReportDefs.reasonHarassmentTroll.value, }, { title: _(msg`Targeted harassment`), - reason: tools.ozone.report.defs.reasonHarassmentTargeted.value, + reason: ToolsOzoneReportDefs.reasonHarassmentTargeted.value, }, { title: _(msg`Hate speech`), - reason: tools.ozone.report.defs.reasonHarassmentHateSpeech.value, + reason: ToolsOzoneReportDefs.reasonHarassmentHateSpeech.value, }, { title: _(msg`Doxxing`), - reason: tools.ozone.report.defs.reasonHarassmentDoxxing.value, + reason: ToolsOzoneReportDefs.reasonHarassmentDoxxing.value, }, { title: _(msg`Other harassing or hateful content`), - reason: tools.ozone.report.defs.reasonHarassmentOther.value, + reason: ToolsOzoneReportDefs.reasonHarassmentOther.value, }, ], }, @@ -129,32 +129,31 @@ export function useReportOptions() { options: [ { title: _(msg`Animal welfare`), - reason: tools.ozone.report.defs.reasonViolenceAnimal.value, + reason: ToolsOzoneReportDefs.reasonViolenceAnimal.value, }, { title: _(msg`Threats or incitement`), - reason: tools.ozone.report.defs.reasonViolenceThreats.value, + reason: ToolsOzoneReportDefs.reasonViolenceThreats.value, }, { title: _(msg`Graphic violent content`), - reason: tools.ozone.report.defs.reasonViolenceGraphicContent.value, + reason: ToolsOzoneReportDefs.reasonViolenceGraphicContent.value, }, { title: _(msg`Glorification of violence`), - reason: tools.ozone.report.defs.reasonViolenceGlorification.value, + reason: ToolsOzoneReportDefs.reasonViolenceGlorification.value, }, { title: _(msg`Extremist content`), - reason: - tools.ozone.report.defs.reasonViolenceExtremistContent.value, + reason: ToolsOzoneReportDefs.reasonViolenceExtremistContent.value, }, { title: _(msg`Human trafficking`), - reason: tools.ozone.report.defs.reasonViolenceTrafficking.value, + reason: ToolsOzoneReportDefs.reasonViolenceTrafficking.value, }, { title: _(msg`Other violent content`), - reason: tools.ozone.report.defs.reasonViolenceOther.value, + reason: ToolsOzoneReportDefs.reasonViolenceOther.value, }, ], }, @@ -165,23 +164,23 @@ export function useReportOptions() { options: [ { title: _(msg`Child Sexual Abuse Material (CSAM)`), - reason: tools.ozone.report.defs.reasonChildSafetyCSAM.value, + reason: ToolsOzoneReportDefs.reasonChildSafetyCSAM.value, }, { title: _(msg`Grooming or predatory behavior`), - reason: tools.ozone.report.defs.reasonChildSafetyGroom.value, + reason: ToolsOzoneReportDefs.reasonChildSafetyGroom.value, }, { title: _(msg`Privacy violation of a minor`), - reason: tools.ozone.report.defs.reasonChildSafetyPrivacy.value, + reason: ToolsOzoneReportDefs.reasonChildSafetyPrivacy.value, }, { title: _(msg`Minor harassment or bullying`), - reason: tools.ozone.report.defs.reasonChildSafetyHarassment.value, + reason: ToolsOzoneReportDefs.reasonChildSafetyHarassment.value, }, { title: _(msg`Other child safety issue`), - reason: tools.ozone.report.defs.reasonChildSafetyOther.value, + reason: ToolsOzoneReportDefs.reasonChildSafetyOther.value, }, ], }, @@ -192,23 +191,23 @@ export function useReportOptions() { options: [ { title: _(msg`Content promoting or depicting self-harm`), - reason: tools.ozone.report.defs.reasonSelfHarmContent.value, + reason: ToolsOzoneReportDefs.reasonSelfHarmContent.value, }, { title: _(msg`Eating disorders`), - reason: tools.ozone.report.defs.reasonSelfHarmED.value, + reason: ToolsOzoneReportDefs.reasonSelfHarmED.value, }, { title: _(msg`Dangerous challenges or activities`), - reason: tools.ozone.report.defs.reasonSelfHarmStunts.value, + reason: ToolsOzoneReportDefs.reasonSelfHarmStunts.value, }, { title: _(msg`Dangerous substances or drug abuse`), - reason: tools.ozone.report.defs.reasonSelfHarmSubstances.value, + reason: ToolsOzoneReportDefs.reasonSelfHarmSubstances.value, }, { title: _(msg`Other dangerous content`), - reason: tools.ozone.report.defs.reasonSelfHarmOther.value, + reason: ToolsOzoneReportDefs.reasonSelfHarmOther.value, }, ], }, @@ -219,19 +218,19 @@ export function useReportOptions() { options: [ { title: _(msg`Hacking or system attacks`), - reason: tools.ozone.report.defs.reasonRuleSiteSecurity.value, + reason: ToolsOzoneReportDefs.reasonRuleSiteSecurity.value, }, { title: _(msg`Promoting or selling prohibited items or services`), - reason: tools.ozone.report.defs.reasonRuleProhibitedSales.value, + reason: ToolsOzoneReportDefs.reasonRuleProhibitedSales.value, }, { title: _(msg`Banned user returning`), - reason: tools.ozone.report.defs.reasonRuleBanEvasion.value, + reason: ToolsOzoneReportDefs.reasonRuleBanEvasion.value, }, { title: _(msg`Other network rule-breaking`), - reason: tools.ozone.report.defs.reasonRuleOther.value, + reason: ToolsOzoneReportDefs.reasonRuleOther.value, }, ], }, @@ -242,7 +241,7 @@ export function useReportOptions() { options: [ { title: _(msg`Other`), - reason: tools.ozone.report.defs.reasonOther.value, + reason: ToolsOzoneReportDefs.reasonOther.value, }, ], }, diff --git a/src/features/liveNow/components/GoLiveDisabledDialog.tsx b/src/features/liveNow/components/GoLiveDisabledDialog.tsx index 3de918d0bd..5e18c3d464 100644 --- a/src/features/liveNow/components/GoLiveDisabledDialog.tsx +++ b/src/features/liveNow/components/GoLiveDisabledDialog.tsx @@ -14,7 +14,9 @@ import * as Dialog from '#/components/Dialog' import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' -import {type app, com, tools} from '#/lexicons' +import {type app} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export function GoLiveDisabledDialog({ control, @@ -57,9 +59,9 @@ export function DialogInner({ }) } else { await client.call( - com.atproto.moderation.createReport, + ComAtprotoModerationCreateReport, { - reasonType: tools.ozone.report.defs.reasonAppeal.value, + reasonType: ToolsOzoneReportDefs.reasonAppeal.value, subject: { $type: 'com.atproto.repo.strongRef', // a status view's uri is an at-uri produced by the appview diff --git a/src/features/liveNow/index.tsx b/src/features/liveNow/index.tsx index 0959b068bd..0982726d7d 100644 --- a/src/features/liveNow/index.tsx +++ b/src/features/liveNow/index.tsx @@ -24,7 +24,11 @@ import {useDialogContext} from '#/components/Dialog' import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils' -import {app, com} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorStatus from '#/lexicons/app/bsky/actor/status' +import * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' +import * as ComAtprotoRepoGetRecord from '#/lexicons/com/atproto/repo/getRecord' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import * as bsky from '#/types/bsky' export * from '#/features/liveNow/utils' @@ -43,7 +47,7 @@ const DEFAULT_STATE = { isDisabled: false, isActive: false, record: {}, -} satisfies app.bsky.actor.defs.StatusView +} satisfies AppBskyActorDefs.StatusView export type LiveNowConfig = { canGoLive: boolean @@ -130,10 +134,10 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) { isDisabled: false, isActive: true, status: 'app.bsky.actor.status#live', - embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this + embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this record: shadowed.status.record, - } satisfies app.bsky.actor.defs.StatusView + } satisfies AppBskyActorDefs.StatusView } return { uri: shadowed.status.uri, @@ -141,10 +145,10 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) { isDisabled, isActive: false, status: 'app.bsky.actor.status#live', - embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this + embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this record: shadowed.status.record, - } satisfies app.bsky.actor.defs.StatusView + } satisfies AppBskyActorDefs.StatusView } else { return DEFAULT_STATE } @@ -164,14 +168,14 @@ export function isStatusStillActive(timeStr: string | undefined) { * validate if the status is valid for the acting user e.g. as they go live. */ export function isStatusValidForViewers( - status: app.bsky.actor.defs.StatusView, + status: AppBskyActorDefs.StatusView, config: LiveNowConfig, ) { if (status.status !== 'app.bsky.actor.status#live') return false if (!status.uri) return false // should not happen, just backwards compat try { const {host: liveDid} = new AtUri(status.uri) - if (bsky.isType(app.bsky.embed.external.view, status.embed)) { + if (bsky.isType(AppBskyEmbedExternal.view, status.embed)) { const host = getLiveNowHost(status.embed.external.uri) const exception = config.allowedHostsExceptionsByDid.get(liveDid) const isValidException = exception ? exception.has(host) : false @@ -227,7 +231,7 @@ export function useUpsertLiveStatusMutation( mutationFn: async () => { if (!currentAccount) throw new Error('Not logged in') - let embed: $Typed | undefined + let embed: $Typed | undefined if (linkMeta) { let thumb: l.BlobRef | undefined @@ -273,14 +277,14 @@ export function useUpsertLiveStatusMutation( status: 'app.bsky.actor.status#live', durationMinutes: duration, embed, - } satisfies app.bsky.actor.status.Main + } satisfies AppBskyActorStatus.Main const upsert = async () => { const repo = currentAccount.did const collection = 'app.bsky.actor.status' const existing = await pdsClient - .call(com.atproto.repo.getRecord, {repo, collection, rkey: 'self'}) + .call(ComAtprotoRepoGetRecord, {repo, collection, rkey: 'self'}) .catch(_e => undefined) /* @@ -288,7 +292,7 @@ export function useUpsertLiveStatusMutation( * `swapRecord` be null (meaning "must not already exist"), while the * record-helper option type is `string | undefined`. */ - await pdsClient.call(com.atproto.repo.putRecord, { + await pdsClient.call(ComAtprotoRepoPutRecord, { repo, collection, rkey: 'self', @@ -300,7 +304,7 @@ export function useUpsertLiveStatusMutation( await retry(upsert, { maxRetries: 5, retryable: e => - matchXrpcError(e, com.atproto.repo.putRecord) === 'InvalidSwap', + matchXrpcError(e, ComAtprotoRepoPutRecord) === 'InvalidSwap', }) return { @@ -367,7 +371,7 @@ export function useRemoveLiveStatusMutation() { mutationFn: async () => { if (!currentAccount) throw new Error('Not logged in') - await pdsClient.delete(app.bsky.actor.status, { + await pdsClient.delete(AppBskyActorStatus, { repo: currentAccount.did, rkey: 'self', }) diff --git a/src/features/liveNow/utils.ts b/src/features/liveNow/utils.ts index a4fb0bbf62..4700ac152f 100644 --- a/src/features/liveNow/utils.ts +++ b/src/features/liveNow/utils.ts @@ -2,7 +2,8 @@ import {type I18n} from '@lingui/core' import {plural} from '@lingui/core/macro' import psl from 'psl' -import {app} from '#/lexicons' +import * as AppBskyActorStatus from '#/lexicons/app/bsky/actor/status' +import * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' import * as bsky from '#/types/bsky' /** @@ -11,8 +12,8 @@ import * as bsky from '#/types/bsky' */ export function getValidLiveStatusRecord( statusRecord: unknown, -): app.bsky.actor.status.Main | null { - if (!bsky.matches(app.bsky.actor.status, statusRecord)) return null +): AppBskyActorStatus.Main | null { + if (!bsky.matches(AppBskyActorStatus, statusRecord)) return null return statusRecord } @@ -23,7 +24,7 @@ export function getValidLiveStatusRecord( export function getLiveLinkFromStatusRecord(statusRecord: unknown): string { const record = getValidLiveStatusRecord(statusRecord) if (!record) return '' - if (!bsky.isType(app.bsky.embed.external.main, record.embed)) return '' + if (!bsky.isType(AppBskyEmbedExternal.main, record.embed)) return '' return record.embed.external.uri } diff --git a/src/lib/__tests__/xrpc-error.test.ts b/src/lib/__tests__/xrpc-error.test.ts index 5c09fb4f08..a0c75884c2 100644 --- a/src/lib/__tests__/xrpc-error.test.ts +++ b/src/lib/__tests__/xrpc-error.test.ts @@ -7,11 +7,12 @@ import { } from '@atproto/lex' import {describe, expect, it} from '@jest/globals' -import {app, com} from '#/lexicons' +import * as AppBskyUnspeccedGetTrends from '#/lexicons/app/bsky/unspecced/getTrends' +import * as ComAtprotoServerCreateAccount from '#/lexicons/com/atproto/server/createAccount' import {matchXrpcError} from '../xrpc-error' -const createAccount = com.atproto.server.createAccount -const getTrends = app.bsky.unspecced.getTrends +const createAccount = ComAtprotoServerCreateAccount +const getTrends = AppBskyUnspeccedGetTrends /** * An `XrpcResponseError` as a lex `Client` would construct it: the method diff --git a/src/lib/api/feed-manip.ts b/src/lib/api/feed-manip.ts index cd99fc9d57..7dca55b976 100644 --- a/src/lib/api/feed-manip.ts +++ b/src/lib/api/feed-manip.ts @@ -1,10 +1,14 @@ -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import {isPostInLanguage} from '../../locale/helpers' import {FALLBACK_MARKER_POST} from './feed/home' import {type ReasonFeedSource} from './feed/types' -type FeedViewPost = app.bsky.feed.defs.FeedViewPost +type FeedViewPost = AppBskyFeedDefs.FeedViewPost export type FeedTunerFn = ( tuner: FeedTuner, @@ -13,18 +17,18 @@ export type FeedTunerFn = ( ) => FeedViewPostsSlice[] type FeedSliceItem = { - post: app.bsky.feed.defs.PostView - record: app.bsky.feed.post.Main - parentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined + post: AppBskyFeedDefs.PostView + record: AppBskyFeedPost.Main + parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined isParentBlocked: boolean isParentNotFound: boolean } type AuthorContext = { - author: app.bsky.actor.defs.ProfileViewBasic - parentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined - grandparentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined - rootAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined + author: AppBskyActorDefs.ProfileViewBasic + parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined + grandparentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined + rootAuthor: AppBskyActorDefs.ProfileViewBasic | undefined } export class FeedViewPostsSlice { @@ -46,7 +50,7 @@ export class FeedViewPostsSlice { this.isOrphan = false this.isThreadMuted = post.viewer?.threadMuted ?? false this.feedPostUri = post.uri - if (bsky.isType(app.bsky.feed.defs.postView, reply?.root)) { + if (bsky.isType(AppBskyFeedDefs.postView, reply?.root)) { this.rootUri = reply.root.uri } else { this.rootUri = post.uri @@ -62,19 +66,16 @@ export class FeedViewPostsSlice { return } if ( - !bsky.isType(app.bsky.feed.post, post.record) || - !bsky.matches(app.bsky.feed.post, post.record) + !bsky.isType(AppBskyFeedPost, post.record) || + !bsky.matches(AppBskyFeedPost, post.record) ) { return } const parent = reply?.parent - const isParentBlocked = bsky.isType(app.bsky.feed.defs.blockedPost, parent) - const isParentNotFound = bsky.isType( - app.bsky.feed.defs.notFoundPost, - parent, - ) - let parentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined - if (bsky.isType(app.bsky.feed.defs.postView, parent)) { + const isParentBlocked = bsky.isType(AppBskyFeedDefs.blockedPost, parent) + const isParentNotFound = bsky.isType(AppBskyFeedDefs.notFoundPost, parent) + let parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined + if (bsky.isType(AppBskyFeedDefs.postView, parent)) { parentAuthor = parent.author } this.items.push({ @@ -96,18 +97,18 @@ export class FeedViewPostsSlice { return } if ( - !bsky.isType(app.bsky.feed.defs.postView, parent) || - !bsky.isType(app.bsky.feed.post, parent.record) || - !bsky.matches(app.bsky.feed.post, parent.record) + !bsky.isType(AppBskyFeedDefs.postView, parent) || + !bsky.isType(AppBskyFeedPost, parent.record) || + !bsky.matches(AppBskyFeedPost, parent.record) ) { this.isOrphan = true return } const root = reply.root const rootIsView = - bsky.isType(app.bsky.feed.defs.postView, root) || - bsky.isType(app.bsky.feed.defs.blockedPost, root) || - bsky.isType(app.bsky.feed.defs.notFoundPost, root) + bsky.isType(AppBskyFeedDefs.postView, root) || + bsky.isType(AppBskyFeedDefs.blockedPost, root) || + bsky.isType(AppBskyFeedDefs.notFoundPost, root) /* * If the parent is also the root, we just so happen to have the data we * need to compute if the parent's parent (grandparent) is blocked. This @@ -120,10 +121,10 @@ export class FeedViewPostsSlice { : undefined const grandparentAuthor = reply.grandparentAuthor const isGrandparentBlocked = Boolean( - grandparent && bsky.isType(app.bsky.feed.defs.blockedPost, grandparent), + grandparent && bsky.isType(AppBskyFeedDefs.blockedPost, grandparent), ) const isGrandparentNotFound = Boolean( - grandparent && bsky.isType(app.bsky.feed.defs.notFoundPost, grandparent), + grandparent && bsky.isType(AppBskyFeedDefs.notFoundPost, grandparent), ) this.items.unshift({ post: parent, @@ -138,9 +139,9 @@ export class FeedViewPostsSlice { // de-deduping } if ( - !bsky.isType(app.bsky.feed.defs.postView, root) || - !bsky.isType(app.bsky.feed.post, root.record) || - !bsky.matches(app.bsky.feed.post, root.record) + !bsky.isType(AppBskyFeedDefs.postView, root) || + !bsky.isType(AppBskyFeedPost, root.record) || + !bsky.matches(AppBskyFeedPost, root.record) ) { this.isOrphan = true return @@ -163,14 +164,14 @@ export class FeedViewPostsSlice { get isQuotePost() { const embed = this._feedPost.post.embed return ( - bsky.isType(app.bsky.embed.record.view, embed) || - bsky.isType(app.bsky.embed.recordWithMedia.view, embed) + bsky.isType(AppBskyEmbedRecord.view, embed) || + bsky.isType(AppBskyEmbedRecordWithMedia.view, embed) ) } get isReply() { return ( - bsky.isType(app.bsky.feed.post, this._feedPost.post.record) && + bsky.isType(AppBskyFeedPost, this._feedPost.post.record) && !!this._feedPost.post.record.reply ) } @@ -191,7 +192,7 @@ export class FeedViewPostsSlice { get isRepost() { const reason = this._feedPost.reason - return bsky.isType(app.bsky.feed.defs.reasonRepost, reason) + return bsky.isType(AppBskyFeedDefs.reasonRepost, reason) } get likeCount() { @@ -204,18 +205,18 @@ export class FeedViewPostsSlice { getAuthors(): AuthorContext { const feedPost = this._feedPost - let author: app.bsky.actor.defs.ProfileViewBasic = feedPost.post.author - let parentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined - let grandparentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined - let rootAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined + let author: AppBskyActorDefs.ProfileViewBasic = feedPost.post.author + let parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined + let grandparentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined + let rootAuthor: AppBskyActorDefs.ProfileViewBasic | undefined if (feedPost.reply) { - if (bsky.isType(app.bsky.feed.defs.postView, feedPost.reply.parent)) { + if (bsky.isType(AppBskyFeedDefs.postView, feedPost.reply.parent)) { parentAuthor = feedPost.reply.parent.author } if (feedPost.reply.grandparentAuthor) { grandparentAuthor = feedPost.reply.grandparentAuthor } - if (bsky.isType(app.bsky.feed.defs.postView, feedPost.reply.root)) { + if (bsky.isType(AppBskyFeedDefs.postView, feedPost.reply.root)) { rootAuthor = feedPost.reply.root.author } } @@ -510,7 +511,7 @@ function shouldDisplayReplyInFollowing( } function isSelfOrFollowing( - profile: app.bsky.actor.defs.ProfileViewBasic, + profile: AppBskyActorDefs.ProfileViewBasic, userDid: string, ) { return Boolean(profile.did === userDid || profile.viewer?.following) diff --git a/src/lib/api/feed/author.ts b/src/lib/api/feed/author.ts index 76e6433f69..2e64fcda3c 100644 --- a/src/lib/api/feed/author.ts +++ b/src/lib/api/feed/author.ts @@ -1,11 +1,12 @@ import {type Client, type XrpcRequestParams} from '@atproto/lex' -import {app} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetAuthorFeed from '#/lexicons/app/bsky/feed/getAuthorFeed' import * as bsky from '#/types/bsky' import {type FeedAPI, type FeedAPIResponse} from './types' type GetAuthorFeedParams = XrpcRequestParams< - typeof app.bsky.feed.getAuthorFeed.main + typeof AppBskyFeedGetAuthorFeed.main > export class AuthorFeedAPI implements FeedAPI { @@ -29,8 +30,8 @@ export class AuthorFeedAPI implements FeedAPI { return params } - async peekLatest(): Promise { - const data = await this.client.call(app.bsky.feed.getAuthorFeed, { + async peekLatest(): Promise { + const data = await this.client.call(AppBskyFeedGetAuthorFeed, { ...this.params, limit: 1, }) @@ -50,7 +51,7 @@ export class AuthorFeedAPI implements FeedAPI { * The agent behaved the same way - its `success` flag was only ever true - * so the empty-page branch this replaces was unreachable. */ - const data = await this.client.call(app.bsky.feed.getAuthorFeed, { + const data = await this.client.call(AppBskyFeedGetAuthorFeed, { ...this.params, cursor, limit, @@ -61,15 +62,12 @@ export class AuthorFeedAPI implements FeedAPI { } } - _filter(feed: app.bsky.feed.defs.FeedViewPost[]) { + _filter(feed: AppBskyFeedDefs.FeedViewPost[]) { if (this.params.filter === 'posts_and_author_threads') { return feed.filter(post => { const isReply = post.reply - const isRepost = bsky.isType( - app.bsky.feed.defs.reasonRepost, - post.reason, - ) - const isPin = bsky.isType(app.bsky.feed.defs.reasonPin, post.reason) + const isRepost = bsky.isType(AppBskyFeedDefs.reasonRepost, post.reason) + const isPin = bsky.isType(AppBskyFeedDefs.reasonPin, post.reason) if (!isReply) return true if (isRepost || isPin) return true return isReply && isAuthorReplyChain(this.params.actor, post, feed) @@ -82,15 +80,15 @@ export class AuthorFeedAPI implements FeedAPI { function isAuthorReplyChain( actor: string, - post: app.bsky.feed.defs.FeedViewPost, - posts: app.bsky.feed.defs.FeedViewPost[], + post: AppBskyFeedDefs.FeedViewPost, + posts: AppBskyFeedDefs.FeedViewPost[], ): boolean { // current post is by a different user (shouldn't happen) if (post.post.author.did !== actor) return false const replyParent = post.reply?.parent - if (bsky.isType(app.bsky.feed.defs.postView, replyParent)) { + if (bsky.isType(AppBskyFeedDefs.postView, replyParent)) { // reply parent is by a different user if (replyParent.author.did !== actor) return false diff --git a/src/lib/api/feed/custom.ts b/src/lib/api/feed/custom.ts index f4a5d4862f..3c6330640b 100644 --- a/src/lib/api/feed/custom.ts +++ b/src/lib/api/feed/custom.ts @@ -10,11 +10,12 @@ import { getAppLanguageAsContentLanguage, getContentLanguages, } from '#/state/preferences/languages' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetFeed from '#/lexicons/app/bsky/feed/getFeed' import {type FeedAPI, type FeedAPIResponse} from './types' import {createBskyTopicsHeader, isBlueskyOwnedFeed} from './utils' -type GetCustomFeedParams = XrpcRequestParams +type GetCustomFeedParams = XrpcRequestParams export class CustomFeedAPI implements FeedAPI { client: Client @@ -35,10 +36,10 @@ export class CustomFeedAPI implements FeedAPI { this.userInterests = userInterests } - async peekLatest(): Promise { + async peekLatest(): Promise { const contentLangs = getContentLanguages().join(',') const data = await this.client.call( - app.bsky.feed.getFeed, + AppBskyFeedGetFeed, { ...this.params, limit: 1, @@ -66,7 +67,7 @@ export class CustomFeedAPI implements FeedAPI { */ const data = this.client.did ? await this.client.call( - app.bsky.feed.getFeed, + AppBskyFeedGetFeed, { ...this.params, cursor, @@ -144,7 +145,7 @@ function getLoggedOutAppviewClient(): Client { */ async function loggedOutFetch( params: GetCustomFeedParams, -): Promise { +): Promise { const contentLangs = getAppLanguageAsContentLanguage() let data = await getFeedOrNull(params, contentLangs) @@ -172,13 +173,11 @@ async function loggedOutFetch( async function getFeedOrNull( params: GetCustomFeedParams, contentLangs: string, -): Promise { +): Promise { try { - return await getLoggedOutAppviewClient().call( - app.bsky.feed.getFeed, - params, - {headers: {'Accept-Language': contentLangs}}, - ) + return await getLoggedOutAppviewClient().call(AppBskyFeedGetFeed, params, { + headers: {'Accept-Language': contentLangs}, + }) } catch (e) { if (e instanceof XrpcResponseError) { return null diff --git a/src/lib/api/feed/following.ts b/src/lib/api/feed/following.ts index 27a08c6985..9fcd6a1e25 100644 --- a/src/lib/api/feed/following.ts +++ b/src/lib/api/feed/following.ts @@ -1,6 +1,7 @@ import {type Client} from '@atproto/lex' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetTimeline from '#/lexicons/app/bsky/feed/getTimeline' import {type FeedAPI, type FeedAPIResponse} from './types' export class FollowingFeedAPI implements FeedAPI { @@ -10,8 +11,8 @@ export class FollowingFeedAPI implements FeedAPI { this.client = client } - async peekLatest(): Promise { - const data = await this.client.call(app.bsky.feed.getTimeline, { + async peekLatest(): Promise { + const data = await this.client.call(AppBskyFeedGetTimeline, { limit: 1, }) return data.feed[0] @@ -30,7 +31,7 @@ export class FollowingFeedAPI implements FeedAPI { * way - its `success` flag was only ever true - so the empty-page branch * this replaces was unreachable. */ - const data = await this.client.call(app.bsky.feed.getTimeline, { + const data = await this.client.call(AppBskyFeedGetTimeline, { cursor, limit, }) diff --git a/src/lib/api/feed/likes.ts b/src/lib/api/feed/likes.ts index d8bba416ac..2fe19689a0 100644 --- a/src/lib/api/feed/likes.ts +++ b/src/lib/api/feed/likes.ts @@ -1,10 +1,11 @@ import {type Client, type XrpcRequestParams} from '@atproto/lex' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetActorLikes from '#/lexicons/app/bsky/feed/getActorLikes' import {type FeedAPI, type FeedAPIResponse} from './types' type GetActorLikesParams = XrpcRequestParams< - typeof app.bsky.feed.getActorLikes.main + typeof AppBskyFeedGetActorLikes.main > export class LikesFeedAPI implements FeedAPI { @@ -22,8 +23,8 @@ export class LikesFeedAPI implements FeedAPI { this.params = feedParams } - async peekLatest(): Promise { - const data = await this.client.call(app.bsky.feed.getActorLikes, { + async peekLatest(): Promise { + const data = await this.client.call(AppBskyFeedGetActorLikes, { ...this.params, limit: 1, }) @@ -43,7 +44,7 @@ export class LikesFeedAPI implements FeedAPI { * way - its `success` flag was only ever true - so the empty-page branch * this replaces was unreachable. */ - const data = await this.client.call(app.bsky.feed.getActorLikes, { + const data = await this.client.call(AppBskyFeedGetActorLikes, { ...this.params, cursor, limit, diff --git a/src/lib/api/feed/list.ts b/src/lib/api/feed/list.ts index 51e67bb4e8..e632fa8d7a 100644 --- a/src/lib/api/feed/list.ts +++ b/src/lib/api/feed/list.ts @@ -1,11 +1,10 @@ import {type Client, type XrpcRequestParams} from '@atproto/lex' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetListFeed from '#/lexicons/app/bsky/feed/getListFeed' import {type FeedAPI, type FeedAPIResponse} from './types' -type GetListFeedParams = XrpcRequestParams< - typeof app.bsky.feed.getListFeed.main -> +type GetListFeedParams = XrpcRequestParams export class ListFeedAPI implements FeedAPI { client: Client @@ -22,8 +21,8 @@ export class ListFeedAPI implements FeedAPI { this.params = feedParams } - async peekLatest(): Promise { - const data = await this.client.call(app.bsky.feed.getListFeed, { + async peekLatest(): Promise { + const data = await this.client.call(AppBskyFeedGetListFeed, { ...this.params, limit: 1, }) @@ -43,7 +42,7 @@ export class ListFeedAPI implements FeedAPI { * way - its `success` flag was only ever true - so the empty-page branch * this replaces was unreachable. */ - const data = await this.client.call(app.bsky.feed.getListFeed, { + const data = await this.client.call(AppBskyFeedGetListFeed, { ...this.params, cursor, limit, diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts index 91d300afb8..03d493c47e 100644 --- a/src/lib/api/feed/merge.ts +++ b/src/lib/api/feed/merge.ts @@ -7,7 +7,9 @@ import {timeout} from '#/lib/async/timeout' import {feedUriToHref} from '#/lib/strings/url-helpers' import {getContentLanguages} from '#/state/preferences/languages' import {type FeedParams} from '#/state/queries/post-feed' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetFeed from '#/lexicons/app/bsky/feed/getFeed' +import * as AppBskyFeedGetTimeline from '#/lexicons/app/bsky/feed/getTimeline' import {FeedTuner} from '../feed-manip' import {type FeedTunerFn} from '../feed-manip' import { @@ -27,7 +29,7 @@ const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours */ type MergeFeedPage = { cursor?: string - feed: app.bsky.feed.defs.FeedViewPost[] + feed: AppBskyFeedDefs.FeedViewPost[] } | null export class MergeFeedAPI implements FeedAPI { @@ -88,8 +90,8 @@ export class MergeFeedAPI implements FeedAPI { } } - async peekLatest(): Promise { - const data = await this.client.call(app.bsky.feed.getTimeline, { + async peekLatest(): Promise { + const data = await this.client.call(AppBskyFeedGetTimeline, { limit: 1, }) return data.feed[0] @@ -135,7 +137,7 @@ export class MergeFeedAPI implements FeedAPI { await Promise.all(promises) // assemble a response by sampling from feeds with content - const posts: app.bsky.feed.defs.FeedViewPost[] = [] + const posts: AppBskyFeedDefs.FeedViewPost[] = [] while (posts.length < limit) { let slice = this.sampleItem() if (slice[0]) { @@ -187,7 +189,7 @@ class MergeFeedSource { feedTuners: FeedTunerFn[] sourceInfo: ReasonFeedSource | undefined cursor: string | undefined = undefined - queue: app.bsky.feed.defs.FeedViewPost[] = [] + queue: AppBskyFeedDefs.FeedViewPost[] = [] hasMore = true constructor({ @@ -209,7 +211,7 @@ class MergeFeedSource { return this.hasMore && this.queue.length === 0 } - take(n: number): app.bsky.feed.defs.FeedViewPost[] { + take(n: number): AppBskyFeedDefs.FeedViewPost[] { return this.queue.splice(0, n) } @@ -254,7 +256,7 @@ class MergeFeedSource_Following extends MergeFeedSource { cursor: string | undefined, limit: number, ): Promise { - const data = await this.client.call(app.bsky.feed.getTimeline, { + const data = await this.client.call(AppBskyFeedGetTimeline, { cursor, limit, }) @@ -307,7 +309,7 @@ class MergeFeedSource_Custom extends MergeFeedSource { const contentLangs = getContentLanguages().join(',') const isBlueskyOwned = isBlueskyOwnedFeed(this.feedUri) const data = await this.client.call( - app.bsky.feed.getFeed, + AppBskyFeedGetFeed, { cursor, limit, @@ -326,7 +328,7 @@ class MergeFeedSource_Custom extends MergeFeedSource { // some custom feeds fail to enforce the pagination limit // so we manually truncate here // -prf - let feed: app.bsky.feed.defs.FeedViewPost[] = + let feed: AppBskyFeedDefs.FeedViewPost[] = limit && data.feed.length > limit ? data.feed.slice(0, limit) : data.feed diff --git a/src/lib/api/feed/posts.ts b/src/lib/api/feed/posts.ts index 18835ecbd2..6b09687323 100644 --- a/src/lib/api/feed/posts.ts +++ b/src/lib/api/feed/posts.ts @@ -1,15 +1,16 @@ import {type Client, type XrpcRequestParams} from '@atproto/lex' import {logger} from '#/logger' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetPosts from '#/lexicons/app/bsky/feed/getPosts' import {type FeedAPI, type FeedAPIResponse} from './types' -type GetPostsParams = XrpcRequestParams +type GetPostsParams = XrpcRequestParams export class PostListFeedAPI implements FeedAPI { client: Client params: GetPostsParams - peek: app.bsky.feed.defs.FeedViewPost | null = null + peek: AppBskyFeedDefs.FeedViewPost | null = null constructor({ client, @@ -29,7 +30,7 @@ export class PostListFeedAPI implements FeedAPI { } } - async peekLatest(): Promise { + async peekLatest(): Promise { if (this.peek) return this.peek throw new Error('Has not fetched yet') } @@ -41,7 +42,7 @@ export class PostListFeedAPI implements FeedAPI { * way - its `success` flag was only ever true - so the empty-page branch * this replaces was unreachable. */ - const data = await this.client.call(app.bsky.feed.getPosts, { + const data = await this.client.call(AppBskyFeedGetPosts, { ...this.params, }) this.peek = {post: data.posts[0]} diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts index 55b0fdecb6..1d8f967960 100644 --- a/src/lib/api/index.ts +++ b/src/lib/api/index.ts @@ -28,7 +28,16 @@ import { type PostDraft, type ThreadDraft, } from '#/view/com/composer/state/composer' -import {app, chat, com} from '#/lexicons' +import type * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' +import type * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import type * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import type * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' +import * as AppBskyFeedGetPosts from '#/lexicons/app/bsky/feed/getPosts' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' +import type * as ComAtprotoLabelDefs from '#/lexicons/com/atproto/label/defs' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' +import type * as ComAtprotoRepoStrongRef from '#/lexicons/com/atproto/repo/strongRef' import * as bsky from '#/types/bsky' import {createGIFDescription} from '../gif-alt-text' import {computeCid} from './computeCid' @@ -65,8 +74,8 @@ export async function post(queryClient: QueryClient, opts: PostOpts) { opts.onStateChange?.(t`Processing...`) let replyPromise: - | Promise - | app.bsky.feed.post.Main['reply'] + | Promise + | AppBskyFeedPost.Main['reply'] | undefined if (opts.replyTo) { // Not awaited to avoid waterfalls. @@ -80,7 +89,7 @@ export async function post(queryClient: QueryClient, opts: PostOpts) { } const did = opts.pdsClient.assertDid - const writes: com.atproto.repo.applyWrites.$InputBody['writes'] = [] + const writes: ComAtprotoRepoApplyWrites.$InputBody['writes'] = [] const uris: string[] = [] let now = new Date() @@ -99,7 +108,7 @@ export async function post(queryClient: QueryClient, opts: PostOpts) { draft, opts.onStateChange, ) - let labels: $Typed | undefined + let labels: $Typed | undefined if (draft.labels.length) { labels = { $type: 'com.atproto.label.defs#selfLabels', @@ -118,7 +127,7 @@ export async function post(queryClient: QueryClient, opts: PostOpts) { const rt = await rtPromise const embed = await embedPromise const reply = await replyPromise - const record: app.bsky.feed.post.Main = { + const record: AppBskyFeedPost.Main = { // IMPORTANT: $type has to exist, CID is calculated with the `$type` field // present and will produce the wrong CID if you omit it. $type: 'app.bsky.feed.post', @@ -179,7 +188,7 @@ export async function post(queryClient: QueryClient, opts: PostOpts) { } try { - await opts.pdsClient.call(com.atproto.repo.applyWrites, { + await opts.pdsClient.call(ComAtprotoRepoApplyWrites, { repo: did, writes: writes, validate: true, @@ -222,7 +231,7 @@ export class ReplyDeletedError extends Error { } async function resolveReply(appviewClient: Client, replyTo: string) { - const data = await appviewClient.call(app.bsky.feed.getPosts, { + const data = await appviewClient.call(AppBskyFeedGetPosts, { uris: [replyTo as AtUriString], }) const parentPost = data.posts[0] @@ -234,9 +243,9 @@ async function resolveReply(appviewClient: Client, replyTo: string) { uri: parentPost.uri, cid: parentPost.cid, } - let rootRef: com.atproto.repo.strongRef.Main = parentRef + let rootRef: ComAtprotoRepoStrongRef.Main = parentRef - if (bsky.isType(app.bsky.feed.post, parentPost.record)) { + if (bsky.isType(AppBskyFeedPost, parentPost.record)) { if (parentPost.record.reply) { rootRef = parentPost.record.reply.root } @@ -255,7 +264,7 @@ async function resolveEmbed( queryClient: QueryClient, draft: PostDraft, onStateChange: ((state: string) => void) | undefined, -): Promise { +): Promise { if (draft.embed.quote) { const [resolvedMedia, resolvedQuote] = await Promise.all([ resolveMedia( @@ -322,10 +331,10 @@ async function resolveMedia( embedDraft: EmbedDraft, onStateChange: ((state: string) => void) | undefined, ): Promise< - | $Typed - | $Typed - | $Typed - | $Typed + | $Typed + | $Typed + | $Typed + | $Typed | undefined > { if (embedDraft.media?.type === 'images') { @@ -334,7 +343,7 @@ async function resolveMedia( count: imagesDraft.length, }) onStateChange?.(t`Uploading images...`) - const images: app.bsky.embed.images.Image[] = await Promise.all( + const images: AppBskyEmbedImages.Image[] = await Promise.all( imagesDraft.map(async (image, i) => { logger.debug(`Compressing image #${i}`) const {path, width, height, mime} = await compressImage( @@ -361,7 +370,7 @@ async function resolveMedia( count: imagesDraft.length, }) onStateChange?.(t`Uploading images...`) - const items: $Typed[] = await Promise.all( + const items: $Typed[] = await Promise.all( imagesDraft.map(async (image, i) => { logger.debug(`Compressing image #${i}`) const {path, width, height, mime} = await compressImage( @@ -431,7 +440,7 @@ async function resolveMedia( if (embedDraft.media?.type === 'gif') { const gifDraft = embedDraft.media const resolvedGif = await fetchResolveGifQuery(queryClient, gifDraft.gif) - let blob: app.bsky.embed.external.External['thumb'] + let blob: AppBskyEmbedExternal.External['thumb'] if (resolvedGif.thumb) { onStateChange?.(t`Uploading link thumbnail...`) const {path, mime} = resolvedGif.thumb.source @@ -455,7 +464,7 @@ async function resolveMedia( embedDraft.link.uri, ) if (resolvedLink.type === 'external') { - let blob: app.bsky.embed.external.External['thumb'] + let blob: AppBskyEmbedExternal.External['thumb'] if (resolvedLink.thumb) { onStateChange?.(t`Uploading link thumbnail...`) const {path, mime} = resolvedLink.thumb.source @@ -475,7 +484,7 @@ async function resolveMedia( } if ( resolvedLink.type === 'chat-invite' && - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, resolvedLink.view) + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, resolvedLink.view) ) { return { $type: 'app.bsky.embed.external', @@ -494,7 +503,7 @@ async function resolveRecord( clients: LinkResolvers, queryClient: QueryClient, uri: string, -): Promise { +): Promise { const resolvedLink = await fetchResolveLinkQuery(queryClient, clients, uri) if (resolvedLink.type !== 'record') { throw Error(t`Expected uri to resolve to a record`) diff --git a/src/lib/api/resolve.ts b/src/lib/api/resolve.ts index 4d9ec3e457..107913021e 100644 --- a/src/lib/api/resolve.ts +++ b/src/lib/api/resolve.ts @@ -24,7 +24,15 @@ import {type ComposerImage} from '#/state/gallery' import {createComposerImage} from '#/state/gallery' import {type ChatInvitePreview} from '#/state/queries/join-links' import {type Gif} from '#/features/gifPicker/types' -import {app, chat, com} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetFeedGenerator from '#/lexicons/app/bsky/feed/getFeedGenerator' +import * as AppBskyFeedGetPosts from '#/lexicons/app/bsky/feed/getPosts' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetList from '#/lexicons/app/bsky/graph/getList' +import * as AppBskyGraphGetStarterPack from '#/lexicons/app/bsky/graph/getStarterPack' +import * as ChatBskyGroupGetJoinLinkPreviews from '#/lexicons/chat/bsky/group/getJoinLinkPreviews' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' +import type * as ComAtprotoRepoStrongRef from '#/lexicons/com/atproto/repo/strongRef' import {createGIFDescription} from '../gif-alt-text' type ResolvedExternalLink = { @@ -43,30 +51,30 @@ type ResolvedExternalLink = { type ResolvedPostRecord = { type: 'record' - record: com.atproto.repo.strongRef.Main + record: ComAtprotoRepoStrongRef.Main kind: 'post' - view: app.bsky.feed.defs.PostView + view: AppBskyFeedDefs.PostView } type ResolvedFeedRecord = { type: 'record' - record: com.atproto.repo.strongRef.Main + record: ComAtprotoRepoStrongRef.Main kind: 'feed' - view: app.bsky.feed.defs.GeneratorView + view: AppBskyFeedDefs.GeneratorView } type ResolvedListRecord = { type: 'record' - record: com.atproto.repo.strongRef.Main + record: ComAtprotoRepoStrongRef.Main kind: 'list' - view: app.bsky.graph.defs.ListView + view: AppBskyGraphDefs.ListView } type ResolvedStarterPackRecord = { type: 'record' - record: com.atproto.repo.strongRef.Main + record: ComAtprotoRepoStrongRef.Main kind: 'starter-pack' - view: app.bsky.graph.defs.StarterPackView + view: AppBskyGraphDefs.StarterPackView } type ResolvedChatInvite = { @@ -133,7 +141,7 @@ export async function resolveLink( const [_0, handleOrDid, _1, rkey] = uri.split('/').filter(Boolean) const did = await fetchDid(handleOrDid) const feed = makeRecordUri(did, 'app.bsky.feed.generator', rkey) - const data = await appviewClient.call(app.bsky.feed.getFeedGenerator, { + const data = await appviewClient.call(AppBskyFeedGetFeedGenerator, { feed: feed, }) return { @@ -151,7 +159,7 @@ export async function resolveLink( const [_0, handleOrDid, _1, rkey] = uri.split('/').filter(Boolean) const did = await fetchDid(handleOrDid) const list = makeRecordUri(did, 'app.bsky.graph.list', rkey) - const data = await appviewClient.call(app.bsky.graph.getList, { + const data = await appviewClient.call(AppBskyGraphGetList, { list: list, }) return { @@ -166,7 +174,7 @@ export async function resolveLink( } const chatInviteCode = getChatInviteCodeFromUrl(uri) if (chatInviteCode) { - const data = await chatClient.call(chat.bsky.group.getJoinLinkPreviews, { + const data = await chatClient.call(ChatBskyGroupGetJoinLinkPreviews, { codes: [chatInviteCode], }) return { @@ -185,7 +193,7 @@ export async function resolveLink( } const did = await fetchDid(parsed.name) const starterPack = createStarterPackUri({did, rkey: parsed.rkey}) - const data = await appviewClient.call(app.bsky.graph.getStarterPack, { + const data = await appviewClient.call(AppBskyGraphGetStarterPack, { starterPack: starterPack as AtUriString, }) return { @@ -204,13 +212,12 @@ export async function resolveLink( async function getPost({uri}: {uri: string}) { const urip = new AtUri(uri) if (!urip.host.startsWith('did:')) { - const data = await appviewClient.call( - com.atproto.identity.resolveHandle, - {handle: urip.host as HandleString}, - ) + const data = await appviewClient.call(ComAtprotoIdentityResolveHandle, { + handle: urip.host as HandleString, + }) urip.host = data.did } - const data = await appviewClient.call(app.bsky.feed.getPosts, { + const data = await appviewClient.call(AppBskyFeedGetPosts, { uris: [urip.toString()], }) if (data.posts[0]) { @@ -223,10 +230,9 @@ export async function resolveLink( async function fetchDid(handleOrDid: string) { let identifier = handleOrDid if (!identifier.startsWith('did:')) { - const data = await appviewClient.call( - com.atproto.identity.resolveHandle, - {handle: identifier as HandleString}, - ) + const data = await appviewClient.call(ComAtprotoIdentityResolveHandle, { + handle: identifier as HandleString, + }) identifier = data.did } return identifier diff --git a/src/lib/generate-starterpack.ts b/src/lib/generate-starterpack.ts index a786fb47ad..227c55b8bb 100644 --- a/src/lib/generate-starterpack.ts +++ b/src/lib/generate-starterpack.ts @@ -9,7 +9,14 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' import {enforceLen} from '#/lib/strings/helpers' import {useAppviewClient, usePdsClient} from '#/state/session' -import {app, com} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as AppBskyActorSearchActors from '#/lexicons/app/bsky/actor/searchActors' +import * as AppBskyGraphGetStarterPack from '#/lexicons/app/bsky/graph/getStarterPack' +import * as AppBskyGraphList from '#/lexicons/app/bsky/graph/list' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' +import type * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' import type * as bsky from '#/types/bsky' export const createStarterPackList = async ({ @@ -21,13 +28,13 @@ export const createStarterPackList = async ({ }: { name: string description?: string - descriptionFacets?: app.bsky.richtext.facet.Main[] + descriptionFacets?: AppBskyRichtextFacet.Main[] profiles: bsky.profile.AnyProfileView[] client: Client }): Promise<{uri: string; cid: string}> => { if (profiles.length === 0) throw new Error('No profiles given') - const list = await client.create(app.bsky.graph.list, { + const list = await client.create(AppBskyGraphList, { name, description, descriptionFacets, @@ -36,7 +43,7 @@ export const createStarterPackList = async ({ purpose: 'app.bsky.graph.defs#referencelist', }) if (!list) throw new Error('List creation failed') - await client.call(com.atproto.repo.applyWrites, { + await client.call(ComAtprotoRepoApplyWrites, { repo: client.assertDid, writes: profiles.map(p => createListItem({did: p.did, listUri: list.uri})), }) @@ -57,18 +64,18 @@ export function useGenerateStarterPackMutation({ return useMutation<{uri: string; cid: string}, Error, void>({ mutationFn: async () => { - let profile: app.bsky.actor.defs.ProfileViewDetailed | undefined - let profiles: app.bsky.actor.defs.ProfileView[] | undefined + let profile: AppBskyActorDefs.ProfileViewDetailed | undefined + let profiles: AppBskyActorDefs.ProfileView[] | undefined await Promise.all([ (async () => { - profile = await appviewClient.call(app.bsky.actor.getProfile, { + profile = await appviewClient.call(AppBskyActorGetProfile, { actor: pdsClient.assertDid, }) })(), (async () => { profiles = ( - await appviewClient.call(app.bsky.actor.searchActors, { + await appviewClient.call(AppBskyActorSearchActors, { q: encodeURIComponent('*'), limit: 49, }) @@ -100,7 +107,7 @@ export function useGenerateStarterPackMutation({ client: pdsClient, }) - return await pdsClient.create(app.bsky.graph.starterpack, { + return await pdsClient.create(AppBskyGraphStarterpack, { name: starterPackName, // `create` returns a plain string uri list: list.uri as AtUriString, @@ -125,7 +132,7 @@ function createListItem({ }: { did: string listUri: string -}): com.atproto.repo.applyWrites.$InputBody['writes'][number] { +}): ComAtprotoRepoApplyWrites.$InputBody['writes'][number] { return { $type: 'com.atproto.repo.applyWrites#create', collection: 'app.bsky.graph.listitem', @@ -141,14 +148,14 @@ function createListItem({ async function whenAppViewReady( client: Client, uri: string, - fn: (res?: app.bsky.graph.getStarterPack.$OutputBody) => boolean, + fn: (res?: AppBskyGraphGetStarterPack.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - client.call(app.bsky.graph.getStarterPack, { + client.call(AppBskyGraphGetStarterPack, { starterPack: uri as AtUriString, }), ) diff --git a/src/lib/media/video/upload.shared.ts b/src/lib/media/video/upload.shared.ts index 9e8d99a185..981d99f226 100644 --- a/src/lib/media/video/upload.shared.ts +++ b/src/lib/media/video/upload.shared.ts @@ -6,7 +6,8 @@ import {msg} from '@lingui/core/macro' import {VIDEO_SERVICE_DID} from '#/lib/constants' import {UploadLimitError} from '#/lib/media/video/errors' import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers' -import {app, com} from '#/lexicons' +import * as AppBskyVideoGetUploadLimits from '#/lexicons/app/bsky/video/getUploadLimits' +import * as ComAtprotoServerGetServiceAuth from '#/lexicons/com/atproto/server/getServiceAuth' import {createVideoServiceClient} from './util' export async function getServiceAuthToken({ @@ -40,7 +41,7 @@ export async function getServiceAuthToken({ } resolvedAud = pdsAud } - const {token} = await client.call(com.atproto.server.getServiceAuth, { + const {token} = await client.call(ComAtprotoServerGetServiceAuth, { aud: resolvedAud as DidString, lxm, exp, @@ -56,7 +57,7 @@ export async function getVideoUploadLimits(client: Client, i18n: I18n) { }) const videoClient = createVideoServiceClient(token) const limits = await videoClient - .call(app.bsky.video.getUploadLimits) + .call(AppBskyVideoGetUploadLimits) .catch(err => { if (err instanceof Error) { throw new UploadLimitError(err.message) diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts index 5acc6ab06d..f6c1de0794 100644 --- a/src/lib/notifications/notifications.ts +++ b/src/lib/notifications/notifications.ts @@ -17,7 +17,8 @@ import BackgroundNotificationHandler from '#/../modules/expo-background-notifica import {useAgeAssurance} from '#/ageAssurance' import {useAnalytics} from '#/analytics' import {IS_DEV, IS_NATIVE} from '#/env' -import {app} from '#/lexicons' +import * as AppBskyNotificationRegisterPush from '#/lexicons/app/bsky/notification/registerPush' +import * as AppBskyNotificationUnregisterPush from '#/lexicons/app/bsky/notification/unregisterPush' /** * A resumed single-use account client paired with the account's service origin @@ -50,7 +51,7 @@ async function _registerPushToken({ } }) { try { - const payload: app.bsky.notification.registerPush.$InputBody = { + const payload: AppBskyNotificationRegisterPush.$InputBody = { serviceDid: currentAccount.service?.includes('staging') ? PUBLIC_STAGING_APPVIEW_DID : PUBLIC_APPVIEW_DID, @@ -62,7 +63,7 @@ async function _registerPushToken({ notyLogger.debug(`registerPushToken: registering`, {...payload}) - await client.call(app.bsky.notification.registerPush, payload, { + await client.call(AppBskyNotificationRegisterPush, payload, { service: NOTIF_SERVICE, }) @@ -348,7 +349,7 @@ export async function unregisterPushToken(clients: TemporaryPushClient[]) { if (token) { for (const {client, service, handle} of clients) { await client.call( - app.bsky.notification.unregisterPush, + AppBskyNotificationUnregisterPush, { serviceDid: service.includes('staging') ? PUBLIC_STAGING_APPVIEW_DID diff --git a/src/lib/strings/rich-text-helpers.ts b/src/lib/strings/rich-text-helpers.ts index 6d201b7664..01d5e54851 100644 --- a/src/lib/strings/rich-text-helpers.ts +++ b/src/lib/strings/rich-text-helpers.ts @@ -1,6 +1,6 @@ import {type RichText} from '@bsky/sdk/richtext' -import {app} from '#/lexicons' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' import {linkRequiresWarning} from './url-helpers' @@ -16,7 +16,7 @@ export function richTextToString(rt: RichText, loose: boolean): string { for (const segment of rt.segments()) { const link = segment.link - if (link && bsky.matches(app.bsky.richtext.facet.link, link)) { + if (link && bsky.matches(AppBskyRichtextFacet.link, link)) { const href = link.uri const text = segment.text diff --git a/src/lib/strings/rich-text-manip.ts b/src/lib/strings/rich-text-manip.ts index 067b2f8cd7..a91b1e8a74 100644 --- a/src/lib/strings/rich-text-manip.ts +++ b/src/lib/strings/rich-text-manip.ts @@ -1,6 +1,6 @@ import {type RichText, UnicodeString} from '@bsky/sdk/richtext' -import {app} from '#/lexicons' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' import {toShortUrl} from './url-helpers' @@ -13,7 +13,7 @@ export function shortenLinks(rt: RichText): RichText { if (rt.facets) { for (const facet of rt.facets) { const isLink = !!facet.features.find(f => - bsky.isType(app.bsky.richtext.facet.link, f), + bsky.isType(AppBskyRichtextFacet.link, f), ) if (!isLink) { continue @@ -45,7 +45,7 @@ export function stripInvalidMentions(rt: RichText): RichText { if (rt.facets) { rt.facets = rt.facets?.filter(facet => { const mention = facet.features.find(f => - bsky.isType(app.bsky.richtext.facet.mention, f), + bsky.isType(AppBskyRichtextFacet.mention, f), ) if (mention && !mention.did) { return false diff --git a/src/lib/xrpc-error.ts b/src/lib/xrpc-error.ts index ec4fd7e872..bf0c430d23 100644 --- a/src/lib/xrpc-error.ts +++ b/src/lib/xrpc-error.ts @@ -9,7 +9,7 @@ import { XrpcResponseError, } from '@atproto/lex' -import {com} from '#/lexicons' +import * as ComAtprotoRepoGetRecord from '#/lexicons/com/atproto/repo/getRecord' /** * True for an XRPC error from a lex `Client` (`XrpcError` is the abstract base @@ -104,7 +104,7 @@ export function matchXrpcError( * turn a previously-handled absence into a thrown error. */ export function isRecordNotFoundError(e: unknown): boolean { - if (matchXrpcError(e, com.atproto.repo.getRecord) === 'RecordNotFound') { + if (matchXrpcError(e, ComAtprotoRepoGetRecord) === 'RecordNotFound') { return true } return e instanceof Error && e.message.includes('Could not locate record:') diff --git a/src/locale/helpers.ts b/src/locale/helpers.ts index e91c540e83..1574549dec 100644 --- a/src/locale/helpers.ts +++ b/src/locale/helpers.ts @@ -2,7 +2,8 @@ import * as bcp47Match from 'bcp-47-match' import lande from 'lande' import {hasProp} from '#/lib/type-guards' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import { AppLanguage, @@ -62,8 +63,8 @@ function getLocalizedLanguage( } } -export function getPostLanguageTags(post: app.bsky.feed.defs.PostView) { - return bsky.isType(app.bsky.feed.post, post.record) && +export function getPostLanguageTags(post: AppBskyFeedDefs.PostView) { + return bsky.isType(AppBskyFeedPost, post.record) && hasProp(post.record, 'langs') && Array.isArray(post.record.langs) ? post.record.langs @@ -87,7 +88,7 @@ export function codeToLanguageName(lang2or3: string, appLang: string): string { } export function getPostLanguage( - post: app.bsky.feed.defs.PostView, + post: AppBskyFeedDefs.PostView, ): string | undefined { let candidates: string[] = getPostLanguageTags(post) let postText: string = '' @@ -122,7 +123,7 @@ export function getPostLanguage( } export function isPostInLanguage( - post: app.bsky.feed.defs.PostView, + post: AppBskyFeedDefs.PostView, targetLangs: string[], ): boolean { const lang = getPostLanguage(post) diff --git a/src/screens/Bookmarks.tsx b/src/screens/Bookmarks.tsx index c36cb0c0a5..ff19bc16bb 100644 --- a/src/screens/Bookmarks.tsx +++ b/src/screens/Bookmarks.tsx @@ -34,7 +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 type * as AppBskyBookmarkDefs from '#/lexicons/app/bsky/bookmark/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' type Props = NativeStackScreenProps @@ -76,15 +77,15 @@ type ListItem = | { type: 'bookmark' key: string - bookmark: Omit & { - item: $Typed + bookmark: Omit & { + item: $Typed } } | { type: 'bookmarkNotFound' key: string - bookmark: Omit & { - item: $Typed + bookmark: Omit & { + item: $Typed } } @@ -130,7 +131,7 @@ function BookmarksInner() { if (bookmarks.length > 0) { for (const bookmark of bookmarks) { - if (bsky.isType(app.bsky.feed.defs.notFoundPost, bookmark.item)) { + if (bsky.isType(AppBskyFeedDefs.notFoundPost, bookmark.item)) { i.push({ type: 'bookmarkNotFound', key: bookmark.item.uri, @@ -140,7 +141,7 @@ function BookmarksInner() { }, }) } - if (bsky.isType(app.bsky.feed.defs.postView, bookmark.item)) { + if (bsky.isType(AppBskyFeedDefs.postView, bookmark.item)) { i.push({ type: 'bookmark', key: bookmark.item.uri, @@ -197,7 +198,7 @@ function BookmarkNotFound({ post, }: { hideTopBorder: boolean - post: $Typed + post: $Typed }) { const t = useTheme() const {_} = useLingui() diff --git a/src/screens/CustomFeed/index.tsx b/src/screens/CustomFeed/index.tsx index 112ea1b5ff..13f2aa1588 100644 --- a/src/screens/CustomFeed/index.tsx +++ b/src/screens/CustomFeed/index.tsx @@ -38,7 +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 * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' 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 === app.bsky.feed.defs.contentModeVideo.value + feedInfo.contentMode === AppBskyFeedDefs.contentModeVideo.value const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode return IS_NATIVE && _isVideoFeed }, [feedInfo]) diff --git a/src/screens/Deactivated.tsx b/src/screens/Deactivated.tsx index 3be42add78..0d6f32da0e 100644 --- a/src/screens/Deactivated.tsx +++ b/src/screens/Deactivated.tsx @@ -26,7 +26,7 @@ import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {IS_WEB} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerActivateAccount from '#/lexicons/com/atproto/server/activateAccount' const COL_WIDTH = 400 @@ -72,7 +72,7 @@ export function Deactivated() { const handleActivate = useCallback(async () => { try { setPending(true) - await pdsClient.call(com.atproto.server.activateAccount) + await pdsClient.call(ComAtprotoServerActivateAccount) await queryClient.resetQueries() await refreshSession() } catch (e: any) { diff --git a/src/screens/List/ListHiddenScreen.tsx b/src/screens/List/ListHiddenScreen.tsx index f562ad1d96..bada5dc275 100644 --- a/src/screens/List/ListHiddenScreen.tsx +++ b/src/screens/List/ListHiddenScreen.tsx @@ -26,13 +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' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' export function ListHiddenScreen({ list, preferences, }: { - list: app.bsky.graph.defs.ListView + list: AppBskyGraphDefs.ListView preferences: UsePreferencesQueryResponse }) { const {_} = useLingui() @@ -43,7 +43,7 @@ export function ListHiddenScreen({ const goBack = useGoBack() const queryClient = useQueryClient() - const isModList = list.purpose === app.bsky.graph.defs.modlist.value + const isModList = list.purpose === AppBskyGraphDefs.modlist.value const [isProcessing, setIsProcessing] = useState(false) const listBlockMutation = useListBlockMutation() diff --git a/src/screens/Login/ForgotPasswordForm.tsx b/src/screens/Login/ForgotPasswordForm.tsx index 1e9eda430e..18812309a4 100644 --- a/src/screens/Login/ForgotPasswordForm.tsx +++ b/src/screens/Login/ForgotPasswordForm.tsx @@ -15,10 +15,11 @@ import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {IS_WEB} from '#/env' -import {com} from '#/lexicons' +import type * as ComAtprotoServerDescribeServer from '#/lexicons/com/atproto/server/describeServer' +import * as ComAtprotoServerRequestPasswordReset from '#/lexicons/com/atproto/server/requestPasswordReset' import {FormContainer} from './FormContainer' -type ServiceDescription = com.atproto.server.describeServer.$OutputBody +type ServiceDescription = ComAtprotoServerDescribeServer.$OutputBody export const ForgotPasswordForm = ({ error, @@ -60,7 +61,7 @@ export const ForgotPasswordForm = ({ * one-off service client rather than a session-scoped one. */ const client = createServiceClient(serviceUrl) - await client.call(com.atproto.server.requestPasswordReset, {email}) + await client.call(ComAtprotoServerRequestPasswordReset, {email}) onEmailSent() } catch (err) { logger.warn('Failed to request password reset', {error: err}) diff --git a/src/screens/Login/SetNewPasswordForm.tsx b/src/screens/Login/SetNewPasswordForm.tsx index f870171be8..3de5361ae6 100644 --- a/src/screens/Login/SetNewPasswordForm.tsx +++ b/src/screens/Login/SetNewPasswordForm.tsx @@ -16,7 +16,7 @@ import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerResetPassword from '#/lexicons/com/atproto/server/resetPassword' import {FormContainer} from './FormContainer' export const SetNewPasswordForm = ({ @@ -67,7 +67,7 @@ export const SetNewPasswordForm = ({ * one-off service client rather than a session-scoped one. */ const client = createServiceClient(serviceUrl) - await client.call(com.atproto.server.resetPassword, { + await client.call(ComAtprotoServerResetPassword, { token: formattedCode, password, }) diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx index 5666e2cdb1..380f76c9d0 100644 --- a/src/screens/Messages/Conversation.tsx +++ b/src/screens/Messages/Conversation.tsx @@ -45,7 +45,7 @@ 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 ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' import {ChatDisabled} from './components/ChatDisabled' import {ChatEnded} from './components/ChatEnded' @@ -181,7 +181,7 @@ function InnerReady({ const unreadRequestCount = convo?.kind === 'group' && - bsky.isType(chat.bsky.convo.defs.groupConvo, convo.view.kind) + bsky.isType(ChatBskyConvoDefs.groupConvo, convo.view.kind) ? (convo.view.kind.unreadJoinRequestCount ?? 0) : 0 const {mutate: markJoinRequestsRead} = useMarkJoinRequestsRead(convo?.view.id) diff --git a/src/screens/Messages/ConversationSettings/index.tsx b/src/screens/Messages/ConversationSettings/index.tsx index 2ddea16b4c..8051f21b3d 100644 --- a/src/screens/Messages/ConversationSettings/index.tsx +++ b/src/screens/Messages/ConversationSettings/index.tsx @@ -55,7 +55,9 @@ import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {chat} from '#/lexicons' +import * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoUnlockConvo from '#/lexicons/chat/bsky/convo/unlockConvo' import * as bsky from '#/types/bsky' import {InviteLinkDialog} from '../components/InviteLinkDialog' import {AddMembersLink} from './AddMembersLink' @@ -170,12 +172,12 @@ function keyExtractor(item: Item) { } function isGroupMember( - member: chat.bsky.actor.defs.ProfileViewBasic, + member: ChatBskyActorDefs.ProfileViewBasic, ): member is GroupConvoMember { // Kind is missing when the account has been deleted. return ( member.kind === undefined || - bsky.isType(chat.bsky.actor.defs.groupConvoMember, member.kind) + bsky.isType(ChatBskyActorDefs.groupConvoMember, member.kind) ) } @@ -409,7 +411,7 @@ function SettingsHeader({ isPending: isLocking, } = useLockConvo(convoId, { onSuccess: (data, {silent}) => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, data.convo.kind)) return + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, data.convo.kind)) return if (silent) return if (data.convo.kind.lockStatus === 'locked') { ax.metric('groupchat:owner:lock', {convoId}) @@ -424,7 +426,7 @@ function SettingsHeader({ logger.error('Failed to lock group chat', {message: e}) Toast.show(l`Failed to lock group chat`, {type: 'error'}) } else if ( - matchXrpcError(e, chat.bsky.convo.unlockConvo) === + matchXrpcError(e, ChatBskyConvoUnlockConvo) === 'ConvoLockedByModeration' ) { Toast.show(l`This chat is locked by a moderation action`, { diff --git a/src/screens/Messages/Inbox.tsx b/src/screens/Messages/Inbox.tsx index 30e06e3ab2..cec1a45f93 100644 --- a/src/screens/Messages/Inbox.tsx +++ b/src/screens/Messages/Inbox.tsx @@ -39,7 +39,9 @@ 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 ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import type * as ChatBskyConvoListConvoRequests from '#/lexicons/chat/bsky/convo/listConvoRequests' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import {IncomingRequestListItem} from './components/IncomingRequestListItem' import {OutgoingRequestListItem} from './components/OutgoingRequestListItem' @@ -48,8 +50,8 @@ import {useIsWithinSplitView} from './components/splitView/context' type Props = NativeStackScreenProps type RequestItem = - | {type: 'incoming'; view: chat.bsky.convo.defs.ConvoView} - | {type: 'outgoing'; view: chat.bsky.group.defs.JoinRequestConvoView} + | {type: 'incoming'; view: ChatBskyConvoDefs.ConvoView} + | {type: 'outgoing'; view: ChatBskyGroupDefs.JoinRequestConvoView} export function MessagesInboxScreen(props: Props) { const {t: l} = useLingui() @@ -72,11 +74,9 @@ export function MessagesInboxScreenInner({}: Props) { const items: RequestItem[] = [] for (const page of data.pages) { for (const item of page.requests) { - if (bsky.isType(chat.bsky.convo.defs.convoView, item)) { + if (bsky.isType(ChatBskyConvoDefs.convoView, item)) { items.push({type: 'incoming', view: item}) - } else if ( - bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item) - ) { + } else if (bsky.isType(ChatBskyGroupDefs.joinRequestConvoView, item)) { items.push({type: 'outgoing', view: item}) } } @@ -111,7 +111,7 @@ function RequestList({ conversations, }: { listConvosQuery: UseInfiniteQueryResult< - InfiniteData, + InfiniteData, Error > conversations: RequestItem[] diff --git a/src/screens/Messages/JoinRequest.tsx b/src/screens/Messages/JoinRequest.tsx index bd7a73dade..44d4bf3669 100644 --- a/src/screens/Messages/JoinRequest.tsx +++ b/src/screens/Messages/JoinRequest.tsx @@ -20,7 +20,7 @@ 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 ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' const desktopDarkBg = require('../../../assets/images/chat-desktop-bg-dark.webp') @@ -86,7 +86,7 @@ export function JoinRequest({setScreenState}: Props) { {error || (data && !bsky.isType( - chat.bsky.group.defs.joinLinkPreviewView, + ChatBskyGroupDefs.joinLinkPreviewView, joinLinkPreview, )) ? ( @@ -106,7 +106,7 @@ export function JoinRequest({setScreenState}: Props) { ) : data && moderationOpts && bsky.isType( - chat.bsky.group.defs.joinLinkPreviewView, + ChatBskyGroupDefs.joinLinkPreviewView, joinLinkPreview, ) ? ( diff --git a/src/screens/Messages/JoinRequests.tsx b/src/screens/Messages/JoinRequests.tsx index baf2d84f81..eaa4e6ceb2 100644 --- a/src/screens/Messages/JoinRequests.tsx +++ b/src/screens/Messages/JoinRequests.tsx @@ -39,7 +39,9 @@ import * as ProfileCard from '#/components/ProfileCard' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {chat} from '#/lexicons' +import * as ChatBskyGroupApproveJoinRequest from '#/lexicons/chat/bsky/group/approveJoinRequest' +import type * as ChatBskyGroupListJoinRequests from '#/lexicons/chat/bsky/group/listJoinRequests' +import * as ChatBskyGroupRejectJoinRequest from '#/lexicons/chat/bsky/group/rejectJoinRequest' import type * as bsky from '#/types/bsky' import {InviteLinkDialog} from './components/InviteLinkDialog' @@ -139,7 +141,7 @@ function JoinRequestsList({ const getRemainingRequestCount = () => { const data = queryClient.getQueryData< - InfiniteData + InfiniteData >(createListJoinRequestsQueryKey({convoId})) return data?.pages.reduce((sum, page) => sum + page.requests.length, 0) ?? 0 } @@ -188,7 +190,7 @@ function JoinRequestsList({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.group.approveJoinRequest)) { + switch (matchXrpcError(error, ChatBskyGroupApproveJoinRequest)) { case 'InvalidConvo': errorMessage = l`Conversation not found.` break @@ -220,7 +222,7 @@ function JoinRequestsList({ if (isNetworkError(error)) { errorMessage = l`A network error occurred. Please check your internet connection.` } else { - switch (matchXrpcError(error, chat.bsky.group.rejectJoinRequest)) { + switch (matchXrpcError(error, ChatBskyGroupRejectJoinRequest)) { case 'InvalidConvo': errorMessage = l`Conversation not found.` break diff --git a/src/screens/Messages/components/ChatDisabled.tsx b/src/screens/Messages/components/ChatDisabled.tsx index b330113d19..639eea4f99 100644 --- a/src/screens/Messages/components/ChatDisabled.tsx +++ b/src/screens/Messages/components/ChatDisabled.tsx @@ -13,7 +13,8 @@ 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, tools} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' export function ChatDisabled({ shape = 'pill', @@ -100,9 +101,9 @@ function DialogInner() { if (!currentAccount) throw new Error('No current account, should be unreachable') await client.call( - com.atproto.moderation.createReport, + ComAtprotoModerationCreateReport, { - reasonType: tools.ozone.report.defs.reasonAppeal.value, + reasonType: ToolsOzoneReportDefs.reasonAppeal.value, subject: { $type: 'com.atproto.admin.defs#repoRef', did: currentAccount.did, diff --git a/src/screens/Messages/components/ChatListItem.tsx b/src/screens/Messages/components/ChatListItem.tsx index f783abc7a0..5731a2a2b9 100644 --- a/src/screens/Messages/components/ChatListItem.tsx +++ b/src/screens/Messages/components/ChatListItem.tsx @@ -52,7 +52,7 @@ import {ProfileBadges} from '#/components/ProfileBadges' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' import {useIsWithinSplitView} from './splitView/context' @@ -64,7 +64,7 @@ export function ChatListItem({ selected = false, children, }: { - convo: chat.bsky.convo.defs.ConvoView + convo: ChatBskyConvoDefs.ConvoView showMenu?: boolean selected?: boolean children?: React.ReactNode @@ -315,10 +315,7 @@ function BaseChatItem({ // Deleted message if ( - bsky.isType( - chat.bsky.convo.defs.deletedMessageView, - convo.view.lastMessage, - ) + bsky.isType(ChatBskyConvoDefs.deletedMessageView, convo.view.lastMessage) ) { lastMessageSentAt = convo.view.lastMessage.sentAt @@ -328,7 +325,7 @@ function BaseChatItem({ } // Message - if (bsky.isType(chat.bsky.convo.defs.messageView, convo.view.lastMessage)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, convo.view.lastMessage)) { const info = getMessageInfo({ convo: convo.view, currentAccountDid: currentAccount?.did, @@ -346,7 +343,7 @@ function BaseChatItem({ // Reaction if ( bsky.isType( - chat.bsky.convo.defs.messageAndReactionView, + ChatBskyConvoDefs.messageAndReactionView, convo.view.lastReaction, ) ) { @@ -369,10 +366,7 @@ function BaseChatItem({ // System message if ( - bsky.isType( - chat.bsky.convo.defs.systemMessageView, - convo.view.lastMessage, - ) + bsky.isType(ChatBskyConvoDefs.systemMessageView, convo.view.lastMessage) ) { const info = getSystemMessageInfo( convo.view.lastMessage.data, diff --git a/src/screens/Messages/components/ChatLocked.tsx b/src/screens/Messages/components/ChatLocked.tsx index c9dcd93c3d..728177fee3 100644 --- a/src/screens/Messages/components/ChatLocked.tsx +++ b/src/screens/Messages/components/ChatLocked.tsx @@ -15,7 +15,7 @@ import {Lock_Stroke2_Corner0_Rounded as LockIcon} from '#/components/icons/Lock' import * as Prompt from '#/components/Prompt' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' -import {chat} from '#/lexicons' +import * as ChatBskyConvoUnlockConvo from '#/lexicons/chat/bsky/convo/unlockConvo' import {LeaveChatPrompt} from '../ConversationSettings/prompts' import {ChatFooter} from './ChatFooter' @@ -43,7 +43,7 @@ export function ChatLocked({ }, onError: e => { if ( - matchXrpcError(e, chat.bsky.convo.unlockConvo) === + matchXrpcError(e, ChatBskyConvoUnlockConvo) === 'ConvoLockedByModeration' ) { Toast.show(l`This chat is locked by a moderation action`, { diff --git a/src/screens/Messages/components/MessageInputEmbed.tsx b/src/screens/Messages/components/MessageInputEmbed.tsx index d5bcd4043c..bcb802a135 100644 --- a/src/screens/Messages/components/MessageInputEmbed.tsx +++ b/src/screens/Messages/components/MessageInputEmbed.tsx @@ -32,7 +32,8 @@ import {ContentHider} from '#/components/moderation/ContentHider' import {PostAlerts} from '#/components/moderation/PostAlerts' import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' /** @@ -102,7 +103,7 @@ export function useExtractEmbedFromFacets( for (const facet of rt.facets ?? []) { for (const feature of facet.features) { if ( - bsky.isType(app.bsky.richtext.facet.link, feature) && + bsky.isType(AppBskyRichtextFacet.link, feature) && (isBskyPostUrl(feature.uri) || isBskyChatInviteUrl(feature.uri)) ) { uriFromFacet = feature.uri @@ -162,7 +163,7 @@ function MessageInputPostEmbed({ ) const {rt, record} = useMemo(() => { - if (post && bsky.isType(app.bsky.feed.post, post.record)) { + if (post && bsky.isType(AppBskyFeedPost, post.record)) { return { rt: new RichTextAPI({ text: post.record.text, diff --git a/src/screens/Messages/components/MessagesList.tsx b/src/screens/Messages/components/MessagesList.tsx index 056ff2f76c..fdc405b78c 100644 --- a/src/screens/Messages/components/MessagesList.tsx +++ b/src/screens/Messages/components/MessagesList.tsx @@ -64,7 +64,11 @@ 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, chat} from '#/lexicons' +import type * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import type * as ChatBskyEmbedJoinLink from '#/lexicons/chat/bsky/embed/joinLink' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import {ChatStatusInfo} from './ChatStatusInfo' import {groupSystemMessages, type RenderItem} from './groupSystemMessages' @@ -111,8 +115,8 @@ function getNeighborMessage( neighbor.type === 'deleted-message' ) { if ( - bsky.isType(chat.bsky.convo.defs.messageView, neighbor.message) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, neighbor.message) + bsky.isType(ChatBskyConvoDefs.messageView, neighbor.message) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, neighbor.message) ) { return neighbor.message } @@ -519,7 +523,7 @@ export function MessagesList({ async ( text: string, embedState?: MessageEmbedState, - reply?: $Typed, + reply?: $Typed, ) => { let rt = new RichText({text: text.trimEnd()}, {cleanNewlines: true}) @@ -531,12 +535,12 @@ export function MessagesList({ */ rt.detectFacetsWithoutResolution() - let embed: chat.bsky.convo.defs.MessageInput['embed'] + let embed: ChatBskyConvoDefs.MessageInput['embed'] let embedView: - | $Typed - | $Typed + | $Typed + | $Typed | undefined - let replyTo: chat.bsky.convo.defs.ReplyRef | undefined + let replyTo: ChatBskyConvoDefs.ReplyRef | undefined /** * Find the embedded link facet and, if it's at the start or end of the @@ -546,7 +550,7 @@ export function MessagesList({ const linkFacet = rt.facets?.find(facet => facet.features.find( feature => - bsky.isType(app.bsky.richtext.facet.link, feature) && + bsky.isType(AppBskyRichtextFacet.link, feature) && predicate(feature.uri), ), ) @@ -656,7 +660,7 @@ export function MessagesList({ if ( embedView?.$type === 'chat.bsky.embed.joinLink#view' && bsky.isType( - chat.bsky.group.defs.joinLinkPreviewView, + ChatBskyGroupDefs.joinLinkPreviewView, embedView.joinLinkPreview, ) ) { @@ -896,7 +900,7 @@ function Composer({ onSendMessage: ( message: string, embed?: MessageEmbedState, - replyTo?: $Typed, + replyTo?: $Typed, ) => Promise messageEmbed: MessageEmbedState | undefined setEmbed: (embedUrl: string | undefined) => void @@ -906,7 +910,7 @@ function Composer({ ( message: string, embed?: MessageEmbedState, - replyTo?: $Typed, + replyTo?: $Typed, ) => { void onSendMessage(message, embed, replyTo) }, diff --git a/src/screens/Messages/components/OutgoingRequestListItem.tsx b/src/screens/Messages/components/OutgoingRequestListItem.tsx index 9aa08fd0cf..546f5844f2 100644 --- a/src/screens/Messages/components/OutgoingRequestListItem.tsx +++ b/src/screens/Messages/components/OutgoingRequestListItem.tsx @@ -11,12 +11,13 @@ import {createStaticClick, Link} from '#/components/Link' import * as Prompt from '#/components/Prompt' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' -import {chat} from '#/lexicons' +import type * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' +import * as ChatBskyGroupWithdrawJoinRequest from '#/lexicons/chat/bsky/group/withdrawJoinRequest' export function OutgoingRequestListItem({ convo: convoView, }: { - convo: chat.bsky.group.defs.JoinRequestConvoView + convo: ChatBskyGroupDefs.JoinRequestConvoView }) { const t = useTheme() const {t: l} = useLingui() @@ -33,7 +34,7 @@ export function OutgoingRequestListItem({ if (isNetworkError(error)) { errorMessage = l`There was a problem with your internet connection, please try again` } else if ( - matchXrpcError(error, chat.bsky.group.withdrawJoinRequest) === + matchXrpcError(error, ChatBskyGroupWithdrawJoinRequest) === 'InvalidJoinRequest' ) { errorMessage = l`Invalid rescind request.` diff --git a/src/screens/Onboarding/StepFinished/index.tsx b/src/screens/Onboarding/StepFinished/index.tsx index f90e7ddcd4..0c35176235 100644 --- a/src/screens/Onboarding/StepFinished/index.tsx +++ b/src/screens/Onboarding/StepFinished/index.tsx @@ -44,7 +44,11 @@ import {ArrowRight_Stroke2_Corner0_Rounded as ArrowRight} from '#/components/ico import {Loader} from '#/components/Loader' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyActorProfile from '#/lexicons/app/bsky/actor/profile' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetStarterPack from '#/lexicons/app/bsky/graph/getStarterPack' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' import {ValuePropositionPager} from './ValuePropositionPager' @@ -65,12 +69,12 @@ export function StepFinished() { const finishOnboarding = useCallback(async () => { setSaving(true) - let starterPack: app.bsky.graph.defs.StarterPackView | undefined - let listItems: app.bsky.graph.defs.ListItemView[] | undefined + let starterPack: AppBskyGraphDefs.StarterPackView | undefined + let listItems: AppBskyGraphDefs.ListItemView[] | undefined if (activeStarterPack?.uri) { try { - const spRes = await appviewClient.call(app.bsky.graph.getStarterPack, { + const spRes = await appviewClient.call(AppBskyGraphGetStarterPack, { starterPack: activeStarterPack.uri as AtUriString, }) starterPack = spRes.starterPack @@ -111,7 +115,7 @@ export function StepFinished() { await pdsClient.call(setInterestsPref, {tags: selectedInterests}) // Default feeds that every user should have pinned when landing in the app - const feedsToSave: app.bsky.actor.defs.SavedFeed[] = [ + const feedsToSave: AppBskyActorDefs.SavedFeed[] = [ { ...DISCOVER_SAVED_FEED, id: TID.nextStr(), @@ -148,7 +152,7 @@ export function StepFinished() { : undefined await pdsClient.call(upsertProfile, async existing => { - let next: Un$Typed = existing ?? {} + let next: Un$Typed = existing ?? {} if (blobPromise) { const res = await blobPromise @@ -210,8 +214,7 @@ export function StepFinished() { ax.metric('onboarding:finished:nextPressed', { usedStarterPack: Boolean(starterPack), starterPackName: - starterPack && - bsky.isType(app.bsky.graph.starterpack, starterPack.record) + starterPack && bsky.isType(AppBskyGraphStarterpack, starterPack.record) ? starterPack.record.name : undefined, starterPackCreator: starterPack?.creator.did, diff --git a/src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx b/src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx index ecbc7a9c4d..ac51a82951 100644 --- a/src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx +++ b/src/screens/Onboarding/StepSuggestedStarterpacks/StarterPackCard.tsx @@ -20,7 +20,8 @@ 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 type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp' @@ -28,7 +29,7 @@ const IGNORED_ACCOUNT = 'did:plc:pifkcjimdcfwaxkanzhwxufp' export function StarterPackCard({ view, }: { - view: app.bsky.graph.defs.StarterPackView + view: AppBskyGraphDefs.StarterPackView }) { const t = useTheme() const {_} = useLingui() @@ -47,7 +48,7 @@ export function StarterPackCard({ setIsProcessing(true) - let listItems: app.bsky.graph.defs.ListItemView[] = [] + let listItems: AppBskyGraphDefs.ListItemView[] = [] try { listItems = await getAllListMembers(appviewClient, view.list.uri) } catch (e) { @@ -103,7 +104,7 @@ export function StarterPackCard({ }) } - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } diff --git a/src/screens/Onboarding/util.ts b/src/screens/Onboarding/util.ts index 07ccc2f17a..3f4245e4e5 100644 --- a/src/screens/Onboarding/util.ts +++ b/src/screens/Onboarding/util.ts @@ -8,17 +8,20 @@ import { import chunk from 'lodash.chunk' import {until} from '#/lib/async/until' -import {app, com} from '#/lexicons' +import type * as AppBskyGraphFollow from '#/lexicons/app/bsky/graph/follow' +import * as AppBskyGraphGetFollows from '#/lexicons/app/bsky/graph/getFollows' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' +import type * as ComAtprotoRepoStrongRef from '#/lexicons/com/atproto/repo/strongRef' export async function bulkWriteFollows( pdsClient: Client, appviewClient: Client, dids: string[], - via?: com.atproto.repo.strongRef.Main, + via?: ComAtprotoRepoStrongRef.Main, ) { const did = pdsClient.assertDid - const followRecords: $Typed[] = dids.map(did => { + const followRecords: $Typed[] = dids.map(did => { return { $type: 'app.bsky.graph.follow', // the helper takes the dids as plain strings @@ -28,7 +31,7 @@ export async function bulkWriteFollows( } }) - const followWrites: $Typed[] = + const followWrites: $Typed[] = followRecords.map(r => ({ $type: 'com.atproto.repo.applyWrites#create', collection: 'app.bsky.graph.follow', @@ -38,7 +41,7 @@ export async function bulkWriteFollows( const chunks = chunk(followWrites, 50) for (const chunk of chunks) { - await pdsClient.call(com.atproto.repo.applyWrites, { + await pdsClient.call(ComAtprotoRepoApplyWrites, { repo: did, writes: chunk, }) @@ -58,14 +61,14 @@ export async function bulkWriteFollows( async function whenFollowsIndexed( appviewClient: Client, actor: string, - fn: (res: app.bsky.graph.getFollows.$OutputBody) => boolean, + fn: (res: AppBskyGraphGetFollows.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - appviewClient.call(app.bsky.graph.getFollows, { + appviewClient.call(AppBskyGraphGetFollows, { actor: actor as AtIdentifierString, limit: 1, }), diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx index 6a1ee4bb55..1b814f04ff 100644 --- a/src/screens/PostThread/components/ThreadItemAnchor.tsx +++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx @@ -59,7 +59,9 @@ 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 AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import type * as AppBskyFeedThreadgate from '#/lexicons/app/bsky/feed/threadgate' import * as bsky from '#/types/bsky' export function ThreadItemAnchor({ @@ -70,7 +72,7 @@ export function ThreadItemAnchor({ }: { item: Extract onPostSuccess?: (data: OnPostSuccessData) => void - threadgateRecord?: app.bsky.feed.threadgate.Main + threadgateRecord?: AppBskyFeedThreadgate.Main postSource?: PostSource }) { const postShadow = usePostShadow(item.value.post) @@ -171,9 +173,9 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({ }: { item: Extract isRoot: boolean - postShadow: Shadow + postShadow: Shadow onPostSuccess?: (data: OnPostSuccessData) => void - threadgateRecord?: app.bsky.feed.threadgate.Main + threadgateRecord?: AppBskyFeedThreadgate.Main postSource?: PostSource }) { const t = useTheme() @@ -240,7 +242,7 @@ const ThreadItemAnchorInner = memo(function ThreadItemAnchorInner({ const reason = postSource?.post.reason if ( - bsky.isType(app.bsky.feed.defs.reasonRepost, reason) && + bsky.isType(AppBskyFeedDefs.reasonRepost, reason) && reason.uri && reason.cid ) { @@ -573,13 +575,13 @@ function ExpandedPostDetails({ ) } -function BackdatedPostIndicator({post}: {post: app.bsky.feed.defs.PostView}) { +function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) { const t = useTheme() const {t: l, i18n} = useLingui() const control = Prompt.usePromptControl() const indexedAt = new Date(post.indexedAt) - const createdAt = bsky.isType(app.bsky.feed.post, post.record) + const createdAt = bsky.isType(AppBskyFeedPost, post.record) ? new Date(post.record.createdAt) : new Date(post.indexedAt) @@ -660,8 +662,8 @@ function BackdatedPostIndicator({post}: {post: app.bsky.feed.defs.PostView}) { } function getThreadAuthor( - post: app.bsky.feed.defs.PostView, - record: app.bsky.feed.post.Main, + post: AppBskyFeedDefs.PostView, + record: AppBskyFeedPost.Main, ): string { if (!record.reply) { return post.author.did diff --git a/src/screens/Profile/components/GermButton.tsx b/src/screens/Profile/components/GermButton.tsx index a3b561ae20..d04e83b3c5 100644 --- a/src/screens/Profile/components/GermButton.tsx +++ b/src/screens/Profile/components/GermButton.tsx @@ -21,14 +21,16 @@ import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {app, com} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as ComGermnetworkDeclaration from '#/lexicons/com/germnetwork/declaration' import type * as bsky from '#/types/bsky' export function GermButton({ germ, profile, }: { - germ: app.bsky.actor.defs.ProfileAssociatedGerm + germ: AppBskyActorDefs.ProfileAssociatedGerm profile: bsky.profile.AnyProfileView }) { const t = useTheme() @@ -125,14 +127,14 @@ function GermSelfButton({did}: {did: string}) { mutationFn: async () => { const previousRecord = await pdsClient // the component takes the did as a plain string prop - .get(com.germnetwork.declaration, { + .get(ComGermnetworkDeclaration, { repo: did as DidString, rkey: 'self', }) .then(res => res.value) .catch(() => null) - await pdsClient.delete(com.germnetwork.declaration, { + await pdsClient.delete(ComGermnetworkDeclaration, { repo: did as DidString, rkey: 'self', }) @@ -147,7 +149,7 @@ function GermSelfButton({did}: {did: string}) { async function undo() { if (!previousRecord) return try { - await pdsClient.put(com.germnetwork.declaration, previousRecord, { + await pdsClient.put(ComGermnetworkDeclaration, previousRecord, { repo: did as DidString, rkey: 'self', }) @@ -278,7 +280,7 @@ function GermSelfButton({did}: {did: string}) { } function constructGermUrl( - declaration: app.bsky.actor.defs.ProfileAssociatedGerm, + declaration: AppBskyActorDefs.ProfileAssociatedGerm, profile: bsky.profile.AnyProfileView, viewerDid?: string, ) { @@ -326,14 +328,14 @@ function platform() { async function whenAppViewReady( appviewClient: Client, actor: string, - fn: (res: app.bsky.actor.getProfile.$OutputBody) => boolean, + fn: (res: AppBskyActorGetProfile.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - appviewClient.call(app.bsky.actor.getProfile, { + appviewClient.call(AppBskyActorGetProfile, { actor: actor as DidString, }), ) diff --git a/src/screens/ProfileList/components/Header.tsx b/src/screens/ProfileList/components/Header.tsx index 98059c37de..45e868524d 100644 --- a/src/screens/ProfileList/components/Header.tsx +++ b/src/screens/ProfileList/components/Header.tsx @@ -23,7 +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 * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' import {MoreOptionsMenu} from './MoreOptionsMenu' import {SubscribeMenu} from './SubscribeMenu' @@ -33,14 +33,14 @@ export function Header({ preferences, }: { rkey: string - list: app.bsky.graph.defs.ListView + list: AppBskyGraphDefs.ListView preferences: UsePreferencesQueryResponse }) { const {_} = useLingui() const ax = useAnalytics() const {currentAccount} = useSession() - const isCurateList = list.purpose === app.bsky.graph.defs.curatelist.value - const isModList = list.purpose === app.bsky.graph.defs.modlist.value + const isCurateList = list.purpose === AppBskyGraphDefs.curatelist.value + const isModList = list.purpose === AppBskyGraphDefs.modlist.value const isBlocking = !!list.viewer?.blocked const isMuting = !!list.viewer?.muted const playHaptic = useHaptics() diff --git a/src/screens/ProfileList/components/MoreOptionsMenu.tsx b/src/screens/ProfileList/components/MoreOptionsMenu.tsx index 02d9cc7212..1a659da26c 100644 --- a/src/screens/ProfileList/components/MoreOptionsMenu.tsx +++ b/src/screens/ProfileList/components/MoreOptionsMenu.tsx @@ -36,14 +36,15 @@ 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' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' export function MoreOptionsMenu({ list, savedFeedConfig, }: { - list: app.bsky.graph.defs.ListView - savedFeedConfig?: app.bsky.actor.defs.SavedFeed + list: AppBskyGraphDefs.ListView + savedFeedConfig?: AppBskyActorDefs.SavedFeed }) { const {_} = useLingui() const ax = useAnalytics() @@ -58,8 +59,8 @@ export function MoreOptionsMenu({ const {mutateAsync: muteList} = useListMuteMutation() const {mutateAsync: blockList} = useListBlockMutation() - const isCurateList = list.purpose === app.bsky.graph.defs.curatelist.value - const isModList = list.purpose === app.bsky.graph.defs.modlist.value + const isCurateList = list.purpose === AppBskyGraphDefs.curatelist.value + const isModList = list.purpose === AppBskyGraphDefs.modlist.value const isBlocking = !!list.viewer?.blocked const isMuting = !!list.viewer?.muted const isPinned = Boolean(savedFeedConfig?.pinned) diff --git a/src/screens/ProfileList/index.tsx b/src/screens/ProfileList/index.tsx index c898663c8f..898c963c41 100644 --- a/src/screens/ProfileList/index.tsx +++ b/src/screens/ProfileList/index.tsx @@ -38,7 +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 * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' 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: app.bsky.graph.defs.ListView + list: AppBskyGraphDefs.ListView moderationOpts: ModerationOpts preferences: UsePreferencesQueryResponse }) { @@ -155,7 +155,7 @@ function ProfileListScreenLoaded({ const {rkey} = route.params const feedSectionRef = useRef(null) const aboutSectionRef = useRef(null) - const isCurateList = list.purpose === app.bsky.graph.defs.curatelist.value + const isCurateList = list.purpose === AppBskyGraphDefs.curatelist.value const isScreenFocused = useIsFocused() const isHidden = list.labels?.findIndex(l => l.val === '!hide') !== -1 const isOwner = currentAccount?.did === list.creator.did diff --git a/src/screens/Search/components/StarterPackCard.tsx b/src/screens/Search/components/StarterPackCard.tsx index 246100c13d..2ce1f9519f 100644 --- a/src/screens/Search/components/StarterPackCard.tsx +++ b/src/screens/Search/components/StarterPackCard.tsx @@ -18,14 +18,15 @@ 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 type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' export function StarterPackCard({ view, onPress, }: { - view: app.bsky.graph.defs.StarterPackView + view: AppBskyGraphDefs.StarterPackView onPress?: () => void }) { const t = useTheme() @@ -35,7 +36,7 @@ export function StarterPackCard({ const link = useStarterPackLink({view}) const record = view.record - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } diff --git a/src/screens/Search/modules/ExploreTrendingVideos.tsx b/src/screens/Search/modules/ExploreTrendingVideos.tsx index 86eafbc54c..45b689c686 100644 --- a/src/screens/Search/modules/ExploreTrendingVideos.tsx +++ b/src/screens/Search/modules/ExploreTrendingVideos.tsx @@ -21,7 +21,7 @@ import { CompactVideoPostCardPlaceholder, } from '#/components/VideoPostCard' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' import * as bsky from '#/types/bsky' const CARD_WIDTH = 100 @@ -160,7 +160,7 @@ function VideoCards({ .flatMap(page => page.slices) .map(slice => slice.items[0]) .filter(Boolean) - .filter(item => bsky.isType(app.bsky.embed.video.view, item.post.embed)) + .filter(item => bsky.isType(AppBskyEmbedVideo.view, item.post.embed)) .slice(0, 8) }, [data]) const href = useMemo(() => { diff --git a/src/screens/Settings/AutomationLabelSettings.tsx b/src/screens/Settings/AutomationLabelSettings.tsx index 480f35a972..daeb05610e 100644 --- a/src/screens/Settings/AutomationLabelSettings.tsx +++ b/src/screens/Settings/AutomationLabelSettings.tsx @@ -22,7 +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 ComAtprotoLabelDefs from '#/lexicons/com/atproto/label/defs' import * as bsky from '#/types/bsky' type Props = NativeStackScreenProps< @@ -54,13 +54,15 @@ export function AutomationLabelSettingsScreen({}: Props) { { profile, updates: existing => { - const labels: $Typed = - bsky.matches(com.atproto.label.defs.selfLabels, existing.labels) - ? existing.labels - : { - $type: 'com.atproto.label.defs#selfLabels', - values: [], - } + const labels: $Typed = bsky.matches( + ComAtprotoLabelDefs.selfLabels, + existing.labels, + ) + ? existing.labels + : { + $type: 'com.atproto.label.defs#selfLabels', + values: [], + } const hasLabel = labels.values.some(l => l.val === 'bot') if (hasLabel) { diff --git a/src/screens/Settings/FindContactsSettings.tsx b/src/screens/Settings/FindContactsSettings.tsx index bc7ef48f8e..55632308ea 100644 --- a/src/screens/Settings/FindContactsSettings.tsx +++ b/src/screens/Settings/FindContactsSettings.tsx @@ -49,7 +49,11 @@ import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' import {InviteFriendsDialog} from '#/features/inviteFriends' -import {app} from '#/lexicons' +import type * as AppBskyContactDefs from '#/lexicons/app/bsky/contact/defs' +import * as AppBskyContactDismissMatch from '#/lexicons/app/bsky/contact/dismissMatch' +import * as AppBskyContactGetMatches from '#/lexicons/app/bsky/contact/getMatches' +import type * as AppBskyContactGetSyncStatus from '#/lexicons/app/bsky/contact/getSyncStatus' +import * as AppBskyContactRemoveData from '#/lexicons/app/bsky/contact/removeData' import type * as bsky from '#/types/bsky' import {bulkWriteFollows} from '../Onboarding/util' @@ -188,7 +192,7 @@ function SyncStatus({ info, refetchStatus, }: { - info: app.bsky.contact.defs.SyncStatus + info: AppBskyContactDefs.SyncStatus refetchStatus: () => Promise }) { const ax = useAnalytics() @@ -217,7 +221,7 @@ function SyncStatus({ const {mutate: dismissMatch} = useMutation({ mutationFn: async (did: string) => { - await client.call(app.bsky.contact.dismissMatch, { + await client.call(AppBskyContactDismissMatch, { subject: did as DidString, }) }, @@ -385,7 +389,7 @@ function StatusHeader({ let cursor: string | undefined do { - const page = await client.call(app.bsky.contact.getMatches, { + const page = await client.call(AppBskyContactGetMatches, { limit: 100, cursor, }) @@ -496,12 +500,12 @@ function StatusFooter({syncedAt}: {syncedAt: string}) { const {mutate: removeData, isPending} = useMutation({ mutationFn: async () => { - await client.call(app.bsky.contact.removeData, {}) + await client.call(AppBskyContactRemoveData, {}) }, onMutate: () => ax.metric('contacts:settings:removeData', {}), onSuccess: () => { Toast.show(_(msg`Contacts removed`)) - queryClient.setQueryData( + queryClient.setQueryData( findContactsStatusQueryKey, {syncStatus: undefined}, ) diff --git a/src/screens/Settings/components/ChangePasswordDialog.tsx b/src/screens/Settings/components/ChangePasswordDialog.tsx index 3015b402b5..4abd88188e 100644 --- a/src/screens/Settings/components/ChangePasswordDialog.tsx +++ b/src/screens/Settings/components/ChangePasswordDialog.tsx @@ -18,7 +18,8 @@ import * as TextField from '#/components/forms/TextField' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerRequestPasswordReset from '#/lexicons/com/atproto/server/requestPasswordReset' +import * as ComAtprotoServerResetPassword from '#/lexicons/com/atproto/server/resetPassword' enum Stages { RequestCode = 'RequestCode', @@ -87,7 +88,7 @@ function Inner() { setError('') setIsProcessing(true) try { - await client.call(com.atproto.server.requestPasswordReset, { + await client.call(ComAtprotoServerRequestPasswordReset, { email: currentAccount.email, }) setStage(Stages.ChangePassword) @@ -131,7 +132,7 @@ function Inner() { setError('') setIsProcessing(true) try { - await client.call(com.atproto.server.resetPassword, { + await client.call(ComAtprotoServerResetPassword, { token: formattedCode, password: newPassword, }) @@ -144,7 +145,7 @@ function Inner() { ), ) } else if ( - matchXrpcError(e, com.atproto.server.resetPassword) === 'InvalidToken' + matchXrpcError(e, ComAtprotoServerResetPassword) === 'InvalidToken' ) { setError(_(msg`This confirmation code is not valid. Please try again.`)) } else { diff --git a/src/screens/Settings/components/DeactivateAccountDialog.tsx b/src/screens/Settings/components/DeactivateAccountDialog.tsx index eaae97659e..6417481c6a 100644 --- a/src/screens/Settings/components/DeactivateAccountDialog.tsx +++ b/src/screens/Settings/components/DeactivateAccountDialog.tsx @@ -14,7 +14,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' -import {com} from '#/lexicons' +import * as ComAtprotoServerDeactivateAccount from '#/lexicons/com/atproto/server/deactivateAccount' export function DeactivateAccountDialog({ control, @@ -43,7 +43,7 @@ function DeactivateAccountDialogInner({ const handleDeactivate = useCallback(async () => { try { setPending(true) - await client.call(com.atproto.server.deactivateAccount, {}) + await client.call(ComAtprotoServerDeactivateAccount, {}) control.close(() => { logoutCurrentAccount('Deactivated') }) diff --git a/src/screens/Settings/components/DeleteAccountDialog.tsx b/src/screens/Settings/components/DeleteAccountDialog.tsx index d2d687bc79..c458347d32 100644 --- a/src/screens/Settings/components/DeleteAccountDialog.tsx +++ b/src/screens/Settings/components/DeleteAccountDialog.tsx @@ -28,7 +28,9 @@ import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import * as toast from '#/components/Toast' import {Span, Text} from '#/components/Typography' -import {chat, com} from '#/lexicons' +import * as ChatBskyActorDeleteAccount from '#/lexicons/chat/bsky/actor/deleteAccount' +import * as ComAtprotoServerDeleteAccount from '#/lexicons/com/atproto/server/deleteAccount' +import * as ComAtprotoServerRequestAccountDelete from '#/lexicons/com/atproto/server/requestAccountDelete' import {resetToTab} from '#/Navigation' const WHITESPACE_RE = /\s/gu @@ -95,7 +97,7 @@ function DeleteAccountDialogInner({ } try { setEmailState(EmailState.PENDING) - await client.call(com.atproto.server.requestAccountDelete) + await client.call(ComAtprotoServerRequestAccountDelete) setError('') setEmailSentCount(prevCount => prevCount + 1) setStep(Step.VERIFY_CODE) @@ -123,8 +125,8 @@ function DeleteAccountDialogInner({ * throws, so reaching the next line means the chat service accepted it - * the agent's `success` flag has no client-side equivalent. */ - await chatClient.call(chat.bsky.actor.deleteAccount) - await client.call(com.atproto.server.deleteAccount, { + await chatClient.call(ChatBskyActorDeleteAccount) + await client.call(ComAtprotoServerDeleteAccount, { did: currentAccount.did, password, token, diff --git a/src/screens/Settings/components/DisableEmail2FADialog.tsx b/src/screens/Settings/components/DisableEmail2FADialog.tsx index c633c82029..1f137cf1fa 100644 --- a/src/screens/Settings/components/DisableEmail2FADialog.tsx +++ b/src/screens/Settings/components/DisableEmail2FADialog.tsx @@ -17,7 +17,8 @@ import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {P, Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerRequestEmailUpdate from '#/lexicons/com/atproto/server/requestEmailUpdate' +import * as ComAtprotoServerUpdateEmail from '#/lexicons/com/atproto/server/updateEmail' enum Stages { Email, @@ -45,7 +46,7 @@ export function DisableEmail2FADialog({ setError('') setIsProcessing(true) try { - await pdsClient.call(com.atproto.server.requestEmailUpdate) + await pdsClient.call(ComAtprotoServerRequestEmailUpdate) setStage(Stages.ConfirmCode) } catch (e) { setError(cleanError(String(e))) @@ -59,7 +60,7 @@ export function DisableEmail2FADialog({ setIsProcessing(true) try { if (currentAccount?.email) { - await pdsClient.call(com.atproto.server.updateEmail, { + await pdsClient.call(ComAtprotoServerUpdateEmail, { email: currentAccount.email, token: confirmationCode.trim(), emailAuthFactor: false, @@ -73,9 +74,7 @@ export function DisableEmail2FADialog({ * The old check matched the PDS message "Token is invalid"; the lexicon * declares that case as `InvalidToken`, so match the code instead. */ - if ( - matchXrpcError(e, com.atproto.server.updateEmail) === 'InvalidToken' - ) { + if (matchXrpcError(e, ComAtprotoServerUpdateEmail) === 'InvalidToken') { setError(_(msg`Invalid 2FA confirmation code.`)) } else { setError(cleanError(e)) diff --git a/src/screens/Settings/components/ExportCarDialog.tsx b/src/screens/Settings/components/ExportCarDialog.tsx index 290f380157..f77f048d09 100644 --- a/src/screens/Settings/components/ExportCarDialog.tsx +++ b/src/screens/Settings/components/ExportCarDialog.tsx @@ -13,7 +13,8 @@ import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' -import {chat, com} from '#/lexicons' +import * as ChatBskyActorExportAccountData from '#/lexicons/chat/bsky/actor/exportAccountData' +import * as ComAtprotoSyncGetRepo from '#/lexicons/com/atproto/sync/getRepo' export function ExportCarDialog({ control, @@ -34,7 +35,7 @@ export function ExportCarDialog({ try { setLoading('repo') const did = currentAccount.did - const data = await pdsClient.call(com.atproto.sync.getRepo, {did}) + const data = await pdsClient.call(ComAtprotoSyncGetRepo, {did}) /* * getRepo declares `application/vnd.ipld.car`, so lex-client hands back * the raw bytes unparsed and does not surface the response content-type. @@ -71,7 +72,7 @@ export function ExportCarDialog({ * fetchHandler workaround, and the chat client emits the proxy header * itself, so the per-call DM headers go away too. */ - const data = await chatClient.call(chat.bsky.actor.exportAccountData) + const data = await chatClient.call(ChatBskyActorExportAccountData) const saveRes = await saveBytesToDisk( 'chat.jsonl', data, diff --git a/src/screens/Settings/components/PwiOptOut.tsx b/src/screens/Settings/components/PwiOptOut.tsx index 4b2edfb64b..fe764e10de 100644 --- a/src/screens/Settings/components/PwiOptOut.tsx +++ b/src/screens/Settings/components/PwiOptOut.tsx @@ -13,7 +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 ComAtprotoLabelDefs from '#/lexicons/com/atproto/label/defs' import * as bsky from '#/types/bsky' export function PwiOptOut() { @@ -36,8 +36,8 @@ export function PwiOptOut() { profile, updates: existing => { // create labels attr if needed - const labels: $Typed = bsky.matches( - com.atproto.label.defs.selfLabels, + const labels: $Typed = bsky.matches( + ComAtprotoLabelDefs.selfLabels, existing.labels, ) ? existing.labels diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx index 644af956a2..6e9559a817 100644 --- a/src/screens/Signup/index.tsx +++ b/src/screens/Signup/index.tsx @@ -31,7 +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 AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' export function Signup({onPressBack}: {onPressBack: () => void}) { @@ -141,7 +141,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) { scrollable> {showStarterPackCard && - bsky.isType(app.bsky.graph.starterpack, starterPack.record) ? ( + bsky.isType(AppBskyGraphStarterpack, starterPack.record) ? ( useContext(SignupContext) * failure is unexpected and should be reported to Sentry. */ function classifyExpectedSignupError(e: unknown): string | undefined { - const code = matchXrpcError(e, com.atproto.server.createAccount) + const code = matchXrpcError(e, ComAtprotoServerCreateAccount) switch (code) { case 'InvalidHandle': case 'HandleNotAvailable': @@ -351,7 +352,7 @@ export function useSubmitSignup() { } catch (err) { const e = err as Error if ( - matchXrpcError(e, com.atproto.server.createAccount) === + matchXrpcError(e, ComAtprotoServerCreateAccount) === 'InvalidInviteCode' ) { dispatch({ diff --git a/src/screens/SignupQueued.tsx b/src/screens/SignupQueued.tsx index e0bf7f2edd..e574afa170 100644 --- a/src/screens/SignupQueued.tsx +++ b/src/screens/SignupQueued.tsx @@ -15,7 +15,7 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Loader} from '#/components/Loader' import {P, Text} from '#/components/Typography' import {IS_IOS, IS_LIQUID_GLASS, IS_WEB} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoTempCheckSignupQueue from '#/lexicons/com/atproto/temp/checkSignupQueue' const COL_WIDTH = 400 @@ -39,7 +39,7 @@ export function SignupQueued() { const checkStatus = useCallback(async () => { setProcessing(true) try { - const res = await pdsClient.call(com.atproto.temp.checkSignupQueue) + const res = await pdsClient.call(ComAtprotoTempCheckSignupQueue) if (res.activated) { /* * Ready to go, exchange the access token for a usable one and kick off diff --git a/src/screens/StarterPack/StarterPackLandingScreen.tsx b/src/screens/StarterPack/StarterPackLandingScreen.tsx index 4e4cf915dd..5731320b01 100644 --- a/src/screens/StarterPack/StarterPackLandingScreen.tsx +++ b/src/screens/StarterPack/StarterPackLandingScreen.tsx @@ -34,7 +34,8 @@ 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 AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' const AnimatedPressable = Animated.createAnimatedComponent(Pressable) @@ -69,8 +70,8 @@ export function LandingScreen({ const isValid = starterPack && starterPack.list && - bsky.matches(app.bsky.graph.defs.starterPackView, starterPack) && - bsky.matches(app.bsky.graph.starterpack, starterPack.record) + bsky.matches(AppBskyGraphDefs.starterPackView, starterPack) && + bsky.matches(AppBskyGraphStarterpack, starterPack.record) useEffect(() => { if (isErrorStarterPack || (starterPack && !isValid)) { @@ -83,7 +84,7 @@ export function LandingScreen({ } // Just for types, this cannot be hit - if (!bsky.isType(app.bsky.graph.starterpack, starterPack.record)) { + if (!bsky.isType(AppBskyGraphStarterpack, starterPack.record)) { return null } @@ -105,8 +106,8 @@ function LandingScreenLoaded({ moderationOpts, }: { - starterPack: app.bsky.graph.defs.StarterPackView - starterPackRecord: app.bsky.graph.starterpack.Main + starterPack: AppBskyGraphDefs.StarterPackView + starterPackRecord: AppBskyGraphStarterpack.Main setScreenState: (state: LoggedOutScreenState) => void moderationOpts: ModerationOpts }) { diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx index 8115f15287..66907afd17 100644 --- a/src/screens/StarterPack/StarterPackScreen.tsx +++ b/src/screens/StarterPack/StarterPackScreen.tsx @@ -73,7 +73,8 @@ 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 AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' type StarterPackScreeProps = NativeStackScreenProps< @@ -146,8 +147,8 @@ export function StarterPackScreenInner({ const isValid = starterPack && (starterPack.list || starterPack?.creator?.did === currentAccount?.did) && - bsky.matches(app.bsky.graph.defs.starterPackView, starterPack) && - bsky.matches(app.bsky.graph.starterpack, starterPack.record) + bsky.matches(AppBskyGraphDefs.starterPackView, starterPack) && + bsky.matches(AppBskyGraphStarterpack, starterPack.record) if (!did || !starterPack || !isValid || !moderationOpts) { return ( @@ -178,7 +179,7 @@ function StarterPackScreenLoaded({ routeParams, moderationOpts, }: { - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView routeParams: StarterPackScreeProps['route']['params'] moderationOpts: ModerationOpts }) { @@ -300,7 +301,7 @@ function Header({ routeParams, onOpenShareDialog, }: { - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView routeParams: StarterPackScreeProps['route']['params'] onOpenShareDialog: () => void }) { @@ -349,7 +350,7 @@ function Header({ setIsProcessing(true) - let listItems: app.bsky.graph.defs.ListItemView[] = [] + let listItems: AppBskyGraphDefs.ListItemView[] = [] try { listItems = await getAllListMembers(appviewClient, starterPack.list.uri) } catch (e) { @@ -404,7 +405,7 @@ function Header({ }) } - if (!bsky.isType(app.bsky.graph.starterpack, record)) { + if (!bsky.isType(AppBskyGraphStarterpack, record)) { return null } @@ -515,7 +516,7 @@ function OverflowMenu({ routeParams, onOpenShareDialog, }: { - starterPack: app.bsky.graph.defs.StarterPackView + starterPack: AppBskyGraphDefs.StarterPackView routeParams: StarterPackScreeProps['route']['params'] onOpenShareDialog: () => void }) { diff --git a/src/screens/StarterPack/Wizard/State.tsx b/src/screens/StarterPack/Wizard/State.tsx index b28a0bd728..bcacc76ee4 100644 --- a/src/screens/StarterPack/Wizard/State.tsx +++ b/src/screens/StarterPack/Wizard/State.tsx @@ -3,7 +3,9 @@ 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 type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' import * as bsky from '#/types/bsky' const steps = ['Details', 'Profiles', 'Feeds'] as const @@ -17,7 +19,7 @@ type Action = | {type: 'SetDescription'; description: string} | {type: 'AddProfile'; profile: bsky.profile.AnyProfileView} | {type: 'RemoveProfile'; profileDid: string} - | {type: 'AddFeed'; feed: app.bsky.feed.defs.GeneratorView} + | {type: 'AddFeed'; feed: AppBskyFeedDefs.GeneratorView} | {type: 'RemoveFeed'; feedUri: string} | {type: 'SetProcessing'; processing: boolean} | {type: 'SetError'; error: string} @@ -28,7 +30,7 @@ interface State { name?: string description?: string profiles: bsky.profile.AnyProfileView[] - feeds: app.bsky.feed.defs.GeneratorView[] + feeds: AppBskyFeedDefs.GeneratorView[] processing: boolean error?: string transitionDirection: 'Backward' | 'Forward' @@ -121,8 +123,8 @@ export function Provider({ targetProfile, children, }: { - starterPack?: app.bsky.graph.defs.StarterPackView - listItems?: app.bsky.graph.defs.ListItemView[] + starterPack?: AppBskyGraphDefs.StarterPackView + listItems?: AppBskyGraphDefs.ListItemView[] targetProfile: bsky.profile.AnyProfileView children: React.ReactNode }) { @@ -131,7 +133,7 @@ export function Provider({ if ( starterPack && - bsky.matches(app.bsky.graph.starterpack, starterPack.record) + bsky.matches(AppBskyGraphStarterpack, starterPack.record) ) { return { canNext: true, diff --git a/src/screens/Takendown.tsx b/src/screens/Takendown.tsx index 60517295f5..336577abf5 100644 --- a/src/screens/Takendown.tsx +++ b/src/screens/Takendown.tsx @@ -23,7 +23,8 @@ import {SimpleInlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import {P, Text} from '#/components/Typography' import {IS_WEB} from '#/env' -import {com, tools} from '#/lexicons' +import * as ComAtprotoModerationCreateReport from '#/lexicons/com/atproto/moderation/createReport' +import * as ToolsOzoneReportDefs from '#/lexicons/tools/ozone/report/defs' const COL_WIDTH = 400 @@ -51,9 +52,9 @@ export function Takendown() { mutationFn: async (appealText: string) => { if (!currentAccount) throw new Error('No session') await client.call( - com.atproto.moderation.createReport, + ComAtprotoModerationCreateReport, { - reasonType: tools.ozone.report.defs.reasonAppeal.value, + reasonType: ToolsOzoneReportDefs.reasonAppeal.value, subject: { $type: 'com.atproto.admin.defs#repoRef', did: currentAccount.did, diff --git a/src/screens/VideoFeed/index.tsx b/src/screens/VideoFeed/index.tsx index 0b6fd3aba0..21561ffc7b 100644 --- a/src/screens/VideoFeed/index.tsx +++ b/src/screens/VideoFeed/index.tsx @@ -98,7 +98,9 @@ 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 AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import {Scrubber, VIDEO_PLAYER_BOTTOM_INSET} from './components/Scrubber' @@ -172,8 +174,8 @@ type CurrentSource = { type VideoItem = { moderation: ModerationDecision - post: app.bsky.feed.defs.PostView - video: app.bsky.embed.video.View + post: AppBskyFeedDefs.PostView + video: AppBskyEmbedVideo.View feedContext: string | undefined reqId: string | undefined } @@ -211,8 +213,8 @@ function Feed() { const items: { _reactKey: string moderation: ModerationDecision - post: app.bsky.feed.defs.PostView - video: app.bsky.embed.video.View + post: AppBskyFeedDefs.PostView + video: AppBskyEmbedVideo.View feedContext: string | undefined reqId: string | undefined }[] = [] @@ -222,7 +224,7 @@ function Feed() { ) if ( feedPost && - bsky.isType(app.bsky.embed.video.view, feedPost.post.embed) + bsky.isType(AppBskyEmbedVideo.view, feedPost.post.embed) ) { items.push({ _reactKey: feedPost._reactKey, @@ -292,14 +294,14 @@ function Feed() { const prevPost = prevSlice?.post const prevEmbed = prevPost?.embed const prevVideo = - prevEmbed && bsky.isType(app.bsky.embed.video.view, prevEmbed) + prevEmbed && bsky.isType(AppBskyEmbedVideo.view, prevEmbed) ? prevEmbed.playlist : null const currSlice = videos.at(index) const currPost = currSlice?.post const currEmbed = currPost?.embed const currVideo = - currEmbed && bsky.isType(app.bsky.embed.video.view, currEmbed) + currEmbed && bsky.isType(AppBskyEmbedVideo.view, currEmbed) ? currEmbed.playlist : null const currVideoModeration = currSlice?.moderation @@ -307,7 +309,7 @@ function Feed() { const nextPost = nextSlice?.post const nextEmbed = nextPost?.embed const nextVideo = - nextEmbed && bsky.isType(app.bsky.embed.video.view, nextEmbed) + nextEmbed && bsky.isType(AppBskyEmbedVideo.view, nextEmbed) ? nextEmbed.playlist : null @@ -477,8 +479,8 @@ let VideoItem = ({ reqId, }: { player?: VideoPlayer - post: app.bsky.feed.defs.PostView - embed: app.bsky.embed.video.View + post: AppBskyFeedDefs.PostView + embed: AppBskyEmbedVideo.View active: boolean adjacent: boolean scrollGesture: NativeGesture @@ -588,7 +590,7 @@ function VideoItemInner({ active, }: { player: VideoPlayer - embed: app.bsky.embed.video.View + embed: AppBskyEmbedVideo.View active: boolean }) { const {bottom} = useSafeAreaInsets() @@ -705,7 +707,7 @@ function ModerationOverlay({ embed, onPressShow, }: { - embed: app.bsky.embed.video.View + embed: AppBskyEmbedVideo.View onPressShow: () => void }) { const {t: l} = useLingui() @@ -803,8 +805,8 @@ function Overlay({ reqId, }: { player?: VideoPlayer - post: Shadow - embed: app.bsky.embed.video.View + post: Shadow + embed: AppBskyEmbedVideo.View active: boolean scrollGesture: NativeGesture moderation: ModerationDecision @@ -825,7 +827,7 @@ function Overlay({ ) const rkey = new AtUri(post.uri).rkey - const record = bsky.isType(app.bsky.feed.post, post.record) + const record = bsky.isType(AppBskyFeedPost, post.record) ? post.record : undefined const richText = new RichTextAPI({ @@ -1085,7 +1087,7 @@ function VideoItemPlaceholder({ style, blur, }: { - embed: app.bsky.embed.video.View + embed: AppBskyEmbedVideo.View style?: ImageStyle blur?: boolean }) { @@ -1126,7 +1128,7 @@ function PlayPauseTapArea({ reqId, }: { player: VideoPlayer - post: Shadow + post: Shadow feedContext: string | undefined reqId: string | undefined }) { @@ -1268,9 +1270,7 @@ function EndMessage() { /* * If the video is taller than 9:16 */ -function isTallAspectRatio( - aspectRatio: app.bsky.embed.video.View['aspectRatio'], -) { +function isTallAspectRatio(aspectRatio: AppBskyEmbedVideo.View['aspectRatio']) { const videoAspectRatio = (aspectRatio?.width ?? 1) / (aspectRatio?.height ?? 1) return videoAspectRatio <= 9 / 16 diff --git a/src/state/cache/post-shadow.ts b/src/state/cache/post-shadow.ts index 6b88bbed35..004110f907 100644 --- a/src/state/cache/post-shadow.ts +++ b/src/state/cache/post-shadow.ts @@ -11,7 +11,9 @@ import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from '#/state/qu import {findAllPostsInQueryData as findAllPostsInQuoteQueryData} from '#/state/queries/post-quotes' import {findAllPostsInQueryData as findAllPostsInSearchQueryData} from '#/state/queries/search-posts-v2' import {findAllPostsInQueryData as findAllPostsInThreadV2QueryData} from '#/state/queries/usePostThread/queryCache' -import {app} from '#/lexicons' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' import {castAsShadow, type Shadow} from './types' export type {Shadow} from './types' @@ -24,8 +26,7 @@ export interface PostShadow { likeUri: AtUriString | 'pending' | undefined repostUri: AtUriString | 'pending' | undefined isDeleted: boolean - embed: - app.bsky.embed.record.View | app.bsky.embed.recordWithMedia.View | undefined + embed: AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined pinned: boolean optimisticReplyCount: number | undefined bookmarked: boolean | undefined @@ -35,7 +36,7 @@ export const POST_TOMBSTONE = Symbol('PostTombstone') const emitter = new EventEmitter() const shadows: WeakMap< - app.bsky.feed.defs.PostView, + AppBskyFeedDefs.PostView, Partial > = new WeakMap() @@ -43,13 +44,13 @@ const shadows: WeakMap< * Use with caution! This function returns the raw shadow data for a post. * Prefer using `usePostShadow`. */ -export function dangerousGetPostShadow(post: app.bsky.feed.defs.PostView) { +export function dangerousGetPostShadow(post: AppBskyFeedDefs.PostView) { return shadows.get(post) } export function usePostShadow( - post: app.bsky.feed.defs.PostView, -): Shadow | typeof POST_TOMBSTONE { + post: AppBskyFeedDefs.PostView, +): Shadow | typeof POST_TOMBSTONE { const [shadow, setShadow] = useState(() => shadows.get(post)) const [prevPost, setPrevPost] = useState(post) if (post !== prevPost) { @@ -77,9 +78,9 @@ export function usePostShadow( } function mergeShadow( - post: app.bsky.feed.defs.PostView, + post: AppBskyFeedDefs.PostView, shadow: Partial, -): Shadow | typeof POST_TOMBSTONE { +): Shadow | typeof POST_TOMBSTONE { if (shadow.isDeleted) { return POST_TOMBSTONE } @@ -128,10 +129,10 @@ function mergeShadow( let embed: typeof post.embed if ('embed' in shadow) { if ( - (bsky.isType(app.bsky.embed.record.view, post.embed) && - bsky.isType(app.bsky.embed.record.view, shadow.embed)) || - (bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed) && - bsky.isType(app.bsky.embed.recordWithMedia.view, shadow.embed)) + (bsky.isType(AppBskyEmbedRecord.view, post.embed) && + bsky.isType(AppBskyEmbedRecord.view, shadow.embed)) || + (bsky.isType(AppBskyEmbedRecordWithMedia.view, post.embed) && + bsky.isType(AppBskyEmbedRecordWithMedia.view, shadow.embed)) ) { /* * `isType` asserts a present, matching `$type` at runtime but narrows to @@ -184,7 +185,7 @@ export function updatePostShadow( function* findPostsInCache( queryClient: QueryClient, uri: string, -): Generator { +): Generator { for (let post of findAllPostsInFeedQueryData(queryClient, uri)) { yield post } diff --git a/src/state/cache/thread-mutes.tsx b/src/state/cache/thread-mutes.tsx index 17f6be9f34..45bcb23e07 100644 --- a/src/state/cache/thread-mutes.tsx +++ b/src/state/cache/thread-mutes.tsx @@ -8,7 +8,7 @@ import { import {type AtUriString} from '@atproto/syntax' import * as persisted from '#/state/persisted' -import {app} from '#/lexicons' +import * as AppBskyGraphMuteThread from '#/lexicons/app/bsky/graph/muteThread' import {useAppviewClient, useSession} from '../session' type StateContext = Map @@ -90,7 +90,7 @@ function useMigrateMutes(setThreadMute: SetStateContext) { setThreadMute(root, true) await client - .call(app.bsky.graph.muteThread, { + .call(AppBskyGraphMuteThread, { // the persisted list only ever holds post at-uris root: root as AtUriString, }) diff --git a/src/state/feed-feedback.tsx b/src/state/feed-feedback.tsx index bcaa8d03c5..19a360de8a 100644 --- a/src/state/feed-feedback.tsx +++ b/src/state/feed-feedback.tsx @@ -22,13 +22,14 @@ import { } from '#/state/queries/post-feed' import {getItemsForFeedback} from '#/view/com/posts/PostFeed' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedSendInteractions from '#/lexicons/app/bsky/feed/sendInteractions' import {useAppviewClient} from './session' export const FEEDBACK_FEEDS = [...PROD_FEEDS, ...STAGING_FEEDS] export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set< - app.bsky.feed.defs.Interaction['event'] + AppBskyFeedDefs.Interaction['event'] >([ // These are explicit actions and are therefore fine to send. 'app.bsky.feed.defs#requestLess', @@ -46,7 +47,7 @@ export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set< export type StateContext = { enabled: boolean onItemSeen: (item: any) => void - sendInteraction: (interaction: app.bsky.feed.defs.Interaction) => void + sendInteraction: (interaction: AppBskyFeedDefs.Interaction) => void feedDescriptor: FeedDescriptor | undefined feedSourceInfo: FeedSourceInfo | undefined } @@ -54,7 +55,7 @@ export type StateContext = { const stateContext = createContext({ enabled: false, onItemSeen: (_item: any) => {}, - sendInteraction: (_interaction: app.bsky.feed.defs.Interaction) => {}, + sendInteraction: (_interaction: AppBskyFeedDefs.Interaction) => {}, feedDescriptor: undefined, feedSourceInfo: undefined, }) @@ -83,7 +84,7 @@ export function useFeedFeedback( const history = useRef< // Use a WeakSet so that we don't need to clear it. // This assumes that referential identity of slice items maps 1:1 to feed (re)fetches. - WeakSet + WeakSet >(new WeakSet()) const flushEvents = useCallback( @@ -158,7 +159,7 @@ export function useFeedFeedback( */ client .call( - app.bsky.feed.sendInteractions, + AppBskyFeedSendInteractions, { interactions: interactionsToSend, feed: feed?.uri as AtUriString | undefined, @@ -224,7 +225,7 @@ export function useFeedFeedback( ) const sendInteraction = useCallback( - (interaction: app.bsky.feed.defs.Interaction) => { + (interaction: AppBskyFeedDefs.Interaction) => { if (!enabled) { return } @@ -272,7 +273,7 @@ export function isDiscoverFeed(feed?: FeedDescriptor) { function isInteractionAllowed( enabled: boolean, feed: FeedSourceFeedInfo | undefined, - interaction: app.bsky.feed.defs.Interaction['event'], + interaction: AppBskyFeedDefs.Interaction['event'], ) { if (!enabled || !feed) { return false @@ -281,19 +282,19 @@ function isInteractionAllowed( return isDiscover ? true : THIRD_PARTY_ALLOWED_INTERACTIONS.has(interaction) } -function toString(interaction: app.bsky.feed.defs.Interaction): string { +function toString(interaction: AppBskyFeedDefs.Interaction): string { return `${interaction.item}|${interaction.event}|${ interaction.feedContext || '' }|${interaction.reqId || ''}` } -function toInteraction(str: string): app.bsky.feed.defs.Interaction { +function toInteraction(str: string): AppBskyFeedDefs.Interaction { const [item, event, feedContext, reqId] = str.split('|') /* * The fields come from splitting an internally-built key, so neither the * at-uri nor the event token is narrowed by the compiler here. */ - return {item, event, feedContext, reqId} as app.bsky.feed.defs.Interaction + return {item, event, feedContext, reqId} as AppBskyFeedDefs.Interaction } type AggregatedStats = { @@ -312,7 +313,7 @@ function createAggregatedStats(): AggregatedStats { function sendOrAggregateInteractionsForStats( stats: AggregatedStats, - interactions: app.bsky.feed.defs.Interaction[], + interactions: AppBskyFeedDefs.Interaction[], ) { for (let interaction of interactions) { switch (interaction.event) { diff --git a/src/state/messages/convo/agent.ts b/src/state/messages/convo/agent.ts index fa2c7fab9b..b068e464ca 100644 --- a/src/state/messages/convo/agent.ts +++ b/src/state/messages/convo/agent.ts @@ -41,7 +41,20 @@ import { parseConvoView, } from '#/components/dms/util' import {IS_NATIVE} from '#/env' -import {type app, chat} from '#/lexicons' +import {type app} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoAddReaction from '#/lexicons/chat/bsky/convo/addReaction' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoDeleteMessageForSelf from '#/lexicons/chat/bsky/convo/deleteMessageForSelf' +import * as ChatBskyConvoGetConvo from '#/lexicons/chat/bsky/convo/getConvo' +import * as ChatBskyConvoGetConvoMembers from '#/lexicons/chat/bsky/convo/getConvoMembers' +import type * as ChatBskyConvoGetLog from '#/lexicons/chat/bsky/convo/getLog' +import * as ChatBskyConvoGetMessages from '#/lexicons/chat/bsky/convo/getMessages' +import * as ChatBskyConvoRemoveReaction from '#/lexicons/chat/bsky/convo/removeReaction' +import * as ChatBskyConvoSendMessage from '#/lexicons/chat/bsky/convo/sendMessage' +import * as ChatBskyConvoSendMessageBatch from '#/lexicons/chat/bsky/convo/sendMessageBatch' +import type * as ChatBskyEmbedJoinLink from '#/lexicons/chat/bsky/embed/joinLink' +import type * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' const logger = Logger.create(Logger.Context.ConversationAgent) @@ -58,21 +71,21 @@ export function isConvoItemMessage( } function toSystemMessageView( - ev: chat.bsky.convo.getLog.$OutputBody['logs'][number], -): chat.bsky.convo.defs.SystemMessageView | null { + ev: ChatBskyConvoGetLog.$OutputBody['logs'][number], +): ChatBskyConvoDefs.SystemMessageView | null { const isSystem = - bsky.isType(chat.bsky.convo.defs.logAddMember, ev) || - bsky.isType(chat.bsky.convo.defs.logRemoveMember, ev) || - bsky.isType(chat.bsky.convo.defs.logMemberJoin, ev) || - bsky.isType(chat.bsky.convo.defs.logMemberLeave, ev) || - bsky.isType(chat.bsky.convo.defs.logLockConvo, ev) || - bsky.isType(chat.bsky.convo.defs.logUnlockConvo, ev) || - bsky.isType(chat.bsky.convo.defs.logLockConvoPermanently, ev) || - bsky.isType(chat.bsky.convo.defs.logEditGroup, ev) || - bsky.isType(chat.bsky.convo.defs.logCreateJoinLink, ev) || - bsky.isType(chat.bsky.convo.defs.logEditJoinLink, ev) || - bsky.isType(chat.bsky.convo.defs.logEnableJoinLink, ev) || - bsky.isType(chat.bsky.convo.defs.logDisableJoinLink, ev) + bsky.isType(ChatBskyConvoDefs.logAddMember, ev) || + bsky.isType(ChatBskyConvoDefs.logRemoveMember, ev) || + bsky.isType(ChatBskyConvoDefs.logMemberJoin, ev) || + bsky.isType(ChatBskyConvoDefs.logMemberLeave, ev) || + bsky.isType(ChatBskyConvoDefs.logLockConvo, ev) || + bsky.isType(ChatBskyConvoDefs.logUnlockConvo, ev) || + bsky.isType(ChatBskyConvoDefs.logLockConvoPermanently, ev) || + bsky.isType(ChatBskyConvoDefs.logEditGroup, ev) || + bsky.isType(ChatBskyConvoDefs.logCreateJoinLink, ev) || + bsky.isType(ChatBskyConvoDefs.logEditJoinLink, ev) || + bsky.isType(ChatBskyConvoDefs.logEnableJoinLink, ev) || + bsky.isType(ChatBskyConvoDefs.logDisableJoinLink, ev) if (!isSystem) return null return ev.message } @@ -82,8 +95,8 @@ function toSystemMessageView( * the fields the deleted view carries so a reply can render it as deleted. */ function toDeletedMessageView( - m: chat.bsky.convo.defs.MessageView, -): $Typed { + m: ChatBskyConvoDefs.MessageView, +): $Typed { return { $type: 'chat.bsky.convo.defs#deletedMessageView', id: m.id, @@ -108,29 +121,28 @@ export class Convo { private pastMessages: Map< string, - | chat.bsky.convo.defs.MessageView - | chat.bsky.convo.defs.DeletedMessageView - | chat.bsky.convo.defs.SystemMessageView + | ChatBskyConvoDefs.MessageView + | ChatBskyConvoDefs.DeletedMessageView + | ChatBskyConvoDefs.SystemMessageView > = new Map() private newMessages: Map< string, - | chat.bsky.convo.defs.MessageView - | chat.bsky.convo.defs.DeletedMessageView - | chat.bsky.convo.defs.SystemMessageView + | ChatBskyConvoDefs.MessageView + | ChatBskyConvoDefs.DeletedMessageView + | ChatBskyConvoDefs.SystemMessageView > = new Map() private pendingMessages: Map< string, { id: string - message: chat.bsky.convo.defs.MessageInput + message: ChatBskyConvoDefs.MessageInput optimisticEmbedView?: - | $Typed - | $Typed - optimisticReplyTo?: $Typed + $Typed | $Typed + optimisticReplyTo?: $Typed } > = new Map() private deletedMessages: Set = new Set() - private relatedProfiles: Map = + private relatedProfiles: Map = new Map() /** * Accumulated profile shadow state, keyed by did. The profiles this agent @@ -150,8 +162,8 @@ export class Convo { convoId: string convo: ConvoWithDetails | undefined - sender: chat.bsky.actor.defs.ProfileViewBasic | undefined - recipients: chat.bsky.actor.defs.ProfileViewBasic[] | undefined + sender: ChatBskyActorDefs.ProfileViewBasic | undefined + recipients: ChatBskyActorDefs.ProfileViewBasic[] | undefined snapshot: ConvoState | undefined constructor(params: ConvoParams) { @@ -589,7 +601,7 @@ export class Convo { } } - private setConvo(convo: chat.bsky.convo.defs.ConvoView) { + private setConvo(convo: ChatBskyConvoDefs.ConvoView) { this.convo = parseConvoView(convo, this.senderUserDid) ?? this.convo if (this.convo) { for (const member of this.convo.members) { @@ -599,7 +611,7 @@ export class Convo { this.applyProfileShadows() } - private updateConvo(convo: Partial) { + private updateConvo(convo: Partial) { if (this.convo) { this.convo = parseConvoView({...this.convo.view, ...convo}, this.senderUserDid) ?? @@ -709,7 +721,7 @@ export class Convo { } private pendingFetchConvo: - Promise<{convo: chat.bsky.convo.defs.ConvoView}> | undefined + Promise<{convo: ChatBskyConvoDefs.ConvoView}> | undefined async fetchConvo() { if (this.pendingFetchConvo) return this.pendingFetchConvo @@ -719,7 +731,7 @@ export class Convo { this.pendingFetchConvo = (async () => { try { const response = await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.getConvo, { + return this.chatClient.call(ChatBskyConvoGetConvo, { convoId: this.convoId, }) }) @@ -761,7 +773,7 @@ export class Convo { let cursor: string | undefined do { const result = await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.getConvoMembers, { + return this.chatClient.call(ChatBskyConvoGetConvoMembers, { convoId: this.convoId, limit: 50, cursor, @@ -803,7 +815,7 @@ export class Convo { const nextCursor = this.oldestRev // for TS const response = await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.getMessages, { + return this.chatClient.call(ChatBskyConvoGetMessages, { cursor: nextCursor, convoId: this.convoId, limit: IS_NATIVE ? 30 : 60, @@ -828,9 +840,9 @@ export class Convo { for (const message of messages) { if ( - bsky.isType(chat.bsky.convo.defs.messageView, message) || - bsky.isType(chat.bsky.convo.defs.deletedMessageView, message) || - bsky.isType(chat.bsky.convo.defs.systemMessageView, message) + bsky.isType(ChatBskyConvoDefs.messageView, message) || + bsky.isType(ChatBskyConvoDefs.deletedMessageView, message) || + bsky.isType(ChatBskyConvoDefs.systemMessageView, message) ) { /* * If this message is already in new messages, it was added by the @@ -905,7 +917,7 @@ export class Convo { this.commit() } - ingestFirehose(events: chat.bsky.convo.getLog.$OutputBody['logs']) { + ingestFirehose(events: ChatBskyConvoGetLog.$OutputBody['logs']) { let needsCommit = false for (const ev of events) { @@ -942,8 +954,8 @@ export class Convo { } if ( - bsky.isType(chat.bsky.convo.defs.logCreateMessage, ev) && - bsky.isType(chat.bsky.convo.defs.messageView, ev.message) + bsky.isType(ChatBskyConvoDefs.logCreateMessage, ev) && + bsky.isType(ChatBskyConvoDefs.messageView, ev.message) ) { /* * If this message is already in past messages, the initial @@ -968,8 +980,8 @@ export class Convo { } needsCommit = true } else if ( - bsky.isType(chat.bsky.convo.defs.logDeleteMessage, ev) && - bsky.isType(chat.bsky.convo.defs.deletedMessageView, ev.message) + bsky.isType(ChatBskyConvoDefs.logDeleteMessage, ev) && + bsky.isType(ChatBskyConvoDefs.deletedMessageView, ev.message) ) { /* * Remove the message itself, and keep its id in `deletedMessages` @@ -984,9 +996,9 @@ export class Convo { this.deletedMessages.add(ev.message.id) needsCommit = true } else if ( - (bsky.isType(chat.bsky.convo.defs.logAddReaction, ev) || - bsky.isType(chat.bsky.convo.defs.logRemoveReaction, ev)) && - bsky.isType(chat.bsky.convo.defs.messageView, ev.message) + (bsky.isType(ChatBskyConvoDefs.logAddReaction, ev) || + bsky.isType(ChatBskyConvoDefs.logRemoveReaction, ev)) && + bsky.isType(ChatBskyConvoDefs.messageView, ev.message) ) { /* * Update if we have this in state - replace message wholesale. If we don't, don't worry about it. @@ -1023,11 +1035,10 @@ export class Convo { private pendingMessageFailure: 'recoverable' | 'unrecoverable' | null = null sendMessage( - message: chat.bsky.convo.defs.MessageInput, + message: ChatBskyConvoDefs.MessageInput, optimisticEmbedView?: - | $Typed - | $Typed, - optimisticReplyTo?: $Typed, + $Typed | $Typed, + optimisticReplyTo?: $Typed, ) { // Ignore empty messages for now since they have no other purpose atm if (!message.text.trim() && !message.embed) return @@ -1102,7 +1113,7 @@ export class Convo { this.commit() } - updateJoinLink(joinLink: chat.bsky.group.defs.JoinLinkView | undefined) { + updateJoinLink(joinLink: ChatBskyGroupDefs.JoinLinkView | undefined) { if (this.convo?.kind !== 'group') { throw new Error('updateJoinLink can only be called on group convo') } @@ -1118,7 +1129,7 @@ export class Convo { } updateLockStatus( - lockStatus: chat.bsky.convo.defs.ConvoLockStatus, + lockStatus: ChatBskyConvoDefs.ConvoLockStatus, lockStatusModerationOverride: boolean, ) { if (this.convo?.kind !== 'group') { @@ -1157,7 +1168,7 @@ export class Convo { const {id, message} = pendingMessage - const res = await this.chatClient.call(chat.bsky.convo.sendMessage, { + const res = await this.chatClient.call(ChatBskyConvoSendMessage, { convoId: this.convoId, message, }) @@ -1257,7 +1268,7 @@ export class Convo { try { const {items} = await this.chatClient.call( - chat.bsky.convo.sendMessageBatch, + ChatBskyConvoSendMessageBatch, { items: messageArray.map(({message}) => ({ convoId: this.convoId, @@ -1298,7 +1309,7 @@ export class Convo { try { await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.deleteMessageForSelf, { + return this.chatClient.call(ChatBskyConvoDeleteMessageForSelf, { convoId: this.convoId, messageId, }) @@ -1332,11 +1343,11 @@ export class Convo { * matching what the server returns on refresh. */ private tombstoneDeletedReplyTo( - m: chat.bsky.convo.defs.MessageView, - ): chat.bsky.convo.defs.MessageView { + m: ChatBskyConvoDefs.MessageView, + ): ChatBskyConvoDefs.MessageView { const {replyTo} = m if ( - !bsky.isType(chat.bsky.convo.defs.messageView, replyTo) || + !bsky.isType(ChatBskyConvoDefs.messageView, replyTo) || !this.deletedMessages.has(replyTo.id) ) { return m @@ -1351,19 +1362,19 @@ export class Convo { const items: ConvoItem[] = [] this.pastMessages.forEach(m => { - if (bsky.isType(chat.bsky.convo.defs.messageView, m)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, m)) { items.unshift({ type: 'message', key: m.id, message: this.tombstoneDeletedReplyTo(m), }) - } else if (bsky.isType(chat.bsky.convo.defs.deletedMessageView, m)) { + } else if (bsky.isType(ChatBskyConvoDefs.deletedMessageView, m)) { items.unshift({ type: 'deleted-message', key: m.id, message: m, }) - } else if (bsky.isType(chat.bsky.convo.defs.systemMessageView, m)) { + } else if (bsky.isType(ChatBskyConvoDefs.systemMessageView, m)) { items.unshift({ type: 'system-message', key: m.id, @@ -1384,19 +1395,19 @@ export class Convo { } this.newMessages.forEach(m => { - if (bsky.isType(chat.bsky.convo.defs.messageView, m)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, m)) { items.push({ type: 'message', key: m.id, message: this.tombstoneDeletedReplyTo(m), }) - } else if (bsky.isType(chat.bsky.convo.defs.deletedMessageView, m)) { + } else if (bsky.isType(ChatBskyConvoDefs.deletedMessageView, m)) { items.push({ type: 'deleted-message', key: m.id, message: m, }) - } else if (bsky.isType(chat.bsky.convo.defs.systemMessageView, m)) { + } else if (bsky.isType(ChatBskyConvoDefs.systemMessageView, m)) { items.push({ type: 'system-message', key: m.id, @@ -1462,7 +1473,7 @@ export class Convo { * @param emoji - must be one grapheme */ async addReaction(messageId: string, emoji: string) { - const optimisticReaction: chat.bsky.convo.defs.ReactionView = { + const optimisticReaction: ChatBskyConvoDefs.ReactionView = { value: emoji, sender: {did: this.senderUserDid}, createdAt: toDatetimeString(new Date()), @@ -1471,7 +1482,7 @@ export class Convo { if (this.pastMessages.has(messageId)) { const prevMessage = this.pastMessages.get(messageId) if ( - bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) && + bsky.isType(ChatBskyConvoDefs.messageView, prevMessage) && // skip optimistic update if reaction already exists !prevMessage.reactions?.find( reaction => @@ -1501,7 +1512,7 @@ export class Convo { } else if (this.newMessages.has(messageId)) { const prevMessage = this.newMessages.get(messageId) if ( - bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) && + bsky.isType(ChatBskyConvoDefs.messageView, prevMessage) && !prevMessage.reactions?.find(reaction => reaction.value === emoji) ) { if (prevMessage.reactions && prevMessage.reactions.length >= 5) @@ -1520,12 +1531,12 @@ export class Convo { try { logger.debug(`Adding reaction ${emoji} to message ${messageId}`) - const data = await this.chatClient.call(chat.bsky.convo.addReaction, { + const data = await this.chatClient.call(ChatBskyConvoAddReaction, { messageId, value: emoji, convoId: this.convoId, }) - if (bsky.isType(chat.bsky.convo.defs.messageView, data.message)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, data.message)) { if (this.pastMessages.has(messageId)) { this.pastMessages.set(messageId, data.message) this.commit() @@ -1550,7 +1561,7 @@ export class Convo { let restore: null | (() => void) = null if (this.pastMessages.has(messageId)) { const prevMessage = this.pastMessages.get(messageId) - if (bsky.isType(chat.bsky.convo.defs.messageView, prevMessage)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, prevMessage)) { this.pastMessages.set(messageId, { ...prevMessage, reactions: prevMessage.reactions?.filter( @@ -1567,7 +1578,7 @@ export class Convo { } } else if (this.newMessages.has(messageId)) { const prevMessage = this.newMessages.get(messageId) - if (bsky.isType(chat.bsky.convo.defs.messageView, prevMessage)) { + if (bsky.isType(ChatBskyConvoDefs.messageView, prevMessage)) { this.newMessages.set(messageId, { ...prevMessage, reactions: prevMessage.reactions?.filter( @@ -1586,7 +1597,7 @@ export class Convo { try { logger.debug(`Removing reaction ${emoji} from message ${messageId}`) - await this.chatClient.call(chat.bsky.convo.removeReaction, { + await this.chatClient.call(ChatBskyConvoRemoveReaction, { messageId, value: emoji, convoId: this.convoId, diff --git a/src/state/messages/convo/index.tsx b/src/state/messages/convo/index.tsx index 63590460ed..bf0d5096b7 100644 --- a/src/state/messages/convo/index.tsx +++ b/src/state/messages/convo/index.tsx @@ -29,14 +29,14 @@ import {RQKEY_ROOT as ListConvosQueryKeyRoot} from '#/state/queries/messages/lis import {RQKEY as createProfileQueryKey} from '#/state/queries/profile' import {useChatClient} from '#/state/session' import {type GroupConvoMember} from '#/components/dms/util' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import * as bsky from '#/types/bsky' export * from '#/state/messages/convo/util' function membersChanged( - a: chat.bsky.convo.defs.ConvoView['members'], - b: chat.bsky.convo.defs.ConvoView['members'], + a: ChatBskyConvoDefs.ConvoView['members'], + b: ChatBskyConvoDefs.ConvoView['members'], ) { if (a.length !== b.length) return true const aDids = new Set(a.map(m => m.did)) @@ -84,10 +84,9 @@ export function ConvoProvider({ const chatClient = useChatClient() const events = useMessagesEventBus() const [convo] = useState(() => { - const placeholder = - queryClient.getQueryData( - getConvoKey(convoId), - ) + const placeholder = queryClient.getQueryData( + getConvoKey(convoId), + ) return new Convo({ convoId, chatClient, @@ -153,13 +152,13 @@ export function ConvoProvider({ const queryKey = event.query.queryKey as string[] if (queryKey[0] === root && queryKey[1] === id) { const data = event.query.state.data as - chat.bsky.convo.defs.ConvoView | undefined + ChatBskyConvoDefs.ConvoView | undefined if (data && convo.convo && data.muted !== convo.convo.view.muted) { convo.updateMuted(data.muted) } if ( data && - bsky.isType(chat.bsky.convo.defs.groupConvo, data.kind) && + bsky.isType(ChatBskyConvoDefs.groupConvo, data.kind) && convo.convo?.kind === 'group' ) { if (data.kind.name !== convo.convo.details.name) { @@ -181,7 +180,7 @@ export function ConvoProvider({ } if ( data && - bsky.isType(chat.bsky.convo.defs.groupConvo, data.kind) && + bsky.isType(ChatBskyConvoDefs.groupConvo, data.kind) && convo.convo?.kind === 'group' && (membersChanged(data.members, convo.convo.members) || data.kind.memberCount !== convo.convo.details.memberCount) diff --git a/src/state/messages/events/agent.ts b/src/state/messages/events/agent.ts index 9bc7158187..8789852742 100644 --- a/src/state/messages/events/agent.ts +++ b/src/state/messages/events/agent.ts @@ -20,7 +20,7 @@ import { type MessagesEventBusParams, MessagesEventBusStatus, } from '#/state/messages/events/types' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetLog from '#/lexicons/chat/bsky/convo/getLog' const logger = Logger.create(Logger.Context.DMsAgent) @@ -269,7 +269,7 @@ export class MessagesEventBus { try { const response = await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.getLog, {}) + return this.chatClient.call(ChatBskyConvoGetLog, {}) }) // throw new Error('UNCOMMENT TO TEST INIT FAILURE') @@ -361,11 +361,11 @@ export class MessagesEventBus { // ) let needsEmit = false - let batch: chat.bsky.convo.getLog.$OutputBody['logs'] = [] + let batch: ChatBskyConvoGetLog.$OutputBody['logs'] = [] try { const response = await networkRetry(2, () => { - return this.chatClient.call(chat.bsky.convo.getLog, { + return this.chatClient.call(ChatBskyConvoGetLog, { cursor: this.latestRev, }) }) diff --git a/src/state/queries/activity-subscriptions.ts b/src/state/queries/activity-subscriptions.ts index 5b52fc7e16..d731d20f76 100644 --- a/src/state/queries/activity-subscriptions.ts +++ b/src/state/queries/activity-subscriptions.ts @@ -11,7 +11,9 @@ import { import {isRecordNotFoundError} from '#/lib/xrpc-error' import {useAppviewClient, usePdsClient, useSession} from '#/state/session' import * as Toast from '#/components/Toast' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyNotificationDeclaration from '#/lexicons/app/bsky/notification/declaration' +import * as AppBskyNotificationListActivitySubscriptions from '#/lexicons/app/bsky/notification/listActivitySubscriptions' export const RQKEY_getActivitySubscriptions = ['activity-subscriptions'] export const RQKEY_getNotificationDeclaration = ['notification-declaration'] @@ -22,10 +24,9 @@ export function useActivitySubscriptionsQuery() { return useInfiniteQuery({ queryKey: RQKEY_getActivitySubscriptions, queryFn: async ({pageParam}) => { - return await client.call( - app.bsky.notification.listActivitySubscriptions, - {cursor: pageParam}, - ) + return await client.call(AppBskyNotificationListActivitySubscriptions, { + cursor: pageParam, + }) }, initialPageParam: undefined as string | undefined, getNextPageParam: prev => prev.cursor, @@ -39,7 +40,7 @@ export function useNotificationDeclarationQuery() { queryKey: RQKEY_getNotificationDeclaration, queryFn: async () => { try { - const response = await client.get(app.bsky.notification.declaration, { + const response = await client.get(AppBskyNotificationDeclaration, { repo: currentAccount!.did, rkey: 'self', }) @@ -50,7 +51,7 @@ export function useNotificationDeclarationQuery() { value: { $type: 'app.bsky.notification.declaration', allowSubscriptions: 'followers', - } satisfies app.bsky.notification.declaration.Main, + } satisfies AppBskyNotificationDeclaration.Main, } } else { throw err @@ -65,9 +66,9 @@ export function useNotificationDeclarationMutation() { const {currentAccount} = useSession() const queryClient = useQueryClient() return useMutation({ - mutationFn: async (record: app.bsky.notification.declaration.Main) => { + mutationFn: async (record: AppBskyNotificationDeclaration.Main) => { const response = await client.put( - app.bsky.notification.declaration, + AppBskyNotificationDeclaration, record, { repo: currentAccount!.did, @@ -82,7 +83,7 @@ export function useNotificationDeclarationMutation() { (old?: { uri: string cid: string - value: app.bsky.notification.declaration.Main + value: AppBskyNotificationDeclaration.Main }) => { if (!old) return old return { @@ -103,9 +104,9 @@ export function useNotificationDeclarationMutation() { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: RQKEY_getActivitySubscriptions, }) diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index b84b5fabdd..d129fa7a92 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -6,7 +6,8 @@ import {isJustAMute, moduiContainsHideableOffense} from '#/lib/moderation' import {logger} from '#/logger' import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorSearchActorsTypeahead from '#/lexicons/app/bsky/actor/searchActorsTypeahead' import {useModerationOpts} from '../preferences/moderation-opts' import {DEFAULT_LOGGED_OUT_PREFERENCES} from './preferences' @@ -32,12 +33,12 @@ export function useActorAutocompleteQuery( prefix = prefix.slice(0, -1) } - return useQuery({ + return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(prefix || ''), async queryFn() { const data = prefix - ? await client.call(app.bsky.actor.searchActorsTypeahead, { + ? await client.call(AppBskyActorSearchActorsTypeahead, { q: prefix, limit: limit || 8, }) @@ -45,7 +46,7 @@ export function useActorAutocompleteQuery( return data?.actors || [] }, select: useCallback( - (data: app.bsky.actor.defs.ProfileViewBasic[]) => { + (data: AppBskyActorDefs.ProfileViewBasic[]) => { return computeSuggestions({ q: prefix, searched: data, @@ -74,7 +75,7 @@ export function useActorAutocompleteFn() { staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(query || ''), queryFn: () => - client.call(app.bsky.actor.searchActorsTypeahead, { + client.call(AppBskyActorSearchActorsTypeahead, { q: query, limit, }), @@ -102,10 +103,10 @@ function computeSuggestions({ moderationOpts, }: { q?: string - searched?: app.bsky.actor.defs.ProfileViewBasic[] + searched?: AppBskyActorDefs.ProfileViewBasic[] moderationOpts: ModerationOpts }) { - let items: app.bsky.actor.defs.ProfileViewBasic[] = [] + let items: AppBskyActorDefs.ProfileViewBasic[] = [] for (const item of searched) { if (!items.find(item2 => item2.handle === item.handle)) { items.push(item) diff --git a/src/state/queries/actor-search.ts b/src/state/queries/actor-search.ts index 547bf39b0f..b6202b14f0 100644 --- a/src/state/queries/actor-search.ts +++ b/src/state/queries/actor-search.ts @@ -8,7 +8,7 @@ import { import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyActorSearchActors from '#/lexicons/app/bsky/actor/searchActors' export const RQKEY_ROOT = 'actor-search' export const RQKEY = (query: string, limit?: number) => [ @@ -30,16 +30,16 @@ export function useActorSearch({ }) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.actor.searchActors.$OutputBody, + AppBskyActorSearchActors.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, string | undefined >({ staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(query, limit), queryFn: async ({pageParam}) => { - return await client.call(app.bsky.actor.searchActors, { + return await client.call(AppBskyActorSearchActors, { q: query, limit, cursor: pageParam, @@ -53,7 +53,7 @@ export function useActorSearch({ }) } -function select(data: InfiniteData) { +function select(data: InfiniteData) { // enforce uniqueness const dids = new Set() @@ -76,7 +76,7 @@ export function* findAllProfilesInQueryData( did: string, ) { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/actor-starter-packs.ts b/src/state/queries/actor-starter-packs.ts index cef91c6bd6..fbf220432c 100644 --- a/src/state/queries/actor-starter-packs.ts +++ b/src/state/queries/actor-starter-packs.ts @@ -2,7 +2,8 @@ import {type DidString} from '@atproto/syntax' import {type QueryClient, useInfiniteQuery} from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyGraphGetActorStarterPacks from '#/lexicons/app/bsky/graph/getActorStarterPacks' +import * as AppBskyGraphGetStarterPacksWithMembership from '#/lexicons/app/bsky/graph/getStarterPacksWithMembership' export const RQKEY_ROOT = 'actor-starter-packs' export const RQKEY_WITH_MEMBERSHIP_ROOT = 'actor-starter-packs-with-membership' @@ -24,7 +25,7 @@ export function useActorStarterPacksQuery({ return useInfiniteQuery({ queryKey: RQKEY(did), queryFn: async ({pageParam}: {pageParam?: string}) => { - return await client.call(app.bsky.graph.getActorStarterPacks, { + return await client.call(AppBskyGraphGetActorStarterPacks, { // the enabled flag prevents this from running until did is set actor: did! as DidString, limit: 10, @@ -49,7 +50,7 @@ export function useActorStarterPacksWithMembershipsQuery({ return useInfiniteQuery({ queryKey: RQKEY_WITH_MEMBERSHIP(did), queryFn: async ({pageParam}: {pageParam?: string}) => { - return await client.call(app.bsky.graph.getStarterPacksWithMembership, { + return await client.call(AppBskyGraphGetStarterPacksWithMembership, { // the enabled flag prevents this from running until did is set actor: did! as DidString, limit: 10, diff --git a/src/state/queries/app-passwords.ts b/src/state/queries/app-passwords.ts index 4403b1fbd4..ec404c0717 100644 --- a/src/state/queries/app-passwords.ts +++ b/src/state/queries/app-passwords.ts @@ -1,7 +1,9 @@ import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {STALE} from '#/state/queries' -import {com} from '#/lexicons' +import * as ComAtprotoServerCreateAppPassword from '#/lexicons/com/atproto/server/createAppPassword' +import * as ComAtprotoServerListAppPasswords from '#/lexicons/com/atproto/server/listAppPasswords' +import * as ComAtprotoServerRevokeAppPassword from '#/lexicons/com/atproto/server/revokeAppPassword' import {usePdsClient} from '../session' const RQKEY_ROOT = 'app-passwords' @@ -13,7 +15,7 @@ export function useAppPasswordsQuery() { staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(), queryFn: async () => { - const data = await client.call(com.atproto.server.listAppPasswords) + const data = await client.call(ComAtprotoServerListAppPasswords) return data.passwords }, }) @@ -23,12 +25,12 @@ export function useAppPasswordCreateMutation() { const queryClient = useQueryClient() const client = usePdsClient() return useMutation< - com.atproto.server.createAppPassword.$OutputBody, + ComAtprotoServerCreateAppPassword.$OutputBody, Error, {name: string; privileged: boolean} >({ mutationFn: async ({name, privileged}) => { - return await client.call(com.atproto.server.createAppPassword, { + return await client.call(ComAtprotoServerCreateAppPassword, { name, privileged, }) @@ -46,7 +48,7 @@ export function useAppPasswordDeleteMutation() { const client = usePdsClient() return useMutation({ mutationFn: async ({name}) => { - await client.call(com.atproto.server.revokeAppPassword, { + await client.call(ComAtprotoServerRevokeAppPassword, { name, }) }, diff --git a/src/state/queries/bookmarks/useBookmarkMutation.ts b/src/state/queries/bookmarks/useBookmarkMutation.ts index 4ba0d1d7f5..569e6046a6 100644 --- a/src/state/queries/bookmarks/useBookmarkMutation.ts +++ b/src/state/queries/bookmarks/useBookmarkMutation.ts @@ -9,10 +9,12 @@ import { optimisticallySaveBookmark, } from '#/state/queries/bookmarks/useBookmarksQuery' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyBookmarkCreateBookmark from '#/lexicons/app/bsky/bookmark/createBookmark' +import * as AppBskyBookmarkDeleteBookmark from '#/lexicons/app/bsky/bookmark/deleteBookmark' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' type MutationArgs = - | {action: 'create'; post: app.bsky.feed.defs.PostView} + | {action: 'create'; post: AppBskyFeedDefs.PostView} | { action: 'delete' /** @@ -30,13 +32,13 @@ export function useBookmarkMutation() { async mutationFn(args: MutationArgs) { if (args.action === 'create') { updatePostShadow(qc, args.post.uri, {bookmarked: true}) - await client.call(app.bsky.bookmark.createBookmark, { + await client.call(AppBskyBookmarkCreateBookmark, { uri: args.post.uri, cid: args.post.cid, }) } else if (args.action === 'delete') { updatePostShadow(qc, args.uri, {bookmarked: false}) - await client.call(app.bsky.bookmark.deleteBookmark, { + await client.call(AppBskyBookmarkDeleteBookmark, { uri: args.uri as AtUriString, }) } diff --git a/src/state/queries/bookmarks/useBookmarksQuery.ts b/src/state/queries/bookmarks/useBookmarksQuery.ts index 2eeab4c213..7623a2d070 100644 --- a/src/state/queries/bookmarks/useBookmarksQuery.ts +++ b/src/state/queries/bookmarks/useBookmarksQuery.ts @@ -13,7 +13,9 @@ import { getEmbeddedPost, } from '#/state/queries/util' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyBookmarkDefs from '#/lexicons/app/bsky/bookmark/defs' +import * as AppBskyBookmarkGetBookmarks from '#/lexicons/app/bsky/bookmark/getBookmarks' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' export const bookmarksQueryKeyRoot = 'bookmarks' @@ -23,15 +25,15 @@ export function useBookmarksQuery() { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.bookmark.getBookmarks.$OutputBody, + AppBskyBookmarkGetBookmarks.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, string | undefined >({ queryKey: createBookmarksQueryKey(), async queryFn({pageParam}) { - return await client.call(app.bsky.bookmark.getBookmarks, { + return await client.call(AppBskyBookmarkGetBookmarks, { cursor: pageParam, }) }, @@ -41,7 +43,7 @@ export function useBookmarksQuery() { } export async function truncateAndInvalidate(qc: QueryClient) { - qc.setQueriesData>( + qc.setQueriesData>( {queryKey: [bookmarksQueryKeyRoot]}, data => { if (data) { @@ -58,9 +60,9 @@ export async function truncateAndInvalidate(qc: QueryClient) { export async function optimisticallySaveBookmark( qc: QueryClient, - post: app.bsky.feed.defs.PostView, + post: AppBskyFeedDefs.PostView, ) { - qc.setQueriesData>( + qc.setQueriesData>( { queryKey: [bookmarksQueryKeyRoot], }, @@ -71,13 +73,13 @@ export async function optimisticallySaveBookmark( pages: data.pages.map((page, index) => { if (index === 0) { post.$type = 'app.bsky.feed.defs#postView' - const bookmark: app.bsky.bookmark.defs.BookmarkView = { + const bookmark: AppBskyBookmarkDefs.BookmarkView = { createdAt: toDatetimeString(new Date()), subject: { uri: post.uri, cid: post.cid, }, - item: post as $Typed, + item: post as $Typed, } return { ...page, @@ -95,7 +97,7 @@ export async function optimisticallyDeleteBookmark( qc: QueryClient, {uri}: {uri: string}, ) { - qc.setQueriesData>( + qc.setQueriesData>( { queryKey: [bookmarksQueryKeyRoot], }, @@ -117,9 +119,9 @@ export async function optimisticallyDeleteBookmark( export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [bookmarksQueryKeyRoot], }) @@ -131,7 +133,7 @@ export function* findAllPostsInQueryData( } for (const page of queryData?.pages) { for (const bookmark of page.bookmarks) { - if (!bsky.isType(app.bsky.feed.defs.postView, bookmark.item)) continue + if (!bsky.isType(AppBskyFeedDefs.postView, bookmark.item)) continue if (didOrHandleUriMatches(atUri, bookmark.item)) { yield bookmark.item diff --git a/src/state/queries/content-visibility.ts b/src/state/queries/content-visibility.ts index 6d53fdae7d..79e0192cfb 100644 --- a/src/state/queries/content-visibility.ts +++ b/src/state/queries/content-visibility.ts @@ -6,7 +6,7 @@ import {createQueryKey} from '#/state/queries/util' import {usePdsClient, useSession} from '#/state/session' import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyActorContentVisibilityDeclaration from '#/lexicons/app/bsky/actor/contentVisibilityDeclaration' export const contentVisibilityQueryKey = (did: string) => createQueryKey('content-visibility', {did}) @@ -21,18 +21,16 @@ export function useContentVisibilityQuery() { queryFn: async () => { try { const response = await client.get( - app.bsky.actor.contentVisibilityDeclaration, + AppBskyActorContentVisibilityDeclaration, { repo: did!, rkey: 'self', }, ) - return app.bsky.actor.contentVisibilityDeclaration.$parse( - response.value, - ) + return AppBskyActorContentVisibilityDeclaration.$parse(response.value) } catch (error) { if (isRecordNotFoundError(error)) { - return app.bsky.actor.contentVisibilityDeclaration.$build({ + return AppBskyActorContentVisibilityDeclaration.$build({ hideFromAlgorithmicRecommendations: false, }) } @@ -55,10 +53,10 @@ export function useContentVisibilityMutation() { mutationFn: async (hideFromAlgorithmicRecommendations: boolean) => { if (!did) throw new Error('Not signed in') - const record = app.bsky.actor.contentVisibilityDeclaration.$build({ + const record = AppBskyActorContentVisibilityDeclaration.$build({ hideFromAlgorithmicRecommendations, }) - await client.put(app.bsky.actor.contentVisibilityDeclaration, record, { + await client.put(AppBskyActorContentVisibilityDeclaration, record, { repo: did, rkey: 'self', }) @@ -67,12 +65,12 @@ export function useContentVisibilityMutation() { onMutate: async hideFromAlgorithmicRecommendations => { await queryClient.cancelQueries({queryKey}) const previous = - queryClient.getQueryData( + queryClient.getQueryData( queryKey, ) queryClient.setQueryData( queryKey, - app.bsky.actor.contentVisibilityDeclaration.$build({ + AppBskyActorContentVisibilityDeclaration.$build({ hideFromAlgorithmicRecommendations, }), ) diff --git a/src/state/queries/explore-feed-previews.tsx b/src/state/queries/explore-feed-previews.tsx index efe331af18..f3ca1a0049 100644 --- a/src/state/queries/explore-feed-previews.tsx +++ b/src/state/queries/explore-feed-previews.tsx @@ -25,7 +25,8 @@ import { getEmbeddedPost, } from '#/state/queries/util' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' const RQKEY_ROOT = 'feed-previews' @@ -83,7 +84,7 @@ export type FeedPreviewItem = | { type: 'preview:header' key: string - feed: app.bsky.feed.defs.GeneratorView + feed: AppBskyFeedDefs.GeneratorView } | { type: 'preview:footer' @@ -95,7 +96,7 @@ export type FeedPreviewItem = key: string slice: FeedPostSlice indexInSlice: number - feed: app.bsky.feed.defs.GeneratorView + feed: AppBskyFeedDefs.GeneratorView showReplyTo: boolean hideTopBorder: boolean } @@ -106,7 +107,7 @@ export type FeedPreviewItem = } export function useFeedPreviews( - feedsMaybeWithDuplicates: app.bsky.feed.defs.GeneratorView[], + feedsMaybeWithDuplicates: AppBskyFeedDefs.GeneratorView[], isEnabled: boolean = true, ) { const feeds = useMemo( @@ -128,8 +129,8 @@ export function useFeedPreviews( const processedPageCache = useRef( new Map< { - feed: app.bsky.feed.defs.GeneratorView - posts: app.bsky.feed.defs.FeedViewPost[] + feed: AppBskyFeedDefs.GeneratorView + posts: AppBskyFeedDefs.FeedViewPost[] }, FeedPreviewItem[] >(), @@ -347,13 +348,13 @@ export function useFeedPreviews( export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const atUri = new AtUri(uri) const queryDatas = queryClient.getQueriesData< InfiniteData<{ - feed: app.bsky.feed.defs.GeneratorView - posts: app.bsky.feed.defs.FeedViewPost[] + feed: AppBskyFeedDefs.GeneratorView + posts: AppBskyFeedDefs.FeedViewPost[] }> >({ queryKey: [RQKEY_ROOT], @@ -373,7 +374,7 @@ export function* findAllPostsInQueryData( yield embedViewRecordToPostView(quotedPost) } - if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.reply?.parent)) { if (didOrHandleUriMatches(atUri, item.reply.parent)) { yield item.reply.parent } @@ -387,7 +388,7 @@ export function* findAllPostsInQueryData( } } - if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.root)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.reply?.root)) { if (didOrHandleUriMatches(atUri, item.reply.root)) { yield item.reply.root } @@ -405,11 +406,11 @@ export function* findAllPostsInQueryData( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< InfiniteData<{ - feed: app.bsky.feed.defs.GeneratorView - posts: app.bsky.feed.defs.FeedViewPost[] + feed: AppBskyFeedDefs.GeneratorView + posts: AppBskyFeedDefs.FeedViewPost[] }> >({ queryKey: [RQKEY_ROOT], @@ -428,13 +429,13 @@ export function* findAllProfilesInQueryData( yield quotedPost.author } if ( - bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent) && + bsky.isType(AppBskyFeedDefs.postView, item.reply?.parent) && item.reply?.parent?.author.did === did ) { yield item.reply.parent.author } if ( - bsky.isType(app.bsky.feed.defs.postView, item.reply?.root) && + bsky.isType(AppBskyFeedDefs.postView, item.reply?.root) && item.reply?.root?.author.did === did ) { yield item.reply.root.author diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts index e3b99846fc..2a15fc4e2a 100644 --- a/src/state/queries/feed.ts +++ b/src/state/queries/feed.ts @@ -21,7 +21,13 @@ import {RQKEY as listQueryKey} from '#/state/queries/list' import {usePreferencesQuery} from '#/state/queries/preferences' import {createQueryKey} from '#/state/queries/util' import {useAppviewClient, useSession} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetFeedGenerator from '#/lexicons/app/bsky/feed/getFeedGenerator' +import * as AppBskyFeedGetFeedGenerators from '#/lexicons/app/bsky/feed/getFeedGenerators' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetList from '#/lexicons/app/bsky/graph/getList' +import * as AppBskyUnspeccedGetPopularFeedGenerators from '#/lexicons/app/bsky/unspecced/getPopularFeedGenerators' import {router} from '#/routes' import {useModerationOpts} from '../preferences/moderation-opts' import {type FeedDescriptor} from './post-feed' @@ -29,7 +35,7 @@ import {precacheResolvedUri} from './resolve-uri' export type FeedSourceFeedInfo = { type: 'feed' - view?: app.bsky.feed.defs.GeneratorView + view?: AppBskyFeedDefs.GeneratorView uri: string feedDescriptor: FeedDescriptor route: { @@ -46,12 +52,12 @@ export type FeedSourceFeedInfo = { likeCount: number | undefined acceptsInteractions?: boolean likeUri: string | undefined - contentMode: app.bsky.feed.defs.GeneratorView['contentMode'] + contentMode: AppBskyFeedDefs.GeneratorView['contentMode'] } export type FeedSourceListInfo = { type: 'list' - view?: app.bsky.graph.defs.ListView + view?: AppBskyGraphDefs.ListView uri: string feedDescriptor: FeedDescriptor route: { @@ -88,7 +94,7 @@ const feedSourceNSIDs = { } export function hydrateFeedGenerator( - view: app.bsky.feed.defs.GeneratorView, + view: AppBskyFeedDefs.GeneratorView, ): FeedSourceInfo { const urip = new AtUri(view.uri) const collection = @@ -130,9 +136,7 @@ export function hydrateFeedGenerator( } } -export function hydrateList( - view: app.bsky.graph.defs.ListView, -): FeedSourceInfo { +export function hydrateList(view: AppBskyGraphDefs.ListView): FeedSourceInfo { const urip = new AtUri(view.uri) const collection = urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'lists' @@ -190,12 +194,12 @@ export function useFeedSourceInfoQuery({uri}: {uri: string}) { let view: FeedSourceInfo if (type === 'feed') { - const data = await client.call(app.bsky.feed.getFeedGenerator, { + const data = await client.call(AppBskyFeedGetFeedGenerator, { feed: uri as AtUriString, }) view = hydrateFeedGenerator(data.view) } else { - const data = await client.call(app.bsky.graph.getList, { + const data = await client.call(AppBskyGraphGetList, { list: uri as AtUriString, limit: 1, }) @@ -254,13 +258,10 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) { enabled: Boolean(moderationOpts) && options?.enabled !== false, queryKey: createGetPopularFeedsQueryKey(options), queryFn: async ({pageParam}) => { - const data = await client.call( - app.bsky.unspecced.getPopularFeedGenerators, - { - limit, - cursor: pageParam, - }, - ) + const data = await client.call(AppBskyUnspeccedGetPopularFeedGenerators, { + limit, + cursor: pageParam, + }) // precache feeds for (const feed of data.feeds) { @@ -274,7 +275,7 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) { getNextPageParam: lastPage => lastPage.cursor, select: useCallback( ( - data: InfiniteData, + data: InfiniteData, ) => { const { savedFeeds, @@ -343,13 +344,10 @@ export function useSearchPopularFeedsMutation() { return useMutation({ mutationFn: async (query: string) => { - const data = await client.call( - app.bsky.unspecced.getPopularFeedGenerators, - { - limit: 10, - query: query, - }, - ) + const data = await client.call(AppBskyUnspeccedGetPopularFeedGenerators, { + limit: 10, + query: query, + }) if (moderationOpts) { return data.feeds.filter(feed => { @@ -384,14 +382,11 @@ export function usePopularFeedsSearch({ enabled: enabledInner, queryKey: createPopularFeedsSearchQueryKey(query), queryFn: async ({pageParam}) => { - const data = await client.call( - app.bsky.unspecced.getPopularFeedGenerators, - { - limit: 15, - query: query, - cursor: pageParam, - }, - ) + const data = await client.call(AppBskyUnspeccedGetPopularFeedGenerators, { + limit: 15, + query: query, + cursor: pageParam, + }) return data }, @@ -414,7 +409,7 @@ export function usePopularFeedsSearch({ } export type SavedFeedSourceInfo = FeedSourceInfo & { - savedFeed: app.bsky.actor.defs.SavedFeed + savedFeed: AppBskyActorDefs.SavedFeed } const PWI_DISCOVER_FEED_STUB: SavedFeedSourceInfo = { @@ -485,7 +480,7 @@ export function usePinnedFeedsInfos() { let feedsPromise = Promise.resolve() if (pinnedFeeds.length > 0) { feedsPromise = client - .call(app.bsky.feed.getFeedGenerators, { + .call(AppBskyFeedGetFeedGenerators, { feeds: pinnedFeeds.map(f => f.value as AtUriString), }) .then(data => { @@ -500,7 +495,7 @@ export function usePinnedFeedsInfos() { const pinnedLists = pinnedItems.filter(feed => feed.type === 'list') const listsPromises = pinnedLists.map(list => client - .call(app.bsky.graph.getList, { + .call(AppBskyGraphGetList, { list: list.value as AtUriString, limit: 1, }) @@ -553,17 +548,17 @@ export function usePinnedFeedsInfos() { export type SavedFeedItem = | { type: 'feed' - config: app.bsky.actor.defs.SavedFeed - view: app.bsky.feed.defs.GeneratorView + config: AppBskyActorDefs.SavedFeed + view: AppBskyFeedDefs.GeneratorView } | { type: 'list' - config: app.bsky.actor.defs.SavedFeed - view: app.bsky.graph.defs.ListView + config: AppBskyActorDefs.SavedFeed + view: AppBskyGraphDefs.ListView } | { type: 'timeline' - config: app.bsky.actor.defs.SavedFeed + config: AppBskyActorDefs.SavedFeed view: undefined } @@ -591,8 +586,8 @@ export function useSavedFeeds() { ) }, queryFn: async () => { - const resolvedFeeds = new Map() - const resolvedLists = new Map() + const resolvedFeeds = new Map() + const resolvedLists = new Map() const savedFeeds = savedItems.filter(feed => feed.type === 'feed') const savedLists = savedItems.filter(feed => feed.type === 'list') @@ -600,7 +595,7 @@ export function useSavedFeeds() { let feedsPromise = Promise.resolve() if (savedFeeds.length > 0) { feedsPromise = client - .call(app.bsky.feed.getFeedGenerators, { + .call(AppBskyFeedGetFeedGenerators, { feeds: savedFeeds.map(f => f.value as AtUriString), }) .then(data => { @@ -612,7 +607,7 @@ export function useSavedFeeds() { const listsPromises = savedLists.map(list => client - .call(app.bsky.graph.getList, { + .call(AppBskyGraphGetList, { list: list.value as AtUriString, limit: 1, }) @@ -683,7 +678,7 @@ export function useFeedInfo(feedUri: string | undefined) { return null } - const data = await client.call(app.bsky.feed.getFeedGenerator, { + const data = await client.call(AppBskyFeedGetFeedGenerator, { feed: feedUri as AtUriString, }) @@ -707,10 +702,10 @@ function precacheFeed(queryClient: QueryClient, hydratedFeed: FeedSourceInfo) { export function precacheList( queryClient: QueryClient, - list: app.bsky.graph.defs.ListView, + list: AppBskyGraphDefs.ListView, ) { precacheResolvedUri(queryClient, list.creator.handle, list.creator.did) - queryClient.setQueryData( + queryClient.setQueryData( listQueryKey(list.uri), list, ) @@ -718,7 +713,7 @@ export function precacheList( export function precacheFeedFromGeneratorView( queryClient: QueryClient, - view: app.bsky.feed.defs.GeneratorView, + view: AppBskyFeedDefs.GeneratorView, ) { const hydratedFeed = hydrateFeedGenerator(view) precacheFeed(queryClient, hydratedFeed) diff --git a/src/state/queries/find-contacts.ts b/src/state/queries/find-contacts.ts index e462e6a6c1..6304ddfe0d 100644 --- a/src/state/queries/find-contacts.ts +++ b/src/state/queries/find-contacts.ts @@ -7,7 +7,8 @@ import { import {useAppviewClient} from '#/state/session' import {type Match} from '#/components/contacts/state' -import {app} from '#/lexicons' +import * as AppBskyContactGetMatches from '#/lexicons/app/bsky/contact/getMatches' +import * as AppBskyContactGetSyncStatus from '#/lexicons/app/bsky/contact/getSyncStatus' import type * as bsky from '#/types/bsky' import {STALE} from '.' @@ -20,7 +21,7 @@ export function useContactsSyncStatusQuery() { return useQuery({ queryKey: findContactsStatusQueryKey, queryFn: async () => { - return await client.call(app.bsky.contact.getSyncStatus, {}) + return await client.call(AppBskyContactGetSyncStatus, {}) }, staleTime: STALE.SECONDS.THIRTY, }) @@ -34,7 +35,7 @@ export function useContactsMatchesQuery() { return useInfiniteQuery({ queryKey: findContactsGetMatchesQueryKey, queryFn: async ({pageParam}) => { - return await client.call(app.bsky.contact.getMatches, { + return await client.call(AppBskyContactGetMatches, { cursor: pageParam, }) }, @@ -45,19 +46,20 @@ export function useContactsMatchesQuery() { } export function optimisticRemoveMatch(queryClient: QueryClient, did: string) { - queryClient.setQueryData< - InfiniteData - >(findContactsGetMatchesQueryKey, old => { - if (!old) return old + queryClient.setQueryData>( + findContactsGetMatchesQueryKey, + old => { + if (!old) return old - return { - ...old, - pages: old.pages.map(page => ({ - ...page, - matches: page.matches.filter(match => match.did !== did), - })), - } - }) + return { + ...old, + pages: old.pages.map(page => ({ + ...page, + matches: page.matches.filter(match => match.did !== did), + })), + } + }, + ) } export const findContactsMatchesPassthroughQueryKey = (dids: string[]) => [ @@ -92,7 +94,7 @@ export function* findAllProfilesInQueryData( did: string, ): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: findContactsGetMatchesQueryKey, }) diff --git a/src/state/queries/handle-availability.ts b/src/state/queries/handle-availability.ts index ab6a2e985b..b07a023494 100644 --- a/src/state/queries/handle-availability.ts +++ b/src/state/queries/handle-availability.ts @@ -10,7 +10,8 @@ import {useDebouncedValue} from '#/lib/hooks/useDebouncedValue' import {createServiceClient} from '#/lib/lexClient' import {createFullHandle} from '#/lib/strings/handles' import {useAnalytics} from '#/analytics' -import {com} from '#/lexicons' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' +import * as ComAtprotoTempCheckHandleAvailability from '#/lexicons/com/atproto/temp/checkHandleAvailability' import * as bsky from '#/types/bsky' export const RQKEY_handleAvailability = ( @@ -88,7 +89,7 @@ export async function checkHandleAvailability( */ const client = createServiceClient(BSKY_SERVICE) // entryway has a special API for handle availability - const data = await client.call(com.atproto.temp.checkHandleAvailability, { + const data = await client.call(ComAtprotoTempCheckHandleAvailability, { // the caller assembles this from a validated username and domain handle: handle as HandleString, // callers pass an ISO date string built from the birth-date picker @@ -98,14 +99,14 @@ export async function checkHandleAvailability( if ( bsky.isType( - com.atproto.temp.checkHandleAvailability.resultAvailable, + ComAtprotoTempCheckHandleAvailability.resultAvailable, data.result, ) ) { return {available: true} as const } else if ( bsky.isType( - com.atproto.temp.checkHandleAvailability.resultUnavailable, + ComAtprotoTempCheckHandleAvailability.resultUnavailable, data.result, ) ) { @@ -126,7 +127,7 @@ export async function checkHandleAvailability( */ const client = createServiceClient(PUBLIC_BSKY_SERVICE) try { - const data = await client.call(com.atproto.identity.resolveHandle, { + const data = await client.call(ComAtprotoIdentityResolveHandle, { handle: handle as HandleString, }) diff --git a/src/state/queries/handle.ts b/src/state/queries/handle.ts index 0aa0160158..c759ade60d 100644 --- a/src/state/queries/handle.ts +++ b/src/state/queries/handle.ts @@ -4,7 +4,9 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {STALE} from '#/state/queries' import {useAppviewClient, usePdsClient} from '#/state/session' -import {app, com} from '#/lexicons' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' +import * as ComAtprotoIdentityUpdateHandle from '#/lexicons/com/atproto/identity/updateHandle' const handleQueryKeyRoot = 'handle' const fetchHandleQueryKey = (handleOrDid: string) => [ @@ -25,7 +27,7 @@ export function useFetchHandle() { staleTime: STALE.MINUTES.FIVE, queryKey: fetchHandleQueryKey(handleOrDid), queryFn: () => - client.call(app.bsky.actor.getProfile, { + client.call(AppBskyActorGetProfile, { actor: handleOrDid as DidString, }), }) @@ -45,7 +47,7 @@ export function useUpdateHandleMutation(opts?: { return useMutation({ mutationFn: async ({handle}: {handle: string}) => { - await client.call(com.atproto.identity.updateHandle, { + await client.call(ComAtprotoIdentityUpdateHandle, { // callers validate the handle before submitting handle: handle as HandleString, }) @@ -71,7 +73,7 @@ export function useFetchDid() { queryFn: async () => { let identifier = handleOrDid if (!identifier.startsWith('did:')) { - const data = await client.call(com.atproto.identity.resolveHandle, { + const data = await client.call(ComAtprotoIdentityResolveHandle, { handle: identifier as HandleString, }) identifier = data.did diff --git a/src/state/queries/join-links.ts b/src/state/queries/join-links.ts index dee7f4d379..b91adcd585 100644 --- a/src/state/queries/join-links.ts +++ b/src/state/queries/join-links.ts @@ -9,7 +9,8 @@ import {logger} from '#/logger' import {STALE} from '#/state/queries/index' import {createQueryKey, type StructuredQueryKey} from '#/state/queries/util' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' +import * as ChatBskyGroupGetJoinLinkPreviews from '#/lexicons/chat/bsky/group/getJoinLinkPreviews' import * as bsky from '#/types/bsky' /** @@ -18,9 +19,9 @@ import * as bsky from '#/types/bsky' * `ChatInvitePreview` for that. */ export type KnownChatInvitePreview = - | $Typed - | $Typed - | $Typed + | $Typed + | $Typed + | $Typed /** * The full open-union shape, including lex's `Unknown$TypedObject` fallback for @@ -36,9 +37,9 @@ export function isKnownJoinLinkPreview( preview: unknown, ): preview is KnownChatInvitePreview { return ( - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) || - bsky.isType(chat.bsky.group.defs.disabledJoinLinkPreviewView, preview) || - bsky.isType(chat.bsky.group.defs.invalidJoinLinkPreviewView, preview) + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview) || + bsky.isType(ChatBskyGroupDefs.disabledJoinLinkPreviewView, preview) || + bsky.isType(ChatBskyGroupDefs.invalidJoinLinkPreviewView, preview) ) } @@ -87,7 +88,7 @@ export function setJoinLinkPreviewRequestedForCode( code: string, requested: boolean, ) { - queryClient.setQueriesData( + queryClient.setQueriesData( { predicate: query => { const [root, args] = query.queryKey as Partial< @@ -106,7 +107,7 @@ export function setJoinLinkPreviewRequestedForCode( ...old, joinLinkPreviews: old.joinLinkPreviews.map(preview => { if ( - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) && + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview) && preview.code === code ) { return { @@ -142,11 +143,11 @@ export function invalidateJoinLinkPreviewsForConvo( const [root] = query.queryKey if (root !== joinLinkPreviewQueryKeyRoot) return false const data = query.state.data as - chat.bsky.group.getJoinLinkPreviews.$OutputBody | undefined + ChatBskyGroupGetJoinLinkPreviews.$OutputBody | undefined return ( data?.joinLinkPreviews.some( preview => - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) && + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, preview) && preview.convoId === convoId, ) ?? false ) @@ -184,7 +185,7 @@ async function fetchJoinLinkPreviews({ hasSession: boolean }) { return await (hasSession ? client : getPublicChatClient()).call( - chat.bsky.group.getJoinLinkPreviews, + ChatBskyGroupGetJoinLinkPreviews, {codes}, ) } @@ -202,7 +203,7 @@ export function useJoinLinkPreviewsQuery({ * Seed the query with an already-known preview (e.g. a DM message embed * already carries the resolved view), avoiding a duplicate fetch. */ - initialData?: chat.bsky.group.getJoinLinkPreviews.$OutputBody + initialData?: ChatBskyGroupGetJoinLinkPreviews.$OutputBody }) { const client = useChatClient() diff --git a/src/state/queries/known-followers.ts b/src/state/queries/known-followers.ts index d7e1fdb1ba..f54e47d3ec 100644 --- a/src/state/queries/known-followers.ts +++ b/src/state/queries/known-followers.ts @@ -7,7 +7,8 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetKnownFollowers from '#/lexicons/app/bsky/graph/getKnownFollowers' const PAGE_SIZE = 50 type RQPageParam = string | undefined @@ -18,15 +19,15 @@ export const RQKEY = (did: string) => [RQKEY_ROOT, did] export function useProfileKnownFollowersQuery(did: string | undefined) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getKnownFollowers.$OutputBody, + AppBskyGraphGetKnownFollowers.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(did || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.graph.getKnownFollowers, { + return await client.call(AppBskyGraphGetKnownFollowers, { // the enabled flag prevents this from running until did is set actor: did! as DidString, limit: PAGE_SIZE, @@ -42,9 +43,9 @@ export function useProfileKnownFollowersQuery(did: string | undefined) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/labeler.ts b/src/state/queries/labeler.ts index 6d26c92c57..b0bd953c7b 100644 --- a/src/state/queries/labeler.ts +++ b/src/state/queries/labeler.ts @@ -11,7 +11,9 @@ import { } from '#/state/queries/preferences' import {createQueryKey} from '#/state/queries/util' import {useAppviewClient, usePdsClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyActorGetProfiles from '#/lexicons/app/bsky/actor/getProfiles' +import type * as AppBskyLabelerDefs from '#/lexicons/app/bsky/labeler/defs' +import * as AppBskyLabelerGetServices from '#/lexicons/app/bsky/labeler/getServices' const labelerInfoQueryKeyRoot = 'labeler-info' export const labelerInfoQueryKey = (did: string) => [ @@ -40,11 +42,11 @@ export function useLabelerInfoQuery({ enabled: !!did && enabled !== false, queryKey: labelerInfoQueryKey(did as string), queryFn: async () => { - const res = await client.call(app.bsky.labeler.getServices, { + const res = await client.call(AppBskyLabelerGetServices, { dids: [did! as DidString], detailed: true, }) - return res.views[0] as app.bsky.labeler.defs.LabelerViewDetailed + return res.views[0] as AppBskyLabelerDefs.LabelerViewDetailed }, }) } @@ -55,10 +57,10 @@ export function useLabelersInfoQuery({dids}: {dids: string[]}) { enabled: !!dids.length, queryKey: labelersInfoQueryKey(dids), queryFn: async () => { - const res = await client.call(app.bsky.labeler.getServices, { + const res = await client.call(AppBskyLabelerGetServices, { dids: dids as DidString[], }) - return res.views as app.bsky.labeler.defs.LabelerView[] + return res.views as AppBskyLabelerDefs.LabelerView[] }, }) } @@ -71,11 +73,11 @@ export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { gcTime: GCTIME.INFINITY, staleTime: STALE.MINUTES.ONE, queryFn: async () => { - const res = await client.call(app.bsky.labeler.getServices, { + const res = await client.call(AppBskyLabelerGetServices, { dids: dids as DidString[], detailed: true, }) - return res.views as app.bsky.labeler.defs.LabelerViewDetailed[] + return res.views as AppBskyLabelerDefs.LabelerViewDetailed[] }, }) } @@ -126,7 +128,7 @@ export function useLabelerSubscriptionMutation() { ).map(l => l.did) const invalidLabelers: DidString[] = [] if (labelerDids.length) { - const profiles = await appviewClient.call(app.bsky.actor.getProfiles, { + const profiles = await appviewClient.call(AppBskyActorGetProfiles, { actors: labelerDids, }) if (profiles) { diff --git a/src/state/queries/list-members.ts b/src/state/queries/list-members.ts index 1d76296623..db69008587 100644 --- a/src/state/queries/list-members.ts +++ b/src/state/queries/list-members.ts @@ -10,7 +10,9 @@ import { import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetList from '#/lexicons/app/bsky/graph/getList' const PAGE_SIZE = 30 type RQPageParam = string | undefined @@ -23,16 +25,16 @@ export const RQKEY_ALL = (uri: string) => [RQKEY_ROOT_ALL, uri] export function useListMembersQuery(uri?: string, limit: number = PAGE_SIZE) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getList.$OutputBody, + AppBskyGraphGetList.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(uri ?? ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.graph.getList, { + return await client.call(AppBskyGraphGetList, { // the enabled flag will prevent this from running until uri is set list: uri! as AtUriString, limit, @@ -60,11 +62,11 @@ export function useAllListMembersQuery(uri?: string) { export async function getAllListMembers(client: Client, uri: string) { let hasMore = true let cursor: string | undefined - const listItems: app.bsky.graph.defs.ListItemView[] = [] + const listItems: AppBskyGraphDefs.ListItemView[] = [] // We want to cap this at 6 pages, just for anything weird happening with the api let i = 0 while (hasMore && i < 6) { - const res = await client.call(app.bsky.graph.getList, { + const res = await client.call(AppBskyGraphGetList, { list: uri as AtUriString, limit: 50, cursor, @@ -90,9 +92,9 @@ export async function invalidateListMembersQuery({ export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) @@ -113,7 +115,7 @@ export function* findAllProfilesInQueryData( } const allQueryData = queryClient.getQueriesData< - app.bsky.graph.defs.ListItemView[] + AppBskyGraphDefs.ListItemView[] >({ queryKey: [RQKEY_ROOT_ALL], }) diff --git a/src/state/queries/list-memberships.ts b/src/state/queries/list-memberships.ts index 01bc795a31..9bb6a06637 100644 --- a/src/state/queries/list-memberships.ts +++ b/src/state/queries/list-memberships.ts @@ -15,7 +15,9 @@ import { RQKEY_ALL as LIST_MEMBERS_ALL_RQKEY, } from '#/state/queries/list-members' import {usePdsClient, useSession} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyGraphGetStarterPacksWithMembership from '#/lexicons/app/bsky/graph/getStarterPacksWithMembership' +import * as AppBskyGraphListitem from '#/lexicons/app/bsky/graph/listitem' import type * as bsky from '#/types/bsky' import {RQKEY_WITH_MEMBERSHIP as STARTER_PACKS_WITH_MEMBERSHIPS_RKEY} from './actor-starter-packs' @@ -47,7 +49,7 @@ export function useListMembershipAddMutation({ * The mutation takes the list uri and actor did as plain strings, so they * are asserted to their branded forms here. */ - const res = await pdsClient.create(app.bsky.graph.listitem, { + const res = await pdsClient.create(AppBskyGraphListitem, { subject: actorDid as DidString, list: listUri as AtUriString, createdAt: toDatetimeString(new Date()), @@ -69,7 +71,7 @@ export function useListMembershipAddMutation({ // update WITH_MEMBERSHIPS query for starter packs if (subject) { queryClient.setQueryData< - InfiniteData + InfiniteData >(STARTER_PACKS_WITH_MEMBERSHIPS_RKEY(variables.actorDid), old => { if (!old) return old @@ -90,7 +92,7 @@ export function useListMembershipAddMutation({ listItemsSample: [ { uri: data.uri, - subject: subject as app.bsky.actor.defs.ProfileView, + subject: subject as AppBskyActorDefs.ProfileView, }, ...(spWithMembership.starterPack.listItemsSample?.filter( item => item.subject.did !== variables.actorDid, @@ -105,7 +107,7 @@ export function useListMembershipAddMutation({ }, listItem: { uri: data.uri, - subject: subject as app.bsky.actor.defs.ProfileView, + subject: subject as AppBskyActorDefs.ProfileView, }, } } @@ -144,7 +146,7 @@ export function useListMembershipRemoveMutation({ throw new Error('Not signed in') } const membershipUrip = new AtUri(membershipUri) - await pdsClient.delete(app.bsky.graph.listitem, { + await pdsClient.delete(AppBskyGraphListitem, { repo: currentAccount.did, rkey: membershipUrip.rkeySafe, }) @@ -163,7 +165,7 @@ export function useListMembershipRemoveMutation({ // update WITH_MEMBERSHIPS query for starter packs queryClient.setQueryData< - InfiniteData + InfiniteData >(STARTER_PACKS_WITH_MEMBERSHIPS_RKEY(variables.actorDid), old => { if (!old) return old diff --git a/src/state/queries/list.ts b/src/state/queries/list.ts index bd29d578dc..265578c066 100644 --- a/src/state/queries/list.ts +++ b/src/state/queries/list.ts @@ -14,7 +14,13 @@ import {until} from '#/lib/async/until' import {type ImageMeta} from '#/state/gallery' import {STALE} from '#/state/queries' import {useAppviewClient, usePdsClient, useSession} from '#/state/session' -import {app, com} from '#/lexicons' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetList from '#/lexicons/app/bsky/graph/getList' +import * as AppBskyGraphList from '#/lexicons/app/bsky/graph/list' +import * as AppBskyGraphListitem from '#/lexicons/app/bsky/graph/listitem' +import type * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import {FEED_INFO_RQKEY_ROOT} from './feed' import {invalidate as invalidateMyLists} from './my-lists' import {RQKEY as PROFILE_LISTS_RQKEY} from './profile-lists' @@ -24,14 +30,14 @@ export const RQKEY = (uri: string) => [RQKEY_ROOT, uri] export function useListQuery(uri?: string) { const client = useAppviewClient() - return useQuery({ + return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(uri || ''), async queryFn() { if (!uri) { throw new Error('URI not provided') } - const res = await client.call(app.bsky.graph.getList, { + const res = await client.call(AppBskyGraphGetList, { list: uri as AtUriString, limit: 1, }) @@ -45,7 +51,7 @@ export interface ListCreateMutateParams { purpose: string name: string description: string - descriptionFacets: app.bsky.richtext.facet.Main[] | undefined + descriptionFacets: AppBskyRichtextFacet.Main[] | undefined avatar: ImageMeta | null | undefined } export function useListCreateMutation() { @@ -71,7 +77,7 @@ export function useListCreateMutation() { ) { throw new Error('Invalid list purpose: must be curatelist or modlist') } - const record: Omit = { + const record: Omit = { purpose, name, description, @@ -83,7 +89,7 @@ export function useListCreateMutation() { const blobRes = await uploadBlob(pdsClient, avatar.path, avatar.mime) record.avatar = blobRes.blob } - const res = await pdsClient.create(app.bsky.graph.list, record) + const res = await pdsClient.create(AppBskyGraphList, record) // wait for the appview to update await whenAppViewReady(appviewClient, res.uri, v => { @@ -105,7 +111,7 @@ export interface ListMetadataMutateParams { uri: string name: string description: string - descriptionFacets: app.bsky.richtext.facet.Main[] | undefined + descriptionFacets: AppBskyRichtextFacet.Main[] | undefined avatar: ImageMeta | null | undefined } export function useListMetadataMutation() { @@ -128,7 +134,7 @@ export function useListMetadataMutation() { } // get the current record - const {value: record} = await pdsClient.get(app.bsky.graph.list, { + const {value: record} = await pdsClient.get(AppBskyGraphList, { repo: currentAccount.did, rkey, }) @@ -143,7 +149,7 @@ export function useListMetadataMutation() { } else if (avatar === null) { record.avatar = undefined } - const res = await pdsClient.call(com.atproto.repo.putRecord, { + const res = await pdsClient.call(ComAtprotoRepoPutRecord, { repo: currentAccount.did, collection: 'app.bsky.graph.list', rkey, @@ -188,7 +194,7 @@ export function useListDeleteMutation() { let cursor: string | undefined let listitemRecordUris: string[] = [] for (let i = 0; i < 100; i++) { - const res = await pdsClient.list(app.bsky.graph.listitem, { + const res = await pdsClient.list(AppBskyGraphListitem, { repo: currentAccount.did, cursor, limit: 100, @@ -207,7 +213,7 @@ export function useListDeleteMutation() { // batch delete the list and listitem records const createDel = ( uri: string, - ): $Typed => { + ): $Typed => { const urip = new AtUri(uri) return { $type: 'com.atproto.repo.applyWrites#delete', @@ -221,7 +227,7 @@ export function useListDeleteMutation() { // apply in chunks for (const writesChunk of chunk(writes, 10)) { - await pdsClient.call(com.atproto.repo.applyWrites, { + await pdsClient.call(ComAtprotoRepoApplyWrites, { repo: currentAccount.did, writes: writesChunk, }) @@ -299,14 +305,14 @@ export function useListBlockMutation() { async function whenAppViewReady( client: Client, uri: string, - fn: (res: app.bsky.graph.getList.$OutputBody) => boolean, + fn: (res: AppBskyGraphGetList.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - client.call(app.bsky.graph.getList, { + client.call(AppBskyGraphGetList, { list: uri as AtUriString, limit: 1, }), diff --git a/src/state/queries/lists-with-membership.ts b/src/state/queries/lists-with-membership.ts index 1ef035c24a..70e6780fc7 100644 --- a/src/state/queries/lists-with-membership.ts +++ b/src/state/queries/lists-with-membership.ts @@ -8,10 +8,11 @@ import { import {createQueryKey} from '#/state/queries/util' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetListsWithMembership from '#/lexicons/app/bsky/graph/getListsWithMembership' export type ListWithMembership = - app.bsky.graph.getListsWithMembership.ListWithMembership + AppBskyGraphGetListsWithMembership.ListWithMembership const listsWithMembershipQueryKeyRoot = 'lists-with-membership' export const createListsWithMembershipQueryKey = (args: {actor: string}) => @@ -27,15 +28,15 @@ export function useListsWithMembershipQuery({ const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getListsWithMembership.$OutputBody, + AppBskyGraphGetListsWithMembership.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, string | undefined >({ queryKey: createListsWithMembershipQueryKey({actor: actor ?? ''}), queryFn: async ({pageParam}: {pageParam?: string}) => { - return await client.call(app.bsky.graph.getListsWithMembership, { + return await client.call(AppBskyGraphGetListsWithMembership, { // the enabled flag prevents this from running until actor is set actor: actor! as AtIdentifierString, limit: 50, @@ -59,10 +60,10 @@ export function updateListMembershipOptimistically({ actor: string listUri: string membershipUri: string - subject: app.bsky.actor.defs.ProfileView + subject: AppBskyActorDefs.ProfileView }) { queryClient.setQueryData< - InfiniteData + InfiniteData >(createListsWithMembershipQueryKey({actor}), old => { if (!old) return old @@ -98,7 +99,7 @@ export function removeListMembershipOptimistically({ listUri: string }) { queryClient.setQueryData< - InfiniteData + InfiniteData >(createListsWithMembershipQueryKey({actor}), old => { if (!old) return old diff --git a/src/state/queries/messages/accept-conversation.ts b/src/state/queries/messages/accept-conversation.ts index f059322f7c..a3a2a57fc9 100644 --- a/src/state/queries/messages/accept-conversation.ts +++ b/src/state/queries/messages/accept-conversation.ts @@ -2,7 +2,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoAcceptConvo from '#/lexicons/chat/bsky/convo/acceptConvo' +import type * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' import { type ConvoRequestListQueryData, optimisticDelete as optimisticDeleteRequest, @@ -25,7 +26,7 @@ export function useAcceptConversation( onError, }: { onMutate?: () => void - onSuccess?: (data: chat.bsky.convo.acceptConvo.$OutputBody) => void + onSuccess?: (data: ChatBskyConvoAcceptConvo.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -34,7 +35,7 @@ export function useAcceptConversation( return useMutation({ mutationFn: async () => { - return await client.call(chat.bsky.convo.acceptConvo, {convoId}) + return await client.call(ChatBskyConvoAcceptConvo, {convoId}) }, onMutate: () => { // snapshot every convo-list cache up front so onError can restore them @@ -43,7 +44,7 @@ export function useAcceptConversation( queryClient.getQueriesData({ queryKey: [CONVO_LIST_ROOT_KEY], }) - let convoBeingAccepted: chat.bsky.convo.defs.ConvoView | null = null + let convoBeingAccepted: ChatBskyConvoDefs.ConvoView | null = null for (const [_key, data] of queryClient.getQueriesData( {queryKey: CONVO_LIST_PARTIAL_KEY('request')}, )) { @@ -56,7 +57,7 @@ export function useAcceptConversation( (old?: ConvoListQueryData) => optimisticDelete(convoId, old), ) if (convoBeingAccepted) { - const acceptedConvo: chat.bsky.convo.defs.ConvoView = { + const acceptedConvo: ChatBskyConvoDefs.ConvoView = { ...convoBeingAccepted, status: 'accepted', } diff --git a/src/state/queries/messages/actor-declaration.ts b/src/state/queries/messages/actor-declaration.ts index e581040ce9..5eb3bf5751 100644 --- a/src/state/queries/messages/actor-declaration.ts +++ b/src/state/queries/messages/actor-declaration.ts @@ -5,7 +5,10 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {usePdsClient, useSession} from '#/state/session' import {resolveAllowGroupInvites} from '#/components/dms/util' -import {type app, chat, com} from '#/lexicons' +import {type app} from '#/lexicons' +import * as ChatBskyActorDeclaration from '#/lexicons/chat/bsky/actor/declaration' +import * as ComAtprotoRepoDeleteRecord from '#/lexicons/com/atproto/repo/deleteRecord' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import {RQKEY as PROFILE_RKEY} from '../profile' export function useUpdateActorDeclaration({ @@ -39,7 +42,7 @@ export function useUpdateActorDeclaration({ update.allowGroupInvites ?? current?.associated?.chat?.allowGroupInvites, }) - const result = await pdsClient.call(com.atproto.repo.putRecord, { + const result = await pdsClient.call(ComAtprotoRepoPutRecord, { repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', @@ -104,7 +107,7 @@ export function useDeleteActorDeclaration() { return useMutation({ mutationFn: async () => { if (!currentAccount) throw new Error('Not signed in') - const result = await pdsClient.call(com.atproto.repo.deleteRecord, { + const result = await pdsClient.call(ComAtprotoRepoDeleteRecord, { repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', @@ -123,7 +126,7 @@ export async function fetchActorDeclarationRecord({ }) { if (!did) return const res = await client - .get(chat.bsky.actor.declaration, {repo: did as DidString, rkey: 'self'}) + .get(ChatBskyActorDeclaration, {repo: did as DidString, rkey: 'self'}) .catch(_e => undefined) return res?.value } diff --git a/src/state/queries/messages/add-group-members.ts b/src/state/queries/messages/add-group-members.ts index 2b7610be16..0a7b127e91 100644 --- a/src/state/queries/messages/add-group-members.ts +++ b/src/state/queries/messages/add-group-members.ts @@ -8,7 +8,10 @@ import { import {logger} from '#/logger' import {useProfileQuery} from '#/state/queries/profile' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import type * as ChatBskyConvoListConvos from '#/lexicons/chat/bsky/convo/listConvos' +import * as ChatBskyGroupAddMembers from '#/lexicons/chat/bsky/group/addMembers' import * as bsky from '#/types/bsky' import {RQKEY as CONVO_KEY} from './conversation' import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations' @@ -20,7 +23,7 @@ export function useAddGroupMembers( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.addMembers.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupAddMembers.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -37,7 +40,7 @@ export function useAddGroupMembers( profiles: bsky.profile.AnyProfileView[] }) => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.addMembers, { + return await client.call(ChatBskyGroupAddMembers, { convoId, // callers pass already-resolved actor dids members: members as DidString[], @@ -46,26 +49,24 @@ export function useAddGroupMembers( onMutate: ({profiles}) => { if (!convoId) return - const prevConvo = - queryClient.getQueryData( - CONVO_KEY(convoId), - ) + const prevConvo = queryClient.getQueryData( + CONVO_KEY(convoId), + ) const prevListEntries = queryClient.getQueriesData< - InfiniteData + InfiniteData >({queryKey: [CONVO_LIST_KEY]}) const prevMemberList = queryClient.getQueryData< - chat.bsky.actor.defs.ProfileViewBasic[] + ChatBskyActorDefs.ProfileViewBasic[] >(listConvoMembersQueryKey(convoId)) - const addedBy: chat.bsky.actor.defs.ProfileViewBasic | undefined = - myProfile - ? { - ...myProfile, - $type: 'chat.bsky.actor.defs#profileViewBasic', - } - : undefined + const addedBy: ChatBskyActorDefs.ProfileViewBasic | undefined = myProfile + ? { + ...myProfile, + $type: 'chat.bsky.actor.defs#profileViewBasic', + } + : undefined - const optimisticMembers: chat.bsky.actor.defs.ProfileViewBasic[] = + const optimisticMembers: ChatBskyActorDefs.ProfileViewBasic[] = profiles.map(profile => ({ ...profile, $type: 'chat.bsky.actor.defs#profileViewBasic', @@ -76,12 +77,11 @@ export function useAddGroupMembers( }, })) - queryClient.setQueryData( + queryClient.setQueryData( CONVO_KEY(convoId), prev => { if (!prev) return - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) - return prev + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return prev return { ...prev, members: [...prev.members, ...optimisticMembers], @@ -94,7 +94,7 @@ export function useAddGroupMembers( ) queryClient.setQueriesData< - InfiniteData + InfiniteData >({queryKey: [CONVO_LIST_KEY]}, prev => { if (!prev?.pages) return return { @@ -103,7 +103,7 @@ export function useAddGroupMembers( ...page, convos: page.convos.map(convo => { if (convo.id !== convoId) return convo - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) return convo return { ...convo, @@ -119,7 +119,7 @@ export function useAddGroupMembers( } }) - queryClient.setQueryData( + queryClient.setQueryData( listConvoMembersQueryKey(convoId), prev => { if (!prev) return @@ -131,13 +131,13 @@ export function useAddGroupMembers( }, onSuccess: data => { if (convoId) { - queryClient.setQueryData( + queryClient.setQueryData( CONVO_KEY(convoId), data.convo, ) queryClient.setQueriesData< - InfiniteData + InfiniteData >({queryKey: [CONVO_LIST_KEY]}, prev => { if (!prev?.pages) return return { diff --git a/src/state/queries/messages/conversation.ts b/src/state/queries/messages/conversation.ts index 04e3a7129b..891ed98576 100644 --- a/src/state/queries/messages/conversation.ts +++ b/src/state/queries/messages/conversation.ts @@ -8,7 +8,11 @@ import { import {STALE} from '#/state/queries' import {useOnMarkAsRead} from '#/state/queries/messages/list-conversations' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import type * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoGetConvo from '#/lexicons/chat/bsky/convo/getConvo' +import type * as ChatBskyConvoGetUnreadCounts from '#/lexicons/chat/bsky/convo/getUnreadCounts' +import * as ChatBskyConvoUpdateRead from '#/lexicons/chat/bsky/convo/updateRead' import { RQKEY_PARTIAL as UNREAD_COUNTS_PARTIAL_KEY, UNREAD_ACCEPTED_CAP, @@ -29,7 +33,7 @@ export function useConvoQuery({convoId}: {convoId: string}) { return useQuery({ queryKey: RQKEY(convoId), queryFn: async () => { - const data = await client.call(chat.bsky.convo.getConvo, {convoId}) + const data = await client.call(ChatBskyConvoGetConvo, {convoId}) return data.convo }, staleTime: STALE.INFINITY, @@ -38,7 +42,7 @@ export function useConvoQuery({convoId}: {convoId: string}) { export function precacheConvoQuery( queryClient: QueryClient, - convo: chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, ) { queryClient.setQueryData(RQKEY(convo.id), convo) } @@ -58,7 +62,7 @@ export function useMarkAsReadMutation() { }) => { if (!convoId) throw new Error('No convoId provided') - await client.call(chat.bsky.convo.updateRead, { + await client.call(ChatBskyConvoUpdateRead, { convoId, messageId, }) @@ -75,7 +79,7 @@ export function useMarkAsReadMutation() { // find the convo so we know which badge counter (if any) to decrement. // keep scanning past a stale unreadCount === 0 cache so another cache // holding the true unread state still drives the decrement - let unreadStatus: chat.bsky.convo.defs.ConvoView['status'] | undefined + let unreadStatus: ChatBskyConvoDefs.ConvoView['status'] | undefined for (const [, data] of prevListQueries) { if (!data) continue const convo = getConvoFromQueryData(convoId, data) @@ -90,13 +94,11 @@ export function useMarkAsReadMutation() { // the badge count query is a separate server query that the list caches // don't feed, so decrement it here to keep the badge in sync const prevUnreadCountsQueries = - queryClient.getQueriesData( - { - queryKey: UNREAD_COUNTS_PARTIAL_KEY, - }, - ) + queryClient.getQueriesData({ + queryKey: UNREAD_COUNTS_PARTIAL_KEY, + }) if (unreadStatus) { - queryClient.setQueriesData( + queryClient.setQueriesData( {queryKey: UNREAD_COUNTS_PARTIAL_KEY}, old => { if (!old) return old @@ -180,9 +182,9 @@ export function useMarkAsReadMutation() { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - chat.bsky.convo.getConvo.$OutputBody['convo'] + ChatBskyConvoGetConvo.$OutputBody['convo'] >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/messages/create-group-chat.ts b/src/state/queries/messages/create-group-chat.ts index 3a12a976e6..237f9d01dc 100644 --- a/src/state/queries/messages/create-group-chat.ts +++ b/src/state/queries/messages/create-group-chat.ts @@ -3,14 +3,14 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyGroupCreateGroup from '#/lexicons/chat/bsky/group/createGroup' import {precacheConvoQuery} from './conversation' export function useCreateGroupChat({ onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.createGroup.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupCreateGroup.$OutputBody) => void onError?: (error: Error) => void }) { const queryClient = useQueryClient() @@ -18,7 +18,7 @@ export function useCreateGroupChat({ return useMutation({ mutationFn: async ({name, members}: {name: string; members: string[]}) => { - return await client.call(chat.bsky.group.createGroup, { + return await client.call(ChatBskyGroupCreateGroup, { name, // callers pass already-resolved actor dids members: members as DidString[], diff --git a/src/state/queries/messages/create-join-link.ts b/src/state/queries/messages/create-join-link.ts index 5f52cadf8f..7a6a50bc77 100644 --- a/src/state/queries/messages/create-join-link.ts +++ b/src/state/queries/messages/create-join-link.ts @@ -3,7 +3,9 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupCreateJoinLink from '#/lexicons/chat/bsky/group/createJoinLink' +import type * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -16,7 +18,7 @@ export function useCreateJoinLink( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.createJoinLink.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupCreateJoinLink.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -28,11 +30,11 @@ export function useCreateJoinLink( joinRule, requireApproval, }: { - joinRule: chat.bsky.group.defs.JoinRule + joinRule: ChatBskyGroupDefs.JoinRule requireApproval: boolean }) => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.createJoinLink, { + return await client.call(ChatBskyGroupCreateJoinLink, { convoId, joinRule, requireApproval, @@ -41,7 +43,7 @@ export function useCreateJoinLink( onMutate: ({joinRule, requireApproval}) => { if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, @@ -62,7 +64,7 @@ export function useCreateJoinLink( onSuccess: data => { if (convoId) { updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/disable-join-link.ts b/src/state/queries/messages/disable-join-link.ts index d58edca37b..b70397e904 100644 --- a/src/state/queries/messages/disable-join-link.ts +++ b/src/state/queries/messages/disable-join-link.ts @@ -3,7 +3,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupDisableJoinLink from '#/lexicons/chat/bsky/group/disableJoinLink' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -16,7 +17,7 @@ export function useDisableJoinLink( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.disableJoinLink.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupDisableJoinLink.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -26,13 +27,13 @@ export function useDisableJoinLink( return useMutation({ mutationFn: async () => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.disableJoinLink, {convoId}) + return await client.call(ChatBskyGroupDisableJoinLink, {convoId}) }, onMutate: () => { if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { if ( - !bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) || + !bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind) || !prev.kind.joinLink ) { return undefined @@ -49,7 +50,7 @@ export function useDisableJoinLink( onSuccess: data => { if (convoId) { updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/edit-group-chat-name.ts b/src/state/queries/messages/edit-group-chat-name.ts index 88c950c7ee..63e8f227db 100644 --- a/src/state/queries/messages/edit-group-chat-name.ts +++ b/src/state/queries/messages/edit-group-chat-name.ts @@ -2,7 +2,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupEditGroup from '#/lexicons/chat/bsky/group/editGroup' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -15,7 +16,7 @@ export function useEditGroupChatName( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.editGroup.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupEditGroup.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -25,7 +26,7 @@ export function useEditGroupChatName( return useMutation({ mutationFn: async ({name: groupName}: {name: string}) => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.editGroup, { + return await client.call(ChatBskyGroupEditGroup, { convoId, name: groupName, }) @@ -33,7 +34,7 @@ export function useEditGroupChatName( onMutate: ({name: groupName}) => { if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/edit-join-link.ts b/src/state/queries/messages/edit-join-link.ts index f921b3062b..365dd689ad 100644 --- a/src/state/queries/messages/edit-join-link.ts +++ b/src/state/queries/messages/edit-join-link.ts @@ -2,7 +2,9 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import type * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' +import * as ChatBskyGroupEditJoinLink from '#/lexicons/chat/bsky/group/editJoinLink' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -15,7 +17,7 @@ export function useEditJoinLink( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.editJoinLink.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupEditJoinLink.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -27,11 +29,11 @@ export function useEditJoinLink( joinRule, requireApproval, }: { - joinRule: chat.bsky.group.defs.JoinRule + joinRule: ChatBskyGroupDefs.JoinRule requireApproval: boolean }) => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.editJoinLink, { + return await client.call(ChatBskyGroupEditJoinLink, { convoId, joinRule, requireApproval, @@ -41,7 +43,7 @@ export function useEditJoinLink( if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { if ( - !bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) || + !bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind) || !prev.kind.joinLink ) { return undefined @@ -58,7 +60,7 @@ export function useEditJoinLink( onSuccess: data => { if (convoId) { updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/enable-join-link.ts b/src/state/queries/messages/enable-join-link.ts index d426adf5d7..73b6c45a8f 100644 --- a/src/state/queries/messages/enable-join-link.ts +++ b/src/state/queries/messages/enable-join-link.ts @@ -3,7 +3,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupEnableJoinLink from '#/lexicons/chat/bsky/group/enableJoinLink' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -16,7 +17,7 @@ export function useEnableJoinLink( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.enableJoinLink.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupEnableJoinLink.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -26,13 +27,13 @@ export function useEnableJoinLink( return useMutation({ mutationFn: async () => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.enableJoinLink, {convoId}) + return await client.call(ChatBskyGroupEnableJoinLink, {convoId}) }, onMutate: () => { if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { if ( - !bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) || + !bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind) || !prev.kind.joinLink ) { return undefined @@ -49,7 +50,7 @@ export function useEnableJoinLink( onSuccess: data => { if (convoId) { updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/get-convo-availability.ts b/src/state/queries/messages/get-convo-availability.ts index 31b4bb4166..88e1f77323 100644 --- a/src/state/queries/messages/get-convo-availability.ts +++ b/src/state/queries/messages/get-convo-availability.ts @@ -2,7 +2,7 @@ import {type DidString} from '@atproto/syntax' import {useQuery} from '@tanstack/react-query' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetConvoAvailability from '#/lexicons/chat/bsky/convo/getConvoAvailability' import {STALE} from '..' const RQKEY_ROOT = 'convo-availability' @@ -18,7 +18,7 @@ export function useGetConvoAvailabilityQuery( return useQuery({ queryKey: RQKEY(did), queryFn: async () => { - return client.call(chat.bsky.convo.getConvoAvailability, { + return client.call(ChatBskyConvoGetConvoAvailability, { // callers pass an already-resolved actor did members: [did as DidString], }) diff --git a/src/state/queries/messages/get-convo-for-members.ts b/src/state/queries/messages/get-convo-for-members.ts index 803fb3e04f..36513b2866 100644 --- a/src/state/queries/messages/get-convo-for-members.ts +++ b/src/state/queries/messages/get-convo-for-members.ts @@ -3,14 +3,14 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetConvoForMembers from '#/lexicons/chat/bsky/convo/getConvoForMembers' import {precacheConvoQuery} from './conversation' export function useGetConvoForMembers({ onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.convo.getConvoForMembers.$OutputBody) => void + onSuccess?: (data: ChatBskyConvoGetConvoForMembers.$OutputBody) => void onError?: (error: Error) => void }) { const queryClient = useQueryClient() @@ -18,7 +18,7 @@ export function useGetConvoForMembers({ return useMutation({ mutationFn: async (members: string[]) => { - return await client.call(chat.bsky.convo.getConvoForMembers, { + return await client.call(ChatBskyConvoGetConvoForMembers, { // callers pass already-resolved actor dids members: members as DidString[], }) diff --git a/src/state/queries/messages/get-status.ts b/src/state/queries/messages/get-status.ts index 465d442cb6..b4724d2ccb 100644 --- a/src/state/queries/messages/get-status.ts +++ b/src/state/queries/messages/get-status.ts @@ -1,7 +1,7 @@ import {useQuery} from '@tanstack/react-query' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyActorGetStatus from '#/lexicons/chat/bsky/actor/getStatus' import {STALE} from '..' import {createQueryKey} from '../util' @@ -17,7 +17,7 @@ export function useChatActorStatusQuery() { staleTime: STALE.SECONDS.FIFTEEN, queryKey: chatActorStatusQueryKey(), queryFn: async () => { - return await client.call(chat.bsky.actor.getStatus) + return await client.call(ChatBskyActorGetStatus) }, enabled: hasSession, }) diff --git a/src/state/queries/messages/get-unread-counts.ts b/src/state/queries/messages/get-unread-counts.ts index 5ec532d6ed..abd4e8dd9c 100644 --- a/src/state/queries/messages/get-unread-counts.ts +++ b/src/state/queries/messages/get-unread-counts.ts @@ -2,7 +2,7 @@ import {useQuery} from '@tanstack/react-query' import {useChatClient, useSession} from '#/state/session' import {useAgeAssurance} from '#/ageAssurance' -import {chat} from '#/lexicons' +import * as ChatBskyConvoGetUnreadCounts from '#/lexicons/chat/bsky/convo/getUnreadCounts' import {STALE} from '..' const RQKEY_ROOT = 'convo-unread-counts' @@ -26,7 +26,7 @@ export function useUnreadCountsQuery() { return useQuery({ queryKey: RQKEY(includeGroupChats), queryFn: async () => { - return await client.call(chat.bsky.convo.getUnreadCounts, { + return await client.call(ChatBskyConvoGetUnreadCounts, { includeGroupChats, }) }, diff --git a/src/state/queries/messages/join-requests.ts b/src/state/queries/messages/join-requests.ts index 03be537426..5283e11c52 100644 --- a/src/state/queries/messages/join-requests.ts +++ b/src/state/queries/messages/join-requests.ts @@ -7,15 +7,18 @@ import { import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyGroupApproveJoinRequest from '#/lexicons/chat/bsky/group/approveJoinRequest' +import type * as ChatBskyGroupListJoinRequests from '#/lexicons/chat/bsky/group/listJoinRequests' +import * as ChatBskyGroupRejectJoinRequest from '#/lexicons/chat/bsky/group/rejectJoinRequest' import {listConvoMembersQueryKey} from './list-convo-members' import {createListJoinRequestsQueryKey} from './list-join-requests' type JoinRequestAction = 'approve' | 'reject' type JoinRequestOutput = A extends 'approve' - ? chat.bsky.group.approveJoinRequest.$OutputBody - : chat.bsky.group.rejectJoinRequest.$OutputBody + ? ChatBskyGroupApproveJoinRequest.$OutputBody + : ChatBskyGroupRejectJoinRequest.$OutputBody export function useJoinRequestMutation( action: A, @@ -38,11 +41,11 @@ export function useJoinRequestMutation( const memberDid = member as DidString const data = action === 'approve' - ? await client.call(chat.bsky.group.approveJoinRequest, { + ? await client.call(ChatBskyGroupApproveJoinRequest, { convoId, member: memberDid, }) - : await client.call(chat.bsky.group.rejectJoinRequest, { + : await client.call(ChatBskyGroupRejectJoinRequest, { convoId, member: memberDid, }) @@ -59,7 +62,7 @@ export function useJoinRequestMutation( const requestsKey = createListJoinRequestsQueryKey({convoId}) const prevRequests = queryClient.getQueryData< - InfiniteData + InfiniteData >(requestsKey) const requestedByProfile = prevRequests?.pages @@ -67,7 +70,7 @@ export function useJoinRequestMutation( .find(request => request.requestedBy.did === member)?.requestedBy queryClient.setQueryData< - InfiniteData + InfiniteData >(requestsKey, prev => { if (!prev?.pages) return prev return { @@ -81,14 +84,14 @@ export function useJoinRequestMutation( } }) - let prevMembers: chat.bsky.actor.defs.ProfileViewBasic[] | undefined + let prevMembers: ChatBskyActorDefs.ProfileViewBasic[] | undefined if (action === 'approve' && requestedByProfile) { const membersKey = listConvoMembersQueryKey(convoId) prevMembers = - queryClient.getQueryData( + queryClient.getQueryData( membersKey, ) - queryClient.setQueryData( + queryClient.setQueryData( membersKey, prev => { if (!prev) return prev diff --git a/src/state/queries/messages/leave-conversation.ts b/src/state/queries/messages/leave-conversation.ts index a0c5f2118d..0b5d27ec7c 100644 --- a/src/state/queries/messages/leave-conversation.ts +++ b/src/state/queries/messages/leave-conversation.ts @@ -3,7 +3,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {invalidateJoinLinkPreviewsForConvo} from '#/state/queries/join-links' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoLeaveConvo from '#/lexicons/chat/bsky/convo/leaveConvo' +import type * as ChatBskyConvoListConvos from '#/lexicons/chat/bsky/convo/listConvos' import { type ConvoRequestListQueryData, optimisticDelete as optimisticDeleteRequest, @@ -18,7 +19,7 @@ export function RQKEY(convoId: string | undefined) { type ConvoListQueryData = { pageParams: Array - pages: Array + pages: Array } export function useLeaveConvo( @@ -29,7 +30,7 @@ export function useLeaveConvo( onError, }: { onMutate?: () => void - onSuccess?: (data: chat.bsky.convo.leaveConvo.$OutputBody) => void + onSuccess?: (data: ChatBskyConvoLeaveConvo.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -41,7 +42,7 @@ export function useLeaveConvo( mutationFn: async () => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.convo.leaveConvo, {convoId}) + return await client.call(ChatBskyConvoLeaveConvo, {convoId}) }, onMutate: () => { const prevConvoListQueries = diff --git a/src/state/queries/messages/list-conversation-requests.tsx b/src/state/queries/messages/list-conversation-requests.tsx index 4c8d5d5caa..292c9fe54b 100644 --- a/src/state/queries/messages/list-conversation-requests.tsx +++ b/src/state/queries/messages/list-conversation-requests.tsx @@ -5,7 +5,9 @@ import { } from '@tanstack/react-query' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoListConvoRequests from '#/lexicons/chat/bsky/convo/listConvoRequests' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' const DEFAULT_LIMIT = 10 @@ -28,7 +30,7 @@ export function useListConvoRequests({ enabled, queryKey: RQKEY(limit), queryFn: async ({pageParam}) => { - return await client.call(chat.bsky.convo.listConvoRequests, { + return await client.call(ChatBskyConvoListConvoRequests, { limit, cursor: pageParam, }) @@ -40,18 +42,16 @@ export function useListConvoRequests({ export type ConvoRequestListQueryData = { pageParams: Array - pages: Array + pages: Array } export type ConvoRequestItem = - chat.bsky.convo.listConvoRequests.$OutputBody['requests'][number] + ChatBskyConvoListConvoRequests.$OutputBody['requests'][number] export function optimisticUpdate( chatId: string, old: ConvoRequestListQueryData | undefined, - updateFn: ( - convo: chat.bsky.convo.defs.ConvoView, - ) => chat.bsky.convo.defs.ConvoView, + updateFn: (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView, ): ConvoRequestListQueryData | undefined { if (!old) return old @@ -61,7 +61,7 @@ export function optimisticUpdate( ...page, requests: page.requests.map((item): ConvoRequestItem => { if ( - bsky.isType(chat.bsky.convo.defs.convoView, item) && + bsky.isType(ChatBskyConvoDefs.convoView, item) && item.id === chatId ) { return { @@ -87,8 +87,7 @@ export function optimisticDelete( ...page, requests: page.requests.filter( item => - !bsky.isType(chat.bsky.convo.defs.convoView, item) || - item.id !== chatId, + !bsky.isType(ChatBskyConvoDefs.convoView, item) || item.id !== chatId, ), })), } @@ -104,7 +103,7 @@ export function markAllRead( pages: old.pages.map(page => ({ ...page, requests: page.requests.map((item): ConvoRequestItem => { - if (bsky.isType(chat.bsky.convo.defs.convoView, item)) { + if (bsky.isType(ChatBskyConvoDefs.convoView, item)) { return { ...item, $type: 'chat.bsky.convo.defs#convoView', @@ -129,7 +128,7 @@ export function optimisticDeleteJoinRequest( ...page, requests: page.requests.filter( item => - !bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item) || + !bsky.isType(ChatBskyGroupDefs.joinRequestConvoView, item) || item.convoId !== convoId, ), })), @@ -141,7 +140,7 @@ export function* findAllProfilesInQueryData( did: string, ) { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) @@ -150,15 +149,13 @@ export function* findAllProfilesInQueryData( for (const page of queryData.pages) { for (const item of page.requests) { - if (bsky.isType(chat.bsky.convo.defs.convoView, item)) { + if (bsky.isType(ChatBskyConvoDefs.convoView, item)) { for (const member of item.members) { if (member.did === did) { yield member } } - } else if ( - bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item) - ) { + } else if (bsky.isType(ChatBskyGroupDefs.joinRequestConvoView, item)) { if (item.owner.did === did) { yield item.owner } diff --git a/src/state/queries/messages/list-conversations.tsx b/src/state/queries/messages/list-conversations.tsx index 71fe202053..e1f08c4d33 100644 --- a/src/state/queries/messages/list-conversations.tsx +++ b/src/state/queries/messages/list-conversations.tsx @@ -13,7 +13,9 @@ import {useCurrentConvoId} from '#/state/messages/current-convo-id' import {useMessagesEventBus} from '#/state/messages/events' import {invalidateJoinLinkPreviewsForConvo} from '#/state/queries/join-links' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoListConvos from '#/lexicons/chat/bsky/convo/listConvos' import * as bsky from '#/types/bsky' import {RQKEY as CONVO_KEY} from './conversation' import { @@ -60,7 +62,7 @@ export const RQKEY_PARTIAL = ( * filters client-side or convos leak into lists that should exclude them. */ export function convoMatchesQueryKey( - convo: chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, queryKey: QueryKey, ): boolean { const [, status, readState, kind, lockStatus] = queryKey as ReturnType< @@ -68,7 +70,7 @@ export function convoMatchesQueryKey( > if (status !== 'all' && status !== convo.status) return false if (readState === 'unread' && convo.unreadCount === 0) return false - if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { if (kind === 'direct') return false if (lockStatus && convo.kind.lockStatus !== lockStatus) return false } else { @@ -86,7 +88,7 @@ export function convoMatchesQueryKey( * longer matches (e.g. unreadCount dropped to 0), mirroring how read/mute * log events update convos in place everywhere. */ -export function convoListQueryPredicate(convo: chat.bsky.convo.defs.ConvoView) { +export function convoListQueryPredicate(convo: ChatBskyConvoDefs.ConvoView) { return (query: Query): boolean => { const data = query.state.data as ConvoListQueryData | undefined if (data && getConvoFromQueryData(convo.id, data)) return true @@ -117,7 +119,7 @@ export function useListConvosQuery({ enabled, queryKey: RQKEY(status ?? 'all', readState, kind, lockStatus, limit), queryFn: async ({pageParam}) => { - return await client.call(chat.bsky.convo.listConvos, { + return await client.call(ChatBskyConvoListConvos, { limit, cursor: pageParam, readState: readState === 'unread' ? 'unread' : undefined, @@ -188,10 +190,10 @@ export function ListConvosProviderInner({ function mutateMembers( convoId: string, fn: ( - members: chat.bsky.actor.defs.ProfileViewBasic[], - ) => chat.bsky.actor.defs.ProfileViewBasic[], + members: ChatBskyActorDefs.ProfileViewBasic[], + ) => ChatBskyActorDefs.ProfileViewBasic[], ) { - queryClient.setQueryData( + queryClient.setQueryData( listConvoMembersQueryKey(convoId), old => { if (!old) return // query doesn't exist yet, skip @@ -203,8 +205,8 @@ export function ListConvosProviderInner({ function updateConvoInAllLists( convoId: string, fn: ( - convo: chat.bsky.convo.defs.ConvoView, - ) => chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, + ) => ChatBskyConvoDefs.ConvoView, ) { queryClient.setQueriesData( {queryKey: [RQKEY_ROOT]}, @@ -219,10 +221,10 @@ export function ListConvosProviderInner({ function mutateConvoView( convoId: string, fn: ( - convo: chat.bsky.convo.defs.ConvoView, - ) => chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, + ) => ChatBskyConvoDefs.ConvoView, ) { - queryClient.setQueryData( + queryClient.setQueryData( CONVO_KEY(convoId), old => (old ? fn(old) : old), ) @@ -243,7 +245,7 @@ export function ListConvosProviderInner({ function handleMemberAdded( convoId: string, did: string, - relatedProfiles: chat.bsky.actor.defs.ProfileViewBasic[], + relatedProfiles: ChatBskyActorDefs.ProfileViewBasic[], rev: string, ) { const newMember = relatedProfiles.find(r => r.did === did) @@ -252,7 +254,7 @@ export function ListConvosProviderInner({ // memberCount bump to avoid double-counting. const alreadyKnownMember = queryClient - .getQueryData( + .getQueryData( listConvoMembersQueryKey(convoId), ) ?.some(m => m.did === did) ?? false @@ -276,7 +278,7 @@ export function ListConvosProviderInner({ // list, skip the memberCount decrement to avoid double-counting. const alreadyRemovedMember = queryClient - .getQueryData( + .getQueryData( listConvoMembersQueryKey(convoId), ) ?.some(m => m.did === did) === false @@ -290,34 +292,31 @@ export function ListConvosProviderInner({ } for (const log of events.logs) { - if (bsky.isType(chat.bsky.convo.defs.logBeginConvo, log)) { + if (bsky.isType(ChatBskyConvoDefs.logBeginConvo, log)) { debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logLeaveConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logLeaveConvo, log)) { deleteConvoFromAllLists(log.convoId) // The viewer is no longer in this convo (they left on another // device, or were removed - removed members receive a // logLeaveConvo, not a logRemoveMember). Refetch any cached join // link preview so its viewer state reflects the lost membership. void invalidateJoinLinkPreviewsForConvo(queryClient, log.convoId) - } else if (bsky.isType(chat.bsky.convo.defs.logDeleteMessage, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logDeleteMessage, log)) { updateConvoInAllLists( log.convoId, withRevGuard(log.rev, convo => { if ( (bsky.isType( - chat.bsky.convo.defs.deletedMessageView, + ChatBskyConvoDefs.deletedMessageView, log.message, ) || - bsky.isType( - chat.bsky.convo.defs.messageView, - log.message, - )) && + bsky.isType(ChatBskyConvoDefs.messageView, log.message)) && (bsky.isType( - chat.bsky.convo.defs.deletedMessageView, + ChatBskyConvoDefs.deletedMessageView, convo.lastMessage, ) || bsky.isType( - chat.bsky.convo.defs.messageView, + ChatBskyConvoDefs.messageView, convo.lastMessage, )) ) { @@ -333,9 +332,9 @@ export function ListConvosProviderInner({ } }), ) - } else if (bsky.isType(chat.bsky.convo.defs.logCreateMessage, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logCreateMessage, log)) { // Store in a new var to avoid TS errors due to closures. - const logRef: chat.bsky.convo.defs.LogCreateMessage = log + const logRef: ChatBskyConvoDefs.LogCreateMessage = log // Get all matching queries const queries = queryClient.getQueriesData({ @@ -343,7 +342,7 @@ export function ListConvosProviderInner({ }) // Check if convo exists in any query - let foundConvo: chat.bsky.convo.defs.ConvoView | null = null + let foundConvo: ChatBskyConvoDefs.ConvoView | null = null for (const [_key, query] of queries) { if (!query) continue const convo = getConvoFromQueryData(logRef.convoId, query) @@ -387,11 +386,11 @@ export function ListConvosProviderInner({ unreadCount: foundConvo.id !== currentConvoId ? (bsky.isType( - chat.bsky.convo.defs.messageView, + ChatBskyConvoDefs.messageView, logRef.message, ) || bsky.isType( - chat.bsky.convo.defs.deletedMessageView, + ChatBskyConvoDefs.deletedMessageView, logRef.message, )) && logRef.message.sender.did !== currentAccount?.did @@ -400,9 +399,7 @@ export function ListConvosProviderInner({ : 0, } - function filterConvoFromPage( - convo: chat.bsky.convo.defs.ConvoView[], - ) { + function filterConvoFromPage(convo: ChatBskyConvoDefs.ConvoView[]) { return convo.filter(c => c.id !== logRef.convoId) } @@ -465,7 +462,7 @@ export function ListConvosProviderInner({ old => moveConvoToTopInRequests(updatedConvo, old), ) } - } else if (bsky.isType(chat.bsky.convo.defs.logReadMessage, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logReadMessage, log)) { updateConvoInAllLists( log.convoId, withRevGuard(log.rev, convo => ({ @@ -474,7 +471,7 @@ export function ListConvosProviderInner({ rev: log.rev, })), ) - } else if (bsky.isType(chat.bsky.convo.defs.logReadConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logReadConvo, log)) { updateConvoInAllLists( log.convoId, withRevGuard(log.rev, convo => ({ @@ -483,12 +480,12 @@ export function ListConvosProviderInner({ rev: log.rev, })), ) - } else if (bsky.isType(chat.bsky.convo.defs.logAcceptConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logAcceptConvo, log)) { const requestQueries = queryClient.getQueriesData({ queryKey: RQKEY_PARTIAL('request'), }) - let foundConvo: chat.bsky.convo.defs.ConvoView | null = null + let foundConvo: ChatBskyConvoDefs.ConvoView | null = null for (const [_key, data] of requestQueries) { if (!data) continue foundConvo = getConvoFromQueryData(log.convoId, data) @@ -504,7 +501,7 @@ export function ListConvosProviderInner({ if (log.rev <= foundConvo.rev) { continue } - const acceptedConvo: chat.bsky.convo.defs.ConvoView = { + const acceptedConvo: ChatBskyConvoDefs.ConvoView = { ...foundConvo, status: 'accepted', rev: log.rev, @@ -565,7 +562,7 @@ export function ListConvosProviderInner({ } }, ) - } else if (bsky.isType(chat.bsky.convo.defs.logMuteConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logMuteConvo, log)) { mutateConvoView( log.convoId, withRevGuard(log.rev, convo => ({ @@ -574,7 +571,7 @@ export function ListConvosProviderInner({ rev: log.rev, })), ) - } else if (bsky.isType(chat.bsky.convo.defs.logUnmuteConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logUnmuteConvo, log)) { mutateConvoView( log.convoId, withRevGuard(log.rev, convo => ({ @@ -583,11 +580,11 @@ export function ListConvosProviderInner({ rev: log.rev, })), ) - } else if (bsky.isType(chat.bsky.convo.defs.logLockConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logLockConvo, log)) { mutateConvoView( log.convoId, withRevGuard(log.rev, convo => { - if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return { ...convo, kind: {...convo.kind, lockStatus: 'locked'}, @@ -602,11 +599,11 @@ export function ListConvosProviderInner({ void queryClient.invalidateQueries({ queryKey: CONVO_KEY(log.convoId), }) - } else if (bsky.isType(chat.bsky.convo.defs.logUnlockConvo, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logUnlockConvo, log)) { mutateConvoView( log.convoId, withRevGuard(log.rev, convo => { - if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return { ...convo, kind: { @@ -622,12 +619,12 @@ export function ListConvosProviderInner({ }), ) } else if ( - bsky.isType(chat.bsky.convo.defs.logLockConvoPermanently, log) + bsky.isType(ChatBskyConvoDefs.logLockConvoPermanently, log) ) { mutateConvoView( log.convoId, withRevGuard(log.rev, convo => { - if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return { ...convo, kind: {...convo.kind, lockStatus: 'locked-permanently'}, @@ -638,20 +635,20 @@ export function ListConvosProviderInner({ }), ) } else if ( - bsky.isType(chat.bsky.convo.defs.logCreateJoinLink, log) || - bsky.isType(chat.bsky.convo.defs.logEditJoinLink, log) || - bsky.isType(chat.bsky.convo.defs.logEnableJoinLink, log) || - bsky.isType(chat.bsky.convo.defs.logDisableJoinLink, log) + bsky.isType(ChatBskyConvoDefs.logCreateJoinLink, log) || + bsky.isType(ChatBskyConvoDefs.logEditJoinLink, log) || + bsky.isType(ChatBskyConvoDefs.logEnableJoinLink, log) || + bsky.isType(ChatBskyConvoDefs.logDisableJoinLink, log) ) { // Join link data not included in the log event, trigger refetch to get it debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logEditGroup, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logEditGroup, log)) { // Updated group details (name etc.) aren't included in the log // event, so refetch to pick them up. debouncedRefetch() } else if ( - bsky.isType(chat.bsky.convo.defs.logApproveJoinRequest, log) || - bsky.isType(chat.bsky.convo.defs.logRejectJoinRequest, log) + bsky.isType(ChatBskyConvoDefs.logApproveJoinRequest, log) || + bsky.isType(ChatBskyConvoDefs.logRejectJoinRequest, log) ) { // Route through mutateConvoView (not updateConvoInAllLists) so the // single-convo cache updates too, keeping the in-convo requests @@ -663,7 +660,7 @@ export function ListConvosProviderInner({ ), ) } else if ( - bsky.isType(chat.bsky.convo.defs.logIncomingJoinRequest, log) + bsky.isType(ChatBskyConvoDefs.logIncomingJoinRequest, log) ) { // Route through mutateConvoView (not updateConvoInAllLists) so the // single-convo cache updates too, letting the in-convo requests @@ -674,16 +671,14 @@ export function ListConvosProviderInner({ applyJoinRequestCountDelta(convo, log.rev, 1), ), ) - } else if ( - bsky.isType(chat.bsky.convo.defs.logReadJoinRequests, log) - ) { + } else if (bsky.isType(ChatBskyConvoDefs.logReadJoinRequests, log)) { // The owner marked join requests as read (possibly on another // device). Zero the unread count but keep the total, mirroring the // useMarkJoinRequestsRead mutation. mutateConvoView( log.convoId, withRevGuard(log.rev, convo => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return {...convo, rev: log.rev} } return { @@ -694,16 +689,13 @@ export function ListConvosProviderInner({ }), ) } else if ( - bsky.isType(chat.bsky.convo.defs.logOutgoingJoinRequest, log) + bsky.isType(ChatBskyConvoDefs.logOutgoingJoinRequest, log) ) { // Viewer isn't in the chat yet, but the inbox surfaces outgoing // requests, so refetch to pick up the new entry. debouncedRefetch() } else if ( - bsky.isType( - chat.bsky.convo.defs.logWithdrawIncomingJoinRequest, - log, - ) + bsky.isType(ChatBskyConvoDefs.logWithdrawIncomingJoinRequest, log) ) { // A requester rescinded their request to a group the viewer owns. // Mirror of isLogIncomingJoinRequest: decrement the counts. @@ -714,10 +706,7 @@ export function ListConvosProviderInner({ ), ) } else if ( - bsky.isType( - chat.bsky.convo.defs.logWithdrawOutgoingJoinRequest, - log, - ) + bsky.isType(ChatBskyConvoDefs.logWithdrawOutgoingJoinRequest, log) ) { // The viewer rescinded their own outgoing join request (possibly on // another device). Remove it from the requests inbox cache. @@ -725,7 +714,7 @@ export function ListConvosProviderInner({ {queryKey: [REQUESTS_RQKEY_ROOT]}, old => optimisticDeleteJoinRequest(log.convoId, old), ) - } else if (bsky.isType(chat.bsky.convo.defs.logAddReaction, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logAddReaction, log)) { updateConvoInAllLists( log.convoId, withRevGuard(log.rev, convo => { @@ -750,15 +739,15 @@ export function ListConvosProviderInner({ $type: 'chat.bsky.convo.defs#messageAndReactionView', reaction: log.reaction, message: log.message, - } as chat.bsky.convo.defs.ConvoView['lastReaction'], + } as ChatBskyConvoDefs.ConvoView['lastReaction'], rev: log.rev, } }), ) - } else if (bsky.isType(chat.bsky.convo.defs.logAddMember, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logAddMember, log)) { const data = log.message.data if ( - bsky.isType(chat.bsky.convo.defs.systemMessageDataAddMember, data) + bsky.isType(ChatBskyConvoDefs.systemMessageDataAddMember, data) ) { handleMemberAdded( log.convoId, @@ -772,13 +761,10 @@ export function ListConvosProviderInner({ queryKey: CONVO_KEY(log.convoId), }) debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logRemoveMember, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logRemoveMember, log)) { const data = log.message.data if ( - bsky.isType( - chat.bsky.convo.defs.systemMessageDataRemoveMember, - data, - ) + bsky.isType(ChatBskyConvoDefs.systemMessageDataRemoveMember, data) ) { handleMemberRemoved(log.convoId, data.member.did, log.rev) } @@ -787,13 +773,10 @@ export function ListConvosProviderInner({ queryKey: CONVO_KEY(log.convoId), }) debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logMemberJoin, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logMemberJoin, log)) { const data = log.message.data if ( - bsky.isType( - chat.bsky.convo.defs.systemMessageDataMemberJoin, - data, - ) + bsky.isType(ChatBskyConvoDefs.systemMessageDataMemberJoin, data) ) { handleMemberAdded( log.convoId, @@ -806,13 +789,10 @@ export function ListConvosProviderInner({ queryKey: CONVO_KEY(log.convoId), }) debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logMemberLeave, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logMemberLeave, log)) { const data = log.message.data if ( - bsky.isType( - chat.bsky.convo.defs.systemMessageDataMemberLeave, - data, - ) + bsky.isType(ChatBskyConvoDefs.systemMessageDataMemberLeave, data) ) { handleMemberRemoved(log.convoId, data.member.did, log.rev) } @@ -820,7 +800,7 @@ export function ListConvosProviderInner({ queryKey: CONVO_KEY(log.convoId), }) debouncedRefetch() - } else if (bsky.isType(chat.bsky.convo.defs.logRemoveReaction, log)) { + } else if (bsky.isType(ChatBskyConvoDefs.logRemoveReaction, log)) { queryClient.setQueriesData( {queryKey: [RQKEY_ROOT]}, (old?: ConvoListQueryData) => @@ -832,13 +812,10 @@ export function ListConvosProviderInner({ // if the convo is the same log.convoId === convo.id && bsky.isType( - chat.bsky.convo.defs.messageAndReactionView, + ChatBskyConvoDefs.messageAndReactionView, convo.lastReaction, ) && - bsky.isType( - chat.bsky.convo.defs.messageView, - log.message, - ) && + bsky.isType(ChatBskyConvoDefs.messageView, log.message) && // ...and the message is the same convo.lastReaction.message.id === log.message.id && // ...and the reaction is the same @@ -920,7 +897,7 @@ export function useUnreadMessageCount(): { export type ConvoListQueryData = { pageParams: Array - pages: Array + pages: Array } export function useOnMarkAsRead() { @@ -957,8 +934,8 @@ export function useOnMarkAsRead() { */ function withRevGuard( rev: string, - fn: (convo: chat.bsky.convo.defs.ConvoView) => chat.bsky.convo.defs.ConvoView, -): (convo: chat.bsky.convo.defs.ConvoView) => chat.bsky.convo.defs.ConvoView { + fn: (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView, +): (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView { return convo => (rev <= convo.rev ? convo : fn(convo)) } @@ -966,8 +943,8 @@ function optimisticUpdate( chatId: string, old?: ConvoListQueryData, updateFn?: ( - convo: chat.bsky.convo.defs.ConvoView, - ) => chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, + ) => ChatBskyConvoDefs.ConvoView, ) { if (!old || !updateFn) return old @@ -983,12 +960,12 @@ function optimisticUpdate( } function applyJoinRequestCountDelta( - convo: chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, rev: string, delta: 1 | -1, -): chat.bsky.convo.defs.ConvoView { +): ChatBskyConvoDefs.ConvoView { // Join requests are only meaningful for group convos. - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return {...convo, rev} } // Bump the total and unread counts together. Both are clamped at 0 and @@ -1009,7 +986,7 @@ function applyJoinRequestCountDelta( } function moveConvoToTopInRequests( - updatedConvo: chat.bsky.convo.defs.ConvoView, + updatedConvo: ChatBskyConvoDefs.ConvoView, old: ConvoRequestListQueryData | undefined, ): ConvoRequestListQueryData | undefined { if (!old) return old @@ -1023,7 +1000,7 @@ function moveConvoToTopInRequests( pages: old.pages.map((page, i) => { const filtered = page.requests.filter( item => - !bsky.isType(chat.bsky.convo.defs.convoView, item) || + !bsky.isType(ChatBskyConvoDefs.convoView, item) || item.id !== updatedConvo.id, ) if (i === 0) { @@ -1038,13 +1015,13 @@ function moveConvoToTopInRequests( } function removeMemberFromConvoView( - convo: chat.bsky.convo.defs.ConvoView, + convo: ChatBskyConvoDefs.ConvoView, did: string, rev: string, alreadyRemovedMember: boolean, -): chat.bsky.convo.defs.ConvoView { +): ChatBskyConvoDefs.ConvoView { // Member add/remove/join/leave events are only meaningful for group convos. - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) return convo + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) return convo const nextMembers = convo.members.filter(m => m.did !== did) return { ...convo, @@ -1060,13 +1037,13 @@ function removeMemberFromConvoView( } function addMemberToConvoView( - convo: chat.bsky.convo.defs.ConvoView, - member: chat.bsky.actor.defs.ProfileViewBasic, + convo: ChatBskyConvoDefs.ConvoView, + member: ChatBskyActorDefs.ProfileViewBasic, rev: string, alreadyKnownMember: boolean, -): chat.bsky.convo.defs.ConvoView { +): ChatBskyConvoDefs.ConvoView { // Member add/remove/join/leave events are only meaningful for group convos. - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) return convo + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) return convo const alreadyInCuratedList = convo.members.some(m => m.did === member.did) const nextMembers = alreadyInCuratedList ? convo.members @@ -1112,7 +1089,7 @@ export function* findAllProfilesInQueryData( did: string, ) { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/messages/list-convo-members.ts b/src/state/queries/messages/list-convo-members.ts index 007650eb00..83e687acc3 100644 --- a/src/state/queries/messages/list-convo-members.ts +++ b/src/state/queries/messages/list-convo-members.ts @@ -3,7 +3,8 @@ import {type QueryClient, useQuery} from '@tanstack/react-query' import {STALE} from '#/state/queries' import {createQueryKey} from '#/state/queries/util' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoGetConvoMembers from '#/lexicons/chat/bsky/convo/getConvoMembers' const RQKEY_ROOT = 'listConvoMembers' export const listConvoMembersQueryKey = (convoId: string) => @@ -17,7 +18,7 @@ export function useListConvoMembersQuery({ placeholderData, }: { convoId: string - placeholderData?: chat.bsky.actor.defs.ProfileViewBasic[] + placeholderData?: ChatBskyActorDefs.ProfileViewBasic[] }) { const client = useChatClient() @@ -31,11 +32,11 @@ export function useListConvoMembersQuery({ * `members` with the exported profile type also keeps the hook's result * type unchanged for consumers. */ - const members: chat.bsky.actor.defs.ProfileViewBasic[] = [] + const members: ChatBskyActorDefs.ProfileViewBasic[] = [] let cursor: string | undefined do { - const data = await client.call(chat.bsky.convo.getConvoMembers, { + const data = await client.call(ChatBskyConvoGetConvoMembers, { convoId, cursor, limit: LIMIT, @@ -54,9 +55,9 @@ export function useListConvoMembersQuery({ export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - chat.bsky.actor.defs.ProfileViewBasic[] + ChatBskyActorDefs.ProfileViewBasic[] >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/messages/list-join-requests.ts b/src/state/queries/messages/list-join-requests.ts index b722fa06f7..954cdf77a8 100644 --- a/src/state/queries/messages/list-join-requests.ts +++ b/src/state/queries/messages/list-join-requests.ts @@ -4,7 +4,8 @@ import {useInfiniteQuery, useQueryClient} from '@tanstack/react-query' import {useMessagesEventBus} from '#/state/messages/events' import {createQueryKey} from '#/state/queries/util' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupListJoinRequests from '#/lexicons/chat/bsky/group/listJoinRequests' import * as bsky from '#/types/bsky' import {STALE} from '..' @@ -35,9 +36,9 @@ export function useListJoinRequestsQuery({ if (event.type !== 'logs') return for (const log of event.logs) { if ( - bsky.isType(chat.bsky.convo.defs.logIncomingJoinRequest, log) || - bsky.isType(chat.bsky.convo.defs.logApproveJoinRequest, log) || - bsky.isType(chat.bsky.convo.defs.logRejectJoinRequest, log) + bsky.isType(ChatBskyConvoDefs.logIncomingJoinRequest, log) || + bsky.isType(ChatBskyConvoDefs.logApproveJoinRequest, log) || + bsky.isType(ChatBskyConvoDefs.logRejectJoinRequest, log) ) { void queryClient.invalidateQueries({ queryKey: createListJoinRequestsQueryKey({convoId}), @@ -54,7 +55,7 @@ export function useListJoinRequestsQuery({ enabled: isEnabled, queryKey: createListJoinRequestsQueryKey({convoId: convoId ?? ''}), queryFn: async ({pageParam}) => { - return await client.call(chat.bsky.group.listJoinRequests, { + return await client.call(ChatBskyGroupListJoinRequests, { // guarded by `isEnabled` convoId: convoId!, cursor: pageParam, diff --git a/src/state/queries/messages/list-mutual-groups.ts b/src/state/queries/messages/list-mutual-groups.ts index 65743a45e7..3dca61e11b 100644 --- a/src/state/queries/messages/list-mutual-groups.ts +++ b/src/state/queries/messages/list-mutual-groups.ts @@ -3,7 +3,7 @@ import {useInfiniteQuery} from '@tanstack/react-query' import {createQueryKey} from '#/state/queries/util' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyGroupListMutualGroups from '#/lexicons/chat/bsky/group/listMutualGroups' const listMutualGroupsQueryKeyRoot = 'list-mutual-groups' @@ -28,7 +28,7 @@ export function useListMutualGroupsQuery({ enabled: isEnabled, queryKey: createListMutualGroupsQueryKey({subject: subject ?? ''}), queryFn: async ({pageParam}) => { - return await client.call(chat.bsky.group.listMutualGroups, { + return await client.call(ChatBskyGroupListMutualGroups, { // guarded by `enabled`, and callers pass a resolved actor did subject: subject as DidString, cursor: pageParam, diff --git a/src/state/queries/messages/lock-conversation.ts b/src/state/queries/messages/lock-conversation.ts index 2057317fab..9068f7804f 100644 --- a/src/state/queries/messages/lock-conversation.ts +++ b/src/state/queries/messages/lock-conversation.ts @@ -1,7 +1,9 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyConvoLockConvo from '#/lexicons/chat/bsky/convo/lockConvo' +import * as ChatBskyConvoUnlockConvo from '#/lexicons/chat/bsky/convo/unlockConvo' import * as bsky from '#/types/bsky' import { rollbackConvoOptimistic, @@ -15,7 +17,7 @@ export function useLockConvo( onError, }: { onSuccess?: ( - data: chat.bsky.convo.lockConvo.$OutputBody, + data: ChatBskyConvoLockConvo.$OutputBody, variables: {lock: boolean; silent?: boolean}, ) => void onError?: ( @@ -31,15 +33,15 @@ export function useLockConvo( mutationFn: async ({lock}: {lock: boolean; silent?: boolean}) => { if (!convoId) throw new Error('No convoId provided') if (lock) { - return await client.call(chat.bsky.convo.lockConvo, {convoId}) + return await client.call(ChatBskyConvoLockConvo, {convoId}) } else { - return await client.call(chat.bsky.convo.unlockConvo, {convoId}) + return await client.call(ChatBskyConvoUnlockConvo, {convoId}) } }, onMutate: ({lock}) => { if (!convoId) return return updateConvoOptimistic(queryClient, convoId, prev => { - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) return undefined return { ...prev, diff --git a/src/state/queries/messages/mark-join-request-read.ts b/src/state/queries/messages/mark-join-request-read.ts index ecc928074b..0d1cbb7d8f 100644 --- a/src/state/queries/messages/mark-join-request-read.ts +++ b/src/state/queries/messages/mark-join-request-read.ts @@ -2,7 +2,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import * as ChatBskyGroupUpdateJoinRequestsRead from '#/lexicons/chat/bsky/group/updateJoinRequestsRead' import * as bsky from '#/types/bsky' import {RQKEY as CONVO_KEY} from './conversation' import { @@ -17,19 +18,18 @@ export function useMarkJoinRequestsRead(convoId: string | undefined) { return useMutation({ mutationFn: async () => { if (!convoId) throw new Error('No convoId provided') - await client.call(chat.bsky.group.updateJoinRequestsRead, {convoId}) + await client.call(ChatBskyGroupUpdateJoinRequestsRead, {convoId}) }, onMutate: () => { if (!convoId) return - const prevConvo = - queryClient.getQueryData( - CONVO_KEY(convoId), - ) - queryClient.setQueryData( + const prevConvo = queryClient.getQueryData( + CONVO_KEY(convoId), + ) + queryClient.setQueryData( CONVO_KEY(convoId), old => { - if (!old || !bsky.isType(chat.bsky.convo.defs.groupConvo, old.kind)) + if (!old || !bsky.isType(ChatBskyConvoDefs.groupConvo, old.kind)) return old return { ...old, @@ -52,7 +52,7 @@ export function useMarkJoinRequestsRead(convoId: string | undefined) { convos: page.convos.map(convo => { if ( convo.id !== convoId || - !bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind) + !bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind) ) { return convo } diff --git a/src/state/queries/messages/mute-conversation.ts b/src/state/queries/messages/mute-conversation.ts index 26cfa2e3b0..2f04ace891 100644 --- a/src/state/queries/messages/mute-conversation.ts +++ b/src/state/queries/messages/mute-conversation.ts @@ -1,7 +1,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyConvoMuteConvo from '#/lexicons/chat/bsky/convo/muteConvo' +import * as ChatBskyConvoUnmuteConvo from '#/lexicons/chat/bsky/convo/unmuteConvo' import { rollbackConvoOptimistic, updateConvoOptimistic, @@ -13,7 +14,7 @@ export function useMuteConvo( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.convo.muteConvo.$OutputBody) => void + onSuccess?: (data: ChatBskyConvoMuteConvo.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -24,9 +25,9 @@ export function useMuteConvo( mutationFn: async ({mute}: {mute: boolean}) => { if (!convoId) throw new Error('No convoId provided') if (mute) { - return await client.call(chat.bsky.convo.muteConvo, {convoId}) + return await client.call(ChatBskyConvoMuteConvo, {convoId}) } else { - return await client.call(chat.bsky.convo.unmuteConvo, {convoId}) + return await client.call(ChatBskyConvoUnmuteConvo, {convoId}) } }, onMutate: ({mute}) => { diff --git a/src/state/queries/messages/remove-from-group.ts b/src/state/queries/messages/remove-from-group.ts index 6abbd4ebc3..5db9ca4e43 100644 --- a/src/state/queries/messages/remove-from-group.ts +++ b/src/state/queries/messages/remove-from-group.ts @@ -7,7 +7,10 @@ import { import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyActorDefs from '#/lexicons/chat/bsky/actor/defs' +import * as ChatBskyConvoDefs from '#/lexicons/chat/bsky/convo/defs' +import type * as ChatBskyConvoListConvos from '#/lexicons/chat/bsky/convo/listConvos' +import * as ChatBskyGroupRemoveMembers from '#/lexicons/chat/bsky/group/removeMembers' import * as bsky from '#/types/bsky' import {RQKEY as CONVO_KEY} from './conversation' import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations' @@ -19,7 +22,7 @@ export function useRemoveFromGroupChat( onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.removeMembers.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupRemoveMembers.$OutputBody) => void onError?: (error: Error) => void }, ) { @@ -29,7 +32,7 @@ export function useRemoveFromGroupChat( return useMutation({ mutationFn: async ({members}: {members: string[]}) => { if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.removeMembers, { + return await client.call(ChatBskyGroupRemoveMembers, { convoId, // callers pass already-resolved actor dids members: members as DidString[], @@ -38,24 +41,23 @@ export function useRemoveFromGroupChat( onMutate: ({members}) => { if (!convoId) return - const prevConvo = - queryClient.getQueryData( - CONVO_KEY(convoId), - ) + const prevConvo = queryClient.getQueryData( + CONVO_KEY(convoId), + ) const prevListEntries = queryClient.getQueriesData< - InfiniteData + InfiniteData >({queryKey: [CONVO_LIST_KEY]}) const prevMemberList = queryClient.getQueryData< - chat.bsky.actor.defs.ProfileViewBasic[] + ChatBskyActorDefs.ProfileViewBasic[] >(listConvoMembersQueryKey(convoId)) - queryClient.setQueryData( + queryClient.setQueryData( CONVO_KEY(convoId), prev => { if (!prev) return const nextMembers = prev.members.filter(m => !members.includes(m.did)) const removed = prev.members.length - nextMembers.length - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) { + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, prev.kind)) { return {...prev, members: nextMembers} } return { @@ -70,7 +72,7 @@ export function useRemoveFromGroupChat( ) queryClient.setQueriesData< - InfiniteData + InfiniteData >({queryKey: [CONVO_LIST_KEY]}, prev => { if (!prev?.pages) return return { @@ -83,7 +85,7 @@ export function useRemoveFromGroupChat( m => !members.includes(m.did), ) const removed = convo.members.length - nextMembers.length - if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) { + if (!bsky.isType(ChatBskyConvoDefs.groupConvo, convo.kind)) { return {...convo, members: nextMembers} } return { @@ -99,7 +101,7 @@ export function useRemoveFromGroupChat( } }) - queryClient.setQueryData( + queryClient.setQueryData( listConvoMembersQueryKey(convoId), prev => { if (!prev) return diff --git a/src/state/queries/messages/request-join-group-chat.ts b/src/state/queries/messages/request-join-group-chat.ts index 32b8043b8f..e4f773fa3e 100644 --- a/src/state/queries/messages/request-join-group-chat.ts +++ b/src/state/queries/messages/request-join-group-chat.ts @@ -2,14 +2,14 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyGroupRequestJoin from '#/lexicons/chat/bsky/group/requestJoin' import {RQKEY_ROOT as REQUESTS_RQKEY_ROOT} from './list-conversation-requests' export function useRequestJoinGroupChat({ onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.requestJoin.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupRequestJoin.$OutputBody) => void onError?: (error: Error) => void } = {}) { const client = useChatClient() @@ -21,7 +21,7 @@ export function useRequestJoinGroupChat({ if (!hasSession) throw new Error('Must be logged in to join') if (!code) throw new Error('No invite code') - return await client.call(chat.bsky.group.requestJoin, {code}) + return await client.call(ChatBskyGroupRequestJoin, {code}) }, onSuccess: data => { void queryClient.invalidateQueries({queryKey: [REQUESTS_RQKEY_ROOT]}) diff --git a/src/state/queries/messages/restrictChatSettings.ts b/src/state/queries/messages/restrictChatSettings.ts index b47440bf6b..1b9af4ae8d 100644 --- a/src/state/queries/messages/restrictChatSettings.ts +++ b/src/state/queries/messages/restrictChatSettings.ts @@ -6,7 +6,7 @@ import { getOtherRequiredDataFromCache, setOtherRequiredDataActorDeclarationCache, } from '#/ageAssurance/data' -import {chat} from '#/lexicons' +import * as ChatBskyActorDeclaration from '#/lexicons/chat/bsky/actor/declaration' /** * Updates the chat actor declaration record to restrict who can contact the @@ -48,7 +48,7 @@ export async function restrictChatSettings({ ) } - const record: chat.bsky.actor.declaration.Main = { + const record: ChatBskyActorDeclaration.Main = { $type: 'chat.bsky.actor.declaration', allowIncoming: restrictIncoming ? 'none' @@ -73,7 +73,7 @@ export async function restrictChatSettings({ * `service: null` on record helpers, so the write lands on the account's * PDS even though the collection is `chat.bsky.*`. */ - client.put(chat.bsky.actor.declaration, record, { + client.put(ChatBskyActorDeclaration, record, { repo: did, rkey: 'self', }), diff --git a/src/state/queries/messages/update-all-read.ts b/src/state/queries/messages/update-all-read.ts index 55d8dfc417..617f5c6e1a 100644 --- a/src/state/queries/messages/update-all-read.ts +++ b/src/state/queries/messages/update-all-read.ts @@ -2,7 +2,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient} from '#/state/session' -import {chat} from '#/lexicons' +import type * as ChatBskyConvoGetUnreadCounts from '#/lexicons/chat/bsky/convo/getUnreadCounts' +import * as ChatBskyConvoUpdateAllRead from '#/lexicons/chat/bsky/convo/updateAllRead' import {RQKEY_PARTIAL as UNREAD_COUNTS_PARTIAL_KEY} from './get-unread-counts' import { type ConvoRequestListQueryData, @@ -32,7 +33,7 @@ export function useUpdateAllRead( return useMutation({ mutationFn: async () => { - return await client.call(chat.bsky.convo.updateAllRead, {status}) + return await client.call(ChatBskyConvoUpdateAllRead, {status}) }, onMutate: () => { // snapshot every convo-list cache up front so onError can restore them @@ -93,12 +94,10 @@ export function useUpdateAllRead( // zero out the badge count query that actually drives the unread badge, // since it's a separate server query that the list caches don't feed const prevUnreadCountsQueries = - queryClient.getQueriesData( - { - queryKey: UNREAD_COUNTS_PARTIAL_KEY, - }, - ) - queryClient.setQueriesData( + queryClient.getQueriesData({ + queryKey: UNREAD_COUNTS_PARTIAL_KEY, + }) + queryClient.setQueriesData( {queryKey: UNREAD_COUNTS_PARTIAL_KEY}, old => { if (!old) return old diff --git a/src/state/queries/messages/withdraw-join-group-chat.ts b/src/state/queries/messages/withdraw-join-group-chat.ts index 10de51a1d1..4211512479 100644 --- a/src/state/queries/messages/withdraw-join-group-chat.ts +++ b/src/state/queries/messages/withdraw-join-group-chat.ts @@ -2,7 +2,7 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {useChatClient, useSession} from '#/state/session' -import {chat} from '#/lexicons' +import * as ChatBskyGroupWithdrawJoinRequest from '#/lexicons/chat/bsky/group/withdrawJoinRequest' import { type ConvoRequestListQueryData, optimisticDeleteJoinRequest, @@ -13,7 +13,7 @@ export function useWithdrawJoinGroupChatRequest({ onSuccess, onError, }: { - onSuccess?: (data: chat.bsky.group.withdrawJoinRequest.$OutputBody) => void + onSuccess?: (data: ChatBskyGroupWithdrawJoinRequest.$OutputBody) => void onError?: (error: Error) => void } = {}) { const client = useChatClient() @@ -26,7 +26,7 @@ export function useWithdrawJoinGroupChatRequest({ throw new Error('Must be logged in to withdraw a join request') if (!convoId) throw new Error('No convoId provided') - return await client.call(chat.bsky.group.withdrawJoinRequest, {convoId}) + return await client.call(ChatBskyGroupWithdrawJoinRequest, {convoId}) }, onSuccess: (data, {convoId}) => { queryClient.setQueriesData( diff --git a/src/state/queries/my-blocked-accounts.ts b/src/state/queries/my-blocked-accounts.ts index 32f9d27833..4f5b8977ae 100644 --- a/src/state/queries/my-blocked-accounts.ts +++ b/src/state/queries/my-blocked-accounts.ts @@ -6,7 +6,8 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetBlocks from '#/lexicons/app/bsky/graph/getBlocks' const RQKEY_ROOT = 'my-blocked-accounts' export const RQKEY = () => [RQKEY_ROOT] @@ -15,15 +16,15 @@ type RQPageParam = string | undefined export function useMyBlockedAccountsQuery() { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getBlocks.$OutputBody, + AppBskyGraphGetBlocks.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.graph.getBlocks, { + return await client.call(AppBskyGraphGetBlocks, { limit: 30, cursor: pageParam, }) @@ -36,9 +37,9 @@ export function useMyBlockedAccountsQuery() { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/my-lists.ts b/src/state/queries/my-lists.ts index a0ac92f52f..2090b9abaf 100644 --- a/src/state/queries/my-lists.ts +++ b/src/state/queries/my-lists.ts @@ -3,7 +3,10 @@ import {type QueryClient, useQuery} from '@tanstack/react-query' import {accumulate} from '#/lib/async/accumulate' import {STALE} from '#/state/queries' import {useAppviewClient, useSession} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetListBlocks from '#/lexicons/app/bsky/graph/getListBlocks' +import * as AppBskyGraphGetListMutes from '#/lexicons/app/bsky/graph/getListMutes' +import * as AppBskyGraphGetLists from '#/lexicons/app/bsky/graph/getLists' export type MyListsFilter = 'all' | 'curate' | 'mod' | 'all-including-subscribed' @@ -14,15 +17,15 @@ export const RQKEY = (filter: MyListsFilter) => [RQKEY_ROOT, filter] export function useMyListsQuery(filter: MyListsFilter) { const {currentAccount} = useSession() const client = useAppviewClient() - return useQuery({ + return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(filter), async queryFn() { - let lists: app.bsky.graph.defs.ListView[] = [] + let lists: AppBskyGraphDefs.ListView[] = [] const promises = [ accumulate(cursor => client - .call(app.bsky.graph.getLists, { + .call(AppBskyGraphGetLists, { actor: currentAccount!.did, cursor, limit: 50, @@ -37,7 +40,7 @@ export function useMyListsQuery(filter: MyListsFilter) { promises.push( accumulate(cursor => client - .call(app.bsky.graph.getListMutes, { + .call(AppBskyGraphGetListMutes, { cursor, limit: 50, }) @@ -50,7 +53,7 @@ export function useMyListsQuery(filter: MyListsFilter) { promises.push( accumulate(cursor => client - .call(app.bsky.graph.getListBlocks, { + .call(AppBskyGraphGetListBlocks, { cursor, limit: 50, }) diff --git a/src/state/queries/my-muted-accounts.ts b/src/state/queries/my-muted-accounts.ts index 06f1ec1a85..8bf009c7a6 100644 --- a/src/state/queries/my-muted-accounts.ts +++ b/src/state/queries/my-muted-accounts.ts @@ -6,7 +6,8 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetMutes from '#/lexicons/app/bsky/graph/getMutes' const RQKEY_ROOT = 'my-muted-accounts' export const RQKEY = () => [RQKEY_ROOT] @@ -15,15 +16,15 @@ type RQPageParam = string | undefined export function useMyMutedAccountsQuery() { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getMutes.$OutputBody, + AppBskyGraphGetMutes.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.graph.getMutes, { + return await client.call(AppBskyGraphGetMutes, { limit: 30, cursor: pageParam, }) @@ -36,9 +37,9 @@ export function useMyMutedAccountsQuery() { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index 978c363df5..db5a9e9501 100644 --- a/src/state/queries/notifications/feed.ts +++ b/src/state/queries/notifications/feed.ts @@ -31,7 +31,8 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' import {useThreadgateHiddenReplyUris} from '#/state/threadgate-hidden-replies' -import {app} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import { didOrHandleUriMatches, @@ -196,9 +197,7 @@ export function useNotificationFeedQuery(opts: { * a `$type` field on the `subject`. But if the nested * `record` is a post, we know it's a post view. */ - if ( - bsky.isType(app.bsky.feed.post, item.subject?.record) - ) { + if (bsky.isType(AppBskyFeedPost, item.subject?.record)) { const mod = moderatePost(item.subject, moderationOpts!) if (mod.ui('contentList').filter) { return false @@ -275,7 +274,7 @@ export function useNotificationFeedQuery(opts: { export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const atUri = new AtUri(uri) const queryDatas = queryClient.getQueriesData>({ @@ -294,7 +293,7 @@ export function* findAllPostsInQueryData( } } - if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.subject)) { const quotedPost = getEmbeddedPost(item.subject?.embed) if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) { yield embedViewRecordToPostView(quotedPost) @@ -332,7 +331,7 @@ export function* findAllProfilesInQueryData( ) { yield item.subject.author } - if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.subject)) { const quotedPost = getEmbeddedPost(item.subject?.embed) if (quotedPost?.author.did === did) { yield quotedPost.author diff --git a/src/state/queries/notifications/settings.ts b/src/state/queries/notifications/settings.ts index 8628d508e0..c5c5431bb0 100644 --- a/src/state/queries/notifications/settings.ts +++ b/src/state/queries/notifications/settings.ts @@ -9,7 +9,12 @@ import { import {logger} from '#/logger' import {useAppviewClient, useChatClient} from '#/state/session' import * as Toast from '#/components/Toast' -import {app, chat} from '#/lexicons' +import type * as AppBskyNotificationDefs from '#/lexicons/app/bsky/notification/defs' +import * as AppBskyNotificationGetPreferences from '#/lexicons/app/bsky/notification/getPreferences' +import * as AppBskyNotificationPutPreferencesV2 from '#/lexicons/app/bsky/notification/putPreferencesV2' +import type * as ChatBskyNotificationDefs from '#/lexicons/chat/bsky/notification/defs' +import * as ChatBskyNotificationGetPreferences from '#/lexicons/chat/bsky/notification/getPreferences' +import * as ChatBskyNotificationPutPreferences from '#/lexicons/chat/bsky/notification/putPreferences' const RQKEY_ROOT = 'notification-settings' const RQKEY_APP = [RQKEY_ROOT, 'app'] @@ -20,18 +25,18 @@ const RQKEY_CHAT = [RQKEY_ROOT, 'chat'] // fetched and cached separately. This combined type names every preference for // the generic settings dialog, but it is never the shape of a query response. export type NotificationSettingsPreferences = Omit< - app.bsky.notification.defs.Preferences, + AppBskyNotificationDefs.Preferences, 'chat' > & - Partial> + Partial> export type AppNotificationSettingsPreferences = Omit< - app.bsky.notification.defs.Preferences, + AppBskyNotificationDefs.Preferences, 'chat' > export type ChatNotificationSettingsPreferences = Pick< - chat.bsky.notification.defs.Preferences, + ChatBskyNotificationDefs.Preferences, 'chat' | 'chatRequest' > @@ -41,9 +46,9 @@ export type NotificationSettingsPreferenceName = Exclude< > export type NotificationSettingsPreference = - | app.bsky.notification.defs.Preference - | app.bsky.notification.defs.FilterablePreference - | chat.bsky.notification.defs.ChatPreference + | AppBskyNotificationDefs.Preference + | AppBskyNotificationDefs.FilterablePreference + | ChatBskyNotificationDefs.ChatPreference export function isChatPreferenceName( name: NotificationSettingsPreferenceName, @@ -54,7 +59,7 @@ export function isChatPreferenceName( type NotificationSettingsUpdate = Partial type AppNotificationSettingsUpdate = Partial< - Omit + Omit > type ChatNotificationSettingsUpdate = @@ -68,7 +73,7 @@ export function useNotificationSettingsQuery({ return useQuery({ queryKey: RQKEY_APP, queryFn: async (): Promise => { - const data = await client.call(app.bsky.notification.getPreferences) + const data = await client.call(AppBskyNotificationGetPreferences) return appPreferencesWithoutChat(data.preferences) }, enabled, @@ -83,7 +88,7 @@ export function useChatNotificationSettingsQuery({ return useQuery({ queryKey: RQKEY_CHAT, queryFn: async (): Promise => { - const data = await client.call(chat.bsky.notification.getPreferences) + const data = await client.call(ChatBskyNotificationGetPreferences) return chatPreferencesForSettings(data.preferences) }, enabled, @@ -103,13 +108,10 @@ export function useNotificationSettingsUpdateMutation() { const {appUpdate, chatUpdate} = splitNotificationSettingsUpdate(update) await Promise.all([ hasUpdates(appUpdate) - ? appviewClient.call( - app.bsky.notification.putPreferencesV2, - appUpdate, - ) + ? appviewClient.call(AppBskyNotificationPutPreferencesV2, appUpdate) : undefined, hasUpdates(chatUpdate) - ? chatClient.call(chat.bsky.notification.putPreferences, chatUpdate) + ? chatClient.call(ChatBskyNotificationPutPreferences, chatUpdate) : undefined, ]) }, @@ -155,15 +157,15 @@ function optimisticUpdateNotificationSettings( } function appPreferencesWithoutChat( - preferences: app.bsky.notification.defs.Preferences, -): Omit { + preferences: AppBskyNotificationDefs.Preferences, +): Omit { const {chat: _ignoredChat, ...appPreferences} = preferences return appPreferences } function chatPreferencesForSettings( - preferences: chat.bsky.notification.defs.Preferences, -): Pick { + preferences: ChatBskyNotificationDefs.Preferences, +): Pick { return { chat: preferences.chat, chatRequest: preferences.chatRequest, diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx index e905b29ac6..10326739ac 100644 --- a/src/state/queries/notifications/unread.tsx +++ b/src/state/queries/notifications/unread.tsx @@ -20,7 +20,7 @@ import {resetBadgeCount} from '#/lib/notifications/notifications' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {truncateAndInvalidate} from '#/state/queries/util' import {useAppviewClient, useSession} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyNotificationUpdateSeen from '#/lexicons/app/bsky/notification/updateSeen' import {RQKEY as RQKEY_NOTIFS} from './feed' import {type CachedFeedPage, type FeedPage} from './types' import {fetchPage} from './util' @@ -122,7 +122,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return { async markAllRead() { // update server - await client.call(app.bsky.notification.updateSeen, { + await client.call(AppBskyNotificationUpdateSeen, { // toISOString always emits the Z-suffixed form the format requires seenAt: cacheRef.current.syncedAt.toISOString() as ISODatetimeString, }) diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index fad64582da..11a05a27ab 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -9,7 +9,15 @@ import {type QueryClient} from '@tanstack/react-query' import chunk from 'lodash.chunk' import {labelIsHideableOffense} from '#/lib/moderation' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetPosts from '#/lexicons/app/bsky/feed/getPosts' +import * as AppBskyFeedLike from '#/lexicons/app/bsky/feed/like' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as AppBskyFeedRepost from '#/lexicons/app/bsky/feed/repost' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetStarterPacks from '#/lexicons/app/bsky/graph/getStarterPacks' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' +import * as AppBskyNotificationListNotifications from '#/lexicons/app/bsky/notification/listNotifications' import * as bsky from '#/types/bsky' import {precacheProfile} from '../profile' import { @@ -53,7 +61,7 @@ export async function fetchPage({ page: FeedPage indexedAt: string | undefined }> { - const data = await client.call(app.bsky.notification.listNotifications, { + const data = await client.call(AppBskyNotificationListNotifications, { limit, cursor, reasons, @@ -124,7 +132,7 @@ export function shouldFilterNotif( } if ( notif.reason === 'subscribed-post' && - bsky.isType(app.bsky.feed.post, notif.record) && + bsky.isType(AppBskyFeedPost, notif.record) && hasMutedWord({ mutedWords: moderationOpts.prefs.mutedWords, text: notif.record.text, @@ -201,8 +209,8 @@ async function fetchSubjects( client: Client, groupedNotifs: FeedNotification[], ): Promise<{ - posts: Map - starterPacks: Map + posts: Map + starterPacks: Map }> { const postUris = new Set() const packUris = new Set() @@ -223,25 +231,25 @@ async function fetchSubjects( const packUriChunks = chunk(Array.from(packUris) as AtUriString[], 25) const postsChunks = await Promise.all( postUriChunks.map(uris => - client.call(app.bsky.feed.getPosts, {uris}).then(data => data.posts), + client.call(AppBskyFeedGetPosts, {uris}).then(data => data.posts), ), ) const packsChunks = await Promise.all( packUriChunks.map(uris => client - .call(app.bsky.graph.getStarterPacks, {uris}) + .call(AppBskyGraphGetStarterPacks, {uris}) .then(data => data.starterPacks), ), ) - const postsMap = new Map() - const packsMap = new Map() + const postsMap = new Map() + const packsMap = new Map() for (const post of postsChunks.flat()) { - if (bsky.isType(app.bsky.feed.post, post.record)) { + if (bsky.isType(AppBskyFeedPost, post.record)) { postsMap.set(post.uri, post) } } for (const pack of packsChunks.flat()) { - if (bsky.isType(app.bsky.graph.starterpack, pack.record)) { + if (bsky.isType(AppBskyGraphStarterpack, pack.record)) { packsMap.set(pack.uri, pack) } } @@ -295,8 +303,8 @@ function getSubjectUri( type === 'repost-via-repost' ) { if ( - bsky.isType(app.bsky.feed.repost, notif.record) || - bsky.isType(app.bsky.feed.like, notif.record) + bsky.isType(AppBskyFeedRepost, notif.record) || + bsky.isType(AppBskyFeedLike, notif.record) ) { return typeof notif.record.subject?.uri === 'string' ? notif.record.subject?.uri diff --git a/src/state/queries/pds-detection.ts b/src/state/queries/pds-detection.ts index 1f2b413d6d..10d98d25a4 100644 --- a/src/state/queries/pds-detection.ts +++ b/src/state/queries/pds-detection.ts @@ -9,7 +9,7 @@ import {isNetworkError} from '#/lib/strings/errors' import {logger} from '#/logger' import {STALE} from '#/state/queries' import {getPublicAppviewClient} from '#/state/session/clients' -import {com} from '#/lexicons' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' const RQKEY_ROOT = 'pds-detection' export const RQKEY = (identifier: string) => [RQKEY_ROOT, identifier] @@ -162,7 +162,7 @@ export async function resolvePdsForIdentifier( } else { const data = await withResolveTimeout(signal => client.call( - com.atproto.identity.resolveHandle, + ComAtprotoIdentityResolveHandle, {handle: norm as HandleString}, {signal}, ), diff --git a/src/state/queries/pinned-post.ts b/src/state/queries/pinned-post.ts index b1364725ca..cf3758ca63 100644 --- a/src/state/queries/pinned-post.ts +++ b/src/state/queries/pinned-post.ts @@ -5,7 +5,8 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import * as Toast from '#/components/Toast' -import {app, type com} from '#/lexicons' +import {type com} from '#/lexicons' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' import {updatePostShadow} from '../cache/post-shadow' import {useAppviewClient, useSession} from '../session' import {useProfileUpdateMutation} from './profile' @@ -34,7 +35,7 @@ export function usePinnedPostMutation() { // get the currently pinned post so we can optimistically remove the pin from it if (!currentAccount) throw new Error('Not signed in') - const profile = await client.call(app.bsky.actor.getProfile, { + const profile = await client.call(AppBskyActorGetProfile, { actor: currentAccount.did, }) prevPinnedPost = profile.pinnedPost?.uri diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 95af63b185..3293044f24 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -33,7 +33,9 @@ import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {useAppviewClient, useSession} from '#/state/session' import * as userActionHistory from '#/state/userActionHistory' import {KnownError} from '#/view/com/posts/PostFeedErrorMessage' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import type * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import {useFeedTuners} from '../preferences/feed-tuners' import {useModerationOpts} from '../preferences/moderation-opts' @@ -79,10 +81,10 @@ export function RQKEY(feedDesc: FeedDescriptor, params?: FeedParams) { export interface FeedPostSliceItem { _reactKey: string uri: AtUriString - post: app.bsky.feed.defs.PostView - record: app.bsky.feed.post.Main + post: AppBskyFeedDefs.PostView + record: AppBskyFeedPost.Main moderation: ModerationDecision - parentAuthor?: app.bsky.actor.defs.ProfileViewBasic + parentAuthor?: AppBskyActorDefs.ProfileViewBasic isParentBlocked?: boolean isParentNotFound?: boolean } @@ -97,8 +99,8 @@ export interface FeedPostSlice { reqId: string | undefined feedPostUri: string reason?: - | app.bsky.feed.defs.ReasonRepost - | app.bsky.feed.defs.ReasonPin + | AppBskyFeedDefs.ReasonRepost + | AppBskyFeedDefs.ReasonPin | ReasonFeedSource | {[k: string]: unknown; $type: string} } @@ -106,7 +108,7 @@ export interface FeedPostSlice { export interface FeedPageUnselected { api: FeedAPI cursor: string | undefined - feed: app.bsky.feed.defs.FeedViewPost[] + feed: AppBskyFeedDefs.FeedViewPost[] fetchedAt: number } @@ -511,7 +513,7 @@ function createApi({ export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const atUri = new AtUri(uri) const queryDatas = queryClient.getQueriesData< @@ -534,7 +536,7 @@ export function* findAllPostsInQueryData( yield embedViewRecordToPostView(quotedPost) } - if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.reply?.parent)) { if (didOrHandleUriMatches(atUri, item.reply.parent)) { yield item.reply.parent } @@ -548,7 +550,7 @@ export function* findAllPostsInQueryData( } } - if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.root)) { + if (bsky.isType(AppBskyFeedDefs.postView, item.reply?.root)) { if (didOrHandleUriMatches(atUri, item.reply.root)) { yield item.reply.root } @@ -566,7 +568,7 @@ export function* findAllPostsInQueryData( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< InfiniteData >({ @@ -586,13 +588,13 @@ export function* findAllProfilesInQueryData( yield quotedPost.author } if ( - bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent) && + bsky.isType(AppBskyFeedDefs.postView, item.reply?.parent) && item.reply?.parent?.author.did === did ) { yield item.reply.parent.author } if ( - bsky.isType(app.bsky.feed.defs.postView, item.reply?.root) && + bsky.isType(AppBskyFeedDefs.postView, item.reply?.root) && item.reply?.root?.author.did === did ) { yield item.reply.root.author @@ -603,7 +605,7 @@ export function* findAllProfilesInQueryData( } function assertSomePostsPassModeration( - feed: app.bsky.feed.defs.FeedViewPost[], + feed: AppBskyFeedDefs.FeedViewPost[], moderationPrefs: ModerationPrefs, ) { // no posts in this feed diff --git a/src/state/queries/post-liked-by.ts b/src/state/queries/post-liked-by.ts index 0964d0be24..1ce3c9496e 100644 --- a/src/state/queries/post-liked-by.ts +++ b/src/state/queries/post-liked-by.ts @@ -10,7 +10,8 @@ import { import {STALE} from '#/state/queries' import {createQueryKey} from '#/state/queries/util' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedGetLikes from '#/lexicons/app/bsky/feed/getLikes' const PAGE_SIZE = 30 type RQPageParam = string | undefined @@ -22,15 +23,15 @@ export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export function useLikedByQuery(resolvedUri: string | undefined) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.feed.getLikes.$OutputBody, + AppBskyFeedGetLikes.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(resolvedUri || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.feed.getLikes, { + return await client.call(AppBskyFeedGetLikes, { // the enabled flag prevents this from running until resolvedUri is set uri: (resolvedUri || '') as AtUriString, limit: PAGE_SIZE, @@ -64,7 +65,7 @@ export function useLikedBySampleQuery({uri}: {uri: string | undefined}) { return useQuery({ queryKey: createLikedBySampleQueryKey({uri: uri ?? ''}), queryFn: async () => { - return await client.call(app.bsky.feed.getLikes, { + return await client.call(AppBskyFeedGetLikes, { uri: (uri ?? '') as AtUriString, limit: SAMPLE_SIZE, }) @@ -82,9 +83,9 @@ export function useLikedBySampleQuery({uri}: {uri: string | undefined}) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) @@ -101,7 +102,7 @@ export function* findAllProfilesInQueryData( } } const sampleQueryDatas = - queryClient.getQueriesData({ + queryClient.getQueriesData({ queryKey: [likedBySampleQueryKeyRoot], }) for (const [_queryKey, queryData] of sampleQueryDatas) { diff --git a/src/state/queries/post-quotes.ts b/src/state/queries/post-quotes.ts index c0bdb70ef9..e0e5b2a657 100644 --- a/src/state/queries/post-quotes.ts +++ b/src/state/queries/post-quotes.ts @@ -7,7 +7,10 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetQuotes from '#/lexicons/app/bsky/feed/getQuotes' import * as bsky from '#/types/bsky' import { didOrHandleUriMatches, @@ -24,15 +27,15 @@ export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export function usePostQuotesQuery(resolvedUri: string | undefined) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.feed.getQuotes.$OutputBody, + AppBskyFeedGetQuotes.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(resolvedUri || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.feed.getQuotes, { + return await client.call(AppBskyFeedGetQuotes, { // the enabled flag prevents this from running until resolvedUri is set uri: (resolvedUri || '') as AtUriString, limit: PAGE_SIZE, @@ -51,11 +54,11 @@ export function usePostQuotesQuery(resolvedUri: string | undefined) { posts: page.posts.filter(post => { if ( post.embed && - bsky.isType(app.bsky.embed.record.view, post.embed) + bsky.isType(AppBskyEmbedRecord.view, post.embed) ) { if ( bsky.isType( - app.bsky.embed.record.viewDetached, + AppBskyEmbedRecord.viewDetached, post.embed.record, ) ) { @@ -74,9 +77,9 @@ export function usePostQuotesQuery(resolvedUri: string | undefined) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) @@ -101,9 +104,9 @@ export function* findAllProfilesInQueryData( export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/post-reposted-by.ts b/src/state/queries/post-reposted-by.ts index 03a0f65126..34a55072c3 100644 --- a/src/state/queries/post-reposted-by.ts +++ b/src/state/queries/post-reposted-by.ts @@ -7,7 +7,8 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedGetRepostedBy from '#/lexicons/app/bsky/feed/getRepostedBy' const PAGE_SIZE = 30 type RQPageParam = string | undefined @@ -19,15 +20,15 @@ export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export function usePostRepostedByQuery(resolvedUri: string | undefined) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.feed.getRepostedBy.$OutputBody, + AppBskyFeedGetRepostedBy.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(resolvedUri || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.feed.getRepostedBy, { + return await client.call(AppBskyFeedGetRepostedBy, { // the enabled flag prevents this from running until resolvedUri is set uri: (resolvedUri || '') as AtUriString, limit: PAGE_SIZE, @@ -43,9 +44,9 @@ export function usePostRepostedByQuery(resolvedUri: string | undefined) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts index 49dfdf0998..deff069fcc 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -16,7 +16,12 @@ import {useAppviewClient, usePdsClient, useSession} from '#/state/session' import * as userActionHistory from '#/state/userActionHistory' import {useAnalytics} from '#/analytics' import {type Metrics, toClout} from '#/analytics/metrics' -import {app, com} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedGetPosts from '#/lexicons/app/bsky/feed/getPosts' +import * as AppBskyGraphMuteThread from '#/lexicons/app/bsky/graph/muteThread' +import * as AppBskyGraphUnmuteThread from '#/lexicons/app/bsky/graph/unmuteThread' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' import {useIsThreadMuted, useSetThreadMute} from '../cache/thread-mutes' import {findProfileQueryData} from './profile' @@ -25,7 +30,7 @@ export const RQKEY = (postUri: string) => [RQKEY_ROOT, postUri] export function usePostQuery(uri: string | undefined) { const client = useAppviewClient() - return useQuery({ + return useQuery({ queryKey: RQKEY(uri || ''), queryFn: async () => { if (!uri) throw new Error('[unreachable] No URI provided') @@ -51,17 +56,17 @@ export function usePostQuery(uri: string | undefined) { async function fetchPost( client: Client, uri: string, -): Promise { +): Promise { const urip = new AtUri(uri) if (!urip.host.startsWith('did:')) { - const data = await client.call(com.atproto.identity.resolveHandle, { + const data = await client.call(ComAtprotoIdentityResolveHandle, { handle: urip.host as HandleString, }) urip.host = data.did } - const data = await client.call(app.bsky.feed.getPosts, { + const data = await client.call(AppBskyFeedGetPosts, { uris: [urip.toString()], }) return data.posts[0] @@ -70,7 +75,7 @@ async function fetchPost( export function precachePost( queryClient: QueryClient, uri: string, - post: app.bsky.feed.defs.PostView, + post: AppBskyFeedDefs.PostView, ) { queryClient.setQueryData(RQKEY(uri), post) } @@ -104,7 +109,7 @@ export function useGetPosts() { return queryClient.fetchQuery({ queryKey: RQKEY(uris.join(',') || ''), async queryFn() { - const data = await client.call(app.bsky.feed.getPosts, { + const data = await client.call(AppBskyFeedGetPosts, { uris: uris as AtUriString[], }) // See the note on `fetchPost` about the view shapes. @@ -117,7 +122,7 @@ export function useGetPosts() { } export function usePostLikeMutationQueue( - post: Shadow, + post: Shadow, viaRepost: {uri: string; cid: string} | undefined, feedDescriptor: string | undefined, logContext: Metrics['post:like']['logContext'], @@ -181,7 +186,7 @@ export function usePostLikeMutationQueue( function usePostLikeMutation( feedDescriptor: string | undefined, logContext: Metrics['post:like']['logContext'], - post: Shadow, + post: Shadow, ) { const {currentAccount} = useSession() const queryClient = useQueryClient() @@ -194,7 +199,7 @@ function usePostLikeMutation( {uri: string; cid: string; via?: {uri: string; cid: string}} // the post's uri and cid, and the repost uri/cid if present >({ mutationFn: ({uri, cid, via}) => { - let ownProfile: app.bsky.actor.defs.ProfileViewDetailed | undefined + let ownProfile: AppBskyActorDefs.ProfileViewDetailed | undefined if (currentAccount) { ownProfile = findProfileQueryData(queryClient, currentAccount.did) } @@ -229,7 +234,7 @@ function usePostLikeMutation( function usePostUnlikeMutation( feedDescriptor: string | undefined, logContext: Metrics['post:unlike']['logContext'], - post: Shadow, + post: Shadow, ) { const pdsClient = usePdsClient() const ax = useAnalytics() @@ -247,7 +252,7 @@ function usePostUnlikeMutation( } export function usePostRepostMutationQueue( - post: Shadow, + post: Shadow, viaRepost: {uri: string; cid: string} | undefined, feedDescriptor: string | undefined, logContext: Metrics['post:repost']['logContext'], @@ -313,7 +318,7 @@ export function usePostRepostMutationQueue( function usePostRepostMutation( feedDescriptor: string | undefined, logContext: Metrics['post:repost']['logContext'], - post: Shadow, + post: Shadow, ) { const pdsClient = usePdsClient() const ax = useAnalytics() @@ -341,7 +346,7 @@ function usePostRepostMutation( function usePostUnrepostMutation( feedDescriptor: string | undefined, logContext: Metrics['post:unrepost']['logContext'], - post: Shadow, + post: Shadow, ) { const pdsClient = usePdsClient() const ax = useAnalytics() @@ -372,7 +377,7 @@ export function usePostDeleteMutation() { } export function useThreadMuteMutationQueue( - post: Shadow, + post: Shadow, rootUri: string, ) { const threadMuteMutation = useThreadMuteMutation() @@ -424,7 +429,7 @@ function useThreadMuteMutation() { {uri: string} // the root post's uri >({ mutationFn: async ({uri}) => { - await appviewClient.call(app.bsky.graph.muteThread, { + await appviewClient.call(AppBskyGraphMuteThread, { root: uri as AtUriString, }) return {} @@ -436,7 +441,7 @@ function useThreadUnmuteMutation() { const appviewClient = useAppviewClient() return useMutation<{}, Error, {uri: string}>({ mutationFn: async ({uri}) => { - await appviewClient.call(app.bsky.graph.unmuteThread, { + await appviewClient.call(AppBskyGraphUnmuteThread, { root: uri as AtUriString, }) return {} diff --git a/src/state/queries/postgate/index.ts b/src/state/queries/postgate/index.ts index 08dff1a45c..f4a58e79ad 100644 --- a/src/state/queries/postgate/index.ts +++ b/src/state/queries/postgate/index.ts @@ -16,7 +16,13 @@ import { POSTGATE_COLLECTION, } from '#/state/queries/postgate/util' import {usePdsClient} from '#/state/session' -import {app, com} from '#/lexicons' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPostgate from '#/lexicons/app/bsky/feed/postgate' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' +import * as ComAtprotoRepoGetRecord from '#/lexicons/com/atproto/repo/getRecord' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import * as bsky from '#/types/bsky' export async function getPostgateRecord({ @@ -25,11 +31,11 @@ export async function getPostgateRecord({ }: { pdsClient: Client postUri: string -}): Promise { +}): Promise { const urip = new AtUri(postUri) if (!urip.host.startsWith('did:')) { - const {did} = await pdsClient.call(com.atproto.identity.resolveHandle, { + const {did} = await pdsClient.call(ComAtprotoIdentityResolveHandle, { handle: urip.host as HandleString, }) urip.host = did @@ -50,14 +56,14 @@ export async function getPostgateRecord({ return true }, () => - pdsClient.call(com.atproto.repo.getRecord, { + pdsClient.call(ComAtprotoRepoGetRecord, { repo: urip.host, collection: POSTGATE_COLLECTION, rkey: urip.rkeySafe, }), ) - if (data.value && bsky.matches(app.bsky.feed.postgate, data.value)) { + if (data.value && bsky.matches(AppBskyFeedPostgate, data.value)) { return data.value } else { return undefined @@ -83,12 +89,12 @@ export async function writePostgateRecord({ }: { pdsClient: Client postUri: string - postgate: app.bsky.feed.postgate.Main + postgate: AppBskyFeedPostgate.Main }) { const postUrip = new AtUri(postUri) await networkRetry(2, () => - pdsClient.call(com.atproto.repo.putRecord, { + pdsClient.call(ComAtprotoRepoPutRecord, { repo: pdsClient.assertDid, collection: POSTGATE_COLLECTION, rkey: postUrip.rkeySafe, @@ -106,8 +112,8 @@ export async function upsertPostgate( postUri: string }, callback: ( - postgate: app.bsky.feed.postgate.Main | undefined, - ) => Promise, + postgate: AppBskyFeedPostgate.Main | undefined, + ) => Promise, ) { const prev = await getPostgateRecord({ pdsClient, @@ -148,7 +154,7 @@ export function useWritePostgateMutation() { postgate, }: { postUri: string - postgate: app.bsky.feed.postgate.Main + postgate: AppBskyFeedPostgate.Main }) => { return writePostgateRecord({ pdsClient, @@ -168,7 +174,7 @@ export function useToggleQuoteDetachmentMutation() { const pdsClient = usePdsClient() const queryClient = useQueryClient() const getPosts = useGetPosts() - const prevEmbed = useRef(undefined) + const prevEmbed = useRef(undefined) return useMutation({ mutationFn: async ({ @@ -176,7 +182,7 @@ export function useToggleQuoteDetachmentMutation() { quoteUri, action, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView quoteUri: AtUriString action: 'detach' | 'reattach' }) => { @@ -242,8 +248,8 @@ export function useToggleQuoteDetachmentMutation() { if (action === 'detach' && prevEmbed.current) { // detach failed, add the embed back if ( - bsky.isType(app.bsky.embed.record.view, prevEmbed.current) || - bsky.isType(app.bsky.embed.recordWithMedia.view, prevEmbed.current) + bsky.isType(AppBskyEmbedRecord.view, prevEmbed.current) || + bsky.isType(AppBskyEmbedRecordWithMedia.view, prevEmbed.current) ) { updatePostShadow(queryClient, post.uri, { embed: prevEmbed.current, diff --git a/src/state/queries/postgate/util.ts b/src/state/queries/postgate/util.ts index 97f85e9369..ba6381c65d 100644 --- a/src/state/queries/postgate/util.ts +++ b/src/state/queries/postgate/util.ts @@ -1,7 +1,10 @@ import {type $Typed} from '@atproto/lex' import {AtUri, type AtUriString, toDatetimeString} from '@atproto/syntax' -import {app} from '#/lexicons' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import type * as AppBskyFeedPostgate from '#/lexicons/app/bsky/feed/postgate' import * as bsky from '#/types/bsky' export const POSTGATE_COLLECTION = 'app.bsky.feed.postgate' @@ -13,13 +16,13 @@ export const POSTGATE_COLLECTION = 'app.bsky.feed.postgate' */ export function createPostgateRecord( postgate: Omit< - Partial, + Partial, 'post' | 'detachedEmbeddingUris' > & { post: string detachedEmbeddingUris?: string[] }, -): app.bsky.feed.postgate.Main { +): AppBskyFeedPostgate.Main { return { $type: POSTGATE_COLLECTION, createdAt: toDatetimeString(new Date()), @@ -31,8 +34,8 @@ export function createPostgateRecord( } export function mergePostgateRecords( - prev: app.bsky.feed.postgate.Main, - next: Omit, 'detachedEmbeddingUris'> & { + prev: AppBskyFeedPostgate.Main, + next: Omit, 'detachedEmbeddingUris'> & { detachedEmbeddingUris?: string[] }, ) { @@ -59,8 +62,8 @@ export function createEmbedViewDetachedRecord({ uri, }: { uri: AtUriString -}): $Typed { - const record: $Typed = { +}): $Typed { + const record: $Typed = { $type: 'app.bsky.embed.record#viewDetached', uri, detached: true, @@ -78,25 +81,24 @@ export function createMaybeDetachedQuoteEmbed({ detached, }: | { - post: app.bsky.feed.defs.PostView - quote: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView + quote: AppBskyFeedDefs.PostView quoteUri: undefined detached: false } | { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView quote: undefined quoteUri: AtUriString detached: true - }): - app.bsky.embed.record.View | app.bsky.embed.recordWithMedia.View | undefined { - if (bsky.isType(app.bsky.embed.record.view, post.embed)) { + }): AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined { + if (bsky.isType(AppBskyEmbedRecord.view, post.embed)) { if (detached) { return createEmbedViewDetachedRecord({uri: quoteUri}) } else { return createEmbedRecordView({post: quote}) } - } else if (bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) { + } else if (bsky.isType(AppBskyEmbedRecordWithMedia.view, post.embed)) { if (detached) { return { ...post.embed, @@ -109,8 +111,8 @@ export function createMaybeDetachedQuoteEmbed({ } export function createEmbedViewRecordFromPost( - post: app.bsky.feed.defs.PostView, -): $Typed { + post: AppBskyFeedDefs.PostView, +): $Typed { return { $type: 'app.bsky.embed.record#viewRecord', uri: post.uri, @@ -130,8 +132,8 @@ export function createEmbedViewRecordFromPost( export function createEmbedRecordView({ post, }: { - post: app.bsky.feed.defs.PostView -}): app.bsky.embed.record.View { + post: AppBskyFeedDefs.PostView +}): AppBskyEmbedRecord.View { return { $type: 'app.bsky.embed.record#view', record: createEmbedViewRecordFromPost(post), @@ -142,10 +144,10 @@ export function createEmbedRecordWithMediaView({ post, quote, }: { - post: app.bsky.feed.defs.PostView - quote: app.bsky.feed.defs.PostView -}): app.bsky.embed.recordWithMedia.View | undefined { - if (!bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) return + post: AppBskyFeedDefs.PostView + quote: AppBskyFeedDefs.PostView +}): AppBskyEmbedRecordWithMedia.View | undefined { + if (!bsky.isType(AppBskyEmbedRecordWithMedia.view, post.embed)) return return { ...(post.embed || {}), record: { @@ -159,11 +161,11 @@ export function getMaybeDetachedQuoteEmbed({ post, }: { viewerDid: string - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView }) { - if (bsky.isType(app.bsky.embed.record.view, post.embed)) { + if (bsky.isType(AppBskyEmbedRecord.view, post.embed)) { // detached - if (bsky.isType(app.bsky.embed.record.viewDetached, post.embed.record)) { + if (bsky.isType(AppBskyEmbedRecord.viewDetached, post.embed.record)) { const urip = new AtUri(post.embed.record.uri) return { embed: post.embed, @@ -174,7 +176,7 @@ export function getMaybeDetachedQuoteEmbed({ } // post - if (bsky.isType(app.bsky.embed.record.viewRecord, post.embed.record)) { + if (bsky.isType(AppBskyEmbedRecord.viewRecord, post.embed.record)) { const urip = new AtUri(post.embed.record.uri) return { embed: post.embed, @@ -183,10 +185,10 @@ export function getMaybeDetachedQuoteEmbed({ isDetached: false, } } - } else if (bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) { + } else if (bsky.isType(AppBskyEmbedRecordWithMedia.view, post.embed)) { // detached if ( - bsky.isType(app.bsky.embed.record.viewDetached, post.embed.record.record) + bsky.isType(AppBskyEmbedRecord.viewDetached, post.embed.record.record) ) { const urip = new AtUri(post.embed.record.record.uri) return { @@ -198,9 +200,7 @@ export function getMaybeDetachedQuoteEmbed({ } // post - if ( - bsky.isType(app.bsky.embed.record.viewRecord, post.embed.record.record) - ) { + if (bsky.isType(AppBskyEmbedRecord.viewRecord, post.embed.record.record)) { const urip = new AtUri(post.embed.record.record.uri) return { embed: post.embed, diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 912a87a1ba..83a473fd6d 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -43,7 +43,8 @@ import {applyLabelersToClient, saveLabelers} from '#/state/session/moderation' import {useAgeAssurance} from '#/ageAssurance' import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorPutPreferences from '#/lexicons/app/bsky/actor/putPreferences' export * from '#/state/queries/preferences/const' export * from '#/state/queries/preferences/moderation' @@ -155,7 +156,7 @@ export function useClearPreferencesMutation() { return useMutation({ mutationFn: async () => { - await client.call(app.bsky.actor.putPreferences, {preferences: []}) + await client.call(AppBskyActorPutPreferences, {preferences: []}) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -277,7 +278,7 @@ export function useOverwriteSavedFeedsMutation() { const queryClient = useQueryClient() const client = usePdsClient() - return useMutation({ + return useMutation({ mutationFn: async savedFeeds => { await client.call(overwriteSavedFeeds, savedFeeds) // triggers a refetch @@ -295,7 +296,7 @@ export function useAddSavedFeedsMutation() { return useMutation< void, unknown, - Pick[] + Pick[] >({ mutationFn: async savedFeeds => { await client.call(addSavedFeeds, savedFeeds) @@ -311,7 +312,7 @@ export function useRemoveFeedMutation() { const queryClient = useQueryClient() const client = usePdsClient() - return useMutation>({ + return useMutation>({ mutationFn: async savedFeed => { await client.call(removeSavedFeeds, [savedFeed.id]) // triggers a refetch @@ -331,8 +332,8 @@ export function useReplaceForYouWithDiscoverFeedMutation() { forYouFeedConfig, discoverFeedConfig, }: { - forYouFeedConfig: app.bsky.actor.defs.SavedFeed | undefined - discoverFeedConfig: app.bsky.actor.defs.SavedFeed | undefined + forYouFeedConfig: AppBskyActorDefs.SavedFeed | undefined + discoverFeedConfig: AppBskyActorDefs.SavedFeed | undefined }) => { if (forYouFeedConfig) { await client.call(removeSavedFeeds, [forYouFeedConfig.id]) @@ -365,7 +366,7 @@ export function useUpdateSavedFeedsMutation() { const queryClient = useQueryClient() const client = usePdsClient() - return useMutation({ + return useMutation({ mutationFn: async feeds => { await client.call(updateSavedFeeds, feeds) @@ -382,7 +383,7 @@ export function useUpsertMutedWordsMutation() { const client = usePdsClient() return useMutation({ - mutationFn: async (mutedWords: app.bsky.actor.defs.MutedWord[]) => { + mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => { await client.call(upsertMutedWords, mutedWords) // triggers a refetch await queryClient.invalidateQueries({ @@ -397,7 +398,7 @@ export function useUpdateMutedWordMutation() { const client = usePdsClient() return useMutation({ - mutationFn: async (mutedWord: app.bsky.actor.defs.MutedWord) => { + mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { await client.call(updateMutedWord, mutedWord) // triggers a refetch await queryClient.invalidateQueries({ @@ -412,7 +413,7 @@ export function useRemoveMutedWordMutation() { const client = usePdsClient() return useMutation({ - mutationFn: async (mutedWord: app.bsky.actor.defs.MutedWord) => { + mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { await client.call(removeMutedWord, mutedWord) // triggers a refetch await queryClient.invalidateQueries({ @@ -427,7 +428,7 @@ export function useRemoveMutedWordsMutation() { const client = usePdsClient() return useMutation({ - mutationFn: async (mutedWords: app.bsky.actor.defs.MutedWord[]) => { + mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => { await client.call(removeMutedWords, mutedWords) // triggers a refetch await queryClient.invalidateQueries({ @@ -476,7 +477,7 @@ export function useSetActiveProgressGuideMutation() { return useMutation({ mutationFn: async ( - guide: app.bsky.actor.defs.BskyAppProgressGuide | undefined, + guide: AppBskyActorDefs.BskyAppProgressGuide | undefined, ) => { await client.call(setActiveProgressGuide, guide) // triggers a refetch @@ -507,7 +508,7 @@ export function useSetVerificationPrefsMutation() { const queryClient = useQueryClient() const client = usePdsClient() - return useMutation({ + return useMutation({ mutationFn: async prefs => { await client.call(setVerificationPrefs, prefs) if (prefs.hideBadges) { diff --git a/src/state/queries/profile-feedgens.ts b/src/state/queries/profile-feedgens.ts index dffc869512..f6898b9887 100644 --- a/src/state/queries/profile-feedgens.ts +++ b/src/state/queries/profile-feedgens.ts @@ -7,7 +7,7 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyFeedGetActorFeeds from '#/lexicons/app/bsky/feed/getActorFeeds' import {useModerationOpts} from '../preferences/moderation-opts' const PAGE_SIZE = 50 @@ -25,15 +25,15 @@ export function useProfileFeedgensQuery( const enabled = opts?.enabled !== false && Boolean(moderationOpts) const client = useAppviewClient() return useInfiniteQuery< - app.bsky.feed.getActorFeeds.$OutputBody, + AppBskyFeedGetActorFeeds.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(did), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const data = await client.call(app.bsky.feed.getActorFeeds, { + const data = await client.call(AppBskyFeedGetActorFeeds, { actor: did as DidString, limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile-followers.ts b/src/state/queries/profile-followers.ts index 59f3c4e842..440f3fde90 100644 --- a/src/state/queries/profile-followers.ts +++ b/src/state/queries/profile-followers.ts @@ -7,7 +7,8 @@ import { import {useAppviewClient} from '#/state/session' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetFollowers from '#/lexicons/app/bsky/graph/getFollowers' const DEFAULT_SORT = 'latest' const PAGE_SIZE = 30 @@ -35,9 +36,9 @@ export function useProfileFollowersQuery( const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined return useInfiniteQuery< - app.bsky.graph.getFollowers.$OutputBody, + AppBskyGraphGetFollowers.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ @@ -49,12 +50,12 @@ export function useProfileFollowersQuery( * undeclared params verbatim but rejects an undeclared key whose value * is `undefined`, hence the conditional spread. */ - return await client.call(app.bsky.graph.getFollowers, { + return await client.call(AppBskyGraphGetFollowers, { actor: did || '', limit: PAGE_SIZE, cursor: pageParam, ...(sortParam ? {sort: sortParam} : {}), - } as app.bsky.graph.getFollowers.$Params) + } as AppBskyGraphGetFollowers.$Params) }, initialPageParam: undefined, getNextPageParam: lastPage => lastPage.cursor, @@ -65,9 +66,9 @@ export function useProfileFollowersQuery( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/profile-follows.ts b/src/state/queries/profile-follows.ts index 0f684054b9..7655cb1997 100644 --- a/src/state/queries/profile-follows.ts +++ b/src/state/queries/profile-follows.ts @@ -8,7 +8,8 @@ import { import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyGraphGetFollows from '#/lexicons/app/bsky/graph/getFollows' const DEFAULT_SORT = 'latest' const PAGE_SIZE = 30 @@ -39,9 +40,9 @@ export function useProfileFollowsQuery( const sortParam = isSortEnabled ? sort || DEFAULT_SORT : undefined return useInfiniteQuery< - app.bsky.graph.getFollows.$OutputBody, + AppBskyGraphGetFollows.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ @@ -54,12 +55,12 @@ export function useProfileFollowsQuery( * undeclared params verbatim but rejects an undeclared key whose value * is `undefined`, hence the conditional spread. */ - return await client.call(app.bsky.graph.getFollows, { + return await client.call(AppBskyGraphGetFollows, { actor: did || '', limit: limit || PAGE_SIZE, cursor: pageParam, ...(sortParam ? {sort: sortParam} : {}), - } as app.bsky.graph.getFollows.$Params) + } as AppBskyGraphGetFollows.$Params) }, initialPageParam: undefined, getNextPageParam: lastPage => lastPage.cursor, @@ -70,9 +71,9 @@ export function useProfileFollowsQuery( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [RQKEY_ROOT], }) diff --git a/src/state/queries/profile-lists.ts b/src/state/queries/profile-lists.ts index 0d466aff29..b6a5a95163 100644 --- a/src/state/queries/profile-lists.ts +++ b/src/state/queries/profile-lists.ts @@ -7,7 +7,7 @@ import { } from '@tanstack/react-query' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyGraphGetLists from '#/lexicons/app/bsky/graph/getLists' import {useModerationOpts} from '../preferences/moderation-opts' const PAGE_SIZE = 30 @@ -21,15 +21,15 @@ export function useProfileListsQuery(did: string, opts?: {enabled?: boolean}) { const enabled = opts?.enabled !== false && Boolean(moderationOpts) const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.getLists.$OutputBody, + AppBskyGraphGetLists.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, RQPageParam >({ queryKey: RQKEY(did), async queryFn({pageParam}: {pageParam: RQPageParam}) { - return await client.call(app.bsky.graph.getLists, { + return await client.call(AppBskyGraphGetLists, { actor: did as DidString, limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index dcfcba82bb..0c64c0fdef 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -41,7 +41,13 @@ import {useAppviewClient, usePdsClient, useSession} from '#/state/session' import * as userActionHistory from '#/state/userActionHistory' import {useAnalytics} from '#/analytics' import {type Metrics, toClout} from '#/analytics/metrics' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as AppBskyActorGetProfiles from '#/lexicons/app/bsky/actor/getProfiles' +import type * as AppBskyActorProfile from '#/lexicons/app/bsky/actor/profile' +import * as AppBskyGraphBlock from '#/lexicons/app/bsky/graph/block' +import type * as AppBskyGraphGetFollows from '#/lexicons/app/bsky/graph/getFollows' +import * as AppBskyGraphGetSuggestedFollowsByActor from '#/lexicons/app/bsky/graph/getSuggestedFollowsByActor' import type * as bsky from '#/types/bsky' import { ProgressGuideAction, @@ -75,7 +81,7 @@ export function useProfileQuery({ }) { const client = useAppviewClient() const {getUnstableProfile} = useUnstableProfileViewCache() - return useQuery({ + return useQuery({ // WARNING // this staleTime is load-bearing // if you remove it, the UI infinite-loops @@ -84,13 +90,13 @@ export function useProfileQuery({ refetchOnWindowFocus: true, queryKey: RQKEY(did ?? ''), queryFn: async () => { - return await client.call(app.bsky.actor.getProfile, { + return await client.call(AppBskyActorGetProfile, { actor: (did ?? '') as AtIdentifierString, }) }, placeholderData: () => { if (!did) return - return getUnstableProfile(did) as app.bsky.actor.defs.ProfileViewDetailed + return getUnstableProfile(did) as AppBskyActorDefs.ProfileViewDetailed }, enabled: !!did, }) @@ -109,7 +115,7 @@ export function useProfilesQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: profilesQueryKey(handles), queryFn: async () => { - return await client.call(app.bsky.actor.getProfiles, { + return await client.call(AppBskyActorGetProfiles, { actors: handles as AtIdentifierString[], }) }, @@ -126,7 +132,7 @@ export function usePrefetchProfileQuery() { staleTime: STALE.SECONDS.THIRTY, queryKey: RQKEY(did), queryFn: async () => { - return await client.call(app.bsky.actor.getProfile, { + return await client.call(AppBskyActorGetProfile, { actor: (did || '') as AtIdentifierString, }) }, @@ -138,15 +144,15 @@ export function usePrefetchProfileQuery() { } interface ProfileUpdateParams { - profile: app.bsky.actor.defs.ProfileViewDetailed + profile: AppBskyActorDefs.ProfileViewDetailed updates: - | Un$Typed + | Un$Typed | (( - existing: Un$Typed, - ) => Un$Typed) + existing: Un$Typed, + ) => Un$Typed) newUserAvatar?: ImageMeta | undefined | null newUserBanner?: ImageMeta | undefined | null - checkCommitted?: (profile: app.bsky.actor.getProfile.$OutputBody) => boolean + checkCommitted?: (profile: AppBskyActorGetProfile.$OutputBody) => boolean } export function useProfileUpdateMutation() { const queryClient = useQueryClient() @@ -178,7 +184,7 @@ export function useProfileUpdateMutation() { ) } await pdsClient.call(upsertProfile, async existing => { - let next: Un$Typed = existing || {} + let next: Un$Typed = existing || {} if (typeof updates === 'function') { next = updates(next) } else { @@ -295,8 +301,7 @@ export function useProfileFollowMutationQueue( // Optimistically update profile follows cache for avatar displays if (currentAccount?.did) { - type FollowsQueryData = - InfiniteData + type FollowsQueryData = InfiniteData queryClient.setQueryData( PROFILE_FOLLOWS_RQKEY(currentAccount.did), old => { @@ -313,7 +318,7 @@ export function useProfileFollowMutationQueue( { ...old.pages[0], follows: [ - profile as app.bsky.actor.defs.ProfileView, + profile as AppBskyActorDefs.ProfileView, ...old.pages[0].follows, ], }, @@ -336,7 +341,7 @@ export function useProfileFollowMutationQueue( if (finalFollowingUri) { void client - .call(app.bsky.graph.getSuggestedFollowsByActor, { + .call(AppBskyGraphGetSuggestedFollowsByActor, { actor: did, }) .then(res => { @@ -383,7 +388,7 @@ function useProfileFollowMutation( return useMutation<{uri: AtUriString; cid: string}, Error, {did: string}>({ mutationFn: async ({did}) => { - let ownProfile: app.bsky.actor.defs.ProfileViewDetailed | undefined + let ownProfile: AppBskyActorDefs.ProfileViewDetailed | undefined if (currentAccount) { ownProfile = findProfileQueryData(queryClient, currentAccount.did) } @@ -641,7 +646,7 @@ function useProfileBlockMutation() { if (!currentAccount) { throw new Error('Not signed in') } - return await pdsClient.create(app.bsky.graph.block, { + return await pdsClient.create(AppBskyGraphBlock, { // the mutation takes the did as a plain string subject: did as DidString, createdAt: toDatetimeString(new Date()), @@ -664,7 +669,7 @@ function useProfileUnblockMutation() { throw new Error('Not signed in') } const {rkeySafe: rkey} = new AtUri(blockUri) - await pdsClient.delete(app.bsky.graph.block, { + await pdsClient.delete(AppBskyGraphBlock, { repo: currentAccount.did, rkey, }) @@ -678,14 +683,14 @@ function useProfileUnblockMutation() { async function whenAppViewReady( client: Client, actor: string, - fn: (profile: app.bsky.actor.getProfile.$OutputBody) => boolean, + fn: (profile: AppBskyActorGetProfile.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, async () => - await client.call(app.bsky.actor.getProfile, { + await client.call(AppBskyActorGetProfile, { actor: actor as AtIdentifierString, }), ) @@ -694,9 +699,9 @@ async function whenAppViewReady( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const profileQueryDatas = - queryClient.getQueriesData({ + queryClient.getQueriesData({ queryKey: [RQKEY_ROOT], }) for (const [_queryKey, queryData] of profileQueryDatas) { @@ -708,7 +713,7 @@ export function* findAllProfilesInQueryData( } } const profilesQueryDatas = - queryClient.getQueriesData({ + queryClient.getQueriesData({ queryKey: [profilesQueryKeyRoot], }) for (const [_queryKey, queryData] of profilesQueryDatas) { @@ -726,8 +731,8 @@ export function* findAllProfilesInQueryData( export function findProfileQueryData( queryClient: QueryClient, did: string, -): app.bsky.actor.defs.ProfileViewDetailed | undefined { - return queryClient.getQueryData( +): AppBskyActorDefs.ProfileViewDetailed | undefined { + return queryClient.getQueryData( RQKEY(did), ) } diff --git a/src/state/queries/resolve-uri.ts b/src/state/queries/resolve-uri.ts index ba2e9f933c..3597a3f5d7 100644 --- a/src/state/queries/resolve-uri.ts +++ b/src/state/queries/resolve-uri.ts @@ -4,7 +4,7 @@ import {type QueryClient, queryOptions, useQuery} from '@tanstack/react-query' import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {com} from '#/lexicons' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' import {useUnstableProfileViewCache} from './profile' const RQKEY_ROOT = 'resolved-did' @@ -28,7 +28,7 @@ const resolvedDidQueryOptions = ( * to the appview, and the PDS implementation is not equivalent for * handles hosted elsewhere. */ - const data = await client.call(com.atproto.identity.resolveHandle, { + const data = await client.call(ComAtprotoIdentityResolveHandle, { handle: didOrHandle as HandleString, }) return data.did diff --git a/src/state/queries/search-posts-v2.ts b/src/state/queries/search-posts-v2.ts index acb69f57d4..4dc7eba280 100644 --- a/src/state/queries/search-posts-v2.ts +++ b/src/state/queries/search-posts-v2.ts @@ -11,7 +11,8 @@ import { import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useAppviewClient} from '#/state/session' import {type SearchFilters} from '#/screens/Search/searchParams' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedSearchPostsV2 from '#/lexicons/app/bsky/feed/searchPostsV2' import { appendFromMe, buildSearchPostsV2Filters, @@ -56,15 +57,15 @@ export function useSearchPostsV2Query({ [query, filters?.author, filters?.from, moderationOpts], ) const lastRun = useRef<{ - data: InfiniteData + data: InfiniteData args: typeof selectArgs - result: InfiniteData + result: InfiniteData } | null>(null) return useInfiniteQuery< - app.bsky.feed.searchPostsV2.$OutputBody, + AppBskyFeedSearchPostsV2.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, string | undefined >({ @@ -85,9 +86,9 @@ export function useSearchPostsV2Query({ const builtFilters = buildSearchPostsV2Filters( embedded, filters, - ) as app.bsky.feed.searchPostsV2.$Params + ) as AppBskyFeedSearchPostsV2.$Params const finalQuery = appendFromMe(q, filters?.from === 'me') - return await client.call(app.bsky.feed.searchPostsV2, { + return await client.call(AppBskyFeedSearchPostsV2, { ...builtFilters, query: finalQuery, limit: 25, @@ -104,7 +105,7 @@ export function useSearchPostsV2Query({ getNextPageParam: lastPage => lastPage.cursor, enabled: enabled ?? !!moderationOpts, select: useCallback( - (data: InfiniteData) => { + (data: InfiniteData) => { const {moderationOpts, isSearchingSpecificUser} = selectArgs /* @@ -180,9 +181,9 @@ export function useSearchPostsV2Query({ export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [searchPostsQueryKeyRoot], }) diff --git a/src/state/queries/service-config.ts b/src/state/queries/service-config.ts index e9f8277b46..73c48f4713 100644 --- a/src/state/queries/service-config.ts +++ b/src/state/queries/service-config.ts @@ -2,7 +2,7 @@ import {useQuery} from '@tanstack/react-query' import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetConfig from '#/lexicons/app/bsky/unspecced/getConfig' type ServiceConfig = { checkEmailConfirmed: boolean @@ -21,7 +21,7 @@ export function useServiceConfigQuery() { queryKey: ['service-config'], queryFn: async () => { try { - const data = await client.call(app.bsky.unspecced.getConfig) + const data = await client.call(AppBskyUnspeccedGetConfig) return { checkEmailConfirmed: Boolean(data.checkEmailConfirmed), // @ts-expect-error not included in the lexicon atm diff --git a/src/state/queries/service.ts b/src/state/queries/service.ts index 754ba81652..ca6f515291 100644 --- a/src/state/queries/service.ts +++ b/src/state/queries/service.ts @@ -1,7 +1,7 @@ import {useQuery} from '@tanstack/react-query' import {createServiceClient} from '#/lib/lexClient' -import {com} from '#/lexicons' +import * as ComAtprotoServerDescribeServer from '#/lexicons/com/atproto/server/describeServer' const RQKEY_ROOT = 'service' export const RQKEY = (serviceUrl: string) => [RQKEY_ROOT, serviceUrl] @@ -15,7 +15,7 @@ export function useServiceQuery(serviceUrl: string) { * through a one-off service client rather than a session-scoped one. */ const client = createServiceClient(serviceUrl) - return await client.call(com.atproto.server.describeServer) + return await client.call(ComAtprotoServerDescribeServer) }, enabled: isValidUrl(serviceUrl), }) diff --git a/src/state/queries/starter-pack-search.ts b/src/state/queries/starter-pack-search.ts index fd6c2ed51c..31628ccbe7 100644 --- a/src/state/queries/starter-pack-search.ts +++ b/src/state/queries/starter-pack-search.ts @@ -7,7 +7,7 @@ import { import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyGraphSearchStarterPacksV2 from '#/lexicons/app/bsky/graph/searchStarterPacksV2' export const RQKEY_ROOT = 'starter-pack-search' export const RQKEY = (query: string, limit?: number) => [ @@ -29,16 +29,16 @@ export function useStarterPackSearch({ }) { const client = useAppviewClient() return useInfiniteQuery< - app.bsky.graph.searchStarterPacksV2.$OutputBody, + AppBskyGraphSearchStarterPacksV2.$OutputBody, Error, - InfiniteData, + InfiniteData, QueryKey, string | undefined >({ staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(query, limit), queryFn: async ({pageParam}) => { - return await client.call(app.bsky.graph.searchStarterPacksV2, { + return await client.call(AppBskyGraphSearchStarterPacksV2, { q: query, limit, cursor: pageParam, @@ -53,7 +53,7 @@ export function useStarterPackSearch({ } function select( - data: InfiniteData, + data: InfiniteData, ) { // enforce uniqueness const uris = new Set() diff --git a/src/state/queries/starter-packs.ts b/src/state/queries/starter-packs.ts index 7dcb76e706..19a4cba942 100644 --- a/src/state/queries/starter-packs.ts +++ b/src/state/queries/starter-packs.ts @@ -20,7 +20,14 @@ import {invalidateActorStarterPacksQuery} from '#/state/queries/actor-starter-pa import {STALE} from '#/state/queries/index' import {invalidateListMembersQuery} from '#/state/queries/list-members' import {useAppviewClient, usePdsClient} from '#/state/session' -import {app, com} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphGetStarterPack from '#/lexicons/app/bsky/graph/getStarterPack' +import * as AppBskyGraphList from '#/lexicons/app/bsky/graph/list' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' +import type * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' +import * as ComAtprotoRepoApplyWrites from '#/lexicons/com/atproto/repo/applyWrites' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import * as bsky from '#/types/bsky' const RQKEY_ROOT = 'starter-pack' @@ -52,7 +59,7 @@ export function useStarterPackQuery({ }) { const client = useAppviewClient() - return useQuery({ + return useQuery({ queryKey: RQKEY(uri ? {uri} : {did, rkey}), queryFn: async () => { if (!uri) { @@ -61,7 +68,7 @@ export function useStarterPackQuery({ uri = httpStarterPackUriToAtUri(uri) as string } - const res = await client.call(app.bsky.graph.getStarterPack, { + const res = await client.call(AppBskyGraphGetStarterPack, { starterPack: uri as AtUriString, }) return res.starterPack @@ -87,7 +94,7 @@ interface UseCreateStarterPackMutationParams { name: string description?: string profiles: bsky.profile.AnyProfileView[] - feeds?: app.bsky.feed.defs.GeneratorView[] + feeds?: AppBskyFeedDefs.GeneratorView[] } export function useCreateStarterPackMutation({ @@ -111,7 +118,7 @@ export function useCreateStarterPackMutation({ UseCreateStarterPackMutationParams >({ mutationFn: async ({name, description, feeds, profiles}) => { - let descriptionFacets: app.bsky.richtext.facet.Main[] | undefined + let descriptionFacets: AppBskyRichtextFacet.Main[] | undefined if (description) { const rt = new RichText({text: description}) await rt.detectFacets(appviewClient) @@ -127,7 +134,7 @@ export function useCreateStarterPackMutation({ client: pdsClient, }) - return await pdsClient.create(app.bsky.graph.starterpack, { + return await pdsClient.create(AppBskyGraphStarterpack, { name, description, descriptionFacets, @@ -168,8 +175,8 @@ export function useEditStarterPackMutation({ void, Error, UseCreateStarterPackMutationParams & { - currentStarterPack: app.bsky.graph.defs.StarterPackView - currentListItems: app.bsky.graph.defs.ListItemView[] + currentStarterPack: AppBskyGraphDefs.StarterPackView + currentListItems: AppBskyGraphDefs.ListItemView[] } >({ mutationFn: async ({ @@ -180,14 +187,14 @@ export function useEditStarterPackMutation({ currentStarterPack, currentListItems, }) => { - let descriptionFacets: app.bsky.richtext.facet.Main[] | undefined + let descriptionFacets: AppBskyRichtextFacet.Main[] | undefined if (description) { const rt = new RichText({text: description}) await rt.detectFacets(appviewClient) descriptionFacets = rt.facets } - if (!bsky.isType(app.bsky.graph.starterpack, currentStarterPack.record)) { + if (!bsky.isType(AppBskyGraphStarterpack, currentStarterPack.record)) { throw new Error('Invalid starter pack') } @@ -199,12 +206,10 @@ export function useEditStarterPackMutation({ if (removedItems.length !== 0) { const chunks = chunk(removedItems, 50) for (const chunk of chunks) { - await pdsClient.call(com.atproto.repo.applyWrites, { + await pdsClient.call(ComAtprotoRepoApplyWrites, { repo: pdsClient.assertDid, writes: chunk.map( - ( - i, - ): com.atproto.repo.applyWrites.$InputBody['writes'][number] => ({ + (i): ComAtprotoRepoApplyWrites.$InputBody['writes'][number] => ({ $type: 'com.atproto.repo.applyWrites#delete', collection: 'app.bsky.graph.listitem', rkey: new AtUri(i.uri).rkeySafe, @@ -220,12 +225,10 @@ export function useEditStarterPackMutation({ if (addedProfiles.length > 0) { const chunks = chunk(addedProfiles, 50) for (const chunk of chunks) { - await pdsClient.call(com.atproto.repo.applyWrites, { + await pdsClient.call(ComAtprotoRepoApplyWrites, { repo: pdsClient.assertDid, writes: chunk.map( - ( - p, - ): com.atproto.repo.applyWrites.$InputBody['writes'][number] => ({ + (p): ComAtprotoRepoApplyWrites.$InputBody['writes'][number] => ({ $type: 'com.atproto.repo.applyWrites#create', collection: 'app.bsky.graph.listitem', value: { @@ -241,7 +244,7 @@ export function useEditStarterPackMutation({ } const rkey = parseStarterPackUri(currentStarterPack.uri)!.rkey - await pdsClient.call(com.atproto.repo.putRecord, { + await pdsClient.call(ComAtprotoRepoPutRecord, { repo: pdsClient.assertDid, collection: 'app.bsky.graph.starterpack', rkey, @@ -307,12 +310,12 @@ export function useDeleteStarterPackMutation({ const did = pdsClient.assertDid if (listUri) { - await pdsClient.delete(app.bsky.graph.list, { + await pdsClient.delete(AppBskyGraphList, { repo: did, rkey: new AtUri(listUri).rkeySafe, }) } - await pdsClient.delete(app.bsky.graph.starterpack, { + await pdsClient.delete(AppBskyGraphStarterpack, { repo: did, rkey, }) @@ -352,14 +355,14 @@ export function useDeleteStarterPackMutation({ async function whenAppViewReady( client: Client, uri: string, - fn: (res?: app.bsky.graph.getStarterPack.$OutputBody) => boolean, + fn: (res?: AppBskyGraphGetStarterPack.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - client.call(app.bsky.graph.getStarterPack, { + client.call(AppBskyGraphGetStarterPack, { starterPack: uri as AtUriString, }), ) @@ -368,33 +371,32 @@ async function whenAppViewReady( export function precacheStarterPack( queryClient: QueryClient, starterPack: - | app.bsky.graph.defs.StarterPackViewBasic - | app.bsky.graph.defs.StarterPackView, + AppBskyGraphDefs.StarterPackViewBasic | AppBskyGraphDefs.StarterPackView, ) { - if (!bsky.isType(app.bsky.graph.starterpack, starterPack.record)) { + if (!bsky.isType(AppBskyGraphStarterpack, starterPack.record)) { return } - let starterPackView: app.bsky.graph.defs.StarterPackView | undefined - if (bsky.isType(app.bsky.graph.defs.starterPackView, starterPack)) { + let starterPackView: AppBskyGraphDefs.StarterPackView | undefined + if (bsky.isType(AppBskyGraphDefs.starterPackView, starterPack)) { starterPackView = starterPack } else if ( - bsky.isType(app.bsky.graph.defs.starterPackViewBasic, starterPack) && - bsky.matches(app.bsky.graph.starterpack, starterPack.record) + bsky.isType(AppBskyGraphDefs.starterPackViewBasic, starterPack) && + bsky.matches(AppBskyGraphStarterpack, starterPack.record) ) { - let feeds: app.bsky.feed.defs.GeneratorView[] | undefined + let feeds: AppBskyFeedDefs.GeneratorView[] | undefined if (starterPack.record.feeds) { feeds = [] for (const feed of starterPack.record.feeds) { // note: types are wrong? claims to be `FeedItem`, but we actually // get un$typed `GeneratorView` objects here -sfn - if (bsky.matches(app.bsky.feed.defs.generatorView, feed)) { + if (bsky.matches(AppBskyFeedDefs.generatorView, feed)) { feeds.push(feed) } } } - const listView: app.bsky.graph.defs.ListViewBasic = { + const listView: AppBskyGraphDefs.ListViewBasic = { uri: starterPack.record.list, // This will be populated once the data from server is fetched cid: '', diff --git a/src/state/queries/suggested-follows.ts b/src/state/queries/suggested-follows.ts index 19f8cc11c4..bb745e610b 100644 --- a/src/state/queries/suggested-follows.ts +++ b/src/state/queries/suggested-follows.ts @@ -9,7 +9,9 @@ import { import {STALE} from '#/state/queries' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyActorGetSuggestions from '#/lexicons/app/bsky/actor/getSuggestions' +import * as AppBskyGraphGetSuggestedFollowsByActor from '#/lexicons/app/bsky/graph/getSuggestedFollowsByActor' import type * as bsky from '#/types/bsky' const suggestedFollowsQueryKeyRoot = 'suggested-follows' @@ -34,12 +36,9 @@ export function useSuggestedFollowsByActorQuery({ staleTime, queryKey: suggestedFollowsByActorQueryKey(did), queryFn: async () => { - const data = await client.call( - app.bsky.graph.getSuggestedFollowsByActor, - { - actor: did as DidString, - }, - ) + const data = await client.call(AppBskyGraphGetSuggestedFollowsByActor, { + actor: did as DidString, + }) const suggestions = data.suggestions.filter( profile => !profile.viewer?.following, ) @@ -102,7 +101,7 @@ export function useSuggestedFollowsByActorWithDismiss({ export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { yield* findAllProfilesInSuggestedFollowsQueryData(queryClient, did) yield* findAllProfilesInSuggestedFollowsByActorQueryData(queryClient, did) } @@ -112,7 +111,7 @@ function* findAllProfilesInSuggestedFollowsQueryData( did: string, ) { const queryDatas = queryClient.getQueriesData< - InfiniteData + InfiniteData >({ queryKey: [suggestedFollowsQueryKeyRoot], }) @@ -135,7 +134,7 @@ function* findAllProfilesInSuggestedFollowsByActorQueryData( did: string, ) { const queryDatas = - queryClient.getQueriesData( + queryClient.getQueriesData( { queryKey: [suggestedFollowsByActorQueryKeyRoot], }, diff --git a/src/state/queries/threadgate/index.ts b/src/state/queries/threadgate/index.ts index c9b1740c0b..fe981ef8b0 100644 --- a/src/state/queries/threadgate/index.ts +++ b/src/state/queries/threadgate/index.ts @@ -16,7 +16,11 @@ import { import {useUpdatePostThreadThreadgateQueryCache} from '#/state/queries/usePostThread' import {usePdsClient} from '#/state/session' import {useThreadgateHiddenReplyUrisAPI} from '#/state/threadgate-hidden-replies' -import {app, com} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedThreadgate from '#/lexicons/app/bsky/feed/threadgate' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' +import * as ComAtprotoRepoGetRecord from '#/lexicons/com/atproto/repo/getRecord' +import * as ComAtprotoRepoPutRecord from '#/lexicons/com/atproto/repo/putRecord' import * as bsky from '#/types/bsky' export * from '#/state/queries/threadgate/types' @@ -38,7 +42,7 @@ export function useThreadgateRecordQuery({ initialData, }: { postUri?: string - initialData?: app.bsky.feed.threadgate.Main + initialData?: AppBskyFeedThreadgate.Main } = {}) { const pdsClient = usePdsClient() @@ -66,7 +70,7 @@ export function useThreadgateViewQuery({ initialData, }: { postUri?: string - initialData?: app.bsky.feed.defs.ThreadgateView + initialData?: AppBskyFeedDefs.ThreadgateView } = {}) { const getPost = useGetPost() @@ -88,11 +92,11 @@ export async function getThreadgateRecord({ }: { pdsClient: Client postUri: string -}): Promise { +}): Promise { const urip = new AtUri(postUri) if (!urip.host.startsWith('did:')) { - const {did} = await pdsClient.call(com.atproto.identity.resolveHandle, { + const {did} = await pdsClient.call(ComAtprotoIdentityResolveHandle, { handle: urip.host as HandleString, }) urip.host = did @@ -113,14 +117,14 @@ export async function getThreadgateRecord({ return true }, () => - pdsClient.call(com.atproto.repo.getRecord, { + pdsClient.call(ComAtprotoRepoGetRecord, { repo: urip.host, collection: 'app.bsky.feed.threadgate', rkey: urip.rkeySafe, }), ) - if (data.value && bsky.matches(app.bsky.feed.threadgate, data.value)) { + if (data.value && bsky.matches(AppBskyFeedThreadgate, data.value)) { return data.value } else { return null @@ -146,7 +150,7 @@ export async function writeThreadgateRecord({ }: { pdsClient: Client postUri: string - threadgate: app.bsky.feed.threadgate.Main + threadgate: AppBskyFeedThreadgate.Main }) { const postUrip = new AtUri(postUri) const record = createThreadgateRecord({ @@ -156,7 +160,7 @@ export async function writeThreadgateRecord({ }) await networkRetry(2, () => - pdsClient.call(com.atproto.repo.putRecord, { + pdsClient.call(ComAtprotoRepoPutRecord, { repo: pdsClient.assertDid, collection: 'app.bsky.feed.threadgate', rkey: postUrip.rkeySafe, @@ -174,8 +178,8 @@ export async function upsertThreadgate( postUri: string }, callback: ( - threadgate: app.bsky.feed.threadgate.Main | null, - ) => Promise, + threadgate: AppBskyFeedThreadgate.Main | null, + ) => Promise, ) { const prev = await getThreadgateRecord({ pdsClient, @@ -247,7 +251,7 @@ export function useSetThreadgateAllowMutation() { }) }, async onSuccess(_, {postUri, allow}) { - const data = await retry( + const data = await retry( 5, // 5 tries _e => true, async () => { @@ -357,9 +361,9 @@ export class InvalidInteractionSettingsError extends Error { } export function validateThreadgateRecordOrThrow( - record: app.bsky.feed.threadgate.Main, + record: AppBskyFeedThreadgate.Main, ) { - const result = bsky.safeParse(app.bsky.feed.threadgate, record) + const result = bsky.safeParse(AppBskyFeedThreadgate, record) if (result.success) { if ((result.value.hiddenReplies?.length ?? 0) > MAX_HIDDEN_REPLIES) { diff --git a/src/state/queries/threadgate/util.ts b/src/state/queries/threadgate/util.ts index 5a9fa4aea9..5a139e0279 100644 --- a/src/state/queries/threadgate/util.ts +++ b/src/state/queries/threadgate/util.ts @@ -1,7 +1,8 @@ import {type AtUriString, toDatetimeString} from '@atproto/syntax' import {type ThreadgateAllowUISetting} from '#/state/queries/threadgate/types' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedThreadgate from '#/lexicons/app/bsky/feed/threadgate' import * as bsky from '#/types/bsky' /* @@ -9,12 +10,11 @@ import * as bsky from '#/types/bsky' * against the threadgate record schema before its `allow` rules are read. */ export function threadgateViewToAllowUISetting( - threadgateView: app.bsky.feed.defs.ThreadgateView | undefined, + threadgateView: AppBskyFeedDefs.ThreadgateView | undefined, ): ThreadgateAllowUISetting[] { // Validate the record for clarity, since backwards compat code is a little confusing const threadgate = - threadgateView && - bsky.matches(app.bsky.feed.threadgate, threadgateView.record) + threadgateView && bsky.matches(AppBskyFeedThreadgate, threadgateView.record) ? threadgateView.record : undefined return threadgateRecordToAllowUISetting(threadgate) @@ -25,7 +25,7 @@ export function threadgateViewToAllowUISetting( * {@link ThreadgateAllowUISetting}, for use by app UI. */ export function threadgateRecordToAllowUISetting( - threadgate: app.bsky.feed.threadgate.Main | undefined, + threadgate: AppBskyFeedThreadgate.Main | undefined, ): ThreadgateAllowUISetting[] { /* * If `threadgate` doesn't exist (default), or if `threadgate.allow === undefined`, it means @@ -45,13 +45,13 @@ export function threadgateRecordToAllowUISetting( const settings: ThreadgateAllowUISetting[] = threadgate.allow .map(allow => { let setting: ThreadgateAllowUISetting | undefined - if (bsky.isType(app.bsky.feed.threadgate.mentionRule, allow)) { + if (bsky.isType(AppBskyFeedThreadgate.mentionRule, allow)) { setting = {type: 'mention'} - } else if (bsky.isType(app.bsky.feed.threadgate.followingRule, allow)) { + } else if (bsky.isType(AppBskyFeedThreadgate.followingRule, allow)) { setting = {type: 'following'} - } else if (bsky.isType(app.bsky.feed.threadgate.listRule, allow)) { + } else if (bsky.isType(AppBskyFeedThreadgate.listRule, allow)) { setting = {type: 'list', list: allow.list} - } else if (bsky.isType(app.bsky.feed.threadgate.followerRule, allow)) { + } else if (bsky.isType(AppBskyFeedThreadgate.followerRule, allow)) { setting = {type: 'followers'} } return setting @@ -70,12 +70,12 @@ export function threadgateRecordToAllowUISetting( */ export function threadgateAllowUISettingToAllowRecordValue( threadgate: ThreadgateAllowUISetting[], -): app.bsky.feed.threadgate.Main['allow'] { +): AppBskyFeedThreadgate.Main['allow'] { if (threadgate.find(v => v.type === 'everybody')) { return undefined } - let allow: Exclude = [] + let allow: Exclude = [] if (!threadgate.find(v => v.type === 'nobody')) { for (const rule of threadgate) { @@ -105,13 +105,13 @@ export function threadgateAllowUISettingToAllowRecordValue( * to an empty array. See other comments in this file. */ export function mergeThreadgateRecords( - prev: app.bsky.feed.threadgate.Main, - next: Omit, 'hiddenReplies'> & { + prev: AppBskyFeedThreadgate.Main, + next: Omit, 'hiddenReplies'> & { hiddenReplies?: string[] }, -): app.bsky.feed.threadgate.Main { +): AppBskyFeedThreadgate.Main { // can be undefined if everyone can reply! - const allow: app.bsky.feed.threadgate.Main['allow'] | undefined = + const allow: AppBskyFeedThreadgate.Main['allow'] | undefined = prev.allow || next.allow ? [...(prev.allow || []), ...(next.allow || [])].filter( (v, i, a) => a.findIndex(t => t.$type === v.$type) === i, @@ -135,13 +135,13 @@ export function mergeThreadgateRecords( */ export function createThreadgateRecord( threadgate: Omit< - Partial, + Partial, 'post' | 'hiddenReplies' > & { post?: string hiddenReplies?: string[] }, -): app.bsky.feed.threadgate.Main { +): AppBskyFeedThreadgate.Main { if (!threadgate.post) { throw new Error('Cannot create a threadgate record without a post URI') } diff --git a/src/state/queries/trending/useGetSuggestedFeedsQuery.ts b/src/state/queries/trending/useGetSuggestedFeedsQuery.ts index 85cf0be794..83f9801976 100644 --- a/src/state/queries/trending/useGetSuggestedFeedsQuery.ts +++ b/src/state/queries/trending/useGetSuggestedFeedsQuery.ts @@ -8,7 +8,7 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetSuggestedFeeds from '#/lexicons/app/bsky/unspecced/getSuggestedFeeds' export const DEFAULT_LIMIT = 15 @@ -26,7 +26,7 @@ export function useGetSuggestedFeedsQuery({enabled}: {enabled?: boolean}) { queryFn: async () => { const contentLangs = getContentLanguages().join(',') const data = await client.call( - app.bsky.unspecced.getSuggestedFeeds, + AppBskyUnspeccedGetSuggestedFeeds, { limit: DEFAULT_LIMIT, }, diff --git a/src/state/queries/trending/useGetSuggestedOnboardingUsersQuery.ts b/src/state/queries/trending/useGetSuggestedOnboardingUsersQuery.ts index f8ffefe68d..019771b77e 100644 --- a/src/state/queries/trending/useGetSuggestedOnboardingUsersQuery.ts +++ b/src/state/queries/trending/useGetSuggestedOnboardingUsersQuery.ts @@ -6,7 +6,8 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyUnspeccedGetSuggestedOnboardingUsers from '#/lexicons/app/bsky/unspecced/getSuggestedOnboardingUsers' export type QueryProps = { category?: string | null @@ -40,7 +41,7 @@ export function useGetSuggestedOnboardingUsersQuery(props: QueryProps) { const overrideInterests = props.overrideInterests.join(',') const data = await client.call( - app.bsky.unspecced.getSuggestedOnboardingUsers, + AppBskyUnspeccedGetSuggestedOnboardingUsers, { category: props.category ?? undefined, limit: props.limit || 10, @@ -64,9 +65,9 @@ export function useGetSuggestedOnboardingUsersQuery(props: QueryProps) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const responses = - queryClient.getQueriesData( + queryClient.getQueriesData( { queryKey: [getSuggestedOnboardingUsersQueryKeyRoot], }, diff --git a/src/state/queries/trending/useGetSuggestedUsersForDiscoverQuery.ts b/src/state/queries/trending/useGetSuggestedUsersForDiscoverQuery.ts index 6e46e073ce..6394b3eb7e 100644 --- a/src/state/queries/trending/useGetSuggestedUsersForDiscoverQuery.ts +++ b/src/state/queries/trending/useGetSuggestedUsersForDiscoverQuery.ts @@ -9,7 +9,8 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyUnspeccedGetSuggestedUsersForDiscover from '#/lexicons/app/bsky/unspecced/getSuggestedUsersForDiscover' export type QueryProps = { limit?: number @@ -33,7 +34,7 @@ export function useGetSuggestedUsersForDiscoverQuery(props: QueryProps = {}) { const userInterests = aggregateUserInterests(preferences) const data = await client.call( - app.bsky.unspecced.getSuggestedUsersForDiscover, + AppBskyUnspeccedGetSuggestedUsersForDiscover, { limit: props.limit || 10, }, @@ -55,9 +56,9 @@ export function useGetSuggestedUsersForDiscoverQuery(props: QueryProps = {}) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const responses = - queryClient.getQueriesData( + queryClient.getQueriesData( { queryKey: [getSuggestedUsersForDiscoverQueryKeyRoot], }, diff --git a/src/state/queries/trending/useGetSuggestedUsersForExploreQuery.ts b/src/state/queries/trending/useGetSuggestedUsersForExploreQuery.ts index 1f729bb269..fb6a7b5368 100644 --- a/src/state/queries/trending/useGetSuggestedUsersForExploreQuery.ts +++ b/src/state/queries/trending/useGetSuggestedUsersForExploreQuery.ts @@ -9,7 +9,8 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyUnspeccedGetSuggestedUsersForExplore from '#/lexicons/app/bsky/unspecced/getSuggestedUsersForExplore' export type QueryProps = { category?: string | null @@ -34,7 +35,7 @@ export function useGetSuggestedUsersForExploreQuery(props: QueryProps = {}) { const userInterests = aggregateUserInterests(preferences) const data = await client.call( - app.bsky.unspecced.getSuggestedUsersForExplore, + AppBskyUnspeccedGetSuggestedUsersForExplore, { category: props.category ?? undefined, limit: props.limit || 10, @@ -58,9 +59,9 @@ export function useGetSuggestedUsersForExploreQuery(props: QueryProps = {}) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const responses = - queryClient.getQueriesData( + queryClient.getQueriesData( { queryKey: [getSuggestedUsersForExploreQueryKeyRoot], }, diff --git a/src/state/queries/trending/useGetSuggestedUsersForSeeMoreQuery.ts b/src/state/queries/trending/useGetSuggestedUsersForSeeMoreQuery.ts index 94c0b7735d..0fc935a7c0 100644 --- a/src/state/queries/trending/useGetSuggestedUsersForSeeMoreQuery.ts +++ b/src/state/queries/trending/useGetSuggestedUsersForSeeMoreQuery.ts @@ -9,7 +9,8 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyUnspeccedGetSuggestedUsersForSeeMore from '#/lexicons/app/bsky/unspecced/getSuggestedUsersForSeeMore' export type QueryProps = { category?: string | null @@ -40,7 +41,7 @@ export function useGetSuggestedUsersForSeeMoreQuery(props: QueryProps = {}) { const userInterests = aggregateUserInterests(preferences) const data = await client.call( - app.bsky.unspecced.getSuggestedUsersForSeeMore, + AppBskyUnspeccedGetSuggestedUsersForSeeMore, { category: props.category ?? undefined, limit: props.limit || 50, @@ -64,9 +65,9 @@ export function useGetSuggestedUsersForSeeMoreQuery(props: QueryProps = {}) { export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const responses = - queryClient.getQueriesData( + queryClient.getQueriesData( { queryKey: [getSuggestedUsersForSeeMoreQueryKeyRoot], }, diff --git a/src/state/queries/trending/useGetTrendsQuery.ts b/src/state/queries/trending/useGetTrendsQuery.ts index fabeccd478..4dee1749a2 100644 --- a/src/state/queries/trending/useGetTrendsQuery.ts +++ b/src/state/queries/trending/useGetTrendsQuery.ts @@ -11,7 +11,7 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetTrends from '#/lexicons/app/bsky/unspecced/getTrends' export const DEFAULT_LIMIT = 5 @@ -48,7 +48,7 @@ export function useGetTrendsQuery(props: QueryProps = {}) { queryFn: async () => { const contentLangs = getContentLanguages().join(',') const data = await client.call( - app.bsky.unspecced.getTrends, + AppBskyUnspeccedGetTrends, { limit, }, @@ -65,7 +65,7 @@ export function useGetTrendsQuery(props: QueryProps = {}) { return data }, select: useCallback( - (data: app.bsky.unspecced.getTrends.$OutputBody) => { + (data: AppBskyUnspeccedGetTrends.$OutputBody) => { return { recId: data.recIdStr, trends: dedupe( diff --git a/src/state/queries/useOnboardingSuggestedStarterPacksQuery.ts b/src/state/queries/useOnboardingSuggestedStarterPacksQuery.ts index f0b5a053e3..f2a76c28d3 100644 --- a/src/state/queries/useOnboardingSuggestedStarterPacksQuery.ts +++ b/src/state/queries/useOnboardingSuggestedStarterPacksQuery.ts @@ -8,7 +8,7 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from '#/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks' export const createOnboardingSuggestedStarterPacksQueryKey = ( interests?: string[], @@ -31,7 +31,7 @@ export function useOnboardingSuggestedStarterPacksQuery({ queryKey: createOnboardingSuggestedStarterPacksQueryKey(overrideInterests), queryFn: async () => { return await client.call( - app.bsky.unspecced.getOnboardingSuggestedStarterPacks, + AppBskyUnspeccedGetOnboardingSuggestedStarterPacks, {limit: 6}, { headers: { diff --git a/src/state/queries/usePostThread/index.ts b/src/state/queries/usePostThread/index.ts index b4e217f4bd..8ade80196f 100644 --- a/src/state/queries/usePostThread/index.ts +++ b/src/state/queries/usePostThread/index.ts @@ -32,7 +32,8 @@ import {useAppviewClient, useSession} from '#/state/session' import {useMergeThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' import {useBreakpoints} from '#/alf' import {IS_WEB} from '#/env' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetPostThreadOtherV2 from '#/lexicons/app/bsky/unspecced/getPostThreadOtherV2' +import * as AppBskyUnspeccedGetPostThreadV2 from '#/lexicons/app/bsky/unspecced/getPostThreadV2' export * from '#/state/queries/usePostThread/context' export {useUpdatePostThreadThreadgateQueryCache} from '#/state/queries/usePostThread/queryCache' @@ -73,7 +74,7 @@ export function usePostThread({anchor}: {anchor?: string}) { enabled: isThreadPreferencesLoaded && !!anchor && !!moderationOpts, queryKey: postThreadQueryKey, async queryFn(ctx) { - const data = await client.call(app.bsky.unspecced.getPostThreadV2, { + const data = await client.call(AppBskyUnspeccedGetPostThreadV2, { anchor: anchor! as AtUriString, branchingFactor: view === 'linear' ? LINEAR_VIEW_BF : TREE_VIEW_BF, below, @@ -169,7 +170,7 @@ export function usePostThread({anchor}: {anchor?: string}) { enabled: additionalQueryEnabled, queryKey: postThreadOtherQueryKey, async queryFn() { - return await client.call(app.bsky.unspecced.getPostThreadOtherV2, { + return await client.call(AppBskyUnspeccedGetPostThreadOtherV2, { anchor: anchor! as AtUriString, }) }, diff --git a/src/state/queries/usePostThread/queryCache.ts b/src/state/queries/usePostThread/queryCache.ts index afc7465ceb..3c957de3d4 100644 --- a/src/state/queries/usePostThread/queryCache.ts +++ b/src/state/queries/usePostThread/queryCache.ts @@ -29,7 +29,11 @@ import { embedViewRecordToPostView, getEmbeddedPost, } from '#/state/queries/util' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyUnspeccedDefs from '#/lexicons/app/bsky/unspecced/defs' +import type * as AppBskyUnspeccedGetPostThreadOtherV2 from '#/lexicons/app/bsky/unspecced/getPostThreadOtherV2' +import type * as AppBskyUnspeccedGetPostThreadV2 from '#/lexicons/app/bsky/unspecced/getPostThreadV2' import * as bsky from '#/types/bsky' export function createCacheMutator({ @@ -46,18 +50,18 @@ export function createCacheMutator({ return { insertReplies( parentUri: string, - replies: app.bsky.unspecced.getPostThreadV2.ThreadItem[], + replies: AppBskyUnspeccedGetPostThreadV2.ThreadItem[], ) { /* * Main thread query mutator. */ - queryClient.setQueryData( + queryClient.setQueryData( postThreadQueryKey, data => { if (!data) return return { ...data, - thread: mutator([ + thread: mutator([ ...data.thread, ]), } @@ -67,15 +71,15 @@ export function createCacheMutator({ /* * Additional replies query mutator. */ - queryClient.setQueryData( + queryClient.setQueryData( postThreadOtherQueryKey, data => { if (!data) return return { ...data, - thread: mutator( - [...data.thread], - ), + thread: mutator([ + ...data.thread, + ]), } }, ) @@ -84,9 +88,7 @@ export function createCacheMutator({ for (let i = 0; i < thread.length; i++) { const parent = thread[i] - if ( - !bsky.isType(app.bsky.unspecced.defs.threadItemPost, parent.value) - ) + if (!bsky.isType(AppBskyUnspeccedDefs.threadItemPost, parent.value)) continue if (parent.uri !== parentUri) continue @@ -123,7 +125,7 @@ export function createCacheMutator({ const isParentBelowRoot = parent.depth > 0 const optimisticReply = replies.at(0) const opIsReplier = bsky.isType( - app.bsky.unspecced.defs.threadItemPost, + AppBskyUnspeccedDefs.threadItemPost, optimisticReply?.value, ) ? opDid === optimisticReply.value.post.author.did @@ -171,8 +173,8 @@ export function createCacheMutator({ * Unused atm, post shadow does the trick, but it would be nice to clean up * the whole sub-tree on deletes. */ - deletePost(post: app.bsky.unspecced.getPostThreadV2.ThreadItem) { - queryClient.setQueryData( + deletePost(post: AppBskyUnspeccedGetPostThreadV2.ThreadItem) { + queryClient.setQueryData( postThreadQueryKey, queryData => { if (!queryData) return @@ -181,9 +183,7 @@ export function createCacheMutator({ for (let i = 0; i < thread.length; i++) { const existingPost = thread[i] - if ( - !bsky.isType(app.bsky.unspecced.defs.threadItemPost, post.value) - ) + if (!bsky.isType(AppBskyUnspeccedDefs.threadItemPost, post.value)) continue if (existingPost.uri === post.uri) { @@ -206,7 +206,7 @@ export function createCacheMutator({ export function getThreadPlaceholder( queryClient: QueryClient, uri: string, -): $Typed | void { +): $Typed | void { let partial for (let item of getThreadPlaceholderCandidates(queryClient, uri)) { /* @@ -233,8 +233,8 @@ export function* getThreadPlaceholderCandidates( uri: string, ): Generator< $Typed< - Omit & { - value: $Typed + Omit & { + value: $Typed } >, void @@ -278,10 +278,10 @@ export function* getThreadPlaceholderCandidates( export function* findAllPostsInQueryData( queryClient: QueryClient, uri: string, -): Generator { +): Generator { const atUri = new AtUri(uri) const queryDatas = - queryClient.getQueriesData({ + queryClient.getQueriesData({ queryKey: [postThreadQueryKeyRoot], }) @@ -291,7 +291,7 @@ export function* findAllPostsInQueryData( const {thread} = queryData for (const item of thread) { - if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) { + if (bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { if (didOrHandleUriMatches(atUri, item.value.post)) { yield item.value.post } @@ -308,9 +308,9 @@ export function* findAllPostsInQueryData( export function* findAllProfilesInQueryData( queryClient: QueryClient, did: string, -): Generator { +): Generator { const queryDatas = - queryClient.getQueriesData({ + queryClient.getQueriesData({ queryKey: [postThreadQueryKeyRoot], }) @@ -320,7 +320,7 @@ export function* findAllProfilesInQueryData( const {thread} = queryData for (const item of thread) { - if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) { + if (bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { if (item.value.post.author.did === did) { yield item.value.post.author } @@ -339,14 +339,14 @@ export function useUpdatePostThreadThreadgateQueryCache() { const context = usePostThreadContext() return useCallback( - (threadgate: app.bsky.feed.defs.ThreadgateView) => { + (threadgate: AppBskyFeedDefs.ThreadgateView) => { if (!context) return function mutator(thread: ApiThreadItem[]): T[] { for (let i = 0; i < thread.length; i++) { const item = thread[i] - if (!bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) + if (!bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) continue if (item.depth === 0) { @@ -366,13 +366,13 @@ export function useUpdatePostThreadThreadgateQueryCache() { return thread as T[] } - qc.setQueryData( + qc.setQueryData( context.postThreadQueryKey, data => { if (!data) return return { ...data, - thread: mutator([ + thread: mutator([ ...data.thread, ]), } diff --git a/src/state/queries/usePostThread/traversal.ts b/src/state/queries/usePostThread/traversal.ts index c7df88a0e4..e6285ac484 100644 --- a/src/state/queries/usePostThread/traversal.ts +++ b/src/state/queries/usePostThread/traversal.ts @@ -14,7 +14,7 @@ import { storeTraversalMetadata, } from '#/state/queries/usePostThread/utils' import * as views from '#/state/queries/usePostThread/views' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedDefs from '#/lexicons/app/bsky/unspecced/defs' import * as bsky from '#/types/bsky' export function sortAndAnnotateThreadItems( @@ -47,7 +47,7 @@ export function sortAndAnnotateThreadItems( let parentMetadata: TraversalMetadata | undefined let metadata: TraversalMetadata | undefined - if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) { + if (bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { parentMetadata = metadatas.get( getPostRecord(item.value.post).reply?.parent?.uri || '', ) @@ -68,22 +68,20 @@ export function sortAndAnnotateThreadItems( } else if (item.depth === 0) { if ( bsky.isType( - app.bsky.unspecced.defs.threadItemNoUnauthenticated, + AppBskyUnspeccedDefs.threadItemNoUnauthenticated, item.value, ) ) { threadItems.push(views.threadPostNoUnauthenticated(item)) } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemNotFound, item.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemNotFound, item.value) ) { threadItems.push(views.threadPostNotFound(item)) } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, item.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemBlocked, item.value) ) { threadItems.push(views.threadPostBlocked(item)) - } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value) - ) { + } else if (bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { const post = views.threadPost({ uri: item.uri, depth: item.depth, @@ -98,7 +96,7 @@ export function sortAndAnnotateThreadItems( if ( bsky.isType( - app.bsky.unspecced.defs.threadItemNoUnauthenticated, + AppBskyUnspeccedDefs.threadItemNoUnauthenticated, parent.value, ) ) { @@ -113,20 +111,17 @@ export function sortAndAnnotateThreadItems( // for now, break parent traversal at first no-unauthed break parentTraversal } else if ( - bsky.isType( - app.bsky.unspecced.defs.threadItemNotFound, - parent.value, - ) + bsky.isType(AppBskyUnspeccedDefs.threadItemNotFound, parent.value) ) { threadItems.unshift(views.threadPostNotFound(parent)) break parentTraversal } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, parent.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemBlocked, parent.value) ) { threadItems.unshift(views.threadPostBlocked(parent)) break parentTraversal } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemPost, parent.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemPost, parent.value) ) { threadItems.unshift( views.threadPost({ @@ -148,20 +143,18 @@ export function sortAndAnnotateThreadItems( */ const shouldBreak = bsky.isType( - app.bsky.unspecced.defs.threadItemNoUnauthenticated, + AppBskyUnspeccedDefs.threadItemNoUnauthenticated, item.value, ) || - bsky.isType(app.bsky.unspecced.defs.threadItemNotFound, item.value) || - bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, item.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemNotFound, item.value) || + bsky.isType(AppBskyUnspeccedDefs.threadItemBlocked, item.value) if (shouldBreak) { const branch = getBranch(thread, i, item.depth) // could insert tombstone i = branch.end continue traversal - } else if ( - bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value) - ) { + } else if (bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { if (parentMetadata) { /* * Set this value before incrementing the `repliesSeenCounter` later @@ -210,7 +203,7 @@ export function sortAndAnnotateThreadItems( const child = thread[ci] if ( - bsky.isType(app.bsky.unspecced.defs.threadItemPost, child.value) + bsky.isType(AppBskyUnspeccedDefs.threadItemPost, child.value) ) { const childParentMetadata = metadatas.get( getPostRecord(child.value.post).reply?.parent?.uri || '', diff --git a/src/state/queries/usePostThread/utils.ts b/src/state/queries/usePostThread/utils.ts index dde80db181..f5fa5168c8 100644 --- a/src/state/queries/usePostThread/utils.ts +++ b/src/state/queries/usePostThread/utils.ts @@ -5,20 +5,24 @@ import { type ThreadItem, type TraversalMetadata, } from '#/state/queries/usePostThread/types' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as AppBskyFeedThreadgate from '#/lexicons/app/bsky/feed/threadgate' +import * as AppBskyUnspeccedDefs from '#/lexicons/app/bsky/unspecced/defs' +import type * as AppBskyUnspeccedGetPostThreadV2 from '#/lexicons/app/bsky/unspecced/getPostThreadV2' import {isDevMode} from '#/storage/hooks/dev-mode' import * as bsky from '#/types/bsky' export function getThreadgateRecord( - view: app.bsky.unspecced.getPostThreadV2.$OutputBody['threadgate'], + view: AppBskyUnspeccedGetPostThreadV2.$OutputBody['threadgate'], ) { - return bsky.isType(app.bsky.feed.threadgate, view?.record) + return bsky.isType(AppBskyFeedThreadgate, view?.record) ? view?.record : undefined } -export function getRootPostAtUri(post: app.bsky.feed.defs.PostView) { - if (bsky.isType(app.bsky.feed.post, post.record)) { +export function getRootPostAtUri(post: AppBskyFeedDefs.PostView) { + if (bsky.isType(AppBskyFeedPost, post.record)) { /** * If the record has no `reply` field, it is a root post. */ @@ -31,8 +35,8 @@ export function getRootPostAtUri(post: app.bsky.feed.defs.PostView) { } } -export function getPostRecord(post: app.bsky.feed.defs.PostView) { - return post.record as app.bsky.feed.post.Main +export function getPostRecord(post: AppBskyFeedDefs.PostView) { + return post.record as AppBskyFeedPost.Main } export function getTraversalMetadata({ @@ -46,7 +50,7 @@ export function getTraversalMetadata({ nextItem?: ApiThreadItem parentMetadata?: TraversalMetadata }): TraversalMetadata { - if (!bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) { + if (!bsky.isType(AppBskyUnspeccedDefs.threadItemPost, item.value)) { throw new Error(`Expected thread item to be a post`) } const repliesCount = item.value.post.replyCount || 0 diff --git a/src/state/queries/useSuggestedStarterPacksQuery.ts b/src/state/queries/useSuggestedStarterPacksQuery.ts index bcd394312e..fcbbbe32b3 100644 --- a/src/state/queries/useSuggestedStarterPacksQuery.ts +++ b/src/state/queries/useSuggestedStarterPacksQuery.ts @@ -8,7 +8,7 @@ import {getContentLanguages} from '#/state/preferences/languages' import {STALE} from '#/state/queries' import {usePreferencesQuery} from '#/state/queries/preferences' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyUnspeccedGetSuggestedStarterPacks from '#/lexicons/app/bsky/unspecced/getSuggestedStarterPacks' export const createSuggestedStarterPacksQueryKey = (interests?: string[]) => [ 'suggested-starter-packs', @@ -32,7 +32,7 @@ export function useSuggestedStarterPacksQuery({ queryKey: createSuggestedStarterPacksQueryKey(overrideInterests), queryFn: async () => { return await client.call( - app.bsky.unspecced.getSuggestedStarterPacks, + AppBskyUnspeccedGetSuggestedStarterPacks, {}, { headers: { diff --git a/src/state/queries/util.ts b/src/state/queries/util.ts index a3fe12aec7..7aebe0b66c 100644 --- a/src/state/queries/util.ts +++ b/src/state/queries/util.ts @@ -5,7 +5,11 @@ import { type QueryKey, } from '@tanstack/react-query' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' export type StructuredQueryKey> = readonly [ @@ -87,7 +91,7 @@ export async function truncateAndInvalidate( // of the currentUri that is being checked. export function didOrHandleUriMatches( atUri: AtUri, - record: {uri: string; author: app.bsky.actor.defs.ProfileViewBasic}, + record: {uri: string; author: AppBskyActorDefs.ProfileViewBasic}, ) { if (atUri.host.startsWith('did:')) { return atUri.href === record.uri @@ -98,19 +102,19 @@ export function didOrHandleUriMatches( export function getEmbeddedPost( v: unknown, -): app.bsky.embed.record.ViewRecord | undefined { - if (bsky.isType(app.bsky.embed.record.view, v)) { +): AppBskyEmbedRecord.ViewRecord | undefined { + if (bsky.isType(AppBskyEmbedRecord.view, v)) { if ( - bsky.isType(app.bsky.embed.record.viewRecord, v.record) && - bsky.isType(app.bsky.feed.post, v.record.value) + bsky.isType(AppBskyEmbedRecord.viewRecord, v.record) && + bsky.isType(AppBskyFeedPost, v.record.value) ) { return v.record } } - if (bsky.isType(app.bsky.embed.recordWithMedia.view, v)) { + if (bsky.isType(AppBskyEmbedRecordWithMedia.view, v)) { if ( - bsky.isType(app.bsky.embed.record.viewRecord, v.record.record) && - bsky.isType(app.bsky.feed.post, v.record.record.value) + bsky.isType(AppBskyEmbedRecord.viewRecord, v.record.record) && + bsky.isType(AppBskyFeedPost, v.record.record.value) ) { return v.record.record } @@ -118,8 +122,8 @@ export function getEmbeddedPost( } export function embedViewRecordToPostView( - v: app.bsky.embed.record.ViewRecord, -): app.bsky.feed.defs.PostView { + v: AppBskyEmbedRecord.ViewRecord, +): AppBskyFeedDefs.PostView { return { uri: v.uri, cid: v.cid, diff --git a/src/state/queries/verification/useUpdateProfileVerificationCache.ts b/src/state/queries/verification/useUpdateProfileVerificationCache.ts index 6079457e2e..f344fb08c2 100644 --- a/src/state/queries/verification/useUpdateProfileVerificationCache.ts +++ b/src/state/queries/verification/useUpdateProfileVerificationCache.ts @@ -4,7 +4,7 @@ import {useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {updateProfileShadow} from '#/state/cache/profile-shadow' import {useAppviewClient} from '#/state/session' -import {app} from '#/lexicons' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' import type * as bsky from '#/types/bsky' /** @@ -23,7 +23,7 @@ export function useUpdateProfileVerificationCache() { logger.warn(`useUpdateProfileVerificationCache: no did`, {profile}) return } - const updated = await client.call(app.bsky.actor.getProfile, { + const updated = await client.call(AppBskyActorGetProfile, { actor: profile.did, }) updateProfileShadow(qc, profile.did, { diff --git a/src/state/queries/verification/useVerificationCreateMutation.tsx b/src/state/queries/verification/useVerificationCreateMutation.tsx index 50510bac9e..d38b929ff8 100644 --- a/src/state/queries/verification/useVerificationCreateMutation.tsx +++ b/src/state/queries/verification/useVerificationCreateMutation.tsx @@ -5,7 +5,8 @@ import {until} from '#/lib/async/until' import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache' import {useAppviewClient, usePdsClient, useSession} from '#/state/session' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as AppBskyGraphVerification from '#/lexicons/app/bsky/graph/verification' import type * as bsky from '#/types/bsky' export function useVerificationCreateMutation() { @@ -21,7 +22,7 @@ export function useVerificationCreateMutation() { throw new Error('User not logged in') } - const {uri} = await pdsClient.create(app.bsky.graph.verification, { + const {uri} = await pdsClient.create(AppBskyGraphVerification, { subject: profile.did, createdAt: toDatetimeString(new Date()), handle: profile.handle, @@ -31,7 +32,7 @@ export function useVerificationCreateMutation() { await until( 5, 1e3, - (profile: app.bsky.actor.getProfile.$OutputBody) => { + (profile: AppBskyActorGetProfile.$OutputBody) => { if ( profile.verification && profile.verification.verifications.find(v => v.uri === uri) @@ -41,7 +42,7 @@ export function useVerificationCreateMutation() { return false }, () => { - return appviewClient.call(app.bsky.actor.getProfile, { + return appviewClient.call(AppBskyActorGetProfile, { actor: profile.did ?? '', }) }, diff --git a/src/state/queries/verification/useVerificationsRemoveMutation.tsx b/src/state/queries/verification/useVerificationsRemoveMutation.tsx index e0e0fe5e5a..02d8a4741d 100644 --- a/src/state/queries/verification/useVerificationsRemoveMutation.tsx +++ b/src/state/queries/verification/useVerificationsRemoveMutation.tsx @@ -5,7 +5,9 @@ import {until} from '#/lib/async/until' import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache' import {useAppviewClient, usePdsClient, useSession} from '#/state/session' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as AppBskyGraphVerification from '#/lexicons/app/bsky/graph/verification' import type * as bsky from '#/types/bsky' export function useVerificationsRemoveMutation() { @@ -21,7 +23,7 @@ export function useVerificationsRemoveMutation() { verifications, }: { profile: bsky.profile.AnyProfileView - verifications: app.bsky.actor.defs.VerificationView[] + verifications: AppBskyActorDefs.VerificationView[] }) { if (!currentAccount) { throw new Error('User not logged in') @@ -31,7 +33,7 @@ export function useVerificationsRemoveMutation() { await Promise.all( uris.map(uri => { - return pdsClient.delete(app.bsky.graph.verification, { + return pdsClient.delete(AppBskyGraphVerification, { rkey: new AtUri(uri).rkeySafe, }) }), @@ -40,7 +42,7 @@ export function useVerificationsRemoveMutation() { await until( 5, 1e3, - (profile: app.bsky.actor.getProfile.$OutputBody) => { + (profile: AppBskyActorGetProfile.$OutputBody) => { if ( !profile.verification?.verifications.some(v => uris.includes(v.uri)) ) { @@ -49,7 +51,7 @@ export function useVerificationsRemoveMutation() { return false }, () => { - return appviewClient.call(app.bsky.actor.getProfile, { + return appviewClient.call(AppBskyActorGetProfile, { actor: profile.did ?? '', }) }, diff --git a/src/state/session/__tests__/clients-test.ts b/src/state/session/__tests__/clients-test.ts index 1dfa93e0ea..b679747679 100644 --- a/src/state/session/__tests__/clients-test.ts +++ b/src/state/session/__tests__/clients-test.ts @@ -18,7 +18,9 @@ import { invalidateCachedIsBetaUser, setCachedIsBetaUser, } from '#/state/preferences/beta-user-cache' -import {app, chat, com} from '#/lexicons' +import * as AppBskyActorGetProfile from '#/lexicons/app/bsky/actor/getProfile' +import * as ChatBskyConvoListConvos from '#/lexicons/chat/bsky/convo/listConvos' +import * as ComAtprotoServerGetSession from '#/lexicons/com/atproto/server/getSession' import {account} from '#/storage' import {configureGlobalAppLabelers} from '../additional-moderation-authorities' import { @@ -102,7 +104,7 @@ describe('buildAppviewClient', () => { it('routes client.call through the session to the network', async () => { const client = buildAppviewClient(makeSession(fetchMock)) - const body = await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + const body = await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect(body.handle).toBe(HANDLE) expect(urlsOf(fetchMock).join()).toContain(`actor=${HANDLE}`) @@ -111,7 +113,7 @@ describe('buildAppviewClient', () => { it('emits the appview proxy header', async () => { const client = buildAppviewClient(makeSession(fetchMock)) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect( headersFor(fetchMock, 'app.bsky.actor.getProfile').get('atproto-proxy'), @@ -124,7 +126,7 @@ describe('buildAppviewClient', () => { const client = buildAppviewClient(makeSession(fetchMock)) setCachedIsBetaUser(DID, isBetaUser) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect( headersFor(fetchMock, 'app.bsky.actor.getProfile').get( @@ -137,7 +139,7 @@ describe('buildAppviewClient', () => { it('omits the beta user header when the preference is not cached', async () => { const client = buildAppviewClient(makeSession(fetchMock)) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect( headersFor(fetchMock, 'app.bsky.actor.getProfile').get( @@ -151,8 +153,8 @@ describe('buildAppviewClient', () => { const getSpy = jest.spyOn(account, 'get') const client = buildAppviewClient(makeSession(fetchMock)) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect(getSpy).toHaveBeenCalledTimes(1) getSpy.mockRestore() @@ -162,7 +164,7 @@ describe('buildAppviewClient', () => { const client = buildAppviewClient(makeSession(fetchMock)) client.setLabelers(['did:plc:labeler']) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) const labelers = headersFor(fetchMock, 'app.bsky.actor.getProfile').get( 'atproto-accept-labelers', @@ -187,7 +189,7 @@ describe('buildAppviewClient', () => { configureGlobalAppLabelers(['did:plc:global-labeler']) const client = buildAppviewClient(makeSession(fetchMock)) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) const labelers = headersFor(fetchMock, 'app.bsky.actor.getProfile').get( 'atproto-accept-labelers', @@ -202,7 +204,7 @@ describe('buildAppviewClient', () => { it('sends the session access token', async () => { const client = buildAppviewClient(makeSession(fetchMock)) - await client.call(app.bsky.actor.getProfile, {actor: HANDLE}) + await client.call(AppBskyActorGetProfile, {actor: HANDLE}) expect( headersFor(fetchMock, 'app.bsky.actor.getProfile').get('authorization'), @@ -225,7 +227,7 @@ describe('buildPdsClient', () => { it('sends the session access token', async () => { await buildPdsClient(makeSession(fetchMock)).call( - com.atproto.server.getSession, + ComAtprotoServerGetSession, {}, ) @@ -245,7 +247,7 @@ describe('buildPdsClient', () => { configureGlobalAppLabelers(['did:plc:global-labeler']) await buildPdsClient(makeSession(fetchMock)).call( - com.atproto.server.getSession, + ComAtprotoServerGetSession, {}, ) @@ -260,7 +262,7 @@ describe('buildPdsClient', () => { * absolutizes it against its didDoc endpoint or, absent one, its service. */ await buildPdsClient(makeSession(fetchMock)).call( - com.atproto.server.getSession, + ComAtprotoServerGetSession, {}, ) @@ -286,7 +288,7 @@ describe('buildChatClient', () => { it('emits the chat proxy header exactly once, with the session token', async () => { /* the stub body fails listConvos output validation; headers are recorded pre-parse */ await buildChatClient(makeSession(fetchMock)) - .call(chat.bsky.convo.listConvos, {}) + .call(ChatBskyConvoListConvos, {}) .catch(() => {}) const headers = headersFor(fetchMock, 'chat.bsky.convo.listConvos') @@ -303,7 +305,7 @@ describe('buildChatClient', () => { configureGlobalAppLabelers(['did:plc:global-labeler']) await buildChatClient(makeSession(fetchMock)) - .call(chat.bsky.convo.listConvos, {}) + .call(ChatBskyConvoListConvos, {}) .catch(() => {}) expect( @@ -332,7 +334,7 @@ describe('routeSessionToPds', () => { const session = makeSession(fetchMock) const client = buildPdsClient(routeSessionToPds(session, PDS_HOST)) - await client.call(com.atproto.server.getSession, {}) + await client.call(ComAtprotoServerGetSession, {}) expect(urlsOf(fetchMock)).toEqual([ `${PDS_HOST}/xrpc/com.atproto.server.getSession`, @@ -343,7 +345,7 @@ describe('routeSessionToPds', () => { const session = makeSession(fetchMock) const client = buildPdsClient(routeSessionToPds(session, PDS_HOST)) - await client.call(com.atproto.server.getSession, {}) + await client.call(ComAtprotoServerGetSession, {}) expect( headersFor(fetchMock, 'com.atproto.server.getSession').get( @@ -369,7 +371,7 @@ describe('routeSessionToPds', () => { const session = makeSession(fetchMock, DIDDOC_PDS_HOST) const client = buildPdsClient(routeSessionToPds(session, PDS_HOST)) - await client.call(com.atproto.server.getSession, {}) + await client.call(ComAtprotoServerGetSession, {}) expect(urlsOf(fetchMock)).toEqual([ `${PDS_HOST}/xrpc/com.atproto.server.getSession`, @@ -383,7 +385,7 @@ describe('routeSessionToPds', () => { */ const client = buildPdsClient(makeSession(fetchMock, DIDDOC_PDS_HOST)) - await client.call(com.atproto.server.getSession, {}) + await client.call(ComAtprotoServerGetSession, {}) expect(urlsOf(fetchMock)).toEqual([ `${DIDDOC_PDS_HOST}/xrpc/com.atproto.server.getSession`, @@ -408,7 +410,7 @@ describe('getUnauthenticatedThrowingClient', () => { */ const fetchMock = makeProfileFetch() const err = await getUnauthenticatedThrowingClient() - .call(com.atproto.server.getSession, {}) + .call(ComAtprotoServerGetSession, {}) .then(() => undefined) .catch((e: unknown) => e) diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index e8e3613ddc..dec097bb38 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -17,7 +17,7 @@ import {useCloseAllActiveElements} from '#/state/util' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' import {AnalyticsContext, useAnalyticsBase, utils} from '#/analytics' import {IS_WEB} from '#/env' -import {com} from '#/lexicons' +import * as ComAtprotoServerGetSession from '#/lexicons/com/atproto/server/getSession' import {emitSessionDropped} from '../events' import {getPublicAppviewClient} from './clients' import {createSessionBundleAndCreateAccount} from './create-account' @@ -462,7 +462,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { .bundle as unknown as SessionBundle const signal = cancelPendingTask() /* getSession targets the PDS; only the persisted account fields are patched. */ - const data = await bundle.pdsClient.call(com.atproto.server.getSession, {}) + const data = await bundle.pdsClient.call(ComAtprotoServerGetSession, {}) if (signal.aborted) return store.dispatch({ type: 'partial-refresh-session', diff --git a/src/state/session/moderation.ts b/src/state/session/moderation.ts index 72afe204c2..4efaa222d7 100644 --- a/src/state/session/moderation.ts +++ b/src/state/session/moderation.ts @@ -3,7 +3,7 @@ import {type DidString} from '@atproto/syntax' import {api} from '@bsky/sdk' import {IS_TEST_USER} from '#/lib/constants' -import {com} from '#/lexicons' +import * as ComAtprotoIdentityResolveHandle from '#/lexicons/com/atproto/identity/resolveHandle' import {account as accountStorage} from '#/storage' import { configureAdditionalModerationAuthorities, @@ -101,7 +101,7 @@ function switchToBskyAppLabeler() { async function trySwitchToTestAppLabeler(client: Client) { const did = ( await client - .call(com.atproto.identity.resolveHandle, { + .call(ComAtprotoIdentityResolveHandle, { handle: 'mod-authority.test', }) .catch(_ => undefined) diff --git a/src/types/bsky/__tests__/index.test.ts b/src/types/bsky/__tests__/index.test.ts index ce7c98acab..4a59fd53e6 100644 --- a/src/types/bsky/__tests__/index.test.ts +++ b/src/types/bsky/__tests__/index.test.ts @@ -1,4 +1,5 @@ -import {app} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' const now = () => new Date().toISOString() @@ -34,11 +35,11 @@ const wrongType = { describe('types/bsky lexicon schema helpers (#/lexicons)', () => { describe('isType (fast, $type-only)', () => { it('accepts a valid record', () => { - expect(bsky.isType(app.bsky.feed.post, validPost)).toBe(true) + expect(bsky.isType(AppBskyFeedPost, validPost)).toBe(true) }) it('rejects a $type mismatch', () => { - expect(bsky.isType(app.bsky.feed.post, wrongType)).toBe(false) + expect(bsky.isType(AppBskyFeedPost, wrongType)).toBe(false) }) it('accepts an invalid body that has the right $type (dangerous semantics)', () => { @@ -46,18 +47,18 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { * Mirrors `dangerousIsType`: only the `$type` is checked, so a * structurally invalid record still passes. */ - expect(bsky.isType(app.bsky.feed.post, invalidPost)).toBe(true) + expect(bsky.isType(AppBskyFeedPost, invalidPost)).toBe(true) }) it('rejects a record with no $type at all', () => { - expect( - bsky.isType(app.bsky.feed.post, {text: 'hi', createdAt: now()}), - ).toBe(false) + expect(bsky.isType(AppBskyFeedPost, {text: 'hi', createdAt: now()})).toBe( + false, + ) }) it('accepts a schema passed as its namespace module or its main schema', () => { - expect(bsky.isType(app.bsky.feed.post, validPost)).toBe(true) - expect(bsky.isType(app.bsky.feed.post.main, validPost)).toBe(true) + expect(bsky.isType(AppBskyFeedPost, validPost)).toBe(true) + expect(bsky.isType(AppBskyFeedPost.main, validPost)).toBe(true) }) it('returns false (does not throw) for null, undefined and non-objects', () => { @@ -65,9 +66,9 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { * Mirrors the `dangerousIsType`/`is$typed` behavior - call sites pass * e.g. `post.record` which may be undefined. */ - expect(bsky.isType(app.bsky.feed.post, null)).toBe(false) - expect(bsky.isType(app.bsky.feed.post, undefined)).toBe(false) - expect(bsky.isType(app.bsky.feed.post, 'string')).toBe(false) + expect(bsky.isType(AppBskyFeedPost, null)).toBe(false) + expect(bsky.isType(AppBskyFeedPost, undefined)).toBe(false) + expect(bsky.isType(AppBskyFeedPost, 'string')).toBe(false) }) it('requires a present $type for typed-object def schemas', () => { @@ -77,10 +78,10 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { * discriminating unions by $type, an object without $type would * otherwise satisfy every branch. */ - expect(bsky.isType(app.bsky.feed.defs.postView, {foo: 1})).toBe(false) - expect(bsky.isType(app.bsky.feed.defs.postView, {})).toBe(false) + expect(bsky.isType(AppBskyFeedDefs.postView, {foo: 1})).toBe(false) + expect(bsky.isType(AppBskyFeedDefs.postView, {})).toBe(false) expect( - bsky.isType(app.bsky.feed.defs.postView, { + bsky.isType(AppBskyFeedDefs.postView, { $type: 'app.bsky.feed.defs#postView', }), ).toBe(true) @@ -92,9 +93,9 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { * `isType`. If either of these expectations starts failing, upstream has * changed and `isType` can consider delegating to `isTypeOf`. */ - expect(app.bsky.feed.defs.postView.isTypeOf({})).toBe(true) + expect(AppBskyFeedDefs.postView.isTypeOf({})).toBe(true) expect(() => - app.bsky.feed.post.main.isTypeOf( + AppBskyFeedPost.main.isTypeOf( null as unknown as {$type?: 'app.bsky.feed.post'}, ), ).toThrow() @@ -103,31 +104,31 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { describe('matches (full validation guard)', () => { it('accepts a valid record', () => { - expect(bsky.matches(app.bsky.feed.post, validPost)).toBe(true) + expect(bsky.matches(AppBskyFeedPost, validPost)).toBe(true) }) it('accepts a schema passed as its namespace module or its main schema', () => { - expect(bsky.matches(app.bsky.feed.post, validPost)).toBe(true) - expect(bsky.matches(app.bsky.feed.post.main, validPost)).toBe(true) + expect(bsky.matches(AppBskyFeedPost, validPost)).toBe(true) + expect(bsky.matches(AppBskyFeedPost.main, validPost)).toBe(true) }) it('rejects a $type mismatch', () => { - expect(bsky.matches(app.bsky.feed.post, wrongType)).toBe(false) + expect(bsky.matches(AppBskyFeedPost, wrongType)).toBe(false) }) it('rejects an invalid body even though the $type matches', () => { - expect(bsky.matches(app.bsky.feed.post, invalidPost)).toBe(false) + expect(bsky.matches(AppBskyFeedPost, invalidPost)).toBe(false) }) it('rejects null and undefined', () => { - expect(bsky.matches(app.bsky.feed.post, null)).toBe(false) - expect(bsky.matches(app.bsky.feed.post, undefined)).toBe(false) + expect(bsky.matches(AppBskyFeedPost, null)).toBe(false) + expect(bsky.matches(AppBskyFeedPost, undefined)).toBe(false) }) }) describe('safeParse (full validation, no throw)', () => { it('succeeds and returns the value for a valid record', () => { - const result = bsky.safeParse(app.bsky.feed.post, validPost) + const result = bsky.safeParse(AppBskyFeedPost, validPost) expect(result.success).toBe(true) if (result.success) { expect(result.value.text).toBe('hello world') @@ -135,7 +136,7 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { }) it('fails with a reason for an invalid record', () => { - const result = bsky.safeParse(app.bsky.feed.post, invalidPost) + const result = bsky.safeParse(AppBskyFeedPost, invalidPost) expect(result.success).toBe(false) if (!result.success) { expect(result.reason).toBeDefined() @@ -143,23 +144,23 @@ describe('types/bsky lexicon schema helpers (#/lexicons)', () => { }) it('accepts a schema passed as its main schema', () => { - const result = bsky.safeParse(app.bsky.feed.post.main, validPost) + const result = bsky.safeParse(AppBskyFeedPost.main, validPost) expect(result.success).toBe(true) }) }) describe('parse (full validation, throws)', () => { it('returns the typed value for a valid record', () => { - const record = bsky.parse(app.bsky.feed.post, validPost) + const record = bsky.parse(AppBskyFeedPost, validPost) expect(record.text).toBe('hello world') }) it('throws for an invalid record', () => { - expect(() => bsky.parse(app.bsky.feed.post, invalidPost)).toThrow() + expect(() => bsky.parse(AppBskyFeedPost, invalidPost)).toThrow() }) it('accepts a schema passed as its main schema', () => { - expect(bsky.parse(app.bsky.feed.post.main, validPost).text).toBe( + expect(bsky.parse(AppBskyFeedPost.main, validPost).text).toBe( 'hello world', ) }) diff --git a/src/types/bsky/index.ts b/src/types/bsky/index.ts index 278c1c1079..375a0c24ee 100644 --- a/src/types/bsky/index.ts +++ b/src/types/bsky/index.ts @@ -21,11 +21,11 @@ export * as starterPack from '#/types/bsky/starterPack' * schema, so these helpers take the schema object itself: * * ```ts - * import {app} from '#/lexicons' + * import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' * import * as bsky from '#/types/bsky' * - * bsky.isType(app.bsky.feed.post, v) - * bsky.matches(app.bsky.feed.post, v) + * bsky.isType(AppBskyFeedPost, v) + * bsky.matches(AppBskyFeedPost, v) * ``` * * Every generated namespace module (e.g. `app.bsky.feed.post`) re-exports its @@ -53,10 +53,10 @@ type TypedSchema = RecordSchema | TypedObjectSchema * * Usage: * ```ts - * import {app} from '#/lexicons' + * import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' * import * as bsky from '#/types/bsky' * - * if (bsky.isType(app.bsky.feed.post, item)) { + * if (bsky.isType(AppBskyFeedPost, item)) { * // `item` is narrowed to the post record type here * } * ``` @@ -89,10 +89,10 @@ export function isType( * * Usage: * ```ts - * import {app} from '#/lexicons' + * import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' * import * as bsky from '#/types/bsky' * - * if (bsky.matches(app.bsky.feed.post, item)) { + * if (bsky.matches(AppBskyFeedPost, item)) { * // `item` is narrowed to the post record type here * } * ``` @@ -115,10 +115,10 @@ export function matches( * * Usage: * ```ts - * import {app} from '#/lexicons' + * import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' * import * as bsky from '#/types/bsky' * - * const record = bsky.parse(app.bsky.feed.post, item) // typed, or throws + * const record = bsky.parse(AppBskyFeedPost, item) // typed, or throws * ``` */ export function parse( @@ -136,10 +136,10 @@ export function parse( * * Usage: * ```ts - * import {app} from '#/lexicons' + * import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' * import * as bsky from '#/types/bsky' * - * const result = bsky.safeParse(app.bsky.feed.post, item) + * const result = bsky.safeParse(AppBskyFeedPost, item) * if (result.success) { * // `result.value` is the typed post record * } else { diff --git a/src/types/bsky/post.ts b/src/types/bsky/post.ts index ed0d8a9d83..d1828530b6 100644 --- a/src/types/bsky/post.ts +++ b/src/types/bsky/post.ts @@ -1,56 +1,64 @@ import {type $Typed} from '@atproto/lex' -import {app} from '#/lexicons' +import * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyLabelerDefs from '#/lexicons/app/bsky/labeler/defs' import {isType} from '#/types/bsky' export type Embed = | { type: 'post' - view: $Typed + view: $Typed } | { type: 'post_not_found' - view: $Typed + view: $Typed } | { type: 'post_blocked' - view: $Typed + view: $Typed } | { type: 'post_detached' - view: $Typed + view: $Typed } | { type: 'feed' - view: $Typed + view: $Typed } | { type: 'list' - view: $Typed + view: $Typed } | { type: 'labeler' - view: $Typed + view: $Typed } | { type: 'starter_pack' - view: $Typed + view: $Typed } | { type: 'images' - view: $Typed + view: $Typed } | { type: 'gallery' - view: $Typed + view: $Typed } | { type: 'link' - view: $Typed + view: $Typed } | { type: 'video' - view: $Typed + view: $Typed } | { type: 'post_with_media' @@ -64,45 +72,43 @@ export type Embed = export type EmbedType = Extract -export function parseEmbedRecordView({ - record, -}: app.bsky.embed.record.View): Embed { - if (isType(app.bsky.embed.record.viewRecord, record)) { +export function parseEmbedRecordView({record}: AppBskyEmbedRecord.View): Embed { + if (isType(AppBskyEmbedRecord.viewRecord, record)) { return { type: 'post', view: record, } - } else if (isType(app.bsky.embed.record.viewNotFound, record)) { + } else if (isType(AppBskyEmbedRecord.viewNotFound, record)) { return { type: 'post_not_found', view: record, } - } else if (isType(app.bsky.embed.record.viewBlocked, record)) { + } else if (isType(AppBskyEmbedRecord.viewBlocked, record)) { return { type: 'post_blocked', view: record, } - } else if (isType(app.bsky.embed.record.viewDetached, record)) { + } else if (isType(AppBskyEmbedRecord.viewDetached, record)) { return { type: 'post_detached', view: record, } - } else if (isType(app.bsky.feed.defs.generatorView, record)) { + } else if (isType(AppBskyFeedDefs.generatorView, record)) { return { type: 'feed', view: record, } - } else if (isType(app.bsky.graph.defs.listView, record)) { + } else if (isType(AppBskyGraphDefs.listView, record)) { return { type: 'list', view: record, } - } else if (isType(app.bsky.labeler.defs.labelerView, record)) { + } else if (isType(AppBskyLabelerDefs.labelerView, record)) { return { type: 'labeler', view: record, } - } else if (isType(app.bsky.graph.defs.starterPackViewBasic, record)) { + } else if (isType(AppBskyGraphDefs.starterPackViewBasic, record)) { return { type: 'starter_pack', view: record, @@ -115,30 +121,30 @@ export function parseEmbedRecordView({ } } -export function parseEmbed(embed: app.bsky.feed.defs.PostView['embed']): Embed { - if (isType(app.bsky.embed.images.view, embed)) { +export function parseEmbed(embed: AppBskyFeedDefs.PostView['embed']): Embed { + if (isType(AppBskyEmbedImages.view, embed)) { return { type: 'images', view: embed, } - } else if (isType(app.bsky.embed.gallery.view, embed)) { + } else if (isType(AppBskyEmbedGallery.view, embed)) { return { type: 'gallery', view: embed, } - } else if (isType(app.bsky.embed.external.view, embed)) { + } else if (isType(AppBskyEmbedExternal.view, embed)) { return { type: 'link', view: embed, } - } else if (isType(app.bsky.embed.video.view, embed)) { + } else if (isType(AppBskyEmbedVideo.view, embed)) { return { type: 'video', view: embed, } - } else if (isType(app.bsky.embed.record.view, embed)) { + } else if (isType(AppBskyEmbedRecord.view, embed)) { return parseEmbedRecordView(embed) - } else if (isType(app.bsky.embed.recordWithMedia.view, embed)) { + } else if (isType(AppBskyEmbedRecordWithMedia.view, embed)) { return { type: 'post_with_media', view: parseEmbedRecordView(embed.record), diff --git a/src/types/bsky/starterPack.ts b/src/types/bsky/starterPack.ts index 594fd40c89..5b1c379411 100644 --- a/src/types/bsky/starterPack.ts +++ b/src/types/bsky/starterPack.ts @@ -1,4 +1,4 @@ -import {app} from '#/lexicons' +import * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' /* * The generated `$type`-only guards. These match on a present, matching @@ -8,20 +8,20 @@ import {app} from '#/lexicons' */ export function isBasicView( v: unknown, -): v is app.bsky.graph.defs.StarterPackViewBasic { +): v is AppBskyGraphDefs.StarterPackViewBasic { return ( v != null && typeof v === 'object' && (v as {$type?: unknown}).$type === - app.bsky.graph.defs.starterPackViewBasic.$type + AppBskyGraphDefs.starterPackViewBasic.$type ) } -export function isView(v: unknown): v is app.bsky.graph.defs.StarterPackView { +export function isView(v: unknown): v is AppBskyGraphDefs.StarterPackView { return ( v != null && typeof v === 'object' && - (v as {$type?: unknown}).$type === app.bsky.graph.defs.starterPackView.$type + (v as {$type?: unknown}).$type === AppBskyGraphDefs.starterPackView.$type ) } @@ -29,4 +29,4 @@ export function isView(v: unknown): v is app.bsky.graph.defs.StarterPackView { * Matches any starter pack view exported by our SDK. */ export type AnyStarterPackView = - app.bsky.graph.defs.StarterPackViewBasic | app.bsky.graph.defs.StarterPackView + AppBskyGraphDefs.StarterPackViewBasic | AppBskyGraphDefs.StarterPackView diff --git a/src/view/com/auth/LoggedOut.tsx b/src/view/com/auth/LoggedOut.tsx index b9d0f722c8..7d5b92942a 100644 --- a/src/view/com/auth/LoggedOut.tsx +++ b/src/view/com/auth/LoggedOut.tsx @@ -23,7 +23,7 @@ import {atoms as a, native, tokens, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times' import {useAnalytics} from '#/analytics' -import {app} from '#/lexicons' +import * as AppBskyActorGetProfiles from '#/lexicons/app/bsky/actor/getProfiles' import {SplashScreen} from './SplashScreen' enum ScreenState { @@ -74,7 +74,7 @@ export function LoggedOut({onDismiss}: {onDismiss?: () => void}) { queryKey: profilesQueryKey(actors), staleTime: STALE.MINUTES.FIVE, queryFn: async () => { - return await client.call(app.bsky.actor.getProfiles, {actors}) + return await client.call(AppBskyActorGetProfiles, {actors}) }, }) }, [accounts, client, queryClient]) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 6b4bf9a63f..0ccd3c2b79 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -144,7 +144,10 @@ import { IS_WEB_SAFARI, } from '#/env' import {type Gif} from '#/features/gifPicker/types' -import {app, chat} from '#/lexicons' +import * as AppBskyDraftCreateDraft from '#/lexicons/app/bsky/draft/createDraft' +import * as AppBskyUnspeccedDefs from '#/lexicons/app/bsky/unspecced/defs' +import * as AppBskyUnspeccedGetPostThreadV2 from '#/lexicons/app/bsky/unspecced/getPostThreadV2' +import * as ChatBskyGroupDefs from '#/lexicons/chat/bsky/group/defs' import * as bsky from '#/types/bsky' import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet' import { @@ -767,9 +770,7 @@ export const ComposePost = ({ const getDraftSaveError = useCallback( (e: unknown): string => { - if ( - matchXrpcError(e, app.bsky.draft.createDraft) === 'DraftLimitReached' - ) { + if (matchXrpcError(e, AppBskyDraftCreateDraft) === 'DraftLimitReached') { return l`You've reached the maximum number of drafts` } return l`Failed to save draft` @@ -1008,7 +1009,7 @@ export const ComposePost = ({ const hasUnavailableChatInvite = linkQueries.some( q => q.data?.type === 'chat-invite' && - !bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, q.data.view), + !bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, q.data.view), ) const canPost = @@ -1124,21 +1125,18 @@ export const ComposePost = ({ 5, _e => true, async () => { - const res = await client.call( - app.bsky.unspecced.getPostThreadV2, - { - anchor: postUri! as AtUriString, - above: false, - below: filteredThread.posts.length - 1, - branchingFactor: 1, - }, - ) + const res = await client.call(AppBskyUnspeccedGetPostThreadV2, { + anchor: postUri! as AtUriString, + above: false, + below: filteredThread.posts.length - 1, + branchingFactor: 1, + }) if (res.thread.length !== filteredThread.posts.length) { throw new Error(`composer: app view is not ready`) } if ( !res.thread.every(p => - bsky.isType(app.bsky.unspecced.defs.threadItemPost, p.value), + bsky.isType(AppBskyUnspeccedDefs.threadItemPost, p.value), ) ) { throw new Error(`composer: app view returned non-post items`) @@ -1210,7 +1208,7 @@ export const ComposePost = ({ const resolved = q.data if ( resolved?.type === 'chat-invite' && - bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, resolved.view) + bsky.isType(ChatBskyGroupDefs.joinLinkPreviewView, resolved.view) ) { ax.metric('groupchat:inviteLink:shared', { convoId: resolved.view.convoId, @@ -1249,7 +1247,7 @@ export const ComposePost = ({ void whenAppViewReady(client, initQuote.uri, res => { const anchor = res.thread.at(0) if ( - bsky.isType(app.bsky.unspecced.defs.threadItemPost, anchor?.value) && + bsky.isType(AppBskyUnspeccedDefs.threadItemPost, anchor?.value) && anchor.value.post.quoteCount !== initQuote.quoteCount ) { onPost?.(postUri) @@ -2512,14 +2510,14 @@ function useKeyboardVerticalOffset() { async function whenAppViewReady( client: Client, uri: string, - fn: (res: app.bsky.unspecced.getPostThreadV2.$OutputBody) => boolean, + fn: (res: AppBskyUnspeccedGetPostThreadV2.$OutputBody) => boolean, ) { await until( 5, // 5 tries 1e3, // 1s delay between tries fn, () => - client.call(app.bsky.unspecced.getPostThreadV2, { + client.call(AppBskyUnspeccedGetPostThreadV2, { anchor: uri as AtUriString, above: false, below: 0, diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 175cda7d30..b23b437b53 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -13,7 +13,11 @@ import {atoms as a, useTheme, utils, web} from '#/alf' import {QuoteEmbed} from '#/components/Post/Embed' import {ProfileBadges} from '#/components/ProfileBadges' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import * as AppBskyEmbedRecord from '#/lexicons/app/bsky/embed/record' +import * as AppBskyEmbedRecordWithMedia from '#/lexicons/app/bsky/embed/recordWithMedia' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import {parseEmbed} from '#/types/bsky/post' @@ -34,15 +38,15 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { const quoteEmbed = useMemo(() => { if ( - bsky.isType(app.bsky.embed.record.view, embed) && - bsky.isType(app.bsky.embed.record.viewRecord, embed.record) && - bsky.isType(app.bsky.feed.post, embed.record.value) + bsky.isType(AppBskyEmbedRecord.view, embed) && + bsky.isType(AppBskyEmbedRecord.viewRecord, embed.record) && + bsky.isType(AppBskyFeedPost, embed.record.value) ) { return embed } else if ( - bsky.isType(app.bsky.embed.recordWithMedia.view, embed) && - bsky.isType(app.bsky.embed.record.viewRecord, embed.record.record) && - bsky.isType(app.bsky.feed.post, embed.record.record.value) + bsky.isType(AppBskyEmbedRecordWithMedia.view, embed) && + bsky.isType(AppBskyEmbedRecord.viewRecord, embed.record.record) && + bsky.isType(AppBskyFeedPost, embed.record.record.value) ) { return embed.record } @@ -56,20 +60,20 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { : null const {images, totalNumber} = useMemo(() => { - if (bsky.isType(app.bsky.embed.images.view, embed)) { + if (bsky.isType(AppBskyEmbedImages.view, embed)) { return {images: embed.images, totalNumber: embed.images.length} - } else if (bsky.isType(app.bsky.embed.gallery.view, embed)) { + } else if (bsky.isType(AppBskyEmbedGallery.view, embed)) { return { images: galleryItemsToImages(embed.items), totalNumber: embed.items.length, } - } else if (bsky.isType(app.bsky.embed.recordWithMedia.view, embed)) { - if (bsky.isType(app.bsky.embed.images.view, embed.media)) { + } else if (bsky.isType(AppBskyEmbedRecordWithMedia.view, embed)) { + if (bsky.isType(AppBskyEmbedImages.view, embed.media)) { return { images: embed.media.images, totalNumber: embed.media.images.length, } - } else if (bsky.isType(app.bsky.embed.gallery.view, embed.media)) { + } else if (bsky.isType(AppBskyEmbedGallery.view, embed.media)) { return { images: galleryItemsToImages(embed.media.items), totalNumber: embed.media.items.length, @@ -140,12 +144,12 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { } function galleryItemsToImages( - items: app.bsky.embed.gallery.View['items'], -): app.bsky.embed.images.ViewImage[] { + items: AppBskyEmbedGallery.View['items'], +): AppBskyEmbedImages.ViewImage[] { // The reply-to thumbnail only renders up to 4 tiles; slicing here keeps // the existing layout switch valid for galleries up to 10 items. return items - .filter(item => bsky.isType(app.bsky.embed.gallery.viewImage, item)) + .filter(item => bsky.isType(AppBskyEmbedGallery.viewImage, item)) .slice(0, 4) .map(item => ({ thumb: item.thumbnail, @@ -159,7 +163,7 @@ function ComposerReplyToImages({ images, totalNumber, }: { - images: app.bsky.embed.images.ViewImage[] + images: AppBskyEmbedImages.ViewImage[] totalNumber: number }) { const t = useTheme() diff --git a/src/view/com/composer/drafts/state/api.ts b/src/view/com/composer/drafts/state/api.ts index 5507460be0..8b25b5fc45 100644 --- a/src/view/com/composer/drafts/state/api.ts +++ b/src/view/com/composer/drafts/state/api.ts @@ -23,7 +23,7 @@ import {type VideoState} from '#/view/com/composer/state/video' import {type AnalyticsContextType} from '#/analytics' import {getDeviceId} from '#/analytics/identifiers' import {type Gif} from '#/features/gifPicker/types' -import {app} from '#/lexicons' +import * as AppBskyDraftDefs from '#/lexicons/app/bsky/draft/defs' import * as bsky from '#/types/bsky' import {logger} from './logger' import {type DraftPostDisplay, type DraftSummary} from './schema' @@ -66,18 +66,18 @@ export async function composerStateToDraft( clients: LinkResolvers, state: ComposerState, ): Promise<{ - draft: app.bsky.draft.defs.Draft + draft: AppBskyDraftDefs.Draft localRefPaths: Map }> { const localRefPaths = new Map() - const posts: app.bsky.draft.defs.DraftPost[] = await Promise.all( + const posts: AppBskyDraftDefs.DraftPost[] = await Promise.all( state.thread.posts.map(post => { return postDraftToServerPost(clients, post, localRefPaths) }), ) - const draft: app.bsky.draft.defs.Draft = { + const draft: AppBskyDraftDefs.Draft = { $type: 'app.bsky.draft.defs#draft', deviceId: getDeviceId(), deviceName: getDeviceName().slice(0, 100), // max length of 100 in lex @@ -102,8 +102,8 @@ async function postDraftToServerPost( clients: LinkResolvers, post: PostDraft, localRefPaths: Map, -): Promise { - const draftPost: app.bsky.draft.defs.DraftPost = { +): Promise { + const draftPost: AppBskyDraftDefs.DraftPost = { $type: 'app.bsky.draft.defs#draftPost', text: post.richtext.text, } @@ -179,7 +179,7 @@ async function postDraftToServerPost( function serializeImages( images: ComposerImage[], localRefPaths: Map, -): app.bsky.draft.defs.DraftEmbedGalleryItems { +): AppBskyDraftDefs.DraftEmbedGalleryItems { return images.map(image => { const sourcePath = image.transformed?.path || image.source.path // Reuse existing localRefPath if present (editing draft), otherwise generate new @@ -211,7 +211,7 @@ function serializeImages( async function serializeVideo( videoState: VideoState, localRefPaths: Map, -): Promise { +): Promise { // Only save videos that have been compressed (have a video file) if (!videoState.video) { return undefined @@ -224,7 +224,7 @@ async function serializeVideo( localRefPaths.set(localRefPath, videoState.video.uri) // Read caption file contents as text - const captions: app.bsky.draft.defs.DraftEmbedCaption[] = [] + const captions: AppBskyDraftDefs.DraftEmbedCaption[] = [] for (const caption of videoState.captions) { if (caption.lang) { const content = await caption.file.text() @@ -255,7 +255,7 @@ function serializeGif(gifMedia: { type: 'gif' gif: Gif alt: string -}): app.bsky.draft.defs.DraftEmbedExternal | undefined { +}): AppBskyDraftDefs.DraftEmbedExternal | undefined { const gif = gifMedia.gif const gifFormat = gif.media_formats.gif || gif.media_formats.tinygif @@ -285,7 +285,7 @@ function serializeGif(gifMedia: { * both the `embedImages` and `embedGallery` paths in draftToComposerPosts. */ async function restoreDraftImages( - draftImages: app.bsky.draft.defs.DraftEmbedImage[], + draftImages: AppBskyDraftDefs.DraftEmbedImage[], loadedMedia: Map, ): Promise { const imagePromises = draftImages.map(async img => { @@ -341,7 +341,7 @@ export function draftViewToSummary({ view, analytics, }: { - view: app.bsky.draft.defs.DraftView + view: AppBskyDraftDefs.DraftView analytics: AnalyticsContextType }): DraftSummary { const meta = { @@ -381,7 +381,7 @@ export function draftViewToSummary({ // Process gallery if (post.embedGallery) { for (const item of post.embedGallery.items) { - if (!bsky.isType(app.bsky.draft.defs.draftEmbedImage, item)) continue + if (!bsky.isType(AppBskyDraftDefs.draftEmbedImage, item)) continue meta.mediaCount++ meta.hasMedia = true const exists = storage.mediaExists(item.localRef.path) @@ -497,7 +497,7 @@ function parseGifFromUrl( * by initiating video processing for each entry. */ export async function draftToComposerPosts( - draft: app.bsky.draft.defs.Draft, + draft: AppBskyDraftDefs.Draft, loadedMedia: Map, ): Promise<{posts: PostDraft[]; restoredVideos: Map}> { const restoredVideos = new Map() @@ -527,7 +527,7 @@ export async function draftToComposerPosts( } if (post.embedGallery && post.embedGallery.items.length > 0) { const galleryImages = post.embedGallery.items.filter(item => - bsky.isType(app.bsky.draft.defs.draftEmbedImage, item), + bsky.isType(AppBskyDraftDefs.draftEmbedImage, item), ) restoredImages.push( ...(await restoreDraftImages(galleryImages, loadedMedia)), @@ -647,7 +647,7 @@ export async function draftToComposerPosts( * Convert server threadgate rules back to UI settings. */ export function threadgateToUISettings( - threadgateAllow?: app.bsky.draft.defs.Draft['threadgateAllow'], + threadgateAllow?: AppBskyDraftDefs.Draft['threadgateAllow'], ): Array<{type: string; list?: string}> { if (!threadgateAllow) { return [] @@ -681,9 +681,7 @@ export function threadgateToUISettings( * Extract all localRef paths from a draft. * Used to identify which media files belong to a draft for cleanup. */ -export function extractLocalRefs( - draft: app.bsky.draft.defs.Draft, -): Set { +export function extractLocalRefs(draft: AppBskyDraftDefs.Draft): Set { const refs = new Set() for (const post of draft.posts) { if (post.embedImages) { @@ -693,7 +691,7 @@ export function extractLocalRefs( } if (post.embedGallery) { for (const item of post.embedGallery.items) { - if (!bsky.isType(app.bsky.draft.defs.draftEmbedImage, item)) continue + if (!bsky.isType(AppBskyDraftDefs.draftEmbedImage, item)) continue refs.add(item.localRef.path) } } diff --git a/src/view/com/composer/drafts/state/queries.ts b/src/view/com/composer/drafts/state/queries.ts index ec786239a4..a4abadbded 100644 --- a/src/view/com/composer/drafts/state/queries.ts +++ b/src/view/com/composer/drafts/state/queries.ts @@ -10,7 +10,11 @@ import {useAppviewClient, useChatClient} from '#/state/session' import {type ComposerState} from '#/view/com/composer/state/composer' import {useAnalytics} from '#/analytics' import {getDeviceId} from '#/analytics/identifiers' -import {app} from '#/lexicons' +import * as AppBskyDraftCreateDraft from '#/lexicons/app/bsky/draft/createDraft' +import * as AppBskyDraftDefs from '#/lexicons/app/bsky/draft/defs' +import * as AppBskyDraftDeleteDraft from '#/lexicons/app/bsky/draft/deleteDraft' +import * as AppBskyDraftGetDrafts from '#/lexicons/app/bsky/draft/getDrafts' +import * as AppBskyDraftUpdateDraft from '#/lexicons/app/bsky/draft/updateDraft' import * as bsky from '#/types/bsky' import {composerStateToDraft, draftViewToSummary} from './api' import {logger} from './logger' @@ -30,7 +34,7 @@ export function useDraftsQuery() { queryFn: async ({pageParam}) => { // Ensure media cache is populated before checking which media exists await storage.ensureMediaCachePopulated() - const data = await client.call(app.bsky.draft.getDrafts, { + const data = await client.call(AppBskyDraftGetDrafts, { cursor: pageParam, }) return { @@ -52,9 +56,7 @@ export function useDraftsQuery() { * Load a draft's local media for editing. * Takes the full Draft object (from DraftSummary) to avoid re-fetching. */ -export async function loadDraftMedia( - draft: app.bsky.draft.defs.Draft, -): Promise<{ +export async function loadDraftMedia(draft: AppBskyDraftDefs.Draft): Promise<{ loadedMedia: Map }> { // Load local media files @@ -83,7 +85,7 @@ export async function loadDraftMedia( // Load gallery if (post.embedGallery) { for (const item of post.embedGallery.items) { - if (!bsky.isType(app.bsky.draft.defs.draftEmbedImage, item)) continue + if (!bsky.isType(AppBskyDraftDefs.draftEmbedImage, item)) continue try { const url = await storage.loadMediaFromLocal(item.localRef.path) loadedMedia.set(item.localRef.path, url) @@ -158,7 +160,7 @@ export function useSaveDraftMutation() { logger.debug('updating existing draft on server', { draftId: existingDraftId, }) - await client.call(app.bsky.draft.updateDraft, { + await client.call(AppBskyDraftUpdateDraft, { draft: { id: existingDraftId, draft, @@ -168,7 +170,7 @@ export function useSaveDraftMutation() { } else { // Create new draft logger.debug('creating new draft on server') - const data = await client.call(app.bsky.draft.createDraft, {draft}) + const data = await client.call(AppBskyDraftCreateDraft, {draft}) draftId = data.id logger.debug('created new draft', {draftId}) } @@ -214,7 +216,7 @@ export function useSaveDraftMutation() { }, onError: error => { // Check for draft limit error - if (matchXrpcError(error, app.bsky.draft.createDraft)) { + if (matchXrpcError(error, AppBskyDraftCreateDraft)) { logger.error('Draft limit reached', {safeMessage: error.message}) // Error will be handled by caller } else if (!isNetworkError(error)) { @@ -239,10 +241,10 @@ export function useDeleteDraftMutation() { draftId, }: { draftId: string - draft: app.bsky.draft.defs.Draft + draft: AppBskyDraftDefs.Draft }) => { // Delete from server first - if this fails, we keep local media for retry - await client.call(app.bsky.draft.deleteDraft, {id: draftId}) + await client.call(AppBskyDraftDeleteDraft, {id: draftId}) }, onSuccess: async (_, {draft}) => { // Only delete local media after server deletion succeeds @@ -254,8 +256,7 @@ export function useDeleteDraftMutation() { } if (post.embedGallery) { for (const item of post.embedGallery.items) { - if (!bsky.isType(app.bsky.draft.defs.draftEmbedImage, item)) - continue + if (!bsky.isType(AppBskyDraftDefs.draftEmbedImage, item)) continue await storage.deleteMediaFromLocal(item.localRef.path) } } @@ -292,7 +293,7 @@ export function useCleanupPublishedDraftMutation() { mediaFileCount: originalLocalRefs.size, }) // Delete from server first - await client.call(app.bsky.draft.deleteDraft, { + await client.call(AppBskyDraftDeleteDraft, { id: draftId, }) logger.debug('deleted draft from server', {draftId}) diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts index 5a013a830b..a1b7992333 100644 --- a/src/view/com/composer/state/composer.ts +++ b/src/view/com/composer/state/composer.ts @@ -24,7 +24,10 @@ import { suggestLinkCardUri, } from '#/view/com/composer/text-input/text-input-util' import {type Gif} from '#/features/gifPicker/types' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyDraftDefs from '#/lexicons/app/bsky/draft/defs' +import type * as AppBskyFeedPostgate from '#/lexicons/app/bsky/feed/postgate' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' import { createVideoState, @@ -105,7 +108,7 @@ export type PostAction = export type ThreadDraft = { posts: PostDraft[] - postgate: app.bsky.feed.postgate.Main + postgate: AppBskyFeedPostgate.Main threadgate: ThreadgateAllowUISetting[] } @@ -124,7 +127,7 @@ export type ComposerState = { } export type ComposerAction = - | {type: 'update_postgate'; postgate: app.bsky.feed.postgate.Main} + | {type: 'update_postgate'; postgate: AppBskyFeedPostgate.Main} | {type: 'update_threadgate'; threadgate: ThreadgateAllowUISetting[]} | { type: 'update_post' @@ -146,8 +149,8 @@ export type ComposerAction = type: 'restore_from_draft' draftId: string posts: PostDraft[] - threadgateAllow: app.bsky.draft.defs.Draft['threadgateAllow'] - postgateEmbeddingRules: app.bsky.draft.defs.Draft['postgateEmbeddingRules'] + threadgateAllow: AppBskyDraftDefs.Draft['threadgateAllow'] + postgateEmbeddingRules: AppBskyDraftDefs.Draft['postgateEmbeddingRules'] /** Map of localRefPath -> loaded media path/URL */ loadedMedia: Map @@ -157,7 +160,7 @@ export type ComposerAction = | { type: 'clear' initInteractionSettings: - app.bsky.actor.defs.PostInteractionSettingsPref | undefined + AppBskyActorDefs.PostInteractionSettingsPref | undefined } | { type: 'mark_saved' @@ -631,7 +634,7 @@ export function createComposerState({ initImageUris: ComposerOpts['imageUris'] initQuoteUri: string | undefined initInteractionSettings: - app.bsky.actor.defs.PostInteractionSettingsPref | undefined + AppBskyActorDefs.PostInteractionSettingsPref | undefined }): ComposerState { let media: ImagesMedia | GalleryMedia | undefined if (initImageUris?.length) { @@ -678,7 +681,7 @@ export function createComposerState({ if (initRichText.facets) { for (const facet of initRichText.facets) { for (const feature of facet.features) { - if (bsky.isType(app.bsky.richtext.facet.link, feature)) { + if (bsky.isType(AppBskyRichtextFacet.link, feature)) { if (isBskyPostUrl(feature.uri)) { detectedPostUris.set(feature.uri, {facet, rt: initRichText}) } else { diff --git a/src/view/com/composer/state/video.ts b/src/view/com/composer/state/video.ts index 2f7a1ead62..2fba509e92 100644 --- a/src/view/com/composer/state/video.ts +++ b/src/view/com/composer/state/video.ts @@ -17,7 +17,8 @@ import {uploadVideo} from '#/lib/media/video/upload' import {createTokenlessVideoServiceClient} from '#/lib/media/video/util' import {isNetworkError} from '#/lib/strings/errors' import {logger} from '#/logger' -import {app} from '#/lexicons' +import type * as AppBskyVideoDefs from '#/lexicons/app/bsky/video/defs' +import * as AppBskyVideoGetJobStatus from '#/lexicons/app/bsky/video/getJobStatus' import { advanceVideoProgress, didSkipVideoCompression, @@ -57,7 +58,7 @@ export type VideoAction = } | { type: 'update_job_status' - jobStatus: app.bsky.video.defs.JobStatus + jobStatus: AppBskyVideoDefs.JobStatus signal: AbortSignal } @@ -127,7 +128,7 @@ type ProcessingState = { asset: ImagePickerAsset video: CompressedVideo jobId: string - jobStatus: app.bsky.video.defs.JobStatus | null + jobStatus: AppBskyVideoDefs.JobStatus | null pendingPublish?: undefined telemetry: VideoTelemetry altText: string @@ -337,7 +338,7 @@ export async function processVideo( signal, }) - let uploadResponse: app.bsky.video.defs.JobStatus | undefined + let uploadResponse: AppBskyVideoDefs.JobStatus | undefined try { telemetry.uploadStarted(video.size) uploadResponse = await uploadVideo({ @@ -381,10 +382,10 @@ export async function processVideo( } const videoClient = createTokenlessVideoServiceClient() - let status: app.bsky.video.defs.JobStatus | undefined + let status: AppBskyVideoDefs.JobStatus | undefined let blob: BlobRef | undefined try { - const response = await videoClient.call(app.bsky.video.getJobStatus, { + const response = await videoClient.call(AppBskyVideoGetJobStatus, { jobId, }) status = response.jobStatus diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx index d2d108b570..e105540a4f 100644 --- a/src/view/com/composer/text-input/TextInput.tsx +++ b/src/view/com/composer/text-input/TextInput.tsx @@ -27,7 +27,7 @@ import { import {atoms as a, useAlf} from '#/alf' import {normalizeTextStyles} from '#/alf/typography' import {IS_ANDROID} from '#/env' -import {app} from '#/lexicons' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' import {Autocomplete} from './mobile/Autocomplete' import {type TextInputProps} from './TextInput.types' @@ -90,7 +90,7 @@ export function TextInput({ if (newRt.facets) { for (const facet of newRt.facets) { for (const feature of facet.features) { - if (bsky.isType(app.bsky.richtext.facet.link, feature)) { + if (bsky.isType(AppBskyRichtextFacet.link, feature)) { if (isUriImage(feature.uri)) { const res = await downloadAndResize({ uri: feature.uri, diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index 79f0c2db46..4860f1ca68 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -40,7 +40,7 @@ import {normalizeTextStyles} from '#/alf/typography' import {type Emoji} from '#/components/EmojiPicker' import {Portal} from '#/components/Portal' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyRichtextFacet from '#/lexicons/app/bsky/richtext/facet' import * as bsky from '#/types/bsky' import {type TextInputProps} from './TextInput.types' import {type AutocompleteRef, createSuggestion} from './web/Autocomplete' @@ -267,7 +267,7 @@ export function TextInput({ if (newRt.facets) { for (const facet of newRt.facets) { for (const feature of facet.features) { - if (bsky.isType(app.bsky.richtext.facet.link, feature)) { + if (bsky.isType(AppBskyRichtextFacet.link, feature)) { nextDetectedUris.set(feature.uri, {facet, rt: newRt}) } } diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index 10572f9cba..1da1abc513 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -37,7 +37,8 @@ import {useHeaderOffset} from '#/components/hooks/useHeaderOffset' import {EditBig_Stroke2_Corner2_Rounded as EditBigIcon} from '#/components/icons/EditBig' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' const POLL_FREQ = 60e3 // 60sec @@ -59,7 +60,7 @@ export function FeedPage({ isPageAdjacent: boolean renderEmptyState: () => JSX.Element renderEndOfFeed?: () => JSX.Element - savedFeedConfig?: app.bsky.actor.defs.SavedFeed + savedFeedConfig?: AppBskyActorDefs.SavedFeed feedInfo: FeedSourceInfo }) { const ax = useAnalytics() @@ -77,7 +78,7 @@ export function FeedPage({ const isVideoFeed = useMemo(() => { const isBskyVideoFeed = VIDEO_FEED_URIS.includes(feedInfo.uri) const feedIsVideoMode = - feedInfo.contentMode === app.bsky.feed.defs.contentModeVideo.value + feedInfo.contentMode === AppBskyFeedDefs.contentModeVideo.value const _isVideoFeed = isBskyVideoFeed || feedIsVideoMode return IS_NATIVE && _isVideoFeed }, [feedInfo]) diff --git a/src/view/com/feeds/FeedSourceCard.tsx b/src/view/com/feeds/FeedSourceCard.tsx index ecc11c5864..566a1b1205 100644 --- a/src/view/com/feeds/FeedSourceCard.tsx +++ b/src/view/com/feeds/FeedSourceCard.tsx @@ -18,15 +18,15 @@ import {atoms as a, useTheme} from '#/alf' import {Link} from '#/components/Link' import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' import * as bsky from '#/types/bsky' import {MissingFeed} from './MissingFeed' type FeedSourceCardProps = { feedUri: string feedData?: - | $Typed - | $Typed + $Typed | $Typed style?: StyleProp showSaveBtn?: boolean showDescription?: boolean @@ -44,7 +44,7 @@ export function FeedSourceCard({ }: FeedSourceCardProps) { if (feedData) { let feed: FeedSourceInfo - if (bsky.isType(app.bsky.feed.defs.generatorView, feedData)) { + if (bsky.isType(AppBskyFeedDefs.generatorView, feedData)) { feed = hydrateFeedGenerator(feedData) } else { feed = hydrateList(feedData) diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx index 0d56dfb873..8400cf6780 100644 --- a/src/view/com/notifications/NotificationFeedItem.tsx +++ b/src/view/com/notifications/NotificationFeedItem.tsx @@ -67,13 +67,19 @@ import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {app, chat} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import type * as AppBskyGraphDefs from '#/lexicons/app/bsky/graph/defs' +import * as AppBskyGraphFollow from '#/lexicons/app/bsky/graph/follow' +import * as AppBskyGraphStarterpack from '#/lexicons/app/bsky/graph/starterpack' +import * as ChatBskyConvoGetConvoForMembers from '#/lexicons/chat/bsky/convo/getConvoForMembers' import * as bsky from '#/types/bsky' const MAX_AUTHORS = 5 interface Author { - profile: app.bsky.actor.defs.ProfileView + profile: AppBskyActorDefs.ProfileView href: string moderation: ModerationDecision } @@ -186,7 +192,7 @@ let NotificationFeedItem = ({ if (item.type !== 'follow') return false if ( item.notification.author.viewer?.following && - bsky.isType(app.bsky.graph.follow, item.notification.record) + bsky.isType(AppBskyGraphFollow, item.notification.record) ) { let followingTimestamp try { @@ -722,7 +728,7 @@ export {NotificationFeedItem} function FollowedViaStarterPack({ starterPack, }: { - starterPack: app.bsky.graph.defs.StarterPackViewBasic + starterPack: AppBskyGraphDefs.StarterPackViewBasic }) { const t = useTheme() const link = useStarterPackLink({view: starterPack}) @@ -756,9 +762,9 @@ function FollowedViaStarterPack({ } function getStarterPackName( - starterPack: app.bsky.graph.defs.StarterPackViewBasic, + starterPack: AppBskyGraphDefs.StarterPackViewBasic, ) { - return bsky.isType(app.bsky.graph.starterpack, starterPack.record) + return bsky.isType(AppBskyGraphStarterpack, starterPack.record) ? starterPack.record.name : undefined } @@ -792,11 +798,7 @@ function ExpandListPressable({ } } -function FollowBackButton({ - profile, -}: { - profile: app.bsky.actor.defs.ProfileView -}) { +function FollowBackButton({profile}: {profile: AppBskyActorDefs.ProfileView}) { const {t: l} = useLingui() const {currentAccount, hasSession} = useSession() const profileShadow = useProfileShadow(profile) @@ -902,7 +904,7 @@ function FollowBackButton({ ) } -function SayHelloBtn({profile}: {profile: app.bsky.actor.defs.ProfileView}) { +function SayHelloBtn({profile}: {profile: AppBskyActorDefs.ProfileView}) { const {t: l} = useLingui() const client = useChatClient() const {currentAccount} = useSession() @@ -912,7 +914,7 @@ function SayHelloBtn({profile}: {profile: app.bsky.actor.defs.ProfileView}) { const onPress = async () => { try { setIsLoading(true) - const data = await client.call(chat.bsky.convo.getConvoForMembers, { + const data = await client.call(ChatBskyConvoGetConvoForMembers, { members: [profile.did, currentAccount!.did], }) navigation.navigate('MessagesConversation', { @@ -1134,9 +1136,9 @@ function ExpandedAuthorProfileCard({ ) } -function AdditionalPostText({post}: {post?: app.bsky.feed.defs.PostView}) { +function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) { const t = useTheme() - if (post && bsky.isType(app.bsky.feed.post, post?.record)) { + if (post && bsky.isType(AppBskyFeedPost, post?.record)) { const text = post.record.text return ( diff --git a/src/view/com/post-thread/PostQuotes.tsx b/src/view/com/post-thread/PostQuotes.tsx index 7bd63d1992..2c31a63911 100644 --- a/src/view/com/post-thread/PostQuotes.tsx +++ b/src/view/com/post-thread/PostQuotes.tsx @@ -12,7 +12,8 @@ import {usePostQuotesQuery} from '#/state/queries/post-quotes' import {useResolveUriQuery} from '#/state/queries/resolve-uri' import {Post} from '#/view/com/post/Post' import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' import {List} from '../util/List' @@ -21,9 +22,9 @@ function renderItem({ index, }: { item: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView moderation: ModerationDecision - record: app.bsky.feed.post.Main + record: AppBskyFeedPost.Main } index: number }) { @@ -31,9 +32,9 @@ function renderItem({ } function keyExtractor(item: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView moderation: ModerationDecision - record: app.bsky.feed.post.Main + record: AppBskyFeedPost.Main }) { return item.post.uri } @@ -67,10 +68,7 @@ export function PostQuotes({uri}: {uri: string}) { data?.pages .flatMap(page => page.posts.map(post => { - if ( - !bsky.isType(app.bsky.feed.post, post.record) || - !moderationOpts - ) { + if (!bsky.isType(AppBskyFeedPost, post.record) || !moderationOpts) { return null } const moderation = moderatePost(post, moderationOpts) diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 94398778e8..841f78c1b0 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -34,7 +34,8 @@ import {TranslatedPost} from '#/components/Post/Translated' import {PostControls} from '#/components/PostControls' import {RichText} from '#/components/RichText' import {SubtleHover} from '#/components/SubtleHover' -import {app} from '#/lexicons' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' import * as bsky from '#/types/bsky' export function Post({ @@ -44,16 +45,16 @@ export function Post({ style, onBeforePress, }: { - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView showReplyLine?: boolean hideTopBorder?: boolean style?: StyleProp onBeforePress?: () => void }) { const moderationOpts = useModerationOpts() - const record = useMemo( + const record = useMemo( () => - bsky.matches(app.bsky.feed.post, post.record) ? post.record : undefined, + bsky.matches(AppBskyFeedPost, post.record) ? post.record : undefined, [post], ) const postShadowed = usePostShadow(post) @@ -103,8 +104,8 @@ function PostInner({ style, onBeforePress: outerOnBeforePress, }: { - post: Shadow - record: app.bsky.feed.post.Main + post: Shadow + record: AppBskyFeedPost.Main richText: RichTextAPI moderation: ModerationDecision showReplyLine?: boolean diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index 62bf3209c9..c1ca9187f2 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -74,7 +74,12 @@ import { isStatusValidForViewers, useLiveNowConfig, } from '#/features/liveNow' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyEmbedExternal from '#/lexicons/app/bsky/embed/external' +import * as AppBskyEmbedGallery from '#/lexicons/app/bsky/embed/gallery' +import * as AppBskyEmbedImages from '#/lexicons/app/bsky/embed/images' +import * as AppBskyEmbedVideo from '#/lexicons/app/bsky/embed/video' +import type * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' import {ComposerPrompt} from '../feeds/ComposerPrompt' import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' @@ -250,7 +255,7 @@ let PostFeed = ({ desktopFixedHeightOffset?: number ListHeaderComponent?: () => React.ReactElement extraData?: Record - savedFeedConfig?: app.bsky.actor.defs.SavedFeed + savedFeedConfig?: AppBskyActorDefs.SavedFeed initialNumToRender?: number isVideoFeed?: boolean lastFetchDate?: () => number @@ -284,7 +289,7 @@ let PostFeed = ({ () => new Set(), ) const onPressShowLess = useCallback( - (interaction: app.bsky.feed.defs.Interaction) => { + (interaction: AppBskyFeedDefs.Interaction) => { if (interaction.item) { const uri = interaction.item setHasPressedShowLessUris(prev => new Set([...prev, uri])) @@ -486,7 +491,7 @@ let PostFeed = ({ ) if ( item && - bsky.isType(app.bsky.embed.video.view, item.post.embed) && + bsky.isType(AppBskyEmbedVideo.view, item.post.embed) && !blockedOrMutedAuthors.includes(item.post.author.did) ) { videos.push({ @@ -1026,13 +1031,13 @@ let PostFeed = ({ // Events that should fire exactly once for every new post, regardless of // its position within a slice or video grid row. - const onPostSeen = (post: app.bsky.feed.defs.PostView) => { + const onPostSeen = (post: AppBskyFeedDefs.PostView) => { if (seenPerPostUrisRef.current.has(post.uri)) return seenPerPostUrisRef.current.add(post.uri) // Standard site embed view tracking if ( - bsky.isType(app.bsky.embed.external.view, post.embed) && + bsky.isType(AppBskyEmbedExternal.view, post.embed) && isStandardSiteEmbed(post.embed.external) ) { ax.metric('embed:standardSite:view', {url: post.embed.external.uri}) @@ -1040,19 +1045,16 @@ let PostFeed = ({ // Photo embed impression tracking if ( - bsky.isType(app.bsky.embed.images.view, post.embed) || - bsky.isType(app.bsky.embed.gallery.view, post.embed) + bsky.isType(AppBskyEmbedImages.view, post.embed) || + bsky.isType(AppBskyEmbedGallery.view, post.embed) ) { - const totalImages = bsky.isType( - app.bsky.embed.gallery.view, - post.embed, - ) + const totalImages = bsky.isType(AppBskyEmbedGallery.view, post.embed) ? post.embed.items.filter(item => - bsky.isType(app.bsky.embed.gallery.viewImage, item), + bsky.isType(AppBskyEmbedGallery.viewImage, item), ).length : post.embed.images.length const useExpandedLayout = bsky.isType( - app.bsky.embed.gallery.view, + AppBskyEmbedGallery.view, post.embed, ) ? totalImages > 4 diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index c9ed6b603b..5682e54894 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -47,20 +47,23 @@ import {RichText} from '#/components/RichText' import {SubtleHover} from '#/components/SubtleHover' import {useAnalytics} from '#/analytics' import {useActorStatus} from '#/features/liveNow' -import {app} from '#/lexicons' +import type * as AppBskyActorDefs from '#/lexicons/app/bsky/actor/defs' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' +import * as AppBskyFeedPost from '#/lexicons/app/bsky/feed/post' +import * as AppBskyFeedThreadgate from '#/lexicons/app/bsky/feed/threadgate' import * as bsky from '#/types/bsky' import {PostFeedReason} from './PostFeedReason' interface FeedItemProps { - record: app.bsky.feed.post.Main + record: AppBskyFeedPost.Main reason: - | app.bsky.feed.defs.ReasonRepost - | app.bsky.feed.defs.ReasonPin + | AppBskyFeedDefs.ReasonRepost + | AppBskyFeedDefs.ReasonPin | ReasonFeedSource | {[k: string]: unknown; $type: string} | undefined moderation: ModerationDecision - parentAuthor: app.bsky.actor.defs.ProfileViewBasic | undefined + parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined showReplyTo: boolean isThreadChild?: boolean isThreadLastChild?: boolean @@ -90,9 +93,9 @@ export function PostFeedItem({ rootPost, onShowLess, }: FeedItemProps & { - post: app.bsky.feed.defs.PostView - rootPost: app.bsky.feed.defs.PostView - onShowLess?: (interaction: app.bsky.feed.defs.Interaction) => void + post: AppBskyFeedDefs.PostView + rootPost: AppBskyFeedDefs.PostView + onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void }): React.ReactNode { const postShadowed = usePostShadow(post) const richText = useMemo( @@ -154,9 +157,9 @@ let FeedItemInner = ({ onShowLess, }: FeedItemProps & { richText: RichTextAPI - post: Shadow - rootPost: app.bsky.feed.defs.PostView - onShowLess?: (interaction: app.bsky.feed.defs.Interaction) => void + post: Shadow + rootPost: AppBskyFeedDefs.PostView + onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void }): React.ReactNode => { const ax = useAnalytics() const queryClient = useQueryClient() @@ -257,8 +260,8 @@ let FeedItemInner = ({ * schema's input type, whose `$type` is optional, so the `$Typed` arm * of `FeedViewPost['reason']` needs the assertion back. */ - reason: bsky.isType(app.bsky.feed.defs.reasonRepost, reason) - ? (reason as app.bsky.feed.defs.FeedViewPost['reason']) + reason: bsky.isType(AppBskyFeedDefs.reasonRepost, reason) + ? (reason as AppBskyFeedDefs.FeedViewPost['reason']) : undefined, feedContext, reqId, @@ -284,7 +287,7 @@ let FeedItemInner = ({ * then we may have a threadgate record to reference */ const threadgateRecord = bsky.isType( - app.bsky.feed.threadgate, + AppBskyFeedThreadgate, rootPost.threadgate?.record, ) ? rootPost.threadgate.record @@ -294,7 +297,7 @@ let FeedItemInner = ({ const viaRepost = useMemo(() => { if ( - bsky.isType(app.bsky.feed.defs.reasonRepost, reason) && + bsky.isType(AppBskyFeedDefs.reasonRepost, reason) && reason.uri && reason.cid ) { @@ -310,7 +313,7 @@ let FeedItemInner = ({ }) const additionalPostAlerts: AppModerationCause[] = useMemo(() => { const isPostHiddenByThreadgate = threadgateHiddenReplies.has(post.uri) - const rootPostUri = bsky.isType(app.bsky.feed.post, post.record) + const rootPostUri = bsky.isType(AppBskyFeedPost, post.record) ? post.record?.reply?.root?.uri || post.uri : undefined const isControlledByViewer = @@ -467,10 +470,10 @@ let PostContent = ({ }: { moderation: ModerationDecision richText: RichTextAPI - postEmbed: app.bsky.feed.defs.PostView['embed'] - postAuthor: app.bsky.feed.defs.PostView['author'] + postEmbed: AppBskyFeedDefs.PostView['embed'] + postAuthor: AppBskyFeedDefs.PostView['author'] onOpenEmbed: () => void - post: app.bsky.feed.defs.PostView + post: AppBskyFeedDefs.PostView additionalPostAlerts?: AppModerationCause[] feedDescriptor?: string }): React.ReactNode => { @@ -478,9 +481,9 @@ let PostContent = ({ () => countLines(richText.text) >= MAX_POST_LINES, ) - const record = useMemo( + const record = useMemo( () => - bsky.matches(app.bsky.feed.post, post.record) ? post.record : undefined, + bsky.matches(AppBskyFeedPost, post.record) ? post.record : undefined, [post], ) diff --git a/src/view/com/posts/PostFeedReason.tsx b/src/view/com/posts/PostFeedReason.tsx index 54fdbfe465..ddb1d4c171 100644 --- a/src/view/com/posts/PostFeedReason.tsx +++ b/src/view/com/posts/PostFeedReason.tsx @@ -14,7 +14,7 @@ import {Repost_Stroke2_Corner3_Rounded as RepostIcon} from '#/components/icons/R import {Link} from '#/components/Link' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {Text} from '#/components/Typography' -import {app} from '#/lexicons' +import * as AppBskyFeedDefs from '#/lexicons/app/bsky/feed/defs' import * as bsky from '#/types/bsky' import {FeedNameText} from '../util/FeedInfoText' @@ -25,8 +25,8 @@ export function PostFeedReason({ }: { reason: | ReasonFeedSource - | app.bsky.feed.defs.ReasonRepost - | app.bsky.feed.defs.ReasonPin + | AppBskyFeedDefs.ReasonRepost + | AppBskyFeedDefs.ReasonPin | {[k: string]: unknown; $type: string} moderation?: ModerationDecision onOpenReposter?: () => void @@ -65,7 +65,7 @@ export function PostFeedReason({ ) } - if (bsky.isType(app.bsky.feed.defs.reasonRepost, reason)) { + if (bsky.isType(AppBskyFeedDefs.reasonRepost, reason)) { const isOwner = reason.by.did === currentAccount?.did const reposter = createSanitizedDisplayName( reason.by, @@ -104,7 +104,7 @@ export function PostFeedReason({ ) } - if (bsky.isType(app.bsky.feed.defs.reasonPin, reason)) { + if (bsky.isType(AppBskyFeedDefs.reasonPin, reason)) { return (