about summary refs log tree commit diff
path: root/src/view/com/modals/ReportPost.tsx
blob: 01a132af098d7795ac2a70ac1faf1742fd3e2ee6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import React, {useState} from 'react'
import {
  ActivityIndicator,
  StyleSheet,
  TouchableOpacity,
  View,
} from 'react-native'
import {ComAtprotoModerationDefs} from '@atproto/api'
import LinearGradient from 'react-native-linear-gradient'
import {useStores} from 'state/index'
import {s, colors, gradients} from 'lib/styles'
import {RadioGroup, RadioGroupItem} from '../util/forms/RadioGroup'
import {Text} from '../util/text/Text'
import * as Toast from '../util/Toast'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {cleanError} from 'lib/strings/errors'
import {usePalette} from 'lib/hooks/usePalette'

const ITEMS: RadioGroupItem[] = [
  {key: 'spam', label: 'Spam or excessive repeat posts'},
  {key: 'abuse', label: 'Abusive, rude, or hateful'},
  {key: 'copyright', label: 'Contains copyrighted material'},
  {key: 'illegal', label: 'Contains illegal content'},
]

export const snapPoints = ['50%']

export function Component({
  postUri,
  postCid,
}: {
  postUri: string
  postCid: string
}) {
  const store = useStores()
  const pal = usePalette('default')
  const [isProcessing, setIsProcessing] = useState<boolean>(false)
  const [error, setError] = useState<string>('')
  const [issue, setIssue] = useState<string>('')
  const onSelectIssue = (v: string) => setIssue(v)
  const onPress = async () => {
    setError('')
    if (!issue) {
      return
    }
    setIsProcessing(true)
    try {
      // NOTE: we should update the lexicon of reasontype to include more options -prf
      let reasonType = ComAtprotoModerationDefs.REASONOTHER
      if (issue === 'spam') {
        reasonType = ComAtprotoModerationDefs.REASONSPAM
      }
      const reason = ITEMS.find(item => item.key === issue)?.label || ''
      await store.agent.createModerationReport({
        reasonType,
        reason,
        subject: {
          $type: 'com.atproto.repo.strongRef',
          uri: postUri,
          cid: postCid,
        },
      })
      Toast.show("Thank you for your report! We'll look into it promptly.")
      store.shell.closeModal()
      return
    } catch (e: any) {
      setError(cleanError(e))
      setIsProcessing(false)
    }
  }
  return (
    <View testID="reportPostModal" style={[s.flex1, s.pl10, s.pr10, pal.view]}>
      <Text style={[pal.text, styles.title]}>Report post</Text>
      <Text style={[pal.textLight, styles.description]}>
        What is the issue with this post?
      </Text>
      <RadioGroup
        testID="reportPostRadios"
        items={ITEMS}
        onSelect={onSelectIssue}
      />
      {error ? (
        <View style={s.mt10}>
          <ErrorMessage message={error} />
        </View>
      ) : undefined}
      {isProcessing ? (
        <View style={[styles.btn, s.mt10]}>
          <ActivityIndicator />
        </View>
      ) : issue ? (
        <TouchableOpacity
          testID="sendReportBtn"
          style={s.mt10}
          onPress={onPress}>
          <LinearGradient
            colors={[gradients.blueLight.start, gradients.blueLight.end]}
            start={{x: 0, y: 0}}
            end={{x: 1, y: 1}}
            style={[styles.btn]}>
            <Text style={[s.white, s.bold, s.f18]}>Send Report</Text>
          </LinearGradient>
        </TouchableOpacity>
      ) : undefined}
    </View>
  )
}

const styles = StyleSheet.create({
  title: {
    textAlign: 'center',
    fontWeight: 'bold',
    fontSize: 24,
    marginBottom: 12,
  },
  description: {
    textAlign: 'center',
    fontSize: 17,
    paddingHorizontal: 22,
    marginBottom: 10,
  },
  btn: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
    borderRadius: 32,
    padding: 14,
    backgroundColor: colors.gray1,
  },
})