130 lines
3.8 KiB
Dart
130 lines
3.8 KiB
Dart
|
|
import 'dart:async';
|
||
|
|
import 'dart:developer';
|
||
|
|
|
||
|
|
import 'package:flutter/widgets.dart';
|
||
|
|
import 'package:mnemo_cards/features/tests/test_state_holder.dart';
|
||
|
|
import 'package:mnemo_cards/features/tests/test_widgets/test_image.dart';
|
||
|
|
import 'package:mnemo_cards/features/packs/pack_cache_manager.dart';
|
||
|
|
import 'package:mnemo_cards/theme/themes.dart';
|
||
|
|
import 'package:mnemo_cards/utils/iterable_helper.dart';
|
||
|
|
import 'package:mnemo_cards/utils/string_helper.dart';
|
||
|
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||
|
|
|
||
|
|
import '../../managers/repository/http_repository.dart';
|
||
|
|
import 'question_states/test_question_state.dart';
|
||
|
|
|
||
|
|
class TestManager extends ChangeNotifier {
|
||
|
|
final PackCacheManager packCacheManager;
|
||
|
|
final HttpRepository _repository;
|
||
|
|
final List<AbstractTestQuestion> questions = [];
|
||
|
|
Color color = borderGray;
|
||
|
|
final PageController pageController = PageController();
|
||
|
|
final TestHolder testHolder = TestHolder();
|
||
|
|
|
||
|
|
Future<List<TestDto>> loadTests({String? packId}) async {
|
||
|
|
final tests = (await _repository.getTests(packId: packId ?? ''))
|
||
|
|
.map((e) => TestDto.fromJson(e))
|
||
|
|
.toList();
|
||
|
|
return tests;
|
||
|
|
}
|
||
|
|
|
||
|
|
TestQuestionState? getState(int id) => testHolder.testQuestionState(id);
|
||
|
|
|
||
|
|
Iterable<TestQuestionState> get states => testHolder.state.questions.values;
|
||
|
|
|
||
|
|
Future<void> setActiveTest(String id, {String? packId}) async {
|
||
|
|
clearStates();
|
||
|
|
if (packId != null) {
|
||
|
|
await packCacheManager.loadPackFromCache(packId);
|
||
|
|
}
|
||
|
|
final test = await _repository.getTest(id);
|
||
|
|
questions.clear();
|
||
|
|
questions.addAll(test!.questions);
|
||
|
|
color = test.color?.asColor ?? borderGray;
|
||
|
|
testHolder.setQuestions(questions);
|
||
|
|
}
|
||
|
|
|
||
|
|
void setState(int id, TestQuestionState state) {
|
||
|
|
testHolder.setQuestionState(id, state);
|
||
|
|
log('Set state $id $state');
|
||
|
|
notifyListeners();
|
||
|
|
}
|
||
|
|
|
||
|
|
TestManager(
|
||
|
|
this.packCacheManager,
|
||
|
|
this._repository,
|
||
|
|
);
|
||
|
|
|
||
|
|
void clearStates() {
|
||
|
|
testHolder.clear();
|
||
|
|
notifyListeners();
|
||
|
|
}
|
||
|
|
|
||
|
|
AbstractTestQuestion getTest(int index) => questions[index];
|
||
|
|
|
||
|
|
void nextTest() {
|
||
|
|
pageController.animateToPage(
|
||
|
|
pageController.page!.toInt() + 1,
|
||
|
|
duration: Duration(milliseconds: 300),
|
||
|
|
curve: Curves.ease,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
void prevTest() {
|
||
|
|
pageController.animateToPage(
|
||
|
|
pageController.page!.toInt() - 1,
|
||
|
|
duration: Duration(milliseconds: 300),
|
||
|
|
curve: Curves.ease,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> preloadImages(BuildContext context) async {
|
||
|
|
for (final question in questions) {
|
||
|
|
switch (question.questionType) {
|
||
|
|
case TestQuestionType.simple:
|
||
|
|
final images = [
|
||
|
|
(question as SimpleTestQuestionBody).image,
|
||
|
|
...question.buttons.map((e) => e.image)
|
||
|
|
].whereNotNull();
|
||
|
|
for (final image in images) {
|
||
|
|
try {
|
||
|
|
final testImage = TestImage.image(image);
|
||
|
|
await precacheImage(
|
||
|
|
(await testImage.loadImage())!,
|
||
|
|
context,
|
||
|
|
);
|
||
|
|
} catch (e) {
|
||
|
|
rethrow;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
case TestQuestionType.input_buttons:
|
||
|
|
final images = [
|
||
|
|
(question as InputButtonsTestQuestionBody).image,
|
||
|
|
].whereNotNull();
|
||
|
|
for (final image in images) {
|
||
|
|
try {
|
||
|
|
final testImage = TestImage.image(image);
|
||
|
|
await precacheImage(
|
||
|
|
(await testImage.loadImage())!,
|
||
|
|
context,
|
||
|
|
);
|
||
|
|
} catch (e) {
|
||
|
|
rethrow;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
case TestQuestionType.matrix:
|
||
|
|
// TODO: Handle this case.
|
||
|
|
case TestQuestionType.match:
|
||
|
|
// TODO: Handle this case.
|
||
|
|
case TestQuestionType.undefined:
|
||
|
|
// TODO: Handle this case.
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<MemoryImage> loadImage(String packId, String path) async {
|
||
|
|
final bytes = await packCacheManager.loadPackFile(packId, path);
|
||
|
|
return MemoryImage(bytes!);
|
||
|
|
}
|
||
|
|
}
|