import 'dart:convert'; import 'dart:math'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:confetti/confetti.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:managerapi/api.dart'; import 'package:provider/provider.dart'; import 'package:tablet_app/Models/ResponseSubDTO.dart'; import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; class QuizzViewWidget extends StatefulWidget { final SectionDTO section; GlobalKey key; QuizzViewWidget({this.section, this.key}); @override _QuizzViewWidget createState() => _QuizzViewWidget(); } class _QuizzViewWidget extends State { ConfettiController _controllerCenter; QuizzDTO quizzDTO; List _questionsSubDTO = []; CarouselController sliderController; int currentIndex = 1; bool showResult = false; @override void initState() { super.initState(); _controllerCenter = ConfettiController(duration: const Duration(seconds: 10)); sliderController = CarouselController(); quizzDTO = QuizzDTO.fromJson(jsonDecode(widget.section.data)); quizzDTO.questions.sort((a, b) => a.order.compareTo(b.order)); _questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO.questions); _controllerCenter.play(); } @override void dispose() { sliderController = null; _controllerCenter.dispose(); _questionsSubDTO = QuestionSubDTO().fromJSON(quizzDTO.questions); super.dispose(); } /// A custom Path to paint stars. Path drawStar(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)); }*/ var path = Path(); path.lineTo(size.width * 0.57, size.height); path.cubicTo(size.width * 0.56, size.height, size.width * 0.53, size.height * 0.97, size.width * 0.51, size.height * 0.96); path.cubicTo(size.width * 0.49, size.height * 0.94, size.width * 0.47, size.height * 0.89, size.width * 0.47, size.height * 0.85); path.cubicTo(size.width * 0.47, size.height * 0.85, size.width * 0.46, size.height * 0.84, size.width * 0.46, size.height * 0.84); path.cubicTo(size.width * 0.46, size.height * 0.84, size.width * 0.44, size.height * 0.85, size.width * 0.44, size.height * 0.85); path.cubicTo(size.width * 0.4, size.height * 0.88, size.width * 0.38, size.height * 0.89, size.width * 0.34, size.height * 0.91); path.cubicTo(size.width * 0.28, size.height * 0.93, size.width * 0.22, size.height * 0.94, size.width * 0.15, size.height * 0.93); path.cubicTo(size.width * 0.11, size.height * 0.93, size.width * 0.09, size.height * 0.93, size.width * 0.07, size.height * 0.93); path.cubicTo(size.width * 0.02, size.height * 0.92, size.width * 0.02, size.height * 0.91, size.width * 0.03, size.height * 0.89); path.cubicTo(size.width * 0.05, size.height * 0.84, size.width * 0.09, size.height * 0.79, size.width * 0.15, size.height * 0.76); path.cubicTo(size.width * 0.17, size.height * 0.75, size.width * 0.19, size.height * 0.74, size.width / 5, size.height * 0.74); path.cubicTo(size.width * 0.22, size.height * 0.73, size.width * 0.22, size.height * 0.73, size.width * 0.22, size.height * 0.73); path.cubicTo(size.width * 0.22, size.height * 0.73, size.width * 0.22, size.height * 0.73, size.width * 0.22, size.height * 0.73); path.cubicTo(size.width / 5, size.height * 0.73, size.width * 0.16, size.height * 0.71, size.width * 0.14, size.height * 0.7); path.cubicTo(size.width * 0.13, size.height * 0.7, size.width * 0.12, size.height * 0.69, size.width * 0.11, size.height * 0.69); path.cubicTo(size.width * 0.1, size.height * 0.68, size.width * 0.07, size.height * 0.66, size.width * 0.06, size.height * 0.65); path.cubicTo(0, size.height * 0.6, -0.01, size.height * 0.54, size.width * 0.02, size.height * 0.45); path.cubicTo(size.width * 0.03, size.height * 0.4, size.width * 0.06, size.height * 0.35, size.width * 0.1, size.height * 0.29); path.cubicTo(size.width * 0.13, size.height / 4, size.width * 0.15, size.height * 0.23, size.width * 0.18, size.height * 0.19); path.cubicTo(size.width * 0.24, size.height * 0.14, size.width * 0.28, size.height * 0.1, size.width * 0.35, size.height * 0.06); path.cubicTo(size.width * 0.42, size.height * 0.01, size.width * 0.47, 0, size.width * 0.51, 0); path.cubicTo(size.width * 0.58, size.height * 0.01, size.width * 0.66, size.height * 0.06, size.width * 0.75, size.height * 0.14); path.cubicTo(size.width * 0.87, size.height * 0.24, size.width * 0.97, size.height * 0.37, size.width, size.height * 0.46); path.cubicTo(size.width, size.height * 0.52, size.width, size.height * 0.56, size.width * 0.97, size.height * 0.6); path.cubicTo(size.width * 0.95, size.height * 0.62, size.width * 0.93, size.height * 0.64, size.width * 0.9, size.height * 0.66); path.cubicTo(size.width * 0.89, size.height * 0.67, size.width * 0.88, size.height * 0.68, size.width * 0.84, size.height * 0.7); path.cubicTo(size.width * 0.84, size.height * 0.7, size.width * 0.83, size.height * 0.7, size.width * 0.83, size.height * 0.7); path.cubicTo(size.width * 0.83, size.height * 0.7, size.width * 0.84, size.height * 0.71, size.width * 0.85, size.height * 0.72); path.cubicTo(size.width * 0.9, size.height * 0.75, size.width * 0.93, size.height * 0.78, size.width * 0.97, size.height * 0.82); path.cubicTo(size.width * 0.98, size.height * 0.84, size.width, size.height * 0.85, size.width, size.height * 0.85); path.cubicTo(size.width, size.height * 0.86, size.width * 0.98, size.height * 0.87, size.width * 0.97, size.height * 0.87); path.cubicTo(size.width * 0.95, size.height * 0.88, size.width * 0.85, size.height * 0.88, size.width * 0.77, size.height * 0.88); path.cubicTo(size.width * 0.7, size.height * 0.88, size.width * 0.67, size.height * 0.88, size.width * 0.61, size.height * 0.86); path.cubicTo(size.width * 0.6, size.height * 0.86, size.width * 0.59, size.height * 0.86, size.width * 0.59, size.height * 0.86); path.cubicTo(size.width * 0.59, size.height * 0.86, size.width * 0.61, size.height * 0.88, size.width * 0.62, size.height * 0.9); path.cubicTo(size.width * 0.64, size.height * 0.93, size.width * 0.65, size.height * 0.93, size.width * 0.65, size.height * 0.95); path.cubicTo(size.width * 0.65, size.height * 0.96, size.width * 0.64, size.height * 0.97, size.width * 0.63, size.height * 0.97); path.cubicTo(size.width * 0.62, size.height * 0.97, size.width * 0.62, size.height * 0.98, size.width * 0.62, size.height * 0.98); path.cubicTo(size.width * 0.62, size.height, size.width * 0.61, size.height, size.width * 0.6, size.height); path.cubicTo(size.width * 0.59, size.height, size.width * 0.58, size.height, size.width * 0.57, size.height); path.cubicTo(size.width * 0.57, size.height, size.width * 0.57, size.height, size.width * 0.57, size.height); path.lineTo(size.width * 0.58, size.height * 0.94); path.cubicTo(size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.93); path.cubicTo(size.width * 0.57, size.height * 0.93, size.width * 0.54, size.height * 0.89, size.width * 0.54, size.height * 0.88); path.cubicTo(size.width * 0.53, size.height * 0.88, size.width * 0.53, size.height * 0.88, size.width * 0.54, size.height * 0.89); path.cubicTo(size.width * 0.55, size.height * 0.91, size.width * 0.56, size.height * 0.93, size.width * 0.57, size.height * 0.94); path.cubicTo(size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.94); path.cubicTo(size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.94, size.width * 0.58, size.height * 0.94); path.lineTo(size.width * 0.19, size.height * 0.89); path.cubicTo(size.width / 4, size.height * 0.89, size.width * 0.3, size.height * 0.88, size.width * 0.34, size.height * 0.86); path.cubicTo(size.width * 0.39, size.height * 0.84, size.width * 0.43, size.height * 0.8, size.width * 0.45, size.height * 0.77); path.cubicTo(size.width * 0.46, size.height * 0.76, size.width * 0.46, size.height * 0.75, size.width * 0.45, size.height * 0.75); path.cubicTo(size.width * 0.44, size.height * 0.75, size.width * 0.37, size.height * 0.75, size.width / 3, size.height * 0.75); path.cubicTo(size.width * 0.29, size.height * 0.75, size.width * 0.24, size.height * 0.77, size.width / 5, size.height * 0.79); path.cubicTo(size.width * 0.18, size.height * 0.8, size.width * 0.15, size.height * 0.82, size.width * 0.13, size.height * 0.83); path.cubicTo(size.width * 0.12, size.height * 0.85, size.width * 0.1, size.height * 0.87, size.width * 0.09, size.height * 0.88); path.cubicTo(size.width * 0.09, size.height * 0.89, size.width * 0.09, size.height * 0.89, size.width * 0.11, size.height * 0.89); path.cubicTo(size.width * 0.15, size.height * 0.9, size.width * 0.17, size.height * 0.9, size.width * 0.19, size.height * 0.89); path.cubicTo(size.width * 0.19, size.height * 0.89, size.width * 0.19, size.height * 0.89, size.width * 0.19, size.height * 0.89); path.lineTo(size.width * 0.87, size.height * 0.84); path.cubicTo(size.width * 0.9, size.height * 0.84, size.width * 0.91, size.height * 0.84, size.width * 0.91, size.height * 0.84); path.cubicTo(size.width * 0.91, size.height * 0.83, size.width * 0.9, size.height * 0.83, size.width * 0.9, size.height * 0.82); path.cubicTo(size.width * 0.85, size.height * 0.77, size.width * 0.79, size.height * 0.73, size.width * 0.73, size.height * 0.72); path.cubicTo(size.width * 0.71, size.height * 0.71, size.width * 0.7, size.height * 0.71, size.width * 0.67, size.height * 0.71); path.cubicTo(size.width * 0.66, size.height * 0.71, size.width * 0.65, size.height * 0.71, size.width * 0.64, size.height * 0.71); path.cubicTo(size.width * 0.61, size.height * 0.72, size.width * 0.57, size.height * 0.73, size.width * 0.55, size.height * 0.74); path.cubicTo(size.width * 0.54, size.height * 0.74, size.width * 0.53, size.height * 0.75, size.width * 0.53, size.height * 0.75); path.cubicTo(size.width * 0.53, size.height * 0.75, size.width * 0.54, size.height * 0.77, size.width * 0.54, size.height * 0.77); path.cubicTo(size.width * 0.56, size.height * 0.8, size.width * 0.59, size.height * 0.81, size.width * 0.63, size.height * 0.82); path.cubicTo(size.width * 0.66, size.height * 0.83, size.width * 0.7, size.height * 0.84, size.width * 0.74, size.height * 0.84); path.cubicTo(size.width * 0.76, size.height * 0.84, size.width * 0.84, size.height * 0.84, size.width * 0.87, size.height * 0.84); path.cubicTo(size.width * 0.87, size.height * 0.84, size.width * 0.87, size.height * 0.84, size.width * 0.87, size.height * 0.84); path.lineTo(size.width / 2, size.height * 0.71); path.cubicTo(size.width / 2, size.height * 0.71, size.width * 0.51, size.height * 0.71, size.width * 0.51, size.height * 0.7); path.cubicTo(size.width * 0.55, size.height * 0.69, size.width * 0.59, size.height * 0.68, size.width * 0.63, size.height * 0.67); path.cubicTo(size.width * 0.63, size.height * 0.67, size.width * 0.65, size.height * 0.67, size.width * 0.67, size.height * 0.67); path.cubicTo(size.width * 0.67, size.height * 0.67, size.width * 0.71, size.height * 0.67, size.width * 0.71, size.height * 0.67); path.cubicTo(size.width * 0.71, size.height * 0.67, size.width * 0.74, size.height * 0.68, size.width * 0.74, size.height * 0.68); path.cubicTo(size.width * 0.74, size.height * 0.68, size.width * 0.76, size.height * 0.68, size.width * 0.76, size.height * 0.68); path.cubicTo(size.width * 0.76, size.height * 0.68, size.width * 0.77, size.height * 0.67, size.width * 0.77, size.height * 0.67); path.cubicTo(size.width * 0.82, size.height * 0.66, size.width * 0.87, size.height * 0.63, size.width * 0.89, size.height * 0.61); path.cubicTo(size.width * 0.94, size.height * 0.57, size.width * 0.95, size.height * 0.51, size.width * 0.93, size.height * 0.44); path.cubicTo(size.width * 0.88, size.height * 0.31, size.width * 0.7, size.height * 0.12, size.width * 0.56, size.height * 0.06); path.cubicTo(size.width * 0.52, size.height * 0.04, size.width / 2, size.height * 0.04, size.width * 0.47, size.height * 0.05); path.cubicTo(size.width * 0.4, size.height * 0.06, size.width * 0.29, size.height * 0.14, size.width / 5, size.height * 0.24); path.cubicTo(size.width * 0.13, size.height / 3, size.width * 0.08, size.height * 0.41, size.width * 0.07, size.height * 0.49); path.cubicTo(size.width * 0.06, size.height * 0.51, size.width * 0.06, size.height * 0.55, size.width * 0.07, size.height * 0.57); path.cubicTo(size.width * 0.07, size.height * 0.58, size.width * 0.08, size.height * 0.59, size.width * 0.09, size.height * 0.6); path.cubicTo(size.width * 0.1, size.height * 0.62, size.width * 0.11, size.height * 0.63, size.width * 0.12, size.height * 0.64); path.cubicTo(size.width * 0.16, size.height * 0.67, size.width * 0.22, size.height * 0.69, size.width * 0.3, size.height * 0.7); path.cubicTo(size.width / 3, size.height * 0.7, size.width / 3, size.height * 0.71, size.width * 0.41, size.height * 0.71); path.cubicTo(size.width * 0.44, size.height * 0.71, size.width * 0.45, size.height * 0.71, size.width * 0.46, size.height * 0.71); path.cubicTo(size.width * 0.48, size.height * 0.71, size.width * 0.49, size.height * 0.71, size.width / 2, size.height * 0.71); path.cubicTo(size.width / 2, size.height * 0.71, size.width / 2, size.height * 0.71, size.width / 2, size.height * 0.71); return path; } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context); if(showResult) return Column( children: [ Center( child: Container( width: 250, height: 250, color: Colors.green, child: ConfettiWidget( confettiController: _controllerCenter, blastDirectionality: BlastDirectionality .explosive, // don't specify a direction, blast randomly shouldLoop: true, // start again as soon as the animation is finished colors: const [ Colors.red, Colors.pink, Colors.orange, Colors.purple ], // manually specify the colors to be used createParticlePath: drawStar, // define a custom shape/path. ), ), ), Text("RESULT TODO"), ], ); else return Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ if(_questionsSubDTO != null && _questionsSubDTO.length > 0) CarouselSlider( carouselController: sliderController, options: CarouselOptions( onPageChanged: (int index, CarouselPageChangedReason reason) { setState(() { currentIndex = index + 1; }); }, height: MediaQuery.of(context).size.height * 0.8, enlargeCenterPage: true, scrollPhysics: NeverScrollableScrollPhysics(), reverse: false, ), items: _questionsSubDTO.map((i) { return Builder( builder: (BuildContext context) { return Padding( padding: const EdgeInsets.all(8.0), child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, margin: EdgeInsets.symmetric(horizontal: 5.0), decoration: BoxDecoration( color: kBackgroundLight, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(20.0), image: i.source_ != null ? new DecorationImage( fit: BoxFit.contain, opacity: 0.35, image: new NetworkImage( i.source_, ), ): null, boxShadow: [ 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: [ Padding( padding: const EdgeInsets.all(10.0), child: Container( //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, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(10.0), boxShadow: [ BoxShadow( color: kBackgroundSecondGrey, spreadRadius: 0.3, blurRadius: 4, offset: Offset(0, 2), // changes position of shadow ), ], ), width: MediaQuery.of(context).size.width *0.65, height: MediaQuery.of(context).size.height *0.18, child: Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(15.0), child: Text(i.label.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.label.firstWhere((translation) => translation.language == appContext.getContext().language).value : "", textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize)), ), ), ), ) ), ] ), ), ), SizedBox( height: MediaQuery.of(context).size.height * 0.05, ), Expanded( child: Padding( padding: const EdgeInsets.all(10.0), child: Container( height: MediaQuery.of(context).size.height * 0.6, 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: 2, mainAxisExtent: 150, mainAxisSpacing: 150, crossAxisSpacing: 150, ), itemCount: i.responsesSubDTO.length, itemBuilder: (BuildContext ctx, index) { return InkWell( onTap: () { setState(() { i.chosen = index; if(currentIndex == _questionsSubDTO.length && i.chosen == index) { showResult = true; _controllerCenter.play(); } }); }, child: Padding( padding: const EdgeInsets.all(8.0), child: Container( alignment: Alignment.center, child: Text(i.responsesSubDTO[index].label.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.responsesSubDTO[index].label.firstWhere((translation) => translation.language == appContext.getContext().language).value : "", textAlign: TextAlign.center, style: TextStyle(fontSize: kDescriptionSize)), decoration: BoxDecoration( color: i.chosen == index ? Colors.green : kBackgroundLight, shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(10.0), boxShadow: [ BoxShadow( color: kBackgroundSecondGrey, spreadRadius: 0.3, blurRadius: 4, offset: Offset(0, 2), // changes position of shadow ), ], ), ), ), ); }), ), ), ), ), ], ) ), ); }, ); }).toList(), ), ], ), if(_questionsSubDTO != null && _questionsSubDTO.length > 1 && currentIndex != _questionsSubDTO.length) Positioned( top: MediaQuery.of(context).size.height * 0.35, right: 60, child: InkWell( onTap: () { if(_questionsSubDTO[currentIndex-1].chosen != null && quizzDTO.questions.length > 0) { sliderController.nextPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn); } else { 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: 150, color: kMainRed, ), ) ), if(_questionsSubDTO != null && _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: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn); }, child: Icon( Icons.chevron_left, size: 150, color: kMainRed, ), ) ), if(_questionsSubDTO != null && _questionsSubDTO.length > 0) Padding( padding: const EdgeInsets.only(bottom: 0), child: Align( alignment: Alignment.bottomCenter, child: InkWell( child: Text( currentIndex.toString()+'/'+quizzDTO.questions.length.toString(), style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500), ), ) ), ), if(_questionsSubDTO == null || _questionsSubDTO.length == 0) Center(child: Text("Aucune question à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect),)) ] ); } }