5e2bbbd3
biao
添加音频
|
1
|
import 'package:audioplayers/audioplayers.dart';
|
d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
2
|
import 'package:flutter/cupertino.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
3
|
import 'package:flutter/foundation.dart';
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
4
|
import 'package:flutter/material.dart';
|
d35a4e87
liangchengyou
feat:磨耳朵功能UI
|
5
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
6
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
5e2bbbd3
biao
添加音频
|
7
|
import 'package:wow_english/common/extension/string_extension.dart';
|
2187c85f
吴启风
feat:课程结构调整
|
8
|
import 'package:wow_english/common/request/dao/lesson_dao.dart';
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
9
|
import 'package:wow_english/common/request/exception.dart';
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
10
11
|
import 'package:wow_english/common/request/dao/listen_dao.dart';
import 'package:wow_english/models/course_process_entity.dart';
|
025d8543
biao
首页gametime播放修改
|
12
|
import 'package:wow_english/utils/audio_player_util.dart';
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
13
|
import 'package:wow_english/utils/loading.dart';
|
c61b3c1a
Key
feat: toast_util....
|
14
|
import 'package:wow_english/utils/toast_util.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
15
|
|
2187c85f
吴启风
feat:课程结构调整
|
16
17
|
import '../../../models/course_section_entity.dart';
import '../../../models/course_unit_entity.dart';
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
18
|
import '../../../utils/list_ext.dart';
|
60e47f7c
liangchengyou
feat:课程选择功能
|
19
|
|
2187c85f
吴启风
feat:课程结构调整
|
20
|
part 'section_event.dart';
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
21
|
|
2187c85f
吴启风
feat:课程结构调整
|
22
|
part 'section_state.dart';
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
23
|
|
2187c85f
吴启风
feat:课程结构调整
|
24
|
class SectionBloc extends Bloc<SectionEvent, SectionState> {
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
25
26
27
28
29
30
31
32
33
34
35
36
37
|
PageController _pageController;
PageController get pageController => _pageController;
///当前页索引
int _currentPage = 0;
int get currentPage => _currentPage;
ScrollController _listController;
ScrollController get listController => _listController;
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
38
39
40
41
|
ScrollController _indicatorSrollController;
ScrollController get indicatorSrollController => _indicatorSrollController;
|
2187c85f
吴启风
feat:课程结构调整
|
42
43
44
45
|
CourseUnitEntity _courseUnitEntity;
CourseUnitEntity get courseUnitEntity => _courseUnitEntity;
|
0cbdbb34
吴启风
feat:环节列表页返回单元列表页...
|
46
47
48
|
///单元列表是否有刷新,有的话返回上一页时通知其刷新接口数据
bool courseUnitEntityChanged = false;
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
49
50
|
///courseUnitId与课程环节列表的映射
final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {};
|
2187c85f
吴启风
feat:课程结构调整
|
51
|
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
52
53
|
Map<int, List<CourseSectionEntity>?> get courseSectionDatasMap =>
_courseSectionDatasMap;
|
8988aa69
liangchengyou
feat:首页+课程列表数据获取
|
54
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
55
56
57
58
|
CourseProcessEntity? _processEntity;
CourseProcessEntity? get processEntity => _processEntity;
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
59
|
SectionBloc(this._courseUnitEntity, this._currentPage, this._pageController,
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
60
|
this._listController, this._indicatorSrollController)
|
22f36232
吴启风
feat:过渡页-练习环节
|
61
|
: super(LessonInitial()) {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
62
|
on<RequestDataEvent>(_requestSectionsData);
|
46675a89
吴启风
feat:过渡页-视频环节
|
63
|
on<RequestEndClassEvent>(_requestEndClass);
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
64
|
on<RequestEnterClassEvent>(_requestEnterClass);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
65
|
on<RequestVideoLessonEvent>(_requestVideoLesson);
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
66
|
on<CurrentUnitIndexChangeEvent>(_pageControllerChange);
|
d5fb5080
biao
设置页添加版本号 ,播放音频冗余代码删除
|
67
|
on<InitEvent>((event, emit) {
|
b1869cf8
biao
背景音乐添加
|
68
|
AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.countWithMe);
|
5e2bbbd3
biao
添加音频
|
69
70
71
72
|
});
}
@override
Future<void> close() {
|
b1869cf8
biao
背景音乐添加
|
73
|
AudioPlayerUtil.getInstance().pause();
|
5e2bbbd3
biao
添加音频
|
74
75
76
|
return super.close();
}
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
77
|
void _requestSectionsData(
|
22f36232
吴启风
feat:过渡页-练习环节
|
78
|
RequestDataEvent event, Emitter<SectionState> emitter) async {
|
993c1a04
liangchengyou
feat:添加数据模型
|
79
80
|
try {
await loading(() async {
|
5e2bbbd3
biao
添加音频
|
81
82
|
List<CourseSectionEntity>? courseSectionEntities =
await LessonDao.courseSection(courseUnitId: event.courseUnitId);
|
42cf5d28
吴启风
feat:环节数据接口请求优化,解...
|
83
84
|
if (courseSectionEntities != null) {
_courseSectionDatasMap[event.courseUnitId] =
|
5e2bbbd3
biao
添加音频
|
85
|
await LessonDao.courseSection(courseUnitId: event.courseUnitId);
|
42cf5d28
吴启风
feat:环节数据接口请求优化,解...
|
86
87
|
emitter(LessonDataLoadState());
}
|
993c1a04
liangchengyou
feat:添加数据模型
|
88
89
90
|
});
} catch (e) {
if (e is ApiException) {
|
c61b3c1a
Key
feat: toast_util....
|
91
|
showToast(e.message.toString());
|
13e6d11d
liangchengyou
feat:首页课程模块接口
|
92
93
94
|
}
}
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
95
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
96
97
|
void _requestVideoLesson(
RequestVideoLessonEvent event, Emitter<SectionState> emitter) async {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
98
99
100
|
try {
await loading(() async {
_processEntity = await ListenDao.process(event.courseLessonId);
|
22f36232
吴启风
feat:过渡页-练习环节
|
101
102
|
emitter(
RequestVideoLessonState(event.courseLessonId, event.courseType));
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
103
104
105
|
});
} catch (e) {
if (e is ApiException) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
106
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
107
108
109
|
}
}
}
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
110
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
111
112
|
void _requestEnterClass(
RequestEnterClassEvent event, Emitter<SectionState> emitter) async {
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
113
114
|
try {
await loading(() async {
|
22f36232
吴启风
feat:过渡页-练习环节
|
115
116
|
await ListenDao.enterClass(event.courseLessonId);
emitter(RequestEnterClassState(event.courseLessonId, event.courseType));
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
117
118
119
|
});
} catch (e) {
if (e is ApiException) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
120
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
121
122
123
124
|
}
}
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
125
126
|
void _requestEndClass(
RequestEndClassEvent event, Emitter<SectionState> emitter) async {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
127
128
|
if (event.isCompleted) {
await await ListenDao.endClass(event.courseLessonId,
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
129
|
currentStep: event.currentStep, currentTime: event.currentTime);
|
22f36232
吴启风
feat:过渡页-练习环节
|
130
|
} else {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
131
|
await await ListenDao.exitClass(event.courseLessonId,
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
132
|
currentStep: event.currentStep, currentTime: event.currentTime);
|
22f36232
吴启风
feat:过渡页-练习环节
|
133
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
134
|
if (event.autoNextSection) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
135
|
final nextCourseSection =
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
136
|
await getNextCourseSection(int.parse(event.courseLessonId), emitter);
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
137
138
|
if (nextCourseSection != null) {
///进入课堂
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
139
140
|
add(RequestEnterClassEvent(
nextCourseSection.id.toString(), nextCourseSection.courseType));
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
141
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
142
|
}
|
934e2b47
liangchengyou
feat:权限调整+课程进度接口对接
|
143
|
}
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
144
|
|
22f36232
吴启风
feat:过渡页-练习环节
|
145
146
|
void _pageControllerChange(
CurrentUnitIndexChangeEvent event, Emitter<SectionState> emitter) async {
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
147
|
_currentPage = event.unitIndex;
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
double indicatorWidth = 30.0.w; // 指示器宽度
// 计算选中项的偏移量
double offset = _currentPage * indicatorWidth -
(_indicatorSrollController.position.viewportDimension -
indicatorWidth) /
2;
// 确保偏移量在合理范围内
if (offset < 0) {
offset = 0;
} else if (offset >
unlockPageCount() * indicatorWidth -
_indicatorSrollController.position.viewportDimension) {
offset = unlockPageCount() * indicatorWidth -
_indicatorSrollController.position.viewportDimension;
}
_indicatorSrollController.animateTo(
offset,
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
);
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
170
171
172
|
emitter(CurrentPageIndexState());
}
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
173
|
///未锁定的页(单元)数
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
174
|
int unlockPageCount() {
|
0cbdbb34
吴启风
feat:环节列表页返回单元列表页...
|
175
176
177
178
179
|
// return _courseUnitEntity.courseUnitVOList
// ?.indexWhereOrNull((element) => element.lock == true) ??
// _courseUnitEntity.courseUnitVOList?.length ??
// 0;
return _courseUnitEntity.courseUnitVOList?.length ?? 0;
|
3ba925a9
吴启风
feat:环节页增加翻页切换单元效果
|
180
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
181
|
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
182
|
///当前页的课程详情
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
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解锁态下...
|
221
|
final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
222
|
?.firstWhereOrNull(
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
223
|
(element) => element.id == curCourseSectionEntity.courseUnitId);
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
224
225
226
227
228
|
return curCourseUnitDetail;
}
return null;
}
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
229
|
///根据courseLessonId查找下一个courseSection
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
230
231
|
Future<CourseSectionEntity?> getNextCourseSection(
int courseLessonId, Emitter<SectionState> emitter) async {
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
232
233
|
final curCourseSectionEntity = findCourseSectionById(courseLessonId);
final curSectionSort = curCourseSectionEntity?.sortOrder ?? 0;
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
234
|
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
235
236
237
238
|
try {
///查找当前unit的下一个section
CourseSectionEntity? nextCourseSectionEntity =
findCourseSectionBySort(curSectionSort + 1);
|
5e2bbbd3
biao
添加音频
|
239
240
|
return checkCourseSectionLocked(
courseLessonId, nextCourseSectionEntity, emitter);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
241
242
243
244
245
246
247
248
249
|
} catch (e) {
if (e is ApiException) {
showToast(e.message.toString());
}
return null;
}
}
///检查section是否锁定
|
5e2bbbd3
biao
添加音频
|
250
251
252
|
Future<CourseSectionEntity?> checkCourseSectionLocked(
int courseLessonId,
CourseSectionEntity? courseSectionEntity,
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
253
254
255
256
257
258
259
260
|
Emitter<SectionState> emitter) async {
if (courseSectionEntity != null) {
if (courseSectionEntity.lock == false) {
///如果section没锁,直接返回
return courseSectionEntity;
} else {
///如果section锁了,请求当前unit下的section数据,查询解锁状态
int courseUnitId = courseSectionEntity.courseUnitId;
|
5e2bbbd3
biao
添加音频
|
261
|
CourseSectionEntity? result = await loading(() async {
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
262
|
List<CourseSectionEntity>? tempSectionEntities =
|
5e2bbbd3
biao
添加音频
|
263
|
await LessonDao.courseSection(courseUnitId: courseUnitId);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
264
265
266
267
268
|
if (tempSectionEntities != null) {
_courseSectionDatasMap[courseUnitId] = tempSectionEntities;
emitter(LessonDataLoadState());
}
courseSectionEntity = tempSectionEntities?.firstWhereOrNull(
|
5e2bbbd3
biao
添加音频
|
269
|
(element) => element.id == courseSectionEntity?.id);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
270
271
272
273
274
275
276
277
278
|
if (courseSectionEntity?.lock == false) {
///刷新后的数据如果解锁了,直接返回
return courseSectionEntity;
} else {
///请求失败或者锁定状态没变(没变就感觉状态异常了,理论上不应该进入这条分支),返回null
showToast('下个课程还没解锁哦');
return null;
}
});
|
9e085b2a
吴启风
feat:异步返回优化
|
279
|
return result;
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
280
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
281
|
} else {
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
282
|
///section为空说明当前unit学完了,找下一个unit。(跨unit选section)
|
1ebed821
吴启风
feat:修复所有unit解锁态下...
|
283
|
///先根据courseLessonId找出当前的unit
|
66a7e3e7
吴启风
feat:退出课堂和结束课堂优化
|
284
|
final curCourseUnitDetail = findCourseUnitDetailById(courseLessonId);
|
46675a89
吴启风
feat:过渡页-视频环节
|
285
|
if (curCourseUnitDetail != null) {
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
286
287
|
///再根据当前unit的sortOrder找出下一个unit
CourseUnitDetail? nextCourseUnitDetail =
|
5e2bbbd3
biao
添加音频
|
288
289
|
_courseUnitEntity.courseUnitVOList?.firstWhereOrNull((element) =>
element.sortOrder == (curCourseUnitDetail.sortOrder! + 1));
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
290
|
|
46675a89
吴启风
feat:过渡页-视频环节
|
291
|
if (nextCourseUnitDetail != null) {
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
292
293
|
if (nextCourseUnitDetail.lock == true) {
///如果下一个unit是锁定状态,请求数据刷新查询解锁状态
|
9e085b2a
吴启风
feat:异步返回优化
|
294
|
CourseSectionEntity? result = await loading(() async {
|
5e2bbbd3
biao
添加音频
|
295
296
297
|
CourseUnitEntity? newCourseUnitEntity =
await LessonDao.courseUnit(
_courseUnitEntity.nowCourseModuleId);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
298
299
|
///拿到重新获取到的unit后,再次判断是否解锁
|
5e2bbbd3
biao
添加音频
|
300
301
|
nextCourseUnitDetail = newCourseUnitEntity?.courseUnitVOList
?.firstWhereOrNull(
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
302
303
304
305
|
(element) => element.id == nextCourseUnitDetail?.id);
if (nextCourseUnitDetail?.lock == false) {
///解锁状态从锁定到解锁,覆盖原unit数据并刷新ui
_courseUnitEntity = newCourseUnitEntity!;
|
0cbdbb34
吴启风
feat:环节列表页返回单元列表页...
|
306
|
courseUnitEntityChanged = true;
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
307
308
|
emitter(LessonDataLoadState());
|
5e2bbbd3
biao
添加音频
|
309
310
|
return checkCourseSectionLockedOfNextUnit(
courseLessonId, nextCourseUnitDetail!.id!, emitter);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
311
312
313
314
315
316
|
} else {
showToast('下个单元课程还没解锁哦');
///如果还是锁定状态,返回null
return null;
}
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
317
|
});
|
9e085b2a
吴启风
feat:异步返回优化
|
318
|
return result;
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
319
|
} else {
|
5e2bbbd3
biao
添加音频
|
320
321
|
return checkCourseSectionLockedOfNextUnit(
courseLessonId, nextCourseUnitDetail.id!, emitter);
|
336074ab
吴启风
feat:过渡页-绘本环节跨单元处理
|
322
|
}
|
46675a89
吴启风
feat:过渡页-视频环节
|
323
|
} else {
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
324
|
showToast("恭喜你,本阶段学到顶啦");
|
5e2bbbd3
biao
添加音频
|
325
|
|
46675a89
吴启风
feat:过渡页-视频环节
|
326
327
328
329
330
331
332
333
|
///最后一个unit了
return null;
}
} else {
///找不到对应的unitDetail,理论上不可能
return null;
}
}
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
334
335
336
|
}
///检查下一个unit的(第一个)section
|
5e2bbbd3
biao
添加音频
|
337
338
339
|
Future<CourseSectionEntity?> checkCourseSectionLockedOfNextUnit(
int courseLessonId,
int nextCourseUnitDetailId,
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
340
|
Emitter<SectionState> emitter) async {
|
5e2bbbd3
biao
添加音频
|
341
342
|
CourseSectionEntity? firstSectionNextUnit =
await getFirstSectionByUnitId(nextCourseUnitDetailId, emitter);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
343
344
|
if (firstSectionNextUnit != null) {
///下个unit的第一个section如果不为空,再次检查是否锁定
|
5e2bbbd3
biao
添加音频
|
345
346
|
CourseSectionEntity? courseSectionEntity = await checkCourseSectionLocked(
courseLessonId, firstSectionNextUnit, emitter);
|
009cf00d
吴启风
feat:环节&单元解锁逻辑
|
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
if (courseSectionEntity != null) {
///只有是下一unit的第一个section并且解锁了,才跳转
_pageController.nextPage(
duration: const Duration(milliseconds: 250),
curve: Curves.ease,
);
}
return courseSectionEntity;
} else {
///下个unit的第一个section如果为空,返回null
showToast('下个课程暂未找到');
return null;
}
}
///根据unitId获取当前unit的第一个section
Future<CourseSectionEntity?> getFirstSectionByUnitId(
int courseUnitId, Emitter<SectionState> emitter) async {
List<CourseSectionEntity>? courseSectionEntity =
_courseSectionDatasMap[courseUnitId];
if (courseSectionEntity == null) {
///如果没下载过,请求数据
await loading(() async {
_courseSectionDatasMap[courseUnitId] =
await LessonDao.courseSection(courseUnitId: courseUnitId);
emitter(LessonDataLoadState());
});
}
return _courseSectionDatasMap[courseUnitId]?.first;
|
46675a89
吴启风
feat:过渡页-视频环节
|
376
|
}
|
60e47f7c
liangchengyou
feat:课程选择功能
|
377
|
}
|