feat(flutter): GoRouter shell + version gate + auth-aware redirects
Cold launch flow: no server-url -> /server-url. URL set, no token -> /login. Token present -> /home with shell. VersionGate runs once when the URL changes, hits /healthz, blocks if min_client_version > package version. /home is a placeholder until Task 14. Replaces Navigator.pushReplacementNamed in server_url_screen + login_screen with context.go now that go_router owns the routes.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../api/client.dart';
|
||||
import '../api/endpoints/auth.dart';
|
||||
@@ -31,7 +32,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
final url = await ref.read(serverUrlProvider.future);
|
||||
if (url == null) {
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pushReplacementNamed('/server-url');
|
||||
context.go('/server-url');
|
||||
return;
|
||||
}
|
||||
final dio = ApiClient.buildDio(
|
||||
@@ -47,7 +48,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
userJson: res.rawUserJson,
|
||||
);
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pushReplacementNamed('/home');
|
||||
context.go('/home');
|
||||
} on DioException catch (e) {
|
||||
final code = ApiError.fromDio(e).code;
|
||||
final copy = (await ErrorCopy.load()).forCode(code);
|
||||
@@ -83,7 +84,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
: const Text('Sign in'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pushReplacementNamed('/server-url'),
|
||||
onPressed: () => context.go('/server-url'),
|
||||
child: const Text('Change server URL'),
|
||||
),
|
||||
]),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../api/endpoints/health.dart';
|
||||
import '../theme/theme_extension.dart';
|
||||
@@ -36,7 +37,7 @@ class _ServerUrlScreenState extends ConsumerState<ServerUrlScreen> {
|
||||
}
|
||||
await ref.read(authControllerProvider.notifier).setServerUrl(url);
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pushReplacementNamed('/login');
|
||||
context.go('/login');
|
||||
} on DioException catch (_) {
|
||||
setState(() => _error = "Couldn't reach that server.");
|
||||
} catch (_) {
|
||||
|
||||
Reference in New Issue
Block a user