import 'dart:math'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:mnemo_cards/utils/color_helper.dart'; import 'package:rxdart/rxdart.dart'; import '../../widgets/big_back_button.dart'; import '../../widgets/horizontal_progress.dart'; import 'question_states/test_question_state.dart'; class TestCompleteWidget extends StatelessWidget { final Iterable states; final Color successColor; static final _pieChartKey = GlobalKey(); TestCompleteWidget( this.states, this.successColor, ); @override Widget build(BuildContext context) { final total = states.length; final correct = states.where((e) => e.isCorrect).length; final incorrect = states.where((e) => !e.isCorrect && e.isAnswered).length; final skipped = states.where((e) => !e.isAnswered).length; final words = states .fold( Map(), (map, state) => map ..[state.word] = (map[state.word] ?? WordStat.zero(state.word)) .inc(state.isCorrect), ) .values .toList() ..sort((p, n) => p.correctCount.compareTo(n.correctCount)); return Column( children: [ Expanded( flex: 3, child: Padding( padding: const EdgeInsets.only(top: 12.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: MediaQuery.of(context).size.width / 1.8, height: MediaQuery.of(context).size.width / 1.8, padding: const EdgeInsets.all(20.0), child: StreamBuilder( stream: Stream.fromIterable([5]) .interval(Duration(milliseconds: 0)), initialData: 0, builder: (context, snapshot) { final a = min(snapshot.requireData / 5.0, 1.0); return PieChart( key: _pieChartKey, swapAnimationDuration: Duration(milliseconds: 600), PieChartData( pieTouchData: PieTouchData(), borderData: FlBorderData( show: false, ), sectionsSpace: 0, centerSpaceRadius: MediaQuery.of(context).size.width / 8, sections: [ PieChartSectionData( color: successColor, showTitle: false, value: correct.toDouble() * a, badgeWidget: Image.asset( 'icons/crown.png', width: 20.w, ), ), PieChartSectionData( color: successColor.lighten(0.15), showTitle: false, value: incorrect.toDouble() * a, badgeWidget: Image.asset( 'icons/skull.png', width: 20.w, ), ), PieChartSectionData( color: Colors.white, showTitle: false, value: skipped.toDouble(), badgeWidget: Image.asset( 'icons/small_circle.png', width: 20.w, ), ), ], ), ); }), ), Text( '$correct/$total', style: TextStyle( fontSize: 36, fontWeight: FontWeight.w500, ), ), Text( '1:47', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500, height: 0.85, ), ), ], ), ), ), Expanded( flex: 2, child: Container( alignment: Alignment.bottomCenter, child: ListView.builder( shrinkWrap: true, itemCount: words.length, itemBuilder: (context, index) { final word = words[index]; return Padding( padding: const EdgeInsets.only( left: 12.0, right: 24, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${word.word}', style: TextStyle( fontSize: 24, fontWeight: FontWeight.w500, ), ), Flexible( child: SizedBox( width: MediaQuery.of(context).size.width / 2.5, child: HorizontalProgressWidget( word.correctCount, word.totalCount, successColor, ), ), ), ], ), ); }, ), ), ), const BigBackButton(), ], ); } } class WordStat { String word; int correctCount; int totalCount; WordStat(this.word, this.correctCount, this.totalCount); factory WordStat.zero(String word) => WordStat(word, 0, 0); WordStat inc(bool isCorrect) => isCorrect ? correct(this) : incorrect(this); WordStat correct(WordStat stat) => WordStat( stat.word, stat.correctCount + 1, stat.totalCount + 1, ); WordStat incorrect(WordStat stat) => WordStat( stat.word, stat.correctCount, stat.totalCount + 1, ); }