diff --git a/packages/neon/neon/lib/src/widgets/account_selection_dialog.dart b/packages/neon/neon/lib/src/widgets/account_selection_dialog.dart new file mode 100644 index 00000000..94fbcd66 --- /dev/null +++ b/packages/neon/neon/lib/src/widgets/account_selection_dialog.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; +import 'package:neon/src/blocs/accounts.dart'; +import 'package:neon/src/theme/dialog.dart'; +import 'package:neon/src/widgets/account_tile.dart'; +import 'package:provider/provider.dart'; + +@internal +class NeonAccountSelectionDialog extends StatelessWidget { + const NeonAccountSelectionDialog({ + this.highlightActiveAccount = false, + this.children, + super.key, + }); + + final bool highlightActiveAccount; + final List? children; + + @override + Widget build(final BuildContext context) { + final accountsBloc = Provider.of(context, listen: false); + final accounts = accountsBloc.accounts.value; + final activeAccount = accountsBloc.activeAccount.value!; + + final sortedAccounts = List.of(accounts) + ..removeWhere((final account) => account.id == activeAccount.id) + ..insert(0, activeAccount); + + final tiles = sortedAccounts + .map( + (final account) => NeonAccountTile( + account: account, + trailing: highlightActiveAccount && account.id == activeAccount.id ? const Icon(Icons.check_circle) : null, + onTap: () { + Navigator.of(context).pop(account); + }, + ), + ) + .toList(); + if (highlightActiveAccount && accounts.length > 1) { + tiles.insert(1, const Divider()); + } + + final body = SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ...tiles, + ...?children, + ], + ), + ); + + return Dialog( + child: IntrinsicHeight( + child: Container( + padding: const EdgeInsets.all(24), + constraints: NeonDialogTheme.of(context).constraints, + child: body, + ), + ), + ); + } +} diff --git a/packages/neon/neon/lib/src/widgets/account_switcher.dart b/packages/neon/neon/lib/src/widgets/account_switcher.dart deleted file mode 100644 index 539218ee..00000000 --- a/packages/neon/neon/lib/src/widgets/account_switcher.dart +++ /dev/null @@ -1,92 +0,0 @@ -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/account_switcher_button.dart b/packages/neon/neon/lib/src/widgets/account_switcher_button.dart new file mode 100644 index 00000000..36e69452 --- /dev/null +++ b/packages/neon/neon/lib/src/widgets/account_switcher_button.dart @@ -0,0 +1,56 @@ +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/models/account.dart'; +import 'package:neon/src/pages/settings.dart'; +import 'package:neon/src/router.dart'; +import 'package:neon/src/widgets/account_selection_dialog.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 account = await showDialog( + context: context, + builder: (final context) => NeonAccountSelectionDialog( + highlightActiveAccount: true, + children: [ + ListTile( + leading: const Icon(Icons.settings), + title: Text(AppLocalizations.of(context).settingsAccountManage), + onTap: () { + Navigator.of(context).pop(); + const SettingsRoute(initialCategory: SettingsCageories.accounts).push(context); + }, + ), + ], + ), + ); + + if (account != null) { + accountsBloc.setActiveAccount(account); + } + } + + @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 df6eef6e..84abc267 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/widgets/account_switcher.dart'; +import 'package:neon/src/widgets/account_switcher_button.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';