1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-10-23 23:13:22 +00:00
comunicmobile/lib/ui/routes/settings/account_privacy_settings.dart

286 lines
9.3 KiB
Dart

import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/helpers/server_config_helper.dart';
import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/models/data_conservation_policy_settings.dart';
import 'package:comunic/models/server_config.dart';
import 'package:comunic/ui/dialogs/input_user_password_dialog.dart';
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/settings/header_spacer_section.dart';
import 'package:comunic/ui/widgets/settings/multi_choices_settings_tile.dart';
import 'package:comunic/utils/flutter_utils.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_settings_ui/flutter_settings_ui.dart';
/// Account privacy settings
///
/// @author Pierre HUBERT
class AccountPrivacySettings extends StatefulWidget {
@override
_AccountPrivacySettingsState createState() => _AccountPrivacySettingsState();
}
class _AccountPrivacySettingsState extends State<AccountPrivacySettings> {
final _key = GlobalKey<AsyncScreenWidgetState>();
ServerConfig? _serverConfig;
late DataConservationPolicySettings _userSettings;
String? _cachedPassword;
Future<void> _loadSettings() async {
_serverConfig = ServerConfigurationHelper.config;
_userSettings = await SettingsHelper.getDataConservationPolicy();
}
@override
Widget build(BuildContext context) {
return AsyncScreenWidget(
key: _key,
onReload: _loadSettings,
onBuild: () => SettingsList(sections: [
HeadSpacerSection(),
SettingsSection(
title: tr("Data conservation policy"),
tiles: _dataConservationPolicyTiles,
),
HeadSpacerSection(),
HeadSpacerSection(),
SettingsSection(title: tr("Danger zone"), tiles: [
SettingsTile(
title: tr("Delete your account"),
subtitle: isIOS
? null
: tr(
"Permanently delete your account and all data related to it."),
onPressed: (_) => _deleteAccount(),
subtitleMaxLines: 2,
)
])
]),
errorMessage: tr("Failed to load privacy settings!")!,
);
}
List<SettingsTile> get _dataConservationPolicyTiles => [
DataConservationPolicyTile(
value: _userSettings.notificationLifetime,
title: tr("Automatically delete unread notifications after")!,
onChange: (val) {
_userSettings.notificationLifetime = val;
_updateDataConservationPolicy();
},
minValue:
_serverConfig!.dataConservationPolicy.minNotificationLifetime,
),
DataConservationPolicyTile(
value: _userSettings.commentsLifetime,
title: tr("Automatically delete your comments after")!,
onChange: (val) {
_userSettings.commentsLifetime = val;
_updateDataConservationPolicy();
},
minValue: _serverConfig!.dataConservationPolicy.minCommentsLifetime,
),
DataConservationPolicyTile(
value: _userSettings.postsLifetime,
title: tr("Automatically delete your posts after")!,
onChange: (val) {
_userSettings.postsLifetime = val;
_updateDataConservationPolicy();
},
minValue: _serverConfig!.dataConservationPolicy.minPostsLifetime,
),
DataConservationPolicyTile(
value: _userSettings.conversationMessagesLifetime,
title: tr("Automatically delete your conversation messages after")!,
onChange: (val) {
_userSettings.conversationMessagesLifetime = val;
_updateDataConservationPolicy();
},
minValue: _serverConfig!
.dataConservationPolicy.minConversationMessagesLifetime,
),
DataConservationPolicyTile(
value: _userSettings.likesLifetime,
title: tr("Automatically delete your likes after")!,
onChange: (val) {
_userSettings.likesLifetime = val;
_updateDataConservationPolicy();
},
minValue: _serverConfig!.dataConservationPolicy.minLikesLifetime,
),
DataConservationPolicyTile(
value: _userSettings.inactiveAccountLifeTime,
title: tr(
"Automatically delete your account if you have been inactive for")!,
onChange: (val) {
_userSettings.inactiveAccountLifeTime = val;
_updateDataConservationPolicy();
},
minValue:
_serverConfig!.dataConservationPolicy.minInactiveAccountLifetime,
),
];
void _updateDataConservationPolicy() async {
try {
if (_cachedPassword == null)
_cachedPassword = await showUserPasswordDialog(context);
await SettingsHelper.setDataConservationPolicy(
_cachedPassword, _userSettings);
_key.currentState!.refresh();
} catch (e, s) {
print("Could not update data conservation policy! $e\n$s");
showSimpleSnack(
context, tr("Failed to update data conservation policy!")!);
}
}
/// Permanently delete user account
void _deleteAccount() async {
try {
// First dialog
if (!await showConfirmDialog(
context: context,
message: tr(
"Do you really want to delete your account? This operation CAN NOT be reverted!")))
return;
// Ask user password dialog
final password = await showUserPasswordDialog(context);
if (password == null) return;
// Last chance dialog
if (await showCupertinoDialog<bool>(
context: context,
builder: (c) => _LastChanceDeleteAccountDialog()) !=
true) return;
// Delete account
await AccountHelper.deleteAccount(password);
} catch (e, stack) {
print("Could not delete user account! $e\n$stack");
showSimpleSnack(context, tr("Could not delete your account!")!);
}
}
}
class DataConservationPolicyTile extends SettingsTile {
final int? value;
final String title;
final Function(int) onChange;
final int minValue;
DataConservationPolicyTile({
required this.value,
required this.title,
required this.onChange,
required this.minValue,
}) : assert(title != null),
assert(onChange != null),
assert(minValue != null);
@override
Widget build(BuildContext context) {
return MultiChoicesSettingsTile(
title: title,
choices: _choices,
currentValue: _roundValue,
onChanged: onChange,
);
}
int get _day => 60 * 60 * 24;
int get _month => _day * 30;
int get _year => _day * 365;
int get _roundValue {
if (this.value == null) return 0;
return _choices.firstWhere((element) => element.id >= this.value!).id;
}
List<MultiChoiceEntry<int>> get _choices => [
MultiChoiceEntry(id: 0, title: tr("Never")!, hidden: false),
MultiChoiceEntry(
id: _day * 7,
title: tr("7 days")!,
hidden: _day * 7 < minValue,
),
MultiChoiceEntry(
id: _day * 15,
title: tr("15 days")!,
hidden: _day * 15 < minValue,
),
MultiChoiceEntry(
id: _month,
title: tr("1 month")!,
hidden: _month < minValue,
),
MultiChoiceEntry(
id: _month * 3,
title: tr("3 months")!,
hidden: _month * 3 < minValue,
),
MultiChoiceEntry(
id: _month * 6,
title: tr("6 months")!,
hidden: _month * 6 < minValue,
),
MultiChoiceEntry(
id: _year,
title: tr("1 year")!,
hidden: _year < minValue,
),
MultiChoiceEntry(
id: _year * 2,
title: tr("2 years")!,
hidden: _year * 5 < minValue,
),
MultiChoiceEntry(
id: _year * 5,
title: tr("5 years")!,
hidden: _year * 5 < minValue,
),
MultiChoiceEntry(
id: _year * 10,
title: tr("10 years")!,
hidden: _year * 10 < minValue,
),
MultiChoiceEntry(
id: _year * 50,
title: tr("50 years")!,
hidden: _year * 50 < minValue,
),
];
}
class _LastChanceDeleteAccountDialog extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CupertinoAlertDialog(
title: Text(tr("Delete your account")!),
content: Text(tr(
"Let us ask you one last time. Do you really want to delete your account? If you decide to do so, your data will be permanently removed from our servers, so we will not be able to recover your account. If you decide to proceed, the deletion process will start immediatly and you will automatically get disconnected from your account.")!),
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
child: Text(tr("Cancel")!),
onPressed: () => Navigator.of(context).pop(false),
),
CupertinoDialogAction(
isDestructiveAction: true,
child: Text(tr("Confirm")!),
onPressed: () => Navigator.of(context).pop(true),
),
],
);
}
}