import 'dart:async'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/tutorial.dart'; import 'package:aitrainer_app/model/tutorial_step.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; part 'tutorial_event.dart'; part 'tutorial_state.dart'; class TutorialBloc extends Bloc with Logging { late String tutorialName; final double mediaHeightBase = 675; bool isActive = false; bool canActivate = false; Tutorial? tutorial; String? actualText; String? actualCheck; List checks = []; double calculatedHeight = 0; TutorialStepAction? action; double? top; double left = 20; bool showCheckText = true; int parent = 0; int step = 0; MenuBloc? menuBloc; TutorialBloc({required this.tutorialName}) : super(TutorialInitial()); init() { if (Cache().tutorials != null) { print("Actual step: $step"); final List tutorials = Cache().tutorials!; tutorials.forEach((element) { final String realTutorialName = tutorialName.replaceFirst("tutorial", "").toLowerCase(); if (element.name.toLowerCase() == realTutorialName) { tutorial = element; setNextStepData(step); isActive = true; canActivate = true; } }); } } void setNextStepData(int step) { if (step == -1) { isActive = false; return; } if (tutorial != null && tutorial!.steps != null) { actualText = tutorial!.steps![step].tutorialTextTranslation; this.actualCheck = tutorial!.steps![step].checkText; print("Step: $step, text: $actualCheck"); this.checks = []; if (this.actualCheck != null) { this.checks = this.actualCheck!.split("|"); } else { this.checks.add("Next"); } if (this.tutorial!.steps![step].action != null) { this.action = this.tutorial!.steps![step].action; this.top = action!.top.toDouble(); this.left = action!.left == -1 ? 20 : action!.left.toDouble(); this.showCheckText = action!.showCheckText == true; this.parent = action!.parent; } } } bool isTutorialDone() { ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName); if (activityDone == null) { return true; } bool? isActivityDone = Cache().activitiesDone[activityDone.toStr()]; log("$tutorialName isActivityDone? $isActivityDone"); if (isActivityDone == null || isActivityDone == true) { return true; } canActivate = true; return false; } bool activateTutorial() { if (isTutorialDone()) { isActive = false; canActivate = false; return false; } init(); return true; } int getElementCount(String elem) { int pos = 0; int count = 0; bool out = false; while (out == false) { pos = actualText!.indexOf(elem, pos); if (pos == -1) { out = true; } else { count++; pos++; } } return count; } int getNextStep(int step) { int next = 0; if (action == null) { return step + 1; } step++; next = step; print("Next step:! $step"); if (step >= tutorial!.steps!.length) { next = -1; this.add(TutorialFinished()); } return next; } bool checkAction(String checkText) { final bool nextStep = checkText == actualCheck; if (nextStep) { this.add(TutorialNext(text: actualCheck!)); } return nextStep; } @override Stream mapEventToState(TutorialEvent event) async* { if (event is TutorialLoad) { init(); if (menuBloc != null) { menuBloc!.add(MenuCreate()); } } else if (event is TutorialNext) { print("Tutorial Next: ${event.text}"); if (tutorial != null) { yield TutorialLoading(); step = this.getNextStep(step); if (step == -1) { print("Tutorial $tutorialName finished!"); return; } print("Step: $step"); setNextStepData(step); if (menuBloc != null) { menuBloc!.add(MenuCreate()); } yield TutorialReady(); } } else if (event is TutorialWrongAction) { yield TutorialLoading(); actualText = tutorial!.steps![step].errorTextTranslation!; yield TutorialReady(); } else if (event is TutorialStart) { yield TutorialLoading(); canActivate = true; step = 0; yield TutorialReady(); } else if (event is TutorialFinished) { yield TutorialLoading(); isActive = false; canActivate = false; ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName); if (activityDone != null) { await Cache().setActivityDonePrefs(activityDone); } yield TutorialReady(); } } }