diff --git a/packages/neon/neon/lib/src/app.dart b/packages/neon/neon/lib/src/app.dart index 2d38c625..0f812909 100644 --- a/packages/neon/neon/lib/src/app.dart +++ b/packages/neon/neon/lib/src/app.dart @@ -171,22 +171,18 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra if (account == null) { return; } - final appImplementation = Provider.of>(context, listen: false) - .singleWhere((final a) => a.id == 'notifications'); - await _accountsBloc.getAppsBloc(account).getAppBloc(appImplementation).refresh(); + final app = Provider.of>(context, listen: false).find('notifications'); + if (app != null) { + await _accountsBloc.getAppsBloc(account).getAppBloc(app).refresh(); + } }; Global.onPushNotificationClicked = (final pushNotificationWithAccountID) async { final allAppImplementations = Provider.of>(context, listen: false); - final matchingAppImplementations = - allAppImplementations.where((final a) => a.id == pushNotificationWithAccountID.subject.app); - - late AppImplementation appImplementation; - if (matchingAppImplementations.isNotEmpty) { - appImplementation = matchingAppImplementations.single; - } else { - appImplementation = allAppImplementations.singleWhere((final a) => a.id == 'notifications'); - } + final app = (pushNotificationWithAccountID.subject.app != null + ? allAppImplementations.find(pushNotificationWithAccountID.subject.app!) + : null) ?? + allAppImplementations.find('notifications'); final account = _accountsBloc.accounts.value.find(pushNotificationWithAccountID.accountID); if (account == null) { @@ -194,13 +190,15 @@ class _NeonAppState extends State with WidgetsBindingObserver, tray.Tra } _accountsBloc.setActiveAccount(account); - if (appImplementation.id != 'notifications') { - _accountsBloc - .getAppsBloc(account) - .getAppBloc(appImplementation) - .deleteNotification(pushNotificationWithAccountID.subject.nid!); + if (app != null) { + if (app.id != 'notifications') { + _accountsBloc + .getAppsBloc(account) + .getAppBloc(app) + .deleteNotification(pushNotificationWithAccountID.subject.nid!); + } + await _openAppFromExternal(account, app.id); } - await _openAppFromExternal(account, appImplementation.id); }; final details = await localNotificationsPlugin.getNotificationAppLaunchDetails(); diff --git a/packages/neon/neon/lib/src/blocs/accounts.dart b/packages/neon/neon/lib/src/blocs/accounts.dart index 9bebe6d7..457e09ec 100644 --- a/packages/neon/neon/lib/src/blocs/accounts.dart +++ b/packages/neon/neon/lib/src/blocs/accounts.dart @@ -37,13 +37,13 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState final as = accounts.value; if (_globalOptions.rememberLastUsedAccount.value && _storage.containsKey(_keyLastUsedAccount)) { final lastUsedAccountID = _storage.getString(_keyLastUsedAccount); - activeAccount.add(as.singleWhere((final account) => account.id == lastUsedAccountID)); + activeAccount.add(lastUsedAccountID != null ? as.find(lastUsedAccountID) : null); } else { unawaited( _globalOptions.initialAccount.stream.first.then((final lastAccount) { - final matches = as.where((final account) => account.id == lastAccount).toList(); - if (matches.isNotEmpty) { - activeAccount.add(matches[0]); + final account = lastAccount != null ? as.find(lastAccount) : null; + if (account != null) { + activeAccount.add(account); } }), ); diff --git a/packages/neon/neon/lib/src/blocs/apps.dart b/packages/neon/neon/lib/src/blocs/apps.dart index 319eca16..129539f5 100644 --- a/packages/neon/neon/lib/src/blocs/apps.dart +++ b/packages/neon/neon/lib/src/blocs/apps.dart @@ -37,7 +37,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates unawaited( options.initialApp.stream.first.then((var initialApp) async { if (initialApp == null) { - if (result.data!.where((final a) => a.id == 'files').isNotEmpty) { + if (result.data!.find('files') != null) { initialApp = 'files'; } else if (result.data!.isNotEmpty) { // This should never happen, because the files app is always installed and can not be removed, but just in @@ -126,10 +126,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates @override Future setActiveApp(final String? appID) async { - if ((await appImplementations.firstWhere((final a) => a.data != null)) - .data! - .where((final app) => app.id == appID) - .isNotEmpty) { + if (appID != null && (await appImplementations.firstWhere((final a) => a.data != null)).data!.find(appID) != null) { if (activeAppID.valueOrNull != appID) { activeAppID.add(appID); } diff --git a/packages/neon/neon/lib/src/pages/home.dart b/packages/neon/neon/lib/src/pages/home.dart index 796f3f67..6915eac4 100644 --- a/packages/neon/neon/lib/src/pages/home.dart +++ b/packages/neon/neon/lib/src/pages/home.dart @@ -216,7 +216,7 @@ class _HomePageState extends State { builder: (final context) { if (accountsSnapshot.hasData) { final accounts = accountsSnapshot.data!; - final account = accounts.singleWhere((final account) => account.id == widget.account.id); + final account = accounts.find(widget.account.id)!; final isQuickBar = navigationMode == NavigationMode.quickBar; final drawer = Drawer( @@ -326,11 +326,8 @@ class _HomePageState extends State { ) .toList(), onChanged: (final id) { - for (final account in accounts) { - if (account.id == id) { - _accountsBloc.setActiveAccount(account); - break; - } + if (id != null) { + _accountsBloc.setActiveAccount(accounts.find(id)); } }, ), @@ -474,7 +471,7 @@ class _HomePageState extends State { Flexible( child: Text( appImplementations.data! - .singleWhere((final a) => a.id == activeAppIDSnapshot.data!) + .find(activeAppIDSnapshot.data!)! .name(context), ), ), @@ -583,7 +580,7 @@ class _HomePageState extends State { if (activeAppIDSnapshot.hasData) ...[ Expanded( child: appImplementations.data! - .singleWhere((final a) => a.id == activeAppIDSnapshot.data!) + .find(activeAppIDSnapshot.data!)! .buildPage(context, _appsBloc), ), ], diff --git a/packages/neon/neon/lib/src/pages/login.dart b/packages/neon/neon/lib/src/pages/login.dart index 4edf6d19..88f71b22 100644 --- a/packages/neon/neon/lib/src/pages/login.dart +++ b/packages/neon/neon/lib/src/pages/login.dart @@ -61,12 +61,11 @@ class _LoginPageState extends State { _accountsBloc.updateAccount(account); Navigator.of(context).pop(); } else { - for (final a in _accountsBloc.accounts.value) { - if (a.id == account.id) { - NeonException.showSnackbar(context, AppLocalizations.of(context).errorAccountAlreadyExists); - await _loginBloc.refresh(); - return; - } + final existingAccount = _accountsBloc.accounts.value.find(account.id); + if (existingAccount != null) { + NeonException.showSnackbar(context, AppLocalizations.of(context).errorAccountAlreadyExists); + await _loginBloc.refresh(); + return; } _accountsBloc ..addAccount(account) diff --git a/packages/neon/neon/lib/src/utils/app_implementation.dart b/packages/neon/neon/lib/src/utils/app_implementation.dart index ac0245c4..a3159d40 100644 --- a/packages/neon/neon/lib/src/utils/app_implementation.dart +++ b/packages/neon/neon/lib/src/utils/app_implementation.dart @@ -46,3 +46,15 @@ abstract class AppImplementation { + AppImplementation? find(final String appID) { + for (final app in this) { + if (app.id == appID) { + return app; + } + } + + return null; + } +} diff --git a/packages/neon/neon/lib/src/utils/settings_export_helper.dart b/packages/neon/neon/lib/src/utils/settings_export_helper.dart index 5057fdba..83e9d683 100644 --- a/packages/neon/neon/lib/src/utils/settings_export_helper.dart +++ b/packages/neon/neon/lib/src/utils/settings_export_helper.dart @@ -20,26 +20,26 @@ class SettingsExportHelper { final appImplementationsData = data['apps'] as Map; for (final appId in appImplementationsData.keys) { - final matchingAppImplementations = appImplementations.where((final app) => app.id == appId).toList(); - if (matchingAppImplementations.length != 1) { + final app = appImplementations.find(appId); + if (app == null) { return; } final appImplementationData = appImplementationsData[appId]! as Map; await _applyOptionsMapToOptions( - matchingAppImplementations[0].options.options, + app.options.options, appImplementationData, ); } final accountsData = data['accounts'] as Map; for (final accountId in accountsData.keys) { - final matchingAccounts = accountSpecificOptions.keys.where((final account) => account.id == accountId).toList(); - if (matchingAccounts.length != 1) { + final account = accountSpecificOptions.keys.toList().find(accountId); + if (account == null) { return; } final accountData = accountsData[accountId]! as Map; await _applyOptionsMapToOptions( - accountSpecificOptions[matchingAccounts[0]]!, + accountSpecificOptions[account]!, accountData, ); } diff --git a/packages/neon/neon_notifications/lib/pages/main.dart b/packages/neon/neon_notifications/lib/pages/main.dart index 21ffc71e..7e0c0c18 100644 --- a/packages/neon/neon_notifications/lib/pages/main.dart +++ b/packages/neon/neon_notifications/lib/pages/main.dart @@ -50,9 +50,7 @@ class _NotificationsMainPageState extends State { final BuildContext context, final NextcloudNotificationsNotification notification, ) { - final matchingAppImplementations = Provider.of>(context, listen: false) - .where((final a) => a.id == notification.app) - .toList(); + final app = Provider.of>(context, listen: false).find(notification.app); return ListTile( title: Text(notification.subject), @@ -73,8 +71,8 @@ class _NotificationsMainPageState extends State { ), ], ), - leading: matchingAppImplementations.isNotEmpty - ? matchingAppImplementations.single.buildIcon( + leading: app != null + ? app.buildIcon( context, width: 40, height: 40, @@ -93,11 +91,9 @@ class _NotificationsMainPageState extends State { if (notification.app == 'notifications') { return; } - final allAppImplementations = Provider.of>(context, listen: false); - final matchingAppImplementations = allAppImplementations.where((final a) => a.id == notification.app); - if (matchingAppImplementations.isNotEmpty) { + if (app != null) { final accountsBloc = Provider.of(context, listen: false); - await accountsBloc.getAppsBloc(accountsBloc.activeAccount.value!).setActiveApp(notification.app); + await accountsBloc.getAppsBloc(accountsBloc.activeAccount.value!).setActiveApp(app.id); } else { await showDialog( context: context,