d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
1
|
import 'package:flutter/cupertino.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
2
|
import 'package:flutter/foundation.dart';
|
d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
3
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2187c85f
吴启风
feat:课程结构调整
|
4
|
import 'package:wow_english/common/request/dao/lesson_dao.dart';
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
5
|
import 'package:wow_english/common/request/exception.dart';
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
6
7
|
import 'package:wow_english/common/request/dao/listen_dao.dart';
import 'package:wow_english/models/course_process_entity.dart';
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
8
|
import 'package:wow_english/utils/loading.dart';
|
c61b3c1a
Key
feat: toast_util....
|
9
|
import 'package:wow_english/utils/toast_util.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
10
|
|
2187c85f
吴启风
feat:课程结构调整
|
11
12
|
import '../../../models/course_section_entity.dart';
import '../../../models/course_unit_entity.dart';
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
13
|
import '../../../utils/list_ext.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
14
|
|
2187c85f
吴启风
feat:课程结构调整
|
15
16
|
part 'section_event.dart';
part 'section_state.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
17
|
|
2187c85f
吴启风
feat:课程结构调整
|
18
|
class SectionBloc extends Bloc<SectionEvent, SectionState> {
|
c61b3c1a
Key
feat: toast_util....
|
19
|
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
20
21
22
23
24
25
26
27
28
29
30
31
32
|
PageController _pageController;
PageController get pageController => _pageController;
///当前页索引
int _currentPage = 0;
int get currentPage => _currentPage;
ScrollController _listController;
ScrollController get listController => _listController;
|
2187c85f
吴启风
feat:课程结构调整
|
33
34
35
36
|
CourseUnitEntity _courseUnitEntity;
CourseUnitEntity get courseUnitEntity => _courseUnitEntity;
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
37
38
|
///courseUnitId与课程环节列表的映射
final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {};
|
2187c85f
吴启风
feat:课程结构调整
|
39
|
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
40
41
|
Map<int, List<CourseSectionEntity>?> get courseSectionDatasMap =>
_courseSectionDatasMap;
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
42
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
43
44
45
46
|
CourseProcessEntity? _processEntity;
CourseProcessEntity? get processEntity => _processEntity;
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
47
48
|
SectionBloc(this._courseUnitEntity, this._currentPage, this._pageController,
this._listController)
|
22f36232
吴启风
feat:过渡页-练习环节
|
49
|
: super(LessonInitial()) {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
50
|
on<RequestDataEvent>(_requestSectionsData);
|
46675a89
吴启风
feat:过渡页-视频环节
|
51
|
on<RequestEndClassEvent>(_requestEndClass);
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
52
|
on<RequestEnterClassEvent>(_requestEnterClass);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
53
|
on<RequestVideoLessonEvent>(_requestVideoLesson);
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
54
|
on<CurrentUnitIndexChangeEvent>(_pageControllerChange);
|
60e47f7c
liangchengyou
feat:课程选择功能
|
55
|
}
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
56
|
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
57
|
void _requestSectionsData(
|
22f36232
吴启风
feat:过渡页-练习环节
|
58
|
RequestDataEvent event, Emitter<SectionState> emitter) async {
|
993c1a04
liangchengyou
feat:添加数据模型
|
59
60
|
try {
await loading(() async {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
61
62
|
_courseSectionDatasMap[event.courseUnitId] =
await LessonDao.courseSection(courseUnitId: event.courseUnitId);
|
2187c85f
吴启风
feat:课程结构调整
|
63
|
emitter(LessonDataLoadState());
|
993c1a04
liangchengyou
feat:添加数据模型
|
64
65
66
|
});
} catch (e) {
if (e is ApiException) {
|
c61b3c1a
Key
feat: toast_util....
|
67
|
showToast(e.message.toString());
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
68
69
70
|
}
}
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
71
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
72
73
|
void _requestVideoLesson(
RequestVideoLessonEvent event, Emitter<SectionState> emitter) async {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
74
75
76
|
try {
await loading(() async {
_processEntity = await ListenDao.process(event.courseLessonId);
|
22f36232
吴启风
feat:过渡页-练习环节
|
77
78
|
emitter(
RequestVideoLessonState(event.courseLessonId, event.courseType));
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
79
80
81
|
});
} catch (e) {
if (e is ApiException) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
82
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
83
84
85
|
}
}
}
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
86
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
87
88
|
void _requestEnterClass(
RequestEnterClassEvent event, Emitter<SectionState> emitter) async {
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
89
90
|
try {
await loading(() async {
|
22f36232
吴启风
feat:过渡页-练习环节
|
91
92
|
await ListenDao.enterClass(event.courseLessonId);
emitter(RequestEnterClassState(event.courseLessonId, event.courseType));
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
93
94
95
|
});
} catch (e) {
if (e is ApiException) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
96
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
97
98
99
100
|
}
}
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
101
102
|
void _requestEndClass(
RequestEndClassEvent event, Emitter<SectionState> emitter) async {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
103
104
|
if (event.isCompleted) {
await await ListenDao.endClass(event.courseLessonId,
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
105
|
currentStep: event.currentStep, currentTime: event.currentTime);
|
22f36232
吴启风
feat:过渡页-练习环节
|
106
|
} else {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
107
|
await await ListenDao.exitClass(event.courseLessonId,
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
108
|
currentStep: event.currentStep, currentTime: event.currentTime);
|
22f36232
吴启风
feat:过渡页-练习环节
|
109
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
110
|
if (event.autoNextSection) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
111
|
final nextCourseSection =
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
112
|
await getNextCourseSection(int.parse(event.courseLessonId), emitter);
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
113
114
|
if (nextCourseSection != null) {
///进入课堂
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
115
116
|
add(RequestEnterClassEvent(
nextCourseSection.id.toString(), nextCourseSection.courseType));
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
117
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
118
|
}
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
119
|
}
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
120
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
121
122
|
void _pageControllerChange(
CurrentUnitIndexChangeEvent event, Emitter<SectionState> emitter) async {
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
123
124
125
126
|
_currentPage = event.unitIndex;
emitter(CurrentPageIndexState());
}
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
127
|
///未锁定的页(单元)数
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
128
|
int unlockPageCount() {
|
22f36232
吴启风
feat:过渡页-练习环节
|
129
130
|
return _courseUnitEntity.courseUnitVOList
?.indexWhereOrNull((element) => element.lock == true) ??
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
131
132
|
_courseUnitEntity.courseUnitVOList?.length ??
0;
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
133
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
134
|
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
135
|
///当前页的课程详情
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
CourseUnitDetail getCourseUnitDetail({int? pageIndex}) {
return _courseUnitEntity.courseUnitVOList![pageIndex ?? _currentPage];
}
///根据courseLessonId查找对应的courseSection
CourseSectionEntity? findCourseSectionById(int courseLessonId) {
for (var entry in courseSectionDatasMap.entries) {
var sectionList = entry.value;
if (sectionList != null) {
for (var section in sectionList) {
if (section.id == courseLessonId) {
return section;
}
}
}
}
return null;
}
///根据sortOrder查找对应的courseSection
CourseSectionEntity? findCourseSectionBySort(int sortOrder) {
for (var entry in courseSectionDatasMap.entries) {
var sectionList = entry.value;
if (sectionList != null) {
for (var section in sectionList) {
if (section.sortOrder == sortOrder) {
return section;
}
}
}
}
return null;
}
///根据courseLessonId查找对应的CourseUnitDetail
CourseUnitDetail? findCourseUnitDetailById(int courseLessonId) {
final curCourseSectionEntity = findCourseSectionById(courseLessonId);
if (curCourseSectionEntity != null) {
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
174
175
176
|
final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList
?.firstWhere(
(element) => element.id == curCourseSectionEntity.courseUnitId);
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
177
178
179
180
181
|
return curCourseUnitDetail;
}
return null;
}
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
182
|
///根据courseLessonId查找下一个courseSection
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
183
184
|
Future<CourseSectionEntity?> getNextCourseSection(
int courseLessonId, Emitter<SectionState> emitter) async {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
185
186
|
final curCourseSectionEntity = findCourseSectionById(courseLessonId);
final curSectionSort = curCourseSectionEntity?.sortOrder ?? 0;
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
187
188
|
///查找下一个section
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
189
|
final nextCourseSectionEntity = findCourseSectionBySort(curSectionSort + 1);
|
46675a89
吴启风
feat:过渡页-视频环节
|
190
191
192
|
if (nextCourseSectionEntity != null) {
return nextCourseSectionEntity;
} else {
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
193
194
|
///section为空说明当前unit学完了,找下一个unit。(跨unit选lesson)
///先根据courseLessonId找出当前的unit
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
195
|
final curCourseUnitDetail = findCourseUnitDetailById(courseLessonId);
|
46675a89
吴启风
feat:过渡页-视频环节
|
196
|
if (curCourseUnitDetail != null) {
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
197
|
///再根据当前unit找出下一个unit
|
22f36232
吴启风
feat:过渡页-练习环节
|
198
|
final nextCourseUnitDetail = _courseUnitEntity.courseUnitVOList
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
199
200
|
?.firstWhere((element) =>
element.sortOrder == (curCourseUnitDetail.sortOrder! + 1));
|
46675a89
吴启风
feat:过渡页-视频环节
|
201
|
if (nextCourseUnitDetail != null) {
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
202
203
204
205
|
final courseUnitId = nextCourseUnitDetail.id!;
try {
await loading(() async {
_courseSectionDatasMap[courseUnitId] =
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
206
207
|
await LessonDao.courseSection(courseUnitId: courseUnitId);
emitter(LessonDataLoadState());
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
208
209
210
211
212
213
214
215
216
217
218
219
|
});
_pageController.nextPage(
duration: const Duration(milliseconds: 500),
curve: Curves.ease,
);
return _courseSectionDatasMap[courseUnitId]!.first;
} catch (e) {
if (e is ApiException) {
showToast(e.message.toString());
}
return null;
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
220
221
222
223
224
225
226
227
228
229
|
} else {
///最后一个unit了
return null;
}
} else {
///找不到对应的unitDetail,理论上不可能
return null;
}
}
}
|
60e47f7c
liangchengyou
feat:课程选择功能
|
230
|
}
|