diff --git a/packages/neon/neon/lib/l10n/en.arb b/packages/neon/neon/lib/l10n/en.arb index 2372a31e..f302dfde 100644 --- a/packages/neon/neon/lib/l10n/en.arb +++ b/packages/neon/neon/lib/l10n/en.arb @@ -82,6 +82,7 @@ "settings": "Settings", "settingsApps": "Apps", "settingsAccount": "Account", + "settingsAccountManage": "Manage accounts", "settingsExport": "Export settings", "settingsImport": "Import settings", "settingsImportWrongFileExtension": "Settings import has wrong file extension (has to be .json.base64)", diff --git a/packages/neon/neon/lib/l10n/localizations.dart b/packages/neon/neon/lib/l10n/localizations.dart index 647b4cfa..67ba04cd 100644 --- a/packages/neon/neon/lib/l10n/localizations.dart +++ b/packages/neon/neon/lib/l10n/localizations.dart @@ -341,6 +341,12 @@ abstract class AppLocalizations { /// **'Account'** String get settingsAccount; + /// No description provided for @settingsAccountManage. + /// + /// In en, this message translates to: + /// **'Manage accounts'** + String get settingsAccountManage; + /// No description provided for @settingsExport. /// /// In en, this message translates to: diff --git a/packages/neon/neon/lib/l10n/localizations_en.dart b/packages/neon/neon/lib/l10n/localizations_en.dart index 90ba1a2d..45eb240b 100644 --- a/packages/neon/neon/lib/l10n/localizations_en.dart +++ b/packages/neon/neon/lib/l10n/localizations_en.dart @@ -160,6 +160,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get settingsAccount => 'Account'; + @override + String get settingsAccountManage => 'Manage accounts'; + @override String get settingsExport => 'Export settings'; diff --git a/packages/neon/neon/lib/src/widgets/account_switcher.dart b/packages/neon/neon/lib/src/widgets/account_switcher.dart new file mode 100644 index 00000000..869c60de --- /dev/null +++ b/packages/neon/neon/lib/src/widgets/account_switcher.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; +import 'package:neon/l10n/localizations.dart'; +import 'package:neon/src/blocs/accounts.dart'; +import 'package:neon/src/pages/settings.dart'; +import 'package:neon/src/router.dart'; +import 'package:neon/src/theme/dialog.dart'; +import 'package:neon/src/widgets/account_tile.dart'; +import 'package:neon/src/widgets/user_avatar.dart'; +import 'package:provider/provider.dart'; + +@internal +class AccountSwitcherButton extends StatelessWidget { + const AccountSwitcherButton({ + super.key, + }); + + Future _onPressed(final BuildContext context) async { + final accountsBloc = Provider.of(context, listen: false); + final accounts = accountsBloc.accounts.value; + final aa = accountsBloc.activeAccount.value!; + + await showDialog( + context: context, + builder: (final context) { + final body = Column( + children: [ + NeonAccountTile( + account: aa, + trailing: const Icon(Icons.check_circle), + onTap: Navigator.of(context).pop, + ), + const Divider(), + if (accounts.length > 1) + Builder( + builder: (final context) { + final inactiveAccounts = List.of(accounts)..removeWhere((final account) => (account.id == aa.id)); + final tiles = inactiveAccounts.map( + (final account) => NeonAccountTile( + account: account, + onTap: () { + accountsBloc.setActiveAccount(account); + Navigator.of(context).pop(); + }, + ), + ); + + return SingleChildScrollView( + child: ListBody( + children: tiles.toList(), + ), + ); + }, + ), + ListTile( + leading: const Icon(Icons.settings), + title: Text(AppLocalizations.of(context).settingsAccountManage), + onTap: () { + Navigator.of(context).pop(); + const SettingsRoute(initialCategory: SettingsCageories.accounts).push(context); + }, + ) + ], + ); + + return Dialog( + child: IntrinsicHeight( + child: Container( + padding: const EdgeInsets.all(24), + constraints: NeonDialogTheme.of(context).constraints, + child: body, + ), + ), + ); + }, + ); + } + + @override + Widget build(final BuildContext context) { + final accountsBloc = Provider.of(context, listen: false); + final account = accountsBloc.activeAccount.value!; + + return IconButton( + onPressed: () async => _onPressed(context), + tooltip: AppLocalizations.of(context).settingsAccount, + icon: NeonUserAvatar( + account: account, + ), + ); + } +} diff --git a/packages/neon/neon/lib/src/widgets/app_bar.dart b/packages/neon/neon/lib/src/widgets/app_bar.dart index 383c85dc..8933c57e 100644 --- a/packages/neon/neon/lib/src/widgets/app_bar.dart +++ b/packages/neon/neon/lib/src/widgets/app_bar.dart @@ -9,7 +9,7 @@ import 'package:neon/src/blocs/apps.dart'; import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/app_implementation.dart'; import 'package:neon/src/models/notifications_interface.dart'; -import 'package:neon/src/router.dart'; +import 'package:neon/src/widgets/account_switcher.dart'; import 'package:neon/src/widgets/app_implementation_icon.dart'; import 'package:neon/src/widgets/exception.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart'; @@ -77,17 +77,9 @@ class NeonAppBar extends StatelessWidget implements PreferredSizeWidget { ], ], ), - actions: [ - const NotificationIconButton(), - IconButton( - onPressed: () { - AccountSettingsRoute(accountid: account.id).go(context); - }, - tooltip: AppLocalizations.of(context).settingsAccount, - icon: NeonUserAvatar( - account: account, - ), - ), + actions: const [ + NotificationIconButton(), + AccountSwitcherButton(), ], ), ),