feat: app Flutter GameManager (OIDC pocket-id, contrôle serveurs, MOTD live, auto-update) + CI APK signée
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2c5476b1db
commit
3286640b37
@@ -0,0 +1,62 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../config.dart';
|
||||
import '../models.dart';
|
||||
import 'auth_service.dart';
|
||||
|
||||
/// Client de l'API GameManager (Bearer JWT pocket-id).
|
||||
class ApiService {
|
||||
ApiService(this._auth);
|
||||
final AuthService _auth;
|
||||
|
||||
Future<String> get baseUrl async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString('api_base') ?? Config.defaultApiBase;
|
||||
}
|
||||
|
||||
Future<void> setBaseUrl(String url) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('api_base', url.trim().replaceAll(RegExp(r'/$'), ''));
|
||||
}
|
||||
|
||||
Future<Map<String, String>> _headers() async {
|
||||
final token = await _auth.validToken();
|
||||
return {'Authorization': 'Bearer ${token ?? ''}', 'Accept': 'application/json'};
|
||||
}
|
||||
|
||||
Future<List<GameServer>> servers() async {
|
||||
final base = await baseUrl;
|
||||
final res = await http.get(Uri.parse('$base/api/servers'), headers: await _headers());
|
||||
if (res.statusCode == 401) throw UnauthorizedException();
|
||||
if (res.statusCode != 200) throw ApiException('Erreur ${res.statusCode}');
|
||||
final list = jsonDecode(res.body) as List;
|
||||
return list.map((e) => GameServer.fromJson(e as Map<String, dynamic>)).toList();
|
||||
}
|
||||
|
||||
Future<void> start(String id) => _action(id, 'start');
|
||||
Future<void> stop(String id) => _action(id, 'stop');
|
||||
|
||||
Future<void> _action(String id, String action) async {
|
||||
final base = await baseUrl;
|
||||
final res = await http.post(
|
||||
Uri.parse('$base/api/servers/$id/$action'),
|
||||
headers: await _headers(),
|
||||
);
|
||||
if (res.statusCode == 401) throw UnauthorizedException();
|
||||
if (res.statusCode >= 400) throw ApiException('Action refusée (${res.statusCode})');
|
||||
}
|
||||
|
||||
Future<String> iconUrl(String id) async => '${await baseUrl}/api/servers/$id/icon';
|
||||
}
|
||||
|
||||
class UnauthorizedException implements Exception {}
|
||||
|
||||
class ApiException implements Exception {
|
||||
ApiException(this.message);
|
||||
final String message;
|
||||
@override
|
||||
String toString() => message;
|
||||
}
|
||||
Reference in New Issue
Block a user