Commit e3c2820cfc9977f7aa833d1d7930557fb8a37347

Authored by liangchengyou
1 parent aa4e28be

feat:先声SDK逻辑调整

ios/Runner.xcodeproj/project.pbxproj
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 10 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 11 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
12 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
  13 + 52450AF12A4C415B007B3E4B /* XSMessageMehtodChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */; };
13 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */; }; 14 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */; };
14 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
15 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
@@ -52,6 +53,7 @@ @@ -52,6 +53,7 @@
52 3563EC8D55A646823FD26A83 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 53 3563EC8D55A646823FD26A83 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
53 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 54 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
54 48BCA0827DCB98991774F5AC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; }; 55 48BCA0827DCB98991774F5AC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
  56 + 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSMessageMehtodChannel.swift; sourceTree = "<group>"; };
55 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceXSMessageChannel.swift; sourceTree = "<group>"; }; 57 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceXSMessageChannel.swift; sourceTree = "<group>"; };
56 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 58 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
57 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 59 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -152,6 +154,7 @@ @@ -152,6 +154,7 @@
152 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 154 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
153 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 155 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
154 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 156 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
  157 + 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */,
155 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */, 158 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */,
156 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 159 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
157 ); 160 );
@@ -397,6 +400,7 @@ @@ -397,6 +400,7 @@
397 buildActionMask = 2147483647; 400 buildActionMask = 2147483647;
398 files = ( 401 files = (
399 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */, 402 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */,
  403 + 52450AF12A4C415B007B3E4B /* XSMessageMehtodChannel.swift in Sources */,
400 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 404 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
401 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 405 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
402 ); 406 );
ios/Runner/AppDelegate.swift
@@ -10,6 +10,7 @@ import Flutter @@ -10,6 +10,7 @@ import Flutter
10 GeneratedPluginRegistrant.register(with: self) 10 GeneratedPluginRegistrant.register(with: self)
11 let controller : FlutterViewController = window?.rootViewController as! FlutterViewController 11 let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
12 _ = VoiceXSMessageChannel(messager: controller.binaryMessenger) 12 _ = VoiceXSMessageChannel(messager: controller.binaryMessenger)
  13 + _ = XSMessageMehtodChannel(message: controller.binaryMessenger);
13 return super.application(application, didFinishLaunchingWithOptions: launchOptions) 14 return super.application(application, didFinishLaunchingWithOptions: launchOptions)
14 } 15 }
15 } 16 }
ios/Runner/XSMessageMehtodChannel.swift 0 → 100644
  1 +//
  2 +// XSMessageMehtodChannel.swift
  3 +// Runner
  4 +//
  5 +// Created by MacBook Pro on 2023/6/28.
  6 +//
  7 +
  8 +import UIKit
  9 +
  10 +class XSMessageMehtodChannel: NSObject,SSOralEvaluatingManagerDelegate {
  11 + var resultData:Dictionary<String, Any>?
  12 + var messageChannel:FlutterMethodChannel?
  13 + init(message:FlutterBinaryMessenger) {
  14 + super.init()
  15 + resultData = Dictionary()
  16 + messageChannel = FlutterMethodChannel.init(name: "wow_english/sing_sound_method_channely", binaryMessenger: message)
  17 + messageChannel!.setMethodCallHandler { call, result in
  18 + self.handle(call, result)
  19 + }
  20 + }
  21 +
  22 + //配置评测信息
  23 + func setEvaluateConfig(dict:Dictionary<String, Any>) {
  24 + let appKey = dict["appKey"] as? String
  25 + let secretKey = dict["secretKey"] as? String
  26 + let userId = dict.keys.contains("userId") ? dict["userId"] as! String:""
  27 + let frontTime = dict["frontTime"] as? TimeInterval
  28 + let backTime = dict["frontTime"] as? TimeInterval
  29 + let config = SSOralEvaluatingManagerConfig.init()
  30 + config.appKey = appKey //"a418"
  31 + config.secretKey = secretKey //"1a16f31f2611bf32fb7b3fc38f5b2c81"'
  32 + config.frontTime = frontTime ?? 3
  33 + config.backTime = backTime ?? 3
  34 + SSOralEvaluatingManager.register(config)
  35 + SSOralEvaluatingManager.share().register(.line, userId: userId)
  36 + SSOralEvaluatingManager.share().delegate = self
  37 + }
  38 +
  39 + //开始评测
  40 + func evaluateVioce(dict:Dictionary<String, Any>) {
  41 + let text = dict["word"] as! String
  42 + let type = dict["type"] as! Int
  43 + let userId = dict["userId"] as! String
  44 + let config = SSOralEvaluatingConfig()
  45 + config.oralContent = text
  46 + if (type == 0) {
  47 + config.oralType = .word
  48 + } else {
  49 + config.oralType = .sentence
  50 + }
  51 + config.userId = userId
  52 + SSOralEvaluatingManager.share().startEvaluateOral(with: config)
  53 + }
  54 +
  55 + func handle(_ call: FlutterMethodCall,_ result: @escaping FlutterResult) {
  56 + if (call.method == "initVoiceSdk") {
  57 + self.setEvaluateConfig(dict:call.arguments as! Dictionary<String, Any>)
  58 + return
  59 + }
  60 + if (call.method == "starVoice") {
  61 + self.evaluateVioce(dict: call.arguments as! Dictionary<String, Any>)
  62 + return
  63 + }
  64 +
  65 + if (call.method == "stopVoice") {
  66 + SSOralEvaluatingManager.share().stopEvaluate();
  67 + return
  68 + }
  69 + }
  70 +
  71 + //评测结果回调
  72 + func evaluateResult() {
  73 + messageChannel!.invokeMethod("voiceResult", arguments: resultData)
  74 + }
  75 +
  76 + //SSOralEvaluatingManagerDelegate
  77 + /**
  78 + 评测开始
  79 + */
  80 + func oralEvaluatingDidStart() {
  81 + print("评测开始")
  82 + messageChannel!.invokeMethod("voiceStart", arguments: nil)
  83 + }
  84 +
  85 + /**
  86 + 评测停止
  87 + */
  88 + func oralEvaluatingDidStop() {
  89 + print("评测结束")
  90 + messageChannel!.invokeMethod("voiceEnd",arguments: nil)
  91 + }
  92 +
  93 + /**
  94 + 评测完成后的结果
  95 + */
  96 + func oralEvaluatingDidEnd(withResult result: [AnyHashable : Any]?, requestId request_id: String?) {
  97 + print("评测完成结果")
  98 + let resultDict:Dictionary<String, Any> = result?["result"] as! Dictionary
  99 + resultData!["result"] = "1"
  100 + //分数
  101 + resultData!["overall"] = resultDict["overall"]
  102 + self.evaluateResult()
  103 + }
  104 +
  105 + /**
  106 + 评测失败回调
  107 + */
  108 + func oralEvaluatingDidEndError(_ error: Error?, requestId request_id: String?) {
  109 + print("评测失败")
  110 + messageChannel!.invokeMethod("voiceFail", arguments: error?.localizedDescription)
  111 + }
  112 +
  113 + /**
  114 + VAD(前置时间)超时回调
  115 + */
  116 + func oralEvaluatingDidVADFrontTimeOut() {
  117 + print("前置超时--->取消")
  118 + SSOralEvaluatingManager.share().cancelEvaluate()
  119 + if(resultData?.keys.count == 0) {
  120 + resultData!["result"] = "0"
  121 + self.evaluateResult();
  122 + }
  123 + }
  124 +
  125 + /**
  126 + VAD(后置时间)超时回调
  127 + */
  128 + func oralEvaluatingDidVADBackTimeOut() {
  129 + print("后置超时--->结束")
  130 + ///结束回调
  131 + SSOralEvaluatingManager.share().stopEvaluate();
  132 + }
  133 +}
lib/pages/home/home_page.dart
@@ -40,11 +40,6 @@ class _HomePageView extends StatelessWidget { @@ -40,11 +40,6 @@ class _HomePageView extends StatelessWidget {
40 Navigator.of(AppRouter.context).pushNamed(AppRouteName.user); 40 Navigator.of(AppRouter.context).pushNamed(AppRouteName.user);
41 } else { 41 } else {
42 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic); 42 // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic);
43 - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicWord);  
44 - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.lookVideo);  
45 - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.voicePic);  
46 - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.voiceWord);  
47 - Navigator.of(AppRouter.context).pushNamed(AppRouteName.voiceAnswer);  
48 } 43 }
49 } 44 }
50 45
lib/pages/practice/bloc/topic_picture_bloc.dart
@@ -35,19 +35,34 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -35,19 +35,34 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
35 35
36 bool get isVoicing => _isVoicing; 36 bool get isVoicing => _isVoicing;
37 37
38 - var messageChannel = const BasicMessageChannel('com.owEnglish.voiceXs.BasicMessageChannel', StandardMessageCodec()); 38 + late MethodChannel methodChannel;
39 39
40 - final audioPlayer = AudioPlayer(); 40 + late AudioPlayer audioPlayer;
41 41
42 TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) { 42 TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) {
43 on<CurrentPageIndexChangeEvent>(_pageControllerChange); 43 on<CurrentPageIndexChangeEvent>(_pageControllerChange);
44 - on<InitMessageChannelEvent>(_initMessageChannelCall);  
45 - on<RequestDataEvent>(_requestData);  
46 on<SelectItemEvent>(_selectItemLoad); 44 on<SelectItemEvent>(_selectItemLoad);
47 - on<VoiceXsTestEvent>(_voiceXsTest);  
48 - on<VoiceResultEvent>(_voiceResult); 45 + on<RequestDataEvent>(_requestData);
  46 + on<XSVoiceTestEvent>(_voiceXsTest);
  47 + on<XSVoiceResultEvent>(_voiceXsResult);
  48 + on<XSVoiceInitEvent>(_initVoiceSdk);
49 on<TopicPictureEvent>((event, emit) { 49 on<TopicPictureEvent>((event, emit) {
  50 + //音频播放器
  51 + audioPlayer = AudioPlayer();
  52 + audioPlayer.onPlayerStateChanged.listen((event) {
  53 + if (event == PlayerState.stopped) {
  54 +
  55 + }
  56 + });
  57 +
50 58
  59 + methodChannel = const MethodChannel('wow_english/sing_sound_method_channely');
  60 + methodChannel.invokeMethod('initVoiceSdk',{});
  61 + methodChannel.setMethodCallHandler((call) async {
  62 + if (call.method == 'voiceResult') {//评测结束
  63 + add(XSVoiceResultEvent(call.arguments));
  64 + }
  65 + });
51 }); 66 });
52 } 67 }
53 68
@@ -58,6 +73,7 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -58,6 +73,7 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
58 return super.close(); 73 return super.close();
59 } 74 }
60 75
  76 + ///请求数据
61 void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async { 77 void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async {
62 try { 78 try {
63 await loading(() async { 79 await loading(() async {
@@ -71,6 +87,12 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -71,6 +87,12 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
71 } 87 }
72 } 88 }
73 89
  90 + ///初始化SDK
  91 + _initVoiceSdk(XSVoiceInitEvent event,Emitter<TopicPictureState> emitter) async {
  92 + methodChannel.invokeMethod('initVoiceSdk',event.data);
  93 + }
  94 +
  95 + ///页面切换
74 void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { 96 void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async {
75 _currentPage = event.pageIndex; 97 _currentPage = event.pageIndex;
76 final topics = _entity?.topics?[_currentPage]; 98 final topics = _entity?.topics?[_currentPage];
@@ -87,15 +109,25 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -87,15 +109,25 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
87 emitter(CurrentPageIndexState()); 109 emitter(CurrentPageIndexState());
88 } 110 }
89 111
  112 + ///选择
90 void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async { 113 void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async {
91 _selectItem = event.selectIndex; 114 _selectItem = event.selectIndex;
92 emitter(SelectItemChangeState()); 115 emitter(SelectItemChangeState());
93 } 116 }
94 117
95 - ///messageChannel回调  
96 - Future messageResultHandler(message,Emitter<TopicPictureState> emitter) async {  
97 - EasyLoading.dismiss();  
98 - final Map args = message as Map; 118 + ///先声测试
  119 + void _voiceXsTest(XSVoiceTestEvent event,Emitter<TopicPictureState> emitter) async {
  120 + EasyLoading.show(status: '录音中....');
  121 + methodChannel.invokeMethod(
  122 + 'startRecord',
  123 + {'word':event.testWord,'type':event.type,'userId':event.userId.toString()}
  124 + );
  125 + _isVoicing = true;
  126 + emitter(XSVoiceTestState());
  127 + }
  128 +
  129 + void _voiceXsResult(XSVoiceResultEvent event,Emitter<TopicPictureState> emitter) async {
  130 + final Map args = event.message as Map;
99 final result = args['result'] as String; 131 final result = args['result'] as String;
100 if (result == '1') { 132 if (result == '1') {
101 final overall = args['overall'].toString(); 133 final overall = args['overall'].toString();
@@ -103,35 +135,7 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -103,35 +135,7 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
103 } else { 135 } else {
104 EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10)); 136 EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10));
105 } 137 }
106 - if (kDebugMode) {  
107 - print('是否被移除>>>>>$emitter');  
108 - }  
109 - _isVoicing = false;  
110 - }  
111 -  
112 - Future _initMessageChannelCall(InitMessageChannelEvent event,Emitter<TopicPictureState> emitter) async {  
113 - messageChannel.setMessageHandler((message) =>  
114 - messageResultHandler(message, emitter)  
115 - );  
116 -  
117 - audioPlayer.onPlayerStateChanged.listen((event) {  
118 - if (event == PlayerState.stopped) {  
119 - if (kDebugMode) {  
120 - print('播放结束');  
121 - }  
122 - }  
123 - });  
124 - }  
125 -  
126 - void _voiceXsTest(VoiceXsTestEvent event,Emitter<TopicPictureState> emitter) async {  
127 - EasyLoading.show(status: '录音中....');  
128 - messageChannel.send({'word':event.testWord,'type':event.type,'userId':event.userId.toString()});  
129 - _isVoicing = true;  
130 - emitter(VoiceXsTestState());  
131 - }  
132 -  
133 - void _voiceResult(VoiceResultEvent event,Emitter<TopicPictureState> emitter) async {  
134 _isVoicing = false; 138 _isVoicing = false;
135 - emitter(VoiceXsTestState()); 139 + emitter(XSVoiceTestState());
136 } 140 }
137 } 141 }
lib/pages/practice/bloc/topic_picture_event.dart
@@ -5,17 +5,24 @@ abstract class TopicPictureEvent {} @@ -5,17 +5,24 @@ abstract class TopicPictureEvent {}
5 5
6 class RequestDataEvent extends TopicPictureEvent {} 6 class RequestDataEvent extends TopicPictureEvent {}
7 7
8 -///初始化消息回调  
9 -class InitMessageChannelEvent extends TopicPictureEvent {} 8 +///初始化先声SDK
  9 +class XSVoiceInitEvent extends TopicPictureEvent {
  10 + final Map data;
  11 + XSVoiceInitEvent(this.data);
  12 +}
10 13
11 -class VoiceResultEvent extends TopicPictureEvent {} 14 +///评测结果
  15 +class XSVoiceResultEvent extends TopicPictureEvent {
  16 + final dynamic message;
  17 + XSVoiceResultEvent(this.message);
  18 +}
12 19
13 ///先声测试 20 ///先声测试
14 -class VoiceXsTestEvent extends TopicPictureEvent { 21 +class XSVoiceTestEvent extends TopicPictureEvent {
15 final String testWord; 22 final String testWord;
16 final int type; 23 final int type;
17 final int userId; 24 final int userId;
18 - VoiceXsTestEvent(this.testWord,this.type,this.userId); 25 + XSVoiceTestEvent(this.testWord,this.type,this.userId);
19 } 26 }
20 27
21 class CurrentPageIndexChangeEvent extends TopicPictureEvent { 28 class CurrentPageIndexChangeEvent extends TopicPictureEvent {
lib/pages/practice/bloc/topic_picture_state.dart
@@ -5,7 +5,7 @@ abstract class TopicPictureState {} @@ -5,7 +5,7 @@ abstract class TopicPictureState {}
5 5
6 class RequestDataState extends TopicPictureState {} 6 class RequestDataState extends TopicPictureState {}
7 7
8 -class VoiceXsTestState extends TopicPictureState {} 8 +class XSVoiceTestState extends TopicPictureState {}
9 9
10 class TopicPictureInitial extends TopicPictureState {} 10 class TopicPictureInitial extends TopicPictureState {}
11 11
lib/pages/practice/topic_picture_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 -import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart'; 4 +import 'package:wow_english/common/core/user_util.dart';
5 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
6 import 'package:wow_english/common/widgets/ow_image_widget.dart'; 6 import 'package:wow_english/common/widgets/ow_image_widget.dart';
7 import 'package:wow_english/models/course_process_entity.dart'; 7 import 'package:wow_english/models/course_process_entity.dart';
@@ -20,7 +20,13 @@ class TopicPicturePage extends StatelessWidget { @@ -20,7 +20,13 @@ class TopicPicturePage extends StatelessWidget {
20 3 20 3
21 ) 21 )
22 ..add(RequestDataEvent()) 22 ..add(RequestDataEvent())
23 - ..add(InitMessageChannelEvent()), 23 + ..add(XSVoiceInitEvent(
  24 + {
  25 + 'appKey':'a418',
  26 + 'secretKey':'1a16f31f2611bf32fb7b3fc38f5b2c81',
  27 + 'userId':UserUtil.getUser()!.id
  28 + }
  29 + )),
24 child: _TopicPicturePage(), 30 child: _TopicPicturePage(),
25 ); 31 );
26 } 32 }
@@ -32,7 +38,11 @@ class _TopicPicturePage extends StatelessWidget { @@ -32,7 +38,11 @@ class _TopicPicturePage extends StatelessWidget {
32 return BlocListener<TopicPictureBloc,TopicPictureState>( 38 return BlocListener<TopicPictureBloc,TopicPictureState>(
33 listener: (context, state){ 39 listener: (context, state){
34 if (state is RequestDataState) { 40 if (state is RequestDataState) {
35 - context.read<TopicPictureBloc>().add(CurrentPageIndexChangeEvent(0)); 41 + // context.read<TopicPictureBloc>().add(CurrentPageIndexChangeEvent(0));
  42 + }
  43 +
  44 + if (state is XSVoiceTestState) {
  45 +
36 } 46 }
37 }, 47 },
38 child: _topicPictureView(), 48 child: _topicPictureView(),
@@ -50,7 +60,10 @@ class _TopicPicturePage extends StatelessWidget { @@ -50,7 +60,10 @@ class _TopicPicturePage extends StatelessWidget {
50 children: [ 60 children: [
51 PracticeHeaderWidget( 61 PracticeHeaderWidget(
52 title: '${bloc.currentPage}/${bloc.entity?.topics?.length}', 62 title: '${bloc.currentPage}/${bloc.entity?.topics?.length}',
53 - onTap: (){Navigator.pop(context);}, 63 + onTap: (){
  64 + bloc.add(XSVoiceTestEvent('Hello', 0,UserUtil.getUser()!.id));
  65 + // Navigator.pop(context);
  66 + },
54 ), 67 ),
55 Expanded( 68 Expanded(
56 child: PageView.builder( 69 child: PageView.builder(
@@ -332,27 +345,6 @@ class _TopicPicturePage extends StatelessWidget { @@ -332,27 +345,6 @@ class _TopicPicturePage extends StatelessWidget {
332 return _decodeVoiceWordImageWidget(index, topics!.topicAnswerList![index]); 345 return _decodeVoiceWordImageWidget(index, topics!.topicAnswerList![index]);
333 }), 346 }),
334 ), 347 ),
335 - // Row(  
336 - // mainAxisAlignment: MainAxisAlignment.spaceBetween,  
337 - // children: [  
338 - // Offstage(  
339 - // offstage: topics.topicAnswerList!.length <= 1,  
340 - // child: _decodeVoiceWordImageWidget(1,topics.topicAnswerList![0]),  
341 - // ),  
342 - // Offstage(  
343 - // offstage: topics.topicAnswerList!.length <= 2,  
344 - // child: _decodeVoiceWordImageWidget(2,topics.topicAnswerList![1]),  
345 - // ),  
346 - // // Offstage(  
347 - // // offstage: topics.topicAnswerList!.length <= 3,  
348 - // // child: _decodeVoiceWordImageWidget(3,topics.topicAnswerList![2]),  
349 - // // ),  
350 - // // Offstage(  
351 - // // offstage: topics.topicAnswerList!.length <= 4,  
352 - // // child: _decodeVoiceWordImageWidget(4,topics.topicAnswerList![3]),  
353 - // // )  
354 - // ],  
355 - // )  
356 ], 348 ],
357 ), 349 ),
358 ); 350 );
@@ -443,7 +435,7 @@ class _TopicPicturePage extends StatelessWidget { @@ -443,7 +435,7 @@ class _TopicPicturePage extends StatelessWidget {
443 if (bloc.isVoicing) { 435 if (bloc.isVoicing) {
444 return; 436 return;
445 } 437 }
446 - bloc.add(VoiceXsTestEvent('Hello', 0,context.read<CacheBloc>().userEntity!.id)); 438 + bloc.add(XSVoiceTestEvent('Hello', 0,UserUtil.getUser()!.id));
447 }, 439 },
448 child: Image.asset( 440 child: Image.asset(
449 'micro_phone'.assetPng, 441 'micro_phone'.assetPng,