209 lines
5.2 KiB
Dart
209 lines
5.2 KiB
Dart
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<TutorialEvent, TutorialState> with Logging {
|
|
late String tutorialName;
|
|
final double mediaHeightBase = 675;
|
|
bool isActive = false;
|
|
bool canActivate = false;
|
|
|
|
Tutorial? tutorial;
|
|
String? actualText;
|
|
String? actualCheck;
|
|
|
|
List<String> 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<TutorialLoad>(_onLoad);
|
|
on<TutorialNext>(_onNext);
|
|
on<TutorialWrongAction>(_onWrongAction);
|
|
on<TutorialStart>(_onStart);
|
|
on<TutorialFinished>(_onFinished);
|
|
}
|
|
|
|
void _onLoad(TutorialLoad event, Emitter<TutorialState> emit) {
|
|
emit(TutorialLoading());
|
|
init();
|
|
if (menuBloc != null) {
|
|
menuBloc!.add(MenuCreate());
|
|
}
|
|
emit(TutorialReady());
|
|
}
|
|
|
|
void _onNext(TutorialNext event, Emitter<TutorialState> 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<TutorialState> emit) {
|
|
emit(TutorialLoading());
|
|
actualText = tutorial!.steps![step].errorTextTranslation!;
|
|
emit(TutorialReady());
|
|
}
|
|
|
|
void _onStart(TutorialStart event, Emitter<TutorialState> emit) {
|
|
emit(TutorialLoading());
|
|
canActivate = true;
|
|
step = 0;
|
|
emit(TutorialReady());
|
|
}
|
|
|
|
void _onFinished(TutorialFinished event, Emitter<TutorialState> 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<Tutorial> 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;
|
|
}
|
|
}
|