From 8cd2b4a721cd276669c401e51f1048033ed3df90 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 2 Jan 2023 13:40:14 -0600 Subject: [PATCH] Implement account muting --- package.json | 2 +- src/lib/images.ts | 1 - src/lib/link-meta.ts | 2 +- src/lib/strings.ts | 2 +- src/state/models/feed-view.ts | 1 - src/state/models/profile-view.ts | 13 +++++++ src/view/com/post-thread/PostThreadItem.tsx | 15 +++++++- src/view/com/post/Post.tsx | 15 +++++++- src/view/com/posts/FeedItem.tsx | 16 ++++++++- src/view/com/profile/ProfileHeader.tsx | 39 +++++++++++++++++++-- src/view/index.ts | 2 ++ yarn.lock | 8 ++--- 12 files changed, 101 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 815cfd0f..8f2723fc 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "postinstall": "patch-package" }, "dependencies": { - "@atproto/api": "^0.0.3", + "@atproto/api": "^0.0.4", "@bam.tech/react-native-image-resizer": "^3.0.4", "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/free-regular-svg-icons": "^6.1.1", diff --git a/src/lib/images.ts b/src/lib/images.ts index caeb96d2..d929a2e8 100644 --- a/src/lib/images.ts +++ b/src/lib/images.ts @@ -72,7 +72,6 @@ export async function resize(localUri: string, opts: ResizeOpts) { undefined, {mode: opts.mode}, ) - console.log(quality, resizeRes) if (resizeRes.size < opts.maxSize) { return resizeRes } diff --git a/src/lib/link-meta.ts b/src/lib/link-meta.ts index 53d5eed7..49e75cde 100644 --- a/src/lib/link-meta.ts +++ b/src/lib/link-meta.ts @@ -77,7 +77,7 @@ export async function getLinkMeta( meta.image = httpResMeta.image } catch (e) { // failed - console.log(e) + console.error(e) meta.error = 'Failed to fetch link' } diff --git a/src/lib/strings.ts b/src/lib/strings.ts index 1bbb4afd..6758e298 100644 --- a/src/lib/strings.ts +++ b/src/lib/strings.ts @@ -256,7 +256,7 @@ export function convertBskyAppUrlIfNeeded(url: string): string { const urlp = new URL(url) return urlp.pathname } catch (e) { - console.log('Unexpected error in convertBskyAppUrlIfNeeded()', e) + console.error('Unexpected error in convertBskyAppUrlIfNeeded()', e) } } return url diff --git a/src/state/models/feed-view.ts b/src/state/models/feed-view.ts index 2c205d7c..b5a3b29d 100644 --- a/src/state/models/feed-view.ts +++ b/src/state/models/feed-view.ts @@ -593,6 +593,5 @@ function ts(item: FeedViewPost | FeedItemModel): string { // @ts-ignore need better type checks return item.reason.indexedAt } - console.log(item) return item.post.indexedAt } diff --git a/src/state/models/profile-view.ts b/src/state/models/profile-view.ts index ce70867a..2a69a134 100644 --- a/src/state/models/profile-view.ts +++ b/src/state/models/profile-view.ts @@ -18,6 +18,7 @@ export const ACTOR_TYPE_SCENE = 'app.bsky.system.actorScene' export class ProfileViewMyStateModel { follow?: string member?: string + muted?: boolean constructor() { makeAutoObservable(this) @@ -156,6 +157,18 @@ export class ProfileViewModel { await this.refresh() } + async muteAccount() { + await this.rootStore.api.app.bsky.graph.mute({user: this.did}) + this.myState.muted = true + await this.refresh() + } + + async unmuteAccount() { + await this.rootStore.api.app.bsky.graph.unmute({user: this.did}) + this.myState.muted = false + await this.refresh() + } + // state transitions // = diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 9bc8df11..ae2bd668 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -282,7 +282,12 @@ export const PostThreadItem = observer(function PostThreadItem({ onCopyPostText={onCopyPostText} onDeletePost={onDeletePost} /> - {record.text ? ( + {item.post.author.viewer?.muted ? ( + + + This post is by a muted account. + + ) : record.text ? ( )} - {record.text ? ( + {item.post.author.viewer?.muted ? ( + + + This post is by a muted account. + + ) : record.text ? ( @@ -222,6 +227,14 @@ const styles = StyleSheet.create({ layoutContent: { flex: 1, }, + mutedWarning: { + flexDirection: 'row', + alignItems: 'center', + padding: 10, + marginTop: 2, + marginBottom: 6, + borderRadius: 2, + }, postTextContainer: { flexDirection: 'row', alignItems: 'center', diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 4d444fea..3916ea45 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -106,6 +106,7 @@ export const FeedItem = observer(function ({ isNoTop ? styles.outerNoTop : undefined, item._isThreadParent ? styles.outerNoBottom : undefined, ] + return ( <> {isChild && !item._isThreadChild && item.replyParent ? ( @@ -200,7 +201,12 @@ export const FeedItem = observer(function ({ )} - {record.text ? ( + {item.post.author.viewer?.muted ? ( + + + This post is by a muted account. + + ) : record.text ? ( { + try { + await view.muteAccount() + Toast.show('Account muted') + } catch (e: any) { + console.error(e) + Toast.show(`There was an issue! ${e.toString()}`) + } + } + const onPressUnmuteAccount = async () => { + try { + await view.unmuteAccount() + Toast.show('Account unmuted') + } catch (e: any) { + console.error(e) + Toast.show(`There was an issue! ${e.toString()}`) + } + } const onPressReportAccount = () => { store.shell.openModal(new ReportAccountModal(view.did)) } @@ -143,6 +161,10 @@ export const ProfileHeader = observer(function ProfileHeader({ let dropdownItems: DropdownItem[] | undefined if (!isMe) { dropdownItems = dropdownItems || [] + dropdownItems.push({ + label: view.myState.muted ? 'Unmute Account' : 'Mute Account', + onPress: view.myState.muted ? onPressUnmuteAccount : onPressMuteAccount, + }) dropdownItems.push({ label: 'Report Account', onPress: onPressReportAccount, @@ -286,7 +308,7 @@ export const ProfileHeader = observer(function ProfileHeader({ /> ) : undefined} {view.isScene && view.creator ? ( - + ) : undefined} {view.isScene && view.myState.member ? ( - + ) : undefined} + {view.myState.muted ? ( + + + + Account muted. + + + ) : undefined} {view.isScene && view.creator === store.me.did ? ( @@ -421,7 +454,7 @@ const styles = StyleSheet.create({ marginBottom: 8, }, - relationshipsLine: { + detailLine: { flexDirection: 'row', alignItems: 'center', marginBottom: 5, diff --git a/src/view/index.ts b/src/view/index.ts index 26695e5c..b38c0aa5 100644 --- a/src/view/index.ts +++ b/src/view/index.ts @@ -30,6 +30,7 @@ import {faCompass} from '@fortawesome/free-regular-svg-icons/faCompass' import {faEllipsis} from '@fortawesome/free-solid-svg-icons/faEllipsis' import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope' import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation' +import {faEyeSlash as farEyeSlash} from '@fortawesome/free-regular-svg-icons/faEyeSlash' import {faGear} from '@fortawesome/free-solid-svg-icons/faGear' import {faGlobe} from '@fortawesome/free-solid-svg-icons/faGlobe' import {faHeart} from '@fortawesome/free-regular-svg-icons/faHeart' @@ -96,6 +97,7 @@ export function setup() { faEllipsis, faEnvelope, faExclamation, + farEyeSlash, faGear, faGlobe, faHeart, diff --git a/yarn.lock b/yarn.lock index 51e8861b..3cac5087 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,10 +19,10 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.0.2.tgz#b6c4f5b670a04e5e79889da792518c8fb84c95bf" - integrity sha512-0ryu3M8kXCmVnRO9eb/PJ8dtwahP28tlMt0SetFQVcjUHZXkZwJGnscJOAznVP7OU1TlyUkjeDXRkUYx9hi4Lg== +"@atproto/api@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.0.4.tgz#f2cb17f234ea1360ebe719be244cabc28724d992" + integrity sha512-lSaww8M2R7pRi1p1CUoidiYRNgIcUrEbhk4SZ7dGYhp9M2BKXYr9PzwWDZmB/tmFLdRPzAslmg9QWKbc0mqeUQ== dependencies: "@atproto/xrpc" "*" typed-emitter "^2.1.0"