mnemo_cards/lib/features/tests/progress_widget.dart
2024-06-11 03:28:57 +03:00

215 lines
6.1 KiB
Dart

import 'dart:math';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:rxdart/rxdart.dart';
import '../../theme/themes.dart';
class ProgressWidget extends StatefulWidget {
final Color color;
final List<Result>? results;
final int length;
final Stream<Duration>? timer;
final bool showMic;
final bool showSound;
final String? popText;
final ValueGetter<Object?>? popValue;
@override
State<StatefulWidget> createState() => _ProgressWidgetState();
factory ProgressWidget.value(int value, int length, Color color) =>
ProgressWidget(
List.generate(
length,
(i) => i < value ? Result.correct : Result.not_visited,
),
length,
color,
);
ProgressWidget(
this.results,
this.length,
this.color, {
this.timer,
this.popValue,
this.showMic = false,
this.showSound = false,
this.popText,
super.key,
});
}
enum Result {
correct,
wrong,
skiped,
not_visited,
}
class _ProgressWidgetState extends State<ProgressWidget> {
List<Result> get results => widget.results!;
int get length => widget.length;
@override
Widget build(BuildContext context) {
return Row(
children: [
TapRegion(
onTapInside: AutoRouter.of(context).maybePop,
behavior: HitTestBehavior.opaque,
child: Container(
height: 30.h,
child: Row(
children: [
Image.asset(
'icons/back.png',
color: Colors.black,
width: 17,
height: 23.h,
),
if (widget.popText != null)
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
widget.popText!,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
),
Expanded(
child: widget.results == null
? SizedBox.shrink()
: Padding(
padding: EdgeInsets.only(left: 10.0.w),
child: ClipRRect(
borderRadius: BorderRadius.circular(16.h),
child: Container(
height: 16.h,
color: white,
child: Stack(
alignment: Alignment.center,
children: [
Row(
children: [
Expanded(
child: AnimatedFractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: length == 0
? 0
: (results
.where((r) =>
r != Result.not_visited)
.length) /
length,
duration: Duration(milliseconds: 300),
child: Container(
color: widget.color,
),
),
),
],
),
],
),
),
),
),
),
if (widget.showMic)
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0.w),
child: Image.asset(
'icons/mic_on.png',
height: 18.h,
width: 13.w,
),
),
if (widget.showSound)
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0.w),
child: Image.asset(
'icons/sound_on.png',
height: 18.h,
width: 24.w,
),
),
if (widget.timer != null)
Padding(
padding: EdgeInsets.only(left: 10.0.w),
child: _TimeWidget(widget.timer),
),
],
);
}
Widget _text() {
return Text(
results.where((r) => r != Result.skiped).length < length
? '${results.where((r) => r != Result.skiped).length + 1} из ${length}'
: '$length',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w800,
),
);
}
_ProgressWidgetState();
}
class _TimeWidget extends StatelessWidget {
final Stream<Duration>? timer;
_TimeWidget(Stream<Duration>? timer) : this.timer = timer;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 68.w,
child: StreamBuilder<Duration>(
stream: timer,
builder: (context, snapshot) {
var text = '-:-';
if (snapshot.hasData) {
final minutes = snapshot.data?.inMinutes ?? 0;
final seconds = (snapshot.data?.inSeconds ?? 0) - 60 * minutes;
text =
"${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}";
}
return Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Image.asset(
'icons/clock.png',
width: 15.w,
height: 15.h,
),
SizedBox(
width: 4.0.w,
),
Text(
text,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
),
)
],
);
}),
);
}
}