about summary refs log tree commit diff
path: root/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/Messages/Conversation.tsx2
-rw-r--r--src/screens/Messages/components/ChatListItem.tsx4
-rw-r--r--src/screens/Messages/components/MessageInputEmbed.tsx7
-rw-r--r--src/screens/Messages/components/MessagesList.tsx9
-rw-r--r--src/screens/Onboarding/StepFinished.tsx31
-rw-r--r--src/screens/Onboarding/util.ts17
-rw-r--r--src/screens/Profile/KnownFollowers.tsx2
-rw-r--r--src/screens/Settings/components/PwiOptOut.tsx19
-rw-r--r--src/screens/Signup/index.tsx6
-rw-r--r--src/screens/StarterPack/StarterPackLandingScreen.tsx8
-rw-r--r--src/screens/StarterPack/StarterPackScreen.tsx8
-rw-r--r--src/screens/StarterPack/Wizard/State.tsx17
-rw-r--r--src/screens/StarterPack/Wizard/StepProfiles.tsx3
-rw-r--r--src/screens/StarterPack/Wizard/index.tsx9
-rw-r--r--src/screens/VideoFeed/index.tsx8
15 files changed, 101 insertions, 49 deletions
diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx
index f51822952..69af0ea58 100644
--- a/src/screens/Messages/Conversation.tsx
+++ b/src/screens/Messages/Conversation.tsx
@@ -165,7 +165,7 @@ function InnerReady({
   setHasScrolled,
 }: {
   moderation: ModerationDecision
-  recipient: Shadow<AppBskyActorDefs.ProfileViewBasic>
+  recipient: Shadow<AppBskyActorDefs.ProfileViewDetailed>
   hasScrolled: boolean
   setHasScrolled: React.Dispatch<React.SetStateAction<boolean>>
 }) {
diff --git a/src/screens/Messages/components/ChatListItem.tsx b/src/screens/Messages/components/ChatListItem.tsx
index ad97497f4..501ab2374 100644
--- a/src/screens/Messages/components/ChatListItem.tsx
+++ b/src/screens/Messages/components/ChatListItem.tsx
@@ -1,7 +1,6 @@
 import React, {useCallback, useMemo, useState} from 'react'
 import {GestureResponderEvent, View} from 'react-native'
 import {
-  AppBskyActorDefs,
   AppBskyEmbedRecord,
   ChatBskyConvoDefs,
   moderateProfile,
@@ -44,6 +43,7 @@ import {Link} from '#/components/Link'
 import {useMenuControl} from '#/components/Menu'
 import {PostAlerts} from '#/components/moderation/PostAlerts'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 export let ChatListItem = ({
   convo,
@@ -78,7 +78,7 @@ function ChatListItemReady({
   moderationOpts,
 }: {
   convo: ChatBskyConvoDefs.ConvoView
-  profile: AppBskyActorDefs.ProfileViewBasic
+  profile: bsky.profile.AnyProfileView
   moderationOpts: ModerationOpts
 }) {
   const t = useTheme()
diff --git a/src/screens/Messages/components/MessageInputEmbed.tsx b/src/screens/Messages/components/MessageInputEmbed.tsx
index 6df0ef2fc..d368f05b6 100644
--- a/src/screens/Messages/components/MessageInputEmbed.tsx
+++ b/src/screens/Messages/components/MessageInputEmbed.tsx
@@ -30,6 +30,7 @@ import {ContentHider} from '#/components/moderation/ContentHider'
 import {PostAlerts} from '#/components/moderation/PostAlerts'
 import {RichText} from '#/components/RichText'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 export function useMessageEmbed() {
   const route =
@@ -113,8 +114,10 @@ export function MessageInputEmbed({
   const {rt, record} = useMemo(() => {
     if (
       post &&
-      AppBskyFeedPost.isRecord(post.record) &&
-      AppBskyFeedPost.validateRecord(post.record).success
+      bsky.dangerousIsType<AppBskyFeedPost.Record>(
+        post.record,
+        AppBskyFeedPost.isRecord,
+      )
     ) {
       return {
         rt: new RichTextAPI({
diff --git a/src/screens/Messages/components/MessagesList.tsx b/src/screens/Messages/components/MessagesList.tsx
index 071ce1cd7..10a2b1d37 100644
--- a/src/screens/Messages/components/MessagesList.tsx
+++ b/src/screens/Messages/components/MessagesList.tsx
@@ -10,7 +10,12 @@ import Animated, {
 } from 'react-native-reanimated'
 import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes'
 import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {AppBskyEmbedRecord, AppBskyRichtextFacet, RichText} from '@atproto/api'
+import {
+  $Typed,
+  AppBskyEmbedRecord,
+  AppBskyRichtextFacet,
+  RichText,
+} from '@atproto/api'
 
 import {clamp} from '#/lib/numbers'
 import {ScrollProvider} from '#/lib/ScrollContext'
@@ -297,7 +302,7 @@ export function MessagesList({
       // we want to remove the post link from the text, re-trim, then detect facets
       rt.detectFacetsWithoutResolution()
 
-      let embed: AppBskyEmbedRecord.Main | undefined
+      let embed: $Typed<AppBskyEmbedRecord.Main> | undefined
 
       if (embedUri) {
         try {
diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx
index 33d27cf66..d0b0cacca 100644
--- a/src/screens/Onboarding/StepFinished.tsx
+++ b/src/screens/Onboarding/StepFinished.tsx
@@ -1,6 +1,11 @@
 import React from 'react'
 import {View} from 'react-native'
-import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
+import {
+  AppBskyActorProfile,
+  AppBskyGraphDefs,
+  AppBskyGraphStarterpack,
+  Un$Typed,
+} from '@atproto/api'
 import {SavedFeed} from '@atproto/api/dist/client/types/app/bsky/actor/defs'
 import {TID} from '@atproto/common-web'
 import {msg, Trans} from '@lingui/macro'
@@ -44,6 +49,7 @@ import {News2_Stroke2_Corner0_Rounded as News} from '#/components/icons/News2'
 import {Trending2_Stroke2_Corner2_Rounded as Trending} from '#/components/icons/Trending2'
 import {Loader} from '#/components/Loader'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 export function StepFinished() {
   const {_} = useLingui()
@@ -141,29 +147,29 @@ export function StepFinished() {
               : undefined
 
           await agent.upsertProfile(async existing => {
-            existing = existing ?? {}
+            let next: Un$Typed<AppBskyActorProfile.Record> = existing ?? {}
 
             if (blobPromise) {
               const res = await blobPromise
               if (res.data.blob) {
-                existing.avatar = res.data.blob
+                next.avatar = res.data.blob
               }
             }
 
             if (starterPack) {
-              existing.joinedViaStarterPack = {
+              next.joinedViaStarterPack = {
                 uri: starterPack.uri,
                 cid: starterPack.cid,
               }
             }
 
-            existing.displayName = ''
+            next.displayName = ''
             // HACKFIX
             // creating a bunch of identical profile objects is breaking the relay
             // tossing this unspecced field onto it to reduce the size of the problem
             // -prf
-            existing.createdAt = new Date().toISOString()
-            return existing
+            next.createdAt = new Date().toISOString()
+            return next
           })
 
           logEvent('onboarding:finished:avatarResult', {
@@ -205,9 +211,14 @@ export function StepFinished() {
     onboardDispatch({type: 'finish'})
     logEvent('onboarding:finished:nextPressed', {
       usedStarterPack: Boolean(starterPack),
-      starterPackName: AppBskyGraphStarterpack.isRecord(starterPack?.record)
-        ? starterPack.record.name
-        : undefined,
+      starterPackName:
+        starterPack &&
+        bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
+          starterPack.record,
+          AppBskyGraphStarterpack.isRecord,
+        )
+          ? starterPack.record.name
+          : undefined,
       starterPackCreator: starterPack?.creator.did,
       starterPackUri: starterPack?.uri,
       profilesFollowed: listItems?.length ?? 0,
diff --git a/src/screens/Onboarding/util.ts b/src/screens/Onboarding/util.ts
index 14750f34c..d14c9562e 100644
--- a/src/screens/Onboarding/util.ts
+++ b/src/screens/Onboarding/util.ts
@@ -1,7 +1,9 @@
 import {
+  $Typed,
   AppBskyGraphFollow,
   AppBskyGraphGetFollows,
   BskyAgent,
+  ComAtprotoRepoApplyWrites,
 } from '@atproto/api'
 import {TID} from '@atproto/common-web'
 import chunk from 'lodash.chunk'
@@ -15,7 +17,7 @@ export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) {
     throw new Error(`bulkWriteFollows failed: no session`)
   }
 
-  const followRecords: AppBskyGraphFollow.Record[] = dids.map(did => {
+  const followRecords: $Typed<AppBskyGraphFollow.Record>[] = dids.map(did => {
     return {
       $type: 'app.bsky.graph.follow',
       subject: did,
@@ -23,12 +25,13 @@ export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) {
     }
   })
 
-  const followWrites = followRecords.map(r => ({
-    $type: 'com.atproto.repo.applyWrites#create',
-    collection: 'app.bsky.graph.follow',
-    rkey: TID.nextStr(),
-    value: r,
-  }))
+  const followWrites: $Typed<ComAtprotoRepoApplyWrites.Create>[] =
+    followRecords.map(r => ({
+      $type: 'com.atproto.repo.applyWrites#create',
+      collection: 'app.bsky.graph.follow',
+      rkey: TID.nextStr(),
+      value: r,
+    }))
 
   const chunks = chunk(followWrites, 50)
   for (const chunk of chunks) {
diff --git a/src/screens/Profile/KnownFollowers.tsx b/src/screens/Profile/KnownFollowers.tsx
index d6dd15c69..6b22a0add 100644
--- a/src/screens/Profile/KnownFollowers.tsx
+++ b/src/screens/Profile/KnownFollowers.tsx
@@ -21,7 +21,7 @@ function renderItem({
   item,
   index,
 }: {
-  item: AppBskyActorDefs.ProfileViewBasic
+  item: AppBskyActorDefs.ProfileView
   index: number
 }) {
   return (
diff --git a/src/screens/Settings/components/PwiOptOut.tsx b/src/screens/Settings/components/PwiOptOut.tsx
index 4339ade9b..e58514976 100644
--- a/src/screens/Settings/components/PwiOptOut.tsx
+++ b/src/screens/Settings/components/PwiOptOut.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import {View} from 'react-native'
-import {ComAtprotoLabelDefs} from '@atproto/api'
+import {$Typed, ComAtprotoLabelDefs} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
@@ -12,6 +12,7 @@ import {useSession} from '#/state/session'
 import {atoms as a, useTheme} from '#/alf'
 import * as Toggle from '#/components/forms/Toggle'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 export function PwiOptOut() {
   const t = useTheme()
@@ -33,7 +34,10 @@ export function PwiOptOut() {
       profile,
       updates: existing => {
         // create labels attr if needed
-        existing.labels = ComAtprotoLabelDefs.isSelfLabels(existing.labels)
+        const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.validate(
+          existing.labels,
+          ComAtprotoLabelDefs.validateSelfLabels,
+        )
           ? existing.labels
           : {
               $type: 'com.atproto.label.defs#selfLabels',
@@ -41,23 +45,26 @@ export function PwiOptOut() {
             }
 
         // toggle the label
-        const hasLabel = existing.labels.values.some(
+        const hasLabel = labels.values.some(
           l => l.val === '!no-unauthenticated',
         )
         if (hasLabel) {
           wasAdded = false
-          existing.labels.values = existing.labels.values.filter(
+          labels.values = labels.values.filter(
             l => l.val !== '!no-unauthenticated',
           )
         } else {
           wasAdded = true
-          existing.labels.values.push({val: '!no-unauthenticated'})
+          labels.values.push({val: '!no-unauthenticated'})
         }
 
         // delete if no longer needed
-        if (existing.labels.values.length === 0) {
+        if (labels.values.length === 0) {
           delete existing.labels
+        } else {
+          existing.labels = labels
         }
+
         return existing
       },
       checkCommitted: res => {
diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx
index 5f406eb7a..e82d0da1c 100644
--- a/src/screens/Signup/index.tsx
+++ b/src/screens/Signup/index.tsx
@@ -26,6 +26,7 @@ import {Divider} from '#/components/Divider'
 import {LinearGradientBackground} from '#/components/LinearGradientBackground'
 import {InlineLinkText} from '#/components/Link'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 export function Signup({onPressBack}: {onPressBack: () => void}) {
   const {_} = useLingui()
@@ -95,7 +96,10 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
         scrollable>
         <View testID="createAccount" style={a.flex_1}>
           {showStarterPackCard &&
-          AppBskyGraphStarterpack.isRecord(starterPack.record) ? (
+          bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
+            starterPack.record,
+            AppBskyGraphStarterpack.isRecord,
+          ) ? (
             <Animated.View entering={!isFetchedAtMount ? FadeIn : undefined}>
               <LinearGradientBackground
                 style={[a.mx_lg, a.p_lg, a.gap_sm, a.rounded_sm]}>
diff --git a/src/screens/StarterPack/StarterPackLandingScreen.tsx b/src/screens/StarterPack/StarterPackLandingScreen.tsx
index ec31fc21d..2d9a91969 100644
--- a/src/screens/StarterPack/StarterPackLandingScreen.tsx
+++ b/src/screens/StarterPack/StarterPackLandingScreen.tsx
@@ -38,6 +38,7 @@ import {Default as ProfileCard} from '#/components/ProfileCard'
 import * as Prompt from '#/components/Prompt'
 import {RichText} from '#/components/RichText'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 const AnimatedPressable = Animated.createAnimatedComponent(Pressable)
 
@@ -85,7 +86,12 @@ export function LandingScreen({
   }
 
   // Just for types, this cannot be hit
-  if (!AppBskyGraphStarterpack.isRecord(starterPack.record)) {
+  if (
+    !bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
+      starterPack.record,
+      AppBskyGraphStarterpack.isRecord,
+    )
+  ) {
     return null
   }
 
diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx
index 3a3e4234f..ac61c153b 100644
--- a/src/screens/StarterPack/StarterPackScreen.tsx
+++ b/src/screens/StarterPack/StarterPackScreen.tsx
@@ -66,6 +66,7 @@ import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList'
 import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog'
 import {ShareDialog} from '#/components/StarterPack/ShareDialog'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 type StarterPackScreeProps = NativeStackScreenProps<
   CommonNavigatorParams,
@@ -387,7 +388,12 @@ function Header({
     })
   }
 
-  if (!AppBskyGraphStarterpack.isRecord(record)) {
+  if (
+    !bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
+      record,
+      AppBskyGraphStarterpack.isRecord,
+    )
+  ) {
     return null
   }
 
diff --git a/src/screens/StarterPack/Wizard/State.tsx b/src/screens/StarterPack/Wizard/State.tsx
index f65933fbb..baf0195d8 100644
--- a/src/screens/StarterPack/Wizard/State.tsx
+++ b/src/screens/StarterPack/Wizard/State.tsx
@@ -1,15 +1,12 @@
 import React from 'react'
-import {
-  AppBskyActorDefs,
-  AppBskyGraphDefs,
-  AppBskyGraphStarterpack,
-} from '@atproto/api'
+import {AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
 import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs'
 import {msg} from '@lingui/macro'
 
 import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
 import {useSession} from '#/state/session'
 import * as Toast from '#/view/com/util/Toast'
+import * as bsky from '#/types/bsky'
 
 const steps = ['Details', 'Profiles', 'Feeds'] as const
 type Step = (typeof steps)[number]
@@ -20,7 +17,7 @@ type Action =
   | {type: 'SetCanNext'; canNext: boolean}
   | {type: 'SetName'; name: string}
   | {type: 'SetDescription'; description: string}
-  | {type: 'AddProfile'; profile: AppBskyActorDefs.ProfileViewBasic}
+  | {type: 'AddProfile'; profile: bsky.profile.AnyProfileView}
   | {type: 'RemoveProfile'; profileDid: string}
   | {type: 'AddFeed'; feed: GeneratorView}
   | {type: 'RemoveFeed'; feedUri: string}
@@ -32,7 +29,7 @@ interface State {
   currentStep: Step
   name?: string
   description?: string
-  profiles: AppBskyActorDefs.ProfileViewBasic[]
+  profiles: bsky.profile.AnyProfileView[]
   feeds: GeneratorView[]
   processing: boolean
   error?: string
@@ -113,7 +110,6 @@ function reducer(state: State, action: Action): State {
   return updatedState
 }
 
-// TODO supply the initial state to this component
 export function Provider({
   starterPack,
   listItems,
@@ -126,7 +122,10 @@ export function Provider({
   const {currentAccount} = useSession()
 
   const createInitialState = (): State => {
-    if (starterPack && AppBskyGraphStarterpack.isRecord(starterPack.record)) {
+    if (
+      starterPack &&
+      bsky.validate(starterPack.record, AppBskyGraphStarterpack.validateRecord)
+    ) {
       return {
         canNext: true,
         currentStep: 'Details',
diff --git a/src/screens/StarterPack/Wizard/StepProfiles.tsx b/src/screens/StarterPack/Wizard/StepProfiles.tsx
index e13febc75..8a9a891e1 100644
--- a/src/screens/StarterPack/Wizard/StepProfiles.tsx
+++ b/src/screens/StarterPack/Wizard/StepProfiles.tsx
@@ -16,6 +16,7 @@ import {Loader} from '#/components/Loader'
 import {ScreenTransition} from '#/components/StarterPack/Wizard/ScreenTransition'
 import {WizardProfileCard} from '#/components/StarterPack/Wizard/WizardListCard'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 
 function keyExtractor(item: AppBskyActorDefs.ProfileViewBasic) {
   return item?.did ?? ''
@@ -50,7 +51,7 @@ export function StepProfiles({
 
   const renderItem = ({
     item,
-  }: ListRenderItemInfo<AppBskyActorDefs.ProfileViewBasic>) => {
+  }: ListRenderItemInfo<bsky.profile.AnyProfileView>) => {
     return (
       <WizardProfileCard
         profile={item}
diff --git a/src/screens/StarterPack/Wizard/index.tsx b/src/screens/StarterPack/Wizard/index.tsx
index 3f8ce3c00..92cad2f65 100644
--- a/src/screens/StarterPack/Wizard/index.tsx
+++ b/src/screens/StarterPack/Wizard/index.tsx
@@ -54,6 +54,7 @@ import {ListMaybePlaceholder} from '#/components/Lists'
 import {Loader} from '#/components/Loader'
 import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 import {Provider} from './State'
 
 export function Wizard({
@@ -141,7 +142,7 @@ function WizardInner({
 }: {
   currentStarterPack?: AppBskyGraphDefs.StarterPackView
   currentListItems?: AppBskyGraphDefs.ListItemView[]
-  profile: AppBskyActorDefs.ProfileViewBasic
+  profile: AppBskyActorDefs.ProfileViewDetailed
   moderationOpts: ModerationOpts
 }) {
   const navigation = useNavigation<NavigationProp>()
@@ -363,7 +364,7 @@ function Footer({
   onNext: () => void
   nextBtnText: string
   moderationOpts: ModerationOpts
-  profile: AppBskyActorDefs.ProfileViewBasic
+  profile: AppBskyActorDefs.ProfileViewDetailed
 }) {
   const {_} = useLingui()
   const t = useTheme()
@@ -577,10 +578,10 @@ function Footer({
   )
 }
 
-function getName(item: AppBskyActorDefs.ProfileViewBasic | GeneratorView) {
+function getName(item: bsky.profile.AnyProfileView | GeneratorView) {
   if (typeof item.displayName === 'string') {
     return enforceLen(sanitizeDisplayName(item.displayName), 28, true)
-  } else if (typeof item.handle === 'string') {
+  } else if ('handle' in item && typeof item.handle === 'string') {
     return enforceLen(sanitizeHandle(item.handle), 28, true)
   }
   return ''
diff --git a/src/screens/VideoFeed/index.tsx b/src/screens/VideoFeed/index.tsx
index 8198d45a3..04c2d7792 100644
--- a/src/screens/VideoFeed/index.tsx
+++ b/src/screens/VideoFeed/index.tsx
@@ -90,6 +90,7 @@ import {ListFooter} from '#/components/Lists'
 import * as Hider from '#/components/moderation/Hider'
 import {RichText} from '#/components/RichText'
 import {Text} from '#/components/Typography'
+import * as bsky from '#/types/bsky'
 import {Scrubber, VIDEO_PLAYER_BOTTOM_INSET} from './components/Scrubber'
 
 function createThreeVideoPlayers(
@@ -694,7 +695,12 @@ function Overlay({
   )
 
   const rkey = new AtUri(post.uri).rkey
-  const record = AppBskyFeedPost.isRecord(post.record) ? post.record : undefined
+  const record = bsky.dangerousIsType<AppBskyFeedPost.Record>(
+    post.record,
+    AppBskyFeedPost.isRecord,
+  )
+    ? post.record
+    : undefined
   const richText = new RichTextAPI({
     text: record?.text || '',
     facets: record?.facets,