Commit 42f15f6c1954d7adc8d5c7ad9908c6b99953ca7f

Authored by 吴启风
1 parent 8616f94b

feat:模块选择持久化&模块主题色从缓存获取

lib/app/app.dart
... ... @@ -32,6 +32,8 @@ class App extends StatelessWidget {
32 32 fontFamily: 'HannotateSC',
33 33 colorScheme: ColorScheme.fromSeed(seedColor: Colors.white),
34 34 useMaterial3: true,
  35 + ///系统主题色
  36 + primaryColor: const Color(0xFF00B6F1)
35 37 ),
36 38 builder: EasyLoading.init(
37 39 builder: (context, child) => ResponsiveBreakpoints(breakpoints: const [
... ...
lib/app/splash_page.dart
... ... @@ -19,6 +19,7 @@ import 'package:wow_english/utils/log_util.dart';
19 19 import 'package:wow_english/utils/sp_util.dart';
20 20  
21 21 import '../common/core/app_consts.dart';
  22 +import '../common/core/module_cache.dart';
22 23 import '../common/widgets/webview_dialog.dart';
23 24  
24 25 class SplashPage extends StatelessWidget {
... ... @@ -167,6 +168,7 @@ class _TransitionViewState extends State<TransitionView> {
167 168 void init() async {
168 169 changeDevice();
169 170 await SpUtil.preInit();
  171 + ModuleCache.instance.init();
170 172 AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.welcomeToWow);
171 173 startTime();
172 174 }
... ...
lib/common/core/module_cache.dart 0 → 100644
  1 +import 'dart:convert';
  2 +import 'dart:ui';
  3 +
  4 +import '../../models/course_module_entity.dart';
  5 +import '../../utils/sp_util.dart';
  6 +import '../utils/color_parser.dart';
  7 +
  8 +///模块缓存类
  9 +class ModuleCache {
  10 + // Private constructor
  11 + ModuleCache._privateConstructor();
  12 +
  13 + // Singleton instance
  14 + static final ModuleCache _instance = ModuleCache._privateConstructor();
  15 +
  16 + // Public accessor for the singleton instance
  17 + static ModuleCache get instance => _instance;
  18 +
  19 + // Variable to store the current module entity
  20 + CourseModuleEntity? _currentModule;
  21 +
  22 + // Key for SharedPreferences
  23 + static const String _moduleKey = "courseModule";
  24 +
  25 + // Initialize the cache by loading data from SharedPreferences
  26 + Future<void> init() async {
  27 + String? jsonString = SpUtil.getInstance().get<String>(_moduleKey);
  28 + if (jsonString != null) {
  29 + _currentModule = CourseModuleEntity.fromJson(json.decode(jsonString));
  30 + }
  31 + }
  32 +
  33 + // Getter and setter for the current module
  34 + CourseModuleEntity? get currentModule => _currentModule;
  35 + set currentModule(CourseModuleEntity? value) {
  36 + _currentModule = value;
  37 + _saveToPrefs(value);
  38 + }
  39 +
  40 + // Method to clear the cached module data
  41 + void clear() {
  42 + _currentModule = null;
  43 + _clearPrefs();
  44 + }
  45 +
  46 + // Save module data to SharedPreferences
  47 + void _saveToPrefs(CourseModuleEntity? module) {
  48 + if (module != null) {
  49 + String jsonString = json.encode(module.toJson());
  50 + SpUtil.getInstance().setData(_moduleKey, jsonString);
  51 + } else {
  52 + SpUtil.getInstance().remove(_moduleKey);
  53 + }
  54 + }
  55 +
  56 + String getCurrentThemeColorStr({String? colorStr}) {
  57 + return colorStr ?? _currentModule.getSafeThemeColor();
  58 + }
  59 +
  60 + ///根据当前课程阶段获取系统主题色
  61 + Color getCurrentThemeColor({String? colorStr}) {
  62 + return parseColor(getCurrentThemeColorStr(colorStr: colorStr));
  63 + }
  64 +
  65 + ///根据当前课程阶段获取系统主题名称
  66 + String getCurrentThemeName({String? name}) {
  67 + return name ?? _currentModule.getSafeName();
  68 + }
  69 +
  70 + // Clear all data from SharedPreferences
  71 + void _clearPrefs() async {
  72 + SpUtil.getInstance().remove(_moduleKey);
  73 + }
  74 +}
0 75 \ No newline at end of file
... ...
lib/common/utils/color_parser.dart 0 → 100644
  1 +import 'package:flutter/material.dart';
  2 +
  3 +/// 将"#80FFFF00"字符串类型的颜色值转成Color对象类型
  4 +Color parseColor(String color) {
  5 + // Remove the '#' character from the beginning of the string
  6 + String hexColor = color.replaceAll("#", "");
  7 +
  8 + // Check if the color is in the correct length (6 or 8)
  9 + if (hexColor.length == 6) {
  10 + // Add 'FF' for the alpha value if not provided
  11 + hexColor = "FF$hexColor";
  12 + } else if (hexColor.length != 8) {
  13 + ///如果数据异常,返回主题色兜底
  14 + // throw const FormatException("Invalid color format");
  15 + hexColor = "FF00B6F1";
  16 + }
  17 +
  18 + // Convert the hex string to an integer and create a Color object
  19 + return Color(int.parse(hexColor, radix: 16));
  20 +}
0 21 \ No newline at end of file
... ...
lib/generated/json/base/json_convert_content.dart
... ... @@ -139,7 +139,12 @@ class JsonConvert {
139 139 if (value == null) {
140 140 return null;
141 141 }
142   - return convertFuncMap[type]!(value as Map<String, dynamic>) as T;
  142 + var covertFunc = convertFuncMap[type]!;
  143 + if (covertFunc is Map<String, dynamic>) {
  144 + return covertFunc(value as Map<String, dynamic>) as T;
  145 + } else {
  146 + return covertFunc(Map<String, dynamic>.from(value)) as T;
  147 + }
143 148 } else {
144 149 throw UnimplementedError(
145 150 '$type unimplemented,you can try running the app again');
... ...
lib/models/course_module_entity.dart
... ... @@ -21,14 +21,49 @@ class CourseModuleEntity {
21 21 int? status;
22 22 String? courseModuleThemeColor;
23 23  
24   - CourseModuleEntity();
  24 + // 无参构造函数
  25 + CourseModuleEntity.empty();
25 26  
26   - factory CourseModuleEntity.fromJson(Map<String, dynamic> json) => $CourseModuleEntityFromJson(json);
  27 + // 命名构造函数
  28 + CourseModuleEntity(
  29 + {int? id,
  30 + String? code,
  31 + String? courseModuleName,
  32 + String? courseModuleThemeColor});
  33 +
  34 + factory CourseModuleEntity.fromJson(Map<String, dynamic> json) =>
  35 + $CourseModuleEntityFromJson(json);
27 36  
28 37 Map<String, dynamic> toJson() => $CourseModuleEntityToJson(this);
29 38  
  39 + // Factory constructor for creating an instance with only three parameters
  40 + factory CourseModuleEntity.of(int? courseModuleId, String? courseModuleCode,
  41 + String? courseModuleName, String? courseModuleThemeColor) {
  42 + return CourseModuleEntity(
  43 + id: courseModuleId,
  44 + code: courseModuleCode,
  45 + courseModuleName: courseModuleName,
  46 + courseModuleThemeColor: courseModuleThemeColor,
  47 + // Set default values or leave other fields null
  48 + );
  49 + }
  50 +
30 51 @override
31 52 String toString() {
32 53 return jsonEncode(this);
33 54 }
34 55 }
  56 +
  57 +///对可空的CourseModuleEntity对象扩展
  58 +extension PersonSafeExt on CourseModuleEntity? {
  59 +
  60 + ///获取非空的主题色,系统主题色0xFF00B6F1兜底
  61 + String getSafeThemeColor() {
  62 + return this?.courseModuleThemeColor ?? '0xFF00B6F1';
  63 + }
  64 +
  65 + ///获取非空的阶段名称
  66 + String getSafeName() {
  67 + return this?.name ?? 'learn wow!';
  68 + }
  69 +}
... ...
lib/pages/module/course_module_page.dart
... ... @@ -5,9 +5,10 @@ import &#39;package:wow_english/common/widgets/we_app_bar.dart&#39;;
5 5 import 'package:wow_english/models/course_module_entity.dart';
6 6 import 'package:wow_english/route/route.dart';
7 7  
  8 +import '../../common/core/module_cache.dart';
8 9 import '../../common/utils/click_with_music_controller.dart';
  10 +import '../../common/utils/color_parser.dart';
9 11 import '../../utils/audio_player_util.dart';
10   -import '../section/courese_module_model.dart';
11 12 import 'bloc/module_bloc.dart';
12 13 import 'widgets/module_item_widget.dart';
13 14  
... ... @@ -94,12 +95,11 @@ class _LessonPageView extends StatelessWidget {
94 95 // ? Colors.red
95 96 // : Colors.white,
96 97 color:
97   - CourseModuleModel(model?.code ?? 'Phase-1')
98   - .color
  98 + parseColor(model.getSafeThemeColor())
99 99 .withOpacity(
100 100 bloc.currentPageIndex == index
101 101 ? 1
102   - : 0.35),
  102 + : 0.15),
103 103 borderRadius: BorderRadius.circular(5.r),
104 104 border: Border.all(
105 105 width: 0.5,
... ... @@ -167,6 +167,7 @@ class _LessonPageView extends StatelessWidget {
167 167 model: model,
168 168 isSelected: bloc.currentPageIndex == index,
169 169 onClickEvent: () {
  170 + ModuleCache.instance.currentModule = model;
170 171 ///todo 不同阶段音乐文件待提供
171 172 ClickWithMusicController.instance.playMusicAndPerformAction(
172 173 context,
... ...
lib/pages/module/widgets/module_item_widget.dart
1 1 import 'package:flutter/material.dart';
2 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 3 import 'package:wow_english/common/extension/string_extension.dart';
  4 +import 'package:wow_english/common/utils/color_parser.dart';
4 5 import 'package:wow_english/common/widgets/ow_image_widget.dart';
5 6 import 'package:wow_english/models/course_module_entity.dart';
6 7  
7   -import '../../section/courese_module_model.dart';
8   -
9 8 ///阶段(模块)item布局
10 9 class ModuleItemWidget extends StatelessWidget {
11   - const ModuleItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent});
  10 + const ModuleItemWidget(
  11 + {super.key, required this.isSelected, this.model, this.onClickEvent});
  12 +
12 13 ///是否被选中
13 14 final bool isSelected;
14 15 final CourseModuleEntity? model;
... ... @@ -23,7 +24,7 @@ class ModuleItemWidget extends StatelessWidget {
23 24 }
24 25 onClickEvent?.call();
25 26 },
26   - child: isSelected?_selectWidget():_unSelectWidget(),
  27 + child: isSelected ? _selectWidget() : _unSelectWidget(),
27 28 );
28 29 }
29 30  
... ... @@ -31,12 +32,9 @@ class ModuleItemWidget extends StatelessWidget {
31 32 return Container(
32 33 padding: const EdgeInsets.all(20),
33 34 decoration: BoxDecoration(
34   - image: DecorationImage(
35   - image: AssetImage('gendubeij'.assetPng)
36   - )
37   - ),
  35 + image: DecorationImage(image: AssetImage('gendubeij'.assetPng))),
38 36 child: OwImageWidget(
39   - name: model?.picUrl??'',
  37 + name: model?.picUrl ?? '',
40 38 ),
41 39 );
42 40 }
... ... @@ -45,48 +43,37 @@ class ModuleItemWidget extends StatelessWidget {
45 43 return Container(
46 44 padding: const EdgeInsets.all(10),
47 45 decoration: BoxDecoration(
48   - image: DecorationImage(
49   - image: AssetImage(
50   - 'gendubeij'.assetPng,
51   - ),
52   - fit: BoxFit.fill
53   - ),
  46 + image: DecorationImage(
  47 + image: AssetImage(
  48 + 'gendubeij'.assetPng,
  49 + ),
  50 + fit: BoxFit.fill),
54 51 ),
55   - child: Column(
  52 + child: Column(
56 53 mainAxisAlignment: MainAxisAlignment.spaceBetween,
57 54 children: [
58 55 Expanded(
59 56 child: OwImageWidget(
60   - name: model?.picUrl??'',
  57 + name: model?.picUrl ?? '',
61 58 ),
62 59 ),
63 60 10.verticalSpace,
64 61 Container(
65 62 decoration: BoxDecoration(
66   - color: CourseModuleModel(model?.code??'Phase-1').color,
67   - borderRadius: BorderRadius.circular(6.r),
68   - border: Border.all(
69   - color: const Color(0xFF333333),
70   - width: 1.0
71   - )
72   - ),
  63 + color: parseColor(model.getSafeThemeColor()),
  64 + borderRadius: BorderRadius.circular(6.r),
  65 + border: Border.all(color: const Color(0xFF333333), width: 1.0)),
73 66 padding: EdgeInsets.symmetric(horizontal: 10.w),
74 67 child: Column(
75 68 children: [
76 69 Text(
77   - model?.name??'',
78   - style: TextStyle(
79   - color: Colors.white,
80   - fontSize: 12.sp
81   - ),
  70 + model?.getSafeName() ?? '',
  71 + style: TextStyle(color: Colors.white, fontSize: 12.sp),
82 72 ),
83 73 Text(
84   - model?.des??'',
  74 + model?.des ?? '',
85 75 maxLines: 1,
86   - style: TextStyle(
87   - color: Colors.white,
88   - fontSize: 12.sp
89   - ),
  76 + style: TextStyle(color: Colors.white, fontSize: 12.sp),
90 77 )
91 78 ],
92 79 ),
... ... @@ -95,4 +82,4 @@ class ModuleItemWidget extends StatelessWidget {
95 82 ),
96 83 );
97 84 }
98   -}
99 85 \ No newline at end of file
  86 +}
... ...
lib/pages/section/bloc/section_bloc.dart
... ... @@ -38,6 +38,7 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
38 38  
39 39 ScrollController get indicatorSrollController => _indicatorSrollController;
40 40  
  41 + ///之前传进来是用于根据courseModuleCode获取主题色的,现在不用了。参数还是先留着,预防后面需要
41 42 CourseUnitEntity _courseUnitEntity;
42 43  
43 44 CourseUnitEntity get courseUnitEntity => _courseUnitEntity;
... ...
lib/pages/section/section_page.dart
... ... @@ -3,6 +3,7 @@ import &#39;package:flutter/material.dart&#39;;
3 3 import 'package:flutter_bloc/flutter_bloc.dart';
4 4 import 'package:flutter_screenutil/flutter_screenutil.dart';
5 5 import 'package:nested_scroll_views/material.dart';
  6 +import 'package:wow_english/common/core/module_cache.dart';
6 7 import 'package:wow_english/common/core/user_util.dart';
7 8 import 'package:wow_english/common/utils/click_with_music_controller.dart';
8 9 import 'package:wow_english/models/course_unit_entity.dart';
... ... @@ -138,9 +139,7 @@ class _SectionPageView extends StatelessWidget {
138 139 await bloc.requestEnterClass(courseLessonId, () {
139 140 pushNamed(AppRouteName.topicPic, arguments: {
140 141 'courseLessonId': courseLessonId,
141   - 'moduleColor': CourseModuleModel(
142   - bloc.courseUnitEntity.courseModuleCode ?? 'Phase-1')
143   - .color
  142 + 'moduleColor': ModuleCache.instance.getCurrentThemeColor()
144 143 }).then((value) {
145 144 if (value != null) {
146 145 Map<String, dynamic> dataMap =
... ... @@ -175,7 +174,6 @@ class _SectionPageView extends StatelessWidget {
175 174 children: [
176 175 SectionHeaderWidget(
177 176 title: bloc.getCourseUnitDetail().name,
178   - courseModuleCode: bloc.courseUnitEntity.courseModuleCode,
179 177 onBack: () {
180 178 popPage(data: {
181 179 'needRefresh': bloc.courseUnitEntityChanged,
... ... @@ -281,9 +279,7 @@ Widget _itemTransCard(
281 279 const SizedBox(height: 16.0),
282 280 // 间距
283 281 CircularProgressIndicator(
284   - color: CourseModuleModel(
285   - bloc.courseUnitEntity.courseModuleCode ?? 'Phase-1')
286   - .color),
  282 + color: ModuleCache.instance.getCurrentThemeColor()),
287 283 // 加载动画
288 284 ],
289 285 ),
... ... @@ -332,7 +328,6 @@ Widget _itemTransCard(
332 328 sectionData.id.toString(), sectionData.courseType));
333 329 },
334 330 child: SectionItem(
335   - courseModuleId: bloc.courseUnitEntity.courseModuleCode,
336 331 lessons: sectionData,
337 332 ),
338 333 );
... ...
lib/pages/section/widgets/section_header_widget.dart
... ... @@ -4,17 +4,15 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;;
4 4 import 'package:wow_english/common/extension/string_extension.dart';
5 5 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
6 6  
7   -import '../courese_module_model.dart';
  7 +import '../../../common/core/module_cache.dart';
8 8  
9 9 /// 环节(课程)列表页标题栏
10 10 class SectionHeaderWidget extends StatelessWidget {
11 11 const SectionHeaderWidget(
12   - {super.key, this.title, this.courseModuleCode, this.onBack});
  12 + {super.key, this.title, this.onBack});
13 13  
14 14 final String? title;
15 15  
16   - final String? courseModuleCode;
17   -
18 16 final VoidCallback? onBack;
19 17  
20 18 @override
... ... @@ -24,7 +22,7 @@ class SectionHeaderWidget extends StatelessWidget {
24 22 return Container(
25 23 height: 45,
26 24 width: double.infinity,
27   - color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
  25 + color: ModuleCache.instance.getCurrentThemeColor(),
28 26 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
29 27 child: Row(
30 28 children: [
... ... @@ -49,9 +47,7 @@ class SectionHeaderWidget extends StatelessWidget {
49 47 20.horizontalSpace,
50 48 Expanded(
51 49 child: Text(
52   - title ??
53   - CourseModuleModel(courseModuleCode ?? 'Phase-1')
54   - .courseModuleTitle,
  50 + title ?? ModuleCache.instance.getCurrentThemeName(),
55 51 textAlign: TextAlign.left,
56 52 style: const TextStyle(color: Colors.white, fontSize: 30.0),
57 53 )),
... ...
lib/pages/section/widgets/section_item.dart
... ... @@ -3,15 +3,13 @@ import &#39;package:flutter_screenutil/flutter_screenutil.dart&#39;;
3 3 import 'package:wow_english/common/extension/string_extension.dart';
4 4 import 'package:wow_english/common/widgets/ow_image_widget.dart';
5 5  
  6 +import '../../../common/core/module_cache.dart';
6 7 import '../../../models/course_section_entity.dart';
7   -import '../../../models/course_unit_entity.dart';
8   -import '../courese_module_model.dart';
9 8  
10 9 ///环节item布局
11 10 class SectionItem extends StatelessWidget {
12   - const SectionItem({super.key, this.lessons, this.courseModuleId});
  11 + const SectionItem({super.key, this.lessons});
13 12  
14   - final String? courseModuleId;
15 13 final CourseSectionEntity? lessons;
16 14  
17 15 @override
... ... @@ -62,7 +60,7 @@ class SectionItem extends StatelessWidget {
62 60 width: 2,
63 61 color: const Color(0xFF140C10),
64 62 ),
65   - color: CourseModuleModel(courseModuleId ?? 'Phase-1').color,
  63 + color: ModuleCache.instance.getCurrentThemeColor(),
66 64 borderRadius: BorderRadius.circular(6)
67 65 ),
68 66 padding: EdgeInsets.symmetric(horizontal: 10.w),
... ...
lib/pages/unit/bloc.dart
... ... @@ -2,6 +2,7 @@ import &#39;package:bloc/bloc.dart&#39;;
2 2 import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart';
3 3 import 'package:wow_english/utils/audio_player_util.dart';
4 4  
  5 +import '../../common/core/module_cache.dart';
5 6 import '../../common/request/dao/lesson_dao.dart';
6 7 import '../../common/request/exception.dart';
7 8 import '../../models/course_module_entity.dart';
... ... @@ -24,6 +25,8 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
24 25 bool exchangeResult = false;
25 26  
26 27 UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) {
  28 + ///缓存当前模块信息
  29 + setIfNotNull(courseEntity);
27 30 on<RequestUnitDataEvent>(_requestUnitDatas);
28 31 on<UnitInitEvent>((event, emit) {
29 32 AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.inMyTummy);
... ... @@ -35,6 +38,7 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
35 38 try {
36 39 await loading(() async {
37 40 _unitData = await LessonDao.courseUnit(event.moduleId);
  41 + setIfNull(_unitData);
38 42 emitter(UnitDataLoadState());
39 43 });
40 44 } catch (e) {
... ... @@ -44,6 +48,27 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
44 48 }
45 49 }
46 50  
  51 + ///如果从模块页选择回来,则刷新缓存,否则认为是从
  52 + void setIfNotNull(CourseModuleEntity? courseModuleEntity) {
  53 + if (courseModuleEntity != null) {
  54 + _moduleEntity = courseModuleEntity;
  55 + } else {
  56 + _moduleEntity = ModuleCache.instance.currentModule;
  57 + }
  58 + }
  59 +
  60 + ///理论上只有没有缓存的情况下首次进入单元列表,数据请求成功后构建第一次缓存
  61 + void setIfNull(CourseUnitEntity? courseUnitData) {
  62 + if (_moduleEntity == null && courseUnitData != null) {
  63 + _moduleEntity = CourseModuleEntity.of(
  64 + courseUnitData.nowCourseModuleId,
  65 + courseUnitData.courseModuleCode,
  66 + courseUnitData.nowCourseModuleName,
  67 + courseUnitData.courseModuleThemeColor);
  68 + ModuleCache.instance.currentModule = _moduleEntity;
  69 + }
  70 + }
  71 +
47 72 String? getCourseModuleCode() {
48 73 return _moduleEntity?.code ?? _unitData?.courseModuleCode;
49 74 }
... ...
lib/pages/unit/widget/home_tab_header_widget.dart
... ... @@ -5,7 +5,7 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;;
5 5 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
6 6  
7 7 import '../../../common/core/app_config_helper.dart';
8   -import '../../section/courese_module_model.dart';
  8 +import '../../../common/core/module_cache.dart';
9 9  
10 10 enum HeaderActionType {
11 11 //视频跟读
... ... @@ -35,7 +35,7 @@ class HomeTabHeaderWidget extends StatelessWidget {
35 35 return Container(
36 36 height: 45,
37 37 width: double.infinity,
38   - color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
  38 + color: ModuleCache.instance.getCurrentThemeColor(),
39 39 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
40 40 child: Row(
41 41 children: [
... ... @@ -60,8 +60,7 @@ class HomeTabHeaderWidget extends StatelessWidget {
60 60 20.horizontalSpace,
61 61 Expanded(
62 62 child: Text(
63   - CourseModuleModel(courseModuleCode ?? 'Phase-1')
64   - .courseModuleTitle,
  63 + ModuleCache.instance.getCurrentThemeName(),
65 64 textAlign: TextAlign.left,
66 65 style: const TextStyle(color: Colors.white, fontSize: 30.0),
67 66 )),
... ...
lib/route/route.dart
... ... @@ -119,7 +119,7 @@ class AppRouter {
119 119 case AppRouteName.courseModule:
120 120 return CupertinoPageRoute(builder: (_) => const CourseModulePage());
121 121 case AppRouteName.courseUnit:
122   - CourseModuleEntity courseModuleEntity = CourseModuleEntity();
  122 + CourseModuleEntity? courseModuleEntity;
123 123 if (settings.arguments != null) {
124 124 courseModuleEntity = (settings.arguments as Map)
125 125 .getOrNull('courseModuleEntity') as CourseModuleEntity;
... ...