mnemo_cards/lib/features/tests/test_widgets/input_buttons_test.dart

283 lines
9.8 KiB
Dart
Raw Normal View History

2024-05-22 20:48:44 +00:00
import 'dart:math';
2024-05-28 21:25:51 +00:00
import 'package:collection/collection.dart';
2024-05-22 20:48:44 +00:00
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mnemo_cards/features/tests/test_manager.dart';
import 'package:mnemo_cards/features/tests/test_widgets/test_image.dart';
2024-05-28 21:25:51 +00:00
import 'package:mnemo_cards/theme/themes.dart';
2024-05-22 20:48:44 +00:00
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
2024-05-28 21:25:51 +00:00
import 'package:collection/collection.dart';
2024-05-22 20:48:44 +00:00
import '../../../di/locator.dart';
import '../../../widgets/game_card_widget.dart';
import '../question_states/input_buttons_test_state.dart';
import 'test_button.dart';
class InputButtonsTestWidget extends StatelessWidget {
bool get isCorrect => state.answer.join() == model.answer;
2024-05-28 21:25:51 +00:00
final InputButtonsTestQuestionBody _inputButtonModel;
InputButtonsTestQuestionBody get model => _inputButtonModel;
2024-05-22 20:48:44 +00:00
InputButtonsTestState get state =>
manager.getState(model.id!) as InputButtonsTestState;
TestManager get manager => locator.testManager;
2024-05-28 21:25:51 +00:00
Color get testColor => manager.color;
2024-05-22 20:48:44 +00:00
2024-05-28 21:25:51 +00:00
InputButtonsTestWidget(this._inputButtonModel, {super.key});
2024-05-22 20:48:44 +00:00
@override
Widget build(BuildContext context) {
final theme = Theme.of(context).textTheme;
2024-05-28 21:25:51 +00:00
// final random = Random(state.seed);
final buttons = model.buttons; //..shuffle(random);
return Padding(
padding: const EdgeInsets.all(8.0),
child: LayoutBuilder(builder: (context, constraints) {
return Column(
2024-05-22 20:48:44 +00:00
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
2024-05-28 21:25:51 +00:00
if (model.image != null)
Container(
margin: const EdgeInsets.all(4.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(16.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AspectRatio(
aspectRatio: 1,
child: TestImageWidget(
TestImage.image(model.image!),
),
),
if (model.text != null)
Container(
padding: EdgeInsets.only(top: 8.0),
child: Center(
child: Text(
model.text!,
style: theme.headlineLarge,
2024-05-22 20:48:44 +00:00
),
2024-05-28 21:25:51 +00:00
),
),
],
),
)
else Flexible(
child: Center(
child: Text(
model.text!,
style: theme.headlineLarge,
2024-05-22 20:48:44 +00:00
),
),
),
StatefulBuilder(builder: (context, setState) {
2024-05-28 21:25:51 +00:00
void buttonTapped(int index, TestButtonDto button) {
2024-05-22 20:48:44 +00:00
if (state.answer.fold(0, (p, n) => p + n.length) >=
model.answer.length) {
return;
}
setState(() {
2024-05-28 21:25:51 +00:00
var answer = [...state.answer, button.text!];
final ignoreSpaces = true;
if (ignoreSpaces &&
model.answer.length > answer.length &&
model.answer[answer.length] == ' ') {
answer.add(' ');
}
2024-05-22 20:48:44 +00:00
manager.setState(
model.id!,
state.copyWith(
2024-05-28 21:25:51 +00:00
answer: answer,
answerIds: [...state.answerIds, button.id],
2024-05-22 20:48:44 +00:00
),
);
manager.setState(
model.id!,
state.copyWith(
isAnswered: isCorrect,
isCorrect: isCorrect,
),
);
});
print('${state.answer} ${model.answer} ${state.isCorrect}');
if (isCorrect) {
Future.delayed(
Duration(milliseconds: 300),
manager.nextTest,
);
}
}
2024-05-28 21:25:51 +00:00
int splitIndex = 0;
if (model.answer.length * 30 > constraints.maxWidth * 0.9) {
splitIndex = model.answer.indexOf(
' ',
(model.answer.length / 2).ceil(),
);
if (splitIndex < 10) {
splitIndex = model.answer.indexOf(
' ',
(model.answer.length / 3).ceil(),
);
}
if (splitIndex == -1) {
splitIndex = model.answer.indexOf(
' ',
0,
);
}
}
if (splitIndex < 0) {
splitIndex = 0;
}
final letters = model.answer
.split('')
.mapIndexed(
(index, letter) => letter == ' '
? SizedBox(width: 10)
: _Letter(
text: state.answer.length > index
? state.answer[index]
: ' ',
color: testColor,
),
)
.toList();
final rows = [
if (splitIndex > 0)
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: letters.sublist(0, splitIndex),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: letters.sublist(splitIndex),
)
];
2024-05-22 20:48:44 +00:00
return Expanded(
child: Column(
children: [
Expanded(
child: GestureDetector(
onTap: () {
2024-05-28 21:25:51 +00:00
var answer = state.answer.toList();
var answerIds = state.answerIds.toList();
if (answer.isNotEmpty) {
if (answer.last == ' ') {
answer.removeLast();
}
if (answer.isNotEmpty) {
answer.removeLast();
answerIds.removeLast();
}
}
2024-05-22 20:48:44 +00:00
setState(() {
manager.setState(
model.id!,
state.copyWith(
2024-05-28 21:25:51 +00:00
// isAnswered: false,
// isCorrect: false,
answer: answer,
answerIds: answerIds,
2024-05-22 20:48:44 +00:00
),
);
});
},
2024-05-28 21:25:51 +00:00
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
2024-05-22 20:48:44 +00:00
mainAxisAlignment: MainAxisAlignment.center,
2024-05-28 21:25:51 +00:00
mainAxisSize: MainAxisSize.min,
children: rows,
2024-05-22 20:48:44 +00:00
),
),
),
SizedBox(
height: 16.0,
),
AbsorbPointer(
absorbing: state.isCorrect,
child: Wrap(
children: [
2024-05-28 21:25:51 +00:00
...buttons.mapIndexed(
(index, button) => Container(
margin: EdgeInsets.all(4.0),
width: button.text!.length > 3
? null
: constraints.maxWidth / 6,
height: 50,
child: state.answerIds.contains(button.id)
? SizedBox.shrink()
: TestButton(
text: button.text,
onTap: () => buttonTapped(index, button),
color: state.answer == button
? isCorrect
? Colors.green[200]
: Colors.red[200]
: Colors.white,
),
2024-05-22 20:48:44 +00:00
),
),
],
),
),
],
),
);
})
],
2024-05-28 21:25:51 +00:00
);
}),
);
}
}
class _Letter extends StatelessWidget {
final String text;
final Color? color;
_Letter({this.text = '', this.color});
@override
Widget build(BuildContext context) {
return Container(
width: 30,
height: 45,
margin: const EdgeInsets.all(2.0),
padding: const EdgeInsets.all(5.0),
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6.0),
border: Border.all(color: color ?? borderGray),
boxShadow: const [
// BoxShadow(
// color: Colors.black26,
// blurRadius: 4.0,
// ),
],
),
child: Material(
color: Colors.white,
child: Text(
text,
style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center,
2024-05-22 20:48:44 +00:00
),
2024-05-28 21:25:51 +00:00
),
);
2024-05-22 20:48:44 +00:00
}
}