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 {cleanError} from '#/lib/strings/errors' import {logger} from '#/logger' import {FeedDescriptor} from '#/state/queries/post-feed' import {useRemoveFeedMutation} from '#/state/queries/preferences' import {usePalette} from 'lib/hooks/usePalette' import {NavigationProp} from 'lib/routes/types' 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', FeedNSFPublic = 'FeedNSFPublic', FeedTooManyRequests = 'FeedTooManyRequests', Unknown = 'Unknown', } export function FeedErrorMessage({ 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.FeedNSFPublic]: _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 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.FeedNSFPublic: { return null } case KnownError.FeedgenDoesNotExist: case KnownError.FeedgenMisconfigured: case KnownError.FeedgenBadResponse: case KnownError.FeedgenOffline: case KnownError.FeedgenUnknown: { return ( {knownError === KnownError.FeedgenDoesNotExist && savedFeedConfig && (