about summary refs log tree commit diff
path: root/src/view/com/profile/ProfileHeader.tsx
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/view/com/profile/ProfileHeader.tsx
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/view/com/profile/ProfileHeader.tsx')
-rw-r--r--src/view/com/profile/ProfileHeader.tsx56
1 files changed, 42 insertions, 14 deletions
diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx
index dee788aff..3b9ca67c9 100644
--- a/src/view/com/profile/ProfileHeader.tsx
+++ b/src/view/com/profile/ProfileHeader.tsx
@@ -23,6 +23,7 @@ import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton'
 import * as Toast from '../util/Toast'
 import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
 import {Text} from '../util/text/Text'
+import {TextLink} from '../util/Link'
 import {RichText} from '../util/text/RichText'
 import {UserAvatar} from '../util/UserAvatar'
 import {UserBanner} from '../util/UserBanner'
@@ -30,6 +31,7 @@ import {ProfileHeaderWarnings} from '../util/moderation/ProfileHeaderWarnings'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useAnalytics} from 'lib/analytics'
 import {NavigationProp} from 'lib/routes/types'
+import {listUriToHref} from 'lib/strings/url-helpers'
 import {isDesktopWeb, isNative} from 'platform/detection'
 import {FollowState} from 'state/models/cache/my-follows'
 import {shareUrl} from 'lib/sharing'
@@ -146,12 +148,21 @@ const ProfileHeaderLoaded = observer(
       navigation.push('ProfileFollows', {name: view.handle})
     }, [track, navigation, view])
 
-    const onPressShare = React.useCallback(async () => {
+    const onPressShare = React.useCallback(() => {
       track('ProfileHeader:ShareButtonClicked')
       const url = toShareUrl(`/profile/${view.handle}`)
       shareUrl(url)
     }, [track, view])
 
+    const onPressAddRemoveLists = React.useCallback(() => {
+      track('ProfileHeader:AddToListsButtonClicked')
+      store.shell.openModal({
+        name: 'list-add-remove-user',
+        subject: view.did,
+        displayName: view.displayName || view.handle,
+      })
+    }, [track, view, store])
+
     const onPressMuteAccount = React.useCallback(async () => {
       track('ProfileHeader:MuteAccountButtonClicked')
       try {
@@ -233,6 +244,11 @@ const ProfileHeaderLoaded = observer(
           label: 'Share',
           onPress: onPressShare,
         },
+        {
+          testID: 'profileHeaderDropdownListAddRemoveBtn',
+          label: 'Add to Lists',
+          onPress: onPressAddRemoveLists,
+        },
       ]
       if (!isMe) {
         items.push({sep: true})
@@ -269,6 +285,7 @@ const ProfileHeaderLoaded = observer(
       onPressUnblockAccount,
       onPressBlockAccount,
       onPressReportAccount,
+      onPressAddRemoveLists,
     ])
 
     const blockHide = !isMe && (view.viewer.blocking || view.viewer.blockedBy)
@@ -422,31 +439,42 @@ const ProfileHeaderLoaded = observer(
             {view.viewer.blocking ? (
               <View
                 testID="profileHeaderBlockedNotice"
-                style={[styles.moderationNotice, pal.view, pal.border]}>
-                <FontAwesomeIcon icon="ban" style={[pal.text, s.mr5]} />
-                <Text type="md" style={[s.mr2, pal.text]}>
+                style={[styles.moderationNotice, pal.viewLight]}>
+                <FontAwesomeIcon icon="ban" style={[pal.text]} />
+                <Text type="lg-medium" style={pal.text}>
                   Account blocked
                 </Text>
               </View>
             ) : view.viewer.muted ? (
               <View
                 testID="profileHeaderMutedNotice"
-                style={[styles.moderationNotice, pal.view, pal.border]}>
+                style={[styles.moderationNotice, pal.viewLight]}>
                 <FontAwesomeIcon
                   icon={['far', 'eye-slash']}
-                  style={[pal.text, s.mr5]}
+                  style={[pal.text]}
                 />
-                <Text type="md" style={[s.mr2, pal.text]}>
-                  Account muted
+                <Text type="lg-medium" style={pal.text}>
+                  Account muted{' '}
+                  {view.viewer.mutedByList && (
+                    <Text type="lg-medium" style={pal.text}>
+                      by{' '}
+                      <TextLink
+                        type="lg-medium"
+                        style={pal.link}
+                        href={listUriToHref(view.viewer.mutedByList.uri)}
+                        text={view.viewer.mutedByList.name}
+                      />
+                    </Text>
+                  )}
                 </Text>
               </View>
             ) : undefined}
             {view.viewer.blockedBy && (
               <View
                 testID="profileHeaderBlockedNotice"
-                style={[styles.moderationNotice, pal.view, pal.border]}>
-                <FontAwesomeIcon icon="ban" style={[pal.text, s.mr5]} />
-                <Text type="md" style={[s.mr2, pal.text]}>
+                style={[styles.moderationNotice, pal.viewLight]}>
+                <FontAwesomeIcon icon="ban" style={[pal.text]} />
+                <Text type="lg-medium" style={pal.text}>
                   This account has blocked you
                 </Text>
               </View>
@@ -595,10 +623,10 @@ const styles = StyleSheet.create({
   moderationNotice: {
     flexDirection: 'row',
     alignItems: 'center',
-    borderWidth: 1,
     borderRadius: 8,
-    paddingHorizontal: 12,
-    paddingVertical: 10,
+    paddingHorizontal: 16,
+    paddingVertical: 14,
+    gap: 8,
   },
 
   br40: {borderRadius: 40},