rework imports

This commit is contained in:
Oleksii Bulenok
2026-08-20 15:49:04 +02:00
parent 39e487cbb7
commit cb3245e8e8
245 changed files with 2453 additions and 2256 deletions
+4 -4
View File
@@ -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,
}),
],
+20 -20
View File
@@ -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<app.bsky.ageassurance.getConfig.$OutputBody>(
AppBskyAgeassuranceGetConfig.$OutputBody | undefined {
return qc.getQueryData<AppBskyAgeassuranceGetConfig.$OutputBody>(
configQueryKey,
)
}
@@ -128,7 +131,7 @@ export function prefetchConfig() {
try {
logger.debug(`prefetchAgeAssuranceConfig: resolving...`)
const res = await networkRetry(3, () => getConfig())
qc.setQueryData<app.bsky.ageassurance.getConfig.$OutputBody>(
qc.setQueryData<AppBskyAgeassuranceGetConfig.$OutputBody>(
configQueryKey,
res,
)
@@ -144,10 +147,7 @@ export function prefetchConfig() {
export async function refetchConfig() {
logger.debug(`refetchConfig: fetching...`)
const res = await getConfig()
qc.setQueryData<app.bsky.ageassurance.getConfig.$OutputBody>(
configQueryKey,
res,
)
qc.setQueryData<AppBskyAgeassuranceGetConfig.$OutputBody>(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<app.bsky.ageassurance.getState.$OutputBody>(
}): AppBskyAgeassuranceGetState.$OutputBody | undefined {
return qc.getQueryData<AppBskyAgeassuranceGetState.$OutputBody>(
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<app.bsky.ageassurance.getState.$OutputBody>(qk, res)
qc.setQueryData<AppBskyAgeassuranceGetState.$OutputBody>(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<app.bsky.ageassurance.getState.$OutputBody>(
qc.setQueryData<AppBskyAgeassuranceGetState.$OutputBody>(
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<app.bsky.ageassurance.getState.$OutputBody>(
qc.setQueryData<AppBskyAgeassuranceGetState.$OutputBody>(
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,
+48 -47
View File
@@ -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',
}),
],
+5 -4
View File
@@ -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,
+13 -13
View File
@@ -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 {
@@ -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,
})
+8 -6
View File
@@ -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<ViewStyle>
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 (
<Embed
embed={e.media.view as app.bsky.feed.defs.PostView['embed']}
embed={e.media.view as AppBskyFeedDefs.PostView['embed']}
style={style}
/>
)
@@ -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()
+4 -3
View File
@@ -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,
+4 -3
View File
@@ -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<app.bsky.feed.defs.PostView>>(
const quote = useMemo<$Typed<AppBskyFeedDefs.PostView>>(
() => ({
...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})
+5 -6
View File
@@ -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<TextStyle>
}) {
const langPrefs = useLanguagePrefs()
@@ -46,10 +47,8 @@ export function TranslatedPost({
key: post.uri,
})
const record = useMemo<app.bsky.feed.post.Main | undefined>(() => {
return bsky.isType(app.bsky.feed.post, post.record)
? post.record
: undefined
const record = useMemo<AppBskyFeedPost.Main | undefined>(() => {
return bsky.isType(AppBskyFeedPost, post.record) ? post.record : undefined
}, [post])
const initialTranslationParams = useMemo<TranslationFunctionParams>(() => {
return {
+4 -4
View File
@@ -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({
</InlineLinkText>
</ProfileHoverCard>,
)
} 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(
<RichTextTag
+4 -3
View File
@@ -11,7 +11,8 @@ import {atoms as a, useTheme} from '#/alf'
import {LinearGradientBackground} from '#/components/LinearGradientBackground'
import {Text} from '#/components/Typography'
import {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'
const LazyViewShot = lazy(() => 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<ViewShotRef>
}) {
const {record} = starterPack
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
if (!bsky.isType(AppBskyGraphStarterpack, record)) {
return null
}
+4 -3
View File
@@ -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
}
@@ -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
}
+10 -7
View File
@@ -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<typeof useTheme>) {
@@ -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
+9 -7
View File
@@ -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<ViewStyle>
}
@@ -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 <Trans>mentioned users</Trans>
@@ -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<app.bsky.notification.defs.ActivitySubscription>,
activitySubscription: Un$Typed<AppBskyNotificationDefs.ActivitySubscription>,
) => {
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<app.bsky.notification.listActivitySubscriptions.$OutputBody>,
old?: InfiniteData<AppBskyNotificationListActivitySubscriptions.$OutputBody>,
) => {
if (!old) return old
return {
@@ -305,8 +307,8 @@ function DialogInner({
}
function parseActivitySubscription(
sub?: app.bsky.notification.defs.ActivitySubscription,
): Un$Typed<app.bsky.notification.defs.ActivitySubscription> {
sub?: AppBskyNotificationDefs.ActivitySubscription,
): Un$Typed<AppBskyNotificationDefs.ActivitySubscription> {
if (!sub) return {post: false, reply: false}
const {post, reply} = sub
return {post, reply}
@@ -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,
@@ -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.`,
@@ -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<app.bsky.actor.profile.Main> = existing ?? {}
let next: Un$Typed<AppBskyActorProfile.Main> = existing ?? {}
if (blobPromise) {
const res = await blobPromise
@@ -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
@@ -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,
@@ -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,
})
},
@@ -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(),
})
@@ -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,
@@ -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)
},
})
}
@@ -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)
},
})
}
@@ -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,
})
+4 -3
View File
@@ -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
}
@@ -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<com.atproto.repo.applyWrites.Create>[] =
const listitemWrites: $Typed<ComAtprotoRepoApplyWrites.Create>[] =
items.map(item => {
const listitemRecord: $Typed<app.bsky.graph.listitem.Main> = {
const listitemRecord: $Typed<AppBskyGraphListitem.Main> = {
$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,
}),
+2 -3
View File
@@ -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, '@')
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+38 -46
View File
@@ -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<string, chat.bsky.actor.defs.ProfileViewBasic>
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
}): 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) && (
<MessageItemEmbed
embed={message.embed}
isFromSelf={isFromSelf}
@@ -536,10 +531,7 @@ let MessageItem = ({
highlightSV={highlightSV}
/>
)}
{bsky.isType(
chat.bsky.embed.joinLink.view,
message.embed,
) && (
{bsky.isType(ChatBskyEmbedJoinLink.view, message.embed) && (
<MessageItemInviteEmbed
embed={message.embed}
isFromSelf={isFromSelf}
@@ -677,7 +669,7 @@ function BlockedPlaceholder({
profile,
style,
}: {
profile: Shadow<chat.bsky.actor.defs.ProfileViewBasic>
profile: Shadow<ChatBskyActorDefs.ProfileViewBasic>
style?: AnimatedStyle<ViewStyle>
}) {
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<string, chat.bsky.actor.defs.ProfileViewBasic>
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
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<string, chat.bsky.actor.defs.ProfileViewBasic>
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
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)`,
+4 -3
View File
@@ -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
@@ -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
+12 -9
View File
@@ -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)
+3 -6
View File
@@ -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
}
+19 -27
View File
@@ -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<string, chat.bsky.actor.defs.ProfileViewBasic>,
user: ChatBskyConvoDefs.SystemMessageReferredUser,
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
): Extract<SystemMessageAction, {kind: 'profile'}> | 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<string, chat.bsky.actor.defs.ProfileViewBasic>,
data: ChatBskyConvoDefs.SystemMessageView['data'],
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
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,
+15 -13
View File
@@ -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,
)
) {
+19 -18
View File
@@ -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<string, chat.bsky.actor.defs.ProfileViewBasic>,
): chat.bsky.convo.defs.ReactionView[] {
reactions: ChatBskyConvoDefs.ReactionView[] | undefined,
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
): 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<chat.bsky.actor.defs.GroupConvoMember>
kind?: $Typed<ChatBskyActorDefs.GroupConvoMember>
}
export type DirectConvoMember = chat.bsky.actor.defs.ProfileViewBasic & {
kind: $Typed<chat.bsky.actor.defs.DirectConvoMember>
export type DirectConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
kind: $Typed<ChatBskyActorDefs.DirectConvoMember>
}
export type ConvoWithDetails = {view: chat.bsky.convo.defs.ConvoView} & (
export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & (
| {
kind: 'group'
details: $Typed<chat.bsky.convo.defs.GroupConvo>
details: $Typed<ChatBskyConvoDefs.GroupConvo>
primaryMember?: GroupConvoMember // the owner - may have left, thus optional
members: Array<GroupConvoMember>
}
| {
kind: 'direct'
details: $Typed<chat.bsky.convo.defs.DirectConvo>
details: $Typed<ChatBskyConvoDefs.DirectConvo>
primaryMember: DirectConvoMember // the other user
members: Array<DirectConvoMember>
}
@@ -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<GroupConvoMember>,
}
} 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
@@ -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,
@@ -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
@@ -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 (
<>
<View style={[a.py_lg, a.align_center]}>
@@ -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')
}
@@ -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])
+6 -4
View File
@@ -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
+7 -5
View File
@@ -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
@@ -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`,
})
}
+114 -116
View File
@@ -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<string, string> = {}
* @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<ComAtprotoModerationDefs.ReasonType, ToolsOzoneReportDefs.ReasonType>,
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<tools.ozone.report.defs.ReasonType> =
export const OTHER_REPORT_REASONS: Set<ToolsOzoneReportDefs.ReasonType> =
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<tools.ozone.report.defs.ReasonType> =
export const BSKY_LABELER_ONLY_REPORT_REASONS: Set<ToolsOzoneReportDefs.ReasonType> =
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,
])
/**
@@ -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}},
)
@@ -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) {
@@ -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,
@@ -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,
@@ -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,
},
],
},
@@ -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
+18 -14
View File
@@ -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<app.bsky.embed.external.View>, // temp_isStatusValid asserts this
embed: shadowed.status.embed as $Typed<AppBskyEmbedExternal.View>, // 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<app.bsky.embed.external.View>, // temp_isStatusValid asserts this
embed: shadowed.status.embed as $Typed<AppBskyEmbedExternal.View>, // 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<app.bsky.embed.external.Main> | undefined
let embed: $Typed<AppBskyEmbedExternal.Main> | 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',
})
+5 -4
View File
@@ -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
}
+4 -3
View File
@@ -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
+42 -41
View File
@@ -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)
+12 -14
View File
@@ -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<app.bsky.feed.defs.FeedViewPost> {
const data = await this.client.call(app.bsky.feed.getAuthorFeed, {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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
+11 -12
View File
@@ -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<typeof app.bsky.feed.getFeed.main>
type GetCustomFeedParams = XrpcRequestParams<typeof AppBskyFeedGetFeed.main>
export class CustomFeedAPI implements FeedAPI {
client: Client
@@ -35,10 +36,10 @@ export class CustomFeedAPI implements FeedAPI {
this.userInterests = userInterests
}
async peekLatest(): Promise<app.bsky.feed.defs.FeedViewPost> {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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<app.bsky.feed.getFeed.$OutputBody | null> {
): Promise<AppBskyFeedGetFeed.$OutputBody | null> {
const contentLangs = getAppLanguageAsContentLanguage()
let data = await getFeedOrNull(params, contentLangs)
@@ -172,13 +173,11 @@ async function loggedOutFetch(
async function getFeedOrNull(
params: GetCustomFeedParams,
contentLangs: string,
): Promise<app.bsky.feed.getFeed.$OutputBody | null> {
): Promise<AppBskyFeedGetFeed.$OutputBody | null> {
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
+5 -4
View File
@@ -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<app.bsky.feed.defs.FeedViewPost> {
const data = await this.client.call(app.bsky.feed.getTimeline, {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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,
})
+6 -5
View File
@@ -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<app.bsky.feed.defs.FeedViewPost> {
const data = await this.client.call(app.bsky.feed.getActorLikes, {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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,
+6 -7
View File
@@ -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<typeof AppBskyFeedGetListFeed.main>
export class ListFeedAPI implements FeedAPI {
client: Client
@@ -22,8 +21,8 @@ export class ListFeedAPI implements FeedAPI {
this.params = feedParams
}
async peekLatest(): Promise<app.bsky.feed.defs.FeedViewPost> {
const data = await this.client.call(app.bsky.feed.getListFeed, {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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,
+12 -10
View File
@@ -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<app.bsky.feed.defs.FeedViewPost> {
const data = await this.client.call(app.bsky.feed.getTimeline, {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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<MergeFeedPage> {
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
+6 -5
View File
@@ -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<typeof app.bsky.feed.getPosts.main>
type GetPostsParams = XrpcRequestParams<typeof AppBskyFeedGetPosts.main>
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<app.bsky.feed.defs.FeedViewPost> {
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
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]}
+30 -21
View File
@@ -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']>
| app.bsky.feed.post.Main['reply']
| Promise<AppBskyFeedPost.Main['reply']>
| 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<com.atproto.label.defs.SelfLabels> | undefined
let labels: $Typed<ComAtprotoLabelDefs.SelfLabels> | 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<app.bsky.feed.post.Main['embed']> {
): Promise<AppBskyFeedPost.Main['embed']> {
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<app.bsky.embed.external.Main>
| $Typed<app.bsky.embed.images.Main>
| $Typed<app.bsky.embed.gallery.Main>
| $Typed<app.bsky.embed.video.Main>
| $Typed<AppBskyEmbedExternal.Main>
| $Typed<AppBskyEmbedImages.Main>
| $Typed<AppBskyEmbedGallery.Main>
| $Typed<AppBskyEmbedVideo.Main>
| 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<app.bsky.embed.gallery.Image>[] = await Promise.all(
const items: $Typed<AppBskyEmbedGallery.Image>[] = 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<com.atproto.repo.strongRef.Main> {
): Promise<ComAtprotoRepoStrongRef.Main> {
const resolvedLink = await fetchResolveLinkQuery(queryClient, clients, uri)
if (resolvedLink.type !== 'record') {
throw Error(t`Expected uri to resolve to a record`)
+28 -22
View File
@@ -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
+19 -12
View File
@@ -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,
}),
)
+4 -3
View File
@@ -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)
+5 -4
View File
@@ -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
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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<M extends Procedure | Query>(
* 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:')
+6 -5
View File
@@ -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)
+9 -8
View File
@@ -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<CommonNavigatorParams, 'Bookmarks'>
@@ -76,15 +77,15 @@ type ListItem =
| {
type: 'bookmark'
key: string
bookmark: Omit<app.bsky.bookmark.defs.BookmarkView, 'item'> & {
item: $Typed<app.bsky.feed.defs.PostView>
bookmark: Omit<AppBskyBookmarkDefs.BookmarkView, 'item'> & {
item: $Typed<AppBskyFeedDefs.PostView>
}
}
| {
type: 'bookmarkNotFound'
key: string
bookmark: Omit<app.bsky.bookmark.defs.BookmarkView, 'item'> & {
item: $Typed<app.bsky.feed.defs.NotFoundPost>
bookmark: Omit<AppBskyBookmarkDefs.BookmarkView, 'item'> & {
item: $Typed<AppBskyFeedDefs.NotFoundPost>
}
}
@@ -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<app.bsky.feed.defs.NotFoundPost>
post: $Typed<AppBskyFeedDefs.NotFoundPost>
}) {
const t = useTheme()
const {_} = useLingui()
+2 -2
View File
@@ -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])
+2 -2
View File
@@ -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) {
+3 -3
View File
@@ -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()
+4 -3
View File
@@ -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})
+2 -2
View File
@@ -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,
})
+2 -2
View File
@@ -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)
@@ -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`, {
+8 -8
View File
@@ -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<CommonNavigatorParams, 'MessagesInbox'>
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<chat.bsky.convo.listConvoRequests.$OutputBody>,
InfiniteData<ChatBskyConvoListConvoRequests.$OutputBody>,
Error
>
conversations: RequestItem[]
+3 -3
View File
@@ -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,
)) ? (
<Wrapper>
@@ -106,7 +106,7 @@ export function JoinRequest({setScreenState}: Props) {
) : data &&
moderationOpts &&
bsky.isType(
chat.bsky.group.defs.joinLinkPreviewView,
ChatBskyGroupDefs.joinLinkPreviewView,
joinLinkPreview,
) ? (
<Wrapper>
+6 -4
View File
@@ -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<chat.bsky.group.listJoinRequests.$OutputBody>
InfiniteData<ChatBskyGroupListJoinRequests.$OutputBody>
>(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
@@ -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,
@@ -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,
@@ -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`, {
@@ -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,
@@ -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<chat.bsky.convo.defs.MessageView>,
reply?: $Typed<ChatBskyConvoDefs.MessageView>,
) => {
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<app.bsky.embed.record.View>
| $Typed<chat.bsky.embed.joinLink.View>
| $Typed<AppBskyEmbedRecord.View>
| $Typed<ChatBskyEmbedJoinLink.View>
| 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<chat.bsky.convo.defs.MessageView>,
replyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
) => Promise<void>
messageEmbed: MessageEmbedState | undefined
setEmbed: (embedUrl: string | undefined) => void
@@ -906,7 +910,7 @@ function Composer({
(
message: string,
embed?: MessageEmbedState,
replyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
replyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
) => {
void onSendMessage(message, embed, replyTo)
},
@@ -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.`
+11 -8
View File
@@ -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<app.bsky.actor.profile.Main> = existing ?? {}
let next: Un$Typed<AppBskyActorProfile.Main> = 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,
@@ -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
}
+10 -7
View File
@@ -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<app.bsky.graph.follow.Main>[] = dids.map(did => {
const followRecords: $Typed<AppBskyGraphFollow.Main>[] = 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<com.atproto.repo.applyWrites.Create>[] =
const followWrites: $Typed<ComAtprotoRepoApplyWrites.Create>[] =
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,
}),
@@ -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<ThreadItem, {type: 'threadPost'}>
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<ThreadItem, {type: 'threadPost'}>
isRoot: boolean
postShadow: Shadow<app.bsky.feed.defs.PostView>
postShadow: Shadow<AppBskyFeedDefs.PostView>
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
+10 -8
View File
@@ -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,
}),
)
@@ -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()
@@ -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)

Some files were not shown because too many files have changed in this diff Show More