Browse Source

Merge pull request #411 from Leptopoda/refactor/activeApp

Refactor/active app
pull/402/head
Nikolas Rimikis 1 year ago committed by GitHub
parent
commit
f0081afbd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      packages/neon/neon/lib/src/app.dart
  2. 4
      packages/neon/neon/lib/src/blocs/accounts.dart
  3. 32
      packages/neon/neon/lib/src/blocs/apps.dart
  4. 2
      packages/neon/neon/lib/src/blocs/push_notifications.dart
  5. 3
      packages/neon/neon/lib/src/models/account.dart
  6. 10
      packages/neon/neon/lib/src/pages/home.dart
  7. 2
      packages/neon/neon/lib/src/pages/login.dart
  8. 4
      packages/neon/neon/lib/src/router.dart
  9. 3
      packages/neon/neon/lib/src/utils/app_implementation.dart
  10. 2
      packages/neon/neon/lib/src/utils/push_utils.dart
  11. 4
      packages/neon/neon/lib/src/utils/settings_export_helper.dart
  12. 10
      packages/neon/neon/lib/src/widgets/app_bar.dart
  13. 2
      packages/neon/neon/lib/src/widgets/drawer.dart
  14. 2
      packages/neon/neon_notifications/lib/pages/main.dart

10
packages/neon/neon/lib/src/app.dart

@ -109,13 +109,13 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
if (_platform.canUsePushNotifications) {
final localNotificationsPlugin = await PushUtils.initLocalNotifications();
Global.onPushNotificationReceived = (final accountID) async {
final account = _accountsBloc.accounts.value.find(accountID);
final account = _accountsBloc.accounts.value.tryFind(accountID);
if (account == null) {
return;
}
final allAppImplementations = Provider.of<Iterable<AppImplementation>>(context, listen: false);
final app = allAppImplementations.find('notifications') as NotificationsAppInterface?;
final app = allAppImplementations.tryFind('notifications') as NotificationsAppInterface?;
if (app == null) {
return;
@ -124,7 +124,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
await _accountsBloc.getAppsBlocFor(account).getAppBloc<NotificationsBlocInterface>(app).refresh();
};
Global.onPushNotificationClicked = (final pushNotificationWithAccountID) async {
final account = _accountsBloc.accounts.value.find(pushNotificationWithAccountID.accountID);
final account = _accountsBloc.accounts.value.tryFind(pushNotificationWithAccountID.accountID);
if (account == null) {
return;
}
@ -132,7 +132,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
final allAppImplementations = Provider.of<Iterable<AppImplementation>>(context, listen: false);
final notificationsApp = allAppImplementations.find('notifications') as NotificationsAppInterface?;
final notificationsApp = allAppImplementations.tryFind('notifications') as NotificationsAppInterface?;
if (notificationsApp != null) {
_accountsBloc
.getAppsBlocFor(account)
@ -140,7 +140,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
.deleteNotification(pushNotificationWithAccountID.subject.nid!);
}
final app = allAppImplementations.find(pushNotificationWithAccountID.subject.app!) ?? notificationsApp;
final app = allAppImplementations.tryFind(pushNotificationWithAccountID.subject.app) ?? notificationsApp;
if (app == null) {
return;
}

4
packages/neon/neon/lib/src/blocs/accounts.dart

@ -65,7 +65,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
if (_globalOptions.rememberLastUsedAccount.value && _storage.containsKey(_keyLastUsedAccount)) {
final lastUsedAccountID = _storage.getString(_keyLastUsedAccount);
if (lastUsedAccountID != null) {
final aa = as.find(lastUsedAccountID);
final aa = as.tryFind(lastUsedAccountID);
if (aa != null) {
setActiveAccount(aa);
}
@ -74,7 +74,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
unawaited(
_globalOptions.initialAccount.stream.first.then((final lastAccount) {
final account = lastAccount != null ? as.find(lastAccount) : null;
final account = as.tryFind(lastAccount);
if (activeAccount.valueOrNull == null) {
if (account != null) {
setActiveAccount(account);

32
packages/neon/neon/lib/src/blocs/apps.dart

@ -3,7 +3,7 @@ part of 'blocs.dart';
typedef NextcloudApp = NextcloudCoreNavigationApps_Ocs_Data;
abstract class AppsBlocEvents {
void setActiveApp(final String? appID);
void setActiveApp(final String appID);
}
abstract class AppsBlocStates {
@ -13,7 +13,7 @@ abstract class AppsBlocStates {
BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation;
BehaviorSubject<String?> get activeAppID;
BehaviorSubject<AppImplementation> get activeApp;
BehaviorSubject get openNotifications;
@ -39,7 +39,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
unawaited(
options.initialApp.stream.first.then((var initialApp) async {
if (initialApp == null) {
if (result.requireData.find('files') != null) {
if (result.requireData.tryFind('files') != null) {
initialApp = 'files';
} else if (result.requireData.isNotEmpty) {
// This should never happen, because the files app is always installed and can not be removed, but just in
@ -47,7 +47,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
initialApp = result.requireData.first.id;
}
}
if (!activeAppID.hasValue) {
if (!activeApp.hasValue && initialApp != null) {
await setActiveApp(initialApp);
}
}),
@ -132,7 +132,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
unawaited(apps.close());
unawaited(appImplementations.close());
unawaited(notificationsAppImplementation.close());
unawaited(activeAppID.close());
unawaited(activeApp.close());
unawaited(openNotifications.close());
unawaited(appVersions.close());
@ -144,7 +144,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
}
@override
BehaviorSubject<String?> activeAppID = BehaviorSubject<String?>();
BehaviorSubject<AppImplementation> activeApp = BehaviorSubject<AppImplementation>();
@override
BehaviorSubject<Result<Iterable<AppImplementation<Bloc, NextcloudAppSpecificOptions>>>> appImplementations =
@ -175,15 +175,19 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
}
@override
Future setActiveApp(final String? appID) async {
if (appID != null &&
(await appImplementations.firstWhere((final a) => a.hasData)).requireData.find(appID) != null) {
if (activeAppID.valueOrNull != appID) {
activeAppID.add(appID);
}
} else if (appID == 'notifications') {
Future setActiveApp(final String appID) async {
if (appID == 'notifications') {
openNotifications.add(null);
} else if (appID != null) {
return;
}
final apps = await appImplementations.firstWhere((final a) => a.hasData);
final app = apps.requireData.tryFind(appID);
if (app != null) {
if (activeApp.valueOrNull?.id != appID) {
activeApp.add(app);
}
} else {
throw Exception('App $appID not found');
}
}

2
packages/neon/neon/lib/src/blocs/push_notifications.dart

@ -52,7 +52,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
Future _setupUnifiedPush() async {
await UnifiedPush.initialize(
onNewEndpoint: (final endpoint, final instance) async {
final account = _accountsBloc.accounts.value.find(instance);
final account = _accountsBloc.accounts.value.tryFind(instance);
if (account == null) {
debugPrint('Account for $instance not found, can not process endpoint');
return;

3
packages/neon/neon/lib/src/models/account.dart

@ -105,5 +105,6 @@ extension NextcloudClientHelpers on NextcloudClient {
}
extension AccountFind on Iterable<Account> {
Account? find(final String accountID) => firstWhereOrNull((final account) => account.id == accountID);
Account? tryFind(final String? accountID) => firstWhereOrNull((final account) => account.id == accountID);
Account find(final String accountID) => firstWhere((final account) => account.id == accountID);
}

10
packages/neon/neon/lib/src/pages/home.dart

@ -100,9 +100,9 @@ class _HomePageState extends State<HomePage> {
@override
Widget build(final BuildContext context) => ResultBuilder<Iterable<AppImplementation>>.behaviorSubject(
stream: _appsBloc.appImplementations,
builder: (final context, final appImplementations) => StreamBuilder<String?>(
stream: _appsBloc.activeAppID,
builder: (final context, final activeAppIDSnapshot) => OptionBuilder<NavigationMode>(
builder: (final context, final appImplementations) => StreamBuilder<AppImplementation>(
stream: _appsBloc.activeApp,
builder: (final context, final activeAppSnapshot) => OptionBuilder<NavigationMode>(
option: _globalOptions.navigationMode,
builder: (final context, final navigationMode) {
final drawerAlwaysVisible = navigationMode == NavigationMode.drawerAlwaysVisible;
@ -124,9 +124,9 @@ class _HomePageState extends State<HomePage> {
),
),
] else ...[
if (activeAppIDSnapshot.hasData) ...[
if (activeAppSnapshot.hasData) ...[
Expanded(
child: appImplementations.data!.find(activeAppIDSnapshot.data!)!.page,
child: activeAppSnapshot.requireData.page,
),
],
],

2
packages/neon/neon/lib/src/pages/login.dart

@ -74,7 +74,7 @@ class _LoginPageState extends State<LoginPage> {
if (widget.serverURL != null) {
_accountsBloc.updateAccount(account);
} else {
final existingAccount = _accountsBloc.accounts.value.find(account.id);
final existingAccount = _accountsBloc.accounts.value.tryFind(account.id);
if (existingAccount != null) {
NeonException.showSnackbar(context, AppLocalizations.of(context).errorAccountAlreadyExists);
await _loginBloc.refresh();

4
packages/neon/neon/lib/src/router.dart

@ -41,7 +41,7 @@ class AccountSettingsRoute extends GoRouteData {
@override
Widget build(final BuildContext context, final GoRouterState state) {
final bloc = Provider.of<AccountsBloc>(context, listen: false);
final account = bloc.accounts.value.find(accountid)!;
final account = bloc.accounts.value.find(accountid);
return AccountSettingsPage(
bloc: bloc,
@ -120,7 +120,7 @@ class NextcloudAppSettingsRoute extends GoRouteData {
@override
Widget build(final BuildContext context, final GoRouterState state) {
final appImplementations = Provider.of<Iterable<AppImplementation>>(context, listen: false);
final appImplementation = appImplementations.find(appid)!;
final appImplementation = appImplementations.tryFind(appid)!;
return NextcloudAppSettingsPage(appImplementation: appImplementation);
}

3
packages/neon/neon/lib/src/utils/app_implementation.dart

@ -74,5 +74,6 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppSpecificO
}
extension AppImplementationFind on Iterable<AppImplementation> {
AppImplementation? find(final String appID) => firstWhereOrNull((final app) => app.id == appID);
AppImplementation? tryFind(final String? appID) => firstWhereOrNull((final app) => app.id == appID);
AppImplementation find(final String appID) => firstWhere((final app) => app.id == appID);
}

2
packages/neon/neon/lib/src/utils/push_utils.dart

@ -82,7 +82,7 @@ class PushUtils {
AndroidBitmap<Object>? largeIconBitmap;
try {
accounts = loadAccounts(AppStorage('accounts', sharedPreferences));
account = accounts.find(instance);
account = accounts.tryFind(instance);
if (account != null) {
notification =
(await account.client.notifications.getNotification(id: pushNotification.subject.nid!)).ocs.data;

4
packages/neon/neon/lib/src/utils/settings_export_helper.dart

@ -20,7 +20,7 @@ class SettingsExportHelper {
final appImplementationsData = data['apps'] as Map<String, dynamic>;
for (final appId in appImplementationsData.keys) {
final app = appImplementations.find(appId);
final app = appImplementations.tryFind(appId);
if (app == null) {
return;
}
@ -33,7 +33,7 @@ class SettingsExportHelper {
final accountsData = data['accounts'] as Map<String, dynamic>;
for (final accountId in accountsData.keys) {
final account = accountSpecificOptions.keys.find(accountId);
final account = accountSpecificOptions.keys.tryFind(accountId);
if (account == null) {
return;
}

10
packages/neon/neon/lib/src/widgets/app_bar.dart

@ -23,18 +23,18 @@ class NeonAppBar extends StatelessWidget implements PreferredSizeWidget {
return ResultBuilder<Iterable<AppImplementation>>.behaviorSubject(
stream: appsBloc.appImplementations,
builder: (final context, final appImplementations) => StreamBuilder<String?>(
stream: appsBloc.activeAppID,
builder: (final context, final activeAppIDSnapshot) => AppBar(
builder: (final context, final appImplementations) => StreamBuilder<AppImplementation>(
stream: appsBloc.activeApp,
builder: (final context, final activeAppSnapshot) => AppBar(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
if (appImplementations.hasData && activeAppIDSnapshot.hasData) ...[
if (activeAppSnapshot.hasData) ...[
Flexible(
child: Text(
appImplementations.requireData.find(activeAppIDSnapshot.data!)!.name(context),
activeAppSnapshot.requireData.name(context),
),
),
],

2
packages/neon/neon/lib/src/widgets/drawer.dart

@ -61,7 +61,7 @@ class __NeonDrawerState extends State<_NeonDrawer> with SingleTickerProviderStat
_appsBloc = _accountsBloc.activeAppsBloc;
_apps = widget.apps.toList();
_activeApp = _apps.indexWhere((final app) => app.id == _appsBloc.activeAppID.valueOrNull);
_activeApp = _apps.indexWhere((final app) => app.id == _appsBloc.activeApp.valueOrNull?.id);
_tabController = TabController(
vsync: this,

2
packages/neon/neon_notifications/lib/pages/main.dart

@ -51,7 +51,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
final BuildContext context,
final NextcloudNotificationsNotification notification,
) {
final app = Provider.of<Iterable<AppImplementation>>(context, listen: false).find(notification.app);
final app = Provider.of<Iterable<AppImplementation>>(context, listen: false).tryFind(notification.app);
return ListTile(
title: Text(notification.subject),

Loading…
Cancel
Save