From 5998b34471a9b75495a8586c23e284901dfdabfb Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 7 Feb 2024 14:53:21 -0600 Subject: [PATCH] Not found state --- src/Navigation.tsx | 2 +- src/alf/atoms.ts | 7 + .../ProfileModerationService/index.tsx | 302 ++++++++++++++++++ 3 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 src/screens/ProfileModerationService/index.tsx diff --git a/src/Navigation.tsx b/src/Navigation.tsx index d57d6a2167..e03b78a2ce 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -56,7 +56,7 @@ import {ProfileFollowersScreen} from './view/screens/ProfileFollowers' import {ProfileFollowsScreen} from './view/screens/ProfileFollows' import {ProfileFeedScreen} from './view/screens/ProfileFeed' import {ProfileFeedLikedByScreen} from './view/screens/ProfileFeedLikedBy' -import {ProfileModserviceScreen} from './view/screens/ProfileModservice' +import {ProfileModserviceScreen} from '#/screens/ProfileModerationService' import {ProfileListScreen} from './view/screens/ProfileList' import {PostThreadScreen} from './view/screens/PostThread' import {PostLikedByScreen} from './view/screens/PostLikedBy' diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index bbf7e32431..a86f8ae7f4 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -208,6 +208,13 @@ export const atoms = { border_b: { borderBottomWidth: 1, }, + border_l: { + borderLeftWidth: 1, + }, + border_r: { + borderRightWidth: 1, + }, + /* * Shadow diff --git a/src/screens/ProfileModerationService/index.tsx b/src/screens/ProfileModerationService/index.tsx new file mode 100644 index 0000000000..a07d4672a9 --- /dev/null +++ b/src/screens/ProfileModerationService/index.tsx @@ -0,0 +1,302 @@ +import React, {useMemo, useCallback} from 'react' +import {Dimensions, StyleSheet, View, ActivityIndicator} from 'react-native' +import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {useIsFocused, useNavigation} from '@react-navigation/native' +import {AppBskyModerationDefs, RichText as RichTextAPI} from '@atproto/api' +import {usePalette} from 'lib/hooks/usePalette' +import {HeartIcon, HeartIconSolid} from 'lib/icons' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {CommonNavigatorParams} from 'lib/routes/types' +import {makeRecordUri} from 'lib/strings/url-helpers' +import {s} from 'lib/styles' +import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader' +import {TextLink} from 'view/com/util/Link' +import {Button as OldButton} from 'view/com/util/forms/Button' +import {Text as RNText} from 'view/com/util/text/Text' +import {RichText} from 'view/com/util/text/RichText' +import {ModServicePrefs} from '#/view/com/moderation/ModServicePrefs' +import * as Toast from 'view/com/util/Toast' +import {useSetTitle} from 'lib/hooks/useSetTitle' +import {Haptics} from 'lib/haptics' +import {useAnalytics} from 'lib/analytics/analytics' +import {makeCustomFeedLink} from 'lib/routes/links' +import {pluralize} from 'lib/strings/helpers' +import {CenteredView, ScrollView} from 'view/com/util/Views' +import {NavigationProp} from 'lib/routes/types' +import {makeProfileLink} from 'lib/routes/links' +import {logger} from '#/logger' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useModalControls} from '#/state/modals' +import {useModServiceInfoQuery} from '#/state/queries/modservice' +import {useResolveDidQuery} from '#/state/queries/resolve-uri' +import { + UsePreferencesQueryResponse, + usePreferencesQuery, +} from '#/state/queries/preferences' +import {useSession} from '#/state/session' +import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like' +import {ModServiceHeader} from '#/view/com/moderation/ModServiceHeader' +import {sanitizeHandle} from '#/lib/strings/handles' + +import { useTheme, atoms as a } from '#/alf' +import {Text} from '#/components/Typography' +import {Button, ButtonText} from '#/components/Button' +import { CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' + +// TODO +const MIN_HEIGHT = Dimensions.get('window').height * 1.5 + +type Props = NativeStackScreenProps +export function ProfileModserviceScreen(props: Props) { + const t = useTheme() + const {name: handleOrDid} = props.route.params + + const pal = usePalette('default') + const {_} = useLingui() + const navigation = useNavigation() + + const {error, data: resolvedDid} = useResolveDidQuery(handleOrDid) + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + if (error) { + return ( + + + + + + Hmmmm, we couldn't load that moderation service. + + + This moderation service is unavailable. See below for more details. If this issue persists, contact us. + + + + Error: {error.toString()} + + + + + + + + + ) + } + + return resolvedDid ? ( + + ) : ( + + + + + + ) +} + +function ProfileModservicecreenIntermediate({modDid}: {modDid: string}) { + const {data: preferences} = usePreferencesQuery() + const {data: info} = useModServiceInfoQuery({did: modDid}) + + if (!preferences || !info) { + return ( + + + + + + ) + } + + return ( + + ) +} + +export function ProfileModserviceScreenInner({ + preferences, + modInfo, +}: { + preferences: UsePreferencesQueryResponse + modInfo: AppBskyModerationDefs.ModServiceViewDetailed +}) { + const {_} = useLingui() + const pal = usePalette('default') + const {hasSession} = useSession() + const {track} = useAnalytics() + const {mutateAsync: likeMod, isPending: isLikePending} = useLikeMutation() + const {mutateAsync: unlikeMod, isPending: isUnlikePending} = + useUnlikeMutation() + const [likeUri, setLikeUri] = React.useState( + modInfo.viewer?.like || '', + ) + + const isLiked = !!likeUri + const isSaved = false // TODO + // !removedFeed && + // (!!savedFeed || preferences.feeds.saved.includes(feedInfo.uri)) + const isEnabled = false // TODO + // !unpinnedFeed && + // (!!pinnedFeed || preferences.feeds.pinned.includes(feedInfo.uri)) + + const descriptionRT = useMemo( + () => + modInfo.description + ? new RichTextAPI({ + text: modInfo.description, + facets: modInfo.descriptionFacets, + }) + : undefined, + [modInfo], + ) + + useSetTitle(modInfo.creator.displayName || modInfo.creator.handle) + + // event handlers + // + const onToggleLiked = React.useCallback(async () => { + try { + Haptics.default() + + if (isLiked && likeUri) { + await unlikeMod({uri: likeUri}) + track('CustomFeed:Unlike') + setLikeUri('') + } else { + const res = await likeMod({uri: modInfo.uri, cid: modInfo.cid}) + track('CustomFeed:Like') + setLikeUri(res.uri) + } + } catch (err) { + Toast.show( + _( + msg`There was an an issue contacting the server, please check your internet connection and try again.`, + ), + ) + logger.error('Failed up toggle like', {error: err}) + } + }, [likeUri, isLiked, modInfo, likeMod, unlikeMod, track, _]) + + // render + // = + + return ( + + + + + {descriptionRT ? ( + + ) : ( + + No description + + )} + + + Operated by{' '} + + . Handles reports of anti-social behavior, illegal content, + unwanted sexual content, and misinformation. + + + + + + {isLiked ? ( + + ) : ( + + )} + + {typeof modInfo.likeCount === 'number' && ( + + )} + + + + + + + ) +} + +const styles = StyleSheet.create({ + btn: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + paddingVertical: 7, + paddingHorizontal: 14, + borderRadius: 50, + marginLeft: 6, + }, + notFoundContainer: { + margin: 10, + paddingHorizontal: 18, + paddingVertical: 14, + borderRadius: 6, + }, +})