From d00879e628145ec6ded18048be212d09c0227ba8 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Dec 2024 20:57:53 +0000 Subject: Disambiguate feed component naming (#7040) * Rename posts/Feed* -> posts/PostFeed* * Rename notifications/Feed* -> notifications/NotificationFeed* --- src/view/com/posts/PostFeedErrorMessage.tsx | 279 ++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 src/view/com/posts/PostFeedErrorMessage.tsx (limited to 'src/view/com/posts/PostFeedErrorMessage.tsx') diff --git a/src/view/com/posts/PostFeedErrorMessage.tsx b/src/view/com/posts/PostFeedErrorMessage.tsx new file mode 100644 index 000000000..39347b89c --- /dev/null +++ b/src/view/com/posts/PostFeedErrorMessage.tsx @@ -0,0 +1,279 @@ +import React from 'react' +import {View} from 'react-native' +import {AppBskyActorDefs, AppBskyFeedGetAuthorFeed, AtUri} from '@atproto/api' +import {msg as msgLingui, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useNavigation} from '@react-navigation/native' + +import {usePalette} from '#/lib/hooks/usePalette' +import {NavigationProp} from '#/lib/routes/types' +import {cleanError} from '#/lib/strings/errors' +import {logger} from '#/logger' +import {FeedDescriptor} from '#/state/queries/post-feed' +import {useRemoveFeedMutation} from '#/state/queries/preferences' +import * as Prompt from '#/components/Prompt' +import {EmptyState} from '../util/EmptyState' +import {ErrorMessage} from '../util/error/ErrorMessage' +import {Button} from '../util/forms/Button' +import {Text} from '../util/text/Text' +import * as Toast from '../util/Toast' + +export enum KnownError { + Block = 'Block', + FeedgenDoesNotExist = 'FeedgenDoesNotExist', + FeedgenMisconfigured = 'FeedgenMisconfigured', + FeedgenBadResponse = 'FeedgenBadResponse', + FeedgenOffline = 'FeedgenOffline', + FeedgenUnknown = 'FeedgenUnknown', + FeedSignedInOnly = 'FeedSignedInOnly', + FeedTooManyRequests = 'FeedTooManyRequests', + Unknown = 'Unknown', +} + +export function PostFeedErrorMessage({ + feedDesc, + error, + onPressTryAgain, + savedFeedConfig, +}: { + feedDesc: FeedDescriptor + error?: Error + onPressTryAgain: () => void + savedFeedConfig?: AppBskyActorDefs.SavedFeed +}) { + const {_: _l} = useLingui() + const knownError = React.useMemo( + () => detectKnownError(feedDesc, error), + [feedDesc, error], + ) + if ( + typeof knownError !== 'undefined' && + knownError !== KnownError.Unknown && + feedDesc.startsWith('feedgen') + ) { + return ( + + ) + } + + if (knownError === KnownError.Block) { + return ( + + ) + } + + return ( + + ) +} + +function FeedgenErrorMessage({ + feedDesc, + knownError, + rawError, + savedFeedConfig, +}: { + feedDesc: FeedDescriptor + knownError: KnownError + rawError?: Error + savedFeedConfig?: AppBskyActorDefs.SavedFeed +}) { + const pal = usePalette('default') + const {_: _l} = useLingui() + const navigation = useNavigation() + const msg = React.useMemo( + () => + ({ + [KnownError.Unknown]: '', + [KnownError.Block]: '', + [KnownError.FeedgenDoesNotExist]: _l( + msgLingui`Hmm, we're having trouble finding this feed. It may have been deleted.`, + ), + [KnownError.FeedgenMisconfigured]: _l( + msgLingui`Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue.`, + ), + [KnownError.FeedgenBadResponse]: _l( + msgLingui`Hmm, the feed server gave a bad response. Please let the feed owner know about this issue.`, + ), + [KnownError.FeedgenOffline]: _l( + msgLingui`Hmm, the feed server appears to be offline. Please let the feed owner know about this issue.`, + ), + [KnownError.FeedSignedInOnly]: _l( + msgLingui`This content is not viewable without a Bluesky account.`, + ), + [KnownError.FeedgenUnknown]: _l( + msgLingui`Hmm, some kind of issue occurred when contacting the feed server. Please let the feed owner know about this issue.`, + ), + [KnownError.FeedTooManyRequests]: _l( + msgLingui`This feed is currently receiving high traffic and is temporarily unavailable. Please try again later.`, + ), + }[knownError]), + [_l, knownError], + ) + const [_, uri] = feedDesc.split('|') + const [ownerDid] = safeParseFeedgenUri(uri) + const removePromptControl = Prompt.usePromptControl() + const {mutateAsync: removeFeed} = useRemoveFeedMutation() + + const onViewProfile = React.useCallback(() => { + navigation.navigate('Profile', {name: ownerDid}) + }, [navigation, ownerDid]) + + const onPressRemoveFeed = React.useCallback(() => { + removePromptControl.open() + }, [removePromptControl]) + + const onRemoveFeed = React.useCallback(async () => { + try { + if (!savedFeedConfig) return + await removeFeed(savedFeedConfig) + } catch (err) { + Toast.show( + _l( + msgLingui`There was an issue removing this feed. Please check your internet connection and try again.`, + ), + 'exclamation-circle', + ) + logger.error('Failed to remove feed', {message: err}) + } + }, [removeFeed, _l, savedFeedConfig]) + + const cta = React.useMemo(() => { + switch (knownError) { + case KnownError.FeedSignedInOnly: { + return null + } + case KnownError.FeedgenDoesNotExist: + case KnownError.FeedgenMisconfigured: + case KnownError.FeedgenBadResponse: + case KnownError.FeedgenOffline: + case KnownError.FeedgenUnknown: { + return ( + + {knownError === KnownError.FeedgenDoesNotExist && + savedFeedConfig && ( +