Handle Quizz (Quizz page + questions list + show response etc) + other small fixes
This commit is contained in:
parent
d78873c9d4
commit
c2c0293ace
@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
import 'package:mymuseum_visitapp/Screens/Article/article_page.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Screens/Quizz/quizz_page.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/constants.dart';
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
import 'package:qr_code_scanner/qr_code_scanner.dart';
|
||||||
@ -152,6 +154,9 @@ class _ScannerDialogState extends State<ScannerDialog> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
SectionDTO section = visitAppContext.currentSections!.firstWhere((cs) => cs!.id == code)!;
|
||||||
|
switch(section.type) {
|
||||||
|
case SectionType.Article:
|
||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@ -160,6 +165,18 @@ class _ScannerDialogState extends State<ScannerDialog> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
|
case SectionType.Quizz:
|
||||||
|
Navigator.pushReplacement(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) {
|
||||||
|
return QuizzPage(visitAppContextIn: visitAppContext, sectionId: code);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
74
lib/Components/rounded_button.dart
Normal file
74
lib/Components/rounded_button.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
|
||||||
|
class RoundedButton extends StatelessWidget {
|
||||||
|
final String? text;
|
||||||
|
final Function? press;
|
||||||
|
final IconData? icon;
|
||||||
|
final Color? color, textColor;
|
||||||
|
final double? fontSize;
|
||||||
|
final double? vertical;
|
||||||
|
final double? horizontal;
|
||||||
|
|
||||||
|
const RoundedButton({
|
||||||
|
Key? key,
|
||||||
|
this.text,
|
||||||
|
this.press,
|
||||||
|
this.icon,
|
||||||
|
this.color = kMainColor,
|
||||||
|
this.textColor = Colors.white,
|
||||||
|
this.fontSize,
|
||||||
|
this.vertical,
|
||||||
|
this.horizontal
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
//Size size = MediaQuery.of(context).size;
|
||||||
|
return TextButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: MaterialStateProperty.resolveWith((states) => EdgeInsets.symmetric(vertical: this.vertical != null ? this.vertical! : 25, horizontal: this.horizontal != null ? this.horizontal! : (icon == null ? 85 : 30))),
|
||||||
|
backgroundColor: MaterialStateColor.resolveWith((states) => color!),
|
||||||
|
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
onPressed: () => {
|
||||||
|
press!()
|
||||||
|
},
|
||||||
|
child: getValue(icon)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue(icon) {
|
||||||
|
if (icon != null) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
text!,
|
||||||
|
style: new TextStyle(color: textColor, fontSize: fontSize, fontWeight: FontWeight.w400),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: textColor,
|
||||||
|
size: fontSize! + 8,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Text(
|
||||||
|
text!,
|
||||||
|
style: new TextStyle(color: textColor, fontSize: fontSize, fontWeight: FontWeight.w400),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
lib/Models/ResponseSubDTO.dart
Normal file
54
lib/Models/ResponseSubDTO.dart
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
|
||||||
|
class ResponseSubDTO {
|
||||||
|
List<TranslationDTO>? label;
|
||||||
|
bool? isGood;
|
||||||
|
int? order;
|
||||||
|
|
||||||
|
ResponseSubDTO({this.label, this.isGood, this.order});
|
||||||
|
|
||||||
|
|
||||||
|
//ResponseSubDTO(List<TranslationDTO> label, bool isGood, int order) : super();
|
||||||
|
|
||||||
|
List<ResponseSubDTO> fromJSON(List<ResponseDTO> responsesDTO) {
|
||||||
|
List<ResponseSubDTO> responsesSubDTO = <ResponseSubDTO>[];
|
||||||
|
for(ResponseDTO responseDTO in responsesDTO)
|
||||||
|
{
|
||||||
|
responsesSubDTO.add(ResponseSubDTO(
|
||||||
|
label: responseDTO.label,
|
||||||
|
isGood: responseDTO.isGood,
|
||||||
|
order: responseDTO.order,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return responsesSubDTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QuestionSubDTO {
|
||||||
|
List<TranslationDTO>? label;
|
||||||
|
List<ResponseSubDTO>? responsesSubDTO;
|
||||||
|
int? chosen;
|
||||||
|
String? resourceId;
|
||||||
|
String? source_;
|
||||||
|
int? order;
|
||||||
|
|
||||||
|
QuestionSubDTO({this.label, this.responsesSubDTO, this.chosen, this.resourceId, this.source_, this.order});
|
||||||
|
|
||||||
|
List<QuestionSubDTO> fromJSON(List<QuestionDTO> questionsDTO) {
|
||||||
|
List<QuestionSubDTO> questionSubDTO = <QuestionSubDTO>[];
|
||||||
|
for(QuestionDTO questionDTO in questionsDTO)
|
||||||
|
{
|
||||||
|
questionSubDTO.add(QuestionSubDTO(
|
||||||
|
chosen: null,
|
||||||
|
label: questionDTO.label,
|
||||||
|
responsesSubDTO: ResponseSubDTO().fromJSON(questionDTO.responses!),
|
||||||
|
resourceId: questionDTO.resourceId,
|
||||||
|
source_: questionDTO.source_,
|
||||||
|
order: questionDTO.order,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return questionSubDTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
25
lib/Screens/Quizz/drawPath.dart
Normal file
25
lib/Screens/Quizz/drawPath.dart
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
Path drawPath(Size size) {
|
||||||
|
// Method to convert degree to radians
|
||||||
|
double degToRad(double deg) => deg * (pi / 180.0);
|
||||||
|
|
||||||
|
const numberOfPoints = 5;
|
||||||
|
final halfWidth = size.width / 2;
|
||||||
|
final externalRadius = halfWidth;
|
||||||
|
final internalRadius = halfWidth / 2.5;
|
||||||
|
final degreesPerStep = degToRad(360 / numberOfPoints);
|
||||||
|
final halfDegreesPerStep = degreesPerStep / 2;
|
||||||
|
final path = Path();
|
||||||
|
final fullAngle = degToRad(360);
|
||||||
|
path.moveTo(size.width, halfWidth);
|
||||||
|
|
||||||
|
for (double step = 0; step < fullAngle; step += degreesPerStep) {
|
||||||
|
path.lineTo(halfWidth + externalRadius * cos(step),
|
||||||
|
halfWidth + externalRadius * sin(step));
|
||||||
|
path.lineTo(halfWidth + internalRadius * cos(step + halfDegreesPerStep),
|
||||||
|
halfWidth + internalRadius * sin(step + halfDegreesPerStep));
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
277
lib/Screens/Quizz/questions_list.dart
Normal file
277
lib/Screens/Quizz/questions_list.dart
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Models/ResponseSubDTO.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class QuestionsListWidget extends StatefulWidget {
|
||||||
|
List<QuestionSubDTO>? questionsSubDTO;
|
||||||
|
bool isShowResponse = false;
|
||||||
|
final Function onShowResponse;
|
||||||
|
QuestionsListWidget({Key? key, this.questionsSubDTO, required this.isShowResponse, required this.onShowResponse}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_QuestionsListWidget createState() => _QuestionsListWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _QuestionsListWidget extends State<QuestionsListWidget> {
|
||||||
|
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
|
||||||
|
CarouselController? sliderController;
|
||||||
|
int currentIndex = 1;
|
||||||
|
|
||||||
|
bool kIsWeb = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
sliderController = CarouselController();
|
||||||
|
_questionsSubDTO = widget.questionsSubDTO!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
sliderController = null;
|
||||||
|
currentIndex = 1;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
//Size sizeAll = MediaQuery.of(context).size;
|
||||||
|
|
||||||
|
//Size size = Size(sizeAll.width * 0.65, kIsWeb ? sizeAll.height * 0.5 : sizeAll.height * 0.32);
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
height: widget.isShowResponse ? MediaQuery.of(context).size.height * 0.825 : MediaQuery.of(context).size.height,
|
||||||
|
width: double.infinity,
|
||||||
|
//color: Colors.orange,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: widget.isShowResponse ? MainAxisAlignment.start : MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if(_questionsSubDTO.isNotEmpty)
|
||||||
|
CarouselSlider(
|
||||||
|
carouselController: sliderController,
|
||||||
|
options: CarouselOptions(
|
||||||
|
onPageChanged: (int index, CarouselPageChangedReason reason) {
|
||||||
|
setState(() {
|
||||||
|
currentIndex = index + 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
height: widget.isShowResponse ? MediaQuery.of(context).size.height * 0.79 : MediaQuery.of(context).size.height * 0.85,
|
||||||
|
enlargeCenterPage: true,
|
||||||
|
scrollPhysics: const NeverScrollableScrollPhysics(),
|
||||||
|
reverse: false,
|
||||||
|
),
|
||||||
|
items: _questionsSubDTO.map<Widget>((i) {
|
||||||
|
return Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 7.5, right: 7.5, bottom: 10.0, top: 8.0),
|
||||||
|
child: Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
// height: widget.isShowResponse ? MediaQuery.of(context).size.height *0.55 : MediaQuery.of(context).size.height,
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 1.5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
//color: Colors.orange, //kBackgroundLight
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
image: i.source_ != null ? DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.35,
|
||||||
|
image: NetworkImage(
|
||||||
|
i.source_!,
|
||||||
|
),
|
||||||
|
): null,
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.5,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: Offset(0, 1.5), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
//crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
//color: Colors.red,
|
||||||
|
//width: MediaQuery.of(context).size.width *0.65,
|
||||||
|
height: MediaQuery.of(context).size.height *0.25,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kBackgroundLight, //kBackgroundLight
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.3,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
width: MediaQuery.of(context).size.width *0.7,
|
||||||
|
height: MediaQuery.of(context).size.height *0.2,
|
||||||
|
child: Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(2.5),
|
||||||
|
child: Text(TranslationHelper.get(i.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: const TextStyle(fontSize: kDescriptionSize)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/*SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.01,
|
||||||
|
),*/
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
child: SizedBox(
|
||||||
|
//height: MediaQuery.of(context).size.height * 0.75,
|
||||||
|
width: MediaQuery.of(context).size.width * 0.72,
|
||||||
|
//color: Colors.green,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: GridView.builder(
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 1, // TODO HERE IS TABLET
|
||||||
|
mainAxisExtent: widget.isShowResponse ? 70 : 75, // TODO depends on percentage
|
||||||
|
mainAxisSpacing: widget.isShowResponse ? 35 : 42.5, // TODO depends on percentage
|
||||||
|
crossAxisSpacing: widget.isShowResponse ? 0 : 0, // TODO depends on percentage
|
||||||
|
),
|
||||||
|
itemCount: i.responsesSubDTO!.length,
|
||||||
|
itemBuilder: (BuildContext ctx, index) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if(!widget.isShowResponse) {
|
||||||
|
setState(() {
|
||||||
|
i.chosen = index;
|
||||||
|
if(currentIndex == _questionsSubDTO.length && i.chosen == index)
|
||||||
|
{
|
||||||
|
widget.onShowResponse();
|
||||||
|
//showResult = true;
|
||||||
|
//_controllerCenter!.play(); // TODO Maybe show only confetti on super score ..
|
||||||
|
} else {
|
||||||
|
sliderController!.nextPage(duration: const Duration(milliseconds: 650), curve: Curves.fastOutSlowIn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(2.5),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(TranslationHelper.get(i.responsesSubDTO![index].label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black)),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: !widget.isShowResponse ? i.chosen == index ? kTestSecondColor : kBackgroundLight : i.responsesSubDTO![index].isGood! ? kGreen : i.chosen == index ? kTextRed : kBackgroundLight,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.3,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if(widget.questionsSubDTO!.isNotEmpty && _questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length && _questionsSubDTO[currentIndex-1].chosen != null)
|
||||||
|
Positioned(
|
||||||
|
top: MediaQuery.of(context).size.height * 0.38,
|
||||||
|
right: -9,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if( _questionsSubDTO.isNotEmpty && _questionsSubDTO[currentIndex-1].chosen != null) {
|
||||||
|
sliderController!.nextPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
size: 75,
|
||||||
|
color: kMainColor,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.length > 1 && currentIndex != 1)
|
||||||
|
Positioned(
|
||||||
|
top: MediaQuery.of(context).size.height * 0.38,
|
||||||
|
left: -9,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if(currentIndex > 1) {
|
||||||
|
sliderController!.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
Icons.chevron_left,
|
||||||
|
size: 75,
|
||||||
|
color: kMainColor,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.isNotEmpty)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: widget.isShowResponse ? 0 : 0),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: InkWell(
|
||||||
|
child: Text(
|
||||||
|
currentIndex.toString()+'/'+widget.questionsSubDTO!.length.toString(),
|
||||||
|
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.isEmpty)
|
||||||
|
const Center(
|
||||||
|
child: Text(
|
||||||
|
"Aucune question à afficher",
|
||||||
|
style: TextStyle(fontSize: kNoneInfoOrIncorrect),
|
||||||
|
textAlign: TextAlign.center
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +1,23 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:developer';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:carousel_slider/carousel_slider.dart';
|
||||||
|
import 'package:confetti/confetti.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/Loading.dart';
|
import 'package:mymuseum_visitapp/Components/Loading.dart';
|
||||||
import 'package:mymuseum_visitapp/Components/SliderImages.dart';
|
import 'package:mymuseum_visitapp/Components/rounded_button.dart';
|
||||||
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
|
||||||
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Models/ResponseSubDTO.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
import 'package:mymuseum_visitapp/Models/articleRead.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
import 'package:mymuseum_visitapp/Models/resourceModel.dart';
|
||||||
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
||||||
import 'package:mymuseum_visitapp/Screens/Article/audio_player.dart';
|
import 'package:mymuseum_visitapp/Screens/Quizz/drawPath.dart';
|
||||||
import 'package:mymuseum_visitapp/Services/apiService.dart';
|
import 'package:mymuseum_visitapp/Screens/Quizz/questions_list.dart';
|
||||||
|
import 'package:mymuseum_visitapp/Screens/Quizz/showResponses.dart';
|
||||||
import 'package:mymuseum_visitapp/app_context.dart';
|
import 'package:mymuseum_visitapp/app_context.dart';
|
||||||
import 'package:mymuseum_visitapp/client.dart';
|
import 'package:mymuseum_visitapp/client.dart';
|
||||||
import 'package:mymuseum_visitapp/constants.dart';
|
import 'package:mymuseum_visitapp/constants.dart';
|
||||||
@ -30,22 +35,45 @@ class QuizzPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _QuizzPageState extends State<QuizzPage> {
|
class _QuizzPageState extends State<QuizzPage> {
|
||||||
SectionDTO? sectionDTO;
|
SectionDTO? sectionDTO;
|
||||||
QuizzDTO? quizzDTO;
|
|
||||||
List<ResourceModel?> resourcesModel = <ResourceModel?>[];
|
List<ResourceModel?> resourcesModel = <ResourceModel?>[];
|
||||||
ResourceModel? audioResourceModel;
|
ResourceModel? audioResourceModel;
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
late Uint8List audiobytes;
|
late Uint8List audiobytes;
|
||||||
VisitAppContext? visitAppContext;
|
VisitAppContext? visitAppContext;
|
||||||
|
|
||||||
|
QuizzDTO? quizzDTO;
|
||||||
|
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
|
||||||
|
//ConfettiController? _controllerCenter;
|
||||||
|
CarouselController? sliderController;
|
||||||
|
int currentIndex = 1;
|
||||||
|
bool showResult = false;
|
||||||
|
bool showResponses = false;
|
||||||
|
|
||||||
|
bool kIsWeb = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
widget.visitAppContextIn.isContentCurrentlyShown = true;
|
widget.visitAppContextIn.isContentCurrentlyShown = true;
|
||||||
|
|
||||||
|
//_controllerCenter = ConfettiController(duration: const Duration(seconds: 10));
|
||||||
|
//_controllerCenter!.play();
|
||||||
|
|
||||||
|
sliderController = CarouselController();
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
visitAppContext!.isContentCurrentlyShown = false;
|
visitAppContext!.isContentCurrentlyShown = false;
|
||||||
|
currentIndex = 1;
|
||||||
|
//_controllerCenter!.dispose();
|
||||||
|
if(quizzDTO != null) {
|
||||||
|
if(quizzDTO!.questions != null) {
|
||||||
|
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,8 +81,6 @@ class _QuizzPageState extends State<QuizzPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
//final notchInset = MediaQuery.of(context).padding;
|
|
||||||
|
|
||||||
visitAppContext = appContext.getContext();
|
visitAppContext = appContext.getContext();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -64,10 +90,439 @@ class _QuizzPageState extends State<QuizzPage> {
|
|||||||
isHomeButton: false,
|
isHomeButton: false,
|
||||||
),
|
),
|
||||||
body: FutureBuilder(
|
body: FutureBuilder(
|
||||||
future: getQuizz(appContext, appContext.clientAPI, widget.sectionId),
|
future: getQuizz(appContext, appContext.clientAPI, widget.sectionId), // MAYBE MOVE THAT TO PARENT ..
|
||||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
if(quizzDTO != null && sectionDTO != null) {
|
if(quizzDTO != null && sectionDTO != null) {
|
||||||
if(size.height > size.width) {
|
|
||||||
|
if(showResult) {
|
||||||
|
var goodResponses = 0;
|
||||||
|
for (var question in _questionsSubDTO) {
|
||||||
|
if(question.chosen == question.responsesSubDTO!.indexWhere((response) => response.isGood!)) {
|
||||||
|
goodResponses +=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("goodResponses =" + goodResponses.toString());
|
||||||
|
QuizzDTOBadLevel levelToShow = QuizzDTOBadLevel();
|
||||||
|
var test = goodResponses/quizzDTO!.questions!.length;
|
||||||
|
|
||||||
|
if((0 == test || test < 0.25) && quizzDTO!.badLevel != null) {
|
||||||
|
levelToShow = quizzDTO!.badLevel!;
|
||||||
|
}
|
||||||
|
if((test>=0.25 && test < 0.5) && quizzDTO!.mediumLevel != null) {
|
||||||
|
levelToShow = quizzDTO!.mediumLevel!;
|
||||||
|
}
|
||||||
|
if((test>=0.5 && test < 0.75) && quizzDTO!.goodLevel != null) {
|
||||||
|
levelToShow = quizzDTO!.goodLevel!;
|
||||||
|
}
|
||||||
|
if((test>=0.75 && test <= 1) && quizzDTO!.greatLevel != null) {
|
||||||
|
levelToShow = quizzDTO!.greatLevel!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
/*Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 5,
|
||||||
|
height: 5,
|
||||||
|
child: ConfettiWidget(
|
||||||
|
confettiController: _controllerCenter!,
|
||||||
|
blastDirectionality: BlastDirectionality.explosive,
|
||||||
|
shouldLoop: false, // start again as soon as the animation is finished
|
||||||
|
colors: const [
|
||||||
|
kMainColor,
|
||||||
|
kSecondColor,
|
||||||
|
kConfigurationColor,
|
||||||
|
kTestSecondColor
|
||||||
|
//Colors.pink,
|
||||||
|
//Colors.orange,
|
||||||
|
//Colors.purple
|
||||||
|
], // manually specify the colors to be used
|
||||||
|
createParticlePath: drawPath, // define a custom shape/path.
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
if (!showResponses && levelToShow.source_ != null)
|
||||||
|
Container(
|
||||||
|
//height: size.height * 0.2,
|
||||||
|
//width: size.width * 0.25,
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: size.height * 0.25,
|
||||||
|
maxWidth: kIsWeb ? size.width * 0.20 : size.width * 0.85,
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: levelToShow.source_ != null ? DecorationImage(
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
opacity: 0.85,
|
||||||
|
image: NetworkImage(
|
||||||
|
levelToShow.source_!,
|
||||||
|
),
|
||||||
|
): null,
|
||||||
|
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
|
||||||
|
border: Border.all(
|
||||||
|
color: kBackgroundGrey,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
//borderRadius: BorderRadius.all(Radius.circular(25.0)),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xff7c94b6),
|
||||||
|
image: DecorationImage(
|
||||||
|
image: NetworkImage(
|
||||||
|
levelToShow.source_!,
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all( Radius.circular(50.0)),
|
||||||
|
border: Border.all(
|
||||||
|
color: kBackgroundGrey,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(!showResponses)
|
||||||
|
// TEXT BOX WITH MAIN SCORE
|
||||||
|
Text('$goodResponses/${quizzDTO!.questions!.length}', textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? (showResponses ? 60 : 100) : 75, color: kBackgroundSecondGrey)),
|
||||||
|
if(!showResponses)
|
||||||
|
// TEXT BOX WITH LEVEL TEXT RESULT
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: Container(
|
||||||
|
width: MediaQuery.of(context).size.width *0.75,
|
||||||
|
height: kIsWeb ? (showResponses ? MediaQuery.of(context).size.height *0.10 : MediaQuery.of(context).size.height *0.20) : MediaQuery.of(context).size.height *0.25,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kBackgroundLight, //kBackgroundLight
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.3,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(15.0),
|
||||||
|
child: Text(TranslationHelper.get(levelToShow.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kIsWeb ? kDescriptionSize : kDescriptionSize)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(showResponses)
|
||||||
|
QuestionsListWidget(
|
||||||
|
questionsSubDTO: _questionsSubDTO,
|
||||||
|
isShowResponse: true,
|
||||||
|
onShowResponse: () {}
|
||||||
|
),
|
||||||
|
// RESPONSE BOX
|
||||||
|
//ShowReponsesWidget(questionsSubDTO: _questionsSubDTO),
|
||||||
|
// Buttons
|
||||||
|
Column( // TABLET IS ROW
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: SizedBox(
|
||||||
|
height: kIsWeb ? 50 : 50,
|
||||||
|
width: size.width * 0.6,
|
||||||
|
child: RoundedButton(
|
||||||
|
text: "Recommencer",
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
textColor: kBackgroundLight,
|
||||||
|
icon: Icons.undo,
|
||||||
|
press: () {
|
||||||
|
setState(() {
|
||||||
|
showResult = false;
|
||||||
|
showResponses = false;
|
||||||
|
currentIndex = 1;
|
||||||
|
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fontSize: 18,
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 5
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(!showResponses)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(4.0),
|
||||||
|
child: SizedBox(
|
||||||
|
height: kIsWeb ? 50 : 50,
|
||||||
|
width: size.width * 0.6,
|
||||||
|
child: RoundedButton(
|
||||||
|
text: "Voir les réponses",
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
textColor: kBackgroundLight,
|
||||||
|
icon: Icons.assignment_turned_in,
|
||||||
|
press: () {
|
||||||
|
setState(() {
|
||||||
|
showResponses = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fontSize: 18,
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 5
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return QuestionsListWidget(
|
||||||
|
isShowResponse: false,
|
||||||
|
questionsSubDTO: _questionsSubDTO,
|
||||||
|
onShowResponse: () {
|
||||||
|
setState(() {
|
||||||
|
showResult = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
/*return Stack(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
if(_questionsSubDTO.isNotEmpty)
|
||||||
|
CarouselSlider(
|
||||||
|
carouselController: sliderController,
|
||||||
|
options: CarouselOptions(
|
||||||
|
onPageChanged: (int index, CarouselPageChangedReason reason) {
|
||||||
|
setState(() {
|
||||||
|
currentIndex = index + 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
height: MediaQuery.of(context).size.height * 0.85,
|
||||||
|
enlargeCenterPage: true,
|
||||||
|
scrollPhysics: const NeverScrollableScrollPhysics(),
|
||||||
|
reverse: false,
|
||||||
|
),
|
||||||
|
items: _questionsSubDTO.map<Widget>((i) {
|
||||||
|
return Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 1.0, right: 1.0, bottom: 15.0),
|
||||||
|
child: Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 1.5),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
//color: Colors.orange, //kBackgroundLight
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
|
image: i.source_ != null ? DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.35,
|
||||||
|
image: NetworkImage(
|
||||||
|
i.source_!,
|
||||||
|
),
|
||||||
|
): null,
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.5,
|
||||||
|
blurRadius: 5,
|
||||||
|
offset: Offset(0, 1.5), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
//crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
//color: Colors.red,
|
||||||
|
//width: MediaQuery.of(context).size.width *0.65,
|
||||||
|
height: MediaQuery.of(context).size.height *0.25,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: kBackgroundLight, //kBackgroundLight
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.3,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
width: MediaQuery.of(context).size.width *0.7,
|
||||||
|
height: MediaQuery.of(context).size.height *0.2,
|
||||||
|
child: Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(2.5),
|
||||||
|
child: Text(TranslationHelper.get(i.label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: const TextStyle(fontSize: kDescriptionSize)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/*SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.01,
|
||||||
|
),*/
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
child: SizedBox(
|
||||||
|
//height: MediaQuery.of(context).size.height * 0.75,
|
||||||
|
width: MediaQuery.of(context).size.width * 0.72,
|
||||||
|
//color: Colors.green,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
child: GridView.builder(
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 1, // TODO HERE IS TABLET
|
||||||
|
mainAxisExtent: kIsWeb ? 75 : 75, // TODO depends on percentage
|
||||||
|
mainAxisSpacing: kIsWeb ? 75 : 42.5, // TODO depends on percentage
|
||||||
|
crossAxisSpacing: kIsWeb ? 75 : 0, // TODO depends on percentage
|
||||||
|
),
|
||||||
|
itemCount: i.responsesSubDTO!.length,
|
||||||
|
itemBuilder: (BuildContext ctx, index) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
print("COUCOU");
|
||||||
|
setState(() {
|
||||||
|
i.chosen = index;
|
||||||
|
if(currentIndex == _questionsSubDTO.length && i.chosen == index)
|
||||||
|
{
|
||||||
|
showResult = true;
|
||||||
|
//_controllerCenter!.play(); // TODO Maybe show only confetti on super score ..
|
||||||
|
} else {
|
||||||
|
sliderController!.nextPage(duration: const Duration(milliseconds: 650), curve: Curves.fastOutSlowIn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(2.5),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(TranslationHelper.get(i.responsesSubDTO![index].label, appContext.getContext() as VisitAppContext), textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black)),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: i.chosen == index ? kTestSecondColor : kBackgroundLight,
|
||||||
|
shape: BoxShape.rectangle,
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
boxShadow: const [
|
||||||
|
BoxShadow(
|
||||||
|
color: kBackgroundSecondGrey,
|
||||||
|
spreadRadius: 0.3,
|
||||||
|
blurRadius: 4,
|
||||||
|
offset: Offset(0, 2), // changes position of shadow
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length && _questionsSubDTO[currentIndex-1].chosen != null && quizzDTO!.questions!.isNotEmpty)
|
||||||
|
Positioned(
|
||||||
|
top: MediaQuery.of(context).size.height * 0.35,
|
||||||
|
right: 60,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if(_questionsSubDTO[currentIndex-1].chosen != null && quizzDTO!.questions!.isNotEmpty) {
|
||||||
|
sliderController!.nextPage(duration: Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
|
/*Fluttertoast.showToast(
|
||||||
|
msg: "Vous n'avez pas répondu à cette question",
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: ToastGravity.BOTTOM,
|
||||||
|
timeInSecForIosWeb: 1,
|
||||||
|
backgroundColor: kMainRed,
|
||||||
|
textColor: Colors.white,
|
||||||
|
fontSize: 35.0
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
size: kIsWeb ? 100 : 150,
|
||||||
|
color: kMainColor,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.length > 1 && currentIndex != 1)
|
||||||
|
Positioned(
|
||||||
|
top: MediaQuery.of(context).size.height * 0.35,
|
||||||
|
left: 60,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if(currentIndex > 1) {
|
||||||
|
sliderController!.previousPage(duration: const Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
Icons.chevron_left,
|
||||||
|
size: kIsWeb ? 100 : 150,
|
||||||
|
color: kMainColor,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.isNotEmpty)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 0),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: InkWell(
|
||||||
|
child: Text(
|
||||||
|
currentIndex.toString()+'/'+quizzDTO!.questions!.length.toString(),
|
||||||
|
style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(_questionsSubDTO.isEmpty)
|
||||||
|
const Center(
|
||||||
|
child:
|
||||||
|
Text("Aucune question à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect), textAlign: TextAlign.center),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(size.height > size.width) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Text("TODO show QUESTION THEN COLUMN WITH ALL RESPONSE")
|
Text("TODO show QUESTION THEN COLUMN WITH ALL RESPONSE")
|
||||||
@ -83,7 +538,7 @@ class _QuizzPageState extends State<QuizzPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
} else {
|
} else {
|
||||||
return const Loading();
|
return const Loading();
|
||||||
}
|
}
|
||||||
@ -256,6 +711,8 @@ class _QuizzPageState extends State<QuizzPage> {
|
|||||||
quizzDTO = QuizzDTO.fromJson(jsonDecode(sectionDTO!.data!));
|
quizzDTO = QuizzDTO.fromJson(jsonDecode(sectionDTO!.data!));
|
||||||
}
|
}
|
||||||
if(quizzDTO != null) {
|
if(quizzDTO != null) {
|
||||||
|
quizzDTO!.questions!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
|
_questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO!.questions!);
|
||||||
if(quizzDTO!.questions != null && quizzDTO!.questions!.isNotEmpty) {
|
if(quizzDTO!.questions != null && quizzDTO!.questions!.isNotEmpty) {
|
||||||
quizzDTO!.questions!.sort((a, b) => a.order!.compareTo(b.order!));
|
quizzDTO!.questions!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
/*var audioIdArticle = articleDTO!.audioIds!.where((audioId) => audioId.language == (appContext.getContext() as VisitAppContext).language);
|
/*var audioIdArticle = articleDTO!.audioIds!.where((audioId) => audioId.language == (appContext.getContext() as VisitAppContext).language);
|
||||||
|
|||||||
@ -461,7 +461,7 @@ class _VisitPageState extends State<VisitPage> with WidgetsBindingObserver {
|
|||||||
var status = await Permission.bluetoothScan.status;
|
var status = await Permission.bluetoothScan.status;
|
||||||
print(status);
|
print(status);
|
||||||
}
|
}
|
||||||
listeningState();
|
await listeningState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,8 @@ const kBlue2 = Color(0xFF309cb0);
|
|||||||
|
|
||||||
const kBackgroundLight = Color(0xfff3f3f3);
|
const kBackgroundLight = Color(0xfff3f3f3);
|
||||||
|
|
||||||
|
const kGreen = Color(0xFF15bd5b);
|
||||||
|
|
||||||
const kTitleSize = 40.0;
|
const kTitleSize = 40.0;
|
||||||
const kDescriptionSize = 25.0;
|
const kDescriptionSize = 25.0;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user