106 lines
3.2 KiB
Dart
106 lines
3.2 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:moonwell_launcher/app/design_system/mw_authentication.dart';
|
|
import 'package:moonwell_launcher/app/design_system/mw_shells.dart';
|
|
import 'package:moonwell_launcher/app/home_screen/home_screen.dart';
|
|
import 'package:moonwell_launcher/features/launcher/data/launcher_api_client.dart';
|
|
import 'package:moonwell_launcher/features/preferences/domain/repositories/preferences_repository.dart';
|
|
import 'package:moonwell_launcher/service_container.dart';
|
|
import 'package:window_manager/window_manager.dart';
|
|
|
|
class LoginScreen extends StatefulWidget {
|
|
const LoginScreen({super.key});
|
|
|
|
@override
|
|
State<LoginScreen> createState() => _LoginScreenState();
|
|
}
|
|
|
|
class _LoginScreenState extends State<LoginScreen> {
|
|
final _usernameController = TextEditingController();
|
|
final _passwordController = TextEditingController();
|
|
bool _isLoading = false;
|
|
String? _error;
|
|
|
|
@override
|
|
void dispose() {
|
|
_usernameController.dispose();
|
|
_passwordController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _login() async {
|
|
final username = _usernameController.text.trim();
|
|
final password = _passwordController.text.trim();
|
|
|
|
if (username.isEmpty || password.isEmpty) {
|
|
setState(() => _error = 'Введите логин и пароль.');
|
|
return;
|
|
}
|
|
|
|
setState(() {
|
|
_isLoading = true;
|
|
_error = null;
|
|
});
|
|
|
|
try {
|
|
final api = getIt<LauncherApiClient>();
|
|
final preferencesRepository = getIt<PreferencesRepository>();
|
|
final session = await api.login(username: username, password: password);
|
|
final manifest = await api.fetchManifest(session.accessToken);
|
|
await preferencesRepository.setLauncherSession(session);
|
|
|
|
if (!mounted) return;
|
|
|
|
await Navigator.of(context).pushReplacement(
|
|
PageRouteBuilder(
|
|
pageBuilder: (_, _, _) =>
|
|
HomeScreen(session: session, manifest: manifest),
|
|
transitionsBuilder: (_, animation, _, child) {
|
|
return FadeTransition(opacity: animation, child: child);
|
|
},
|
|
transitionDuration: const Duration(milliseconds: 400),
|
|
),
|
|
);
|
|
} catch (e) {
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_isLoading = false;
|
|
_error = _formatError(e);
|
|
});
|
|
}
|
|
}
|
|
|
|
String _formatError(Object error) {
|
|
final raw = error.toString();
|
|
if (raw.startsWith('Exception: ')) return raw.substring(11);
|
|
return raw;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MwLoginShell(
|
|
form: MwAuthenticationForm(
|
|
usernameController: _usernameController,
|
|
passwordController: _passwordController,
|
|
loading: _isLoading,
|
|
error: _error,
|
|
onSubmit: _login,
|
|
),
|
|
onDrag: windowManager.startDragging,
|
|
onDoubleTap: () => unawaited(_toggleMaximized()),
|
|
onMinimize: windowManager.minimize,
|
|
onMaximizeRestore: () => unawaited(_toggleMaximized()),
|
|
onClose: () => unawaited(windowManager.destroy()),
|
|
);
|
|
}
|
|
|
|
Future<void> _toggleMaximized() async {
|
|
if (await windowManager.isMaximized()) {
|
|
await windowManager.unmaximize();
|
|
} else {
|
|
await windowManager.maximize();
|
|
}
|
|
}
|
|
}
|