bsky-app/src/view/com/modals/report/ReasonOptions.tsx
Foysal Ahamed abbc6543f4
Repurpose report post modal and re-use for list reporting (#1070)
*  Repupose report post modal and re-use for list reporting

*  Allow reporting a feed generator

*  ♻️ Refactor report modal into one shared component for reporting different collections

*  Adjust report option selector in tests

*  Add test for list reporting

* ♻️  Refactor reason options and add options for list and feedgen

* 🧹 Cleanup remaining todo

* Fix to mutelist react keys

* Fix regression from rebase

* Improve customfeed mobile header

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2023-08-15 14:32:06 -07:00

123 lines
3.6 KiB
TypeScript

import {View} from 'react-native'
import React, {useMemo} from 'react'
import {AtUri, ComAtprotoModerationDefs} from '@atproto/api'
import {Text} from '../../util/text/Text'
import {UsePaletteValue, usePalette} from 'lib/hooks/usePalette'
import {RadioGroup, RadioGroupItem} from 'view/com/util/forms/RadioGroup'
import {CollectionId} from './types'
type ReasonMap = Record<string, {title: string; description: string}>
const CommonReasons = {
[ComAtprotoModerationDefs.REASONRUDE]: {
title: 'Anti-Social Behavior',
description: 'Harassment, trolling, or intolerance',
},
[ComAtprotoModerationDefs.REASONVIOLATION]: {
title: 'Illegal and Urgent',
description: 'Glaring violations of law or terms of service',
},
[ComAtprotoModerationDefs.REASONOTHER]: {
title: 'Other',
description: 'An issue not included in these options',
},
}
const CollectionToReasonsMap: Record<string, ReasonMap> = {
[CollectionId.Post]: {
[ComAtprotoModerationDefs.REASONSPAM]: {
title: 'Spam',
description: 'Excessive mentions or replies',
},
[ComAtprotoModerationDefs.REASONSEXUAL]: {
title: 'Unwanted Sexual Content',
description: 'Nudity or pornography not labeled as such',
},
__copyright__: {
title: 'Copyright Violation',
description: 'Contains copyrighted material',
},
...CommonReasons,
},
[CollectionId.List]: {
...CommonReasons,
[ComAtprotoModerationDefs.REASONVIOLATION]: {
title: 'Name or Description Violates Community Standards',
description: 'Terms used violate community standards',
},
},
}
const AccountReportReasons = {
[ComAtprotoModerationDefs.REASONMISLEADING]: {
title: 'Misleading Account',
description: 'Impersonation or false claims about identity or affiliation',
},
[ComAtprotoModerationDefs.REASONSPAM]: {
title: 'Frequently Posts Unwanted Content',
description: 'Spam; excessive mentions or replies',
},
[ComAtprotoModerationDefs.REASONVIOLATION]: {
title: 'Name or Description Violates Community Standards',
description: 'Terms used violate community standards',
},
}
const Option = ({
pal,
title,
description,
}: {
pal: UsePaletteValue
description: string
title: string
}) => {
return (
<View>
<Text style={pal.text} type="md-bold">
{title}
</Text>
<Text style={pal.textLight}>{description}</Text>
</View>
)
}
// This is mostly just content copy without almost any logic
// so this may grow over time and it makes sense to split it up into its own file
// to keep it separate from the actual reporting modal logic
const useReportRadioOptions = (pal: UsePaletteValue, atUri: AtUri | null) =>
useMemo(() => {
let items: ReasonMap = {...CommonReasons}
// If no atUri is passed, that means the reporting collection is account
if (!atUri) {
items = {...AccountReportReasons}
}
if (atUri?.collection && CollectionToReasonsMap[atUri.collection]) {
items = {...CollectionToReasonsMap[atUri.collection]}
}
return Object.entries(items).map(([key, {title, description}]) => ({
key,
label: <Option pal={pal} title={title} description={description} />,
}))
}, [pal, atUri])
export const ReportReasonOptions = ({
atUri,
selectedIssue,
onSelectIssue,
}: {
atUri: AtUri | null
selectedIssue?: string
onSelectIssue: (key: string) => void
}) => {
const pal = usePalette('default')
const ITEMS: RadioGroupItem[] = useReportRadioOptions(pal, atUri)
return (
<RadioGroup
items={ITEMS}
onSelect={onSelectIssue}
testID="reportReasonRadios"
initialSelection={selectedIssue}
/>
)
}