about summary refs log tree commit diff
path: root/src/view/com/feeds/FeedSourceCard.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/feeds/FeedSourceCard.tsx')
-rw-r--r--src/view/com/feeds/FeedSourceCard.tsx254
1 files changed, 128 insertions, 126 deletions
diff --git a/src/view/com/feeds/FeedSourceCard.tsx b/src/view/com/feeds/FeedSourceCard.tsx
index 4af62f6f6..9300b4159 100644
--- a/src/view/com/feeds/FeedSourceCard.tsx
+++ b/src/view/com/feeds/FeedSourceCard.tsx
@@ -11,7 +11,6 @@ import {AtUri} from '@atproto/api'
 import * as Toast from 'view/com/util/Toast'
 import {sanitizeHandle} from 'lib/strings/handles'
 import {logger} from '#/logger'
-import {useModalControls} from '#/state/modals'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {
@@ -24,6 +23,7 @@ import {
 import {useFeedSourceInfoQuery, FeedSourceInfo} from '#/state/queries/feed'
 import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
 import {useTheme} from '#/alf'
+import * as Prompt from '#/components/Prompt'
 import {useNavigationDeduped} from 'lib/hooks/useNavigationDeduped'
 
 export function FeedSourceCard({
@@ -85,8 +85,8 @@ export function FeedSourceCardLoaded({
   const t = useTheme()
   const pal = usePalette('default')
   const {_} = useLingui()
+  const removePromptControl = Prompt.usePromptControl()
   const navigation = useNavigationDeduped()
-  const {openModal} = useModalControls()
 
   const {isPending: isSavePending, mutateAsync: saveFeed} =
     useSaveFeedMutation()
@@ -96,40 +96,45 @@ export function FeedSourceCardLoaded({
 
   const isSaved = Boolean(preferences?.feeds?.saved?.includes(feed?.uri || ''))
 
+  const onSave = React.useCallback(async () => {
+    if (!feed) return
+
+    try {
+      if (pinOnSave) {
+        await pinFeed({uri: feed.uri})
+      } else {
+        await saveFeed({uri: feed.uri})
+      }
+      Toast.show(_(msg`Added to my feeds`))
+    } catch (e) {
+      Toast.show(_(msg`There was an issue contacting your server`))
+      logger.error('Failed to save feed', {message: e})
+    }
+  }, [_, feed, pinFeed, pinOnSave, saveFeed])
+
+  const onUnsave = React.useCallback(async () => {
+    if (!feed) return
+
+    try {
+      await removeFeed({uri: feed.uri})
+      // await item.unsave()
+      Toast.show(_(msg`Removed from my feeds`))
+    } catch (e) {
+      Toast.show(_(msg`There was an issue contacting your server`))
+      logger.error('Failed to unsave feed', {message: e})
+    }
+  }, [_, feed, removeFeed])
+
   const onToggleSaved = React.useCallback(async () => {
     // Only feeds can be un/saved, lists are handled elsewhere
     if (feed?.type !== 'feed') return
 
     if (isSaved) {
-      openModal({
-        name: 'confirm',
-        title: _(msg`Remove from my feeds`),
-        message: _(msg`Remove ${feed?.displayName} from my feeds?`),
-        onPressConfirm: async () => {
-          try {
-            await removeFeed({uri: feed.uri})
-            // await item.unsave()
-            Toast.show(_(msg`Removed from my feeds`))
-          } catch (e) {
-            Toast.show(_(msg`There was an issue contacting your server`))
-            logger.error('Failed to unsave feed', {message: e})
-          }
-        },
-      })
+      removePromptControl.open()
     } else {
-      try {
-        if (pinOnSave) {
-          await pinFeed({uri: feed.uri})
-        } else {
-          await saveFeed({uri: feed.uri})
-        }
-        Toast.show(_(msg`Added to my feeds`))
-      } catch (e) {
-        Toast.show(_(msg`There was an issue contacting your server`))
-        logger.error('Failed to save feed', {message: e})
-      }
+      await onSave()
     }
-  }, [isSaved, openModal, feed, removeFeed, saveFeed, _, pinOnSave, pinFeed])
+  }, [feed?.type, isSaved, removePromptControl, onSave])
 
   /*
    * LOAD STATE
@@ -167,25 +172,7 @@ export function FeedSourceCardLoaded({
             accessibilityRole="button"
             accessibilityLabel={_(msg`Remove from my feeds`)}
             accessibilityHint=""
-            onPress={() => {
-              openModal({
-                name: 'confirm',
-                title: _(msg`Remove from my feeds`),
-                message: _(msg`Remove this feed from my feeds?`),
-                onPressConfirm: async () => {
-                  try {
-                    await removeFeed({uri: feedUri})
-                    // await item.unsave()
-                    Toast.show(_(msg`Removed from my feeds`))
-                  } catch (e) {
-                    Toast.show(
-                      _(msg`There was an issue contacting your server`),
-                    )
-                    logger.error('Failed to unsave feed', {message: e})
-                  }
-                },
-              })
-            }}
+            onPress={onToggleSaved}
             hitSlop={15}
             style={styles.btn}>
             <FontAwesomeIcon
@@ -199,89 +186,104 @@ export function FeedSourceCardLoaded({
     )
 
   return (
-    <Pressable
-      testID={`feed-${feed.displayName}`}
-      accessibilityRole="button"
-      style={[styles.container, pal.border, style]}
-      onPress={() => {
-        if (feed.type === 'feed') {
-          navigation.push('ProfileFeed', {
-            name: feed.creatorDid,
-            rkey: new AtUri(feed.uri).rkey,
-          })
-        } else if (feed.type === 'list') {
-          navigation.push('ProfileList', {
-            name: feed.creatorDid,
-            rkey: new AtUri(feed.uri).rkey,
-          })
-        }
-      }}
-      key={feed.uri}>
-      <View style={[styles.headerContainer]}>
-        <View style={[s.mr10]}>
-          <UserAvatar type="algo" size={36} avatar={feed.avatar} />
-        </View>
-        <View style={[styles.headerTextContainer]}>
-          <Text style={[pal.text, s.bold]} numberOfLines={3}>
-            {feed.displayName}
-          </Text>
-          <Text style={[pal.textLight]} numberOfLines={3}>
-            {feed.type === 'feed' ? (
-              <Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
-            ) : (
-              <Trans>List by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
-            )}
-          </Text>
-        </View>
-
-        {showSaveBtn && feed.type === 'feed' && (
-          <View style={[s.justifyCenter]}>
-            <Pressable
-              testID={`feed-${feed.displayName}-toggleSave`}
-              disabled={isSavePending || isPinPending || isRemovePending}
-              accessibilityRole="button"
-              accessibilityLabel={
-                isSaved ? _(msg`Remove from my feeds`) : _(msg`Add to my feeds`)
-              }
-              accessibilityHint=""
-              onPress={onToggleSaved}
-              hitSlop={15}
-              style={styles.btn}>
-              {isSaved ? (
-                <FontAwesomeIcon
-                  icon={['far', 'trash-can']}
-                  size={19}
-                  color={pal.colors.icon}
-                />
+    <>
+      <Pressable
+        testID={`feed-${feed.displayName}`}
+        accessibilityRole="button"
+        style={[styles.container, pal.border, style]}
+        onPress={() => {
+          if (feed.type === 'feed') {
+            navigation.push('ProfileFeed', {
+              name: feed.creatorDid,
+              rkey: new AtUri(feed.uri).rkey,
+            })
+          } else if (feed.type === 'list') {
+            navigation.push('ProfileList', {
+              name: feed.creatorDid,
+              rkey: new AtUri(feed.uri).rkey,
+            })
+          }
+        }}
+        key={feed.uri}>
+        <View style={[styles.headerContainer]}>
+          <View style={[s.mr10]}>
+            <UserAvatar type="algo" size={36} avatar={feed.avatar} />
+          </View>
+          <View style={[styles.headerTextContainer]}>
+            <Text style={[pal.text, s.bold]} numberOfLines={3}>
+              {feed.displayName}
+            </Text>
+            <Text style={[pal.textLight]} numberOfLines={3}>
+              {feed.type === 'feed' ? (
+                <Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
               ) : (
-                <FontAwesomeIcon
-                  icon="plus"
-                  size={18}
-                  color={pal.colors.link}
-                />
+                <Trans>List by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
               )}
-            </Pressable>
+            </Text>
           </View>
-        )}
-      </View>
 
-      {showDescription && feed.description ? (
-        <RichText
-          style={[t.atoms.text_contrast_high, styles.description]}
-          value={feed.description}
-          numberOfLines={3}
-        />
-      ) : null}
+          {showSaveBtn && feed.type === 'feed' && (
+            <View style={[s.justifyCenter]}>
+              <Pressable
+                testID={`feed-${feed.displayName}-toggleSave`}
+                disabled={isSavePending || isPinPending || isRemovePending}
+                accessibilityRole="button"
+                accessibilityLabel={
+                  isSaved
+                    ? _(msg`Remove from my feeds`)
+                    : _(msg`Add to my feeds`)
+                }
+                accessibilityHint=""
+                onPress={onToggleSaved}
+                hitSlop={15}
+                style={styles.btn}>
+                {isSaved ? (
+                  <FontAwesomeIcon
+                    icon={['far', 'trash-can']}
+                    size={19}
+                    color={pal.colors.icon}
+                  />
+                ) : (
+                  <FontAwesomeIcon
+                    icon="plus"
+                    size={18}
+                    color={pal.colors.link}
+                  />
+                )}
+              </Pressable>
+            </View>
+          )}
+        </View>
+
+        {showDescription && feed.description ? (
+          <RichText
+            style={[t.atoms.text_contrast_high, styles.description]}
+            value={feed.description}
+            numberOfLines={3}
+          />
+        ) : null}
 
-      {showLikes && feed.type === 'feed' ? (
-        <Text type="sm-medium" style={[pal.text, pal.textLight]}>
-          <Trans>
-            Liked by {feed.likeCount || 0}{' '}
-            {pluralize(feed.likeCount || 0, 'user')}
-          </Trans>
-        </Text>
-      ) : null}
-    </Pressable>
+        {showLikes && feed.type === 'feed' ? (
+          <Text type="sm-medium" style={[pal.text, pal.textLight]}>
+            <Trans>
+              Liked by {feed.likeCount || 0}{' '}
+              {pluralize(feed.likeCount || 0, 'user')}
+            </Trans>
+          </Text>
+        ) : null}
+      </Pressable>
+
+      <Prompt.Basic
+        control={removePromptControl}
+        title={_(msg`Remove from my feeds?`)}
+        description={_(
+          msg`Are you sure you want to remove ${feed.displayName} from your feeds?`,
+        )}
+        onConfirm={onUnsave}
+        confirmButtonCta={_(msg`Remove`)}
+        confirmButtonColor="negative"
+      />
+    </>
   )
 }