Merge branch 'master' into development_sikander
commit
3438b9c174
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>aps-environment</key>
|
||||||
|
<string>development</string>
|
||||||
|
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||||
|
<array>
|
||||||
|
<string>iCloud.com.cloudsolutions.mohemm</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.developer.icloud-services</key>
|
||||||
|
<array>
|
||||||
|
<string>CloudDocuments</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.developer.networking.HotspotConfiguration</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.developer.networking.networkextension</key>
|
||||||
|
<array/>
|
||||||
|
<key>com.apple.developer.networking.wifi-info</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.developer.nfc.readersession.formats</key>
|
||||||
|
<array>
|
||||||
|
<string>TAG</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
||||||
|
<array>
|
||||||
|
<string>iCloud.com.cloudsolutions.mohemm</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,178 @@
|
|||||||
|
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<String> getMarathonToken() async {
|
||||||
|
String employeeUserName = AppState().getUserName ?? "";
|
||||||
|
String employeeSession = AppState().postParamsObject?.pSessionId.toString() ?? "";
|
||||||
|
|
||||||
|
Map<String, String> jsonObject = <String, String>{"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<String> getProjectId() async {
|
||||||
|
Response response = await ApiClient().postJsonForResponse(ApiConsts.marathonProjectGetUrl, <String, dynamic>{}, 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<MarathonDetailModel> 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<void> 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: <int>[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: <Object>[
|
||||||
|
<String, dynamic>{
|
||||||
|
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "",
|
||||||
|
"employeeName": AppState().memberInformationList!.eMPLOYEENAME ?? "",
|
||||||
|
"marathonId": AppState().getMarathonProjectId,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
).catchError((e) {
|
||||||
|
logger.i("Error in AddParticipant: $e");
|
||||||
|
});
|
||||||
|
|
||||||
|
context.read<MarathonProvider>().addItemToList(ApiConsts.dummyQuestion);
|
||||||
|
|
||||||
|
await hubConnection.invoke(
|
||||||
|
"SendQuestionToParticipant",
|
||||||
|
args: <Object>[
|
||||||
|
<String, dynamic>{
|
||||||
|
"marathonId": "${AppState().getMarathonProjectId}",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
).catchError((e) {
|
||||||
|
logger.i("Error in SendQuestionToParticipant: $e");
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
hubConnection.on("OnSendQuestionToParticipant", (List<Object?>? arguments) {
|
||||||
|
onSendQuestionToParticipant(arguments, context);
|
||||||
|
});
|
||||||
|
} catch (e, s) {
|
||||||
|
logger.i("Error in OnSendQuestionToParticipant");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
hubConnection.on("OnParticipantJoin", (List<Object?>? arguments) {
|
||||||
|
onParticipantJoin(arguments, context);
|
||||||
|
});
|
||||||
|
} catch (e, s) {
|
||||||
|
logger.i("Error in OnParticipantJoin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> onSendQuestionToParticipant(List<Object?>? arguments, BuildContext context) async {
|
||||||
|
logger.i("onSendQuestionToParticipant arguments: $arguments");
|
||||||
|
|
||||||
|
if (arguments != null) {
|
||||||
|
Map<dynamic, dynamic> data = arguments.first! as Map<dynamic, dynamic>;
|
||||||
|
var json = data["data"];
|
||||||
|
QuestionModel newQuestion = QuestionModel.fromJson(json);
|
||||||
|
context.read<MarathonProvider>().onNewQuestionReceived(newQuestion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> onParticipantJoin(List<Object?>? arguments, BuildContext context) async {
|
||||||
|
logger.i("OnParticipantJoin arguments: $arguments");
|
||||||
|
context.watch<MarathonProvider>().totalMarathoners++;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
class MarathonGenericModel {
|
||||||
|
MarathonGenericModel({
|
||||||
|
this.data,
|
||||||
|
this.isSuccessful,
|
||||||
|
this.message,
|
||||||
|
this.statusCode,
|
||||||
|
this.errors,
|
||||||
|
});
|
||||||
|
|
||||||
|
dynamic data;
|
||||||
|
bool? isSuccessful;
|
||||||
|
String? message;
|
||||||
|
int? statusCode;
|
||||||
|
dynamic errors;
|
||||||
|
|
||||||
|
factory MarathonGenericModel.fromJson(Map<String, dynamic> json) => MarathonGenericModel(
|
||||||
|
data: json["data"],
|
||||||
|
isSuccessful: json["isSuccessful"],
|
||||||
|
message: json["message"],
|
||||||
|
statusCode: json["statusCode"],
|
||||||
|
errors: json["errors"],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"data": data,
|
||||||
|
"isSuccessful": isSuccessful,
|
||||||
|
"message": message,
|
||||||
|
"statusCode": statusCode,
|
||||||
|
"errors": errors,
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,256 @@
|
|||||||
|
class MarathonDetailModel {
|
||||||
|
String? id;
|
||||||
|
String? titleEn;
|
||||||
|
String? titleAr;
|
||||||
|
String? descEn;
|
||||||
|
String? descAr;
|
||||||
|
int? winDeciderTime;
|
||||||
|
int? winnersCount;
|
||||||
|
int? questGapTime;
|
||||||
|
String? startTime;
|
||||||
|
String? endTime;
|
||||||
|
int? marathoneStatusId;
|
||||||
|
String? scheduleTime;
|
||||||
|
int? selectedLanguage;
|
||||||
|
Projects? projects;
|
||||||
|
List<Sponsors>? sponsors;
|
||||||
|
List<Questions>? questions;
|
||||||
|
int? totalQuestions;
|
||||||
|
|
||||||
|
MarathonDetailModel(
|
||||||
|
{id,
|
||||||
|
titleEn,
|
||||||
|
titleAr,
|
||||||
|
descEn,
|
||||||
|
descAr,
|
||||||
|
winDeciderTime,
|
||||||
|
winnersCount,
|
||||||
|
questGapTime,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
marathoneStatusId,
|
||||||
|
scheduleTime,
|
||||||
|
selectedLanguage,
|
||||||
|
projects,
|
||||||
|
sponsors,
|
||||||
|
questions,
|
||||||
|
totalQuestions});
|
||||||
|
|
||||||
|
MarathonDetailModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
titleEn = json['titleEn'];
|
||||||
|
titleAr = json['titleAr'];
|
||||||
|
descEn = json['descEn'];
|
||||||
|
descAr = json['descAr'];
|
||||||
|
winDeciderTime = json['winDeciderTime'];
|
||||||
|
winnersCount = json['winnersCount'];
|
||||||
|
questGapTime = json['questGapTime'];
|
||||||
|
startTime = json['startTime'];
|
||||||
|
endTime = json['endTime'];
|
||||||
|
marathoneStatusId = json['marathoneStatusId'];
|
||||||
|
scheduleTime = json['scheduleTime'];
|
||||||
|
selectedLanguage = json['selectedLanguage'];
|
||||||
|
projects = json['projects'] != null
|
||||||
|
? Projects.fromJson(json['projects'])
|
||||||
|
: null;
|
||||||
|
if (json['sponsors'] != null) {
|
||||||
|
sponsors = <Sponsors>[];
|
||||||
|
json['sponsors'].forEach((v) {
|
||||||
|
sponsors!.add( Sponsors.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (json['questions'] != null) {
|
||||||
|
questions = <Questions>[];
|
||||||
|
json['questions'].forEach((v) {
|
||||||
|
questions!.add( Questions.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
totalQuestions = json["totalQuestions"];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['titleEn'] = titleEn;
|
||||||
|
data['titleAr'] = titleAr;
|
||||||
|
data['descEn'] = descEn;
|
||||||
|
data['descAr'] = descAr;
|
||||||
|
data['winDeciderTime'] = winDeciderTime;
|
||||||
|
data['winnersCount'] = winnersCount;
|
||||||
|
data['questGapTime'] = questGapTime;
|
||||||
|
data['startTime'] = startTime;
|
||||||
|
data['endTime'] = endTime;
|
||||||
|
data['marathoneStatusId'] = marathoneStatusId;
|
||||||
|
data['scheduleTime'] = scheduleTime;
|
||||||
|
data['selectedLanguage'] = selectedLanguage;
|
||||||
|
if (projects != null) {
|
||||||
|
data['projects'] = projects!.toJson();
|
||||||
|
}
|
||||||
|
if (sponsors != null) {
|
||||||
|
data['sponsors'] = sponsors!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
if (questions != null) {
|
||||||
|
data['questions'] = questions!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
data['totalQuestions'] = totalQuestions;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Projects {
|
||||||
|
String? id;
|
||||||
|
String? nameEn;
|
||||||
|
String? nameAr;
|
||||||
|
String? projectCode;
|
||||||
|
|
||||||
|
Projects({id, nameEn, nameAr, projectCode});
|
||||||
|
|
||||||
|
Projects.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
nameEn = json['nameEn'];
|
||||||
|
nameAr = json['nameAr'];
|
||||||
|
projectCode = json['projectCode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['nameEn'] = nameEn;
|
||||||
|
data['nameAr'] = nameAr;
|
||||||
|
data['projectCode'] = projectCode;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sponsors {
|
||||||
|
String? id;
|
||||||
|
String? nameEn;
|
||||||
|
Null? nameAr;
|
||||||
|
String? image;
|
||||||
|
Null? video;
|
||||||
|
Null? logo;
|
||||||
|
List<SponsorPrizes>? sponsorPrizes;
|
||||||
|
|
||||||
|
Sponsors(
|
||||||
|
{id,
|
||||||
|
nameEn,
|
||||||
|
nameAr,
|
||||||
|
image,
|
||||||
|
video,
|
||||||
|
logo,
|
||||||
|
sponsorPrizes});
|
||||||
|
|
||||||
|
Sponsors.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
nameEn = json['nameEn'];
|
||||||
|
nameAr = json['nameAr'];
|
||||||
|
image = json['image'];
|
||||||
|
video = json['video'];
|
||||||
|
logo = json['logo'];
|
||||||
|
if (json['sponsorPrizes'] != null) {
|
||||||
|
sponsorPrizes = <SponsorPrizes>[];
|
||||||
|
json['sponsorPrizes'].forEach((v) {
|
||||||
|
sponsorPrizes!.add( SponsorPrizes.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['nameEn'] = nameEn;
|
||||||
|
data['nameAr'] = nameAr;
|
||||||
|
data['image'] = image;
|
||||||
|
data['video'] = video;
|
||||||
|
data['logo'] = logo;
|
||||||
|
if (sponsorPrizes != null) {
|
||||||
|
data['sponsorPrizes'] =
|
||||||
|
sponsorPrizes!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SponsorPrizes {
|
||||||
|
String? id;
|
||||||
|
String? marathonPrizeEn;
|
||||||
|
String? marathonPrizeAr;
|
||||||
|
|
||||||
|
SponsorPrizes({id, marathonPrizeEn, marathonPrizeAr});
|
||||||
|
|
||||||
|
SponsorPrizes.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
marathonPrizeEn = json['marathonPrizeEn'];
|
||||||
|
marathonPrizeAr = json['marathonPrizeAr'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['id'] = id;
|
||||||
|
data['marathonPrizeEn'] = marathonPrizeEn;
|
||||||
|
data['marathonPrizeAr'] = marathonPrizeAr;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Questions {
|
||||||
|
String? id;
|
||||||
|
String? titleEn;
|
||||||
|
String? titleAr;
|
||||||
|
String? marathonId;
|
||||||
|
int? questionTypeId;
|
||||||
|
int? questionTime;
|
||||||
|
int? nextQuestGap;
|
||||||
|
int? gapType;
|
||||||
|
String? gapValue;
|
||||||
|
String? gapImage;
|
||||||
|
int? questOptionsLimit;
|
||||||
|
List? questionOptions;
|
||||||
|
|
||||||
|
Questions(
|
||||||
|
{id,
|
||||||
|
titleEn,
|
||||||
|
titleAr,
|
||||||
|
marathonId,
|
||||||
|
questionTypeId,
|
||||||
|
questionTime,
|
||||||
|
nextQuestGap,
|
||||||
|
gapType,
|
||||||
|
gapValue,
|
||||||
|
gapImage,
|
||||||
|
questOptionsLimit,
|
||||||
|
questionOptions});
|
||||||
|
|
||||||
|
Questions.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
titleEn = json['titleEn'];
|
||||||
|
titleAr = json['titleAr'];
|
||||||
|
marathonId = json['marathonId'];
|
||||||
|
questionTypeId = json['questionTypeId'];
|
||||||
|
questionTime = json['questionTime'];
|
||||||
|
nextQuestGap = json['nextQuestGap'];
|
||||||
|
gapType = json['gapType'];
|
||||||
|
gapValue = json['gapValue'];
|
||||||
|
gapImage = json['gapImage'];
|
||||||
|
questOptionsLimit = json['questOptionsLimit'];
|
||||||
|
questionOptions = json['questionOptions'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['titleEn'] = titleEn;
|
||||||
|
data['titleAr'] = titleAr;
|
||||||
|
data['marathonId'] = marathonId;
|
||||||
|
data['questionTypeId'] = questionTypeId;
|
||||||
|
data['questionTime'] = questionTime;
|
||||||
|
data['nextQuestGap'] = nextQuestGap;
|
||||||
|
data['gapType'] = gapType;
|
||||||
|
data['gapValue'] = gapValue;
|
||||||
|
data['gapImage'] = gapImage;
|
||||||
|
data['questOptionsLimit'] = questOptionsLimit;
|
||||||
|
data['questionOptions'] = questionOptions;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
enum QuestionsOptionStatus { correct, wrong, selected, unSelected }
|
||||||
|
|
||||||
|
enum QuestionCardStatus { question, wrongAnswer, correctAnswer, skippedAnswer, completed, findingWinner, winnerFound }
|
||||||
|
|
||||||
|
class QuestionModel {
|
||||||
|
String? id;
|
||||||
|
String? titleEn;
|
||||||
|
String? titleAr;
|
||||||
|
String? marathonId;
|
||||||
|
int? questionTypeId;
|
||||||
|
int? questionTime;
|
||||||
|
int? nextQuestGap;
|
||||||
|
int? gapType;
|
||||||
|
String? gapText;
|
||||||
|
String? gapImage;
|
||||||
|
int? questOptionsLimit;
|
||||||
|
List<QuestionOptions>? questionOptions;
|
||||||
|
|
||||||
|
QuestionModel({
|
||||||
|
String? id,
|
||||||
|
String? titleEn,
|
||||||
|
String? titleAr,
|
||||||
|
String? marathonId,
|
||||||
|
int? questionTypeId,
|
||||||
|
int? questionTime,
|
||||||
|
int? nextQuestGap,
|
||||||
|
int? gapType,
|
||||||
|
String? gapText,
|
||||||
|
String? gapImage,
|
||||||
|
int? questOptionsLimit,
|
||||||
|
List<QuestionOptions>? questionOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
QuestionModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
titleEn = json['titleEn'];
|
||||||
|
titleAr = json['titleAr'];
|
||||||
|
marathonId = json['marathonId'];
|
||||||
|
questionTypeId = json['questionTypeId'];
|
||||||
|
questionTime = json['questionTime'];
|
||||||
|
nextQuestGap = json['nextQuestGap'];
|
||||||
|
gapType = json['gapType'];
|
||||||
|
gapText = json['gapText'];
|
||||||
|
gapImage = json['gapImage'];
|
||||||
|
questOptionsLimit = json['questOptionsLimit'];
|
||||||
|
if (json['questionOptions'] != null) {
|
||||||
|
questionOptions = <QuestionOptions>[];
|
||||||
|
json['questionOptions'].forEach((v) {
|
||||||
|
questionOptions!.add(QuestionOptions.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['titleEn'] = titleEn;
|
||||||
|
data['titleAr'] = titleAr;
|
||||||
|
data['marathonId'] = marathonId;
|
||||||
|
data['questionTypeId'] = questionTypeId;
|
||||||
|
data['questionTime'] = questionTime;
|
||||||
|
data['nextQuestGap'] = nextQuestGap;
|
||||||
|
data['gapType'] = gapType;
|
||||||
|
data['gapText'] = gapText;
|
||||||
|
data['gapImage'] = gapImage;
|
||||||
|
data['questOptionsLimit'] = questOptionsLimit;
|
||||||
|
if (questionOptions != null) {
|
||||||
|
data['questionOptions'] = questionOptions!.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QuestionOptions {
|
||||||
|
String? id;
|
||||||
|
String? titleEn;
|
||||||
|
String? titleAr;
|
||||||
|
String? questionId;
|
||||||
|
int? sequence;
|
||||||
|
String? image;
|
||||||
|
bool? isCorrectOption;
|
||||||
|
QuestionsOptionStatus? optionStatus;
|
||||||
|
|
||||||
|
QuestionOptions({
|
||||||
|
String? id,
|
||||||
|
String? titleEn,
|
||||||
|
String? titleAr,
|
||||||
|
String? questionId,
|
||||||
|
int? sequence,
|
||||||
|
String? image,
|
||||||
|
bool? isCorrectOption,
|
||||||
|
QuestionsOptionStatus? optionStatus,
|
||||||
|
});
|
||||||
|
|
||||||
|
QuestionOptions.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
titleEn = json['titleEn'];
|
||||||
|
titleAr = json['titleAr'];
|
||||||
|
questionId = json['questionId'];
|
||||||
|
sequence = json['sequence'];
|
||||||
|
image = json['image'];
|
||||||
|
isCorrectOption = json['isCorrectOption'];
|
||||||
|
optionStatus = QuestionsOptionStatus.unSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['titleEn'] = titleEn;
|
||||||
|
data['titleAr'] = titleAr;
|
||||||
|
data['questionId'] = questionId;
|
||||||
|
data['sequence'] = sequence;
|
||||||
|
data['image'] = image;
|
||||||
|
data['isCorrectOption'] = isCorrectOption;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mohem_flutter_app/models/marathon/question_model.dart';
|
||||||
|
|
||||||
|
class QuestionCardBuilder extends StatelessWidget {
|
||||||
|
final WidgetBuilder onQuestion;
|
||||||
|
final WidgetBuilder onCompleted;
|
||||||
|
final WidgetBuilder onWrongAnswer;
|
||||||
|
final WidgetBuilder onCorrectAnswer;
|
||||||
|
final WidgetBuilder onWinner;
|
||||||
|
final WidgetBuilder onSkippedAnswer;
|
||||||
|
final WidgetBuilder onFindingWinner;
|
||||||
|
final QuestionCardStatus questionCardStatus;
|
||||||
|
|
||||||
|
const QuestionCardBuilder({
|
||||||
|
Key? key,
|
||||||
|
required this.onQuestion,
|
||||||
|
required this.onCompleted,
|
||||||
|
required this.onCorrectAnswer,
|
||||||
|
required this.onWinner,
|
||||||
|
required this.onSkippedAnswer,
|
||||||
|
required this.onWrongAnswer,
|
||||||
|
required this.onFindingWinner,
|
||||||
|
required this.questionCardStatus,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
switch (questionCardStatus) {
|
||||||
|
case QuestionCardStatus.question:
|
||||||
|
return onQuestion(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.wrongAnswer:
|
||||||
|
return onWrongAnswer(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.correctAnswer:
|
||||||
|
return onCorrectAnswer(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.completed:
|
||||||
|
return onCompleted(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.winnerFound:
|
||||||
|
return onWinner(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.findingWinner:
|
||||||
|
return onFindingWinner(context);
|
||||||
|
|
||||||
|
case QuestionCardStatus.skippedAnswer:
|
||||||
|
return onSkippedAnswer(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue