Set account label

This commit is contained in:
Ming Ming 2022-07-10 23:53:24 +08:00
parent b65e8fdb91
commit c4fd0fafdd
6 changed files with 127 additions and 32 deletions

View file

@ -330,6 +330,11 @@
"@settingsAccountPageTitle": {
"description": "Dedicated page for account settings"
},
"settingsAccountLabelTitle": "Label",
"@settingsAccountLabelTitle": {
"description": "An account label is used to replace the server URL in the app bar, could be useful for privacy reason"
},
"settingsAccountLabelDescription": "Set a label to be shown in place of the server URL",
"settingsIncludedFoldersTitle": "Included folders",
"@settingsIncludedFoldersTitle": {
"description": "Change the included folders of an account"

View file

@ -6,6 +6,8 @@
"settingsMemoriesSubtitle",
"settingsAccountTitle",
"settingsAccountPageTitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsIncludedFoldersTitle",
"settingsShareFolderTitle",
"settingsShareFolderDialogTitle",
@ -118,6 +120,8 @@
"settingsMemoriesSubtitle",
"settingsAccountTitle",
"settingsAccountPageTitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsIncludedFoldersTitle",
"settingsShareFolderTitle",
"settingsShareFolderDialogTitle",
@ -240,17 +244,28 @@
"el": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"enhanceStyleTransferStyleDialogTitle"
],
"es": [
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"rootPickerSkipConfirmationDialogContent2"
],
"fi": [
"settingsAccountLabelTitle",
"settingsAccountLabelDescription"
],
"fr": [
"collectionsTooltip",
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",
@ -281,6 +296,8 @@
"pl": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",
@ -329,6 +346,8 @@
"pt": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",
@ -356,6 +375,8 @@
"ru": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",
@ -383,6 +404,8 @@
"zh": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",
@ -410,6 +433,8 @@
"zh_Hant": [
"settingsExifWifiOnlyTitle",
"settingsExifWifiOnlyFalseSubtitle",
"settingsAccountLabelTitle",
"settingsAccountLabelDescription",
"settingsPhotoEnhancementTitle",
"settingsPhotoEnhancementPageTitle",
"settingsEnhanceMaxResolutionTitle",

View file

@ -289,6 +289,17 @@ class AccountPref {
(key, value) => provider.setString(key, value));
Future<bool> removeTouchRootEtag() => _remove(PrefKey.touchRootEtag);
String? getAccountLabel() => provider.getString(PrefKey.accountLabel);
String getAccountLabelOr([String def = ""]) => getAccountLabel() ?? def;
Future<bool> setAccountLabel(String? value) {
if (value == null) {
return _remove(PrefKey.accountLabel);
} else {
return _set<String>(PrefKey.accountLabel, value,
(key, value) => provider.setString(key, value));
}
}
Future<bool> _set<T>(PrefKey key, T value,
Future<bool> Function(PrefKey key, T value) setFn) async {
if (await setFn(key, value)) {
@ -519,6 +530,7 @@ enum PrefKey {
hasNewSharedAlbum,
isEnableMemoryAlbum,
touchRootEtag,
accountLabel,
}
extension on PrefKey {
@ -590,6 +602,8 @@ extension on PrefKey {
return "isEnableMemoryAlbum";
case PrefKey.touchRootEtag:
return "touchRootEtag";
case PrefKey.accountLabel:
return "accountLabel";
}
}
}

View file

@ -33,26 +33,27 @@ class _AccountPickerDialogState extends State<AccountPickerDialog> {
@override
build(BuildContext context) {
final otherAccountOptions = _accounts
.where((a) => a != widget.account)
.map((a) => SimpleDialogOption(
padding: const EdgeInsets.symmetric(horizontal: 8),
onPressed: () => _onItemPressed(a),
child: ListTile(
dense: true,
title: Text(a.url),
subtitle: Text(a.username.toString()),
trailing: IconButton(
icon: Icon(
Icons.close,
color: AppTheme.getUnfocusedIconColor(context),
),
tooltip: L10n.global().deleteTooltip,
onPressed: () => _onRemoveItemPressed(a),
),
),
))
.toList();
final otherAccountOptions =
_accounts.where((a) => a != widget.account).map((a) {
final label = AccountPref.of(a).getAccountLabel();
return SimpleDialogOption(
padding: const EdgeInsets.symmetric(horizontal: 8),
onPressed: () => _onItemPressed(a),
child: ListTile(
dense: true,
title: Text(label ?? a.url),
subtitle: label == null ? Text(a.username.toString()) : null,
trailing: IconButton(
icon: Icon(
Icons.close,
color: AppTheme.getUnfocusedIconColor(context),
),
tooltip: L10n.global().deleteTooltip,
onPressed: () => _onRemoveItemPressed(a),
),
),
);
}).toList();
final addAccountOptions = [
SimpleDialogOption(
padding: const EdgeInsets.all(8),
@ -72,18 +73,21 @@ class _AccountPickerDialogState extends State<AccountPickerDialog> {
),
),
];
final accountLabel = AccountPref.of(widget.account).getAccountLabel();
return AppTheme(
child: SimpleDialog(
title: ListTile(
dense: true,
title: Text(
widget.account.url,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
widget.account.username.toString(),
accountLabel ?? widget.account.url,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: accountLabel == null
? Text(
widget.account.username.toString(),
style: const TextStyle(fontWeight: FontWeight.bold),
)
: null,
trailing: IconButton(
icon: Icon(
Icons.settings_outlined,

View file

@ -23,6 +23,7 @@ class HomeSliverAppBar extends StatelessWidget {
@override
build(BuildContext context) {
final accountLabel = AccountPref.of(account).getAccountLabel();
return SliverAppBar(
title: InkWell(
onTap: () {
@ -57,16 +58,17 @@ class HomeSliverAppBar extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
account.url.substring(account.scheme.length + 3),
accountLabel ?? account.address,
style: const TextStyle(fontSize: 16),
),
Text(
account.username.toString(),
style: TextStyle(
fontSize: 14,
color: AppTheme.getSecondaryTextColor(context),
if (accountLabel == null)
Text(
account.username.toString(),
style: TextStyle(
fontSize: 14,
color: AppTheme.getSecondaryTextColor(context),
),
),
),
],
),
),

View file

@ -26,6 +26,7 @@ import 'package:nc_photos/widget/home.dart';
import 'package:nc_photos/widget/list_tile_center_leading.dart';
import 'package:nc_photos/widget/root_picker.dart';
import 'package:nc_photos/widget/share_folder_picker.dart';
import 'package:nc_photos/widget/simple_input_dialog.dart';
import 'package:nc_photos/widget/stateful_slider.dart';
import 'package:screen_brightness/screen_brightness.dart';
import 'package:tuple/tuple.dart';
@ -495,6 +496,7 @@ class _AccountSettingsState extends State<AccountSettingsWidget> {
final settings = AccountPref.of(_account);
_isEnableFaceRecognitionApp = settings.isEnableFaceRecognitionAppOr();
_shareFolder = settings.getShareFolderOr();
_label = settings.getAccountLabel();
}
@override
@ -527,6 +529,12 @@ class _AccountSettingsState extends State<AccountSettingsWidget> {
SliverList(
delegate: SliverChildListDelegate(
[
ListTile(
title: Text(L10n.global().settingsAccountLabelTitle),
subtitle: Text(
_label ?? L10n.global().settingsAccountLabelDescription),
onTap: () => _onLabelPressed(context),
),
ListTile(
title: Text(L10n.global().settingsIncludedFoldersTitle),
subtitle: Text(_account.roots.map((e) => "/$e").join("; ")),
@ -560,6 +568,24 @@ class _AccountSettingsState extends State<AccountSettingsWidget> {
);
}
Future<void> _onLabelPressed(BuildContext context) async {
final result = await showDialog<String>(
context: context,
builder: (context) => SimpleInputDialog(
titleText: L10n.global().settingsAccountLabelTitle,
buttonText: MaterialLocalizations.of(context).okButtonLabel,
initialText: _label ?? "",
));
if (result == null) {
return;
}
if (result.isEmpty) {
_setLabel(null);
} else {
_setLabel(result);
}
}
Future<void> _onIncludedFoldersPressed() async {
try {
final result = await Navigator.of(context).pushNamed<Account>(
@ -650,6 +676,24 @@ class _AccountSettingsState extends State<AccountSettingsWidget> {
}
}
Future<void> _setLabel(String? value) async {
_log.info("[_setLabel] New value: $value");
final oldValue = _label;
setState(() {
_label = value;
});
if (!await AccountPref.of(_account).setAccountLabel(value)) {
_log.severe("[_setLabel] Failed writing pref");
SnackBarManager().showSnackBar(SnackBar(
content: Text(L10n.global().writePreferenceFailureNotification),
duration: k.snackBarDurationNormal,
));
setState(() {
_label = oldValue;
});
}
}
Future<void> _setShareFolder(String value) async {
_log.info("[_setShareFolder] New value: $value");
final oldValue = _shareFolder;
@ -672,6 +716,7 @@ class _AccountSettingsState extends State<AccountSettingsWidget> {
late Account _account;
late bool _isEnableFaceRecognitionApp;
late String _shareFolder;
late String? _label;
static final _log = Logger("widget.settings._AccountSettingsState");
}