chore(merge): 合并未使用注销原因清理

This commit is contained in:
Zhou Weidong committed 2026-10-23 12:45:30 +08:00
commit 0ef0d46919
9 files changed
+1 -231

No files matched your search

-6
View File
@@ -595,10 +595,6 @@
"accountDeactivateWarning": "Requests enter a 15-day cooling-off period. All devices are signed out immediately.",
"accountDeactivateReason": "Reason (optional)",
"accountDeactivateReasonHint": "Add more detail here",
"accountDeactivateReasonUnused": "Not using it anymore",
"accountDeactivateReasonContent": "Not interested in the content",
"accountDeactivateReasonPrivacy": "Privacy concerns",
"accountDeactivateReasonOther": "Other",
"accountRequestDeactivate": "Request account deletion",
"accountConfirmDeactivateTitle": "Request account deletion?",
"accountConfirmDeactivateMessage": "All devices will be signed out immediately. You can cancel during the 15-day cooling-off period after signing in again.",
@@ -722,8 +718,6 @@
"homeBadgeHot": "Hot",
"homeBadgeNew": "New",
"homeBadgeAnime": "Anime",
"homeGridFilterEmpty": "No dramas match these filters",
"homeGridClearFilter": "Clear filters",
"emptyContent": "No content yet",
"recommendTopTab": "Recommend",
"playlistTopTab": "Playlists",
-6
View File
@@ -559,10 +559,6 @@
"accountDeactivateWarning": "Permintaan masuk masa tenang 15 hari. Semua perangkat langsung keluar.",
"accountDeactivateReason": "Alasan (opsional)",
"accountDeactivateReasonHint": "Tambahkan penjelasan di sini",
"accountDeactivateReasonUnused": "Tidak lagi digunakan",
"accountDeactivateReasonContent": "Konten tidak menarik",
"accountDeactivateReasonPrivacy": "Masalah privasi",
"accountDeactivateReasonOther": "Lainnya",
"accountRequestDeactivate": "Ajukan penghapusan akun",
"accountConfirmDeactivateTitle": "Ajukan penghapusan akun?",
"accountConfirmDeactivateMessage": "Semua perangkat akan langsung keluar. Setelah masuk lagi, kamu dapat membatalkannya selama masa tenang 15 hari.",
@@ -679,8 +675,6 @@
"homeBadgeHot": "Populer",
"homeBadgeNew": "Baru",
"homeBadgeAnime": "Anime",
"homeGridFilterEmpty": "Tidak ada drama yang cocok dengan filter",
"homeGridClearFilter": "Hapus filter",
"emptyContent": "Belum ada konten",
"recommendTopTab": "Rekomendasi",
"playlistTopTab": "Daftar Putar",
-36
View File
@@ -2488,30 +2488,6 @@ abstract class AppLocalizations {
/// **'Add more detail here'**
String get accountDeactivateReasonHint;
/// No description provided for @accountDeactivateReasonUnused.
///
/// In en, this message translates to:
/// **'Not using it anymore'**
String get accountDeactivateReasonUnused;
/// No description provided for @accountDeactivateReasonContent.
///
/// In en, this message translates to:
/// **'Not interested in the content'**
String get accountDeactivateReasonContent;
/// No description provided for @accountDeactivateReasonPrivacy.
///
/// In en, this message translates to:
/// **'Privacy concerns'**
String get accountDeactivateReasonPrivacy;
/// No description provided for @accountDeactivateReasonOther.
///
/// In en, this message translates to:
/// **'Other'**
String get accountDeactivateReasonOther;
/// No description provided for @accountRequestDeactivate.
///
/// In en, this message translates to:
@@ -3136,18 +3112,6 @@ abstract class AppLocalizations {
/// **'Anime'**
String get homeBadgeAnime;
/// No description provided for @homeGridFilterEmpty.
///
/// In en, this message translates to:
/// **'No dramas match these filters'**
String get homeGridFilterEmpty;
/// No description provided for @homeGridClearFilter.
///
/// In en, this message translates to:
/// **'Clear filters'**
String get homeGridClearFilter;
/// No description provided for @emptyContent.
///
/// In en, this message translates to:
-18
View File
@@ -1289,18 +1289,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get accountDeactivateReasonHint => 'Add more detail here';
@override
String get accountDeactivateReasonUnused => 'Not using it anymore';
@override
String get accountDeactivateReasonContent => 'Not interested in the content';
@override
String get accountDeactivateReasonPrivacy => 'Privacy concerns';
@override
String get accountDeactivateReasonOther => 'Other';
@override
String get accountRequestDeactivate => 'Request account deletion';
@@ -1638,12 +1626,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get homeBadgeAnime => 'Anime';
@override
String get homeGridFilterEmpty => 'No dramas match these filters';
@override
String get homeGridClearFilter => 'Clear filters';
@override
String get emptyContent => 'No content yet';
-18
View File
@@ -1288,18 +1288,6 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get accountDeactivateReasonHint => 'Tambahkan penjelasan di sini';
@override
String get accountDeactivateReasonUnused => 'Tidak lagi digunakan';
@override
String get accountDeactivateReasonContent => 'Konten tidak menarik';
@override
String get accountDeactivateReasonPrivacy => 'Masalah privasi';
@override
String get accountDeactivateReasonOther => 'Lainnya';
@override
String get accountRequestDeactivate => 'Ajukan penghapusan akun';
@@ -1638,12 +1626,6 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get homeBadgeAnime => 'Anime';
@override
String get homeGridFilterEmpty => 'Tidak ada drama yang cocok dengan filter';
@override
String get homeGridClearFilter => 'Hapus filter';
@override
String get emptyContent => 'Belum ada konten';
-18
View File
@@ -1266,18 +1266,6 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get accountDeactivateReasonHint => '也可以在这里补充说明';
@override
String get accountDeactivateReasonUnused => '不再使用';
@override
String get accountDeactivateReasonContent => '内容不感兴趣';
@override
String get accountDeactivateReasonPrivacy => '隐私顾虑';
@override
String get accountDeactivateReasonOther => '其他';
@override
String get accountRequestDeactivate => '申请注销账号';
@@ -1613,12 +1601,6 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get homeBadgeAnime => '漫剧';
@override
String get homeGridFilterEmpty => '没有符合筛选条件的短剧';
@override
String get homeGridClearFilter => '清除筛选';
@override
String get emptyContent => '暂无内容';
-6
View File
@@ -521,10 +521,6 @@
"accountDeactivateWarning": "提交后进入 15 天冷静期,所有设备会立即退出登录。",
"accountDeactivateReason": "注销原因(选填)",
"accountDeactivateReasonHint": "也可以在这里补充说明",
"accountDeactivateReasonUnused": "不再使用",
"accountDeactivateReasonContent": "内容不感兴趣",
"accountDeactivateReasonPrivacy": "隐私顾虑",
"accountDeactivateReasonOther": "其他",
"accountRequestDeactivate": "申请注销账号",
"accountConfirmDeactivateTitle": "确认申请注销?",
"accountConfirmDeactivateMessage": "所有设备会立即退出登录。重新登录后,可在 15 天冷静期内撤销申请。",
@@ -641,8 +637,6 @@
"homeBadgeHot": "热剧",
"homeBadgeNew": "新剧",
"homeBadgeAnime": "漫剧",
"homeGridFilterEmpty": "没有符合筛选条件的短剧",
"homeGridClearFilter": "清除筛选",
"emptyContent": "暂无内容",
"recommendTopTab": "推荐",
"playlistTopTab": "剧单",
@@ -1,106 +0,0 @@
// Author: fruit.com.cn
import 'package:flutter/material.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_dimens.dart';
import '../../l10n/app_localizations.dart';
import 'account_deactivate_logic.dart';
/// 注销原因:固定选项在标题下换行排列,补充说明留在输入框内。
class DeactivateReasonField extends StatelessWidget {
const DeactivateReasonField({
super.key,
required this.controller,
required this.onChanged,
});
final TextEditingController controller;
final VoidCallback onChanged;
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final options = _options(l10n);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.accountDeactivateReason,
style: const TextStyle(
color: AppColors.textPrimary,
fontSize: AppDimens.listTitle,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: AppDimens.spaceSm),
Wrap(
spacing: AppDimens.spaceSm,
runSpacing: AppDimens.spaceSm,
children: [
for (var index = 0; index < options.length; index++)
_chip(options[index], index, options),
],
),
const SizedBox(height: AppDimens.spaceMd),
TextField(
key: const Key('account-deactivate-reason'),
controller: controller,
maxLength: AccountDeactivateLogic.maxReasonLength,
minLines: 3,
maxLines: 4,
textAlignVertical: TextAlignVertical.top,
onChanged: (_) => onChanged(),
decoration: InputDecoration(
hintText: l10n.accountDeactivateReasonHint,
floatingLabelBehavior: FloatingLabelBehavior.never,
alignLabelWithHint: true,
contentPadding: const EdgeInsets.all(AppDimens.cardPadding),
),
),
],
);
}
Widget _chip(_ReasonOption option, int index, List<_ReasonOption> options) {
final selected = option.custom
? _customSelected(options)
: controller.text == option.label;
return ChoiceChip(
key: Key('account-deactivate-reason-$index'),
label: Text(option.label),
selected: selected,
onSelected: (_) => _select(option),
);
}
bool _customSelected(List<_ReasonOption> options) {
final text = controller.text.trim();
if (text.isEmpty) return false;
return options
.where((item) => !item.custom)
.every((item) => item.label != text);
}
void _select(_ReasonOption option) {
controller.text = option.custom ? '' : option.label;
controller.selection = TextSelection.collapsed(
offset: controller.text.length,
);
onChanged();
}
List<_ReasonOption> _options(AppLocalizations l10n) => [
_ReasonOption(l10n.accountDeactivateReasonUnused),
_ReasonOption(l10n.accountDeactivateReasonContent),
_ReasonOption(l10n.accountDeactivateReasonPrivacy),
_ReasonOption(l10n.accountDeactivateReasonOther, custom: true),
];
}
class _ReasonOption {
const _ReasonOption(this.label, {this.custom = false});
final String label;
final bool custom;
}
+1 -17
View File
@@ -71,23 +71,7 @@ void main() {
);
final l10n = await AppLocalizations.delegate.load(const Locale('en'));
final titleTop = tester
.getTopLeft(find.text(l10n.accountDeactivateReason))
.dy;
final fieldTop = tester
.getTopLeft(find.byKey(const Key('account-deactivate-reason')))
.dy;
expect(fieldTop, greaterThan(titleTop));
expect(find.text(l10n.accountDeactivateReasonUnused), findsOneWidget);
await tester.tap(find.byKey(const Key('account-deactivate-reason-0')));
await tester.pumpAndSettle();
expect(
tester
.widget<TextField>(find.byKey(const Key('account-deactivate-reason')))
.controller
?.text,
l10n.accountDeactivateReasonUnused,
);
expect(find.text(l10n.accountDeactivateReason), findsOneWidget);
await tester.enterText(
find.byKey(const Key('account-deactivate-reason')),
'不再使用',