From 2b13dc0f3abfdb0eca03150bd77d773bbb26ebd4 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 22 Aug 2023 14:30:51 -0500 Subject: [PATCH] Add likes tab (#1227) * add likes tab (cherry picked from commit 6c5ffd964ca0b185ddfc37088d82712a006a1163) * only show Likes tab to authenticated user (cherry picked from commit ecc1254411d760158b6d7a4c5f05d940db872dfc) * Bump @atproto/api@0.6.5 * fix types --------- Co-authored-by: Paul Frazee --- package.json | 2 +- src/state/models/feeds/posts.ts | 9 +++- src/state/models/ui/profile.ts | 73 ++++++++++++++++++++++----------- yarn.lock | 8 ++-- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 3d4613e3..5eb4780a 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "e2e:run": "detox test --configuration ios.sim.debug --take-screenshots all" }, "dependencies": { - "@atproto/api": "^0.6.3", + "@atproto/api": "^0.6.5", "@bam.tech/react-native-image-resizer": "^3.0.4", "@braintree/sanitize-url": "^6.0.2", "@expo/html-elements": "^0.4.2", diff --git a/src/state/models/feeds/posts.ts b/src/state/models/feeds/posts.ts index 93add810..8bc75daa 100644 --- a/src/state/models/feeds/posts.ts +++ b/src/state/models/feeds/posts.ts @@ -3,6 +3,7 @@ import { AppBskyFeedGetTimeline as GetTimeline, AppBskyFeedGetAuthorFeed as GetAuthorFeed, AppBskyFeedGetFeed as GetCustomFeed, + AppBskyFeedGetActorLikes as GetActorLikes, } from '@atproto/api' import AwaitLock from 'await-lock' import {bundleAsync} from 'lib/async/bundle' @@ -57,7 +58,7 @@ export class PostsFeedModel { constructor( public rootStore: RootStoreModel, - public feedType: 'home' | 'author' | 'custom', + public feedType: 'home' | 'author' | 'custom' | 'likes', params: QueryParams, options?: Options, ) { @@ -429,10 +430,14 @@ export class PostsFeedModel { res.data.feed = res.data.feed.slice(0, params.limit) } return res - } else { + } else if (this.feedType === 'author') { return this.rootStore.agent.getAuthorFeed( params as GetAuthorFeed.QueryParams, ) + } else { + return this.rootStore.agent.getActorLikes( + params as GetActorLikes.QueryParams, + ) } } } diff --git a/src/state/models/ui/profile.ts b/src/state/models/ui/profile.ts index e026a27f..436ab313 100644 --- a/src/state/models/ui/profile.ts +++ b/src/state/models/ui/profile.ts @@ -9,6 +9,7 @@ export enum Sections { PostsNoReplies = 'Posts', PostsWithReplies = 'Posts & replies', PostsWithMedia = 'Media', + Likes = 'Likes', CustomAlgorithms = 'Feeds', Lists = 'Lists', } @@ -22,6 +23,8 @@ export class ProfileUiModel { static END_ITEM = {_reactKey: '__end__'} static EMPTY_ITEM = {_reactKey: '__empty__'} + isAuthenticatedUser = false + // data profile: ProfileModel feed: PostsFeedModel @@ -57,7 +60,8 @@ export class ProfileUiModel { if ( this.selectedView === Sections.PostsNoReplies || this.selectedView === Sections.PostsWithReplies || - this.selectedView === Sections.PostsWithMedia + this.selectedView === Sections.PostsWithMedia || + this.selectedView === Sections.Likes ) { return this.feed } else if (this.selectedView === Sections.Lists) { @@ -83,7 +87,8 @@ export class ProfileUiModel { Sections.PostsNoReplies, Sections.PostsWithReplies, Sections.PostsWithMedia, - ] + this.isAuthenticatedUser && Sections.Likes, + ].filter(Boolean) as string[] if (this.algos.hasLoaded && !this.algos.isEmpty) { items.push(Sections.CustomAlgorithms) } @@ -117,7 +122,8 @@ export class ProfileUiModel { if ( this.selectedView === Sections.PostsNoReplies || this.selectedView === Sections.PostsWithReplies || - this.selectedView === Sections.PostsWithMedia + this.selectedView === Sections.PostsWithMedia || + this.selectedView === Sections.Likes ) { if (this.feed.hasContent) { arr = this.feed.slices.slice() @@ -151,7 +157,8 @@ export class ProfileUiModel { if ( this.selectedView === Sections.PostsNoReplies || this.selectedView === Sections.PostsWithReplies || - this.selectedView === Sections.PostsWithMedia + this.selectedView === Sections.PostsWithMedia || + this.selectedView === Sections.Likes ) { return this.feed.hasContent && this.feed.hasMore && this.feed.isLoading } else if (this.selectedView === Sections.Lists) { @@ -169,27 +176,45 @@ export class ProfileUiModel { this.selectedViewIndex = index - let filter = 'posts_no_replies' - if (this.selectedView === Sections.PostsWithReplies) { - filter = 'posts_with_replies' - } else if (this.selectedView === Sections.PostsWithMedia) { - filter = 'posts_with_media' - } + if ( + this.selectedView === Sections.PostsNoReplies || + this.selectedView === Sections.PostsWithReplies || + this.selectedView === Sections.PostsWithMedia + ) { + let filter = 'posts_no_replies' + if (this.selectedView === Sections.PostsWithReplies) { + filter = 'posts_with_replies' + } else if (this.selectedView === Sections.PostsWithMedia) { + filter = 'posts_with_media' + } - this.feed = new PostsFeedModel( - this.rootStore, - 'author', - { - actor: this.params.user, - limit: 10, - filter, - }, - { - isSimpleFeed: ['posts_with_media'].includes(filter), - }, - ) + this.feed = new PostsFeedModel( + this.rootStore, + 'author', + { + actor: this.params.user, + limit: 10, + filter, + }, + { + isSimpleFeed: ['posts_with_media'].includes(filter), + }, + ) + + this.feed.setup() + } else if (this.selectedView === Sections.Likes) { + this.feed = new PostsFeedModel( + this.rootStore, + 'likes', + { + actor: this.params.user, + limit: 10, + }, + { + isSimpleFeed: true, + }, + ) - if (this.currentView instanceof PostsFeedModel) { this.feed.setup() } } @@ -203,6 +228,8 @@ export class ProfileUiModel { .setup() .catch(err => this.rootStore.log.error('Failed to fetch feed', err)), ]) + this.isAuthenticatedUser = + this.profile.did === this.rootStore.session.currentSession?.did this.algos.refresh() // HACK: need to use the DID as a param, not the username -prf this.lists.source = this.profile.did diff --git a/yarn.lock b/yarn.lock index 45bc4df9..1a9fed10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,10 +40,10 @@ tlds "^1.234.0" typed-emitter "^2.1.0" -"@atproto/api@^0.6.3": - version "0.6.3" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.6.3.tgz#2d604897df9098d84f3dfb3bffe1d4859513b1ba" - integrity sha512-vgwJn6M4wEyMm/oQKSATO3C0iRUZ/u5LTTl3E/MqV1mrWzvWLVhOqlATw7CDhEdzwJciO83ei72re6skhSp+Zg== +"@atproto/api@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.6.5.tgz#496a011b7e8fbf2af32a30cec07a021aa6ef3f4b" + integrity sha512-u6NVkYpdUU5jKGxio2FIRmok0LL+eqqMzihm9LDfydZ4Pi4NqfrOrWw0H1WA7zO3vH9AaxnLSMTwSEAkRRb2FA== dependencies: "@atproto/common-web" "*" "@atproto/uri" "*"