about summary refs log tree commit diff
path: root/src/state/models
diff options
context:
space:
mode:
Diffstat (limited to 'src/state/models')
-rw-r--r--src/state/models/badges-view.ts49
-rw-r--r--src/state/models/feed-view.ts48
-rw-r--r--src/state/models/liked-by-view.ts6
-rw-r--r--src/state/models/me.ts12
-rw-r--r--src/state/models/notifications-view.ts37
-rw-r--r--src/state/models/post-thread-view.ts10
-rw-r--r--src/state/models/post.ts4
-rw-r--r--src/state/models/profile-ui.ts11
-rw-r--r--src/state/models/profile-view.ts14
-rw-r--r--src/state/models/reposted-by-view.ts6
-rw-r--r--src/state/models/root-store.ts18
-rw-r--r--src/state/models/session.ts104
-rw-r--r--src/state/models/shell.ts2
-rw-r--r--src/state/models/user-followers-view.ts21
-rw-r--r--src/state/models/user-follows-view.ts20
15 files changed, 164 insertions, 198 deletions
diff --git a/src/state/models/badges-view.ts b/src/state/models/badges-view.ts
deleted file mode 100644
index 644ec7d9e..000000000
--- a/src/state/models/badges-view.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {makeAutoObservable} from 'mobx'
-import {RootStoreModel} from './root-store'
-
-// TODO / DEBUG
-// this is a temporary fake for the model until the view actually gets implemented in the bsky api
-// -prf
-
-export class BadgesViewModel {
-  // state
-  isLoading = false
-  isRefreshing = false
-  hasLoaded = false
-  error = ''
-
-  constructor(public rootStore: RootStoreModel) {
-    makeAutoObservable(
-      this,
-      {
-        rootStore: false,
-      },
-      {autoBind: true},
-    )
-  }
-
-  get hasContent() {
-    return false
-  }
-
-  get hasError() {
-    return this.error !== ''
-  }
-
-  get isEmpty() {
-    return this.hasLoaded && !this.hasContent
-  }
-
-  // public api
-  // =
-
-  async setup() {
-    this.hasLoaded = true
-  }
-
-  async refresh() {}
-
-  async loadMore() {}
-
-  async update() {}
-}
diff --git a/src/state/models/feed-view.ts b/src/state/models/feed-view.ts
index 4b2fa9a58..9505ad556 100644
--- a/src/state/models/feed-view.ts
+++ b/src/state/models/feed-view.ts
@@ -1,6 +1,6 @@
 import {makeAutoObservable, runInAction} from 'mobx'
-import * as GetHomeFeed from '../../third-party/api/src/types/app/bsky/getHomeFeed'
-import * as GetAuthorFeed from '../../third-party/api/src/types/app/bsky/getAuthorFeed'
+import * as GetTimeline from '../../third-party/api/src/client/types/app/bsky/feed/getTimeline'
+import * as GetAuthorFeed from '../../third-party/api/src/client/types/app/bsky/feed/getAuthorFeed'
 import {RootStoreModel} from './root-store'
 import * as apilib from '../lib/api'
 
@@ -13,20 +13,20 @@ export class FeedItemMyStateModel {
   }
 }
 
-export class FeedItemModel implements GetHomeFeed.FeedItem {
+export class FeedItemModel implements GetTimeline.FeedItem {
   // ui state
   _reactKey: string = ''
 
   // data
   uri: string = ''
   cid: string = ''
-  author: GetHomeFeed.User = {did: '', name: '', displayName: ''}
-  repostedBy?: GetHomeFeed.User
+  author: GetTimeline.User = {did: '', handle: '', displayName: ''}
+  repostedBy?: GetTimeline.User
   record: Record<string, unknown> = {}
   embed?:
-    | GetHomeFeed.RecordEmbed
-    | GetHomeFeed.ExternalEmbed
-    | GetHomeFeed.UnknownEmbed
+    | GetTimeline.RecordEmbed
+    | GetTimeline.ExternalEmbed
+    | GetTimeline.UnknownEmbed
   replyCount: number = 0
   repostCount: number = 0
   likeCount: number = 0
@@ -36,14 +36,14 @@ export class FeedItemModel implements GetHomeFeed.FeedItem {
   constructor(
     public rootStore: RootStoreModel,
     reactKey: string,
-    v: GetHomeFeed.FeedItem | GetAuthorFeed.FeedItem,
+    v: GetTimeline.FeedItem | GetAuthorFeed.FeedItem,
   ) {
     makeAutoObservable(this, {rootStore: false})
     this._reactKey = reactKey
     this.copy(v)
   }
 
-  copy(v: GetHomeFeed.FeedItem | GetAuthorFeed.FeedItem) {
+  copy(v: GetTimeline.FeedItem | GetAuthorFeed.FeedItem) {
     this.uri = v.uri
     this.cid = v.cid
     this.author = v.author
@@ -100,7 +100,7 @@ export class FeedModel {
   hasLoaded = false
   hasReachedEnd = false
   error = ''
-  params: GetHomeFeed.QueryParams | GetAuthorFeed.QueryParams
+  params: GetTimeline.QueryParams | GetAuthorFeed.QueryParams
   loadMoreCursor: string | undefined
   _loadPromise: Promise<void> | undefined
   _loadMorePromise: Promise<void> | undefined
@@ -113,7 +113,7 @@ export class FeedModel {
   constructor(
     public rootStore: RootStoreModel,
     public feedType: 'home' | 'author',
-    params: GetHomeFeed.QueryParams | GetAuthorFeed.QueryParams,
+    params: GetTimeline.QueryParams | GetAuthorFeed.QueryParams,
   ) {
     makeAutoObservable(
       this,
@@ -286,7 +286,7 @@ export class FeedModel {
     let cursor = undefined
     try {
       do {
-        const res: GetHomeFeed.Response = await this._getFeed({
+        const res: GetTimeline.Response = await this._getFeed({
           before: cursor,
           limit: Math.min(numToFetch, 100),
         })
@@ -304,13 +304,13 @@ export class FeedModel {
     }
   }
 
-  private _replaceAll(res: GetHomeFeed.Response | GetAuthorFeed.Response) {
+  private _replaceAll(res: GetTimeline.Response | GetAuthorFeed.Response) {
     this.feed.length = 0
     this.hasReachedEnd = false
     this._appendAll(res)
   }
 
-  private _appendAll(res: GetHomeFeed.Response | GetAuthorFeed.Response) {
+  private _appendAll(res: GetTimeline.Response | GetAuthorFeed.Response) {
     this.loadMoreCursor = res.data.cursor
     let counter = this.feed.length
     for (const item of res.data.feed) {
@@ -320,13 +320,13 @@ export class FeedModel {
 
   private _append(
     keyId: number,
-    item: GetHomeFeed.FeedItem | GetAuthorFeed.FeedItem,
+    item: GetTimeline.FeedItem | GetAuthorFeed.FeedItem,
   ) {
     // TODO: validate .record
     this.feed.push(new FeedItemModel(this.rootStore, `item-${keyId}`, item))
   }
 
-  private _prependAll(res: GetHomeFeed.Response | GetAuthorFeed.Response) {
+  private _prependAll(res: GetTimeline.Response | GetAuthorFeed.Response) {
     let counter = this.feed.length
     for (const item of res.data.feed) {
       if (this.feed.find(item2 => item2.uri === item.uri)) {
@@ -338,13 +338,13 @@ export class FeedModel {
 
   private _prepend(
     keyId: number,
-    item: GetHomeFeed.FeedItem | GetAuthorFeed.FeedItem,
+    item: GetTimeline.FeedItem | GetAuthorFeed.FeedItem,
   ) {
     // TODO: validate .record
     this.feed.unshift(new FeedItemModel(this.rootStore, `item-${keyId}`, item))
   }
 
-  private _updateAll(res: GetHomeFeed.Response | GetAuthorFeed.Response) {
+  private _updateAll(res: GetTimeline.Response | GetAuthorFeed.Response) {
     for (const item of res.data.feed) {
       const existingItem = this.feed.find(
         // this find function has a key subtley- the indexedAt comparison
@@ -359,15 +359,15 @@ export class FeedModel {
   }
 
   protected _getFeed(
-    params: GetHomeFeed.QueryParams | GetAuthorFeed.QueryParams = {},
-  ): Promise<GetHomeFeed.Response | GetAuthorFeed.Response> {
+    params: GetTimeline.QueryParams | GetAuthorFeed.QueryParams = {},
+  ): Promise<GetTimeline.Response | GetAuthorFeed.Response> {
     params = Object.assign({}, this.params, params)
     if (this.feedType === 'home') {
-      return this.rootStore.api.app.bsky.getHomeFeed(
-        params as GetHomeFeed.QueryParams,
+      return this.rootStore.api.app.bsky.feed.getTimeline(
+        params as GetTimeline.QueryParams,
       )
     } else {
-      return this.rootStore.api.app.bsky.getAuthorFeed(
+      return this.rootStore.api.app.bsky.feed.getAuthorFeed(
         params as GetAuthorFeed.QueryParams,
       )
     }
diff --git a/src/state/models/liked-by-view.ts b/src/state/models/liked-by-view.ts
index c2256e955..facda9032 100644
--- a/src/state/models/liked-by-view.ts
+++ b/src/state/models/liked-by-view.ts
@@ -1,6 +1,6 @@
 import {makeAutoObservable, runInAction} from 'mobx'
 import {AtUri} from '../../third-party/uri'
-import * as GetLikedBy from '../../third-party/api/src/types/app/bsky/getLikedBy'
+import * as GetLikedBy from '../../third-party/api/src/client/types/app/bsky/feed/getLikedBy'
 import {RootStoreModel} from './root-store'
 
 type LikedByItem = GetLikedBy.OutputSchema['likedBy'][number]
@@ -11,7 +11,7 @@ export class LikedByViewItemModel implements LikedByItem {
 
   // data
   did: string = ''
-  name: string = ''
+  handle: string = ''
   displayName: string = ''
   createdAt?: string
   indexedAt: string = ''
@@ -113,7 +113,7 @@ export class LikedByViewModel {
   private async _fetch(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getLikedBy(
+      const res = await this.rootStore.api.app.bsky.feed.getLikedBy(
         Object.assign({}, this.params, {uri: this.resolvedUri}),
       )
       this._replaceAll(res)
diff --git a/src/state/models/me.ts b/src/state/models/me.ts
index 333cf5626..7a94d63ac 100644
--- a/src/state/models/me.ts
+++ b/src/state/models/me.ts
@@ -3,7 +3,7 @@ import {RootStoreModel} from './root-store'
 
 export class MeModel {
   did?: string
-  name?: string
+  handle?: string
   displayName?: string
   description?: string
   notificationCount: number = 0
@@ -14,7 +14,7 @@ export class MeModel {
 
   clear() {
     this.did = undefined
-    this.name = undefined
+    this.handle = undefined
     this.displayName = undefined
     this.description = undefined
     this.notificationCount = 0
@@ -23,9 +23,9 @@ export class MeModel {
   async load() {
     const sess = this.rootStore.session
     if (sess.isAuthed && sess.data) {
-      this.did = sess.data.userdid || ''
-      this.name = sess.data.username
-      const profile = await this.rootStore.api.app.bsky.getProfile({
+      this.did = sess.data.did || ''
+      this.handle = sess.data.handle
+      const profile = await this.rootStore.api.app.bsky.actor.getProfile({
         user: this.did,
       })
       runInAction(() => {
@@ -43,7 +43,7 @@ export class MeModel {
   }
 
   async fetchStateUpdate() {
-    const res = await this.rootStore.api.app.bsky.getNotificationCount({})
+    const res = await this.rootStore.api.app.bsky.notification.getCount()
     runInAction(() => {
       this.notificationCount = res.data.count
     })
diff --git a/src/state/models/notifications-view.ts b/src/state/models/notifications-view.ts
index 8dd1cdf1a..8d8eede05 100644
--- a/src/state/models/notifications-view.ts
+++ b/src/state/models/notifications-view.ts
@@ -1,10 +1,10 @@
 import {makeAutoObservable} from 'mobx'
-import * as GetNotifications from '../../third-party/api/src/types/app/bsky/getNotifications'
+import * as ListNotifications from '../../third-party/api/src/client/types/app/bsky/notification/list'
 import {RootStoreModel} from './root-store'
 import {hasProp} from '../lib/type-guards'
 
-export interface GroupedNotification extends GetNotifications.Notification {
-  additional?: GetNotifications.Notification[]
+export interface GroupedNotification extends ListNotifications.Notification {
+  additional?: ListNotifications.Notification[]
 }
 
 export class NotificationsViewItemModel implements GroupedNotification {
@@ -16,9 +16,9 @@ export class NotificationsViewItemModel implements GroupedNotification {
   cid: string = ''
   author: {
     did: string
-    name: string
+    handle: string
     displayName?: string
-  } = {did: '', name: ''}
+  } = {did: '', handle: ''}
   reason: string = ''
   reasonSubject?: string
   record: any = {}
@@ -93,7 +93,7 @@ export class NotificationsViewModel {
   isRefreshing = false
   hasLoaded = false
   error = ''
-  params: GetNotifications.QueryParams
+  params: ListNotifications.QueryParams
   loadMoreCursor?: string
   _loadPromise: Promise<void> | undefined
   _loadMorePromise: Promise<void> | undefined
@@ -104,7 +104,7 @@ export class NotificationsViewModel {
 
   constructor(
     public rootStore: RootStoreModel,
-    params: GetNotifications.QueryParams,
+    params: ListNotifications.QueryParams,
   ) {
     makeAutoObservable(
       this,
@@ -216,7 +216,7 @@ export class NotificationsViewModel {
   private async _initialLoad(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getNotifications(
+      const res = await this.rootStore.api.app.bsky.notification.list(
         this.params,
       )
       this._replaceAll(res)
@@ -232,7 +232,7 @@ export class NotificationsViewModel {
       const params = Object.assign({}, this.params, {
         before: this.loadMoreCursor,
       })
-      const res = await this.rootStore.api.app.bsky.getNotifications(params)
+      const res = await this.rootStore.api.app.bsky.notification.list(params)
       this._appendAll(res)
       this._xIdle()
     } catch (e: any) {
@@ -246,8 +246,8 @@ export class NotificationsViewModel {
     let cursor = undefined
     try {
       do {
-        const res: GetNotifications.Response =
-          await this.rootStore.api.app.bsky.getNotifications({
+        const res: ListNotifications.Response =
+          await this.rootStore.api.app.bsky.notification.list({
             before: cursor,
             limit: Math.min(numToFetch, 100),
           })
@@ -265,12 +265,12 @@ export class NotificationsViewModel {
     }
   }
 
-  private _replaceAll(res: GetNotifications.Response) {
+  private _replaceAll(res: ListNotifications.Response) {
     this.notifications.length = 0
     this._appendAll(res)
   }
 
-  private _appendAll(res: GetNotifications.Response) {
+  private _appendAll(res: ListNotifications.Response) {
     this.loadMoreCursor = res.data.cursor
     let counter = this.notifications.length
     for (const item of groupNotifications(res.data.notifications)) {
@@ -285,7 +285,7 @@ export class NotificationsViewModel {
     )
   }
 
-  private _updateAll(res: GetNotifications.Response) {
+  private _updateAll(res: ListNotifications.Response) {
     for (const item of res.data.notifications) {
       const existingItem = this.notifications.find(
         // this find function has a key subtlety- the indexedAt comparison
@@ -301,10 +301,9 @@ export class NotificationsViewModel {
 
   private async _updateReadState() {
     try {
-      await this.rootStore.api.app.bsky.postNotificationsSeen(
-        {},
-        {seenAt: new Date().toISOString()},
-      )
+      await this.rootStore.api.app.bsky.notification.updateSeen({
+        seenAt: new Date().toISOString(),
+      })
     } catch (e) {
       console.log('Failed to update notifications read state', e)
     }
@@ -312,7 +311,7 @@ export class NotificationsViewModel {
 }
 
 function groupNotifications(
-  items: GetNotifications.Notification[],
+  items: ListNotifications.Notification[],
 ): GroupedNotification[] {
   const items2: GroupedNotification[] = []
   for (const item of items) {
diff --git a/src/state/models/post-thread-view.ts b/src/state/models/post-thread-view.ts
index 72e9513a6..0fc0dadbb 100644
--- a/src/state/models/post-thread-view.ts
+++ b/src/state/models/post-thread-view.ts
@@ -1,5 +1,5 @@
 import {makeAutoObservable, runInAction} from 'mobx'
-import * as GetPostThread from '../../third-party/api/src/types/app/bsky/getPostThread'
+import * as GetPostThread from '../../third-party/api/src/client/types/app/bsky/feed/getPostThread'
 import {AtUri} from '../../third-party/uri'
 import _omit from 'lodash.omit'
 import {RootStoreModel} from './root-store'
@@ -30,7 +30,7 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
   // data
   uri: string = ''
   cid: string = ''
-  author: GetPostThread.User = {did: '', name: '', displayName: ''}
+  author: GetPostThread.User = {did: '', handle: '', displayName: ''}
   record: Record<string, unknown> = {}
   embed?:
     | GetPostThread.RecordEmbed
@@ -82,8 +82,8 @@ export class PostThreadViewPostModel implements GetPostThread.Post {
       }
       this.parent = parentModel
     }
-    if (v.parent?.author.name) {
-      this.replyingToAuthor = v.parent.author.name
+    if (v.parent?.author.handle) {
+      this.replyingToAuthor = v.parent.author.handle
     }
     // replies
     if (includeChildren && v.replies) {
@@ -239,7 +239,7 @@ export class PostThreadViewModel {
   private async _load(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getPostThread(
+      const res = await this.rootStore.api.app.bsky.feed.getPostThread(
         Object.assign({}, this.params, {uri: this.resolvedUri}),
       )
       this._replaceAll(res)
diff --git a/src/state/models/post.ts b/src/state/models/post.ts
index 12a554f5c..7ecd62287 100644
--- a/src/state/models/post.ts
+++ b/src/state/models/post.ts
@@ -1,5 +1,5 @@
 import {makeAutoObservable} from 'mobx'
-import * as Post from '../../third-party/api/src/types/app/bsky/post'
+import * as Post from '../../third-party/api/src/client/types/app/bsky/feed/post'
 import {AtUri} from '../../third-party/uri'
 import {RootStoreModel} from './root-store'
 
@@ -77,7 +77,7 @@ export class PostModel implements RemoveIndex<Post.Record> {
     this._xLoading()
     try {
       const urip = new AtUri(this.uri)
-      const res = await this.rootStore.api.app.bsky.post.get({
+      const res = await this.rootStore.api.app.bsky.feed.post.get({
         user: urip.host,
         rkey: urip.rkey,
       })
diff --git a/src/state/models/profile-ui.ts b/src/state/models/profile-ui.ts
index cd29c35d2..830dc22b1 100644
--- a/src/state/models/profile-ui.ts
+++ b/src/state/models/profile-ui.ts
@@ -2,7 +2,6 @@ import {makeAutoObservable} from 'mobx'
 import {RootStoreModel} from './root-store'
 import {ProfileViewModel} from './profile-view'
 import {FeedModel} from './feed-view'
-import {BadgesViewModel} from './badges-view'
 
 export const SECTION_IDS = {
   POSTS: 0,
@@ -20,7 +19,6 @@ export class ProfileUiModel {
   // data
   profile: ProfileViewModel
   feed: FeedModel
-  badges: BadgesViewModel
 
   // ui state
   selectedViewIndex = 0
@@ -42,16 +40,12 @@ export class ProfileUiModel {
       author: params.user,
       limit: 10,
     })
-    this.badges = new BadgesViewModel(rootStore)
   }
 
-  get currentView(): FeedModel | BadgesViewModel {
+  get currentView(): FeedModel {
     if (this.selectedViewIndex === SECTION_IDS.POSTS) {
       return this.feed
     }
-    if (this.selectedViewIndex === SECTION_IDS.BADGES) {
-      return this.badges
-    }
     throw new Error(`Invalid selector value: ${this.selectedViewIndex}`)
   }
 
@@ -79,9 +73,6 @@ export class ProfileUiModel {
       this.feed
         .setup()
         .catch(err => console.error('Failed to fetch feed', err)),
-      this.badges
-        .setup()
-        .catch(err => console.error('Failed to fetch badges', err)),
     ])
   }
 
diff --git a/src/state/models/profile-view.ts b/src/state/models/profile-view.ts
index 64c162478..ebb75bdb6 100644
--- a/src/state/models/profile-view.ts
+++ b/src/state/models/profile-view.ts
@@ -1,6 +1,6 @@
 import {makeAutoObservable, runInAction} from 'mobx'
-import * as GetProfile from '../../third-party/api/src/types/app/bsky/getProfile'
-import * as Profile from '../../third-party/api/src/types/app/bsky/profile'
+import * as GetProfile from '../../third-party/api/src/client/types/app/bsky/actor/getProfile'
+import * as Profile from '../../third-party/api/src/client/types/app/bsky/actor/profile'
 import {RootStoreModel} from './root-store'
 import * as apilib from '../lib/api'
 
@@ -22,13 +22,12 @@ export class ProfileViewModel {
 
   // data
   did: string = ''
-  name: string = ''
+  handle: string = ''
   displayName?: string
   description?: string
   followersCount: number = 0
   followsCount: number = 0
   postsCount: number = 0
-  pinnedBadges: GetProfile.Badge[] = []
   myState = new ProfileViewMyStateModel()
 
   constructor(
@@ -118,7 +117,9 @@ export class ProfileViewModel {
   private async _load(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getProfile(this.params)
+      const res = await this.rootStore.api.app.bsky.actor.getProfile(
+        this.params,
+      )
       this._replaceAll(res)
       this._xIdle()
     } catch (e: any) {
@@ -128,13 +129,12 @@ export class ProfileViewModel {
 
   private _replaceAll(res: GetProfile.Response) {
     this.did = res.data.did
-    this.name = res.data.name
+    this.handle = res.data.handle
     this.displayName = res.data.displayName
     this.description = res.data.description
     this.followersCount = res.data.followersCount
     this.followsCount = res.data.followsCount
     this.postsCount = res.data.postsCount
-    this.pinnedBadges = res.data.pinnedBadges
     if (res.data.myState) {
       Object.assign(this.myState, res.data.myState)
     }
diff --git a/src/state/models/reposted-by-view.ts b/src/state/models/reposted-by-view.ts
index 507a8bbba..2911ae7ef 100644
--- a/src/state/models/reposted-by-view.ts
+++ b/src/state/models/reposted-by-view.ts
@@ -1,6 +1,6 @@
 import {makeAutoObservable, runInAction} from 'mobx'
 import {AtUri} from '../../third-party/uri'
-import * as GetRepostedBy from '../../third-party/api/src/types/app/bsky/getRepostedBy'
+import * as GetRepostedBy from '../../third-party/api/src/client/types/app/bsky/feed/getRepostedBy'
 import {RootStoreModel} from './root-store'
 
 type RepostedByItem = GetRepostedBy.OutputSchema['repostedBy'][number]
@@ -11,7 +11,7 @@ export class RepostedByViewItemModel implements RepostedByItem {
 
   // data
   did: string = ''
-  name: string = ''
+  handle: string = ''
   displayName: string = ''
   createdAt?: string
   indexedAt: string = ''
@@ -113,7 +113,7 @@ export class RepostedByViewModel {
   private async _fetch(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getRepostedBy(
+      const res = await this.rootStore.api.app.bsky.feed.getRepostedBy(
         Object.assign({}, this.params, {uri: this.resolvedUri}),
       )
       this._replaceAll(res)
diff --git a/src/state/models/root-store.ts b/src/state/models/root-store.ts
index 949049a18..68b042d68 100644
--- a/src/state/models/root-store.ts
+++ b/src/state/models/root-store.ts
@@ -3,8 +3,8 @@
  */
 
 import {makeAutoObservable} from 'mobx'
-import AtpApi from '../../third-party/api'
-import type {ServiceClient} from '../../third-party/api/src/index'
+import {sessionClient as AtpApi} from '../../third-party/api'
+import type {SessionServiceClient} from '../../third-party/api/src/index'
 import {createContext, useContext} from 'react'
 import {isObj, hasProp} from '../lib/type-guards'
 import {SessionModel} from './session'
@@ -18,7 +18,7 @@ export class RootStoreModel {
   shell = new ShellModel()
   me = new MeModel(this)
 
-  constructor(public api: ServiceClient) {
+  constructor(public api: SessionServiceClient) {
     makeAutoObservable(this, {
       api: false,
       resolveName: false,
@@ -27,14 +27,14 @@ export class RootStoreModel {
     })
   }
 
-  async resolveName(didOrName: string) {
-    if (!didOrName) {
-      throw new Error('Invalid name: ""')
+  async resolveName(didOrHandle: string) {
+    if (!didOrHandle) {
+      throw new Error('Invalid handle: ""')
     }
-    if (didOrName.startsWith('did:')) {
-      return didOrName
+    if (didOrHandle.startsWith('did:')) {
+      return didOrHandle
     }
-    const res = await this.api.com.atproto.resolveName({name: didOrName})
+    const res = await this.api.com.atproto.handle.resolve({handle: didOrHandle})
     return res.data.did
   }
 
diff --git a/src/state/models/session.ts b/src/state/models/session.ts
index 6be43e6fe..e29960954 100644
--- a/src/state/models/session.ts
+++ b/src/state/models/session.ts
@@ -1,6 +1,7 @@
 import {makeAutoObservable} from 'mobx'
-import AtpApi from '../../third-party/api'
-import type * as GetAccountsConfig from '../../third-party/api/src/types/com/atproto/getAccountsConfig'
+import {sessionClient as AtpApi} from '../../third-party/api/index'
+import type {SessionServiceClient} from '../../third-party/api/src/index'
+import type * as GetAccountsConfig from '../../third-party/api/src/client/types/com/atproto/server/getAccountsConfig'
 import {isObj, hasProp} from '../lib/type-guards'
 import {RootStoreModel} from './root-store'
 
@@ -8,9 +9,10 @@ export type ServiceDescription = GetAccountsConfig.OutputSchema
 
 interface SessionData {
   service: string
-  token: string
-  username: string
-  userdid: string
+  refreshJwt: string
+  accessJwt: string
+  handle: string
+  did: string
 }
 
 export enum OnboardingStage {
@@ -49,26 +51,39 @@ export class SessionModel {
       if (hasProp(v, 'data') && isObj(v.data)) {
         const data: SessionData = {
           service: '',
-          token: '',
-          username: '',
-          userdid: '',
+          refreshJwt: '',
+          accessJwt: '',
+          handle: '',
+          did: '',
         }
         if (hasProp(v.data, 'service') && typeof v.data.service === 'string') {
           data.service = v.data.service
         }
-        if (hasProp(v.data, 'token') && typeof v.data.token === 'string') {
-          data.token = v.data.token
+        if (
+          hasProp(v.data, 'refreshJwt') &&
+          typeof v.data.refreshJwt === 'string'
+        ) {
+          data.refreshJwt = v.data.refreshJwt
         }
         if (
-          hasProp(v.data, 'username') &&
-          typeof v.data.username === 'string'
+          hasProp(v.data, 'accessJwt') &&
+          typeof v.data.accessJwt === 'string'
         ) {
-          data.username = v.data.username
+          data.accessJwt = v.data.accessJwt
         }
-        if (hasProp(v.data, 'userdid') && typeof v.data.userdid === 'string') {
-          data.userdid = v.data.userdid
+        if (hasProp(v.data, 'handle') && typeof v.data.handle === 'string') {
+          data.handle = v.data.handle
         }
-        if (data.service && data.token && data.username && data.userdid) {
+        if (hasProp(v.data, 'did') && typeof v.data.did === 'string') {
+          data.did = v.data.did
+        }
+        if (
+          data.service &&
+          data.refreshJwt &&
+          data.accessJwt &&
+          data.handle &&
+          data.did
+        ) {
           this.data = data
         }
       }
@@ -112,7 +127,10 @@ export class SessionModel {
       return false
     }
 
-    this.rootStore.api.setHeader('Authorization', `Bearer ${this.data.token}`)
+    this.rootStore.api.sessionManager.set({
+      refreshJwt: this.data.refreshJwt,
+      accessJwt: this.data.accessJwt,
+    })
     return true
   }
 
@@ -122,8 +140,8 @@ export class SessionModel {
     }
 
     try {
-      const sess = await this.rootStore.api.com.atproto.getSession({})
-      if (sess.success && this.data && this.data.userdid === sess.data.did) {
+      const sess = await this.rootStore.api.com.atproto.session.get()
+      if (sess.success && this.data && this.data.did === sess.data.did) {
         this.rootStore.me.load().catch(e => {
           console.error('Failed to fetch local user information', e)
         })
@@ -135,28 +153,29 @@ export class SessionModel {
   }
 
   async describeService(service: string): Promise<ServiceDescription> {
-    const api = AtpApi.service(service)
-    const res = await api.com.atproto.getAccountsConfig({})
+    const api = AtpApi.service(service) as SessionServiceClient
+    const res = await api.com.atproto.server.getAccountsConfig({})
     return res.data
   }
 
   async login({
     service,
-    username,
+    handle,
     password,
   }: {
     service: string
-    username: string
+    handle: string
     password: string
   }) {
-    const api = AtpApi.service(service)
-    const res = await api.com.atproto.createSession({}, {username, password})
-    if (res.data.jwt) {
+    const api = AtpApi.service(service) as SessionServiceClient
+    const res = await api.com.atproto.session.create({handle, password})
+    if (res.data.accessJwt && res.data.refreshJwt) {
       this.setState({
         service: service,
-        token: res.data.jwt,
-        username: res.data.name,
-        userdid: res.data.did,
+        accessJwt: res.data.accessJwt,
+        refreshJwt: res.data.refreshJwt,
+        handle: res.data.handle,
+        did: res.data.did,
       })
       this.configureApi()
       this.rootStore.me.load().catch(e => {
@@ -169,26 +188,29 @@ export class SessionModel {
     service,
     email,
     password,
-    username,
+    handle,
     inviteCode,
   }: {
     service: string
     email: string
     password: string
-    username: string
+    handle: string
     inviteCode?: string
   }) {
-    const api = AtpApi.service(service)
-    const res = await api.com.atproto.createAccount(
-      {},
-      {username, password, email, inviteCode},
-    )
-    if (res.data.jwt) {
+    const api = AtpApi.service(service) as SessionServiceClient
+    const res = await api.com.atproto.account.create({
+      handle,
+      password,
+      email,
+      inviteCode,
+    })
+    if (res.data.accessJwt && res.data.refreshJwt) {
       this.setState({
         service: service,
-        token: res.data.jwt,
-        username: res.data.name,
-        userdid: res.data.did,
+        accessJwt: res.data.accessJwt,
+        refreshJwt: res.data.refreshJwt,
+        handle: res.data.handle,
+        did: res.data.did,
       })
       this.setOnboardingStage(OnboardingStage.Init)
       this.configureApi()
@@ -200,7 +222,7 @@ export class SessionModel {
 
   async logout() {
     if (this.isAuthed) {
-      this.rootStore.api.com.atproto.deleteSession({}).catch((e: any) => {
+      this.rootStore.api.com.atproto.session.delete().catch((e: any) => {
         console.error('(Minor issue) Failed to delete session on the server', e)
       })
     }
diff --git a/src/state/models/shell.ts b/src/state/models/shell.ts
index 33b8eef36..bef6ef765 100644
--- a/src/state/models/shell.ts
+++ b/src/state/models/shell.ts
@@ -1,6 +1,6 @@
 import {makeAutoObservable} from 'mobx'
 import {ProfileViewModel} from './profile-view'
-import * as Post from '../../third-party/api/src/types/app/bsky/post'
+import * as Post from '../../third-party/api/src/client/types/app/bsky/feed/post'
 
 export interface LinkActionsModelOpts {
   newTab?: boolean
diff --git a/src/state/models/user-followers-view.ts b/src/state/models/user-followers-view.ts
index 9ec5a42a6..1edd95232 100644
--- a/src/state/models/user-followers-view.ts
+++ b/src/state/models/user-followers-view.ts
@@ -1,10 +1,11 @@
 import {makeAutoObservable} from 'mobx'
-import * as GetUserFollowers from '../../third-party/api/src/types/app/bsky/getUserFollowers'
+import * as GetFollowers from '../../third-party/api/src/client/types/app/bsky/graph/getFollowers'
 import {RootStoreModel} from './root-store'
 
-type Subject = GetUserFollowers.OutputSchema['subject']
-export type FollowerItem =
-  GetUserFollowers.OutputSchema['followers'][number] & {_reactKey: string}
+type Subject = GetFollowers.OutputSchema['subject']
+export type FollowerItem = GetFollowers.OutputSchema['followers'][number] & {
+  _reactKey: string
+}
 
 export class UserFollowersViewModel {
   // state
@@ -12,15 +13,15 @@ export class UserFollowersViewModel {
   isRefreshing = false
   hasLoaded = false
   error = ''
-  params: GetUserFollowers.QueryParams
+  params: GetFollowers.QueryParams
 
   // data
-  subject: Subject = {did: '', name: '', displayName: ''}
+  subject: Subject = {did: '', handle: '', displayName: ''}
   followers: FollowerItem[] = []
 
   constructor(
     public rootStore: RootStoreModel,
-    params: GetUserFollowers.QueryParams,
+    params: GetFollowers.QueryParams,
   ) {
     makeAutoObservable(
       this,
@@ -82,7 +83,7 @@ export class UserFollowersViewModel {
   private async _fetch(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getUserFollowers(
+      const res = await this.rootStore.api.app.bsky.graph.getFollowers(
         this.params,
       )
       this._replaceAll(res)
@@ -92,9 +93,9 @@ export class UserFollowersViewModel {
     }
   }
 
-  private _replaceAll(res: GetUserFollowers.Response) {
+  private _replaceAll(res: GetFollowers.Response) {
     this.subject.did = res.data.subject.did
-    this.subject.name = res.data.subject.name
+    this.subject.handle = res.data.subject.handle
     this.subject.displayName = res.data.subject.displayName
     this.followers.length = 0
     let counter = 0
diff --git a/src/state/models/user-follows-view.ts b/src/state/models/user-follows-view.ts
index 92f9b4bc4..b7875c22c 100644
--- a/src/state/models/user-follows-view.ts
+++ b/src/state/models/user-follows-view.ts
@@ -1,9 +1,9 @@
 import {makeAutoObservable} from 'mobx'
-import * as GetUserFollows from '../../third-party/api/src/types/app/bsky/getUserFollows'
+import * as GetFollows from '../../third-party/api/src/client/types/app/bsky/graph/getFollows'
 import {RootStoreModel} from './root-store'
 
-type Subject = GetUserFollows.OutputSchema['subject']
-export type FollowItem = GetUserFollows.OutputSchema['follows'][number] & {
+type Subject = GetFollows.OutputSchema['subject']
+export type FollowItem = GetFollows.OutputSchema['follows'][number] & {
   _reactKey: string
 }
 
@@ -13,15 +13,15 @@ export class UserFollowsViewModel {
   isRefreshing = false
   hasLoaded = false
   error = ''
-  params: GetUserFollows.QueryParams
+  params: GetFollows.QueryParams
 
   // data
-  subject: Subject = {did: '', name: '', displayName: ''}
+  subject: Subject = {did: '', handle: '', displayName: ''}
   follows: FollowItem[] = []
 
   constructor(
     public rootStore: RootStoreModel,
-    params: GetUserFollows.QueryParams,
+    params: GetFollows.QueryParams,
   ) {
     makeAutoObservable(
       this,
@@ -83,7 +83,9 @@ export class UserFollowsViewModel {
   private async _fetch(isRefreshing = false) {
     this._xLoading(isRefreshing)
     try {
-      const res = await this.rootStore.api.app.bsky.getUserFollows(this.params)
+      const res = await this.rootStore.api.app.bsky.graph.getFollows(
+        this.params,
+      )
       this._replaceAll(res)
       this._xIdle()
     } catch (e: any) {
@@ -91,9 +93,9 @@ export class UserFollowsViewModel {
     }
   }
 
-  private _replaceAll(res: GetUserFollows.Response) {
+  private _replaceAll(res: GetFollows.Response) {
     this.subject.did = res.data.subject.did
-    this.subject.name = res.data.subject.name
+    this.subject.handle = res.data.subject.handle
     this.subject.displayName = res.data.subject.displayName
     this.follows.length = 0
     let counter = 0