Roadbound-BRR/lib/main.dart

108 lines
3.9 KiB
Dart

import 'package:bus_running_record/pages/home/page.dart' as home_v2;
import 'package:bus_running_record/pages/home_page.dart' as legacy_home;
import "package:bus_running_record/pages/operations_upload/page.dart";
import "package:bus_running_record/pages/invite/page.dart";
import "package:bus_running_record/pages/org_settings/page.dart";
import "package:bus_running_record/pages/auth/page.dart";
import "package:bus_running_record/pages/auth/verify_email_page.dart";
import "package:bus_running_record/pages/station_selection_page.dart";
import "package:bus_running_record/pages/trip_list_page.dart";
import "package:bus_running_record/provider/collaboration_state.dart";
import "package:bus_running_record/provider/supabase_state.dart";
import "package:bus_running_record/constants.dart";
import 'package:flutter/foundation.dart';
import 'package:go_router/go_router.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
await Supabase.initialize(
url: kSupabaseEndpoint,
anonKey: kSupabasePublishableKey,
);
final supabaseProvider = SupabaseProvider();
runApp(RoadboundApp(supabaseProvider: supabaseProvider));
}
class RoadboundApp extends StatefulWidget {
const RoadboundApp({required this.supabaseProvider, super.key});
final SupabaseProvider supabaseProvider;
@override
State<RoadboundApp> createState() => _RoadboundAppState();
}
class _RoadboundAppState extends State<RoadboundApp> {
late final GoRouter _routerConfig = GoRouter(
refreshListenable: widget.supabaseProvider,
routes: [
LoginPage.route,
VerifyEmailPage.route,
home_v2.HomePage.rootRoute,
home_v2.HomePage.channelRoute,
legacy_home.HomePage.route,
StationSelectionPage.route,
TripListPage.route,
OperationsUploadPage.route,
InvitePage.route,
OrganizationSettingsPage.route,
],
redirect: (context, state) {
final isLoggedIn = widget.supabaseProvider.isAuthenticated;
final isValidatingSession = widget.supabaseProvider.isValidatingSession;
final hasSession = widget.supabaseProvider.session != null;
final requestedPath = state.uri.path;
final onLogin = requestedPath == LoginPage.routePath;
final onVerify = requestedPath == VerifyEmailPage.routePath;
final onInvite = requestedPath.startsWith("/invite/");
final onLegacyFlow =
requestedPath == legacy_home.HomePage.routePath ||
requestedPath == StationSelectionPage.routePath ||
requestedPath == TripListPage.routePath;
if (onVerify) return null;
if (onInvite) return null;
if (onLegacyFlow) return null;
// Avoid login flash on cold start: keep current route until
// persisted session validation completes.
if (hasSession && isValidatingSession) return null;
if (!isLoggedIn && !onLogin) return LoginPage.routePath;
if (isLoggedIn && onLogin) {
final next = state.uri.queryParameters["next"];
return (next != null && next.isNotEmpty) ? next : "/";
}
return null;
},
);
@override
Widget build(BuildContext context) {
AdaptiveScaling? adaptiveScaling;
if (defaultTargetPlatform == TargetPlatform.iOS) {
adaptiveScaling = AdaptiveScaling(1.15);
}
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: widget.supabaseProvider),
ChangeNotifierProvider(
create: (context) =>
CollaborationProvider(context.read<SupabaseProvider>())
..initialize(),
),
],
child: ShadcnApp.router(
routerConfig: _routerConfig,
scaling: adaptiveScaling,
theme: ThemeData(
colorScheme: ColorSchemes.darkNeutral,
),
),
);
}
}