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:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/track.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()) { on(_onLoad); on(_onNext); on(_onWrongAction); on(_onStart); on(_onFinished); } void _onLoad(TutorialLoad event, Emitter emit) { emit(TutorialLoading()); init(); if (menuBloc != null) { menuBloc!.add(MenuCreate()); } emit(TutorialReady()); } void _onNext(TutorialNext event, Emitter emit) { print("Tutorial Next: ${event.text}"); if (tutorial != null) { emit(TutorialLoading()); step = this.getNextStep(step); if (step == -1) { print("Tutorial $tutorialName finished!"); return; } print("Step: $step"); setNextStepData(step); if (menuBloc != null) { menuBloc!.add(MenuCreate()); } Track().track(TrackingEvent.tutorial_step, eventValue: step.toString()); } } void _onWrongAction(TutorialWrongAction event, Emitter emit) { emit(TutorialLoading()); actualText = tutorial!.steps![step].errorTextTranslation!; emit(TutorialReady()); } void _onStart(TutorialStart event, Emitter emit) { emit(TutorialLoading()); canActivate = true; step = 0; emit(TutorialReady()); } void _onFinished(TutorialFinished event, Emitter emit) async { emit(TutorialLoading()); isActive = false; canActivate = false; ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName); if (activityDone != null) { await Cache().setActivityDonePrefs(activityDone); } Track().track(TrackingEvent.tutorial_finished); emit(TutorialReady()); } init() { if (Cache().tutorials != null) { 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; 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()]; 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; } }