Update ReportDialog

This commit is contained in:
Eric Bailey
2024-02-26 18:10:46 -06:00
parent 67fea6d317
commit 304b6f4f00
5 changed files with 112 additions and 98 deletions
@@ -7,7 +7,6 @@ import {AppBskyModerationDefs, LabelGroupDefinition} from '@atproto/api'
import {atoms as a, useTheme, tokens, native} from '#/alf' import {atoms as a, useTheme, tokens, native} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
import {GlobalDialogProps} from '#/components/dialogs'
import { import {
Button, Button,
ButtonIcon, ButtonIcon,
@@ -35,22 +34,27 @@ import {
useConfigurableProfileLabelGroups, useConfigurableProfileLabelGroups,
getLabelGroupToLabelerMap, getLabelGroupToLabelerMap,
} from '#/lib/moderation' } from '#/lib/moderation'
import {DMCA_LINK} from '#/components/dialogs/ReportDialog/const' import {DMCA_LINK} from '#/components/ReportDialog/const'
import {Link} from '#/components/Link' import {Link} from '#/components/Link'
import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from '#/components/icons/SquareArrowTopRight' import {SquareArrowTopRight_Stroke2_Corner0_Rounded as SquareArrowTopRight} from '#/components/icons/SquareArrowTopRight'
// import {getAgent} from '#/state/session' // import {getAgent} from '#/state/session'
export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
export type ReportDialogLabelIds = LabelGroupDefinition['id'] | 'other' export type ReportDialogLabelIds = LabelGroupDefinition['id'] | 'other'
export type ReportDialogProps = export type ReportDialogProps = {
| { control: Dialog.DialogOuterProps['control']
type: 'content' params:
uri: string | {
cid: string type: 'content'
} uri: string
| { cid: string
type: 'profile' }
did: string | {
} type: 'profile'
did: string
}
}
function LabelGroupButton({ function LabelGroupButton({
name, name,
@@ -162,8 +166,7 @@ function SubmitView({
goBack, goBack,
onSubmitComplete, onSubmitComplete,
labelGroupToLabelerMap, labelGroupToLabelerMap,
}: { }: ReportDialogProps & {
params: ReportDialogProps
selectedLabelGroup: ReportDialogLabelIds selectedLabelGroup: ReportDialogLabelIds
goBack: () => void goBack: () => void
onSubmitComplete: () => void onSubmitComplete: () => void
@@ -287,7 +290,6 @@ function SubmitView({
label="Text field" label="Text field"
style={{paddingRight: 60}} style={{paddingRight: 60}}
numberOfLines={6} numberOfLines={6}
disabled={!supportedLabelers}
/> />
<View <View
@@ -335,11 +337,10 @@ function SubmitView({
) )
} }
export function ReportDialogInner({ export function ReportDialogLoaded({
params,
labelGroupToLabelerMap, labelGroupToLabelerMap,
}: { ...props
params: ReportDialogProps }: ReportDialogProps & {
labelers: AppBskyModerationDefs.ModServiceViewDetailed[] labelers: AppBskyModerationDefs.ModServiceViewDetailed[]
labelGroupToLabelerMap: ReturnType<typeof getLabelGroupToLabelerMap> labelGroupToLabelerMap: ReturnType<typeof getLabelGroupToLabelerMap>
}) { }) {
@@ -352,7 +353,7 @@ export function ReportDialogInner({
const labelGroupStrings = useLabelGroupStrings() const labelGroupStrings = useLabelGroupStrings()
const contentGroups = useConfigurableContentLabelGroups() const contentGroups = useConfigurableContentLabelGroups()
const profileGroups = useConfigurableProfileLabelGroups() const profileGroups = useConfigurableProfileLabelGroups()
const groups = params.type === 'content' ? contentGroups : profileGroups const groups = props.params.type === 'content' ? contentGroups : profileGroups
const filteredGroups = groups.filter(group => { const filteredGroups = groups.filter(group => {
return Boolean(labelGroupToLabelerMap[group.id]) return Boolean(labelGroupToLabelerMap[group.id])
}) })
@@ -361,7 +362,7 @@ export function ReportDialogInner({
let title = _(msg`Report this post`) let title = _(msg`Report this post`)
let description = _(msg`Why should this post be reviewed?`) let description = _(msg`Why should this post be reviewed?`)
if (params.type === 'profile') { if (props.params.type === 'profile') {
title = _(msg`Report this user`) title = _(msg`Report this user`)
description = _(msg`Why should this user be reviewed?`) description = _(msg`Why should this user be reviewed?`)
} }
@@ -370,7 +371,7 @@ export function ReportDialogInner({
title, title,
description, description,
} }
}, [_, params.type]) }, [_, props.params.type])
const next = React.useCallback( const next = React.useCallback(
(group: ReportDialogLabelIds | 'copyright') => { (group: ReportDialogLabelIds | 'copyright') => {
@@ -387,8 +388,8 @@ export function ReportDialogInner({
<> <>
{selectedLabelGroup ? ( {selectedLabelGroup ? (
<SubmitView <SubmitView
{...props}
labelGroupToLabelerMap={labelGroupToLabelerMap} labelGroupToLabelerMap={labelGroupToLabelerMap}
params={params}
selectedLabelGroup={selectedLabelGroup} selectedLabelGroup={selectedLabelGroup}
goBack={() => setSelectedLabelGroup(undefined)} goBack={() => setSelectedLabelGroup(undefined)}
onSubmitComplete={control.close} onSubmitComplete={control.close}
@@ -429,7 +430,7 @@ export function ReportDialogInner({
/> />
</Button> </Button>
{params.type === 'content' && ( {props.params.type === 'content' && (
<View style={[a.pt_md, a.px_md]}> <View style={[a.pt_md, a.px_md]}>
<View <View
style={[ style={[
@@ -472,14 +473,7 @@ export function ReportDialogInner({
) )
} }
export function ReportDialog({ function ReportDialogInner(props: ReportDialogProps) {
params,
cleanup,
}: GlobalDialogProps<ReportDialogProps>) {
// REQUIRED CLEANUP
const onClose = React.useCallback(() => cleanup(), [cleanup])
const control = Dialog.useDialogControl()
const { const {
isLoading: isPreferencesLoading, isLoading: isPreferencesLoading,
error: preferencesError, error: preferencesError,
@@ -505,24 +499,22 @@ export function ReportDialog({
<Loader /> <Loader />
</View> </View>
) : error || !(preferences && modservices) ? null : ( // TODO ) : error || !(preferences && modservices) ? null : ( // TODO
<Dialog.Outer <Dialog.ScrollableInner label="Report Dialog">
defaultOpen <ReportDialogLoaded
control={control} {...props}
onClose={onClose} labelers={modservices}
nativeOptions={{ labelGroupToLabelerMap={labelGroupToLabelerMap}
sheet: { />
snapPoints: ['100%'], </Dialog.ScrollableInner>
}, )
}}> }
export function ReportDialog(props: ReportDialogProps) {
return (
<Dialog.Outer control={props.control}>
<Dialog.Handle /> <Dialog.Handle />
<Dialog.ScrollableInner label="Report Dialog"> <ReportDialogInner {...props} />
<ReportDialogInner
params={params}
labelers={modservices}
labelGroupToLabelerMap={labelGroupToLabelerMap}
/>
</Dialog.ScrollableInner>
</Dialog.Outer> </Dialog.Outer>
) )
} }
+34 -26
View File
@@ -24,8 +24,7 @@ import {NEW_REPORT_DIALOG_ENABLED} from '#/lib/build-flags'
import {atoms as a, useTheme, tokens} from '#/alf' import {atoms as a, useTheme, tokens} from '#/alf'
import * as Toast from 'view/com/util/Toast' import * as Toast from 'view/com/util/Toast'
import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown' import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown'
import {useOpenGlobalDialog} from '#/components/dialogs' import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {ReportDialog} from '#/components/dialogs/ReportDialog'
import {DotGrid1x3Horizontal_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid' import {DotGrid1x3Horizontal_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/DotGrid'
export function ProfileHeaderDropdownBtn({ export function ProfileHeaderDropdownBtn({
@@ -41,7 +40,7 @@ export function ProfileHeaderDropdownBtn({
const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile)
const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile)
const queryClient = useQueryClient() const queryClient = useQueryClient()
const openDialog = useOpenGlobalDialog() const control = useReportDialogControl()
const invalidateProfileQuery = React.useCallback(() => { const invalidateProfileQuery = React.useCallback(() => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
@@ -139,14 +138,14 @@ export function ProfileHeaderDropdownBtn({
const onPressReportAccount = React.useCallback(() => { const onPressReportAccount = React.useCallback(() => {
track('ProfileHeader:ReportAccountButtonClicked') track('ProfileHeader:ReportAccountButtonClicked')
if (NEW_REPORT_DIALOG_ENABLED) { if (NEW_REPORT_DIALOG_ENABLED) {
openDialog(ReportDialog, {type: 'profile', did: profile.did}) control.open()
} else { } else {
openModal({ openModal({
name: 'report', name: 'report',
did: profile.did, did: profile.did,
}) })
} }
}, [track, openModal, profile, openDialog]) }, [track, openModal, profile, control])
const isMe = React.useMemo( const isMe = React.useMemo(
() => currentAccount?.did === profile.did, () => currentAccount?.did === profile.did,
@@ -256,26 +255,35 @@ export function ProfileHeaderDropdownBtn({
]) ])
return dropdownItems?.length ? ( return dropdownItems?.length ? (
<NativeDropdown <>
testID="profileHeaderDropdownBtn" <ReportDialog
items={dropdownItems} control={control}
accessibilityLabel={_(msg`More options`)} params={{type: 'profile', did: profile.did}}
accessibilityHint=""> />
<View
style={[ <NativeDropdown
{ testID="profileHeaderDropdownBtn"
height: 40, items={dropdownItems}
width: 40, accessibilityLabel={_(msg`More options`)}
backgroundColor: accessibilityHint="">
t.name === 'light' ? tokens.color.gray_50 : tokens.color.gray_900, <View
}, style={[
a.flex_row, {
a.align_center, height: 40,
a.justify_center, width: 40,
a.rounded_full, backgroundColor:
]}> t.name === 'light'
<Ellipsis width={20} fill={t.atoms.text_contrast_medium.color} /> ? tokens.color.gray_50
</View> : tokens.color.gray_900,
</NativeDropdown> },
a.flex_row,
a.align_center,
a.justify_center,
a.rounded_full,
]}>
<Ellipsis width={20} fill={t.atoms.text_contrast_medium.color} />
</View>
</NativeDropdown>
</>
) : null ) : null
} }
+9 -5
View File
@@ -56,8 +56,7 @@ import {Shadow} from '#/state/cache/types'
import {useRequireAuth} from '#/state/session' import {useRequireAuth} from '#/state/session'
import {LabelsOnMe} from '../util/moderation/LabelsOnMe' import {LabelsOnMe} from '../util/moderation/LabelsOnMe'
import {useProfileShadow} from 'state/cache/profile-shadow' import {useProfileShadow} from 'state/cache/profile-shadow'
import {useOpenGlobalDialog} from '#/components/dialogs' import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {ReportDialog} from '#/components/dialogs/ReportDialog'
import {NEW_REPORT_DIALOG_ENABLED} from '#/lib/build-flags' import {NEW_REPORT_DIALOG_ENABLED} from '#/lib/build-flags'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
@@ -118,7 +117,7 @@ let ProfileHeader = ({
() => moderateProfile(profile, moderationOpts), () => moderateProfile(profile, moderationOpts),
[profile, moderationOpts], [profile, moderationOpts],
) )
const openDialog = useOpenGlobalDialog() const control = useReportDialogControl()
const invalidateProfileQuery = React.useCallback(() => { const invalidateProfileQuery = React.useCallback(() => {
queryClient.invalidateQueries({ queryClient.invalidateQueries({
@@ -281,14 +280,14 @@ let ProfileHeader = ({
const onPressReportAccount = React.useCallback(() => { const onPressReportAccount = React.useCallback(() => {
track('ProfileHeader:ReportAccountButtonClicked') track('ProfileHeader:ReportAccountButtonClicked')
if (NEW_REPORT_DIALOG_ENABLED) { if (NEW_REPORT_DIALOG_ENABLED) {
openDialog(ReportDialog, {type: 'profile', did: profile.did}) control.open()
} else { } else {
openModal({ openModal({
name: 'report', name: 'report',
did: profile.did, did: profile.did,
}) })
} }
}, [track, openModal, profile, openDialog]) }, [track, openModal, profile, control])
const isMe = React.useMemo( const isMe = React.useMemo(
() => currentAccount?.did === profile.did, () => currentAccount?.did === profile.did,
@@ -402,6 +401,11 @@ let ProfileHeader = ({
return ( return (
<View style={[pal.view]} pointerEvents="box-none"> <View style={[pal.view]} pointerEvents="box-none">
<ReportDialog
control={control}
params={{type: 'profile', did: profile.did}}
/>
<View pointerEvents="none"> <View pointerEvents="none">
{isPlaceholderProfile ? ( {isPlaceholderProfile ? (
<LoadingPlaceholder <LoadingPlaceholder
+29 -19
View File
@@ -34,8 +34,7 @@ import {useLingui} from '@lingui/react'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {isWeb} from '#/platform/detection' import {isWeb} from '#/platform/detection'
import {richTextToString} from '#/lib/strings/rich-text-helpers' import {richTextToString} from '#/lib/strings/rich-text-helpers'
import {useOpenGlobalDialog} from '#/components/dialogs' import {ReportDialog, useReportDialogControl} from '#/components/ReportDialog'
import {ReportDialog} from '#/components/dialogs/ReportDialog'
import {NEW_REPORT_DIALOG_ENABLED} from '#/lib/build-flags' import {NEW_REPORT_DIALOG_ENABLED} from '#/lib/build-flags'
let PostDropdownBtn = ({ let PostDropdownBtn = ({
@@ -67,7 +66,7 @@ let PostDropdownBtn = ({
const hiddenPosts = useHiddenPosts() const hiddenPosts = useHiddenPosts()
const {hidePost} = useHiddenPostsApi() const {hidePost} = useHiddenPostsApi()
const openLink = useOpenLink() const openLink = useOpenLink()
const openDialog = useOpenGlobalDialog() const control = useReportDialogControl()
const navigation = useNavigation() const navigation = useNavigation()
const rootUri = record.reply?.root?.uri || postUri const rootUri = record.reply?.root?.uri || postUri
@@ -241,11 +240,7 @@ let PostDropdownBtn = ({
label: _(msg`Report post`), label: _(msg`Report post`),
onPress() { onPress() {
if (NEW_REPORT_DIALOG_ENABLED) { if (NEW_REPORT_DIALOG_ENABLED) {
openDialog(ReportDialog, { control.open()
type: 'content',
uri: postUri,
cid: postCid,
})
} else { } else {
openModal({ openModal({
name: 'report', name: 'report',
@@ -285,17 +280,32 @@ let PostDropdownBtn = ({
].filter(Boolean) as NativeDropdownItem[] ].filter(Boolean) as NativeDropdownItem[]
return ( return (
<EventStopper> <>
<NativeDropdown <ReportDialog
testID={testID} control={control}
items={dropdownItems} params={{
accessibilityLabel={_(msg`More post options`)} type: 'content',
accessibilityHint=""> uri: postUri,
<View style={style}> cid: postCid,
<FontAwesomeIcon icon="ellipsis" size={20} color={defaultCtrlColor} /> }}
</View> />
</NativeDropdown>
</EventStopper> <EventStopper>
<NativeDropdown
testID={testID}
items={dropdownItems}
accessibilityLabel={_(msg`More post options`)}
accessibilityHint="">
<View style={style}>
<FontAwesomeIcon
icon="ellipsis"
size={20}
color={defaultCtrlColor}
/>
</View>
</NativeDropdown>
</EventStopper>
</>
) )
} }