Files
MatchLiveTv/mobile/lib/app/router.dart
Emiliano Frascaro 566104aff4 Billing upgrade/downgrade, inviti in app e diretta YouTube da mobile.
Upgrade Stripe con addebito immediato; downgrade programmato a fine periodo.
UX billing più sobria con box info; icone piani. API inviti e OAuth YouTube
per staff trasmissione; deep link join; scelta partita programmata o nuova.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 22:15:27 +02:00

85 lines
2.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../features/auth/login_screen.dart';
import '../features/auth/splash_screen.dart';
import '../features/camera_mode/camera_screen.dart';
import '../features/archive/archive_screen.dart';
import '../features/matches/matches_screen.dart';
import '../features/setup_wizard/wizard_shell.dart';
import '../providers/auth_provider.dart';
/// Notifica GoRouter solo su cambi auth rilevanti (non su ogni loading tick).
class _AuthRefreshNotifier extends ChangeNotifier {
_AuthRefreshNotifier(this._ref) {
_ref.listen<AuthState>(authProvider, (prev, next) {
final authChanged = prev?.isAuthenticated != next.isAuthenticated;
if (authChanged) notifyListeners();
});
}
final Ref _ref;
}
final routerProvider = Provider<GoRouter>((ref) {
final refresh = _AuthRefreshNotifier(ref);
return GoRouter(
initialLocation: '/',
refreshListenable: refresh,
redirect: (context, state) {
final auth = ref.read(authProvider);
final loggingIn = state.matchedLocation == '/login';
final onSplash = state.matchedLocation == '/';
if (onSplash) return null;
if (!auth.isAuthenticated && !loggingIn) {
return '/login';
}
if (auth.isAuthenticated && loggingIn) {
return '/matches';
}
return null;
},
routes: [
GoRoute(
path: '/',
builder: (context, state) => const SplashScreen(),
),
GoRoute(
path: '/login',
builder: (context, state) => LoginScreen(
inviteToken: state.uri.queryParameters['invite'],
),
),
GoRoute(
path: '/matches',
builder: (context, state) => const MatchesScreen(),
),
GoRoute(
path: '/archive',
builder: (context, state) => const ArchiveScreen(),
),
GoRoute(
path: '/setup/:matchId/:step',
builder: (context, state) {
final matchId = state.pathParameters['matchId']!;
final step = int.tryParse(state.pathParameters['step'] ?? '1') ?? 1;
return WizardShell(matchId: matchId, step: step);
},
),
GoRoute(
path: '/session/:id/camera',
builder: (context, state) {
final sessionId = state.pathParameters['id']!;
return CameraScreen(sessionId: sessionId);
},
),
],
);
});