nc-photos/lib/widget/account_picker_dialog.dart

188 lines
6 KiB
Dart
Raw Normal View History

2021-04-10 06:28:12 +02:00
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:logging/logging.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/account.dart';
2021-07-25 07:00:38 +02:00
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/exception_util.dart' as exception_util;
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/snack_bar_manager.dart';
2021-04-17 10:59:16 +02:00
import 'package:nc_photos/theme.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/widget/home.dart';
import 'package:nc_photos/widget/root_picker.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/widget/sign_in.dart';
/// A dialog that allows the user to switch between accounts
2021-04-10 06:28:12 +02:00
class AccountPickerDialog extends StatefulWidget {
AccountPickerDialog({
2021-07-23 22:05:57 +02:00
Key? key,
required this.account,
2021-04-10 06:28:12 +02:00
}) : super(key: key);
@override
createState() => _AccountPickerDialogState();
final Account account;
}
class _AccountPickerDialogState extends State<AccountPickerDialog> {
@override
initState() {
super.initState();
2021-07-23 22:05:57 +02:00
_accounts = Pref.inst().getAccountsOr([]);
2021-04-10 06:28:12 +02:00
}
@override
build(BuildContext context) {
final otherAccountOptions = _accounts
.where((a) => a != widget.account)
.map((a) => SimpleDialogOption(
2021-07-05 07:24:09 +02:00
padding: const EdgeInsets.symmetric(horizontal: 8),
2021-04-10 06:28:12 +02:00
onPressed: () => _onItemPressed(a),
child: ListTile(
2021-07-05 07:24:09 +02:00
dense: true,
2021-04-10 06:28:12 +02:00
title: Text(a.url),
subtitle: Text(a.username),
trailing: IconButton(
2021-07-02 21:47:01 +02:00
icon: Icon(
Icons.close,
color: AppTheme.getSecondaryTextColor(context),
),
tooltip: L10n.global().deleteTooltip,
2021-07-02 21:47:01 +02:00
onPressed: () => _onRemoveItemPressed(a),
),
2021-04-10 06:28:12 +02:00
),
))
.toList();
final addAccountOptions = [
SimpleDialogOption(
2021-07-05 07:24:09 +02:00
padding: const EdgeInsets.all(8),
2021-04-10 06:28:12 +02:00
onPressed: () {
Navigator.of(context)
..pop()
..pushNamed(SignIn.routeName);
},
child: Tooltip(
message: L10n.global().addServerTooltip,
2021-04-17 10:59:16 +02:00
child: Center(
child: Icon(
Icons.add,
color: AppTheme.getSecondaryTextColor(context),
),
2021-04-10 06:28:12 +02:00
),
),
),
];
return SimpleDialog(
title: ListTile(
2021-07-05 07:24:09 +02:00
dense: true,
2021-04-10 06:28:12 +02:00
title: Text(
widget.account.url,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
widget.account.username,
style: const TextStyle(fontWeight: FontWeight.bold),
),
trailing: IconButton(
icon: Icon(
Icons.edit,
color: AppTheme.getSecondaryTextColor(context),
),
tooltip: L10n.global().editTooltip,
onPressed: () => _onEditPressed(),
),
2021-04-10 06:28:12 +02:00
),
2021-07-05 07:24:09 +02:00
titlePadding: const EdgeInsetsDirectional.fromSTEB(8, 16, 8, 0),
contentPadding: const EdgeInsetsDirectional.fromSTEB(0, 12, 0, 8),
2021-04-10 06:28:12 +02:00
children: otherAccountOptions + addAccountOptions,
);
}
void _onItemPressed(Account account) {
Pref.inst().setCurrentAccountIndex(_accounts.indexOf(account));
Navigator.of(context).pushNamedAndRemoveUntil(Home.routeName, (_) => false,
arguments: HomeArguments(account));
}
void _onRemoveItemPressed(Account account) {
2021-07-23 22:05:57 +02:00
try {
_removeAccount(account);
setState(() {
_accounts = Pref.inst().getAccounts()!;
});
SnackBarManager().showSnackBar(SnackBar(
2021-07-25 07:00:38 +02:00
content:
Text(L10n.global().removeServerSuccessNotification(account.url)),
2021-07-23 22:05:57 +02:00
duration: k.snackBarDurationNormal,
));
} catch (e) {
SnackBarManager().showSnackBar(SnackBar(
content: Text(exception_util.toUserString(e)),
2021-07-23 22:05:57 +02:00
duration: k.snackBarDurationNormal,
));
}
2021-04-10 06:28:12 +02:00
}
void _onEditPressed() async {
try {
2021-07-23 22:05:57 +02:00
final result = await Navigator.of(context).pushNamed<Account>(
RootPicker.routeName,
arguments: RootPickerArguments(widget.account));
if (result != null) {
// we've got a good account
if (result == widget.account) {
// no changes, do nothing
_log.fine("[_onEditPressed] No changes");
Navigator.of(context).pop();
return;
}
2021-07-23 22:05:57 +02:00
final accounts = Pref.inst().getAccounts()!;
if (accounts.contains(result)) {
// conflict with another account. This normally won't happen because
// the app passwords are unique to each entry, but just in case
Navigator.of(context).pop();
SnackBarManager().showSnackBar(SnackBar(
2021-07-25 07:00:38 +02:00
content:
Text(L10n.global().editAccountConflictFailureNotification),
duration: k.snackBarDurationNormal,
));
return;
}
2021-07-23 22:05:57 +02:00
accounts[Pref.inst().getCurrentAccountIndex()!] = result;
Pref.inst()..setAccounts(accounts);
Navigator.pushNamedAndRemoveUntil(
context, Home.routeName, (route) => false,
arguments: HomeArguments(result));
}
} catch (e, stacktrace) {
_log.shout("[_onEditPressed] Exception", e, stacktrace);
SnackBarManager().showSnackBar(SnackBar(
content: Text(exception_util.toUserString(e)),
duration: k.snackBarDurationNormal,
));
Navigator.of(context).pop();
}
}
2021-04-10 06:28:12 +02:00
void _removeAccount(Account account) {
2021-07-23 22:05:57 +02:00
final currentAccounts = Pref.inst().getAccounts()!;
2021-04-10 06:28:12 +02:00
final currentAccount =
2021-07-23 22:05:57 +02:00
currentAccounts[Pref.inst().getCurrentAccountIndex()!];
2021-04-10 06:28:12 +02:00
final newAccounts =
currentAccounts.where((element) => element != account).toList();
final newAccountIndex = newAccounts.indexOf(currentAccount);
if (newAccountIndex == -1) {
throw StateError("Active account not found in resulting account list");
}
Pref.inst()
..setAccounts(newAccounts)
..setCurrentAccountIndex(newAccountIndex);
}
2021-07-23 22:05:57 +02:00
late List<Account> _accounts;
static final _log =
Logger("widget.account_picker_dialog._AccountPickerDialogState");
2021-04-10 06:28:12 +02:00
}