import 'dart:developer'; import 'package:flutter/foundation.dart'; import '../../api/errors/auth_exception.dart'; import '../../api/errors/error_mapper.dart'; import '../../api/marianumcloud/talk/room/get_room.dart'; import '../../api/marianumcloud/talk/room/get_room_params.dart'; import '../../model/account_data.dart'; /// Owns the login flow's transient state (loading, last error) so it can be /// driven from a thin Stateful view and unit-tested without a widget tree. class LoginController extends ChangeNotifier { bool _loading = false; String? _errorMessage; String? _errorDetails; bool get loading => _loading; String? get errorMessage => _errorMessage; String? get errorDetails => _errorDetails; /// Returns `true` when the credential probe succeeded. The view should /// then transition the AccountBloc to `loggedIn`. Future submit(String username, String password) async { if (_loading) return false; _loading = true; _errorMessage = null; _errorDetails = null; notifyListeners(); final user = username.trim().toLowerCase(); try { await AccountData().removeData(); await AccountData().setData(user, password); await GetRoom(GetRoomParams(includeStatus: false)).run(); _loading = false; notifyListeners(); return true; } catch (e) { log(e.toString()); await AccountData().removeData(); // 401 from the probe means the credentials were wrong; everything else // (no network, server down, TLS errors, …) gets the generic mapped // message so the user knows it isn't their typo. final isWrongCredentials = e is AuthException && e.statusCode == 401; _errorMessage = isWrongCredentials ? 'Benutzername oder Passwort falsch.' : errorToUserMessage(e); _errorDetails = errorToTechnicalDetails(e); _loading = false; notifyListeners(); return false; } } }