Browse Source

neon: use go_router for the main app page

pull/423/head
Nikolas Rimikis 2 years ago
parent
commit
c00b2b8cac
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 10
      packages/neon/neon/lib/src/app.dart
  2. 24
      packages/neon/neon/lib/src/blocs/accounts.dart
  3. 8
      packages/neon/neon/lib/src/blocs/apps.dart
  4. 14
      packages/neon/neon/lib/src/pages/account_settings.dart
  5. 41
      packages/neon/neon/lib/src/pages/home.dart
  6. 5
      packages/neon/neon/lib/src/pages/login.dart
  7. 12
      packages/neon/neon/lib/src/pages/settings.dart
  8. 73
      packages/neon/neon/lib/src/router.dart
  9. 98
      packages/neon/neon/lib/src/router.g.dart
  10. 4
      packages/neon/neon/lib/src/utils/global_popups.dart
  11. 4
      packages/neon/neon/lib/src/widgets/app_bar.dart
  12. 4
      packages/neon/neon/lib/src/widgets/drawer.dart

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

@ -37,15 +37,12 @@ class NeonApp extends StatefulWidget {
// ignore: prefer_mixin // ignore: prefer_mixin
class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.TrayListener, WindowListener { class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.TrayListener, WindowListener {
final _appRegex = RegExp(r'^app_([a-z]+)$', multiLine: true); final _appRegex = RegExp(r'^app_([a-z]+)$', multiLine: true);
final _navigatorKey = GlobalKey<NavigatorState>(); late final GlobalKey<NavigatorState> _navigatorKey;
late final Iterable<AppImplementation> _appImplementations; late final Iterable<AppImplementation> _appImplementations;
late final NeonPlatform _platform; late final NeonPlatform _platform;
late final GlobalOptions _globalOptions; late final GlobalOptions _globalOptions;
late final AccountsBloc _accountsBloc; late final AccountsBloc _accountsBloc;
late final _routerDelegate = AppRouter( late final AppRouter _routerDelegate;
navigatorKey: _navigatorKey,
accountsBloc: _accountsBloc,
);
Rect? _lastBounds; Rect? _lastBounds;
@ -58,6 +55,9 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, tray.Tra
_globalOptions = Provider.of<GlobalOptions>(context, listen: false); _globalOptions = Provider.of<GlobalOptions>(context, listen: false);
_accountsBloc = Provider.of<AccountsBloc>(context, listen: false); _accountsBloc = Provider.of<AccountsBloc>(context, listen: false);
_routerDelegate = _accountsBloc.router;
_navigatorKey = _routerDelegate.navigatorKey;
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
if (_platform.canUseSystemTray) { if (_platform.canUseSystemTray) {
tray.trayManager.addListener(this); tray.trayManager.addListener(this);

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

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart';
import 'package:neon/src/bloc/bloc.dart'; import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/blocs/apps.dart'; import 'package:neon/src/blocs/apps.dart';
import 'package:neon/src/blocs/capabilities.dart'; import 'package:neon/src/blocs/capabilities.dart';
@ -10,6 +10,7 @@ import 'package:neon/src/blocs/user_statuses.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/models/app_implementation.dart'; import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/platform/platform.dart'; import 'package:neon/src/platform/platform.dart';
import 'package:neon/src/router.dart';
import 'package:neon/src/settings/models/storage.dart'; import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/account_options.dart'; import 'package:neon/src/utils/account_options.dart';
import 'package:neon/src/utils/global_options.dart'; import 'package:neon/src/utils/global_options.dart';
@ -63,6 +64,11 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
this._globalOptions, this._globalOptions,
this._allAppImplementations, this._allAppImplementations,
) { ) {
router = AppRouter(
navigatorKey: GlobalKey<NavigatorState>(),
accountsBloc: this,
appImplementations: _allAppImplementations,
);
accounts accounts
..add(loadAccounts(_storage)) ..add(loadAccounts(_storage))
..listen((final as) async { ..listen((final as) async {
@ -109,6 +115,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
final SharedPreferences _sharedPreferences; final SharedPreferences _sharedPreferences;
final GlobalOptions _globalOptions; final GlobalOptions _globalOptions;
final Iterable<AppImplementation> _allAppImplementations; final Iterable<AppImplementation> _allAppImplementations;
late final AppRouter router;
final _keyLastUsedAccount = 'last-used-account'; final _keyLastUsedAccount = 'last-used-account';
final _accountsOptions = <String, AccountSpecificOptions>{}; final _accountsOptions = <String, AccountSpecificOptions>{};
@ -134,8 +141,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
BehaviorSubject<List<Account>> accounts = BehaviorSubject<List<Account>>.seeded([]); BehaviorSubject<List<Account>> accounts = BehaviorSubject<List<Account>>.seeded([]);
@override @override
BehaviorSubject<Account?> activeAccount = BehaviorSubject<Account?>.seeded(null) BehaviorSubject<Account?> activeAccount = BehaviorSubject<Account?>.seeded(null);
..distinct((final current, final next) => current?.id != next?.id);
@override @override
void addAccount(final Account account) { void addAccount(final Account account) {
@ -154,6 +160,9 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
if (aa?.id == account.id) { if (aa?.id == account.id) {
if (as.firstOrNull != null) { if (as.firstOrNull != null) {
setActiveAccount(as.first); setActiveAccount(as.first);
final activeApp = getAppsBlocFor(as.first).activeApp.value.initialRouteName;
router.goNamed(activeApp);
} else { } else {
activeAccount.add(null); activeAccount.add(null);
} }
@ -171,7 +180,13 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
@override @override
void setActiveAccount(final Account account) { void setActiveAccount(final Account account) {
activeAccount.add(account); if (activeAccount.valueOrNull?.id != account.id) {
if (activeAccount.valueOrNull == null) {
router.go(const HomeRoute().location);
}
activeAccount.add(account);
}
} }
@override @override
@ -240,6 +255,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
this, this,
account, account,
_allAppImplementations, _allAppImplementations,
router,
); );
} }

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

@ -9,6 +9,7 @@ import 'package:neon/src/blocs/capabilities.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/models/app_implementation.dart'; import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/models/notifications_interface.dart'; import 'package:neon/src/models/notifications_interface.dart';
import 'package:neon/src/router.dart';
import 'package:neon/src/settings/models/nextcloud_app_options.dart'; import 'package:neon/src/settings/models/nextcloud_app_options.dart';
import 'package:neon/src/utils/request_manager.dart'; import 'package:neon/src/utils/request_manager.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
@ -43,6 +44,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
this._accountsBloc, this._accountsBloc,
this._account, this._account,
this._allAppImplementations, this._allAppImplementations,
this._router,
) { ) {
apps.listen((final result) { apps.listen((final result) {
appImplementations appImplementations
@ -156,6 +158,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
final AccountsBloc _accountsBloc; final AccountsBloc _accountsBloc;
final Account _account; final Account _account;
final Iterable<AppImplementation> _allAppImplementations; final Iterable<AppImplementation> _allAppImplementations;
final AppRouter _router;
@override @override
void dispose() { void dispose() {
@ -216,6 +219,11 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
if (app != null) { if (app != null) {
if (activeApp.valueOrNull?.id != appID) { if (activeApp.valueOrNull?.id != appID) {
activeApp.add(app); activeApp.add(app);
// avoid inactive accounts calling the navigator with a potentially unsupported app.
if (_accountsBloc.activeAccount.value?.id == _account.id) {
_router.goNamed(app.initialRouteName);
}
} }
} else { } else {
throw Exception('App $appID not found'); throw Exception('App $appID not found');

14
packages/neon/neon/lib/src/pages/account_settings.dart

@ -5,7 +5,6 @@ import 'package:neon/l10n/localizations.dart';
import 'package:neon/src/bloc/result_builder.dart'; import 'package:neon/src/bloc/result_builder.dart';
import 'package:neon/src/blocs/accounts.dart'; import 'package:neon/src/blocs/accounts.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/router.dart';
import 'package:neon/src/settings/widgets/custom_settings_tile.dart'; import 'package:neon/src/settings/widgets/custom_settings_tile.dart';
import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart'; import 'package:neon/src/settings/widgets/dropdown_button_settings_tile.dart';
import 'package:neon/src/settings/widgets/settings_category.dart'; import 'package:neon/src/settings/widgets/settings_category.dart';
@ -41,20 +40,7 @@ class AccountSettingsPage extends StatelessWidget {
context, context,
AppLocalizations.of(context).accountOptionsRemoveConfirm(account.client.humanReadableID), AppLocalizations.of(context).accountOptionsRemoveConfirm(account.client.humanReadableID),
)) { )) {
final isActive = bloc.activeAccount.value == account;
bloc.removeAccount(account); bloc.removeAccount(account);
// ignore: use_build_context_synchronously
if (!context.mounted) {
return;
}
if (isActive) {
const HomeRoute().go(context);
} else {
Navigator.of(context).pop();
}
} }
}, },
tooltip: AppLocalizations.of(context).accountOptionsRemove, tooltip: AppLocalizations.of(context).accountOptionsRemove,

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

@ -21,9 +21,12 @@ const kQuickBarWidth = kAvatarSize + 20;
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
const HomePage({ const HomePage({
this.appView,
super.key, super.key,
}); });
final Widget? appView;
@override @override
State<HomePage> createState() => _HomePageState(); State<HomePage> createState() => _HomePageState();
} }
@ -121,34 +124,26 @@ class _HomePageState extends State<HomePage> {
const drawer = NeonDrawer(); const drawer = NeonDrawer();
const appBar = NeonAppBar(); const appBar = NeonAppBar();
final appView = ResultBuilder<Iterable<AppImplementation>>.behaviorSubject( final appView = widget.appView ??
stream: _appsBloc.appImplementations, ResultBuilder<Iterable<AppImplementation>>.behaviorSubject(
builder: (final context, final appImplementations) { stream: _appsBloc.appImplementations,
if (!appImplementations.hasData) { builder: (final context, final appImplementations) {
return const SizedBox(); if (!appImplementations.hasData) {
}
if (appImplementations.requireData.isEmpty) {
return Center(
child: Text(
AppLocalizations.of(context).errorNoCompatibleNextcloudAppsFound,
textAlign: TextAlign.center,
),
);
}
return StreamBuilder<AppImplementation>(
stream: _appsBloc.activeApp,
builder: (final context, final activeAppIDSnapshot) {
if (!activeAppIDSnapshot.hasData) {
return const SizedBox(); return const SizedBox();
} }
return activeAppIDSnapshot.requireData.page; if (appImplementations.requireData.isEmpty) {
return Center(
child: Text(
AppLocalizations.of(context).errorNoCompatibleNextcloudAppsFound,
textAlign: TextAlign.center,
),
);
}
return const SizedBox();
}, },
); );
},
);
final body = OptionBuilder<global_options.NavigationMode>( final body = OptionBuilder<global_options.NavigationMode>(
option: _globalOptions.navigationMode, option: _globalOptions.navigationMode,

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

@ -5,7 +5,6 @@ import 'package:neon/src/blocs/login.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
import 'package:neon/src/models/branding.dart'; import 'package:neon/src/models/branding.dart';
import 'package:neon/src/platform/platform.dart'; import 'package:neon/src/platform/platform.dart';
import 'package:neon/src/router.dart';
import 'package:neon/src/utils/validators.dart'; import 'package:neon/src/utils/validators.dart';
import 'package:neon/src/widgets/exception.dart'; import 'package:neon/src/widgets/exception.dart';
import 'package:neon/src/widgets/linear_progress_indicator.dart'; import 'package:neon/src/widgets/linear_progress_indicator.dart';
@ -99,10 +98,6 @@ class _LoginPageState extends State<LoginPage> {
..addAccount(account) ..addAccount(account)
..setActiveAccount(account); ..setActiveAccount(account);
} }
if (mounted) {
const HomeRoute().go(context);
}
} catch (e, s) { } catch (e, s) {
debugPrint(e.toString()); debugPrint(e.toString());
debugPrint(s.toString()); debugPrint(s.toString());

12
packages/neon/neon/lib/src/pages/settings.dart

@ -106,9 +106,7 @@ class _SettingsPageState extends State<SettingsPage> {
CustomSettingsTile( CustomSettingsTile(
leading: appImplementation.buildIcon(), leading: appImplementation.buildIcon(),
title: Text(appImplementation.name(context)), title: Text(appImplementation.name(context)),
onTap: () { onTap: () async => NextcloudAppSettingsRoute(appid: appImplementation.id).push(context),
NextcloudAppSettingsRoute(appid: appImplementation.id).go(context);
},
), ),
], ],
], ],
@ -201,16 +199,12 @@ class _SettingsPageState extends State<SettingsPage> {
for (final account in accountsSnapshot.requireData) ...[ for (final account in accountsSnapshot.requireData) ...[
AccountSettingsTile( AccountSettingsTile(
account: account, account: account,
onTap: () { onTap: () async => AccountSettingsRoute(accountid: account.id).push(context),
AccountSettingsRoute(accountid: account.id).go(context);
},
), ),
], ],
CustomSettingsTile( CustomSettingsTile(
title: ElevatedButton.icon( title: ElevatedButton.icon(
onPressed: () { onPressed: () async => const AddAccountRoute().push(context),
const AddAccountRoute().go(context);
},
icon: Icon(MdiIcons.accountPlus), icon: Icon(MdiIcons.accountPlus),
label: Text(AppLocalizations.of(context).globalOptionsAccountsAdd), label: Text(AppLocalizations.of(context).globalOptionsAccountsAdd),
), ),

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

@ -18,8 +18,9 @@ part 'router.g.dart';
@internal @internal
class AppRouter extends GoRouter { class AppRouter extends GoRouter {
AppRouter({ AppRouter({
required final GlobalKey<NavigatorState> navigatorKey, required this.navigatorKey,
required final AccountsBloc accountsBloc, required final AccountsBloc accountsBloc,
required final Iterable<AppImplementation> appImplementations,
}) : super( }) : super(
debugLogDiagnostics: kDebugMode, debugLogDiagnostics: kDebugMode,
refreshListenable: StreamListenable(accountsBloc.activeAccount), refreshListenable: StreamListenable(accountsBloc.activeAccount),
@ -35,8 +36,30 @@ class AppRouter extends GoRouter {
return null; return null;
}, },
routes: $appRoutes, routes: [
StatefulShellRoute.indexedStack(
branches: appImplementations.map((final a) => a.mainBranch).toList(),
builder: _mainViewBuilder,
),
...$appRoutes,
],
); );
final GlobalKey<NavigatorState> navigatorKey;
}
Widget _mainViewBuilder(
final BuildContext context,
final GoRouterState state, [
final StatefulNavigationShell? navigationShell,
]) {
final accountsBloc = Provider.of<AccountsBloc>(context, listen: false);
final account = accountsBloc.activeAccount.valueOrNull!;
return HomePage(
appView: navigationShell,
key: Key(account.id),
);
} }
@immutable @immutable
@ -62,38 +85,14 @@ class AccountSettingsRoute extends GoRouteData {
@TypedGoRoute<HomeRoute>( @TypedGoRoute<HomeRoute>(
path: '/', path: '/',
name: 'home', name: 'home',
routes: [
TypedGoRoute<SettingsRoute>(
path: 'settings',
name: 'Settings',
routes: [
TypedGoRoute<NextcloudAppSettingsRoute>(
path: 'apps/:appid',
name: 'NextcloudAppSettings',
),
TypedGoRoute<AddAccountRoute>(
path: 'account/add',
name: 'addAccount',
),
TypedGoRoute<AccountSettingsRoute>(
path: 'account/:accountid',
name: 'AccountSettings',
),
],
)
],
) )
@immutable @immutable
@internal
class HomeRoute extends GoRouteData { class HomeRoute extends GoRouteData {
const HomeRoute(); const HomeRoute();
@override @override
Widget build(final BuildContext context, final GoRouterState state) { Widget build(final BuildContext context, final GoRouterState state) => _mainViewBuilder(context, state);
final accountsBloc = Provider.of<AccountsBloc>(context, listen: false);
final account = accountsBloc.activeAccount.valueOrNull!;
return HomePage(key: Key(account.id));
}
} }
@TypedGoRoute<LoginRoute>( @TypedGoRoute<LoginRoute>(
@ -135,6 +134,24 @@ class NextcloudAppSettingsRoute extends GoRouteData {
} }
} }
@TypedGoRoute<SettingsRoute>(
path: '/settings',
name: 'Settings',
routes: [
TypedGoRoute<NextcloudAppSettingsRoute>(
path: 'apps/:appid',
name: 'NextcloudAppSettings',
),
TypedGoRoute<AddAccountRoute>(
path: 'account/add',
name: 'addAccount',
),
TypedGoRoute<AccountSettingsRoute>(
path: 'account/:accountid',
name: 'AccountSettings',
),
],
)
@immutable @immutable
class SettingsRoute extends GoRouteData { class SettingsRoute extends GoRouteData {
const SettingsRoute(); const SettingsRoute();

98
packages/neon/neon/lib/src/router.g.dart

@ -9,36 +9,13 @@ part of 'router.dart';
List<RouteBase> get $appRoutes => [ List<RouteBase> get $appRoutes => [
$homeRoute, $homeRoute,
$loginRoute, $loginRoute,
$settingsRoute,
]; ];
RouteBase get $homeRoute => GoRouteData.$route( RouteBase get $homeRoute => GoRouteData.$route(
path: '/', path: '/',
name: 'home', name: 'home',
factory: $HomeRouteExtension._fromState, factory: $HomeRouteExtension._fromState,
routes: [
GoRouteData.$route(
path: 'settings',
name: 'Settings',
factory: $SettingsRouteExtension._fromState,
routes: [
GoRouteData.$route(
path: 'apps/:appid',
name: 'NextcloudAppSettings',
factory: $NextcloudAppSettingsRouteExtension._fromState,
),
GoRouteData.$route(
path: 'account/add',
name: 'addAccount',
factory: $AddAccountRouteExtension._fromState,
),
GoRouteData.$route(
path: 'account/:accountid',
name: 'AccountSettings',
factory: $AccountSettingsRouteExtension._fromState,
),
],
),
],
); );
extension $HomeRouteExtension on HomeRoute { extension $HomeRouteExtension on HomeRoute {
@ -55,6 +32,54 @@ extension $HomeRouteExtension on HomeRoute {
void pushReplacement(BuildContext context) => context.pushReplacement(location); void pushReplacement(BuildContext context) => context.pushReplacement(location);
} }
RouteBase get $loginRoute => GoRouteData.$route(
path: '/login',
name: 'login',
factory: $LoginRouteExtension._fromState,
);
extension $LoginRouteExtension on LoginRoute {
static LoginRoute _fromState(GoRouterState state) => LoginRoute(
server: state.queryParameters['server'],
);
String get location => GoRouteData.$location(
'/login',
queryParams: {
if (server != null) 'server': server,
},
);
void go(BuildContext context) => context.go(location);
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
void pushReplacement(BuildContext context) => context.pushReplacement(location);
}
RouteBase get $settingsRoute => GoRouteData.$route(
path: '/settings',
name: 'Settings',
factory: $SettingsRouteExtension._fromState,
routes: [
GoRouteData.$route(
path: 'apps/:appid',
name: 'NextcloudAppSettings',
factory: $NextcloudAppSettingsRouteExtension._fromState,
),
GoRouteData.$route(
path: 'account/add',
name: 'addAccount',
factory: $AddAccountRouteExtension._fromState,
),
GoRouteData.$route(
path: 'account/:accountid',
name: 'AccountSettings',
factory: $AccountSettingsRouteExtension._fromState,
),
],
);
extension $SettingsRouteExtension on SettingsRoute { extension $SettingsRouteExtension on SettingsRoute {
static SettingsRoute _fromState(GoRouterState state) => const SettingsRoute(); static SettingsRoute _fromState(GoRouterState state) => const SettingsRoute();
@ -114,28 +139,3 @@ extension $AccountSettingsRouteExtension on AccountSettingsRoute {
void pushReplacement(BuildContext context) => context.pushReplacement(location); void pushReplacement(BuildContext context) => context.pushReplacement(location);
} }
RouteBase get $loginRoute => GoRouteData.$route(
path: '/login',
name: 'login',
factory: $LoginRouteExtension._fromState,
);
extension $LoginRouteExtension on LoginRoute {
static LoginRoute _fromState(GoRouterState state) => LoginRoute(
server: state.queryParameters['server'],
);
String get location => GoRouteData.$location(
'/login',
queryParams: {
if (server != null) 'server': server,
},
);
void go(BuildContext context) => context.go(location);
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
void pushReplacement(BuildContext context) => context.pushReplacement(location);
}

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

@ -42,9 +42,7 @@ class GlobalPopups {
content: Text(AppLocalizations.of(context).firstLaunchGoToSettingsToEnablePushNotifications), content: Text(AppLocalizations.of(context).firstLaunchGoToSettingsToEnablePushNotifications),
action: SnackBarAction( action: SnackBarAction(
label: AppLocalizations.of(context).settings, label: AppLocalizations.of(context).settings,
onPressed: () { onPressed: () => const SettingsRoute().push(context),
const SettingsRoute().go(context);
},
), ),
), ),
); );

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

@ -80,9 +80,7 @@ class NeonAppBar extends StatelessWidget implements PreferredSizeWidget {
actions: [ actions: [
const NotificationIconButton(), const NotificationIconButton(),
IconButton( IconButton(
onPressed: () { onPressed: () async => AccountSettingsRoute(accountid: account.id).push(context),
AccountSettingsRoute(accountid: account.id).go(context);
},
tooltip: AppLocalizations.of(context).settingsAccount, tooltip: AppLocalizations.of(context).settingsAccount,
icon: NeonUserAvatar( icon: NeonUserAvatar(
account: account, account: account,

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

@ -60,7 +60,7 @@ class __NeonDrawerState extends State<_NeonDrawer> with SingleTickerProviderStat
late AppsBloc _appsBloc; late AppsBloc _appsBloc;
late List<AppImplementation> _apps; late List<AppImplementation> _apps;
int _activeApp = 0; late int _activeApp;
@override @override
void initState() { void initState() {
@ -89,7 +89,7 @@ class __NeonDrawerState extends State<_NeonDrawer> with SingleTickerProviderStat
// selected item is not a registered app like the SettingsPage // selected item is not a registered app like the SettingsPage
if (index >= _apps.length) { if (index >= _apps.length) {
const SettingsRoute().go(context); unawaited(const SettingsRoute().push(context));
return; return;
} }

Loading…
Cancel
Save