[client] Separate login/logout MaterialApps

This commit is contained in:
Abhishek Shroff
2025-04-16 19:59:40 +05:30
parent a6b2214265
commit f3965eb399
6 changed files with 164 additions and 105 deletions

View File

@@ -1,7 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
import 'package:go_router/go_router.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/integrations/download_manager.dart';
@@ -10,7 +9,7 @@ import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/libphylum/phylum_api_types.dart';
import 'package:phylum/ui/app/action_queue_status_notifier.dart';
import 'package:phylum/ui/app/app_layout.dart';
import 'package:phylum/ui/app/app_logout.dart';
import 'package:phylum/ui/logout/logout_app.dart';
import 'package:phylum/libphylum/explorer/page.dart';
import 'package:provider/provider.dart';
@@ -80,20 +79,8 @@ class _PhylumAppState extends State<PhylumApp> {
shortcuts: getAppShortcuts(),
);
}
return MaterialApp.router(
key: ValueKey('loggingout'),
title: 'Logging Out | Phylum',
debugShowCheckedModeBanner: false,
theme: theme,
darkTheme: darkTheme,
routerConfig: createLogoutRouter(),
);
return const LogoutApp();
}
RouterConfig<Object> createLogoutRouter() => GoRouter(
errorBuilder: (context, state) => const AppLogout(),
routes: [],
);
}
class PhylumRouteInformationParser extends RouteInformationParser<ExplorerPage> {
@@ -147,12 +134,6 @@ class PhylumRouterDelegate extends RouterDelegate<ExplorerPage>
return Navigator(
key: navigatorKey,
onGenerateRoute: (settings) => MaterialPageRoute(builder: (context) => const AppLayout()),
// pages: [
// MaterialPage(
// child: const AppLayout(),
// onPopInvoked: (didPop, result) => navigator.goBack(),
// )
// ],
);
}
@@ -164,67 +145,6 @@ class PhylumRouterDelegate extends RouterDelegate<ExplorerPage>
@override
Future<void> setNewRoutePath(ExplorerPage configuration) {
// navigator.go(configuration);
return SynchronousFuture(null);
}
}
// sealed class PhylumRoute {
// Uri get uri;
// ExplorerPage get page;
// const PhylumRoute();
// }
// class PhylumRouteHome extends PhylumRoute {
// @override
// Uri get uri => Uri(path: '/home');
// @override
// ExplorerPage get page => const ExplorerPageHome();
// const PhylumRouteHome();
// }
// class PhylumRouteFolder extends PhylumRoute {
// @override
// Uri get uri => Uri(path: '/folder/$folderId');
// final String folderId;
// @override
// ExplorerPage get page => ExplorerPageFolder(folderId: folderId);
// const PhylumRouteFolder(this.folderId);
// }
// class PhylumRouteRecents extends PhylumRoute {
// @override
// Uri get uri => Uri(path: '/recents');
// @override
// ExplorerPage get page => const ExplorerPageRecents();
// const PhylumRouteRecents();
// }
// class PhylumRouteShared extends PhylumRoute {
// @override
// Uri get uri => Uri(path: '/shared');
// @override
// ExplorerPage get page => const ExplorerPageShared();
// const PhylumRouteShared();
// }
// class PhylumRouteTrash extends PhylumRoute {
// @override
// Uri get uri => Uri(path: '/trash');
// @override
// ExplorerPage get page => const ExplorerPageTrash();
// const PhylumRouteTrash();
// }

View File

@@ -14,7 +14,7 @@ import 'package:phylum/integrations/directories.dart';
import 'package:phylum/libphylum/actions/deserializers.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/login_page.dart';
import 'package:phylum/ui/login/login_app.dart';
import 'package:phylum/util/logging.dart';
import 'package:provider/provider.dart';
@@ -36,7 +36,6 @@ void main() async {
};
logger.log(lvl, message, error: error, stackTrace: stackTrace);
};
// GoRouter.optionURLReflectsImperativeAPIs = true;
// We use multiple distinct databases for different accounts, so this is expected behavior
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
@@ -70,9 +69,8 @@ void main() async {
class AccountSelector extends StatelessWidget {
final AccountManager<PhylumAccount> accountManager;
final Key _loginAppKey = UniqueKey();
AccountSelector({
const AccountSelector({
super.key,
required this.accountManager,
});
@@ -86,23 +84,8 @@ class AccountSelector extends StatelessWidget {
context.select<AccountManagerState<PhylumAccount>, PhylumAccount?>((state) => state.selectedAccount);
if (account == null) {
return buildLoginPage(context);
return const LoginApp(key: ValueKey('login'));
}
return PhylumApp.create(account);
});
Widget buildLoginPage(BuildContext context) => MaterialApp(
key: _loginAppKey,
title: 'Login | Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
initialRoute: '/',
onGenerateRoute: (settings) {
return MaterialPageRoute(
settings: settings,
builder: (context) => const LoginPage(),
);
},
);
}

View File

@@ -0,0 +1,84 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:uri/uri.dart';
import 'login_page.dart';
class LoginApp extends StatefulWidget {
const LoginApp({super.key});
@override
State<LoginApp> createState() => _LoginAppState();
}
class _LoginAppState extends State<LoginApp> {
final delegate = LoginRouterDelegate();
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Login | Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
routeInformationParser: const LoginRouteInformationParser(),
routerDelegate: delegate,
);
}
}
class LoginRouteConfiguration {
final String? next;
LoginRouteConfiguration(this.next);
}
class LoginRouteInformationParser extends RouteInformationParser<LoginRouteConfiguration> {
const LoginRouteInformationParser();
@override
Future<LoginRouteConfiguration> parseRouteInformation(RouteInformation routeInformation) {
final uri = routeInformation.uri;
final segments = uri.pathSegments;
final next = (segments.isEmpty || (segments.length == 1 && segments[0] == 'home')) ? null : uri.path;
return SynchronousFuture(LoginRouteConfiguration(next));
}
@override
RouteInformation? restoreRouteInformation(LoginRouteConfiguration configuration) {
final b = UriBuilder()..path = '/login';
if (configuration.next != null) {
b.queryParameters['next'] = configuration.next!;
}
return RouteInformation(uri: b.build());
}
}
class LoginRouterDelegate extends RouterDelegate<LoginRouteConfiguration>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<LoginRouteConfiguration> {
@override
final navigatorKey = GlobalKey<NavigatorState>();
LoginRouterDelegate();
LoginRouteConfiguration? _currentConfiguration;
@override
LoginRouteConfiguration? get currentConfiguration => _currentConfiguration;
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
onGenerateRoute: (settings) => MaterialPageRoute(builder: (context) => const LoginPage()),
);
}
@override
Future<void> setNewRoutePath(LoginRouteConfiguration configuration) {
_currentConfiguration = configuration;
notifyListeners();
return SynchronousFuture(null);
}
}

View File

@@ -27,7 +27,8 @@ class _LoginPageState extends State<LoginPage> {
String? urlError;
String? emailError;
bool get serverUrlValid => (kIsWeb && serverUrl == Uri()) || (serverUrl?.hasScheme == true && serverUrl?.hasAuthority == true);
bool get serverUrlValid =>
(kIsWeb && serverUrl == Uri()) || (serverUrl?.hasScheme == true && serverUrl?.hasAuthority == true);
@override
void initState() {

View File

@@ -0,0 +1,71 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:phylum/ui/logout/logout_page.dart';
class LogoutApp extends StatefulWidget {
const LogoutApp({super.key});
@override
State<LogoutApp> createState() => _LoginAppState();
}
class _LoginAppState extends State<LogoutApp> {
final delegate = LogoutRouterDelegate();
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Login | Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
routeInformationParser: const LogoutRouteInformationParser(),
routerDelegate: delegate,
);
}
}
class LogoutRouteConfiguration {
const LogoutRouteConfiguration();
}
class LogoutRouteInformationParser extends RouteInformationParser<LogoutRouteConfiguration> {
const LogoutRouteInformationParser();
@override
Future<LogoutRouteConfiguration> parseRouteInformation(RouteInformation routeInformation) {
return SynchronousFuture(const LogoutRouteConfiguration());
}
@override
RouteInformation? restoreRouteInformation(LogoutRouteConfiguration configuration) {
return RouteInformation(uri: Uri(path: '/logout'));
}
}
class LogoutRouterDelegate extends RouterDelegate<LogoutRouteConfiguration>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<LogoutRouteConfiguration> {
@override
final navigatorKey = GlobalKey<NavigatorState>();
LogoutRouterDelegate();
LogoutRouteConfiguration? _currentConfiguration;
@override
LogoutRouteConfiguration? get currentConfiguration => _currentConfiguration;
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
onGenerateRoute: (settings) => MaterialPageRoute(builder: (context) => const LogoutPage()),
);
}
@override
Future<void> setNewRoutePath(LogoutRouteConfiguration configuration) {
_currentConfiguration = configuration;
notifyListeners();
return SynchronousFuture(null);
}
}

View File

@@ -3,8 +3,8 @@ import 'package:offtheline/offtheline.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:provider/provider.dart';
class AppLogout extends StatelessWidget {
const AppLogout({super.key});
class LogoutPage extends StatelessWidget {
const LogoutPage({super.key});
@override
Widget build(BuildContext context) {