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; 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; } }); } } void setNextStepData(int step) { if (step == -1) { isActive = false; return; } if (tutorial != null && tutorial!.steps != null) { actualText = tutorial!.steps![step].tutorialTextTranslation; print("Step: $step, text: $actualText"); this.actualCheck = tutorial!.steps![step].checkText; 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; } calculateHeight(); } /* else { this.add(TutorialFinished()); } */ } bool activateTutorial() { if (!canActivate) { print("Tutorial canActivate false"); return false; } ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName); if (activityDone == null) { return false; } bool? isActivityDone = Cache().activitiesDone[activityDone.toStr()]; log("isActivityDone? $isActivityDone"); if (isActivityDone == null || isActivityDone == true) { return false; } log("Running tutorial $activityDone"); init(); return true; } void calculateHeight() { int count = getElementCount('

'); count += getElementCount('
'); double lines = (actualText!.length / 32 + count); if (lines < 5) { lines = lines + 2; } calculatedHeight = lines * 15; print("Calculated Height: $calculatedHeight length: ${actualText!.length} lines: $lines count: $count"); } 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; } /* bool found = false; if (tutorial != null && tutorial!.steps != null) { for (var nextStep in tutorial!.steps!) { print("step $step parent: ${nextStep.action!.parent}"); if (step + 1 == nextStep.step) { next = nextStep.step!; found = true; break; } } } */ step++; next = step; print("Next step:! $next"); 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) { if (tutorial != null) { yield TutorialLoading(); step = this.getNextStep(step); if (step == -1) { print("Tutorial $tutorialName finished!"); return; } print("Step: $step"); setNextStepData(step); print("Menu rebuild $menuBloc"); 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(); isActive = true; canActivate = true; step = 0; yield TutorialReady(); } else if (event is TutorialFinished) { yield TutorialLoading(); isActive = false; canActivate = false; ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName); print("activity Finished: $activityDone"); if (activityDone != null) { await Cache().setActivityDonePrefs(activityDone); } yield TutorialReady(); } } }