refactor(account): 收敛账号页组件结构
This commit is contained in:
1 parent
da095115d4
commit
6fce24d9ec
5 files changed
+308
-247
No files matched your search
@@ -69,84 +69,101 @@ class _AccountDeactivatePageState extends State<AccountDeactivatePage> {
|
||||
}
|
||||
|
||||
Widget _body(AppLocalizations l10n) {
|
||||
final errorColor = Theme.of(context).colorScheme.error;
|
||||
return ListView(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 28),
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: errorColor.withValues(alpha: 0.10),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: errorColor.withValues(alpha: 0.35)),
|
||||
),
|
||||
child: Text(
|
||||
l10n.accountDeactivateWarning,
|
||||
style: TextStyle(color: errorColor, height: 1.5),
|
||||
),
|
||||
),
|
||||
if (_logic.scheduledAt != null) ...[
|
||||
const SizedBox(height: 14),
|
||||
Container(
|
||||
key: const Key('account-deactivate-scheduled'),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.card,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Text(
|
||||
l10n.accountScheduledFor(
|
||||
formatLocalizedDateTime(context, _logic.scheduledAt!),
|
||||
),
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
key: const Key('account-deactivate-reason'),
|
||||
controller: _reason,
|
||||
maxLength: AccountDeactivateLogic.maxReasonLength,
|
||||
maxLines: 4,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.accountDeactivateReason,
|
||||
hintText: l10n.accountDeactivateReasonHint,
|
||||
),
|
||||
),
|
||||
if (_logic.error != null)
|
||||
Text(
|
||||
_message(l10n, _logic.error, l10n.accountDeactivateFailed),
|
||||
style: TextStyle(color: errorColor, fontSize: 12),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton(
|
||||
key: const Key('account-deactivate-submit'),
|
||||
onPressed: _logic.requesting ? null : _confirm,
|
||||
child: _logic.requesting
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(l10n.accountRequestDeactivate),
|
||||
),
|
||||
],
|
||||
_warning(l10n),
|
||||
const SizedBox(height: 14),
|
||||
OutlinedButton(
|
||||
key: const Key('account-deactivate-cancel'),
|
||||
onPressed: _logic.cancelling ? null : _cancel,
|
||||
child: Text(l10n.accountCancelDeactivation),
|
||||
),
|
||||
if (_logic.actionMessage != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
_message(l10n, _logic.actionMessage, l10n.accountCancelFailed),
|
||||
style: TextStyle(color: errorColor, fontSize: 12),
|
||||
),
|
||||
],
|
||||
if (_logic.scheduledAt != null)
|
||||
_scheduledPanel(l10n)
|
||||
else
|
||||
_requestPanel(l10n),
|
||||
const SizedBox(height: 14),
|
||||
_cancelPanel(l10n),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _warning(AppLocalizations l10n) {
|
||||
final errorColor = Theme.of(context).colorScheme.error;
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: errorColor.withValues(alpha: 0.10),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
border: Border.all(color: errorColor.withValues(alpha: 0.35)),
|
||||
),
|
||||
child: Text(
|
||||
l10n.accountDeactivateWarning,
|
||||
style: TextStyle(color: errorColor, height: 1.5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _scheduledPanel(AppLocalizations l10n) => Container(
|
||||
key: const Key('account-deactivate-scheduled'),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.card,
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Text(
|
||||
l10n.accountScheduledFor(
|
||||
formatLocalizedDateTime(context, _logic.scheduledAt!),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _requestPanel(AppLocalizations l10n) => Column(
|
||||
children: [
|
||||
TextField(
|
||||
key: const Key('account-deactivate-reason'),
|
||||
controller: _reason,
|
||||
maxLength: AccountDeactivateLogic.maxReasonLength,
|
||||
maxLines: 4,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.accountDeactivateReason,
|
||||
hintText: l10n.accountDeactivateReasonHint,
|
||||
),
|
||||
),
|
||||
if (_logic.error != null)
|
||||
_errorText(_message(l10n, _logic.error, l10n.accountDeactivateFailed)),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton(
|
||||
key: const Key('account-deactivate-submit'),
|
||||
onPressed: _logic.requesting ? null : _confirm,
|
||||
child: _logic.requesting
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(l10n.accountRequestDeactivate),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Widget _cancelPanel(AppLocalizations l10n) => Column(
|
||||
children: [
|
||||
OutlinedButton(
|
||||
key: const Key('account-deactivate-cancel'),
|
||||
onPressed: _logic.cancelling ? null : _cancel,
|
||||
child: Text(l10n.accountCancelDeactivation),
|
||||
),
|
||||
if (_logic.actionMessage != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
_errorText(
|
||||
_message(l10n, _logic.actionMessage, l10n.accountCancelFailed),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
|
||||
Widget _errorText(String value) => Text(
|
||||
value,
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.error, fontSize: 12),
|
||||
);
|
||||
|
||||
Future<void> _confirm() async {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final confirmed = await showDialog<bool>(
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
import 'account_deactivate_page.dart';
|
||||
import 'account_devices_page.dart';
|
||||
import 'account_export_page.dart';
|
||||
import 'account_profile_page.dart';
|
||||
|
||||
/// 我的页账号入口卡;只在登录态由父页面展示。
|
||||
class AccountEntryCard extends StatelessWidget {
|
||||
const AccountEntryCard({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Material(
|
||||
key: const Key('mine-account-card'),
|
||||
color: AppColors.card,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 14, 16, 8),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
l10n.accountCenter,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
_entry(
|
||||
context,
|
||||
key: const Key('mine-account-profile'),
|
||||
icon: Icons.person_outline_rounded,
|
||||
title: l10n.accountProfile,
|
||||
page: const AccountProfilePage(),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
_entry(
|
||||
context,
|
||||
key: const Key('mine-account-devices'),
|
||||
icon: Icons.devices_other_rounded,
|
||||
title: l10n.accountDevices,
|
||||
page: const AccountDevicesPage(),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
_entry(
|
||||
context,
|
||||
key: const Key('mine-account-export'),
|
||||
icon: Icons.file_download_outlined,
|
||||
title: l10n.accountDataExport,
|
||||
page: const AccountExportPage(),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
_entry(
|
||||
context,
|
||||
key: const Key('mine-account-deactivate'),
|
||||
icon: Icons.person_remove_outlined,
|
||||
title: l10n.accountDeactivate,
|
||||
page: const AccountDeactivatePage(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _entry(
|
||||
BuildContext context, {
|
||||
required Key key,
|
||||
required IconData icon,
|
||||
required String title,
|
||||
required Widget page,
|
||||
}) {
|
||||
return ListTile(
|
||||
key: key,
|
||||
leading: Icon(icon, color: AppColors.blueSoft),
|
||||
title: Text(title),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => Navigator.of(
|
||||
context,
|
||||
).push<void>(MaterialPageRoute(builder: (_) => page)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../core/data/models/account_export.dart';
|
||||
import '../../core/data/repositories/account_repository.dart';
|
||||
import '../../core/data/services/auth_controller.dart';
|
||||
import '../../core/formatting/error_text.dart';
|
||||
@@ -87,57 +88,61 @@ class _AccountExportPageState extends State<AccountExportPage> {
|
||||
key: const Key('account-export-content'),
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 28),
|
||||
children: [
|
||||
_card(
|
||||
children: [
|
||||
Text(
|
||||
data.profile.nickname,
|
||||
style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w700),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${l10n.accountUid}: ${data.profile.uid}',
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
_profileCard(data, l10n),
|
||||
const SizedBox(height: 12),
|
||||
_card(
|
||||
children: [
|
||||
Text(
|
||||
l10n.accountCredentials,
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
|
||||
),
|
||||
for (final credential in data.credentials)
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(
|
||||
Icons.verified_user_outlined,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(credential.masked),
|
||||
subtitle: Text(credential.type),
|
||||
trailing: Text(
|
||||
credential.verified
|
||||
? l10n.accountVerified
|
||||
: l10n.accountUnverified,
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 11),
|
||||
),
|
||||
),
|
||||
_summary(l10n.accountConsentRecords, '${data.consentCount}'),
|
||||
_summary(l10n.accountDeviceCount, '${data.deviceCount}'),
|
||||
],
|
||||
),
|
||||
_credentialsCard(data, l10n),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton.icon(
|
||||
key: const Key('account-export-copy'),
|
||||
onPressed: _copy,
|
||||
icon: const Icon(Icons.copy_rounded),
|
||||
label: Text(l10n.accountCopyJson),
|
||||
),
|
||||
_copyButton(l10n),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _profileCard(AccountExport data, AppLocalizations l10n) => _card(
|
||||
children: [
|
||||
Text(
|
||||
data.profile.nickname,
|
||||
style: const TextStyle(fontSize: 19, fontWeight: FontWeight.w700),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${l10n.accountUid}: ${data.profile.uid}',
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 12),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Widget _credentialsCard(AccountExport data, AppLocalizations l10n) => _card(
|
||||
children: [
|
||||
Text(
|
||||
l10n.accountCredentials,
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
|
||||
),
|
||||
for (final credential in data.credentials)
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(
|
||||
Icons.verified_user_outlined,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(credential.masked),
|
||||
subtitle: Text(credential.type),
|
||||
trailing: Text(
|
||||
credential.verified ? l10n.accountVerified : l10n.accountUnverified,
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 11),
|
||||
),
|
||||
),
|
||||
_summary(l10n.accountConsentRecords, '${data.consentCount}'),
|
||||
_summary(l10n.accountDeviceCount, '${data.deviceCount}'),
|
||||
],
|
||||
);
|
||||
|
||||
Widget _copyButton(AppLocalizations l10n) => FilledButton.icon(
|
||||
key: const Key('account-export-copy'),
|
||||
onPressed: _copy,
|
||||
icon: const Icon(Icons.copy_rounded),
|
||||
label: Text(l10n.accountCopyJson),
|
||||
);
|
||||
|
||||
Widget _card({required List<Widget> children}) => Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@@ -156,84 +156,93 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
|
||||
}
|
||||
|
||||
Widget _editableForm(AppLocalizations l10n) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
return _AccountCard(
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
key: const Key('account-nickname'),
|
||||
controller: _nickname,
|
||||
maxLength: AccountProfileLogic.maxNicknameLength,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.accountNickname,
|
||||
errorText: _logic.fieldError == null
|
||||
? null
|
||||
: l10n.accountNicknameInvalid,
|
||||
),
|
||||
),
|
||||
_nicknameField(l10n),
|
||||
const SizedBox(height: _fieldGap),
|
||||
DropdownButtonFormField<String>(
|
||||
key: const Key('account-gender'),
|
||||
initialValue: _gender,
|
||||
decoration: InputDecoration(labelText: l10n.accountGender),
|
||||
items: [
|
||||
DropdownMenuItem(value: 'male', child: Text(l10n.accountMale)),
|
||||
DropdownMenuItem(
|
||||
value: 'female',
|
||||
child: Text(l10n.accountFemale),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'unknown',
|
||||
child: Text(l10n.accountUnknownGender),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) setState(() => _gender = value);
|
||||
},
|
||||
),
|
||||
_genderField(l10n),
|
||||
const SizedBox(height: _fieldGap),
|
||||
OutlinedButton.icon(
|
||||
key: const Key('account-birthday'),
|
||||
onPressed: _pickBirthday,
|
||||
icon: const Icon(Icons.cake_outlined),
|
||||
label: Text(_birthday ?? l10n.accountSelectBirthday),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
l10n.accountBirthdayHint,
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 12),
|
||||
),
|
||||
),
|
||||
if (_logic.error != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
errorText(l10n, _logic.error, l10n.accountProfileSaveFailed),
|
||||
style: TextStyle(color: scheme.error, fontSize: 12),
|
||||
),
|
||||
],
|
||||
_birthdayField(l10n),
|
||||
if (_logic.error != null) _saveError(l10n),
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 52,
|
||||
child: FilledButton(
|
||||
key: const Key('account-profile-save'),
|
||||
onPressed: _logic.saving ? null : _save,
|
||||
child: _logic.saving
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(l10n.save),
|
||||
),
|
||||
),
|
||||
_saveButton(l10n),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _nicknameField(AppLocalizations l10n) => TextField(
|
||||
key: const Key('account-nickname'),
|
||||
controller: _nickname,
|
||||
maxLength: AccountProfileLogic.maxNicknameLength,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.accountNickname,
|
||||
errorText: _logic.fieldError == null ? null : l10n.accountNicknameInvalid,
|
||||
),
|
||||
);
|
||||
|
||||
Widget _genderField(AppLocalizations l10n) => DropdownButtonFormField<String>(
|
||||
key: const Key('account-gender'),
|
||||
initialValue: _gender,
|
||||
decoration: InputDecoration(labelText: l10n.accountGender),
|
||||
items: [
|
||||
DropdownMenuItem(value: 'male', child: Text(l10n.accountMale)),
|
||||
DropdownMenuItem(value: 'female', child: Text(l10n.accountFemale)),
|
||||
DropdownMenuItem(
|
||||
value: 'unknown',
|
||||
child: Text(l10n.accountUnknownGender),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value != null) setState(() => _gender = value);
|
||||
},
|
||||
);
|
||||
|
||||
Widget _birthdayField(AppLocalizations l10n) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
OutlinedButton.icon(
|
||||
key: const Key('account-birthday'),
|
||||
onPressed: _pickBirthday,
|
||||
icon: const Icon(Icons.cake_outlined),
|
||||
label: Text(_birthday ?? l10n.accountSelectBirthday),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
l10n.accountBirthdayHint,
|
||||
style: const TextStyle(color: AppColors.muted, fontSize: 12),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Widget _saveError(AppLocalizations l10n) => Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
errorText(l10n, _logic.error, l10n.accountProfileSaveFailed),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _saveButton(AppLocalizations l10n) => SizedBox(
|
||||
width: double.infinity,
|
||||
height: 52,
|
||||
child: FilledButton(
|
||||
key: const Key('account-profile-save'),
|
||||
onPressed: _logic.saving ? null : _save,
|
||||
child: _logic.saving
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(l10n.save),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _readOnlyCard(AccountProfile profile, AppLocalizations l10n) {
|
||||
return _AccountCard(
|
||||
child: Column(
|
||||
|
||||
@@ -24,10 +24,7 @@ import '../watch_records/watch_records_page.dart';
|
||||
import '../favorites/favorites_page.dart';
|
||||
import '../notices/notices_page.dart';
|
||||
import '../downloads/downloads_page.dart';
|
||||
import '../account/account_profile_page.dart';
|
||||
import '../account/account_devices_page.dart';
|
||||
import '../account/account_export_page.dart';
|
||||
import '../account/account_deactivate_page.dart';
|
||||
import '../account/account_entry_card.dart';
|
||||
|
||||
class MyPage extends StatefulWidget {
|
||||
const MyPage({
|
||||
@@ -206,7 +203,7 @@ class _MyPageState extends State<MyPage> {
|
||||
const SizedBox(height: 18),
|
||||
_wallet(l10n),
|
||||
const SizedBox(height: 14),
|
||||
_accountCard(l10n),
|
||||
const AccountEntryCard(),
|
||||
],
|
||||
const SizedBox(height: 14),
|
||||
_menuCard(l10n),
|
||||
@@ -496,66 +493,6 @@ class _MyPageState extends State<MyPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _accountCard(AppLocalizations l10n) {
|
||||
return Material(
|
||||
key: const Key('mine-account-card'),
|
||||
color: AppColors.card,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
key: const Key('mine-account-profile'),
|
||||
leading: const Icon(
|
||||
Icons.person_outline_rounded,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(l10n.accountProfile),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => _openAccount(const AccountProfilePage()),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
ListTile(
|
||||
key: const Key('mine-account-devices'),
|
||||
leading: const Icon(
|
||||
Icons.devices_other_rounded,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(l10n.accountDevices),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => _openAccount(const AccountDevicesPage()),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
ListTile(
|
||||
key: const Key('mine-account-export'),
|
||||
leading: const Icon(
|
||||
Icons.file_download_outlined,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(l10n.accountDataExport),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => _openAccount(const AccountExportPage()),
|
||||
),
|
||||
const Divider(height: 1, color: AppColors.outlineVariantDark),
|
||||
ListTile(
|
||||
key: const Key('mine-account-deactivate'),
|
||||
leading: const Icon(
|
||||
Icons.person_remove_outlined,
|
||||
color: AppColors.blueSoft,
|
||||
),
|
||||
title: Text(l10n.accountDeactivate),
|
||||
trailing: const Icon(Icons.chevron_right_rounded),
|
||||
onTap: () => _openAccount(const AccountDeactivatePage()),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _openAccount(Widget page) {
|
||||
Navigator.of(context).push<void>(MaterialPageRoute(builder: (_) => page));
|
||||
}
|
||||
|
||||
Widget _library(
|
||||
AppLocalizations l10n,
|
||||
Duration position,
|
||||
|
||||
Reference in new issue
Block a user