Commit 93825fa57313d7eaf255156a1880f4ade627c8fd
Merge branch 'feat-wqf-payment' into ios_umeng
Showing
4 changed files
with
115 additions
and
94 deletions
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<SectionEvent, SectionState> { | @@ -101,20 +102,18 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
| 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<SectionEvent, SectionState> { | @@ -129,7 +128,8 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
| 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<SectionEvent, SectionState> { | @@ -171,33 +171,40 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { | ||
| 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 | } |