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
|
import 'package:flutter/foundation.dart';
|
688b7b5c
liangchengyou
feat:更新文件结构
|
6
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
7
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
8
|
import 'package:permission_handler/permission_handler.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
9
10
|
import 'package:wow_english/common/request/dao/listen_dao.dart';
import 'package:wow_english/common/request/exception.dart';
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
11
|
import 'package:wow_english/common/speech/chivox_evaluation_channel.dart';
|
2eb67dd4
liangchengyou
feat:调整代码
|
12
|
import 'package:wow_english/models/course_process_entity.dart';
|
22f36232
吴启风
feat:过渡页-练习环节
|
13
14
15
|
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:语音跟读作答结果动效&语音
|
16
|
import 'package:wow_english/utils/audio_player_util.dart';
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
17
|
import 'package:wow_english/utils/toast_util.dart';
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
18
|
|
e811f164
吴启风
feat:权限申请页面增加隐私合规...
|
19
|
import '../../../common/permission/permissionRequester.dart';
|
642081ad
吴启风
feat:lottie动画加载优化...
|
20
|
import '../../../common/utils/show_star_reward_dialog.dart';
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
21
|
import '../../../models/voice_result_type.dart';
|
22f36232
吴启风
feat:过渡页-练习环节
|
22
|
import '../../../route/route.dart';
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
23
|
import '../../../utils/log_util.dart';
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
24
|
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
25
|
part 'topic_picture_event.dart';
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
26
|
|
688b7b5c
liangchengyou
feat:更新文件结构
|
27
|
part 'topic_picture_state.dart';
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
28
|
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
29
|
class TopicPictureBloc
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
30
31
|
extends BaseSectionBloc<TopicPictureEvent, TopicPictureState>
with WidgetsBindingObserver {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
32
33
|
final PageController pageController;
|
608c05b4
liangchengyou
feat:兑换课程
|
34
|
final String courseLessonId;
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
35
36
37
|
int _currentPage = 0;
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
38
|
int _optionSelectItem = -1;
|
2eb67dd4
liangchengyou
feat:调整代码
|
39
40
41
|
CourseProcessEntity? _entity;
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
42
43
|
CourseProcessEntity? get entity => _entity;
|
2eb67dd4
liangchengyou
feat:调整代码
|
44
|
///正在评测
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
45
|
bool _isRecording = false;
|
2eb67dd4
liangchengyou
feat:调整代码
|
46
|
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
47
48
|
int get currentPage => _currentPage + 1;
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
49
50
|
/// 选择题选中项
int get optionSelectItem => _optionSelectItem;
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
51
|
|
d4d91cb0
吴启风
feat:lottie动效组件封装...
|
52
|
bool get isRecording => _isRecording;
|
2eb67dd4
liangchengyou
feat:调整代码
|
53
|
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
54
|
final ChivoxEvaluationChannel methodChannel = ChivoxEvaluationChannel();
|
2eb67dd4
liangchengyou
feat:调整代码
|
55
|
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
56
|
late AudioPlayer audioPlayer;
|
2eb67dd4
liangchengyou
feat:调整代码
|
57
|
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
58
59
|
final BuildContext context;
|
07b173c9
吴启风
feat:练习页上方进度信息改成进...
|
60
61
|
final Color? moduleColor;
|
8fb5f860
吴启风
feat:先声录音状态优化
|
62
63
|
final String TAG = 'TopicPictureBloc';
|
07b173c9
吴启风
feat:练习页上方进度信息改成进...
|
64
65
|
TopicPictureBloc(
this.context, this.pageController, this.courseLessonId, this.moduleColor)
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
66
|
: super(TopicPictureInitial()) {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
67
|
on<CurrentPageIndexChangeEvent>(_pageControllerChange);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
68
69
|
on<VoicePlayStateChangeEvent>(_voicePlayStateChange);
on<XSVoiceResultEvent>(_voiceXsResult);
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
70
|
on<SelectItemEvent>(_selectItemLoad);
|
5989d250
吴启风
feat:体验优化-选择题选中边框...
|
71
|
on<SelectItemResetEvent>(_selectItemReset);
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
72
|
on<RequestDataEvent>(_requestData);
|
ae77d87f
吴启风
feat:fix语音题无法手动停止...
|
73
|
on<XSVoiceStartEvent>(_voiceXsStart);
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
74
|
on<XSVoiceStopEvent>(_voiceXsStop);
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
75
|
on<VoicePlayEvent>(_questionVoicePlay);
|
8fb5f860
吴启风
feat:先声录音状态优化
|
76
|
on<OnXSVoiceStateChangeEvent>(_onVoiceXsStateChange);
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
77
|
on<InitBlocEvent>((event, emit) async {
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
78
79
|
//音频播放器
audioPlayer = AudioPlayer();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
80
|
audioPlayer.onPlayerStateChanged.listen((event) async {
|
8fb5f860
吴启风
feat:先声录音状态优化
|
81
|
Log.d('$TAG onPlayerStateChanged event=$event');
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
82
83
84
85
|
if (isClosed) {
return;
}
add(VoicePlayStateChangeEvent());
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
86
87
|
});
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
88
|
methodChannel.setMethodCallHandler((call) async {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
89
90
91
92
|
if (call.method == 'voiceResult') {
//评测结果
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
93
|
add(XSVoiceResultEvent(call.arguments));
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
94
95
96
|
return;
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
97
98
|
if (call.method == 'voiceStart') {
//评测开始
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
99
100
101
|
if (kDebugMode) {
print('评测开始');
}
|
8fb5f860
吴启风
feat:先声录音状态优化
|
102
103
|
_isRecording = true;
add(OnXSVoiceStateChangeEvent());
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
104
105
106
|
return;
}
|
8fb5f860
吴启风
feat:先声录音状态优化
|
107
|
if (call.method == 'voiceEnd' || call.method == 'voiceCancel') {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
108
109
110
|
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
//评测结束
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
111
|
if (kDebugMode) {
|
8fb5f860
吴启风
feat:先声录音状态优化
|
112
|
print(call.method == 'voiceEnd' ? '评测结束' : '评测取消');
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
113
|
}
|
8fb5f860
吴启风
feat:先声录音状态优化
|
114
115
|
_isRecording = false;
add(OnXSVoiceStateChangeEvent());
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
116
117
118
|
return;
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
119
120
121
122
123
|
if (call.method == 'voiceFail') {
//评测失败
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
8fb5f860
吴启风
feat:先声录音状态优化
|
124
125
|
_isRecording = false;
add(OnXSVoiceStateChangeEvent());
|
b90a1518
liangchengyou
feat:练习接口逻辑完成
|
126
127
|
EasyLoading.showToast('评测失败');
return;
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
128
129
|
}
});
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
130
|
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
131
132
|
await methodChannel.invokeMethod('initVoiceSdk', {});
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
133
|
WidgetsBinding.instance.addObserver(this);
|
2eb67dd4
liangchengyou
feat:调整代码
|
134
|
});
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
135
136
|
}
|
8fb5f860
吴启风
feat:先声录音状态优化
|
137
138
139
140
141
|
void _onVoiceXsStateChange(OnXSVoiceStateChangeEvent event,
Emitter<TopicPictureState> emitter) async {
emitter(XSVoiceTestState());
}
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
142
|
@override
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
143
144
|
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
|
8fb5f860
吴启风
feat:先声录音状态优化
|
145
|
Log.d('$TAG didChangeAppLifecycleState state=$state');
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
146
147
148
149
150
151
152
153
154
155
|
if (state == AppLifecycleState.paused) {
///切到后台暂停音频播放、录音等
if (audioPlayer.state == PlayerState.playing) {
await audioPlayer.pause();
}
_voiceXsCancel();
}
}
@override
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
156
|
Future<void> close() async {
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
157
|
pageController.dispose();
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
158
159
160
161
|
await audioPlayer.release();
await audioPlayer.dispose();
await _voiceXsCancel(force: true);
await methodChannel.dispose();
|
d100908a
吴启风
feat:解决练习切后台后音频未暂停问题
|
162
|
WidgetsBinding.instance.removeObserver(this);
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
163
164
165
|
return super.close();
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
166
|
///请求数据
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
167
168
|
void _requestData(
RequestDataEvent event, Emitter<TopicPictureState> emitter) async {
|
2eb67dd4
liangchengyou
feat:调整代码
|
169
|
try {
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
170
171
|
_entity = await ListenDao.process(courseLessonId);
emitter(RequestDataState());
|
2eb67dd4
liangchengyou
feat:调整代码
|
172
173
|
} catch (e) {
if (e is ApiException) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
174
|
showToast(e.message ?? '请求失败,请检查网络连接');
|
2eb67dd4
liangchengyou
feat:调整代码
|
175
176
177
178
|
}
}
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
179
|
///页面切换
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
180
181
|
void _pageControllerChange(CurrentPageIndexChangeEvent event,
Emitter<TopicPictureState> emitter) async {
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
182
|
await pageResetIfNeed();
|
8fb5f860
吴启风
feat:先声录音状态优化
|
183
|
Log.d('$TAG _pageControllerChange $_currentPage->${event.pageIndex}');
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
184
185
|
if (_currentPage == _entity?.topics?.length) {
return;
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
186
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
187
|
_currentPage = event.pageIndex;
|
2eb67dd4
liangchengyou
feat:调整代码
|
188
|
final topics = _entity?.topics?[_currentPage];
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
189
|
if (topics?.type != 3 && topics?.type != 4) {
|
2eb67dd4
liangchengyou
feat:调整代码
|
190
|
if (topics?.audioUrl != null) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
191
|
final urlStr = topics?.audioUrl ?? '';
|
2eb67dd4
liangchengyou
feat:调整代码
|
192
|
if (urlStr.isNotEmpty) {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
193
194
|
debugPrint(urlStr);
await audioPlayer.play(UrlSource(urlStr));
|
2eb67dd4
liangchengyou
feat:调整代码
|
195
196
|
}
}
|
2eb67dd4
liangchengyou
feat:调整代码
|
197
|
}
|
624214d0
liangchengyou
feat:看题选字/选图UI和部分逻辑
|
198
199
200
|
emitter(CurrentPageIndexState());
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
201
|
///选择
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
202
203
|
void _selectItemLoad(
SelectItemEvent event, Emitter<TopicPictureState> emitter) async {
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
204
205
206
207
208
|
_optionSelectItem = event.selectIndex;
emitter(SelectItemChangeState());
if (checkAnswerRight(_optionSelectItem) == true) {
/// 如果选择题答(选)对后题目没播完,则暂停播放题目。答错的话继续播放体验也不错
await closePlayerResource();
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
209
210
211
212
|
/// right音频长度比动效短,所以等动效完了再翻页
AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.right);
await showStarRewardDialog(context, onDismiss: () {
|
5989d250
吴启风
feat:体验优化-选择题选中边框...
|
213
|
_resetSelectItem();
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
214
215
|
autoFlipPage();
});
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
216
|
} else {
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
217
|
await AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.wrong);
|
5989d250
吴启风
feat:体验优化-选择题选中边框...
|
218
|
_resetSelectItem();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
219
|
}
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
220
|
}
|
2eb67dd4
liangchengyou
feat:调整代码
|
221
|
|
5989d250
吴启风
feat:体验优化-选择题选中边框...
|
222
223
224
225
226
227
228
|
///重置选择
void _selectItemReset(
SelectItemResetEvent event, Emitter<TopicPictureState> emitter) async {
///用于一次完整的选择后重置视图
emitter(SelectItemResetState());
}
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
229
230
231
|
///为空则数据异常,用于是否晃动时需要
bool? checkAnswerRight(int selectIndex) {
CourseProcessTopics? topics = _entity?.topics?[_currentPage];
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
232
233
234
235
|
if (topics == null ||
topics.topicAnswerList == null ||
selectIndex < 0 ||
selectIndex >= topics.topicAnswerList!.length) {
|
45c862fd
吴启风
feat:闯关交互优化-答错晃动、...
|
236
237
238
239
240
241
242
|
return null;
}
CourseProcessTopicsTopicAnswerList? answerList =
topics.topicAnswerList?[selectIndex];
return answerList?.correct != 0;
}
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
243
|
///驰声测试
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
244
245
|
void _voiceXsStart(
XSVoiceStartEvent event, Emitter<TopicPictureState> emitter) async {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
246
|
await audioPlayer.stop();
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
247
|
// 调用封装好的权限检查和请求方法
|
1e22b7d1
吴启风
feat:儿歌/视频环节接口请求时机优化
|
248
249
|
bool result = await requestPermission(
context, Permission.microphone, "录音", "用于开启录音,识别您的开口作答并给出反馈");
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
250
|
if (result) {
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
251
|
await methodChannel.invokeMethod('startVoice', {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
252
253
254
255
|
'word': event.testWord,
'type': event.type,
'userId': event.userId.toString()
});
|
354ac7e6
吴启风
feat:隐藏视频跟读入口、底部草...
|
256
|
}
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
257
258
|
}
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
259
|
///终止评测
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
260
|
Future<void> _voiceXsStop(
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
261
|
XSVoiceStopEvent event, Emitter<TopicPictureState> emitter) async {
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
262
|
await methodChannel.invokeMethod('stopVoice');
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
263
264
|
}
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
265
|
///取消评测(用于处理退出页面后录音未停止等异常情况的保护操作)
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
266
267
|
Future<void> _voiceXsCancel({bool force = false}) async {
if (_isRecording || force) {
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
268
|
await methodChannel.invokeMethod('cancelVoice');
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
269
|
}
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
270
271
|
}
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
272
|
///驰声评测结果
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
273
274
|
void _voiceXsResult(
XSVoiceResultEvent event, Emitter<TopicPictureState> emitter) async {
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
275
276
|
_isRecording = false;
emitter(XSVoiceTestState());
|
e3c2820c
liangchengyou
feat:先声SDK逻辑调整
|
277
|
final Map args = event.message as Map;
|
cb38bc90
liangchengyou
feat:视频跟读逻辑处理
|
278
279
|
final result = args['result'] as Map;
final overall = result['overall'].toString();
|
c623c7b2
吴启风
feat:语音跟读作答结果动效&语音
|
280
|
int score = int.parse(overall);
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
281
282
|
final voiceResult = VoiceResultType.fromScore(score);
if (voiceResult.lottieFilePath != null) {
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
283
|
AudioPlayerUtil.getInstance().playAudio(voiceResult.audioType);
|
0fa4e405
吴启风
feat: 将语音评测从先声迁移至驰声
|
284
285
|
await showCheerRewardDialog(context,
lottieFile: voiceResult.lottieFilePath!, onDismiss: () {
|
4f9b0fa4
吴启风
feat:语音跟读题90分以上增加...
|
286
|
autoFlipPageByVoice(score);
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
287
288
289
|
});
} else {
await AudioPlayerUtil.getInstance().playAudio(voiceResult.audioType);
|
4f9b0fa4
吴启风
feat:语音跟读题90分以上增加...
|
290
|
autoFlipPageByVoice(score);
|
642081ad
吴启风
feat:lottie动画加载优化...
|
291
|
}
|
642081ad
吴启风
feat:lottie动画加载优化...
|
292
293
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
294
|
// 暂时没用上
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
295
296
|
void _voicePlayStateChange(VoicePlayStateChangeEvent event,
Emitter<TopicPictureState> emitter) async {
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
297
298
299
|
emitter(VoicePlayStateChange());
}
|
8fb5f860
吴启风
feat:先声录音状态优化
|
300
301
302
303
|
bool isAudioPlaying() {
return audioPlayer.state == PlayerState.playing;
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
304
|
// 题目音频播放
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
305
306
|
void _questionVoicePlay(
VoicePlayEvent event, Emitter<TopicPictureState> emitter) async {
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
307
|
await pageResetIfNeed();
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
308
|
final topics = _entity?.topics?[_currentPage];
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
309
310
311
|
final urlStr = topics?.audioUrl ?? '';
await audioPlayer.play(UrlSource(urlStr),
balance: 0.0, ctx: AudioContext());
|
3c1d5c64
liangchengyou
feat:练习功能完成
|
312
|
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
313
|
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
314
315
316
317
|
/// 重置状态,音频播放、录音以及一些变量等。用于翻页,打断等场景
Future<void> pageResetIfNeed() async {
_optionSelectItem = -1;
_isRecording = false;
|
819ae43b
吴启风
feat:体验优化-练习题目取消阻...
|
318
319
320
321
322
|
await closePlayerResource();
await _voiceXsCancel();
}
|
5989d250
吴启风
feat:体验优化-选择题选中边框...
|
323
324
325
326
327
|
void _resetSelectItem() {
_optionSelectItem = -1;
add(SelectItemResetEvent());
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
328
|
Future<void> closePlayerResource() async {
|
8fb5f860
吴启风
feat:先声录音状态优化
|
329
|
if (isAudioPlaying()) {
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
330
331
|
await audioPlayer.stop();
}
|
aeafd474
吴启风
feat:选择题作答后播放音效&答...
|
332
333
|
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
334
335
336
337
338
|
///是否是最后一页
bool isLastPage() {
return currentPage == _entity?.topics?.length;
}
|
951eb853
吴启风
feat:代码优化-星星等动效对话...
|
339
340
341
342
343
344
345
346
347
348
349
350
351
|
///自动翻页
void autoFlipPage() {
if (isLastPage()) {
showStepPage();
} else {
// 答对后且播放完自动翻页
pageController.nextPage(
duration: const Duration(milliseconds: 250),
curve: Curves.ease,
);
}
}
|
4f9b0fa4
吴启风
feat:语音跟读题90分以上增加...
|
352
353
354
355
356
357
358
359
360
361
362
363
|
///语音题自动翻页
///90分以上自动翻页
void autoFlipPageByVoice(int score) {
if (score >= 90) {
autoFlipPage();
} else {
if (isLastPage()) {
showStepPage();
}
}
}
|
22f36232
吴启风
feat:过渡页-练习环节
|
364
365
366
367
|
///展示过渡页
void showStepPage() {
///如果最后一页是语音问答题,评测完后自动翻页
sectionComplete(() {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
368
369
370
371
372
373
|
popPage(data: {
'currentStep': currentPage,
'courseLessonId': courseLessonId,
'isCompleted': true,
'nextSection': true
});
|
22f36232
吴启风
feat:过渡页-练习环节
|
374
|
}, againSectionTap: () {
|
22f36232
吴启风
feat:过渡页-练习环节
|
375
376
377
|
pageController.jumpToPage(0);
});
}
|
7652f701
liangchengyou
feat:课程购买UI逻辑
|
378
|
}
|