about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-05-11 16:08:21 -0500
committerGitHub <noreply@github.com>2023-05-11 16:08:21 -0500
commitebcd6333863a2073278fad482981d9898c0f20ca (patch)
tree9417a5c282fc6ce22af2251f437f02b0700c7714 /src/lib
parent34d8fa59916d87922c83a6cf93e3e288d43dadcc (diff)
downloadvoidsky-ebcd6333863a2073278fad482981d9898c0f20ca.tar.zst
[APP-635] Mutelists (#601)
* Add lists and profilelist screens

* Implement lists screen and lists-list in profiles

* Add empty states to the lists screen

* Switch (mostly) from blocklists to mutelists

* Rework: create a new moderation screen and move everything related under it

* Fix moderation screen on desktop web

* Tune the empty state code

* Change content moderation modal to content filtering

* Add CreateMuteList modal

* Implement mutelist creation

* Add lists listings

* Add the ability to create new mutelists

* Add 'add to list' tool

* Satisfy the hashtag hyphen haters

* Add update/delete/subscribe/unsubscribe to lists

* Show which list caused a mute

* Add list un/subscribe

* Add the mute override when viewing a profile's posts

* Update to latest backend

* Add simulation tests and tune some behaviors

* Fix lint

* Bump deps

* Fix list refresh after creation

* Mute list subscriptions -> Mute lists
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/labeling/helpers.ts33
-rw-r--r--src/lib/labeling/types.ts4
-rw-r--r--src/lib/routes/types.ts7
-rw-r--r--src/lib/strings/url-helpers.ts9
4 files changed, 47 insertions, 6 deletions
diff --git a/src/lib/labeling/helpers.ts b/src/lib/labeling/helpers.ts
index baac0ed5a..447b0a99a 100644
--- a/src/lib/labeling/helpers.ts
+++ b/src/lib/labeling/helpers.ts
@@ -1,5 +1,6 @@
 import {
   AppBskyActorDefs,
+  AppBskyGraphDefs,
   AppBskyEmbedRecordWithMedia,
   AppBskyEmbedRecord,
   AppBskyEmbedImages,
@@ -16,6 +17,7 @@ import {
   Label,
   LabelValGroup,
   ModerationBehaviorCode,
+  ModerationBehavior,
   PostModeration,
   ProfileModeration,
   PostLabelInfo,
@@ -127,11 +129,15 @@ export function getPostModeration(
 
   // muting
   if (postInfo.isMuted) {
+    let msg = 'Post from an account you muted.'
+    if (postInfo.mutedByList) {
+      msg = `Muted by ${postInfo.mutedByList.name}`
+    }
     return {
       avatar,
-      list: hide('Post from an account you muted.'),
-      thread: warn('Post from an account you muted.'),
-      view: warn('Post from an account you muted.'),
+      list: isMute(hide(msg)),
+      thread: isMute(warn(msg)),
+      view: isMute(warn(msg)),
     }
   }
 
@@ -273,6 +279,7 @@ export function getProfileViewBasicLabelInfo(
     profileLabels: filterProfileLabels(profile.labels),
     isMuted: profile.viewer?.muted || false,
     isBlocking: !!profile.viewer?.blocking || false,
+    isBlockedBy: !!profile.viewer?.blockedBy || false,
   }
 }
 
@@ -302,6 +309,21 @@ export function getEmbedMuted(embed?: Embed): boolean {
   return false
 }
 
+export function getEmbedMutedByList(
+  embed?: Embed,
+): AppBskyGraphDefs.ListViewBasic | undefined {
+  if (!embed) {
+    return undefined
+  }
+  if (
+    AppBskyEmbedRecord.isView(embed) &&
+    AppBskyEmbedRecord.isViewRecord(embed.record)
+  ) {
+    return embed.record.author.viewer?.mutedByList
+  }
+  return undefined
+}
+
 export function getEmbedBlocking(embed?: Embed): boolean {
   if (!embed) {
     return false
@@ -401,6 +423,11 @@ function warnContent(reason: string) {
   }
 }
 
+function isMute(behavior: ModerationBehavior): ModerationBehavior {
+  behavior.isMute = true
+  return behavior
+}
+
 function warnImages(reason: string) {
   return {
     behavior: ModerationBehaviorCode.WarnImages,
diff --git a/src/lib/labeling/types.ts b/src/lib/labeling/types.ts
index 078043076..1ee058024 100644
--- a/src/lib/labeling/types.ts
+++ b/src/lib/labeling/types.ts
@@ -1,4 +1,4 @@
-import {ComAtprotoLabelDefs} from '@atproto/api'
+import {ComAtprotoLabelDefs, AppBskyGraphDefs} from '@atproto/api'
 import {LabelPreferencesModel} from 'state/models/ui/preferences'
 
 export type Label = ComAtprotoLabelDefs.Label
@@ -22,6 +22,7 @@ export interface PostLabelInfo {
   accountLabels: Label[]
   profileLabels: Label[]
   isMuted: boolean
+  mutedByList?: AppBskyGraphDefs.ListViewBasic
   isBlocking: boolean
   isBlockedBy: boolean
 }
@@ -44,6 +45,7 @@ export enum ModerationBehaviorCode {
 
 export interface ModerationBehavior {
   behavior: ModerationBehaviorCode
+  isMute?: boolean
   noOverride?: boolean
   reason?: string
 }
diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts
index 34e6e6a46..56775deee 100644
--- a/src/lib/routes/types.ts
+++ b/src/lib/routes/types.ts
@@ -5,10 +5,15 @@ export type {NativeStackScreenProps} from '@react-navigation/native-stack'
 
 export type CommonNavigatorParams = {
   NotFound: undefined
+  Moderation: undefined
+  ModerationMuteLists: undefined
+  ModerationMutedAccounts: undefined
+  ModerationBlockedAccounts: undefined
   Settings: undefined
   Profile: {name: string; hideBackButton?: boolean}
   ProfileFollowers: {name: string}
   ProfileFollows: {name: string}
+  ProfileList: {name: string; rkey: string}
   PostThread: {name: string; rkey: string}
   PostLikedBy: {name: string; rkey: string}
   PostRepostedBy: {name: string; rkey: string}
@@ -20,8 +25,6 @@ export type CommonNavigatorParams = {
   CommunityGuidelines: undefined
   CopyrightPolicy: undefined
   AppPasswords: undefined
-  MutedAccounts: undefined
-  BlockedAccounts: undefined
 }
 
 export type BottomTabNavigatorParams = CommonNavigatorParams & {
diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts
index 549587f74..a5412920e 100644
--- a/src/lib/strings/url-helpers.ts
+++ b/src/lib/strings/url-helpers.ts
@@ -94,6 +94,15 @@ export function convertBskyAppUrlIfNeeded(url: string): string {
   return url
 }
 
+export function listUriToHref(url: string): string {
+  try {
+    const {hostname, rkey} = new AtUri(url)
+    return `/profile/${hostname}/lists/${rkey}`
+  } catch {
+    return ''
+  }
+}
+
 export function getYoutubeVideoId(link: string): string | undefined {
   let url
   try {