Files
ReelShort/lib/pages/interaction/widgets/report_dialog.dart

127 lines
3.5 KiB
Dart

// Author: fruit.com.cn
import 'package:flutter/material.dart';
import '../../../core/data/models/interaction.dart';
import '../../../core/widgets/app_glow_panel.dart';
import '../../../l10n/app_localizations.dart';
const int _maxDescriptionLength = 300;
/// 举报弹窗收集的结果。
class ReportDialogResult {
const ReportDialogResult({
required this.reason,
required this.description,
});
final ReportReason reason;
final String description;
}
/// 打开举报原因单选弹窗;取消时返回 null。
Future<ReportDialogResult?> showReportDialog(
BuildContext context, {
required String title,
}) => showDialog<ReportDialogResult>(
context: context,
builder: (_) => _ReportDialog(title: title),
);
class _ReportDialog extends StatefulWidget {
const _ReportDialog({required this.title});
final String title;
@override
State<_ReportDialog> createState() => _ReportDialogState();
}
class _ReportDialogState extends State<_ReportDialog> {
final _description = TextEditingController();
ReportReason _reason = ReportReason.spam;
@override
void dispose() {
_description.dispose();
super.dispose();
}
void _submit() {
Navigator.of(context).pop(
ReportDialogResult(
reason: _reason,
description: _description.text.trim(),
),
);
}
String _reasonLabel(AppLocalizations l10n, ReportReason reason) =>
switch (reason) {
ReportReason.spam => l10n.reportReasonSpam,
ReportReason.abuse => l10n.reportReasonAbuse,
ReportReason.porn => l10n.reportReasonPorn,
ReportReason.ad => l10n.reportReasonAd,
ReportReason.other => l10n.reportReasonOther,
};
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return AppGlowDialog(
title: widget.title,
contentChild: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(l10n.reportReason),
RadioGroup<ReportReason>(
groupValue: _reason,
onChanged: (value) {
if (value == null) return;
setState(() => _reason = value);
},
child: Column(
children: [
for (final reason in ReportReason.values)
RadioListTile<ReportReason>(
key: Key('report-reason-${reason.apiValue}'),
value: reason,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(_reasonLabel(l10n, reason)),
),
],
),
),
const SizedBox(height: 8),
TextField(
key: const Key('report-description'),
controller: _description,
maxLength: _maxDescriptionLength,
maxLines: 3,
minLines: 2,
decoration: InputDecoration(
hintText: l10n.reportDescriptionHint,
border: const OutlineInputBorder(),
),
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(l10n.cancel),
),
FilledButton(
key: const Key('report-submit'),
onPressed: _submit,
child: Text(l10n.reportSubmit),
),
],
);
}
}