diff options
author | Paul Frazee <pfrazee@gmail.com> | 2022-07-22 11:18:47 -0500 |
---|---|---|
committer | Paul Frazee <pfrazee@gmail.com> | 2022-07-22 11:18:47 -0500 |
commit | 0ec0ba996f05876d78039509e0ea61528c5faeec (patch) | |
tree | 1184d8adc886033c312def5b8326a8eda1d8c921 /src/state/models/post-thread-view.ts | |
parent | cc8a1702043cfbd783f4caa61ab9eb8aeb421072 (diff) | |
download | voidsky-0ec0ba996f05876d78039509e0ea61528c5faeec.tar.zst |
Implement like and repost
Diffstat (limited to 'src/state/models/post-thread-view.ts')
-rw-r--r-- | src/state/models/post-thread-view.ts | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/src/state/models/post-thread-view.ts b/src/state/models/post-thread-view.ts index 3c3b8d92d..ef3a49e9e 100644 --- a/src/state/models/post-thread-view.ts +++ b/src/state/models/post-thread-view.ts @@ -2,6 +2,7 @@ import {makeAutoObservable, runInAction} from 'mobx' import {bsky, AdxUri} from '@adxp/mock-api' import _omit from 'lodash.omit' import {RootStoreModel} from './root-store' +import * as apilib from '../lib/api' function* reactKeyGenerator(): Generator<string> { let counter = 0 @@ -10,6 +11,15 @@ function* reactKeyGenerator(): Generator<string> { } } +export class PostThreadViewPostMyStateModel { + hasLiked: boolean = false + hasReposted: boolean = false + + constructor() { + makeAutoObservable(this) + } +} + export class PostThreadViewPostModel implements bsky.PostThreadView.Post { // ui state _reactKey: string = '' @@ -30,12 +40,20 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post { repostCount: number = 0 likeCount: number = 0 indexedAt: string = '' + myState = new PostThreadViewPostMyStateModel() - constructor(reactKey: string, v?: bsky.PostThreadView.Post) { - makeAutoObservable(this) + constructor( + public rootStore: RootStoreModel, + reactKey: string, + v?: bsky.PostThreadView.Post, + ) { + makeAutoObservable(this, {rootStore: false}) this._reactKey = reactKey if (v) { - Object.assign(this, _omit(v, 'parent', 'replies')) // copy everything but the replies and the parent + Object.assign(this, _omit(v, 'parent', 'replies', 'myState')) // replies and parent are handled via assignTreeModels + if (v.myState) { + Object.assign(this.myState, v.myState) + } } } @@ -44,6 +62,7 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post { if (v.parent) { // TODO: validate .record const parentModel = new PostThreadViewPostModel( + this.rootStore, keyGen.next().value, v.parent, ) @@ -58,7 +77,11 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post { const replies = [] for (const item of v.replies) { // TODO: validate .record - const itemModel = new PostThreadViewPostModel(keyGen.next().value, item) + const itemModel = new PostThreadViewPostModel( + this.rootStore, + keyGen.next().value, + item, + ) itemModel._depth = this._depth + 1 if (item.replies) { itemModel.assignTreeModels(keyGen, item) @@ -68,10 +91,41 @@ export class PostThreadViewPostModel implements bsky.PostThreadView.Post { this.replies = replies } } + + async toggleLike() { + if (this.myState.hasLiked) { + await apilib.unlike(this.rootStore.api, 'alice.com', this.uri) + runInAction(() => { + this.likeCount-- + this.myState.hasLiked = false + }) + } else { + await apilib.like(this.rootStore.api, 'alice.com', this.uri) + runInAction(() => { + this.likeCount++ + this.myState.hasLiked = true + }) + } + } + + async toggleRepost() { + if (this.myState.hasReposted) { + await apilib.unrepost(this.rootStore.api, 'alice.com', this.uri) + runInAction(() => { + this.repostCount-- + this.myState.hasReposted = false + }) + } else { + await apilib.repost(this.rootStore.api, 'alice.com', this.uri) + runInAction(() => { + this.repostCount++ + this.myState.hasReposted = true + }) + } + } } -const UNLOADED_THREAD = new PostThreadViewPostModel('') -export class PostThreadViewModel implements bsky.PostThreadView.Response { +export class PostThreadViewModel { // state isLoading = false isRefreshing = false @@ -81,7 +135,7 @@ export class PostThreadViewModel implements bsky.PostThreadView.Response { params: bsky.PostThreadView.Params // data - thread: PostThreadViewPostModel = UNLOADED_THREAD + thread?: PostThreadViewPostModel constructor( public rootStore: RootStoreModel, @@ -99,7 +153,7 @@ export class PostThreadViewModel implements bsky.PostThreadView.Response { } get hasContent() { - return this.thread !== UNLOADED_THREAD + return typeof this.thread !== 'undefined' } get hasError() { @@ -177,7 +231,11 @@ export class PostThreadViewModel implements bsky.PostThreadView.Response { private _replaceAll(res: bsky.PostThreadView.Response) { // TODO: validate .record const keyGen = reactKeyGenerator() - const thread = new PostThreadViewPostModel(keyGen.next().value, res.thread) + const thread = new PostThreadViewPostModel( + this.rootStore, + keyGen.next().value, + res.thread, + ) thread._isHighlightedPost = true thread.assignTreeModels(keyGen, res.thread) this.thread = thread |