Commit d0623cfde9d8fc3f04604441f5546fae59d6c673
1 parent
819ae43b
feat:绘本作答结果动效
Showing
5 changed files
with
44 additions
and
40 deletions
assets/lotties/good.zip
No preview for this file type
assets/lotties/recorder_playback.zip
No preview for this file type
lib/common/widgets/record_playback_widget.dart
| @@ -67,7 +67,7 @@ class _RecorderPlaybackWidgetState extends State<RecorderPlaybackWidget> | @@ -67,7 +67,7 @@ class _RecorderPlaybackWidgetState extends State<RecorderPlaybackWidget> | ||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | Future<void> _loadComposition() async { | 69 | Future<void> _loadComposition() async { |
| 70 | - _futureComposition = AssetLottie('assets/lotties/recorder_back.zip').load(); | 70 | + _futureComposition = AssetLottie('assets/lotties/recorder_playback.zip').load(); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void _playAnimation() { | 73 | void _playAnimation() { |
lib/pages/reading/bloc/reading_bloc.dart
| @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; | @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; | ||
| 5 | import 'package:flutter_bloc/flutter_bloc.dart'; | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 6 | import 'package:flutter_easyloading/flutter_easyloading.dart'; | 6 | import 'package:flutter_easyloading/flutter_easyloading.dart'; |
| 7 | import 'package:permission_handler/permission_handler.dart'; | 7 | import 'package:permission_handler/permission_handler.dart'; |
| 8 | +import 'package:wow_english/common/extension/string_extension.dart'; | ||
| 8 | import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart'; | 9 | import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart'; |
| 9 | import 'package:wow_english/pages/section/subsection/base_section/bloc.dart'; | 10 | import 'package:wow_english/pages/section/subsection/base_section/bloc.dart'; |
| 10 | import 'package:wow_english/pages/section/subsection/base_section/event.dart'; | 11 | import 'package:wow_english/pages/section/subsection/base_section/event.dart'; |
| @@ -14,13 +15,17 @@ import '../../../common/core/user_util.dart'; | @@ -14,13 +15,17 @@ import '../../../common/core/user_util.dart'; | ||
| 14 | import '../../../common/permission/permissionRequester.dart'; | 15 | import '../../../common/permission/permissionRequester.dart'; |
| 15 | import '../../../common/request/dao/listen_dao.dart'; | 16 | import '../../../common/request/dao/listen_dao.dart'; |
| 16 | import '../../../common/request/exception.dart'; | 17 | import '../../../common/request/exception.dart'; |
| 18 | +import '../../../common/utils/click_with_music_controller.dart'; | ||
| 19 | +import '../../../common/utils/show_star_reward_dialog.dart'; | ||
| 17 | import '../../../models/course_process_entity.dart'; | 20 | import '../../../models/course_process_entity.dart'; |
| 21 | +import '../../../models/voice_result_type.dart'; | ||
| 18 | import '../../../route/route.dart'; | 22 | import '../../../route/route.dart'; |
| 19 | import '../../../utils/loading.dart'; | 23 | import '../../../utils/loading.dart'; |
| 20 | 24 | ||
| 21 | import '../../../utils/log_util.dart'; | 25 | import '../../../utils/log_util.dart'; |
| 22 | 26 | ||
| 23 | part 'reading_event.dart'; | 27 | part 'reading_event.dart'; |
| 28 | + | ||
| 24 | part 'reading_state.dart'; | 29 | part 'reading_state.dart'; |
| 25 | 30 | ||
| 26 | enum VoicePlayState { | 31 | enum VoicePlayState { |
| @@ -340,8 +345,8 @@ class ReadingPageBloc | @@ -340,8 +345,8 @@ class ReadingPageBloc | ||
| 340 | ///开始录音 | 345 | ///开始录音 |
| 341 | void startRecord(String content) async { | 346 | void startRecord(String content) async { |
| 342 | // 调用封装好的权限检查和请求方法 | 347 | // 调用封装好的权限检查和请求方法 |
| 343 | - bool result = | ||
| 344 | - await requestPermission(context, Permission.microphone, "录音", "用于开启录音,识别您的开口作答并给出反馈"); | 348 | + bool result = await requestPermission( |
| 349 | + context, Permission.microphone, "录音", "用于开启录音,识别您的开口作答并给出反馈"); | ||
| 345 | if (result) { | 350 | if (result) { |
| 346 | methodChannel.invokeMethod('startVoice', { | 351 | methodChannel.invokeMethod('startVoice', { |
| 347 | 'word': content, | 352 | 'word': content, |
| @@ -357,27 +362,35 @@ class ReadingPageBloc | @@ -357,27 +362,35 @@ class ReadingPageBloc | ||
| 357 | final result = args['result'] as Map; | 362 | final result = args['result'] as Map; |
| 358 | Log.d("_voiceXsResult result=$result"); | 363 | Log.d("_voiceXsResult result=$result"); |
| 359 | final overall = result['overall'].toString(); | 364 | final overall = result['overall'].toString(); |
| 360 | - EasyLoading.showToast('测评成功,分数是$overall', | ||
| 361 | - duration: const Duration(seconds: 2)); | 365 | + |
| 366 | + ///todo 后面可以考虑要不要传自己的服务器 | ||
| 367 | + final recordFileUrl = args['audioUrl'].toString(); | ||
| 368 | + int score = int.parse(overall); | ||
| 362 | currentPageData()?.recordScore = overall; | 369 | currentPageData()?.recordScore = overall; |
| 363 | - currentPageData()?.recordUrl = args['audioUrl'] + '.mp3'; | 370 | + currentPageData()?.recordUrl = recordFileUrl.assetMp3; |
| 364 | 371 | ||
| 365 | - ///完成录音后紧接着播放录音 | ||
| 366 | - await _playRecordAudioInner(); | ||
| 367 | - if (isLastPage()) { | ||
| 368 | - sectionComplete(() { | ||
| 369 | - popPage(data: { | ||
| 370 | - 'currentStep': currentPage, | ||
| 371 | - 'courseLessonId': courseLessonId, | ||
| 372 | - 'isCompleted': true, | ||
| 373 | - 'nextSection': true | ||
| 374 | - }); | ||
| 375 | - }, againSectionTap: () { | ||
| 376 | - _resetLocalResult(); | ||
| 377 | - pageController.jumpToPage(0); | ||
| 378 | - }); | 372 | + final voiceResult = VoiceResultType.fromScore(score); |
| 373 | + if (voiceResult.lottieFilePath != null) { | ||
| 374 | + showCheerRewardDialog(context, lottieFile: voiceResult.lottieFilePath!); | ||
| 379 | } | 375 | } |
| 380 | - // emitter(FeedbackState()); | 376 | + await ClickWithMusicController.instance |
| 377 | + .playMusicAndPerformAction(context, voiceResult.audioType, () async { | ||
| 378 | + ///完成录音后紧接着播放录音 | ||
| 379 | + await _playRecordAudioInner(); | ||
| 380 | + if (isLastPage()) { | ||
| 381 | + sectionComplete(() { | ||
| 382 | + popPage(data: { | ||
| 383 | + 'currentStep': currentPage, | ||
| 384 | + 'courseLessonId': courseLessonId, | ||
| 385 | + 'isCompleted': true, | ||
| 386 | + 'nextSection': true | ||
| 387 | + }); | ||
| 388 | + }, againSectionTap: () { | ||
| 389 | + _resetLocalResult(); | ||
| 390 | + pageController.jumpToPage(0); | ||
| 391 | + }); | ||
| 392 | + } | ||
| 393 | + }); | ||
| 381 | } | 394 | } |
| 382 | 395 | ||
| 383 | ///终止评测 | 396 | ///终止评测 |
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/record_playback_widget.dart'; | ||
| 11 | import '../../common/widgets/recorder_widget.dart'; | 12 | import '../../common/widgets/recorder_widget.dart'; |
| 12 | import '../../common/widgets/speaker_widget.dart'; | 13 | import '../../common/widgets/speaker_widget.dart'; |
| 13 | import '../../models/course_process_entity.dart'; | 14 | import '../../models/course_process_entity.dart'; |
| @@ -186,8 +187,6 @@ class _ReadingPage extends StatelessWidget { | @@ -186,8 +187,6 @@ class _ReadingPage extends StatelessWidget { | ||
| 186 | ), | 187 | ), |
| 187 | RecorderWidget( | 188 | RecorderWidget( |
| 188 | isPlaying: bloc.isRecording, | 189 | isPlaying: bloc.isRecording, |
| 189 | - isClickable: | ||
| 190 | - bloc.voicePlayState != VoicePlayState.playing, | ||
| 191 | width: 60.w, | 190 | width: 60.w, |
| 192 | height: 60.w, | 191 | height: 60.w, |
| 193 | onTap: () { | 192 | onTap: () { |
| @@ -202,23 +201,15 @@ class _ReadingPage extends StatelessWidget { | @@ -202,23 +201,15 @@ class _ReadingPage extends StatelessWidget { | ||
| 202 | SizedBox( | 201 | SizedBox( |
| 203 | width: 10.w, | 202 | width: 10.w, |
| 204 | ), | 203 | ), |
| 205 | - GestureDetector( | ||
| 206 | - onTap: () { | ||
| 207 | - if (bloc.isRecording) { | ||
| 208 | - return; | ||
| 209 | - } | ||
| 210 | - bloc.add(PlayRecordAudioEvent()); | ||
| 211 | - }, | ||
| 212 | - child: Visibility( | ||
| 213 | - visible: bloc.currentPageData()?.recordUrl != null, | ||
| 214 | - child: Image.asset( | ||
| 215 | - bloc.isRecordAudioPlaying | ||
| 216 | - ? 'record_pause'.assetWebp | ||
| 217 | - : 'record_play'.assetWebp, | ||
| 218 | - height: 33.h, | ||
| 219 | - width: 33.w, | ||
| 220 | - ), | ||
| 221 | - )), | 204 | + RecorderPlaybackWidget( |
| 205 | + isClickable: !bloc.isRecording && bloc.currentPageData()?.recordUrl != null, | ||
| 206 | + isPlaying: bloc.isRecordAudioPlaying, | ||
| 207 | + width: 42.w, | ||
| 208 | + height: 42.w, | ||
| 209 | + onTap: () { | ||
| 210 | + bloc.add(PlayRecordAudioEvent()); | ||
| 211 | + }, | ||
| 212 | + ) | ||
| 222 | ], | 213 | ], |
| 223 | ), | 214 | ), |
| 224 | ), | 215 | ), |