diff options
Diffstat (limited to 'src/state')
-rw-r--r-- | src/state/lib/api.ts | 38 | ||||
-rw-r--r-- | src/state/models/feed-view.ts | 55 | ||||
-rw-r--r-- | src/state/models/me.ts | 2 | ||||
-rw-r--r-- | src/state/models/notifications-view.ts | 4 | ||||
-rw-r--r-- | src/state/models/post-thread-view.ts | 49 | ||||
-rw-r--r-- | src/state/models/profile-ui.ts | 2 | ||||
-rw-r--r-- | src/state/models/votes-view.ts (renamed from src/state/models/liked-by-view.ts) | 38 |
7 files changed, 132 insertions, 56 deletions
diff --git a/src/state/lib/api.ts b/src/state/lib/api.ts index 3d2d26a56..efaac5c7b 100644 --- a/src/state/lib/api.ts +++ b/src/state/lib/api.ts @@ -50,21 +50,45 @@ export async function post( ) } -export async function like(store: RootStoreModel, uri: string, cid: string) { - return await store.api.app.bsky.feed.like.create( +export async function upvote(store: RootStoreModel, uri: string, cid: string) { + return await store.api.app.bsky.feed.vote.create( {did: store.me.did || ''}, { subject: {uri, cid}, + direction: 'up', createdAt: new Date().toISOString(), }, ) } -export async function unlike(store: RootStoreModel, likeUri: string) { - const likeUrip = new AtUri(likeUri) - return await store.api.app.bsky.feed.like.delete({ - did: likeUrip.hostname, - rkey: likeUrip.rkey, +export async function unupvote(store: RootStoreModel, upvoteUri: string) { + const urip = new AtUri(upvoteUri) + return await store.api.app.bsky.feed.vote.delete({ + did: urip.hostname, + rkey: urip.rkey, + }) +} + +export async function downvote( + store: RootStoreModel, + uri: string, + cid: string, +) { + return await store.api.app.bsky.feed.vote.create( + {did: store.me.did || ''}, + { + subject: {uri, cid}, + direction: 'down', + createdAt: new Date().toISOString(), + }, + ) +} + +export async function undownvote(store: RootStoreModel, downvoteUri: string) { + const urip = new AtUri(downvoteUri) + return await store.api.app.bsky.feed.vote.delete({ + did: urip.hostname, + rkey: urip.rkey, }) } diff --git a/src/state/models/feed-view.ts b/src/state/models/feed-view.ts index 9505ad556..392f9d215 100644 --- a/src/state/models/feed-view.ts +++ b/src/state/models/feed-view.ts @@ -6,7 +6,8 @@ import * as apilib from '../lib/api' export class FeedItemMyStateModel { repost?: string - like?: string + upvote?: string + downvote?: string constructor() { makeAutoObservable(this) @@ -29,7 +30,8 @@ export class FeedItemModel implements GetTimeline.FeedItem { | GetTimeline.UnknownEmbed replyCount: number = 0 repostCount: number = 0 - likeCount: number = 0 + upvoteCount: number = 0 + downvoteCount: number = 0 indexedAt: string = '' myState = new FeedItemMyStateModel() @@ -52,26 +54,53 @@ export class FeedItemModel implements GetTimeline.FeedItem { this.embed = v.embed this.replyCount = v.replyCount this.repostCount = v.repostCount - this.likeCount = v.likeCount + this.upvoteCount = v.upvoteCount + this.downvoteCount = v.downvoteCount this.indexedAt = v.indexedAt if (v.myState) { - this.myState.like = v.myState.like + this.myState.upvote = v.myState.upvote + this.myState.downvote = v.myState.downvote this.myState.repost = v.myState.repost } } - async toggleLike() { - if (this.myState.like) { - await apilib.unlike(this.rootStore, this.myState.like) + async _clearVotes() { + if (this.myState.upvote) { + await apilib.unupvote(this.rootStore, this.myState.upvote) runInAction(() => { - this.likeCount-- - this.myState.like = undefined + this.upvoteCount-- + this.myState.upvote = undefined }) - } else { - const res = await apilib.like(this.rootStore, this.uri, this.cid) + } + if (this.myState.downvote) { + await apilib.undownvote(this.rootStore, this.myState.downvote) + runInAction(() => { + this.downvoteCount-- + this.myState.downvote = undefined + }) + } + } + + async toggleUpvote() { + const wasntUpvoted = !this.myState.upvote + await this._clearVotes() + if (wasntUpvoted) { + const res = await apilib.upvote(this.rootStore, this.uri, this.cid) + runInAction(() => { + this.upvoteCount++ + this.myState.upvote = res.uri + }) + } + } + + async toggleDownvote() { + const wasntDownvoted = !this.myState.downvote + await this._clearVotes() + if (wasntDownvoted) { + const res = await apilib.downvote(this.rootStore, this.uri, this.cid) runInAction(() => { - this.likeCount++ - this.myState.like = res.uri + this.downvoteCount++ + this.myState.downvote = res.uri }) } } diff --git a/src/state/models/me.ts b/src/state/models/me.ts index 7a94d63ac..70f45097d 100644 --- a/src/state/models/me.ts +++ b/src/state/models/me.ts @@ -26,7 +26,7 @@ export class MeModel { this.did = sess.data.did || '' this.handle = sess.data.handle const profile = await this.rootStore.api.app.bsky.actor.getProfile({ - user: this.did, + actor: this.did, }) runInAction(() => { if (profile?.data) { diff --git a/src/state/models/notifications-view.ts b/src/state/models/notifications-view.ts index 8d8eede05..7b1508a19 100644 --- a/src/state/models/notifications-view.ts +++ b/src/state/models/notifications-view.ts @@ -57,8 +57,8 @@ export class NotificationsViewItemModel implements GroupedNotification { } } - get isLike() { - return this.reason === 'like' + get isUpvote() { + return this.reason === 'vote' } get isRepost() { diff --git a/src/state/models/post-thread-view.ts b/src/state/models/post-thread-view.ts index 0fc0dadbb..7a735de03 100644 --- a/src/state/models/post-thread-view.ts +++ b/src/state/models/post-thread-view.ts @@ -13,8 +13,9 @@ function* reactKeyGenerator(): Generator<string> { } export class PostThreadViewPostMyStateModel { - like?: string repost?: string + upvote?: string + downvote?: string constructor() { makeAutoObservable(this) @@ -40,7 +41,8 @@ export class PostThreadViewPostModel implements GetPostThread.Post { replyCount: number = 0 replies?: PostThreadViewPostModel[] repostCount: number = 0 - likeCount: number = 0 + upvoteCount: number = 0 + downvoteCount: number = 0 indexedAt: string = '' myState = new PostThreadViewPostMyStateModel() @@ -105,18 +107,43 @@ export class PostThreadViewPostModel implements GetPostThread.Post { } } - async toggleLike() { - if (this.myState.like) { - await apilib.unlike(this.rootStore, this.myState.like) + async _clearVotes() { + if (this.myState.upvote) { + await apilib.unupvote(this.rootStore, this.myState.upvote) runInAction(() => { - this.likeCount-- - this.myState.like = undefined + this.upvoteCount-- + this.myState.upvote = undefined }) - } else { - const res = await apilib.like(this.rootStore, this.uri, this.cid) + } + if (this.myState.downvote) { + await apilib.undownvote(this.rootStore, this.myState.downvote) + runInAction(() => { + this.downvoteCount-- + this.myState.downvote = undefined + }) + } + } + + async toggleUpvote() { + const wasntUpvoted = !this.myState.upvote + await this._clearVotes() + if (wasntUpvoted) { + const res = await apilib.upvote(this.rootStore, this.uri, this.cid) + runInAction(() => { + this.upvoteCount++ + this.myState.upvote = res.uri + }) + } + } + + async toggleDownvote() { + const wasntDownvoted = !this.myState.downvote + await this._clearVotes() + if (wasntDownvoted) { + const res = await apilib.downvote(this.rootStore, this.uri, this.cid) runInAction(() => { - this.likeCount++ - this.myState.like = res.uri + this.downvoteCount++ + this.myState.downvote = res.uri }) } } diff --git a/src/state/models/profile-ui.ts b/src/state/models/profile-ui.ts index 0ad893dd1..2ec615a9c 100644 --- a/src/state/models/profile-ui.ts +++ b/src/state/models/profile-ui.ts @@ -37,7 +37,7 @@ export class ProfileUiModel { }, {autoBind: true}, ) - this.profile = new ProfileViewModel(rootStore, {user: params.user}) + this.profile = new ProfileViewModel(rootStore, {actor: params.user}) this.feed = new FeedModel(rootStore, 'author', { author: params.user, limit: 10, diff --git a/src/state/models/liked-by-view.ts b/src/state/models/votes-view.ts index facda9032..d70737021 100644 --- a/src/state/models/liked-by-view.ts +++ b/src/state/models/votes-view.ts @@ -1,45 +1,41 @@ import {makeAutoObservable, runInAction} from 'mobx' import {AtUri} from '../../third-party/uri' -import * as GetLikedBy from '../../third-party/api/src/client/types/app/bsky/feed/getLikedBy' +import * as GetVotes from '../../third-party/api/src/client/types/app/bsky/feed/getVotes' import {RootStoreModel} from './root-store' -type LikedByItem = GetLikedBy.OutputSchema['likedBy'][number] +type VoteItem = GetVotes.OutputSchema['votes'][number] -export class LikedByViewItemModel implements LikedByItem { +export class VotesViewItemModel implements VoteItem { // ui state _reactKey: string = '' // data - did: string = '' - handle: string = '' - displayName: string = '' - createdAt?: string + direction: 'up' | 'down' = 'up' indexedAt: string = '' + createdAt: string = '' + actor: GetVotes.Actor = {did: '', handle: ''} - constructor(reactKey: string, v: LikedByItem) { + constructor(reactKey: string, v: VoteItem) { makeAutoObservable(this) this._reactKey = reactKey Object.assign(this, v) } } -export class LikedByViewModel { +export class VotesViewModel { // state isLoading = false isRefreshing = false hasLoaded = false error = '' resolvedUri = '' - params: GetLikedBy.QueryParams + params: GetVotes.QueryParams // data uri: string = '' - likedBy: LikedByViewItemModel[] = [] + votes: VotesViewItemModel[] = [] - constructor( - public rootStore: RootStoreModel, - params: GetLikedBy.QueryParams, - ) { + constructor(public rootStore: RootStoreModel, params: GetVotes.QueryParams) { makeAutoObservable( this, { @@ -113,7 +109,7 @@ export class LikedByViewModel { private async _fetch(isRefreshing = false) { this._xLoading(isRefreshing) try { - const res = await this.rootStore.api.app.bsky.feed.getLikedBy( + const res = await this.rootStore.api.app.bsky.feed.getVotes( Object.assign({}, this.params, {uri: this.resolvedUri}), ) this._replaceAll(res) @@ -123,15 +119,15 @@ export class LikedByViewModel { } } - private _replaceAll(res: GetLikedBy.Response) { - this.likedBy.length = 0 + private _replaceAll(res: GetVotes.Response) { + this.votes.length = 0 let counter = 0 - for (const item of res.data.likedBy) { + for (const item of res.data.votes) { this._append(counter++, item) } } - private _append(keyId: number, item: LikedByItem) { - this.likedBy.push(new LikedByViewItemModel(`item-${keyId}`, item)) + private _append(keyId: number, item: VoteItem) { + this.votes.push(new VotesViewItemModel(`item-${keyId}`, item)) } } |