import 'dart:collection'; import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart'; import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/workout_tree.dart'; import 'package:aitrainer_app/widgets/app_bar_common.dart'; import 'package:aitrainer_app/widgets/splash.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_treeview/tree_view.dart'; class ExerciseByPlanPage extends StatefulWidget { @override _ExerciseByPlanPage createState() => _ExerciseByPlanPage(); } class _ExerciseByPlanPage extends State { final GlobalKey _scaffoldKey = new GlobalKey(); // ignore: close_sinks ExerciseByPlanBloc bloc; @override void initState() { super.initState(); /// We require the initializers to run after the loading screen is rendered SchedulerBinding.instance.addPostFrameCallback((_) { BlocProvider.of(context).add(ExerciseByPlanLoad()); }); } @override Widget build(BuildContext context) { LinkedHashMap arguments = ModalRoute.of(context).settings.arguments; final int customerId = arguments['customerId']; bloc = BlocProvider.of(context); bloc.customerId = customerId; return Scaffold( key: _scaffoldKey, appBar: AppBarCommonNav(), body: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( image: DecorationImage( image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'): AssetImage('asset/image/WT_menu_dark.png'), fit: BoxFit.cover, alignment: Alignment.center, ), ), child: BlocConsumer(listener: (context, state) { if (state is ExerciseByPlanError) { Scaffold.of(context).showSnackBar(SnackBar( content: Text( state.message, ), backgroundColor: Colors.orange, )); } else if (state is ExerciseByPlanLoading) { LoadingDialog(); } }, // ignore: missing_return builder: (context, state) { if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) { return Container(); } else if (state is ExerciseByPlanReady) { return exerciseWidget(bloc); } else if (state is ExerciseByPlanError) { return exerciseWidget(bloc); } }))); } Widget exerciseWidget(ExerciseByPlanBloc bloc) { final LinkedHashMap args = LinkedHashMap(); TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc)); TreeViewTheme _treeViewTheme = TreeViewTheme( expanderTheme: ExpanderThemeData( type: ExpanderType.plusMinus, modifier: ExpanderModifier.circleOutlined, position: ExpanderPosition.start, color: Colors.black26, size: 10, ), labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800), parentLabelStyle: TextStyle( fontSize: 14, letterSpacing: 0.3, fontWeight: FontWeight.w800, color: Colors.orange.shade600, ), iconTheme: IconThemeData( size: 20, color: Colors.blue.shade800, ), colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent), ); return Scaffold( backgroundColor: Colors.transparent, body: TreeView( controller: _treeViewController, allowParentSelect: false, supportParentDoubleTap: false, //onExpansionChanged: _expandNodeHandler, onNodeTap: (key) { /* Node node = _treeViewController.getNode(key); WorkoutTree workoutTree = node.data as WorkoutTree; bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType); print("change node " + node.label + " key " + key); bloc.add(ExercisePlanUpdate(workoutTree: workoutTree)); Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc); */ Node node = _treeViewController.getNode(key); WorkoutTree workoutTree = node.data as WorkoutTree; args['blocExerciseByPlan'] = bloc; args['customerId'] = bloc.customerId; args['workoutTree'] = workoutTree; Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args); }, theme: _treeViewTheme, ), //bottomNavigationBar: BottomNavigator(bottomNavIndex: 2), floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, ); } List nodeExercisePlan(ExerciseByPlanBloc bloc) { List nodes = List(); Node actualNode; bool isEnglish = AppLanguage().appLocal == Locale("en"); bloc.menuTreeRepository.sortedTree.forEach((name, list) { List listWorkoutItem = list; List listExerciseTypePerMuscle = List(); NodeIcon icon; listWorkoutItem.forEach((element) { WorkoutTree treeItem = element; if ( treeItem.selected ) { icon = treeItem.executed == false ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") : NodeIcon(codePoint: Icons.check_box.codePoint, color: "green"); String exerciseLabel = isEnglish ? treeItem.name : treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation; List> planDetailList = List>(); String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId); if (planDetail.length > 0) { exerciseLabel += " (" + planDetail + ")"; } actualNode = Node( label: exerciseLabel, key: treeItem.id.toString(), data: treeItem, expanded: planDetailList.length > 0 ? true : false, children: [], icon: icon); listExerciseTypePerMuscle.add(actualNode); } }); if (name != null) { actualNode = Node( label: name, key: name, expanded: true, children: listExerciseTypePerMuscle, icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange")); nodes.add(actualNode); } }); return nodes; } }