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:
neckfire
2026-07-13 09:13:55 +02:00
co-authored by Claude Opus 4.8
parent 2c5476b1db
commit 3286640b37
14 changed files with 969 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../services/api_service.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({super.key, required this.api});
final ApiService api;
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
final _controller = TextEditingController();
String _version = '';
@override
void initState() {
super.initState();
widget.api.baseUrl.then((v) => _controller.text = v);
PackageInfo.fromPlatform()
.then((i) => setState(() => _version = '${i.version} (build ${i.buildNumber})'));
}
Future<void> _save() async {
await widget.api.setBaseUrl(_controller.text);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Enregistré')));
Navigator.pop(context);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Réglages')),
body: ListView(
padding: const EdgeInsets.all(20),
children: [
Text('Adresse de l\'API',
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
const SizedBox(height: 8),
TextField(
controller: _controller,
keyboardType: TextInputType.url,
autocorrect: false,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'https://gamemanager-api.nfteam.ovh',
),
),
const SizedBox(height: 20),
FilledButton(onPressed: _save, child: const Text('Enregistrer')),
const SizedBox(height: 40),
Center(
child: Text('GameManager · v$_version',
style: TextStyle(color: Theme.of(context).colorScheme.outline)),
),
],
),
);
}
}