Commit 2187c85f138169f7b863bea0c5aff8b5d6cdf7b2
1 parent
2c079546
feat:课程结构调整
Showing
34 changed files
with
576 additions
and
354 deletions
lib/app/splash_page.dart
... | ... | @@ -77,7 +77,7 @@ class _TransitionViewState extends State<TransitionView> { |
77 | 77 | }*/ |
78 | 78 | bool isAggreementAccepted = AppConfigHelper.getAgreementAccepted(); |
79 | 79 | if (isAggreementAccepted) { |
80 | - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false); | |
80 | + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); | |
81 | 81 | } else { |
82 | 82 | showDialog( |
83 | 83 | context: context, |
... | ... | @@ -91,7 +91,7 @@ class _TransitionViewState extends State<TransitionView> { |
91 | 91 | leftTap: () { |
92 | 92 | AppConfigHelper.saveAgreementAccepted(true); |
93 | 93 | pushNamedAndRemoveUntil( |
94 | - AppRouteName.moduleSelect, (route) => false); | |
94 | + AppRouteName.home, (route) => false); | |
95 | 95 | }, |
96 | 96 | rightTap: () { |
97 | 97 | // 退出应用 | ... | ... |
lib/common/request/apis.dart
... | ... | @@ -53,6 +53,9 @@ class Apis { |
53 | 53 | // 接口地址:https://app.apifox.com/link/project/2684751/apis/api-89897662 |
54 | 54 | static const String courseLesson = 'home/courseLesson'; |
55 | 55 | |
56 | + // 课程环节列表 | |
57 | + static const String courseSection = 'course/courseLesson'; | |
58 | + | |
56 | 59 | /// 磨耳朵 |
57 | 60 | /// GET |
58 | 61 | static const String ears = 'course/grinding/ears'; | ... | ... |
lib/common/request/dao/home_dao.dart renamed to lib/common/request/dao/lesson_dao.dart
1 | 1 | import 'package:wow_english/common/request/request_client.dart'; |
2 | 2 | import 'package:wow_english/models/course_entity.dart'; |
3 | +import 'package:wow_english/models/course_section_entity.dart'; | |
3 | 4 | |
4 | 5 | import '../../../models/course_module_entity.dart'; |
5 | 6 | import '../../../models/course_unit_entity.dart'; |
6 | 7 | |
7 | -class HomeDao { | |
8 | +class LessonDao { | |
8 | 9 | ///获取课程模块(列表)信息 |
9 | 10 | static Future<List<CourseModuleEntity?>?> courseModule() async { |
10 | 11 | var data = await requestClient.get<List<CourseModuleEntity>>(Apis.courseModule); |
... | ... | @@ -12,20 +13,30 @@ class HomeDao { |
12 | 13 | } |
13 | 14 | |
14 | 15 | ///课程单元列表 |
15 | - static Future<CourseUnitEntity?> courseUnit(int moduleId) async { | |
16 | + static Future<CourseUnitEntity?> courseUnit(int? moduleId) async { | |
16 | 17 | Map<String, dynamic> mapData = {}; |
17 | - mapData['moduleId'] = moduleId; | |
18 | + if (moduleId != null) { | |
19 | + mapData['moduleId'] = moduleId; | |
20 | + } | |
18 | 21 | var data = await requestClient.get<CourseUnitEntity>(Apis.courseUnit, queryParameters: mapData); |
19 | 22 | return data; |
20 | 23 | } |
21 | 24 | |
22 | 25 | ///课程列表 |
23 | - static Future<CourseEntity?> courseLesson({int? moduleId}) async { | |
26 | + static Future<CourseEntity?> courseLesson({int? courseUnitId}) async { | |
24 | 27 | Map<String, dynamic> mapData = {}; |
25 | - if (moduleId != null) { | |
26 | - mapData['moduleId'] = moduleId; | |
28 | + if (courseUnitId != null) { | |
29 | + mapData['courseUnitId'] = courseUnitId; | |
27 | 30 | } |
28 | 31 | var data = await requestClient.get<CourseEntity>(Apis.courseLesson, queryParameters: mapData); |
29 | 32 | return data; |
30 | 33 | } |
34 | + | |
35 | + ///课程(单元)列表 | |
36 | + static Future<List<CourseSectionEntity>?> courseSection({required int courseUnitId}) async { | |
37 | + Map<String, dynamic> mapData = {}; | |
38 | + mapData['courseUnitId'] = courseUnitId; | |
39 | + var data = await requestClient.get<List<CourseSectionEntity>?>(Apis.courseSection, queryParameters: mapData); | |
40 | + return data; | |
41 | + } | |
31 | 42 | } | ... | ... |
lib/generated/json/base/json_convert_content.dart
... | ... | @@ -10,6 +10,7 @@ import 'package:wow_english/models/app_version_entity.dart'; |
10 | 10 | import 'package:wow_english/models/course_entity.dart'; |
11 | 11 | import 'package:wow_english/models/course_module_entity.dart'; |
12 | 12 | import 'package:wow_english/models/course_process_entity.dart'; |
13 | +import 'package:wow_english/models/course_section_entity.dart'; | |
13 | 14 | import 'package:wow_english/models/course_unit_entity.dart'; |
14 | 15 | import 'package:wow_english/models/follow_read_entity.dart'; |
15 | 16 | import 'package:wow_english/models/listen_entity.dart'; |
... | ... | @@ -198,6 +199,10 @@ class JsonConvert { |
198 | 199 | return data.map<CourseProcessVideos>((Map<String, dynamic> e) => |
199 | 200 | CourseProcessVideos.fromJson(e)).toList() as M; |
200 | 201 | } |
202 | + if (<CourseSectionEntity>[] is M) { | |
203 | + return data.map<CourseSectionEntity>((Map<String, dynamic> e) => | |
204 | + CourseSectionEntity.fromJson(e)).toList() as M; | |
205 | + } | |
201 | 206 | if (<CourseUnitEntity>[] is M) { |
202 | 207 | return data.map<CourseUnitEntity>((Map<String, dynamic> e) => |
203 | 208 | CourseUnitEntity.fromJson(e)).toList() as M; |
... | ... | @@ -261,6 +266,7 @@ class JsonConvertClassCollection { |
261 | 266 | (CourseProcessTopicsTopicAnswerList) |
262 | 267 | .toString(): CourseProcessTopicsTopicAnswerList.fromJson, |
263 | 268 | (CourseProcessVideos).toString(): CourseProcessVideos.fromJson, |
269 | + (CourseSectionEntity).toString(): CourseSectionEntity.fromJson, | |
264 | 270 | (CourseUnitEntity).toString(): CourseUnitEntity.fromJson, |
265 | 271 | (CourseUnitDetail).toString(): CourseUnitDetail.fromJson, |
266 | 272 | (FollowReadEntity).toString(): FollowReadEntity.fromJson, | ... | ... |
lib/generated/json/course_section_entity.g.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | |
2 | +import 'package:wow_english/models/course_section_entity.dart'; | |
3 | + | |
4 | +CourseSectionEntity $CourseSectionEntityFromJson(Map<String, dynamic> json) { | |
5 | + final CourseSectionEntity courseSectionEntity = CourseSectionEntity(); | |
6 | + final int? id = jsonConvert.convert<int>(json['id']); | |
7 | + if (id != null) { | |
8 | + courseSectionEntity.id = id; | |
9 | + } | |
10 | + final int? courseUnitId = jsonConvert.convert<int>(json['courseUnitId']); | |
11 | + if (courseUnitId != null) { | |
12 | + courseSectionEntity.courseUnitId = courseUnitId; | |
13 | + } | |
14 | + final int? courseModuleId = jsonConvert.convert<int>(json['courseModuleId']); | |
15 | + if (courseModuleId != null) { | |
16 | + courseSectionEntity.courseModuleId = courseModuleId; | |
17 | + } | |
18 | + final String? name = jsonConvert.convert<String>(json['name']); | |
19 | + if (name != null) { | |
20 | + courseSectionEntity.name = name; | |
21 | + } | |
22 | + final dynamic des = json['des']; | |
23 | + if (des != null) { | |
24 | + courseSectionEntity.des = des; | |
25 | + } | |
26 | + final int? courseType = jsonConvert.convert<int>(json['courseType']); | |
27 | + if (courseType != null) { | |
28 | + courseSectionEntity.courseType = courseType; | |
29 | + } | |
30 | + final dynamic coverUrl = json['coverUrl']; | |
31 | + if (coverUrl != null) { | |
32 | + courseSectionEntity.coverUrl = coverUrl; | |
33 | + } | |
34 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | |
35 | + if (sortOrder != null) { | |
36 | + courseSectionEntity.sortOrder = sortOrder; | |
37 | + } | |
38 | + final int? status = jsonConvert.convert<int>(json['status']); | |
39 | + if (status != null) { | |
40 | + courseSectionEntity.status = status; | |
41 | + } | |
42 | + final bool? lock = jsonConvert.convert<bool>(json['lock']); | |
43 | + if (lock != null) { | |
44 | + courseSectionEntity.lock = lock; | |
45 | + } | |
46 | + return courseSectionEntity; | |
47 | +} | |
48 | + | |
49 | +Map<String, dynamic> $CourseSectionEntityToJson(CourseSectionEntity entity) { | |
50 | + final Map<String, dynamic> data = <String, dynamic>{}; | |
51 | + data['id'] = entity.id; | |
52 | + data['courseUnitId'] = entity.courseUnitId; | |
53 | + data['courseModuleId'] = entity.courseModuleId; | |
54 | + data['name'] = entity.name; | |
55 | + data['des'] = entity.des; | |
56 | + data['courseType'] = entity.courseType; | |
57 | + data['coverUrl'] = entity.coverUrl; | |
58 | + data['sortOrder'] = entity.sortOrder; | |
59 | + data['status'] = entity.status; | |
60 | + data['lock'] = entity.lock; | |
61 | + return data; | |
62 | +} | |
63 | + | |
64 | +extension CourseSectionEntityExtension on CourseSectionEntity { | |
65 | + CourseSectionEntity copyWith({ | |
66 | + int? id, | |
67 | + int? courseUnitId, | |
68 | + int? courseModuleId, | |
69 | + String? name, | |
70 | + dynamic des, | |
71 | + int? courseType, | |
72 | + dynamic coverUrl, | |
73 | + int? sortOrder, | |
74 | + int? status, | |
75 | + bool? lock, | |
76 | + }) { | |
77 | + return CourseSectionEntity() | |
78 | + ..id = id ?? this.id | |
79 | + ..courseUnitId = courseUnitId ?? this.courseUnitId | |
80 | + ..courseModuleId = courseModuleId ?? this.courseModuleId | |
81 | + ..name = name ?? this.name | |
82 | + ..des = des ?? this.des | |
83 | + ..courseType = courseType ?? this.courseType | |
84 | + ..coverUrl = coverUrl ?? this.coverUrl | |
85 | + ..sortOrder = sortOrder ?? this.sortOrder | |
86 | + ..status = status ?? this.status | |
87 | + ..lock = lock ?? this.lock; | |
88 | + } | |
89 | +} | |
0 | 90 | \ No newline at end of file | ... | ... |
lib/models/course_module_entity.dart
lib/models/course_section_entity.dart
0 → 100644
1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | |
2 | +import 'package:wow_english/generated/json/course_section_entity.g.dart'; | |
3 | +import 'dart:convert'; | |
4 | +export 'package:wow_english/generated/json/course_section_entity.g.dart'; | |
5 | + | |
6 | +@JsonSerializable() | |
7 | +class CourseSectionEntity { | |
8 | + late int id; | |
9 | + late int courseUnitId; | |
10 | + late int courseModuleId; | |
11 | + late String name; | |
12 | + dynamic des; | |
13 | + late int courseType; | |
14 | + dynamic coverUrl; | |
15 | + late int sortOrder; | |
16 | + late int status; | |
17 | + late bool lock; | |
18 | + | |
19 | + CourseSectionEntity(); | |
20 | + | |
21 | + factory CourseSectionEntity.fromJson(Map<String, dynamic> json) => $CourseSectionEntityFromJson(json); | |
22 | + | |
23 | + Map<String, dynamic> toJson() => $CourseSectionEntityToJson(this); | |
24 | + | |
25 | + @override | |
26 | + String toString() { | |
27 | + return jsonEncode(this); | |
28 | + } | |
29 | +} | |
0 | 30 | \ No newline at end of file | ... | ... |
lib/pages/moduleSelect/bloc.dart renamed to lib/pages/home/bloc.dart
1 | 1 | import 'package:bloc/bloc.dart'; |
2 | 2 | import 'package:flutter/cupertino.dart'; |
3 | 3 | import 'package:flutter/foundation.dart'; |
4 | -import 'package:wow_english/models/app_config_entity.dart'; | |
5 | 4 | |
6 | 5 | import '../../common/core/app_config_helper.dart'; |
7 | 6 | import '../../common/request/dao/system_dao.dart'; |
... | ... | @@ -10,17 +9,17 @@ import '../../utils/log_util.dart'; |
10 | 9 | import 'event.dart'; |
11 | 10 | import 'state.dart'; |
12 | 11 | |
13 | -class ModuleSelectBloc extends Bloc<ModuleSelectEvent, ModuleSelectState> { | |
14 | - ModuleSelectBloc() : super(ModuleSelectState().init()) { | |
12 | +class ModuleSelectBloc extends Bloc<HomeEvent, HomeState> { | |
13 | + ModuleSelectBloc() : super(HomeState().init()) { | |
15 | 14 | on<InitEvent>(_init); |
16 | 15 | } |
17 | 16 | |
18 | - void _init(InitEvent event, Emitter<ModuleSelectState> emit) async { | |
17 | + void _init(InitEvent event, Emitter<HomeState> emit) async { | |
19 | 18 | await _checkUpdate(emit); |
20 | 19 | debugPrint('WQF ModuleSelectBloc _init'); |
21 | 20 | } |
22 | 21 | |
23 | - Future<void> _checkUpdate(Emitter<ModuleSelectState> emit) async { | |
22 | + Future<void> _checkUpdate(Emitter<HomeState> emit) async { | |
24 | 23 | if (AppConfigHelper.checkedUpdate) { |
25 | 24 | return; |
26 | 25 | } | ... | ... |
lib/pages/home/event.dart
0 → 100644
lib/pages/moduleSelect/state.dart renamed to lib/pages/home/state.dart
1 | 1 | import 'package:wow_english/models/app_version_entity.dart'; |
2 | 2 | |
3 | -class ModuleSelectState { | |
4 | - ModuleSelectState init() { | |
5 | - return ModuleSelectState(); | |
3 | +class HomeState { | |
4 | + HomeState init() { | |
5 | + return HomeState(); | |
6 | 6 | } |
7 | 7 | |
8 | - ModuleSelectState clone() { | |
9 | - return ModuleSelectState(); | |
8 | + HomeState clone() { | |
9 | + return HomeState(); | |
10 | 10 | } |
11 | 11 | } |
12 | 12 | |
13 | -class UpdateDialogState extends ModuleSelectState { | |
13 | +class UpdateDialogState extends HomeState { | |
14 | 14 | |
15 | 15 | final AppVersionEntity appVersionEntity; |
16 | 16 | ... | ... |
lib/pages/moduleSelect/view.dart renamed to lib/pages/home/view.dart
... | ... | @@ -9,8 +9,8 @@ import 'package:url_launcher/url_launcher.dart'; |
9 | 9 | import 'package:wow_english/common/core/app_config_helper.dart'; |
10 | 10 | import 'package:wow_english/common/extension/string_extension.dart'; |
11 | 11 | import 'package:wow_english/models/app_version_entity.dart'; |
12 | -import 'package:wow_english/pages/moduleSelect/state.dart'; | |
13 | -import 'package:wow_english/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart'; | |
12 | +import 'package:wow_english/pages/home/state.dart'; | |
13 | +import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart'; | |
14 | 14 | import 'package:wow_english/pages/user/bloc/user_bloc.dart'; |
15 | 15 | |
16 | 16 | import '../../common/core/user_util.dart'; |
... | ... | @@ -21,8 +21,8 @@ import 'event.dart'; |
21 | 21 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
22 | 22 | import 'package:wow_english/route/route.dart'; |
23 | 23 | |
24 | -class ModuleSelectPage extends StatelessWidget { | |
25 | - const ModuleSelectPage({super.key}); | |
24 | +class HomePage extends StatelessWidget { | |
25 | + const HomePage({super.key}); | |
26 | 26 | |
27 | 27 | @override |
28 | 28 | Widget build(BuildContext context) { |
... | ... | @@ -42,7 +42,7 @@ class _HomePageView extends StatelessWidget { |
42 | 42 | BlocListener<UserBloc, UserState>(listener: (context, state) { |
43 | 43 | debugPrint('WQF ModuleSelectPage BlocListener state: $state'); |
44 | 44 | }), |
45 | - BlocListener<ModuleSelectBloc, ModuleSelectState>( | |
45 | + BlocListener<ModuleSelectBloc, HomeState>( | |
46 | 46 | listener: (context, state) { |
47 | 47 | if (state is UpdateDialogState) { |
48 | 48 | _showUpdateDialog(context, state.forceUpdate, state.appVersionEntity); |
... | ... | @@ -53,7 +53,7 @@ class _HomePageView extends StatelessWidget { |
53 | 53 | } |
54 | 54 | |
55 | 55 | Widget _homeView() => |
56 | - BlocBuilder<ModuleSelectBloc, ModuleSelectState>( | |
56 | + BlocBuilder<ModuleSelectBloc, HomeState>( | |
57 | 57 | builder: (context, state) { |
58 | 58 | return Scaffold( |
59 | 59 | body: Container( |
... | ... | @@ -69,7 +69,7 @@ class _HomePageView extends StatelessWidget { |
69 | 69 | child: GestureDetector( |
70 | 70 | onTap: () { |
71 | 71 | if (UserUtil.isLogined()) { |
72 | - pushNamed(AppRouteName.home); | |
72 | + pushNamed(AppRouteName.courseUnit); | |
73 | 73 | } else { |
74 | 74 | pushNamed(AppRouteName.login); |
75 | 75 | } | ... | ... |
lib/pages/moduleSelect/widgets/BaseHomeHeaderWidget.dart renamed to lib/pages/home/widgets/BaseHomeHeaderWidget.dart
lib/pages/lessons/bloc/lesson_state.dart deleted
lib/pages/login/loginpage/login_page.dart
... | ... | @@ -34,7 +34,7 @@ class _LoginPageView extends StatelessWidget { |
34 | 34 | if (state is LoginResultChangeState) { |
35 | 35 | // 调试用 |
36 | 36 | // Navigator.of(context).pushNamed(AppRouteName.home); |
37 | - pushNamedAndRemoveUntil(AppRouteName.moduleSelect, (route) => false); | |
37 | + pushNamedAndRemoveUntil(AppRouteName.home, (route) => false); | |
38 | 38 | } |
39 | 39 | }, |
40 | 40 | child: _buildLoginViewWidget(), | ... | ... |
lib/pages/lessons/bloc/lesson_bloc.dart renamed to lib/pages/module/bloc/module_bloc.dart
1 | 1 | import 'package:flutter/cupertino.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | -import 'package:wow_english/common/request/dao/home_dao.dart'; | |
3 | +import 'package:wow_english/common/request/dao/lesson_dao.dart'; | |
4 | 4 | import 'package:wow_english/common/request/exception.dart'; |
5 | 5 | import 'package:wow_english/models/course_module_entity.dart'; |
6 | 6 | import 'package:wow_english/utils/loading.dart'; |
7 | 7 | import 'package:wow_english/utils/toast_util.dart'; |
8 | 8 | |
9 | -part 'lesson_event.dart'; | |
10 | -part 'lesson_state.dart'; | |
9 | +part 'module_event.dart'; | |
10 | +part 'module_state.dart'; | |
11 | 11 | |
12 | -class LessonBloc extends Bloc<LessonEvent, LessonState> { | |
12 | +class ModuleBloc extends Bloc<ModuleEvent, ModuleState> { | |
13 | 13 | final int pageIndex; |
14 | 14 | |
15 | 15 | final PageController pageController; |
... | ... | @@ -22,22 +22,22 @@ class LessonBloc extends Bloc<LessonEvent, LessonState> { |
22 | 22 | |
23 | 23 | List<CourseModuleEntity?> get listData => _listData; |
24 | 24 | |
25 | - LessonBloc(this.pageIndex, this.pageController) : super(LessonInitial()) { | |
25 | + ModuleBloc(this.pageIndex, this.pageController) : super(ModuleInitial()) { | |
26 | 26 | _currentPageIndex = pageIndex; |
27 | 27 | on<PageViewChangeIndexEvent>(_pageIndexChange); |
28 | 28 | on<RequestDataEvent>(_requestData); |
29 | 29 | } |
30 | 30 | |
31 | - void _pageIndexChange(PageViewChangeIndexEvent event, Emitter<LessonState> emitter) async { | |
31 | + void _pageIndexChange(PageViewChangeIndexEvent event, Emitter<ModuleState> emitter) async { | |
32 | 32 | _currentPageIndex = event.index; |
33 | 33 | emitter(PageIndexChangeState()); |
34 | 34 | } |
35 | 35 | |
36 | - void _requestData(RequestDataEvent event, Emitter<LessonState> emitter) async { | |
36 | + void _requestData(RequestDataEvent event, Emitter<ModuleState> emitter) async { | |
37 | 37 | try { |
38 | 38 | await loading(() async { |
39 | - _listData = await HomeDao.courseModule() ?? []; | |
40 | - emitter(LessonDataLoadState()); | |
39 | + _listData = await LessonDao.courseModule() ?? []; | |
40 | + emitter(ModuleDataLoadState()); | |
41 | 41 | }); |
42 | 42 | } catch (e) { |
43 | 43 | if (e is ApiException) { | ... | ... |
lib/pages/lessons/bloc/lesson_event.dart renamed to lib/pages/module/bloc/module_event.dart
1 | -part of 'lesson_bloc.dart'; | |
1 | +part of 'module_bloc.dart'; | |
2 | 2 | |
3 | 3 | @immutable |
4 | -abstract class LessonEvent {} | |
4 | +abstract class ModuleEvent {} | |
5 | 5 | |
6 | -class PageViewChangeIndexEvent extends LessonEvent { | |
6 | +class PageViewChangeIndexEvent extends ModuleEvent { | |
7 | 7 | final int index; |
8 | 8 | PageViewChangeIndexEvent(this.index); |
9 | 9 | } |
10 | 10 | |
11 | -class RequestDataEvent extends LessonEvent {} | |
11 | +class RequestDataEvent extends ModuleEvent {} | ... | ... |
lib/pages/module/bloc/module_state.dart
0 → 100644
lib/pages/lessons/lesson_page.dart renamed to lib/pages/module/module_page.dart
... | ... | @@ -6,23 +6,21 @@ import 'package:wow_english/common/widgets/we_app_bar.dart'; |
6 | 6 | import 'package:wow_english/models/course_module_entity.dart'; |
7 | 7 | import 'package:wow_english/route/route.dart'; |
8 | 8 | |
9 | -import 'bloc/lesson_bloc.dart'; | |
10 | -import 'widgets/lesson_item_widget.dart'; | |
9 | +import 'bloc/module_bloc.dart'; | |
10 | +import 'widgets/module_item_widget.dart'; | |
11 | 11 | |
12 | -class LessonPage extends StatelessWidget { | |
13 | - const LessonPage({super.key, this.starPageIndex}); | |
12 | +// 阶段(模块)列表页 | |
13 | +class ModulePage extends StatelessWidget { | |
14 | + const ModulePage({super.key, this.starPageIndex}); | |
14 | 15 | |
15 | 16 | final int? starPageIndex; |
16 | 17 | |
17 | 18 | @override |
18 | 19 | Widget build(BuildContext context) { |
19 | 20 | return BlocProvider( |
20 | - create: (context) => LessonBloc( | |
21 | - starPageIndex??0, | |
22 | - PageController( | |
23 | - initialPage: starPageIndex??0, | |
24 | - viewportFraction: 0.3 | |
25 | - ), | |
21 | + create: (context) => ModuleBloc( | |
22 | + starPageIndex ?? 0, | |
23 | + PageController(initialPage: starPageIndex ?? 0, viewportFraction: 0.3), | |
26 | 24 | )..add(RequestDataEvent()), |
27 | 25 | child: _LessonPageView(), |
28 | 26 | ); |
... | ... | @@ -30,27 +28,25 @@ class LessonPage extends StatelessWidget { |
30 | 28 | } |
31 | 29 | |
32 | 30 | class _LessonPageView extends StatelessWidget { |
33 | - | |
34 | 31 | final double _cardHeight = 240.h; |
35 | 32 | |
36 | 33 | final double _scale = 0.8; |
37 | 34 | |
38 | 35 | @override |
39 | 36 | Widget build(BuildContext context) { |
40 | - return BlocListener<LessonBloc,LessonState>( | |
41 | - listener: (context, state){}, | |
37 | + return BlocListener<ModuleBloc, ModuleState>( | |
38 | + listener: (context, state) {}, | |
42 | 39 | child: Scaffold( |
43 | 40 | appBar: WEAppBar( |
44 | 41 | leading: IconButton( |
45 | - onPressed: (){ | |
46 | - popPage(); | |
42 | + onPressed: () { | |
43 | + popPage(); | |
47 | 44 | }, |
48 | 45 | icon: Image.asset( |
49 | 46 | 'back'.assetPng, |
50 | 47 | height: 43, |
51 | 48 | width: 43, |
52 | - ) | |
53 | - ), | |
49 | + )), | |
54 | 50 | // actions: <Widget>[ |
55 | 51 | // IconButton( |
56 | 52 | // icon: Image.asset('shop'.assetPng), |
... | ... | @@ -66,9 +62,9 @@ class _LessonPageView extends StatelessWidget { |
66 | 62 | ); |
67 | 63 | } |
68 | 64 | |
69 | - Widget _lessViewWidget() => BlocBuilder<LessonBloc,LessonState>( | |
70 | - builder: (context, state){ | |
71 | - final bloc = BlocProvider.of<LessonBloc>(context); | |
65 | + Widget _lessViewWidget() => | |
66 | + BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) { | |
67 | + final bloc = BlocProvider.of<ModuleBloc>(context); | |
72 | 68 | return Center( |
73 | 69 | child: SafeArea( |
74 | 70 | child: Column( |
... | ... | @@ -81,8 +77,7 @@ class _LessonPageView extends StatelessWidget { |
81 | 77 | onPageChanged: (int index) { |
82 | 78 | bloc.add(PageViewChangeIndexEvent(index)); |
83 | 79 | }, |
84 | - itemBuilder: (context,index) => _itemTransCard(index) | |
85 | - ), | |
80 | + itemBuilder: (context, index) => _itemTransCard(index)), | |
86 | 81 | ), |
87 | 82 | 32.verticalSpace, |
88 | 83 | SizedBox( |
... | ... | @@ -91,7 +86,7 @@ class _LessonPageView extends StatelessWidget { |
91 | 86 | child: ListView.builder( |
92 | 87 | itemCount: bloc.listData.length, |
93 | 88 | scrollDirection: Axis.horizontal, |
94 | - itemBuilder: (BuildContext context,int index){ | |
89 | + itemBuilder: (BuildContext context, int index) { | |
95 | 90 | return Container( |
96 | 91 | height: 32.h, |
97 | 92 | width: 66.w, |
... | ... | @@ -101,13 +96,19 @@ class _LessonPageView extends StatelessWidget { |
101 | 96 | if (index == bloc.currentPageIndex) { |
102 | 97 | return; |
103 | 98 | } |
104 | - int mill = (index - bloc.currentPageIndex) > 0 ? 100 * (index - bloc.currentPageIndex):100 * (bloc.currentPageIndex-index); | |
105 | - bloc.pageController.animateToPage(index, duration: Duration(milliseconds: mill), curve: Curves.ease); | |
99 | + int mill = (index - bloc.currentPageIndex) > 0 | |
100 | + ? 100 * (index - bloc.currentPageIndex) | |
101 | + : 100 * (bloc.currentPageIndex - index); | |
102 | + bloc.pageController.animateToPage(index, | |
103 | + duration: Duration(milliseconds: mill), | |
104 | + curve: Curves.ease); | |
106 | 105 | }, |
107 | 106 | child: Container( |
108 | - height: bloc.currentPageIndex == index ? 32:20, | |
107 | + height: bloc.currentPageIndex == index ? 32 : 20, | |
109 | 108 | decoration: BoxDecoration( |
110 | - color: bloc.currentPageIndex == index ? Colors.red:Colors.white, | |
109 | + color: bloc.currentPageIndex == index | |
110 | + ? Colors.red | |
111 | + : Colors.white, | |
111 | 112 | borderRadius: BorderRadius.circular(5.r), |
112 | 113 | border: Border.all( |
113 | 114 | width: 0.5, |
... | ... | @@ -116,10 +117,11 @@ class _LessonPageView extends StatelessWidget { |
116 | 117 | ), |
117 | 118 | alignment: Alignment.center, |
118 | 119 | child: Text( |
119 | - (index+1).toString(), | |
120 | + (index + 1).toString(), | |
120 | 121 | style: TextStyle( |
121 | - color: bloc.currentPageIndex == index ? Colors.white:Colors.black | |
122 | - ), | |
122 | + color: bloc.currentPageIndex == index | |
123 | + ? Colors.white | |
124 | + : Colors.black), | |
123 | 125 | ), |
124 | 126 | ), |
125 | 127 | ), |
... | ... | @@ -132,49 +134,54 @@ class _LessonPageView extends StatelessWidget { |
132 | 134 | ); |
133 | 135 | }); |
134 | 136 | |
135 | - Widget _itemTransCard(int index) => BlocBuilder<LessonBloc,LessonState>( | |
136 | - builder: (context, state) { | |
137 | - final bloc = BlocProvider.of<LessonBloc>(context); | |
138 | - Matrix4 matrix4 = Matrix4.identity(); | |
139 | - if (index == bloc.currentPageIndex.floor()) { | |
140 | - //当前的item | |
141 | - double currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
142 | - var currTrans = _cardHeight * (1 - currScale) / 2; | |
137 | + Widget _itemTransCard(int index) => | |
138 | + BlocBuilder<ModuleBloc, ModuleState>(builder: (context, state) { | |
139 | + final bloc = BlocProvider.of<ModuleBloc>(context); | |
140 | + Matrix4 matrix4 = Matrix4.identity(); | |
141 | + if (index == bloc.currentPageIndex.floor()) { | |
142 | + //当前的item | |
143 | + double currScale = | |
144 | + (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
145 | + var currTrans = _cardHeight * (1 - currScale) / 2; | |
143 | 146 | |
144 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
145 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
146 | - } else if (index == bloc.currentPageIndex.floor() + 1) { | |
147 | - //右边的item | |
148 | - var currScale = _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale); | |
149 | - var currTrans = _cardHeight * (1 - currScale) / 2; | |
147 | + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
148 | + ..setTranslationRaw(0.0, currTrans, 0.0); | |
149 | + } else if (index == bloc.currentPageIndex.floor() + 1) { | |
150 | + //右边的item | |
151 | + var currScale = | |
152 | + _scale + (bloc.currentPageIndex - index + 1) * (1 - _scale); | |
153 | + var currTrans = _cardHeight * (1 - currScale) / 2; | |
150 | 154 | |
151 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
152 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
153 | - } else if (index == bloc.currentPageIndex - 1) { | |
154 | - //左边 | |
155 | - var currScale = (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
156 | - var currTrans = _cardHeight * (1 - currScale) / 2; | |
155 | + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
156 | + ..setTranslationRaw(0.0, currTrans, 0.0); | |
157 | + } else if (index == bloc.currentPageIndex - 1) { | |
158 | + //左边 | |
159 | + var currScale = | |
160 | + (1 - (bloc.currentPageIndex - index) * (1 - _scale)).toDouble(); | |
161 | + var currTrans = _cardHeight * (1 - currScale) / 2; | |
157 | 162 | |
158 | - matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
159 | - ..setTranslationRaw(0.0, currTrans, 0.0); | |
160 | - } else { | |
161 | - //其他,不在屏幕显示的item | |
162 | - matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) | |
163 | - ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); | |
164 | - } | |
165 | - CourseModuleEntity? model = bloc.listData[index]; | |
166 | - return Transform( | |
167 | - transform: matrix4, | |
168 | - child: Padding( | |
169 | - padding: const EdgeInsets.symmetric(horizontal: 10), | |
170 | - child: LessonItemWidget( | |
171 | - model: model, | |
172 | - isSelected: bloc.currentPageIndex == index, | |
173 | - onClickEvent: () { | |
174 | - pushNamed(AppRouteName.unit, arguments: {'courseModuleEntity':model}); | |
175 | - }, | |
163 | + matrix4 = Matrix4.diagonal3Values(1.0, currScale, 1.0) | |
164 | + ..setTranslationRaw(0.0, currTrans, 0.0); | |
165 | + } else { | |
166 | + //其他,不在屏幕显示的item | |
167 | + matrix4 = Matrix4.diagonal3Values(1.0, _scale, 1.0) | |
168 | + ..setTranslationRaw(0.0, _cardHeight * (1 - _scale) / 2, 0.0); | |
169 | + } | |
170 | + CourseModuleEntity? model = bloc.listData[index]; | |
171 | + return Transform( | |
172 | + transform: matrix4, | |
173 | + child: Padding( | |
174 | + padding: const EdgeInsets.symmetric(horizontal: 10), | |
175 | + child: ModuleItemWidget( | |
176 | + model: model, | |
177 | + isSelected: bloc.currentPageIndex == index, | |
178 | + onClickEvent: () { | |
179 | + pushNamedAndRemoveUntil( | |
180 | + AppRouteName.courseUnit, (route) => route.isFirst, | |
181 | + arguments: {'courseModuleEntity': model}); | |
182 | + }, | |
183 | + ), | |
176 | 184 | ), |
177 | - ), | |
178 | - ); | |
179 | - }); | |
185 | + ); | |
186 | + }); | |
180 | 187 | } | ... | ... |
lib/pages/lessons/widgets/lesson_item_widget.dart renamed to lib/pages/module/widgets/module_item_widget.dart
... | ... | @@ -4,10 +4,10 @@ import 'package:wow_english/common/extension/string_extension.dart'; |
4 | 4 | import 'package:wow_english/common/widgets/ow_image_widget.dart'; |
5 | 5 | import 'package:wow_english/models/course_module_entity.dart'; |
6 | 6 | |
7 | -import '../../home/courese_module_model.dart'; | |
7 | +import '../../section/courese_module_model.dart'; | |
8 | 8 | |
9 | -class LessonItemWidget extends StatelessWidget { | |
10 | - const LessonItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent}); | |
9 | +class ModuleItemWidget extends StatelessWidget { | |
10 | + const ModuleItemWidget({super.key, required this.isSelected, this.model, this.onClickEvent}); | |
11 | 11 | ///是否被选中 |
12 | 12 | final bool isSelected; |
13 | 13 | final CourseModuleEntity? model; | ... | ... |
lib/pages/moduleSelect/event.dart deleted
lib/pages/home/bloc/home_bloc.dart renamed to lib/pages/section/bloc/section_bloc.dart
1 | 1 | import 'package:flutter/cupertino.dart'; |
2 | 2 | import 'package:flutter/foundation.dart'; |
3 | 3 | import 'package:flutter_bloc/flutter_bloc.dart'; |
4 | -import 'package:wow_english/common/request/dao/home_dao.dart'; | |
4 | +import 'package:wow_english/common/request/dao/lesson_dao.dart'; | |
5 | 5 | import 'package:wow_english/common/request/exception.dart'; |
6 | -import 'package:wow_english/models/course_entity.dart'; | |
7 | 6 | import 'package:wow_english/common/request/dao/listen_dao.dart'; |
8 | 7 | import 'package:wow_english/models/course_process_entity.dart'; |
9 | 8 | import 'package:wow_english/utils/loading.dart'; |
10 | 9 | import 'package:wow_english/utils/toast_util.dart'; |
11 | 10 | |
12 | -part 'home_event.dart'; | |
13 | -part 'home_state.dart'; | |
11 | +import '../../../models/course_section_entity.dart'; | |
12 | +import '../../../models/course_unit_entity.dart'; | |
14 | 13 | |
15 | -class HomeBloc extends Bloc<HomeEvent, HomeState> { | |
16 | - final int? moduleId; | |
14 | +part 'section_event.dart'; | |
15 | +part 'section_state.dart'; | |
17 | 16 | |
18 | - CourseEntity? _modelData; | |
17 | +class SectionBloc extends Bloc<SectionEvent, SectionState> { | |
19 | 18 | |
20 | - CourseEntity? get modelData => _modelData; | |
19 | + CourseUnitEntity _courseUnitEntity; | |
20 | + | |
21 | + CourseUnitEntity get courseUnitEntity => _courseUnitEntity; | |
22 | + | |
23 | + CourseUnitDetail _courseUnitDetail; | |
24 | + | |
25 | + CourseUnitDetail get courseUnitDetail => _courseUnitDetail; | |
26 | + | |
27 | + List<CourseSectionEntity>? _courseSectionDatas; | |
28 | + | |
29 | + List<CourseSectionEntity>? get courseSectionDatas => _courseSectionDatas; | |
21 | 30 | |
22 | 31 | CourseProcessEntity? _processEntity; |
23 | 32 | |
24 | 33 | CourseProcessEntity? get processEntity => _processEntity; |
25 | 34 | |
26 | - HomeBloc(this.moduleId) : super(HomeInitial()) { | |
35 | + SectionBloc(this._courseUnitEntity, this._courseUnitDetail) : super(LessonInitial()) { | |
27 | 36 | on<RequestDataEvent>(_requestData); |
28 | 37 | on<RequestExitClassEvent>(_requestExitClass); |
29 | 38 | on<RequestEnterClassEvent>(_requestEnterClass); |
30 | 39 | on<RequestVideoLessonEvent>(_requestVideoLesson); |
31 | 40 | } |
32 | 41 | |
33 | - void _requestData(RequestDataEvent event, Emitter<HomeState> emitter) async { | |
42 | + void _requestData(RequestDataEvent event, Emitter<SectionState> emitter) async { | |
34 | 43 | try { |
35 | 44 | await loading(() async { |
36 | - _modelData = await HomeDao.courseLesson(moduleId: moduleId); | |
37 | - emitter(HomeDataLoadState()); | |
45 | + _courseSectionDatas = await LessonDao.courseSection(courseUnitId: _courseUnitDetail.id!); | |
46 | + emitter(LessonDataLoadState()); | |
38 | 47 | }); |
39 | 48 | } catch (e) { |
40 | 49 | if (e is ApiException) { |
... | ... | @@ -43,7 +52,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { |
43 | 52 | } |
44 | 53 | } |
45 | 54 | |
46 | - void _requestVideoLesson(RequestVideoLessonEvent event, Emitter<HomeState> emitter) async { | |
55 | + void _requestVideoLesson(RequestVideoLessonEvent event, Emitter<SectionState> emitter) async { | |
47 | 56 | try { |
48 | 57 | await loading(() async { |
49 | 58 | _processEntity = await ListenDao.process(event.courseLessonId); |
... | ... | @@ -57,7 +66,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { |
57 | 66 | } |
58 | 67 | |
59 | 68 | |
60 | - void _requestEnterClass(RequestEnterClassEvent event,Emitter<HomeState> emitter) async { | |
69 | + void _requestEnterClass(RequestEnterClassEvent event,Emitter<SectionState> emitter) async { | |
61 | 70 | try { |
62 | 71 | await loading(() async { |
63 | 72 | await ListenDao.enterClass(event.courseLessonId); |
... | ... | @@ -70,7 +79,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { |
70 | 79 | } |
71 | 80 | } |
72 | 81 | |
73 | - void _requestExitClass(RequestExitClassEvent event,Emitter<HomeState> emitter) async { | |
82 | + void _requestExitClass(RequestExitClassEvent event,Emitter<SectionState> emitter) async { | |
74 | 83 | await ListenDao.exitClass(event.courseLessonId,event.currentStep,event.currentTime); |
75 | 84 | } |
76 | 85 | } | ... | ... |
lib/pages/home/bloc/home_event.dart renamed to lib/pages/section/bloc/section_event.dart
1 | -part of 'home_bloc.dart'; | |
1 | +part of 'section_bloc.dart'; | |
2 | 2 | |
3 | 3 | @immutable |
4 | -abstract class HomeEvent {} | |
4 | +abstract class SectionEvent {} | |
5 | 5 | |
6 | -class RequestDataEvent extends HomeEvent {} | |
6 | +class RequestDataEvent extends SectionEvent {} | |
7 | 7 | |
8 | 8 | ///获取视频课程内容 |
9 | -class RequestVideoLessonEvent extends HomeEvent { | |
9 | +class RequestVideoLessonEvent extends SectionEvent { | |
10 | 10 | final String courseLessonId; |
11 | 11 | final int courseType; |
12 | 12 | RequestVideoLessonEvent(this.courseLessonId, this.courseType); |
13 | 13 | } |
14 | 14 | |
15 | 15 | ///进入课堂 |
16 | -class RequestEnterClassEvent extends HomeEvent { | |
16 | +class RequestEnterClassEvent extends SectionEvent { | |
17 | 17 | final String courseLessonId; |
18 | 18 | final int courseType; |
19 | 19 | RequestEnterClassEvent(this.courseLessonId,this.courseType); |
20 | 20 | } |
21 | 21 | |
22 | 22 | ///退出课堂 |
23 | -class RequestExitClassEvent extends HomeEvent { | |
23 | +class RequestExitClassEvent extends SectionEvent { | |
24 | 24 | final String courseLessonId; |
25 | 25 | final String currentStep; |
26 | 26 | final String currentTime; | ... | ... |
lib/pages/home/bloc/home_state.dart renamed to lib/pages/section/bloc/section_state.dart
1 | -part of 'home_bloc.dart'; | |
1 | +part of 'section_bloc.dart'; | |
2 | 2 | |
3 | 3 | @immutable |
4 | -abstract class HomeState {} | |
4 | +abstract class SectionState {} | |
5 | 5 | |
6 | -class HomeInitial extends HomeState {} | |
6 | +class LessonInitial extends SectionState {} | |
7 | 7 | |
8 | -class HomeDataLoadState extends HomeState {} | |
8 | +class LessonDataLoadState extends SectionState {} | |
9 | 9 | |
10 | -class RequestVideoLessonState extends HomeState { | |
10 | +class RequestVideoLessonState extends SectionState { | |
11 | 11 | final String courseLessonId; |
12 | 12 | final int type; |
13 | 13 | RequestVideoLessonState(this.courseLessonId,this.type); |
14 | 14 | } |
15 | 15 | |
16 | -class RequestEnterClassState extends HomeState{ | |
16 | +class RequestEnterClassState extends SectionState{ | |
17 | 17 | final String courseLessonId; |
18 | 18 | final int courseType; |
19 | 19 | RequestEnterClassState(this.courseLessonId,this.courseType); | ... | ... |
lib/pages/home/courese_module_model.dart renamed to lib/pages/section/courese_module_model.dart
... | ... | @@ -2,9 +2,10 @@ import 'package:flutter/material.dart'; |
2 | 2 | |
3 | 3 | class CourseModuleModel { |
4 | 4 | Color get color => getCourseColor(); |
5 | - String get courseModuleTitle => getCourseModuleTitle(); | |
6 | - String get courseModuleLogo => getCoureseImageName(); | |
7 | 5 | |
6 | + String get courseModuleTitle => getCourseModuleTitle(); | |
7 | + | |
8 | + String get courseModuleLogo => getCoureseImageName(); | |
8 | 9 | |
9 | 10 | String course; |
10 | 11 | |
... | ... | @@ -84,4 +85,4 @@ class CourseModuleModel { |
84 | 85 | } |
85 | 86 | return 'red_positive'; |
86 | 87 | } |
87 | -} | |
88 | 88 | \ No newline at end of file |
89 | +} | ... | ... |
lib/pages/home/home_page.dart renamed to lib/pages/section/section_page.dart
... | ... | @@ -3,60 +3,47 @@ import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | 4 | import 'package:wow_english/common/core/user_util.dart'; |
5 | 5 | import 'package:wow_english/common/extension/string_extension.dart'; |
6 | -import 'package:wow_english/models/course_entity.dart'; | |
7 | -import 'package:wow_english/pages/home/widgets/home_bouns_item.dart'; | |
8 | -import 'package:wow_english/pages/home/widgets/home_tab_header_widget.dart'; | |
9 | -import 'package:wow_english/pages/home/widgets/home_video_item.dart'; | |
6 | +import 'package:wow_english/models/course_unit_entity.dart'; | |
7 | +import 'package:wow_english/pages/section/widgets/home_video_item.dart'; | |
8 | +import 'package:wow_english/pages/section/widgets/section_bouns_item.dart'; | |
9 | +import 'package:wow_english/pages/section/widgets/section_header_widget.dart'; | |
10 | 10 | import 'package:wow_english/route/route.dart'; |
11 | 11 | import 'package:wow_english/utils/toast_util.dart'; |
12 | 12 | |
13 | -import 'bloc/home_bloc.dart'; | |
13 | +import '../../models/course_section_entity.dart'; | |
14 | +import 'bloc/section_bloc.dart'; | |
14 | 15 | import 'courese_module_model.dart'; |
15 | 16 | |
16 | -class HomePage extends StatelessWidget { | |
17 | - const HomePage({super.key, this.moduleId}); | |
17 | +/// 环节列表页 | |
18 | +class SectionPage extends StatelessWidget { | |
19 | + const SectionPage({super.key, required this.courseUnitEntity, required this.courseUnitDetail}); | |
18 | 20 | |
19 | - /// 模块id | |
20 | - final int? moduleId; | |
21 | + final CourseUnitEntity courseUnitEntity; | |
22 | + | |
23 | + /// unitId | |
24 | + final CourseUnitDetail courseUnitDetail; | |
21 | 25 | |
22 | 26 | @override |
23 | 27 | Widget build(BuildContext context) { |
24 | 28 | return BlocProvider( |
25 | - create: (context) => HomeBloc(moduleId)..add(RequestDataEvent()), | |
26 | - child: _HomePageView(context), | |
29 | + create: (context) => SectionBloc(courseUnitEntity, courseUnitDetail)..add(RequestDataEvent()), | |
30 | + child: _SectionPageView(context), | |
27 | 31 | ); |
28 | 32 | } |
29 | 33 | } |
30 | 34 | |
31 | -class _HomePageView extends StatelessWidget { | |
32 | - | |
33 | - const _HomePageView(this.context); | |
35 | +class _SectionPageView extends StatelessWidget { | |
36 | + const _SectionPageView(this.context); | |
34 | 37 | |
35 | 38 | final BuildContext context; |
36 | 39 | |
37 | - void _headerActionEvent(HeaderActionType type) { | |
38 | - if (type == HeaderActionType.video) { | |
39 | - pushNamed(AppRouteName.reAfter); | |
40 | - } else if (type == HeaderActionType.phase) { | |
41 | - pushNamed(AppRouteName.lesson); | |
42 | - } else if (type == HeaderActionType.listen) { | |
43 | - pushNamed(AppRouteName.listen); | |
44 | - } else if (type == HeaderActionType.shop) { | |
45 | - pushNamed(AppRouteName.shop); | |
46 | - } else if (type == HeaderActionType.user) { | |
47 | - pushNamed(AppRouteName.user); | |
48 | - } else if (type == HeaderActionType.home) { | |
49 | - Navigator.pop(context); | |
50 | - } | |
51 | - } | |
52 | - | |
53 | 40 | @override |
54 | 41 | Widget build(BuildContext context) { |
55 | - final bloc = BlocProvider.of<HomeBloc>(context); | |
56 | - return BlocListener<HomeBloc, HomeState>( | |
42 | + final bloc = BlocProvider.of<SectionBloc>(context); | |
43 | + return BlocListener<SectionBloc, SectionState>( | |
57 | 44 | listener: (context, state) { |
58 | 45 | if (state is RequestVideoLessonState) { |
59 | - final videoUrl = bloc.processEntity?.videos?.videoUrl??''; | |
46 | + final videoUrl = bloc.processEntity?.videos?.videoUrl ?? ''; | |
60 | 47 | var title = ''; |
61 | 48 | if (state.type == 1) { |
62 | 49 | title = 'song'; |
... | ... | @@ -73,9 +60,13 @@ class _HomePageView extends StatelessWidget { |
73 | 60 | if (videoUrl.isEmpty || !videoUrl.contains('http')) { |
74 | 61 | return; |
75 | 62 | } |
76 | - pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':videoUrl,'title':title,'courseLessonId':state.courseLessonId}).then((value) { | |
63 | + pushNamed(AppRouteName.lookVideo, arguments: { | |
64 | + 'videoUrl': videoUrl, | |
65 | + 'title': title, | |
66 | + 'courseLessonId': state.courseLessonId | |
67 | + }).then((value) { | |
77 | 68 | if (value != null) { |
78 | - Map<String,String> dataMap = value as Map<String,String>; | |
69 | + Map<String, String> dataMap = value as Map<String, String>; | |
79 | 70 | bloc.add(RequestExitClassEvent( |
80 | 71 | dataMap['courseLessonId']!, |
81 | 72 | '0', |
... | ... | @@ -87,35 +78,37 @@ class _HomePageView extends StatelessWidget { |
87 | 78 | } |
88 | 79 | |
89 | 80 | if (state is RequestEnterClassState) { |
90 | - if (state.courseType != 3 && state.courseType != 4) {///视频类型 | |
81 | + if (state.courseType != 3 && state.courseType != 4) { | |
82 | + ///视频类型 | |
91 | 83 | ///获取视频课程内容 |
92 | - bloc.add(RequestVideoLessonEvent(state.courseLessonId,state.courseType)); | |
84 | + bloc.add(RequestVideoLessonEvent( | |
85 | + state.courseLessonId, state.courseType)); | |
93 | 86 | return; |
94 | 87 | } |
95 | 88 | |
96 | - if (state.courseType == 4) {//绘本 | |
97 | - pushNamed(AppRouteName.reading, arguments: {'courseLessonId':state.courseLessonId}).then((value) { | |
89 | + if (state.courseType == 4) { | |
90 | + //绘本 | |
91 | + pushNamed(AppRouteName.reading, | |
92 | + arguments: {'courseLessonId': state.courseLessonId}) | |
93 | + .then((value) { | |
98 | 94 | if (value != null) { |
99 | - Map<String,String> dataMap = value as Map<String,String>; | |
95 | + Map<String, String> dataMap = value as Map<String, String>; | |
100 | 96 | bloc.add(RequestExitClassEvent( |
101 | - dataMap['courseLessonId']!, | |
102 | - dataMap['currentStep']!, | |
103 | - '0' | |
104 | - )); | |
97 | + dataMap['courseLessonId']!, dataMap['currentStep']!, '0')); | |
105 | 98 | } |
106 | 99 | }); |
107 | 100 | return; |
108 | 101 | } |
109 | 102 | |
110 | - if (state.courseType == 3) {//练习 | |
111 | - pushNamed(AppRouteName.topicPic,arguments: {'courseLessonId':state.courseLessonId}).then((value) { | |
103 | + if (state.courseType == 3) { | |
104 | + //练习 | |
105 | + pushNamed(AppRouteName.topicPic, | |
106 | + arguments: {'courseLessonId': state.courseLessonId}) | |
107 | + .then((value) { | |
112 | 108 | if (value != null) { |
113 | - Map<String,String> dataMap = value as Map<String,String>; | |
109 | + Map<String, String> dataMap = value as Map<String, String>; | |
114 | 110 | bloc.add(RequestExitClassEvent( |
115 | - dataMap['courseLessonId']!, | |
116 | - dataMap['currentStep']!, | |
117 | - '0' | |
118 | - )); | |
111 | + dataMap['courseLessonId']!, dataMap['currentStep']!, '0')); | |
119 | 112 | } |
120 | 113 | }); |
121 | 114 | return; |
... | ... | @@ -126,9 +119,9 @@ class _HomePageView extends StatelessWidget { |
126 | 119 | ); |
127 | 120 | } |
128 | 121 | |
129 | - Widget _homeView() => BlocBuilder<HomeBloc, HomeState>( | |
130 | - builder: (context, state) { | |
131 | - final bloc = BlocProvider.of<HomeBloc>(context); | |
122 | + Widget _homeView() => | |
123 | + BlocBuilder<SectionBloc, SectionState>(builder: (context, state) { | |
124 | + final bloc = BlocProvider.of<SectionBloc>(context); | |
132 | 125 | return Scaffold( |
133 | 126 | body: Container( |
134 | 127 | color: Colors.white, |
... | ... | @@ -136,19 +129,17 @@ class _HomePageView extends StatelessWidget { |
136 | 129 | child: Column( |
137 | 130 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
138 | 131 | children: [ |
139 | - HomeTabHeaderWidget( | |
140 | - entity: bloc.modelData, | |
141 | - actionTap: (HeaderActionType type) { | |
142 | - _headerActionEvent(type); | |
143 | - }, | |
144 | - ), | |
132 | + SectionHeaderWidget( | |
133 | + title: bloc.courseUnitDetail.name, | |
134 | + courseModuleCode: bloc.courseUnitEntity.courseModuleCode), | |
145 | 135 | Expanded( |
146 | 136 | child: ListView.builder( |
147 | - itemCount: bloc.modelData?.totalCourseLesson??0, | |
137 | + itemCount: bloc.courseSectionDatas?.length ?? 0, | |
148 | 138 | scrollDirection: Axis.horizontal, |
149 | 139 | itemBuilder: (BuildContext context, int index) { |
150 | - CourseCourseLessons? data = bloc.modelData?.courseLessons?[index]; | |
151 | - if (data?.courseType == 5) { | |
140 | + CourseSectionEntity sectionData = | |
141 | + bloc.courseSectionDatas![index]; | |
142 | + if (sectionData.courseType == 5) { | |
152 | 143 | //彩蛋 |
153 | 144 | return GestureDetector( |
154 | 145 | onTap: () { |
... | ... | @@ -156,15 +147,17 @@ class _HomePageView extends StatelessWidget { |
156 | 147 | pushNamed(AppRouteName.login); |
157 | 148 | return; |
158 | 149 | } |
159 | - if (data!.lock!) { | |
150 | + if (sectionData.lock == true) { | |
160 | 151 | showToast('当前课程暂未解锁'); |
161 | 152 | return; |
162 | 153 | } |
154 | + | |
163 | 155 | ///进入课堂 |
164 | - bloc.add(RequestEnterClassEvent(data.id!,data.courseType!)); | |
156 | + bloc.add(RequestEnterClassEvent( | |
157 | + sectionData.id.toString(), sectionData.courseType)); | |
165 | 158 | }, |
166 | - child: HomeBoundsItem( | |
167 | - imageUrl: data?.coverUrl, | |
159 | + child: SectionBoundsItem( | |
160 | + imageUrl: sectionData.coverUrl, | |
168 | 161 | ), |
169 | 162 | ); |
170 | 163 | } else { |
... | ... | @@ -174,16 +167,18 @@ class _HomePageView extends StatelessWidget { |
174 | 167 | pushNamed(AppRouteName.login); |
175 | 168 | return; |
176 | 169 | } |
177 | - if (data!.lock!) { | |
170 | + if (sectionData.lock == true) { | |
178 | 171 | showToast('当前课程暂未解锁'); |
179 | 172 | return; |
180 | 173 | } |
174 | + | |
181 | 175 | ///进入课堂 |
182 | - bloc.add(RequestEnterClassEvent(data.id!,data.courseType!)); | |
176 | + bloc.add(RequestEnterClassEvent( | |
177 | + sectionData.id.toString(), sectionData.courseType)); | |
183 | 178 | }, |
184 | - child: HomeVideoItem( | |
185 | - entity: bloc.modelData, | |
186 | - lessons: data, | |
179 | + child: SectionVideoItem( | |
180 | + unitEntity: bloc.courseUnitEntity, | |
181 | + lessons: sectionData, | |
187 | 182 | ), |
188 | 183 | ); |
189 | 184 | } |
... | ... | @@ -200,17 +195,26 @@ class _HomePageView extends StatelessWidget { |
200 | 195 | ), |
201 | 196 | Container( |
202 | 197 | decoration: BoxDecoration( |
203 | - color: CourseModuleModel(bloc.modelData?.courseModuleCode??'Phase-1').color, | |
198 | + color: CourseModuleModel( | |
199 | + bloc.courseUnitEntity.courseModuleCode ?? | |
200 | + 'Phase-1') | |
201 | + .color, | |
204 | 202 | borderRadius: BorderRadius.circular(14.5.r), |
205 | 203 | ), |
206 | - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 24.w), | |
204 | + padding: EdgeInsets.symmetric( | |
205 | + vertical: 8.h, horizontal: 24.w), | |
207 | 206 | child: Text( |
208 | - '${(bloc.modelData?.nowCourseLesson??0)}/${bloc.modelData?.totalCourseLesson??0}', | |
209 | - style: TextStyle(color: Colors.white, fontSize: 12.sp), | |
207 | + '${(bloc.courseUnitEntity.nowStep ?? 0)}/${bloc.courseUnitEntity.total ?? 0}', | |
208 | + style: TextStyle( | |
209 | + color: Colors.white, fontSize: 12.sp), | |
210 | 210 | ), |
211 | 211 | ), |
212 | 212 | Image.asset( |
213 | - CourseModuleModel(bloc.modelData?.courseModuleCode??'Phase-1').courseModuleLogo.assetPng, | |
213 | + CourseModuleModel( | |
214 | + bloc.courseUnitEntity.courseModuleCode ?? | |
215 | + 'Phase-1') | |
216 | + .courseModuleLogo | |
217 | + .assetPng, | |
214 | 218 | height: 47.h, |
215 | 219 | width: 80.w, |
216 | 220 | // color: Colors.red, | ... | ... |
lib/pages/home/widgets/home_video_item.dart renamed to lib/pages/section/widgets/home_video_item.dart
... | ... | @@ -2,15 +2,16 @@ 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 | 4 | import 'package:wow_english/common/widgets/ow_image_widget.dart'; |
5 | -import 'package:wow_english/models/course_entity.dart'; | |
6 | 5 | |
6 | +import '../../../models/course_section_entity.dart'; | |
7 | +import '../../../models/course_unit_entity.dart'; | |
7 | 8 | import '../courese_module_model.dart'; |
8 | 9 | |
9 | -class HomeVideoItem extends StatelessWidget { | |
10 | - const HomeVideoItem({super.key, this.lessons, this.entity}); | |
10 | +class SectionVideoItem extends StatelessWidget { | |
11 | + const SectionVideoItem({super.key, this.lessons, this.unitEntity}); | |
11 | 12 | |
12 | - final CourseEntity? entity; | |
13 | - final CourseCourseLessons? lessons; | |
13 | + final CourseUnitEntity? unitEntity; | |
14 | + final CourseSectionEntity? lessons; | |
14 | 15 | |
15 | 16 | @override |
16 | 17 | Widget build(BuildContext context) { |
... | ... | @@ -50,7 +51,7 @@ class HomeVideoItem extends StatelessWidget { |
50 | 51 | width: 2, |
51 | 52 | color: const Color(0xFF140C10), |
52 | 53 | ), |
53 | - color: CourseModuleModel(entity?.courseModuleCode??'Phase-1').color, | |
54 | + color: CourseModuleModel(unitEntity?.courseModuleCode??'Phase-1').color, | |
54 | 55 | borderRadius: BorderRadius.circular(6) |
55 | 56 | ), |
56 | 57 | padding: EdgeInsets.symmetric(horizontal: 10.w), | ... | ... |
lib/pages/home/widgets/home_bouns_item.dart renamed to lib/pages/section/widgets/section_bouns_item.dart
... | ... | @@ -2,8 +2,8 @@ import 'package:flutter/cupertino.dart'; |
2 | 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
3 | 3 | import 'package:wow_english/common/widgets/ow_image_widget.dart'; |
4 | 4 | |
5 | -class HomeBoundsItem extends StatelessWidget { | |
6 | - const HomeBoundsItem({super.key, this.imageUrl}); | |
5 | +class SectionBoundsItem extends StatelessWidget { | |
6 | + const SectionBoundsItem({super.key, this.imageUrl}); | |
7 | 7 | |
8 | 8 | final String? imageUrl; |
9 | 9 | ... | ... |
lib/pages/unit/widget/course_unit_header_widget.dart renamed to lib/pages/section/widgets/section_header_widget.dart
... | ... | @@ -4,13 +4,14 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; |
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 '../../../models/course_module_entity.dart'; | |
8 | -import '../../home/courese_module_model.dart'; | |
7 | +import '../courese_module_model.dart'; | |
9 | 8 | |
10 | -class CourseUnitHeaderWidget extends StatelessWidget { | |
11 | - const CourseUnitHeaderWidget({super.key, this.entity}); | |
9 | +class SectionHeaderWidget extends StatelessWidget { | |
10 | + const SectionHeaderWidget({super.key, this.title, this.courseModuleCode}); | |
12 | 11 | |
13 | - final CourseModuleEntity? entity; | |
12 | + final String? title; | |
13 | + | |
14 | + final String? courseModuleCode; | |
14 | 15 | |
15 | 16 | @override |
16 | 17 | Widget build(BuildContext context) { |
... | ... | @@ -19,8 +20,7 @@ class CourseUnitHeaderWidget extends StatelessWidget { |
19 | 20 | return Container( |
20 | 21 | height: 45, |
21 | 22 | width: double.infinity, |
22 | - color: | |
23 | - CourseModuleModel(entity?.code ?? 'Phase-1').color, | |
23 | + color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color, | |
24 | 24 | padding: EdgeInsets.symmetric(horizontal: 9.5.w), |
25 | 25 | child: Row( |
26 | 26 | children: [ |
... | ... | @@ -40,9 +40,10 @@ class CourseUnitHeaderWidget extends StatelessWidget { |
40 | 40 | ), |
41 | 41 | 20.horizontalSpace, |
42 | 42 | Expanded( |
43 | - child: Text(entity?.name ?? | |
44 | - CourseModuleModel(entity?.code ?? 'Phase-1') | |
45 | - .courseModuleTitle, | |
43 | + child: Text( | |
44 | + title ?? | |
45 | + CourseModuleModel(courseModuleCode ?? 'Phase-1') | |
46 | + .courseModuleTitle, | |
46 | 47 | textAlign: TextAlign.left, |
47 | 48 | style: const TextStyle(color: Colors.white, fontSize: 30.0), |
48 | 49 | )), | ... | ... |
lib/pages/tab/tab_page.dart
1 | 1 | import 'package:flutter/material.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | -import 'package:wow_english/pages/home/home_page.dart'; | |
4 | -import 'package:wow_english/pages/lessons/lesson_page.dart'; | |
3 | +import 'package:wow_english/pages/module/module_page.dart'; | |
5 | 4 | |
5 | +import '../unit/view.dart'; | |
6 | 6 | import 'blocs/tab_bloc.dart'; |
7 | 7 | |
8 | 8 | class TabPage extends StatelessWidget { |
9 | 9 | const TabPage({super.key}); |
10 | 10 | |
11 | 11 | final _pages =const <Widget>[ |
12 | - HomePage(), | |
13 | - LessonPage() | |
12 | + UnitPage(), | |
13 | + ModulePage() | |
14 | 14 | ]; |
15 | 15 | |
16 | 16 | final _tabIcons = const <Icon>[ | ... | ... |
lib/pages/unit/bloc.dart
1 | 1 | import 'package:bloc/bloc.dart'; |
2 | +import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; | |
2 | 3 | |
3 | -import '../../common/request/dao/home_dao.dart'; | |
4 | +import '../../common/request/dao/lesson_dao.dart'; | |
4 | 5 | import '../../common/request/exception.dart'; |
6 | +import '../../models/course_module_entity.dart'; | |
5 | 7 | import '../../models/course_unit_entity.dart'; |
8 | +import '../../route/route.dart'; | |
6 | 9 | import '../../utils/loading.dart'; |
7 | 10 | import '../../utils/toast_util.dart'; |
8 | 11 | import 'event.dart'; |
... | ... | @@ -10,19 +13,23 @@ import 'state.dart'; |
10 | 13 | |
11 | 14 | class UnitBloc extends Bloc<UnitEvent, UnitState> { |
12 | 15 | |
13 | - CourseUnitEntity? _modelData; | |
16 | + CourseModuleEntity? _moduleEntity; | |
14 | 17 | |
15 | - CourseUnitEntity? get modelData => _modelData; | |
18 | + CourseModuleEntity? get moduleEntity => _moduleEntity; | |
16 | 19 | |
20 | + CourseUnitEntity? _unitData; | |
17 | 21 | |
18 | - UnitBloc() : super(UnitState().init()) { | |
22 | + CourseUnitEntity? get unitData => _unitData; | |
23 | + | |
24 | + | |
25 | + UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) { | |
19 | 26 | on<RequestUnitDataEvent>(_requestData); |
20 | 27 | } |
21 | 28 | |
22 | 29 | void _requestData(RequestUnitDataEvent event, Emitter<UnitState> emitter) async { |
23 | 30 | try { |
24 | 31 | await loading(() async { |
25 | - _modelData = await HomeDao.courseUnit(event.moduleId); | |
32 | + _unitData = await LessonDao.courseUnit(event.moduleId); | |
26 | 33 | emitter(UnitDataLoadState()); |
27 | 34 | }); |
28 | 35 | } catch (e) { |
... | ... | @@ -31,4 +38,22 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { |
31 | 38 | } |
32 | 39 | } |
33 | 40 | } |
41 | + | |
42 | + String? getCourseModuleCode() { | |
43 | + return _moduleEntity?.code ?? _unitData?.courseModuleCode; | |
44 | + } | |
45 | + | |
46 | + void headerActionEvent(HeaderActionType type) { | |
47 | + if (type == HeaderActionType.video) { | |
48 | + pushNamed(AppRouteName.reAfter); | |
49 | + } else if (type == HeaderActionType.phase) { | |
50 | + pushNamed(AppRouteName.courseModule); | |
51 | + } else if (type == HeaderActionType.listen) { | |
52 | + pushNamed(AppRouteName.listen); | |
53 | + } else if (type == HeaderActionType.shop) { | |
54 | + pushNamed(AppRouteName.shop); | |
55 | + } else if (type == HeaderActionType.user) { | |
56 | + pushNamed(AppRouteName.user); | |
57 | + } | |
58 | + } | |
34 | 59 | } | ... | ... |
lib/pages/unit/event.dart
lib/pages/unit/view.dart
... | ... | @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; |
2 | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | 4 | import 'package:wow_english/pages/unit/state.dart'; |
5 | -import 'package:wow_english/pages/unit/widget/course_unit_header_widget.dart'; | |
6 | 5 | import 'package:wow_english/pages/unit/widget/course_unit_item.dart'; |
6 | +import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; | |
7 | 7 | import 'package:wow_english/route/route.dart'; |
8 | 8 | |
9 | 9 | import '../../models/course_module_entity.dart'; |
... | ... | @@ -12,17 +12,18 @@ import '../../utils/toast_util.dart'; |
12 | 12 | import 'bloc.dart'; |
13 | 13 | import 'event.dart'; |
14 | 14 | |
15 | +// 课程列表页(多unit,参考口语星球的框或分割标志) | |
15 | 16 | class UnitPage extends StatelessWidget { |
16 | - const UnitPage({super.key, required this.courseEntity}); | |
17 | + const UnitPage({super.key, this.courseModuleEntity}); | |
17 | 18 | |
18 | 19 | /// 模块 |
19 | - final CourseModuleEntity courseEntity; | |
20 | + final CourseModuleEntity? courseModuleEntity; | |
20 | 21 | |
21 | 22 | @override |
22 | 23 | Widget build(BuildContext context) { |
23 | 24 | return BlocProvider( |
24 | - create: (BuildContext context) => | |
25 | - UnitBloc()..add(RequestUnitDataEvent(courseEntity.id)), | |
25 | + create: (BuildContext context) => UnitBloc(courseModuleEntity) | |
26 | + ..add(RequestUnitDataEvent(courseModuleEntity?.id)), | |
26 | 27 | child: Builder(builder: (context) => _buildPage(context)), |
27 | 28 | ); |
28 | 29 | } |
... | ... | @@ -37,36 +38,42 @@ class UnitPage extends StatelessWidget { |
37 | 38 | child: Column( |
38 | 39 | mainAxisAlignment: MainAxisAlignment.spaceBetween, |
39 | 40 | children: [ |
40 | - CourseUnitHeaderWidget(entity: courseEntity), | |
41 | + HomeTabHeaderWidget( | |
42 | + courseModuleCode: bloc.getCourseModuleCode(), | |
43 | + actionTap: (HeaderActionType type) { | |
44 | + bloc.headerActionEvent(type); | |
45 | + }, | |
46 | + ), | |
41 | 47 | Expanded( |
42 | - child: ListView.builder( | |
43 | - itemCount: | |
44 | - bloc.modelData?.courseUnitVOList?.length ?? 0, | |
45 | - scrollDirection: Axis.horizontal, | |
46 | - itemBuilder: (BuildContext context, int index) { | |
47 | - CourseUnitDetail? data = | |
48 | - bloc.modelData?.courseUnitVOList?[index]; | |
49 | - return GestureDetector( | |
50 | - onTap: () { | |
51 | - if (data.lock == true) { | |
52 | - showToast('当前unit暂未解锁'); | |
53 | - return; | |
54 | - } | |
48 | + child: Container( | |
49 | + margin: EdgeInsets.symmetric(horizontal: 12.w), | |
50 | + child: ListView.builder( | |
51 | + itemCount: | |
52 | + bloc.unitData?.courseUnitVOList?.length ?? 0, | |
53 | + scrollDirection: Axis.horizontal, | |
54 | + itemBuilder: (BuildContext context, int index) { | |
55 | + CourseUnitDetail? data = | |
56 | + bloc.unitData?.courseUnitVOList?[index]; | |
57 | + return GestureDetector( | |
58 | + onTap: () { | |
59 | + if (data.lock == true) { | |
60 | + showToast('当前unit暂未解锁'); | |
61 | + return; | |
62 | + } | |
55 | 63 | |
56 | - ///进入课堂 | |
57 | - pushNamedAndRemoveUntil( | |
58 | - AppRouteName.home, (route) => route.isFirst, | |
59 | - arguments: { | |
60 | - 'moduleId': data.courseModuleId, | |
61 | - 'unitId': data.id | |
62 | - }); | |
63 | - }, | |
64 | - child: CourseUnitItem( | |
65 | - unitEntity: bloc.modelData!, | |
66 | - unitLesson: data!, | |
67 | - ), | |
68 | - ); | |
69 | - })), | |
64 | + pushNamed(AppRouteName.courseSection, | |
65 | + arguments: { | |
66 | + 'courseUnitEntity': bloc.unitData, | |
67 | + 'courseUnitDetail': data | |
68 | + }); | |
69 | + }, | |
70 | + child: CourseUnitItem( | |
71 | + unitEntity: bloc.unitData!, | |
72 | + unitLesson: data!, | |
73 | + ), | |
74 | + ); | |
75 | + })), | |
76 | + ), | |
70 | 77 | SafeArea( |
71 | 78 | child: Column( |
72 | 79 | children: [ | ... | ... |
lib/pages/home/widgets/home_tab_header_widget.dart renamed to lib/pages/unit/widget/home_tab_header_widget.dart
... | ... | @@ -5,8 +5,7 @@ import 'package:wow_english/common/extension/string_extension.dart'; |
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 '../../../models/course_entity.dart'; | |
9 | -import '../courese_module_model.dart'; | |
8 | +import '../../section/courese_module_model.dart'; | |
10 | 9 | |
11 | 10 | enum HeaderActionType { |
12 | 11 | //视频跟读 |
... | ... | @@ -19,14 +18,13 @@ enum HeaderActionType { |
19 | 18 | shop, |
20 | 19 | //个人信息 |
21 | 20 | user, |
22 | - //返回到(模块选择)首页 | |
23 | - home, | |
24 | 21 | } |
25 | 22 | |
26 | 23 | class HomeTabHeaderWidget extends StatelessWidget { |
27 | - const HomeTabHeaderWidget({super.key, this.entity, this.actionTap}); | |
24 | + const HomeTabHeaderWidget({super.key, this.courseModuleCode, this.actionTap}); | |
25 | + | |
26 | + final String? courseModuleCode; | |
28 | 27 | |
29 | - final CourseEntity? entity; | |
30 | 28 | final Function(HeaderActionType type)? actionTap; |
31 | 29 | |
32 | 30 | @override |
... | ... | @@ -37,16 +35,14 @@ class HomeTabHeaderWidget extends StatelessWidget { |
37 | 35 | height: 45, |
38 | 36 | width: double.infinity, |
39 | 37 | color: |
40 | - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1').color, | |
38 | + CourseModuleModel(courseModuleCode ?? 'Phase-1').color, | |
41 | 39 | padding: EdgeInsets.symmetric(horizontal: 9.5.w), |
42 | 40 | child: Row( |
43 | 41 | children: [ |
44 | 42 | ScreenUtil().bottomBarHeight.horizontalSpace, |
45 | 43 | GestureDetector( |
46 | 44 | onTap: () { |
47 | - if (actionTap != null) { | |
48 | - actionTap!(HeaderActionType.home); | |
49 | - } | |
45 | + Navigator.pop(context); | |
50 | 46 | }, |
51 | 47 | child: Container( |
52 | 48 | alignment: Alignment.center, |
... | ... | @@ -96,7 +92,7 @@ class HomeTabHeaderWidget extends StatelessWidget { |
96 | 92 | 20.horizontalSpace, |
97 | 93 | Expanded( |
98 | 94 | child: Text( |
99 | - CourseModuleModel(entity?.courseModuleCode ?? 'Phase-1') | |
95 | + CourseModuleModel(courseModuleCode ?? 'Phase-1') | |
100 | 96 | .courseModuleTitle, |
101 | 97 | textAlign: TextAlign.left, |
102 | 98 | style: const TextStyle(color: Colors.white, fontSize: 30.0), | ... | ... |
lib/route/route.dart
... | ... | @@ -3,22 +3,21 @@ import 'package:flutter/material.dart'; |
3 | 3 | import 'package:wow_english/app/splash_page.dart'; |
4 | 4 | import 'package:wow_english/common/pages/wow_web_page.dart'; |
5 | 5 | import 'package:wow_english/generated/json/base/json_convert_content.dart'; |
6 | +import 'package:wow_english/models/course_unit_entity.dart'; | |
6 | 7 | import 'package:wow_english/models/product_entity.dart'; |
7 | 8 | import 'package:wow_english/pages/games/view.dart'; |
8 | -import 'package:wow_english/pages/home/home_page.dart'; | |
9 | -import 'package:wow_english/pages/lessons/lesson_page.dart'; | |
9 | +import 'package:wow_english/pages/home/view.dart'; | |
10 | 10 | import 'package:wow_english/pages/listen/listen_page.dart'; |
11 | 11 | import 'package:wow_english/pages/login/forgetpwd/forget_password_home_page.dart'; |
12 | 12 | import 'package:wow_english/pages/login/loginpage/login_page.dart'; |
13 | 13 | import 'package:wow_english/pages/login/setpwd/set_pwd_page.dart'; |
14 | -import 'package:wow_english/pages/moduleSelect/view.dart'; | |
14 | +import 'package:wow_english/pages/module/module_page.dart'; | |
15 | 15 | import 'package:wow_english/pages/practice/topic_picture_page.dart'; |
16 | 16 | import 'package:wow_english/pages/repeatafter/repeat_after_page.dart'; |
17 | 17 | import 'package:wow_english/pages/repeataftercontent/repeat_after_content_page.dart'; |
18 | 18 | import 'package:wow_english/pages/shop/exchane/exchange_lesson_page.dart'; |
19 | 19 | import 'package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.dart'; |
20 | 20 | import 'package:wow_english/pages/shop/home/shop_home_page.dart'; |
21 | -import 'package:wow_english/pages/tab/tab_page.dart'; | |
22 | 21 | import 'package:wow_english/pages/user/information/user_information_page.dart'; |
23 | 22 | import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart'; |
24 | 23 | import 'package:wow_english/pages/user/modify/modify_user_information_page.dart'; |
... | ... | @@ -28,7 +27,9 @@ import 'package:wow_english/pages/video/lookvideo/look_video_page.dart'; |
28 | 27 | |
29 | 28 | import '../models/course_module_entity.dart'; |
30 | 29 | import '../pages/reading/reading_page.dart'; |
30 | +import '../pages/section/section_page.dart'; | |
31 | 31 | import '../pages/shopping/view.dart'; |
32 | +import '../pages/tab/tab_page.dart'; | |
32 | 33 | import '../pages/unit/view.dart'; |
33 | 34 | import '../pages/user/setting/delete_account_page.dart'; |
34 | 35 | import '../pages/user/setting/reback_page.dart'; |
... | ... | @@ -36,16 +37,16 @@ import '../pages/user/setting/reback_page.dart'; |
36 | 37 | class AppRouteName { |
37 | 38 | static const String splash = 'splash'; |
38 | 39 | static const String login = 'login'; |
39 | - static const String moduleSelect = 'moduleSelect'; | |
40 | - static const String games = 'games'; | |
41 | 40 | static const String home = 'home'; |
41 | + static const String games = 'games'; | |
42 | 42 | static const String fogPwd = 'fogPwd'; |
43 | 43 | |
44 | 44 | /// 设置密码,修改密码;不要自己调用,使用[SetPassWordPage.push]方法,隐藏这种实现 |
45 | 45 | //static const String setPwd = 'setPwd'; |
46 | 46 | static const String webView = 'webView'; |
47 | - static const String unit = 'courseUnits'; | |
48 | - static const String lesson = 'courseModules'; | |
47 | + static const String courseModule = 'courseModules'; | |
48 | + static const String courseUnit = 'courseUnits'; | |
49 | + static const String courseSection = 'courseSections'; | |
49 | 50 | static const String listen = 'listen'; |
50 | 51 | static const String shop = 'shop'; |
51 | 52 | static const String exLesson = 'exLesson'; |
... | ... | @@ -57,6 +58,7 @@ class AppRouteName { |
57 | 58 | |
58 | 59 | /// 用户详细信息页 |
59 | 60 | static const String userInformation = 'userInformation'; |
61 | + | |
60 | 62 | /// 修改用户头像 |
61 | 63 | static const String userAvatar = 'userAvatar'; |
62 | 64 | |
... | ... | @@ -64,15 +66,19 @@ class AppRouteName { |
64 | 66 | //static const String userModifyInformation = 'userModifyInformation'; |
65 | 67 | ///看视频 |
66 | 68 | static const String lookVideo = 'lookVideo'; |
69 | + | |
67 | 70 | ///绘本 |
68 | 71 | static const String reading = 'reading'; |
72 | + | |
69 | 73 | ///视频跟读详情 |
70 | 74 | static const String readAfterContent = 'readAfterContent'; |
71 | 75 | |
72 | 76 | ///设置 |
73 | 77 | static const String setting = 'setting'; |
78 | + | |
74 | 79 | ///注销账号 |
75 | 80 | static const String deleteAccount = 'deleteAccount'; |
81 | + | |
76 | 82 | ///帮助与反馈 |
77 | 83 | static const String reBack = 'reBack'; |
78 | 84 | |
... | ... | @@ -95,31 +101,42 @@ class AppRouter { |
95 | 101 | transitionsBuilder: (_, __, ___, child) => child); |
96 | 102 | case AppRouteName.login: |
97 | 103 | // 是否默认密码登录,修改密码后跳登录页,优先密码登录体验好点 |
98 | - final bool showPasswordPage = (settings.arguments as Map?)?.getOrNull('showPasswordPage') as bool? ?? false; | |
99 | - return CupertinoPageRoute(builder: (_) => LoginPage(preferencesPasswordLogin: showPasswordPage)); | |
100 | - case AppRouteName.moduleSelect: | |
101 | - return CupertinoPageRoute(builder: (_) => const ModuleSelectPage()); | |
104 | + final bool showPasswordPage = (settings.arguments as Map?) | |
105 | + ?.getOrNull('showPasswordPage') as bool? ?? | |
106 | + false; | |
107 | + return CupertinoPageRoute( | |
108 | + builder: (_) => | |
109 | + LoginPage(preferencesPasswordLogin: showPasswordPage)); | |
110 | + case AppRouteName.home: | |
111 | + return CupertinoPageRoute(builder: (_) => const HomePage()); | |
102 | 112 | case AppRouteName.games: |
103 | 113 | return CupertinoPageRoute(builder: (_) => const GamesPage()); |
104 | - case AppRouteName.home: | |
105 | - int? moduleId; | |
114 | + case AppRouteName.fogPwd: | |
115 | + return CupertinoPageRoute( | |
116 | + builder: (_) => const ForgetPasswordHomePage()); | |
117 | + case AppRouteName.courseModule: | |
118 | + return CupertinoPageRoute(builder: (_) => const ModulePage()); | |
119 | + case AppRouteName.courseUnit: | |
120 | + CourseModuleEntity courseModuleEntity = CourseModuleEntity(); | |
106 | 121 | if (settings.arguments != null) { |
107 | - moduleId = (settings.arguments as Map).getOrNull('moduleId') as int?; | |
122 | + courseModuleEntity = (settings.arguments as Map) | |
123 | + .getOrNull('courseModuleEntity') as CourseModuleEntity; | |
108 | 124 | } |
109 | 125 | return CupertinoPageRoute( |
110 | - builder: (_) => HomePage( | |
111 | - moduleId: moduleId, | |
112 | - )); | |
113 | - case AppRouteName.fogPwd: | |
114 | - return CupertinoPageRoute(builder: (_) => const ForgetPasswordHomePage()); | |
115 | - case AppRouteName.lesson: | |
116 | - return CupertinoPageRoute(builder: (_) => const LessonPage()); | |
117 | - case AppRouteName.unit: | |
118 | - CourseModuleEntity courseEntity = CourseModuleEntity(); | |
126 | + builder: (_) => UnitPage(courseModuleEntity: courseModuleEntity)); | |
127 | + case AppRouteName.courseSection: | |
128 | + CourseUnitEntity courseUnitEntity = CourseUnitEntity(); | |
129 | + CourseUnitDetail courseUnitDetail = CourseUnitDetail(); | |
119 | 130 | if (settings.arguments != null) { |
120 | - courseEntity = (settings.arguments as Map).getOrNull('courseModuleEntity') as CourseModuleEntity; | |
131 | + courseUnitEntity = (settings.arguments as Map) | |
132 | + .getOrNull('courseUnitEntity') as CourseUnitEntity; | |
133 | + courseUnitDetail = (settings.arguments as Map) | |
134 | + .getOrNull('courseUnitDetail') as CourseUnitDetail; | |
121 | 135 | } |
122 | - return CupertinoPageRoute(builder: (_) => UnitPage(courseEntity: courseEntity)); | |
136 | + return CupertinoPageRoute( | |
137 | + builder: (_) => SectionPage( | |
138 | + courseUnitEntity: courseUnitEntity, | |
139 | + courseUnitDetail: courseUnitDetail)); | |
123 | 140 | case AppRouteName.listen: |
124 | 141 | return CupertinoPageRoute(builder: (_) => const ListenPage()); |
125 | 142 | case AppRouteName.shop: |
... | ... | @@ -129,11 +146,13 @@ class AppRouter { |
129 | 146 | if (settings.arguments != null && settings.arguments is ProductEntity) { |
130 | 147 | productEntity = settings.arguments as ProductEntity; |
131 | 148 | } |
132 | - return CupertinoPageRoute(builder: (_) => ShoppingPage(productEntity: productEntity)); | |
149 | + return CupertinoPageRoute( | |
150 | + builder: (_) => ShoppingPage(productEntity: productEntity)); | |
133 | 151 | case AppRouteName.exLesson: |
134 | 152 | return CupertinoPageRoute(builder: (_) => const ExchangeLessonPage()); |
135 | 153 | case AppRouteName.exList: |
136 | - return CupertinoPageRoute(builder: (_) => const ExchangeLessonListPage()); | |
154 | + return CupertinoPageRoute( | |
155 | + builder: (_) => const ExchangeLessonListPage()); | |
137 | 156 | case AppRouteName.reAfter: |
138 | 157 | return CupertinoPageRoute(builder: (_) => const RepeatAfterPage()); |
139 | 158 | case AppRouteName.user: |
... | ... | @@ -161,19 +180,22 @@ class AppRouter { |
161 | 180 | case AppRouteName.topicPic: |
162 | 181 | var courseLessonId = ''; |
163 | 182 | if (settings.arguments != null) { |
164 | - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String; | |
183 | + courseLessonId = | |
184 | + (settings.arguments as Map)['courseLessonId'] as String; | |
165 | 185 | } |
166 | - return CupertinoPageRoute(builder: (_) => TopicPicturePage(courseLessonId: courseLessonId)); | |
186 | + return CupertinoPageRoute( | |
187 | + builder: (_) => TopicPicturePage(courseLessonId: courseLessonId)); | |
167 | 188 | case AppRouteName.lookVideo: |
168 | 189 | final videoUrl = (settings.arguments as Map)['videoUrl'] as String; |
169 | 190 | final title = (settings.arguments as Map)['title'] as String?; |
170 | - final courseLessonId = (settings.arguments as Map)['courseLessonId'] as String?; | |
191 | + final courseLessonId = | |
192 | + (settings.arguments as Map)['courseLessonId'] as String?; | |
171 | 193 | return CupertinoPageRoute( |
172 | 194 | builder: (_) => LookVideoPage( |
173 | - videoUrl: videoUrl, | |
174 | - typeTitle: title, | |
175 | - courseLessonId: courseLessonId, | |
176 | - )); | |
195 | + videoUrl: videoUrl, | |
196 | + typeTitle: title, | |
197 | + courseLessonId: courseLessonId, | |
198 | + )); | |
177 | 199 | /*case AppRouteName.setPwd: |
178 | 200 | case AppRouteName.setPwd: |
179 | 201 | phoneNum: phoneNum, |
... | ... | @@ -182,7 +204,8 @@ class AppRouter { |
182 | 204 | ));*/ |
183 | 205 | case AppRouteName.webView: |
184 | 206 | final urlStr = (settings.arguments as Map)['urlStr'] as String; |
185 | - final webViewTitle = (settings.arguments as Map)['webViewTitle'] as String; | |
207 | + final webViewTitle = | |
208 | + (settings.arguments as Map)['webViewTitle'] as String; | |
186 | 209 | return CupertinoPageRoute( |
187 | 210 | builder: (_) => WowWebViewPage( |
188 | 211 | urlStr: urlStr, |
... | ... | @@ -191,13 +214,16 @@ class AppRouter { |
191 | 214 | case AppRouteName.readAfterContent: |
192 | 215 | var videoFollowReadId = ''; |
193 | 216 | if (settings.arguments != null) { |
194 | - videoFollowReadId = (settings.arguments as Map)['videoFollowReadId'] as String; | |
217 | + videoFollowReadId = | |
218 | + (settings.arguments as Map)['videoFollowReadId'] as String; | |
195 | 219 | } |
196 | - return CupertinoPageRoute(builder: (_) => RepeatAfterContentPage(videoFollowReadId: videoFollowReadId)); | |
220 | + return CupertinoPageRoute( | |
221 | + builder: (_) => | |
222 | + RepeatAfterContentPage(videoFollowReadId: videoFollowReadId)); | |
197 | 223 | case AppRouteName.setting: |
198 | - return CupertinoPageRoute(builder: (_) => const SettingPage()); | |
224 | + return CupertinoPageRoute(builder: (_) => const SettingPage()); | |
199 | 225 | case AppRouteName.deleteAccount: |
200 | - return CupertinoPageRoute(builder: (_) => const DeleteAccountPage()); | |
226 | + return CupertinoPageRoute(builder: (_) => const DeleteAccountPage()); | |
201 | 227 | case AppRouteName.reBack: |
202 | 228 | return CupertinoPageRoute(builder: (_) => const ReBackPage()); |
203 | 229 | case AppRouteName.tab: |
... | ... | @@ -210,26 +236,34 @@ class AppRouter { |
210 | 236 | case AppRouteName.reading: |
211 | 237 | var courseLessonId = ''; |
212 | 238 | if (settings.arguments != null) { |
213 | - courseLessonId = (settings.arguments as Map)['courseLessonId'] as String; | |
239 | + courseLessonId = | |
240 | + (settings.arguments as Map)['courseLessonId'] as String; | |
214 | 241 | } |
215 | - return CupertinoPageRoute(builder: (_) => ReadingPage(courseLessonId: courseLessonId)); | |
242 | + return CupertinoPageRoute( | |
243 | + builder: (_) => ReadingPage(courseLessonId: courseLessonId)); | |
216 | 244 | default: |
217 | 245 | return CupertinoPageRoute( |
218 | - builder: (_) => Scaffold(body: Center(child: Text('No route defined for ${settings.name}')))); | |
246 | + builder: (_) => Scaffold( | |
247 | + body: Center( | |
248 | + child: Text('No route defined for ${settings.name}')))); | |
219 | 249 | } |
220 | 250 | } |
221 | 251 | } |
222 | 252 | |
223 | 253 | Future pushNamed(String routeName, {Object? arguments}) { |
224 | - return Navigator.of(AppRouter.context).pushNamed(routeName, arguments: arguments).then((value) { | |
254 | + return Navigator.of(AppRouter.context) | |
255 | + .pushNamed(routeName, arguments: arguments) | |
256 | + .then((value) { | |
225 | 257 | return value; |
226 | 258 | }); |
227 | 259 | } |
228 | 260 | |
229 | -Future pushNamedAndRemoveUntil(String routeName, RoutePredicate predicate, {Object? arguments}) { | |
230 | - return Navigator.of(AppRouter.context).pushNamedAndRemoveUntil(routeName, predicate, arguments: arguments); | |
261 | +Future pushNamedAndRemoveUntil(String routeName, RoutePredicate predicate, | |
262 | + {Object? arguments}) { | |
263 | + return Navigator.of(AppRouter.context) | |
264 | + .pushNamedAndRemoveUntil(routeName, predicate, arguments: arguments); | |
231 | 265 | } |
232 | 266 | |
233 | 267 | void popPage({dynamic data}) { |
234 | - Navigator.of(AppRouter.context).pop(data); | |
268 | + Navigator.of(AppRouter.context).pop(data); | |
235 | 269 | } | ... | ... |