blob: 560feb01f314ac5f58be777ad6ba448f44f70489 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../api/player_api_client.dart';
import '../models/models.dart';
import 'api_client_provider.dart';
/// Provides the currently authenticated [User] object.
///
/// Calls [PlayerApiClient.login] is not used here — instead, the logged-in
/// user is fetched lazily via [listUsers] or derived from the auth context.
/// Since the server does not expose a "GET /api/v1/auth/me" endpoint, we
/// obtain the current user by calling [listUsers] and matching against the
/// stored username token.
///
/// The provider is autoDispose so it is released when no screen is watching it,
/// and keepAlive is not used — a fresh fetch is acceptable when navigating back.
///
/// Returns null when the user list cannot be fetched or the username is not
/// found among the registered users (e.g. during a race with logout).
final currentUserProvider = FutureProvider.autoDispose<User?>((ref) async {
// Obtain the stored username from token storage (same source as the settings
// screen's _currentUsernameProvider) to identify which user is logged in.
final storage = ref.watch(tokenStorageProvider);
final username = await storage.readToken();
if (username == null || username.isEmpty) return null;
// Fetch the full user list to resolve the user object for the stored username.
// This is the only way to get the User with isAdmin flag since there is no
// dedicated /api/v1/auth/me endpoint. Admin-only screens already require
// admin status so this round-trip is acceptable at navigation time.
final client = ref.watch(apiClientProvider);
try {
final users = await client.listUsers();
return users.firstWhere(
(u) => u.username == username,
orElse: () => User(id: 0, username: username, isAdmin: false),
);
} catch (_) {
// If listUsers fails (e.g. non-admin user, network error) fall back to a
// minimal user object with isAdmin=false so gating logic fails safely.
return User(id: 0, username: username, isAdmin: false);
}
});
|