@@ -10,6 +10,7 @@ import {
1010 TextInput ,
1111 Tooltip ,
1212 useTheme ,
13+ ActivityIndicator ,
1314} from 'react-native-paper' ;
1415import BaseView from '../../components/baseview/baseview.tsx' ;
1516import { FONTS } from '../../config/misc.ts' ;
@@ -22,6 +23,12 @@ import {
2223} from '../../config/dimensions.ts' ;
2324import { PhotoType } from '../../config/image-picker/image-picker.tsx' ;
2425import ImagePicker from 'react-native-image-crop-picker' ;
26+ import storage from '@react-native-firebase/storage' ;
27+ import firestore from '@react-native-firebase/firestore' ;
28+ import auth from '@react-native-firebase/auth' ;
29+ import { alert } from '@baronha/ting' ;
30+ import { getRandomInt } from '../../utils/algo-utils.ts' ;
31+ import { Appodeal , AppodealAdType , AppodealMrec } from 'react-native-appodeal' ;
2532
2633const BugReport : React . FC = ( ) => {
2734 const navigation = useNavigation ( ) ;
@@ -34,11 +41,83 @@ const BugReport: React.FC = () => {
3441
3542 const [ isTouched , setIsTouched ] = useState ( false ) ;
3643
44+ const [ loading , setLoading ] = useState ( false ) ;
45+
3746 const incorrectReport = ( ) => {
3847 const textLength = reportText . trim ( ) . length ;
3948 return textLength < 19 || textLength > 240 ;
4049 } ;
4150
51+ const handleSendReport = async ( ) => {
52+ if ( incorrectReport ( ) ) {
53+ alert ( {
54+ preset : 'error' ,
55+ title : 'Invalid Report' ,
56+ message : 'Report must be between 20 and 240 characters' ,
57+ } ) ;
58+ return ;
59+ }
60+
61+ setLoading ( true ) ;
62+ try {
63+ let photoUrl = null ;
64+ const user = auth ( ) . currentUser ;
65+
66+ if ( ! user ) {
67+ return ;
68+ }
69+
70+ const uid = user . uid ;
71+
72+ if ( ! uid ) {
73+ return ;
74+ }
75+
76+ if ( userPhoto ) {
77+ const photoRef = storage ( ) . ref (
78+ `bug-reports/${ Date . now ( ) } -${ userPhoto ?. filename } ` ,
79+ ) ;
80+ await photoRef . putFile ( userPhoto . path ) ;
81+ photoUrl = await photoRef . getDownloadURL ( ) ;
82+ }
83+
84+ await firestore ( ) . collection ( 'bug_reports' ) . add ( {
85+ text : reportText . trim ( ) ,
86+ screenshot : photoUrl ,
87+ uid : uid ,
88+ createdAt : firestore . FieldValue . serverTimestamp ( ) ,
89+ status : 'pending' ,
90+ } ) ;
91+
92+ alert ( {
93+ preset : 'done' ,
94+ title : 'Report Sent' ,
95+ message : 'Thank you for your feedback!' ,
96+ } ) ;
97+
98+ const randomNumber = getRandomInt ( 1 , 3 ) ;
99+ if ( __DEV__ ) {
100+ console . log ( 'random number for ad is:' , randomNumber ) ;
101+ }
102+ if ( randomNumber === 2 ) {
103+ Appodeal . show ( AppodealAdType . INTERSTITIAL , 'Interstitial' ) ;
104+ }
105+
106+ navigation . goBack ( ) ;
107+ } catch ( error ) {
108+ if ( __DEV__ ) {
109+ console . log ( error ) ;
110+ }
111+ alert ( {
112+ preset : 'error' ,
113+ title : 'Error' ,
114+ message : 'Failed to send report. Please try again.' ,
115+ } ) ;
116+ } finally {
117+ setLoading ( false ) ;
118+ }
119+ } ;
120+
42121 return (
43122 < BaseView
44123 needsPaddingTop = { false }
@@ -72,73 +151,77 @@ const BugReport: React.FC = () => {
72151 setReportText ( text ) ;
73152 setIsTouched ( true ) ;
74153 } }
154+ />
155+ </ View >
156+ < HelperText
157+ type = { incorrectReport ( ) ? 'error' : 'info' }
158+ visible = { isTouched && incorrectReport ( ) } >
159+ { reportText . trim ( ) . length > 240
160+ ? 'Report message must be less than 240 characters.'
161+ : 'Report message must be longer than 20 characters.' }
162+ </ HelperText >
163+ < View style = { styles . attachView } >
164+ { userPhoto ? (
165+ < >
166+ < Image
167+ source = { { uri : userPhoto ?. path } }
168+ style = { {
169+ marginTop : heightPercentageToDP ( 0.5 ) ,
170+ height : heightPercentageToDP ( 40 ) ,
171+ width : widthPercentageToDP ( 40 ) ,
172+ borderRadius : 8 ,
173+ resizeMode : 'cover' ,
174+ overflow : 'hidden' ,
175+ } }
75176 />
76- </ View >
77- < HelperText
78- type = { incorrectReport ( ) ? 'error' : 'info' }
79- visible = { isTouched && incorrectReport ( ) } >
80- { reportText . trim ( ) . length > 240
81- ? 'Report message must be less than 240 characters.'
82- : 'Report message must be longer than 20 characters.' }
83- </ HelperText >
84- < View style = { styles . attachView } >
85- { userPhoto ? (
86- < >
87- < Image
88- source = { { uri : userPhoto ?. path } }
177+ < Pressable
178+ style = { {
179+ marginTop : heightPercentageToDP ( - 39 ) ,
180+ marginLeft : widthPercentageToDP ( 28 ) ,
181+ } }
182+ onPress = { ( ) => setUserPhoto ( null ) } >
183+ < Avatar . Icon
184+ size = { 24 }
185+ icon = { 'close' }
89186 style = { {
90- marginTop : heightPercentageToDP ( 0.5 ) ,
91- height : heightPercentageToDP ( 40 ) ,
92- width : widthPercentageToDP ( 40 ) ,
93- borderRadius : 8 ,
94- resizeMode : 'cover' ,
95187 overflow : 'hidden' ,
96188 } }
97189 />
98- < Pressable
99- style = { {
100- marginTop : heightPercentageToDP ( - 39 ) ,
101- marginLeft : widthPercentageToDP ( 28 ) ,
102- } }
103- onPress = { ( ) => setUserPhoto ( null ) } >
104- < Avatar . Icon
105- size = { 24 }
106- icon = { 'close' }
107- style = { {
108- overflow : 'hidden' ,
109- } }
110- />
111- </ Pressable >
112- </ >
113- ) : (
114- < Chip
115- icon = { 'image-plus' }
116- mode = { 'outlined' }
117- onPress = { ( ) => {
118- ImagePicker . openPicker ( {
119- width : 1024 ,
120- height : 1024 ,
121- cropping : false ,
122- mediaType : 'photo' ,
190+ </ Pressable >
191+ </ >
192+ ) : (
193+ < Chip
194+ icon = { 'image-plus' }
195+ mode = { 'outlined' }
196+ onPress = { ( ) => {
197+ ImagePicker . openPicker ( {
198+ width : 1024 ,
199+ height : 1024 ,
200+ cropping : false ,
201+ mediaType : 'photo' ,
202+ } )
203+ . then ( image => {
204+ setUserPhoto ( image as PhotoType ) ;
123205 } )
124- . then ( image => {
125- setUserPhoto ( image as PhotoType ) ;
126- } )
127- . catch ( error => {
128- if ( __DEV__ ) {
129- console . error ( error ) ;
130- }
131- } ) ;
132- } } >
133- Attach Photo
134- </ Chip >
135- ) }
136- </ View >
137- < FAB
138- style = { styles . fab }
139- icon = { 'send' }
140- onPress = { ( ) => console . log ( 'hello' ) }
141- />
206+ . catch ( error => {
207+ if ( __DEV__ ) {
208+ console . error ( error ) ;
209+ }
210+ } ) ;
211+ } } >
212+ Attach Photo
213+ </ Chip >
214+ ) }
215+ </ View >
216+ < AppodealMrec placement = { 'Mrec' } />
217+ < FAB
218+ icon = { 'send' }
219+ label = "Send Report"
220+ style = { styles . fab }
221+ loading = { loading }
222+ onPress = { handleSendReport }
223+ disabled = { loading || incorrectReport ( ) }
224+ />
142225 </ BaseView >
143226 ) ;
144227} ;
0 commit comments