16 changed files with 659 additions and 477 deletions
			
			
		| @ -1,23 +1,36 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:intersperse/intersperse.dart'; | ||||
| import 'package:meta/meta.dart'; | ||||
| import 'package:neon/src/settings/widgets/settings_category.dart'; | ||||
| import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; | ||||
| 
 | ||||
| @internal | ||||
| class SettingsList extends StatelessWidget { | ||||
|   const SettingsList({ | ||||
|     required this.categories, | ||||
|     this.initialCategory, | ||||
|     super.key, | ||||
|   }); | ||||
| 
 | ||||
|   final List<SettingsCategory> categories; | ||||
|   final String? initialCategory; | ||||
| 
 | ||||
|   int? _getIndex(final String? initialCategory) { | ||||
|     if (initialCategory == null) { | ||||
|       return null; | ||||
|     } | ||||
| 
 | ||||
|     final key = Key(initialCategory); | ||||
|     final index = categories.indexWhere((final category) => category.key == key); | ||||
| 
 | ||||
|     return index != -1 ? index : null; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(final BuildContext context) => Scrollbar( | ||||
|         child: ListView( | ||||
|           primary: true, | ||||
|   Widget build(final BuildContext context) => ScrollablePositionedList.separated( | ||||
|         padding: const EdgeInsets.all(20), | ||||
|           children: categories.cast<Widget>().intersperse(const Divider()).toList(), | ||||
|         ), | ||||
|         itemCount: categories.length, | ||||
|         initialScrollIndex: _getIndex(initialCategory) ?? 0, | ||||
|         itemBuilder: (final context, final index) => categories[index], | ||||
|         separatorBuilder: (final context, final index) => const Divider(), | ||||
|       ); | ||||
| } | ||||
|  | ||||
| @ -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<void> _onPressed(final BuildContext context) async { | ||||
|     final accountsBloc = Provider.of<AccountsBloc>(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<AccountsBloc>(context, listen: false); | ||||
|     final account = accountsBloc.activeAccount.value!; | ||||
| 
 | ||||
|     return IconButton( | ||||
|       onPressed: () async => _onPressed(context), | ||||
|       tooltip: AppLocalizations.of(context).settingsAccount, | ||||
|       icon: NeonUserAvatar( | ||||
|         account: account, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue