import 'dart:async'; import 'dart:convert'; import '../../../../model/account_data.dart'; import '../../webuntis_api.dart'; import 'authenticate_params.dart'; import 'authenticate_response.dart'; class Authenticate extends WebuntisApi { AuthenticateParams param; Authenticate(this.param) : super('authenticate', param, authenticatedResponse: false); @override Future run() async { awaitingResponse = true; try { final rawAnswer = await query(this); final decoded = jsonDecode(rawAnswer) as Map; final response = finalize( AuthenticateResponse.fromJson( decoded['result'] as Map, ), ); _lastResponse = response; if (!awaitedResponse.isCompleted) awaitedResponse.complete(); return response; } catch (e) { // Surface the error to anyone waiting on the current completer, then // install a fresh one so a future attempt can succeed. Without this, // any later call to getSession() would hang forever on a completer // that is already settled with no listeners (or never settles at all). if (!awaitedResponse.isCompleted) awaitedResponse.completeError(e); awaitedResponse = Completer(); rethrow; } finally { awaitingResponse = false; } } static bool awaitingResponse = false; static Completer awaitedResponse = Completer(); static AuthenticateResponse? _lastResponse; static Future createSession() async { _lastResponse = await Authenticate( AuthenticateParams( user: AccountData().getUsername(), password: AccountData().getPassword(), ), ).run(); } static Future getSession() async { if (awaitingResponse) { await awaitedResponse.future; } if (_lastResponse == null) { awaitingResponse = true; await createSession(); } return _lastResponse!; } }