45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
1
2
|
import 'dart:async';
|
2eb67dd4
liangchengyou
feat:调整代码
|
3
|
import 'package:audioplayers/audioplayers.dart';
|
688b7b5c
liangchengyou
feat:更新文件结构
|
4
|
import 'package:flutter/cupertino.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
5
6
|
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
|
688b7b5c
liangchengyou
feat:更新文件结构
|
7
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
8
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
9
|
import 'package:permission_handler/permission_handler.dart';
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
10
|
import 'package:wow_english/common/extension/string_extension.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
11
12
13
|
import 'package:wow_english/common/request/dao/listen_dao.dart';
import 'package:wow_english/common/request/exception.dart';
import 'package:wow_english/models/course_process_entity.dart';
|
22f36232
吴启风
feat:过渡页-练习环节
|
14
15
16
|
import 'package:wow_english/pages/section/subsection/base_section/bloc.dart';
import 'package:wow_english/pages/section/subsection/base_section/event.dart';
import 'package:wow_english/pages/section/subsection/base_section/state.dart';
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
17
|
import 'package:wow_english/utils/audio_player_util.dart';
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
18
|
import 'package:wow_english/utils/toast_util.dart';
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
19
|
|
e811f164
吴启风
feat:权限申请页面增加隐私合规...
|
20
|
import '../../../common/permission/permissionRequester.dart';
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
21
|
import '../../../common/utils/click_with_music_controller.dart';
|
642081ad
吴启风
feat:lottie动画加载优化...
|
22
|
import '../../../common/utils/show_star_reward_dialog.dart';
|
22f36232
吴启风
feat:过渡页-练习环节
|
23
|
import '../../../route/route.dart';
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
24
|
import '../../../utils/log_util.dart';
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
25
|
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
26
|
part 'topic_picture_event.dart';
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
27
|
|
688b7b5c
liangchengyou
feat:更新文件结构
|
28
|
part 'topic_picture_state.dart';
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
29
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
30
31
32
|
enum VoicePlayState {
///未知
unKnow,
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
33
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
34
35
|
///播放中
playing,
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
36
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
37
38
|
///播放完成
completed,
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
39
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
40
41
42
43
|
///播放终止
stop
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
44
45
|
class TopicPictureBloc
extends BaseSectionBloc<TopicPictureEvent, TopicPictureState> {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
46
47
|
final PageController pageController;
|
608c05b4
liangchengyou
feat:兑换课程
|
48
|
final String courseLessonId;
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
49
50
51
|
int _currentPage = 0;
|
2eb67dd4
liangchengyou
feat:调整代码
|
52
53
54
55
|
int _selectItem = -1;
CourseProcessEntity? _entity;
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
56
57
|
CourseProcessEntity? get entity => _entity;
|
2eb67dd4
liangchengyou
feat:调整代码
|
58
|
///正在评测
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
59
|
bool _isRecording = false;
|
2eb67dd4
liangchengyou
feat:调整代码
|
60
|
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
61
62
63
|
///正在播放音频
VoicePlayState _voicePlayState = VoicePlayState.unKnow;
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
64
65
66
67
68
69
70
71
72
73
|
// 是否是回答(选择)结果音效
bool _isResultSoundPlaying = false;
bool get isResultSoundPlaying => _isResultSoundPlaying;
// 答对播放音效时禁止任何点击(选择)操作
bool _forbiddenWhenCorrect = false;
bool get forbiddenWhenCorrect => _forbiddenWhenCorrect;
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
74
75
76
77
|
int get currentPage => _currentPage + 1;
int get selectItem => _selectItem;
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
78
|
bool get isRecording => _isRecording;
|
2eb67dd4
liangchengyou
feat:调整代码
|
79
|
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
80
|
VoicePlayState get voicePlayState => _voicePlayState;
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
81
|
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
82
|
late MethodChannel methodChannel;
|
2eb67dd4
liangchengyou
feat:调整代码
|
83
|
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
84
|
late AudioPlayer audioPlayer;
|
2eb67dd4
liangchengyou
feat:调整代码
|
85
|
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
86
87
|
final BuildContext context;
|
07b173c9
吴启风
feat:练习页上方进度信息改成进...
|
88
89
90
91
|
final Color? moduleColor;
TopicPictureBloc(
this.context, this.pageController, this.courseLessonId, this.moduleColor)
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
92
|
: super(TopicPictureInitial()) {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
93
|
on<CurrentPageIndexChangeEvent>(_pageControllerChange);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
94
95
96
|
on<VoicePlayStateChangeEvent>(_voicePlayStateChange);
on<XSVoiceResultEvent>(_voiceXsResult);
on<XSVoiceInitEvent>(_initVoiceSdk);
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
97
|
on<SelectItemEvent>(_selectItemLoad);
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
98
|
on<RequestDataEvent>(_requestData);
|
ae77d87f
吴启风
feat:fix语音题无法手动停止...
|
99
|
on<XSVoiceStartEvent>(_voiceXsStart);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
100
|
on<XSVoiceStopEvent>(_voiceXsStop);
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
101
|
on<VoicePlayEvent>(_questionVoicePlay);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
102
|
on<InitBlocEvent>((event, emit) {
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
103
104
|
//音频播放器
audioPlayer = AudioPlayer();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
105
|
audioPlayer.onPlayerStateChanged.listen((event) async {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
106
107
|
debugPrint(
'播放状态变化 _voicePlayState=$_voicePlayState event=$event _isResultSoundPlaying=$_isResultSoundPlaying _forbiddenWhenCorrect=$_forbiddenWhenCorrect');
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
108
109
110
111
112
|
if (_isResultSoundPlaying) {
if (event != PlayerState.playing) {
_isResultSoundPlaying = false;
if (_forbiddenWhenCorrect) {
_forbiddenWhenCorrect = false;
|
77d53ec4
吴启风
feat:练习音效控制优化
|
113
114
|
debugPrint('播放完成后解除禁止');
if (event == PlayerState.completed) {
|
22f36232
吴启风
feat:过渡页-练习环节
|
115
116
117
118
119
|
if (isLastPage()) {
showStepPage();
} else {
// 答对后且播放完自动翻页
pageController.nextPage(
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
120
|
duration: const Duration(milliseconds: 250),
|
22f36232
吴启风
feat:过渡页-练习环节
|
121
122
123
|
curve: Curves.ease,
);
}
|
77d53ec4
吴启风
feat:练习音效控制优化
|
124
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
125
126
127
128
129
130
131
132
133
134
135
|
}
}
} else {
if (event == PlayerState.completed) {
debugPrint('播放完成');
_voicePlayState = VoicePlayState.completed;
}
if (event == PlayerState.stopped) {
debugPrint('播放结束');
_voicePlayState = VoicePlayState.stop;
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
136
|
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
137
138
139
140
141
142
143
144
|
if (event == PlayerState.playing) {
debugPrint('正在播放中');
_voicePlayState = VoicePlayState.playing;
}
if (isClosed) {
return;
}
add(VoicePlayStateChangeEvent());
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
145
|
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
146
147
|
});
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
148
149
|
methodChannel =
const MethodChannel('wow_english/sing_sound_method_channel');
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
150
|
methodChannel.setMethodCallHandler((call) async {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
151
152
153
154
|
if (call.method == 'voiceResult') {
//评测结果
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
155
|
add(XSVoiceResultEvent(call.arguments));
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
156
157
158
|
return;
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
159
160
|
if (call.method == 'voiceStart') {
//评测开始
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
161
162
163
164
165
166
|
if (kDebugMode) {
print('评测开始');
}
return;
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
167
168
169
170
|
if (call.method == 'voiceEnd') {
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
//评测结束
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
171
172
173
174
175
176
|
if (kDebugMode) {
print('评测结束');
}
return;
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
177
178
179
180
181
|
if (call.method == 'voiceFail') {
//评测失败
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
182
183
|
EasyLoading.showToast('评测失败');
return;
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
184
185
|
}
});
|
2eb67dd4
liangchengyou
feat:调整代码
|
186
|
});
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
187
188
189
|
}
@override
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
190
|
Future<void> close() {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
191
|
pageController.dispose();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
192
|
audioPlayer.release();
|
2eb67dd4
liangchengyou
feat:调整代码
|
193
|
audioPlayer.dispose();
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
194
195
|
_isResultSoundPlaying = false;
_forbiddenWhenCorrect = false;
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
196
|
_voiceXsCancel();
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
197
198
199
|
return super.close();
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
200
|
///请求数据
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
201
202
|
void _requestData(
RequestDataEvent event, Emitter<TopicPictureState> emitter) async {
|
2eb67dd4
liangchengyou
feat:调整代码
|
203
|
try {
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
204
205
|
_entity = await ListenDao.process(courseLessonId);
emitter(RequestDataState());
|
2eb67dd4
liangchengyou
feat:调整代码
|
206
207
|
} catch (e) {
if (e is ApiException) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
208
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
2eb67dd4
liangchengyou
feat:调整代码
|
209
210
211
212
|
}
}
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
213
|
///页面切换
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
214
215
|
void _pageControllerChange(CurrentPageIndexChangeEvent event,
Emitter<TopicPictureState> emitter) async {
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
216
217
218
219
|
await closePlayerResource();
debugPrint('翻页 $_currentPage->${event.pageIndex}');
if (_currentPage == _entity?.topics?.length) {
return;
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
220
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
221
|
_currentPage = event.pageIndex;
|
2eb67dd4
liangchengyou
feat:调整代码
|
222
|
final topics = _entity?.topics?[_currentPage];
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
223
|
if (topics?.type != 3 && topics?.type != 4) {
|
2eb67dd4
liangchengyou
feat:调整代码
|
224
|
if (topics?.audioUrl != null) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
225
|
final urlStr = topics?.audioUrl ?? '';
|
2eb67dd4
liangchengyou
feat:调整代码
|
226
|
if (urlStr.isNotEmpty) {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
227
228
|
debugPrint(urlStr);
await audioPlayer.play(UrlSource(urlStr));
|
2eb67dd4
liangchengyou
feat:调整代码
|
229
230
|
}
}
|
2eb67dd4
liangchengyou
feat:调整代码
|
231
|
}
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
232
|
_selectItem = -1;
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
233
234
235
|
emitter(CurrentPageIndexState());
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
236
|
///选择
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
237
238
|
void _selectItemLoad(
SelectItemEvent event, Emitter<TopicPictureState> emitter) async {
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
239
240
241
|
if (_forbiddenWhenCorrect) {
return;
}
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
242
|
_selectItem = event.selectIndex;
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
243
|
if (checkAnswerRight(_selectItem) == true) {
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
244
|
_playResultSound(true);
|
642081ad
吴启风
feat:lottie动画加载优化...
|
245
|
showStarRewardDialog(context);
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
246
|
// showToast('恭喜你,答对啦!',duration: const Duration(seconds: 2));
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
247
248
249
|
} else {
_playResultSound(false);
// showToast('继续加油哦',duration: const Duration(seconds: 2));
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
250
|
}
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
251
|
emitter(SelectItemChangeState());
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
252
|
}
|
2eb67dd4
liangchengyou
feat:调整代码
|
253
|
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
254
255
256
|
///为空则数据异常,用于是否晃动时需要
bool? checkAnswerRight(int selectIndex) {
CourseProcessTopics? topics = _entity?.topics?[_currentPage];
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
257
258
259
260
|
if (topics == null ||
topics.topicAnswerList == null ||
selectIndex < 0 ||
selectIndex >= topics.topicAnswerList!.length) {
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
261
262
263
264
265
266
267
|
return null;
}
CourseProcessTopicsTopicAnswerList? answerList =
topics.topicAnswerList?[selectIndex];
return answerList?.correct != 0;
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
268
|
///初始化SDK
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
269
270
271
|
_initVoiceSdk(
XSVoiceInitEvent event, Emitter<TopicPictureState> emitter) async {
methodChannel.invokeMethod('initVoiceSdk', event.data);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
272
273
|
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
274
|
///先声测试
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
275
276
|
void _voiceXsStart(
XSVoiceStartEvent event, Emitter<TopicPictureState> emitter) async {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
277
|
await audioPlayer.stop();
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
278
|
// 调用封装好的权限检查和请求方法
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
279
280
|
bool result = await requestPermission(
context, Permission.microphone, "录音", "用于开启录音,识别您的开口作答并给出反馈");
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
281
|
if (result) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
282
283
284
285
286
|
methodChannel.invokeMethod('startVoice', {
'word': event.testWord,
'type': event.type,
'userId': event.userId.toString()
});
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
287
|
_isRecording = true;
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
288
289
|
emitter(XSVoiceTestState());
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
290
291
|
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
292
|
///终止评测
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
293
294
|
void _voiceXsStop(
XSVoiceStopEvent event, Emitter<TopicPictureState> emitter) async {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
295
296
297
|
methodChannel.invokeMethod('stopVoice');
}
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
298
299
300
301
302
|
///取消评测(用于处理退出页面后录音未停止等异常情况的保护操作)
void _voiceXsCancel() {
methodChannel.invokeMethod('cancelVoice');
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
303
|
///先声评测结果
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
304
305
|
void _voiceXsResult(
XSVoiceResultEvent event, Emitter<TopicPictureState> emitter) async {
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
306
|
final Map args = event.message as Map;
|
cb38bc90
liangchengyou
feat:视频跟读逻辑处理
|
307
308
|
final result = args['result'] as Map;
final overall = result['overall'].toString();
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
int score = int.parse(overall);
AudioPlayerUtilType audioPlayerUtilType;
String? lottieFile;
if (score > 90) {
audioPlayerUtilType = AudioPlayerUtilType.excellent;
lottieFile = 'assets/lotties/excellent.zip';
} else if (score > 70) {
audioPlayerUtilType = AudioPlayerUtilType.great;
lottieFile = 'assets/lotties/great.zip';
} else if (score > 50) {
audioPlayerUtilType = AudioPlayerUtilType.good;
lottieFile = 'assets/lotties/good.zip';
} else {
audioPlayerUtilType = AudioPlayerUtilType.tryAgain;
}
if (lottieFile != null) {
showCheerRewardDialog(context, lottieFile: lottieFile);
}
Log.d("WQF audioPlayerUtilType=$audioPlayerUtilType lottieFile=$lottieFile");
ClickWithMusicController.instance
.playMusicAndPerformAction(context, audioPlayerUtilType, () => {
///todo 是否需要自动翻页
});
|
642081ad
吴启风
feat:lottie动画加载优化...
|
332
|
// showToast('测评成功,分数是$overall', duration: const Duration(seconds: 5));
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
333
|
_isRecording = false;
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
334
|
emitter(XSVoiceTestState());
|
22f36232
吴启风
feat:过渡页-练习环节
|
335
336
337
|
if (isLastPage()) {
showStepPage();
}
|
2eb67dd4
liangchengyou
feat:调整代码
|
338
|
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
339
|
|
642081ad
吴启风
feat:lottie动画加载优化...
|
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/// 根据得分计算星星数
int _evaluateScore(String scoreStr) {
try {
int score = int.parse(scoreStr);
if (score > 80) {
return 3;
} else if (score > 60) {
return 2;
} else {
return 1;
}
} catch (e) {
// 如果转换失败,可以返回一个默认值或抛出异常
print('Error parsing score: $e');
return 1; // 返回一个默认值表示错误
}
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
358
|
// 暂时没用上
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
359
360
|
void _voicePlayStateChange(VoicePlayStateChangeEvent event,
Emitter<TopicPictureState> emitter) async {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
361
362
363
|
emitter(VoicePlayStateChange());
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
364
|
// 题目音频播放
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
365
366
|
void _questionVoicePlay(
VoicePlayEvent event, Emitter<TopicPictureState> emitter) async {
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
367
|
if (_forbiddenWhenCorrect) {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
368
369
|
return;
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
370
371
|
_forbiddenWhenCorrect = false;
await closePlayerResource();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
372
|
final topics = _entity?.topics?[_currentPage];
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
373
374
375
|
final urlStr = topics?.audioUrl ?? '';
await audioPlayer.play(UrlSource(urlStr),
balance: 0.0, ctx: AudioContext());
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
376
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
377
378
379
380
381
382
383
|
Future<void> closePlayerResource() async {
if (voicePlayState == VoicePlayState.playing || _isResultSoundPlaying) {
await audioPlayer.stop();
}
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
384
|
///播放选择结果音效
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
385
|
void _playResultSound(bool isCorrect) async {
|
77d53ec4
吴启风
feat:练习音效控制优化
|
386
|
// await audioPlayer.stop();
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
387
388
|
if (audioPlayer.state == PlayerState.playing &&
_isResultSoundPlaying == false) {
|
77d53ec4
吴启风
feat:练习音效控制优化
|
389
390
391
|
_voicePlayState = VoicePlayState.stop;
}
debugPrint("_playResultSound isCorrect=$isCorrect");
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
392
393
394
|
_isResultSoundPlaying = true;
_forbiddenWhenCorrect = isCorrect;
if (isCorrect) {
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
395
|
await audioPlayer.play(AssetSource('right'.assetMp3));
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
396
|
} else {
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
397
|
await audioPlayer.play(AssetSource('wrong'.assetMp3));
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
398
399
|
}
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
400
401
402
403
404
405
406
407
408
409
|
///是否是最后一页
bool isLastPage() {
return currentPage == _entity?.topics?.length;
}
///展示过渡页
void showStepPage() {
///如果最后一页是语音问答题,评测完后自动翻页
sectionComplete(() {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
410
411
412
413
414
415
|
popPage(data: {
'currentStep': currentPage,
'courseLessonId': courseLessonId,
'isCompleted': true,
'nextSection': true
});
|
22f36232
吴启风
feat:过渡页-练习环节
|
416
|
}, againSectionTap: () {
|
22f36232
吴启风
feat:过渡页-练习环节
|
417
418
419
|
pageController.jumpToPage(0);
});
}
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
420
|
}
|