import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:surface/providers/sn_network.dart'; import 'package:surface/widgets/dialog.dart'; import '../types/account.dart'; class AbuseReportScreen extends StatefulWidget { const AbuseReportScreen({super.key}); @override State createState() => _AbuseReportScreenState(); } class _AbuseReportScreenState extends State { bool _isBusy = false; List _reports = List.empty(); Future _fetchReports() async { setState(() => _isBusy = true); try { final sn = context.read(); final resp = await sn.client.get('/cgi/id/reports/abuse'); if (!mounted) return; _reports = resp.data.map((e) => SnAbuseReport.fromJson(e)).cast().toList(); } catch (err) { if (!mounted) return; context.showErrorDialog(err); } finally { setState(() => _isBusy = false); } } void _showAbuseReportDialog() { showDialog( context: context, builder: (context) => _AbuseReportDialog(), ).then((value) { if (value == true && mounted) { _fetchReports(); context.showSnackbar('abuseReportSubmitted'.tr()); } }); } @override void initState() { super.initState(); _fetchReports(); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ ListTile( title: Text('abuseReportAction').tr(), subtitle: Text('abuseReportActionDescription').tr(), contentPadding: const EdgeInsets.symmetric(horizontal: 24), leading: const Icon(Icons.report), trailing: const Icon(Icons.chevron_right), onTap: _showAbuseReportDialog, ), const Divider(height: 1), if (_isBusy) const CircularProgressIndicator().padding(all: 24).center() else Expanded( child: ListView.builder( itemCount: _reports.length, itemBuilder: (context, idx) { return ListTile( isThreeLine: true, title: Text(_reports[idx].resource, style: GoogleFonts.robotoMono(fontSize: 13)), subtitle: Text(_reports[idx].reason), contentPadding: const EdgeInsets.symmetric(horizontal: 24), leading: const Icon(Icons.flag), ); }, ), ), ], ), ); } } class _AbuseReportDialog extends StatefulWidget { const _AbuseReportDialog({super.key}); @override State<_AbuseReportDialog> createState() => _AbuseReportDialogState(); } class _AbuseReportDialogState extends State<_AbuseReportDialog> { bool _isBusy = false; final _resourceController = TextEditingController(); final _reasonController = TextEditingController(); @override dispose() { _resourceController.dispose(); _reasonController.dispose(); super.dispose(); } Future _performAction() async { setState(() => _isBusy = true); try { final sn = context.read(); await sn.client.post( '/cgi/id/reports/abuse', data: { 'resource': _resourceController.text, 'reason': _reasonController.text, }, ); if (!mounted) return; Navigator.pop(context, true); } catch (err) { if (!mounted) return; context.showErrorDialog(err); } finally { setState(() => _isBusy = false); } } @override Widget build(BuildContext context) { return AlertDialog( title: Text('abuseReport'.tr()), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('abuseReportDescription'.tr()), const Gap(12), TextField( controller: _resourceController, maxLength: null, decoration: InputDecoration( border: const UnderlineInputBorder(), labelText: 'abuseReportResource'.tr(), ), onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), ), const Gap(4), TextField( controller: _reasonController, maxLength: null, decoration: InputDecoration( border: const UnderlineInputBorder(), labelText: 'abuseReportReason'.tr(), ), onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), ), ], ), actions: [ TextButton( onPressed: _isBusy ? null : () => Navigator.pop(context), child: Text('dialogDismiss').tr(), ), TextButton( onPressed: _isBusy ? null : _performAction, child: Text('submit').tr(), ), ], ); } }