Commit 93825fa57313d7eaf255156a1880f4ade627c8fd

Authored by xiaoyu
2 parents 9c556200 a9e0b001

Merge branch 'feat-wqf-payment' into ios_umeng

lib/common/request/basic_config.dart
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 2
3 class BasicConfig { 3 class BasicConfig {
4 - // static bool isTestDev = true;  
5 - static bool isTestDev = false; 4 + static bool isTestDev = !isEnvProd();
  5 + // static bool isTestDev = false;
6 6
7 7
8 // 暂时未启用 8 // 暂时未启用
lib/pages/reading/reading_page.dart
@@ -8,6 +8,7 @@ import 'package:wow_english/route/route.dart'; @@ -8,6 +8,7 @@ import 'package:wow_english/route/route.dart';
8 8
9 import '../../common/core/app_consts.dart'; 9 import '../../common/core/app_consts.dart';
10 import '../../common/core/user_util.dart'; 10 import '../../common/core/user_util.dart';
  11 +import '../../common/widgets/throttledGesture_gesture_detector.dart';
11 import '../../models/course_process_entity.dart'; 12 import '../../models/course_process_entity.dart';
12 import '../../utils/log_util.dart'; 13 import '../../utils/log_util.dart';
13 import 'bloc/reading_bloc.dart'; 14 import 'bloc/reading_bloc.dart';
@@ -187,7 +188,8 @@ class _ReadingPage extends StatelessWidget { @@ -187,7 +188,8 @@ class _ReadingPage extends StatelessWidget {
187 SizedBox( 188 SizedBox(
188 width: 10.w, 189 width: 10.w,
189 ), 190 ),
190 - GestureDetector( 191 + ThrottledGestureDetector(
  192 + throttleTime: 1000,
191 onTap: () { 193 onTap: () {
192 if (bloc.isRecording) { 194 if (bloc.isRecording) {
193 bloc.add(XSVoiceStopEvent()); 195 bloc.add(XSVoiceStopEvent());
lib/pages/section/bloc/section_bloc.dart
@@ -37,14 +37,15 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { @@ -37,14 +37,15 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> {
37 ///courseUnitId与课程环节列表的映射 37 ///courseUnitId与课程环节列表的映射
38 final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {}; 38 final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {};
39 39
40 - Map<int, List<CourseSectionEntity>?> get courseSectionDatasMap => _courseSectionDatasMap; 40 + Map<int, List<CourseSectionEntity>?> get courseSectionDatasMap =>
  41 + _courseSectionDatasMap;
41 42
42 CourseProcessEntity? _processEntity; 43 CourseProcessEntity? _processEntity;
43 44
44 CourseProcessEntity? get processEntity => _processEntity; 45 CourseProcessEntity? get processEntity => _processEntity;
45 46
46 - SectionBloc(this._courseUnitEntity, this._currentPage,  
47 - this._pageController, this._listController) 47 + SectionBloc(this._courseUnitEntity, this._currentPage, this._pageController,
  48 + this._listController)
48 : super(LessonInitial()) { 49 : super(LessonInitial()) {
49 on<RequestDataEvent>(_requestSectionsData); 50 on<RequestDataEvent>(_requestSectionsData);
50 on<RequestEndClassEvent>(_requestEndClass); 51 on<RequestEndClassEvent>(_requestEndClass);
@@ -101,20 +102,18 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; { @@ -101,20 +102,18 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
101 RequestEndClassEvent event, Emitter<SectionState> emitter) async { 102 RequestEndClassEvent event, Emitter<SectionState> emitter) async {
102 if (event.isCompleted) { 103 if (event.isCompleted) {
103 await await ListenDao.endClass(event.courseLessonId, 104 await await ListenDao.endClass(event.courseLessonId,
104 - currentStep: event.currentStep,  
105 - currentTime: event.currentTime); 105 + currentStep: event.currentStep, currentTime: event.currentTime);
106 } else { 106 } else {
107 await await ListenDao.exitClass(event.courseLessonId, 107 await await ListenDao.exitClass(event.courseLessonId,
108 - currentStep: event.currentStep,  
109 - currentTime: event.currentTime); 108 + currentStep: event.currentStep, currentTime: event.currentTime);
110 } 109 }
111 if (event.autoNextSection) { 110 if (event.autoNextSection) {
112 final nextCourseSection = 111 final nextCourseSection =
113 - await getNextCourseSection(int.parse(event.courseLessonId)); 112 + await getNextCourseSection(int.parse(event.courseLessonId), emitter);
114 if (nextCourseSection != null) { 113 if (nextCourseSection != null) {
115 ///进入课堂 114 ///进入课堂
116 - add(RequestEnterClassEvent(nextCourseSection.id.toString(),  
117 - nextCourseSection.courseType)); 115 + add(RequestEnterClassEvent(
  116 + nextCourseSection.id.toString(), nextCourseSection.courseType));
118 } 117 }
119 } 118 }
120 } 119 }
@@ -129,7 +128,8 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; { @@ -129,7 +128,8 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
129 int unlockPageCount() { 128 int unlockPageCount() {
130 return _courseUnitEntity.courseUnitVOList 129 return _courseUnitEntity.courseUnitVOList
131 ?.indexWhereOrNull((element) => element.lock == true) ?? 130 ?.indexWhereOrNull((element) => element.lock == true) ??
132 - 1; 131 + _courseUnitEntity.courseUnitVOList?.length ??
  132 + 0;
133 } 133 }
134 134
135 ///当前页的课程详情 135 ///当前页的课程详情
@@ -171,33 +171,40 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; { @@ -171,33 +171,40 @@ class SectionBloc extends Bloc&lt;SectionEvent, SectionState&gt; {
171 CourseUnitDetail? findCourseUnitDetailById(int courseLessonId) { 171 CourseUnitDetail? findCourseUnitDetailById(int courseLessonId) {
172 final curCourseSectionEntity = findCourseSectionById(courseLessonId); 172 final curCourseSectionEntity = findCourseSectionById(courseLessonId);
173 if (curCourseSectionEntity != null) { 173 if (curCourseSectionEntity != null) {
174 - final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList?.firstWhere((element) =>  
175 - element.id == curCourseSectionEntity.courseUnitId); 174 + final curCourseUnitDetail = _courseUnitEntity.courseUnitVOList
  175 + ?.firstWhere(
  176 + (element) => element.id == curCourseSectionEntity.courseUnitId);
176 return curCourseUnitDetail; 177 return curCourseUnitDetail;
177 } 178 }
178 return null; 179 return null;
179 } 180 }
180 181
181 ///根据courseLessonId查找下一个courseSection 182 ///根据courseLessonId查找下一个courseSection
182 - Future<CourseSectionEntity?> getNextCourseSection(int courseLessonId) async { 183 + Future<CourseSectionEntity?> getNextCourseSection(
  184 + int courseLessonId, Emitter<SectionState> emitter) async {
183 final curCourseSectionEntity = findCourseSectionById(courseLessonId); 185 final curCourseSectionEntity = findCourseSectionById(courseLessonId);
184 final curSectionSort = curCourseSectionEntity?.sortOrder ?? 0; 186 final curSectionSort = curCourseSectionEntity?.sortOrder ?? 0;
  187 +
  188 + ///查找下一个section
185 final nextCourseSectionEntity = findCourseSectionBySort(curSectionSort + 1); 189 final nextCourseSectionEntity = findCourseSectionBySort(curSectionSort + 1);
186 if (nextCourseSectionEntity != null) { 190 if (nextCourseSectionEntity != null) {
187 return nextCourseSectionEntity; 191 return nextCourseSectionEntity;
188 } else { 192 } else {
189 - ///跨unit选lesson 193 + ///section为空说明当前unit学完了,找下一个unit。(跨unit选lesson)
  194 + ///先根据courseLessonId找出当前的unit
190 final curCourseUnitDetail = findCourseUnitDetailById(courseLessonId); 195 final curCourseUnitDetail = findCourseUnitDetailById(courseLessonId);
191 if (curCourseUnitDetail != null) { 196 if (curCourseUnitDetail != null) {
  197 + ///再根据当前unit找出下一个unit
192 final nextCourseUnitDetail = _courseUnitEntity.courseUnitVOList 198 final nextCourseUnitDetail = _courseUnitEntity.courseUnitVOList
193 - ?.firstWhere((element) => element.sortOrder == (curCourseUnitDetail.sortOrder! + 1)); 199 + ?.firstWhere((element) =>
  200 + element.sortOrder == (curCourseUnitDetail.sortOrder! + 1));
194 if (nextCourseUnitDetail != null) { 201 if (nextCourseUnitDetail != null) {
195 final courseUnitId = nextCourseUnitDetail.id!; 202 final courseUnitId = nextCourseUnitDetail.id!;
196 try { 203 try {
197 await loading(() async { 204 await loading(() async {
198 _courseSectionDatasMap[courseUnitId] = 205 _courseSectionDatasMap[courseUnitId] =
199 - await LessonDao.courseSection(courseUnitId: courseUnitId);  
200 - emit(LessonDataLoadState()); 206 + await LessonDao.courseSection(courseUnitId: courseUnitId);
  207 + emitter(LessonDataLoadState());
201 }); 208 });
202 _pageController.nextPage( 209 _pageController.nextPage(
203 duration: const Duration(milliseconds: 500), 210 duration: const Duration(milliseconds: 500),
lib/pages/section/section_page.dart
@@ -148,32 +148,36 @@ class _SectionPageView extends StatelessWidget { @@ -148,32 +148,36 @@ class _SectionPageView extends StatelessWidget {
148 title: bloc.getCourseUnitDetail().name, 148 title: bloc.getCourseUnitDetail().name,
149 courseModuleCode: bloc.courseUnitEntity.courseModuleCode), 149 courseModuleCode: bloc.courseUnitEntity.courseModuleCode),
150 Expanded( 150 Expanded(
151 - child: Padding(  
152 - padding: EdgeInsets.symmetric(horizontal: 10.w),  
153 - child: OverflowBox(  
154 - child: NestedPageView.builder(  
155 - itemCount: bloc.unlockPageCount(),  
156 - controller: bloc.pageController,  
157 - onPageChanged: (int index) {  
158 - bloc.add(CurrentUnitIndexChangeEvent(index));  
159 - },  
160 - itemBuilder: (context, index) {  
161 - // return ScrollConfiguration(  
162 - // ///去掉 Android 上默认的边缘拖拽效果  
163 - // behavior: ScrollConfiguration.of(context)  
164 - // .copyWith(overscroll: false),  
165 - // child: _itemTransCard(  
166 - // bloc.getCourseUnitDetail(pageIndex: index),  
167 - // index,  
168 - // context),  
169 - // );  
170 - return _itemTransCard(  
171 - bloc.getCourseUnitDetail(pageIndex: index),  
172 - index,  
173 - context);  
174 - }),  
175 - ), // 设置外部padding,  
176 - )), 151 + child: Container(
  152 + color: Colors.blue,
  153 + child: Padding(
  154 + padding: EdgeInsets.symmetric(horizontal: 10.w),
  155 + // child: OverflowBox(
  156 + child: NestedPageView.builder(
  157 + itemCount: bloc.unlockPageCount(),
  158 + controller: bloc.pageController,
  159 + onPageChanged: (int index) {
  160 + bloc.add(CurrentUnitIndexChangeEvent(index));
  161 + },
  162 + itemBuilder: (context, index) {
  163 + // return ScrollConfiguration(
  164 + // ///去掉 Android 上默认的边缘拖拽效果
  165 + // behavior: ScrollConfiguration.of(context)
  166 + // .copyWith(overscroll: false),
  167 + // child: _itemTransCard(
  168 + // bloc.getCourseUnitDetail(pageIndex: index),
  169 + // index,
  170 + // context),
  171 + // );
  172 + return _itemTransCard(
  173 + bloc.getCourseUnitDetail(pageIndex: index),
  174 + index,
  175 + context);
  176 + }),
  177 + // ), // 设置外部padding,
  178 + )
  179 + )
  180 + ),
177 SafeArea( 181 SafeArea(
178 child: Padding( 182 child: Padding(
179 padding: EdgeInsets.symmetric(horizontal: 13.w), 183 padding: EdgeInsets.symmetric(horizontal: 13.w),
@@ -248,54 +252,62 @@ Widget _itemTransCard( @@ -248,54 +252,62 @@ Widget _itemTransCard(
248 ), 252 ),
249 ); 253 );
250 } else { 254 } else {
251 - return NestedListView.builder(  
252 - itemCount: bloc.courseSectionDatasMap[courseUnitDetail.id]?.length ?? 0,  
253 - scrollDirection: Axis.horizontal,  
254 - itemBuilder: (BuildContext context, int index) {  
255 - CourseSectionEntity sectionData = courseSectionEntities[index];  
256 - if (sectionData.courseType == SectionType.bouns.value) {  
257 - //彩蛋  
258 - return GestureDetector(  
259 - onTap: () {  
260 - if (!UserUtil.isLogined()) {  
261 - pushNamed(AppRouteName.login);  
262 - return;  
263 - }  
264 - if (sectionData.lock == true) {  
265 - showToast('当前课程暂未解锁');  
266 - return;  
267 - } 255 + return
  256 + Padding(padding: EdgeInsets.symmetric(
  257 + vertical: 28.h),
  258 + child: Container(
  259 + color: Colors.red,
  260 + margin: EdgeInsets.symmetric(vertical: 10.h),
  261 + child: NestedListView.builder(
  262 + itemCount: bloc.courseSectionDatasMap[courseUnitDetail.id]?.length ?? 0,
  263 + scrollDirection: Axis.horizontal,
  264 + itemBuilder: (BuildContext context, int index) {
  265 + CourseSectionEntity sectionData = courseSectionEntities[index];
  266 + if (sectionData.courseType == SectionType.bouns.value) {
  267 + //彩蛋
  268 + return GestureDetector(
  269 + onTap: () {
  270 + if (!UserUtil.isLogined()) {
  271 + pushNamed(AppRouteName.login);
  272 + return;
  273 + }
  274 + if (sectionData.lock == true) {
  275 + showToast('当前课程暂未解锁');
  276 + return;
  277 + }
268 278
269 - ///进入课堂  
270 - bloc.add(RequestEnterClassEvent(  
271 - sectionData.id.toString(), sectionData.courseType));  
272 - },  
273 - child: SectionBoundsItem(  
274 - imageUrl: sectionData.coverUrl,  
275 - ),  
276 - );  
277 - } else {  
278 - return GestureDetector(  
279 - onTap: () {  
280 - if (!UserUtil.isLogined()) {  
281 - pushNamed(AppRouteName.login);  
282 - return;  
283 - }  
284 - if (sectionData.lock == true) {  
285 - showToast('当前课程暂未解锁');  
286 - return;  
287 - } 279 + ///进入课堂
  280 + bloc.add(RequestEnterClassEvent(
  281 + sectionData.id.toString(), sectionData.courseType));
  282 + },
  283 + child: SectionBoundsItem(
  284 + imageUrl: sectionData.coverUrl,
  285 + ),
  286 + );
  287 + } else {
  288 + return GestureDetector(
  289 + onTap: () {
  290 + if (!UserUtil.isLogined()) {
  291 + pushNamed(AppRouteName.login);
  292 + return;
  293 + }
  294 + if (sectionData.lock == true) {
  295 + showToast('当前课程暂未解锁');
  296 + return;
  297 + }
288 298
289 - ///进入课堂  
290 - bloc.add(RequestEnterClassEvent(  
291 - sectionData.id.toString(), sectionData.courseType));  
292 - },  
293 - child: SectionItem(  
294 - courseModuleId: bloc.courseUnitEntity.courseModuleCode,  
295 - lessons: sectionData,  
296 - ),  
297 - );  
298 - }  
299 - }); 299 + ///进入课堂
  300 + bloc.add(RequestEnterClassEvent(
  301 + sectionData.id.toString(), sectionData.courseType));
  302 + },
  303 + child: SectionItem(
  304 + courseModuleId: bloc.courseUnitEntity.courseModuleCode,
  305 + lessons: sectionData,
  306 + ),
  307 + );
  308 + }
  309 + }),
  310 + ),
  311 + );
300 } 312 }
301 } 313 }