From af5b545e255ec99da5907989bc7df92cdcfed8a9 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 7 Feb 2024 16:59:27 -0600 Subject: [PATCH] Reorg, add icon --- ...ingHand4Finger_stroke2_corner0_rounded.svg | 1 + src/components/icons/RaisingHand.tsx | 5 + .../ProfileModerationService/ErrorState.tsx | 72 ++++++ .../ProfileModerationService/Header.tsx | 232 ++++++++++++++++++ .../ProfileModerationService/index.tsx | 142 +++++------ 5 files changed, 374 insertions(+), 78 deletions(-) create mode 100644 assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg create mode 100644 src/components/icons/RaisingHand.tsx create mode 100644 src/screens/ProfileModerationService/ErrorState.tsx create mode 100644 src/screens/ProfileModerationService/Header.tsx diff --git a/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg b/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..aed3d9e7ec --- /dev/null +++ b/assets/icons/raisingHand4Finger_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/src/components/icons/RaisingHand.tsx b/src/components/icons/RaisingHand.tsx new file mode 100644 index 0000000000..cd023cb7ef --- /dev/null +++ b/src/components/icons/RaisingHand.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const RaisingHande4Finger_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M10.25 4a.75.75 0 0 0-.75.75V11a1 1 0 1 1-2 0V6.75a.75.75 0 0 0-1.5 0V14a6 6 0 0 0 12 0V9a2 2 0 0 0-2 2v1.5a1 1 0 0 1-.684.949l-.628.21A2.469 2.469 0 0 0 13 16a1 1 0 1 1-2 0 4.469 4.469 0 0 1 3-4.22V11c0-.703.181-1.364.5-1.938V5.75a.75.75 0 0 0-1.5 0V9a1 1 0 1 1-2 0V4.75a.75.75 0 0 0-.75-.75Zm2.316-.733A2.75 2.75 0 0 1 16.5 5.75v1.54c.463-.187.97-.29 1.5-.29h1a1 1 0 0 1 1 1v6a8 8 0 1 1-16 0V6.75a2.75 2.75 0 0 1 3.571-2.625 2.751 2.751 0 0 1 4.995-.858Z', +}) diff --git a/src/screens/ProfileModerationService/ErrorState.tsx b/src/screens/ProfileModerationService/ErrorState.tsx new file mode 100644 index 0000000000..b421d20c36 --- /dev/null +++ b/src/screens/ProfileModerationService/ErrorState.tsx @@ -0,0 +1,72 @@ +import React from 'react' +import {View} from 'react-native' +import {Trans, msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useNavigation} from '@react-navigation/native' + +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' +import {NavigationProp} from '#/lib/routes/types' + +export function ErrorState({error}: {error: string}) { + const t = useTheme() + const {_} = useLingui() + const navigation = useNavigation() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + 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} + + + + + + + ) +} diff --git a/src/screens/ProfileModerationService/Header.tsx b/src/screens/ProfileModerationService/Header.tsx new file mode 100644 index 0000000000..2dac57b3c4 --- /dev/null +++ b/src/screens/ProfileModerationService/Header.tsx @@ -0,0 +1,232 @@ +import React from 'react' +import {Pressable, StyleSheet, View} from 'react-native' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {useNavigation} from '@react-navigation/native' +import {usePalette} from 'lib/hooks/usePalette' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {Text as OldText} from '#/view/com/util/text/Text' +import {TextLink} from '#/view/com/util/Link' +import {CenteredView} from '#/view/com/util/Views' +import {sanitizeHandle} from 'lib/strings/handles' +import {makeProfileLink} from 'lib/routes/links' +import {NavigationProp} from 'lib/routes/types' +import {BACK_HITSLOP} from 'lib/constants' +import {isNative} from 'platform/detection' +import {useLingui} from '@lingui/react' +import {Trans, msg} from '@lingui/macro' +import {useSetDrawerOpen} from '#/state/shell' +import {emitSoftReset} from '#/state/events' +import {AppBskyModerationDefs} from '@atproto/api' +import {HandIcon} from '#/lib/icons' +import {shareUrl} from 'lib/sharing' +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {Button as OldButton} from '#/view/com/util/forms/Button' +import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown' +import {useSession} from '#/state/session' +import {useModalControls} from '#/state/modals' + +import { useTheme, atoms as a } from '#/alf' +import {Text} from '#/components/Typography' +import {Button, ButtonText} from '#/components/Button' +import {RaisingHande4Finger_Stroke2_Corner0_Rounded as RaisingHand} from '#/components/icons/RaisingHand' + +export function Header({ + info, +}: { + info: AppBskyModerationDefs.ModServiceViewDetailed +}) { + const setDrawerOpen = useSetDrawerOpen() + const navigation = useNavigation() + const {_} = useLingui() + const {isMobile} = useWebMediaQueries() + const pal = usePalette('default') + const canGoBack = navigation.canGoBack() + + const onPressBack = React.useCallback(() => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Home') + } + }, [navigation]) + + const onPressMenu = React.useCallback(() => { + setDrawerOpen(true) + }, [setDrawerOpen]) + + return ( + + {isMobile && ( + + + {canGoBack ? ( + + ) : ( + + )} + + + + + )} + + + + + + + + Moderation service + + + + + {!isMobile && } + + + + ) +} + +function CommonControls({ + info, +}: { + info: AppBskyModerationDefs.ModServiceViewDetailed +}) { + const pal = usePalette('default') + const {hasSession} = useSession() + const {openModal} = useModalControls() + const {_} = useLingui() + + const onPressShare = React.useCallback(() => { + const url = makeProfileLink(info.creator, 'modservice') + shareUrl(url) + // track('CustomFeed:Share') TODO + }, [info /*, track*/]) + + const onPressReport = React.useCallback(() => { + if (!info) return + openModal({ + name: 'report', + uri: info.uri, + cid: info.cid, + }) + }, [openModal, info]) + + const dropdownItems: DropdownItem[] = React.useMemo(() => { + return [ + hasSession && { + testID: 'modHeaderDropdownReportBtn', + label: _(msg`Report mod service`), + onPress: onPressReport, + icon: { + ios: { + name: 'exclamationmark.triangle', + }, + android: 'ic_menu_report_image', + web: 'circle-exclamation', + }, + }, + { + testID: 'modHeaderDropdownShareBtn', + label: _(msg`Share mod service`), + onPress: onPressShare, + icon: { + ios: { + name: 'square.and.arrow.up', + }, + android: 'ic_menu_share', + web: 'share', + }, + }, + ].filter(Boolean) as DropdownItem[] + }, [hasSession, onPressReport, onPressShare, _]) + + return ( + <> + + + + + + + ) +} + +const styles = StyleSheet.create({ + backBtn: { + width: 20, + height: 30, + }, + backBtnWide: { + width: 20, + height: 30, + paddingHorizontal: 6, + }, + backIcon: { + marginTop: 6, + }, + btn: { + flexDirection: 'row', + alignItems: 'center', + gap: 6, + paddingVertical: 7, + paddingHorizontal: 14, + borderRadius: 50, + }, +}) + diff --git a/src/screens/ProfileModerationService/index.tsx b/src/screens/ProfileModerationService/index.tsx index a07d4672a9..b8ce5f807e 100644 --- a/src/screens/ProfileModerationService/index.tsx +++ b/src/screens/ProfileModerationService/index.tsx @@ -36,104 +36,90 @@ import { } 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 {useTheme, atoms as a} from '#/alf' import {Text} from '#/components/Typography' +import {Loader} from '#/components/Loader' import {Button, ButtonText} from '#/components/Button' -import { CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' + +import {ErrorState} from '#/screens/ProfileModerationService/ErrorState' +import {Header} from '#/screens/ProfileModerationService/Header' // TODO const MIN_HEIGHT = Dimensions.get('window').height * 1.5 +// TODO loader default color -type Props = NativeStackScreenProps -export function ProfileModserviceScreen(props: Props) { +export function ProfileModserviceScreen( + props: NativeStackScreenProps, +) { const t = useTheme() - const {name: handleOrDid} = props.route.params - - const pal = usePalette('default') const {_} = useLingui() - const navigation = useNavigation() + const {name: handleOrDid} = props.route.params + const {isLoading, error, data: resolvedDid} = useResolveDidQuery(handleOrDid) - 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 ? ( - - ) : ( + return ( - - + + {isLoading ? ( + + + + ) : resolvedDid ? ( + + ) : ( + + )} ) } function ProfileModservicecreenIntermediate({modDid}: {modDid: string}) { - const {data: preferences} = usePreferencesQuery() - const {data: info} = useModServiceInfoQuery({did: modDid}) + const t = useTheme() + const {_} = useLingui() + const { + isLoading: isPreferencesLoading, + error: preferencesError, + data: preferences, + } = usePreferencesQuery() + const { + isLoading: isModServiceLoading, + error: modServiceError, + data: info, + } = useModServiceInfoQuery({did: modDid}) - if (!preferences || !info) { - return ( - - - - - - ) - } + const isLoading = isPreferencesLoading || isModServiceLoading + const error = preferencesError || modServiceError - return ( + return isLoading ? ( + + + + ) : preferences && info ? ( + ) : ( + ) } @@ -211,7 +197,7 @@ export function ProfileModserviceScreenInner({ contentContainerStyle={{ minHeight: Dimensions.get('window').height * 1.5, }}> - +