import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:logger/logger.dart' as L; import 'package:logging/logging.dart'; import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_generic_model.dart'; import 'package:mohem_flutter_app/models/marathon/marathon_model.dart'; import 'package:mohem_flutter_app/models/marathon/question_model.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:provider/provider.dart'; import 'package:signalr_netcore/http_connection_options.dart'; import 'package:signalr_netcore/hub_connection.dart'; import 'package:signalr_netcore/hub_connection_builder.dart'; class MarathonApiClient { Future getMarathonToken() async { String employeeUserName = AppState().getUserName ?? ""; String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? ""; Map jsonObject = {"userName": employeeUserName, "password": employeeSession}; Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonParticipantLoginUrl, jsonObject); var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); if (marathonModel.statusCode == 200) { if (marathonModel.data != null && marathonModel.isSuccessful == true) { AppState().setMarathonToken = marathonModel.data["token"] ?? ""; print("bearer: ${AppState().getMarathonToken}"); return marathonModel.data["token"] ?? ""; } else { //TODO : DO ERROR HANDLING HERE return ""; } } else { //TODO : DO ERROR HANDLING HERE return ""; } } Future getProjectId() async { Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonProjectGetUrl, {}, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); MarathonGenericModel marathonModel = MarathonGenericModel.fromJson(json); if (marathonModel.statusCode == 200) { if (marathonModel.data != null && marathonModel.isSuccessful == true) { logger.i("message: ${marathonModel.data[0]["id"]}"); AppState().setMarathonProjectId = marathonModel.data[0]["id"] ?? ""; return marathonModel.data[0]["id"] ?? ""; } else { //TODO : DO ERROR HANDLING HERE return ""; } } else { //TODO : DO ERROR HANDLING HERE return ""; } } Future getMarathonDetails() async { String payrollString = AppState().postParamsObject?.payrollCodeStr.toString() ?? "CS"; Response response = await ApiClient().getJsonForResponse(ApiConsts.marathonUpcomingUrl + payrollString, token: AppState().getMarathonToken ?? await getMarathonToken()); var json = jsonDecode(response.body); MarathonGenericModel marathonGenericModel = MarathonGenericModel.fromJson(json); MarathonDetailModel marathonDetailModel = MarathonDetailModel.fromJson(marathonGenericModel.data); AppState().setMarathonProjectId = marathonDetailModel.id!; return marathonDetailModel; } late HubConnection hubConnection; L.Logger logger = L.Logger(); Future buildHubConnection(BuildContext context) async { HttpConnectionOptions httpOptions = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true); hubConnection = HubConnectionBuilder() .withUrl( ApiConsts.marathonHubConnectionUrl + "?employeeNumber=${AppState().memberInformationList!.eMPLOYEENUMBER ?? ""}&employeeName=${AppState().memberInformationList!.eMPLOYEENAME ?? ""}", options: httpOptions, ) .withAutomaticReconnect( retryDelays: [2000, 5000, 10000, 20000], ) .configureLogging( Logger("Logging"), ) .build(); hubConnection.onclose( ({Exception? error}) { logger.i("onclose"); }, ); hubConnection.onreconnecting( ({Exception? error}) { logger.i("onreconnecting"); }, ); hubConnection.onreconnected( ({String? connectionId}) { logger.i("onreconnected"); }, ); if (hubConnection.state != HubConnectionState.Connected) { await hubConnection.start(); logger.i("Started HubConnection"); await hubConnection.invoke( "AddParticipant", args: [ { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "", "employeeName": AppState().memberInformationList!.eMPLOYEENAME ?? "", "marathonId": AppState().getMarathonProjectId, } ], ).catchError((e) { logger.i("Error in AddParticipant: $e"); }); context.read().addItemToList(ApiConsts.dummyQuestion); await hubConnection.invoke( "SendQuestionToParticipant", args: [ { "marathonId": "${AppState().getMarathonProjectId}", } ], ).catchError((e) { logger.i("Error in SendQuestionToParticipant: $e"); }); try { hubConnection.on("OnSendQuestionToParticipant", (List? arguments) { onSendQuestionToParticipant(arguments, context); }); } catch (e, s) { logger.i("Error in OnSendQuestionToParticipant"); } try { hubConnection.on("OnParticipantJoin", (List? arguments) { onParticipantJoin(arguments, context); }); } catch (e, s) { logger.i("Error in OnParticipantJoin"); } } } Future onSendQuestionToParticipant(List? arguments, BuildContext context) async { logger.i("onSendQuestionToParticipant arguments: $arguments"); if (arguments != null) { Map data = arguments.first! as Map; var json = data["data"]; QuestionModel newQuestion = QuestionModel.fromJson(json); context.read().onNewQuestionReceived(newQuestion); } } Future onParticipantJoin(List? arguments, BuildContext context) async { logger.i("OnParticipantJoin arguments: $arguments"); context.watch().totalMarathoners++; } }