Use a post and handle-resolution cache to enable quick postthread loading (#1097)

* Use a post and handle-resolution cache to enable quick postthread loading

* Fix positioning of thread when loaded from cache and give more visual cues

* Include parent posts in cache

* Include notifications in cache
This commit is contained in:
Paul Frazee 2023-08-03 09:44:43 -07:00 committed by GitHub
parent 7256169506
commit a63f97aef2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 167 additions and 18 deletions

View file

@ -12,6 +12,8 @@ import {PostThreadItemModel} from './post-thread-item'
export class PostThreadModel {
// state
isLoading = false
isLoadingFromCache = false
isFromCache = false
isRefreshing = false
hasLoaded = false
error = ''
@ -20,7 +22,7 @@ export class PostThreadModel {
params: GetPostThread.QueryParams
// data
thread?: PostThreadItemModel
thread?: PostThreadItemModel | null = null
isBlocked = false
constructor(
@ -52,7 +54,7 @@ export class PostThreadModel {
}
get hasContent() {
return typeof this.thread !== 'undefined'
return !!this.thread
}
get hasError() {
@ -82,10 +84,16 @@ export class PostThreadModel {
if (!this.resolvedUri) {
await this._resolveUri()
}
if (this.hasContent) {
await this.update()
} else {
await this._load()
const precache = this.rootStore.posts.cache.get(this.resolvedUri)
if (precache) {
await this._loadPrecached(precache)
} else {
await this._load()
}
}
}
@ -169,6 +177,37 @@ export class PostThreadModel {
})
}
async _loadPrecached(precache: AppBskyFeedDefs.PostView) {
// start with the cached version
this.isLoadingFromCache = true
this.isFromCache = true
this._replaceAll({
success: true,
headers: {},
data: {
thread: {
post: precache,
},
},
})
this._xIdle()
// then update in the background
try {
const res = await this.rootStore.agent.getPostThread(
Object.assign({}, this.params, {uri: this.resolvedUri}),
)
this._replaceAll(res)
} catch (e: any) {
console.log(e)
this._xIdle(e)
} finally {
runInAction(() => {
this.isLoadingFromCache = false
})
}
}
async _load(isRefreshing = false) {
if (this.hasLoaded && !isRefreshing) {
return

View file

@ -253,6 +253,12 @@ export class ProfileModel {
try {
const res = await this.rootStore.agent.getProfile(this.params)
this.rootStore.profiles.overwrite(this.params.actor, res) // cache invalidation
if (res.data.handle) {
this.rootStore.handleResolutions.cache.set(
res.data.handle,
res.data.did,
)
}
this._replaceAll(res)
await this._createRichText()
this._xIdle()