Commit 2eb67dd4fdb548124043dfb1c9d37a681b349ea4
1 parent
4b2c2f07
feat:调整代码
Showing
13 changed files
with
937 additions
and
258 deletions
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 | + 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */; }; | ||
| 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; | 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; |
| 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; |
| 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; | 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; |
| @@ -51,6 +52,7 @@ | @@ -51,6 +52,7 @@ | ||
| 51 | 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>"; }; | 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>"; }; |
| 52 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | 53 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; |
| 53 | 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>"; }; | 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 | + 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceXSMessageChannel.swift; sourceTree = "<group>"; }; | ||
| 54 | 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 56 | 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 55 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | 57 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; |
| 56 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | 58 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; |
| @@ -150,6 +152,7 @@ | @@ -150,6 +152,7 @@ | ||
| 150 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | 152 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, |
| 151 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | 153 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, |
| 152 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, | 154 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, |
| 155 | + 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */, | ||
| 153 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, | 156 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, |
| 154 | ); | 157 | ); |
| 155 | path = Runner; | 158 | path = Runner; |
| @@ -393,6 +396,7 @@ | @@ -393,6 +396,7 @@ | ||
| 393 | isa = PBXSourcesBuildPhase; | 396 | isa = PBXSourcesBuildPhase; |
| 394 | buildActionMask = 2147483647; | 397 | buildActionMask = 2147483647; |
| 395 | files = ( | 398 | files = ( |
| 399 | + 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */, | ||
| 396 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, | 400 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, |
| 397 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | 401 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, |
| 398 | ); | 402 | ); |
ios/Runner/AppDelegate.swift
| @@ -3,11 +3,13 @@ import Flutter | @@ -3,11 +3,13 @@ import Flutter | ||
| 3 | 3 | ||
| 4 | @UIApplicationMain | 4 | @UIApplicationMain |
| 5 | @objc class AppDelegate: FlutterAppDelegate { | 5 | @objc class AppDelegate: FlutterAppDelegate { |
| 6 | - override func application( | ||
| 7 | - _ application: UIApplication, | ||
| 8 | - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||
| 9 | - ) -> Bool { | ||
| 10 | - GeneratedPluginRegistrant.register(with: self) | ||
| 11 | - return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||
| 12 | - } | 6 | + override func application( |
| 7 | + _ application: UIApplication, | ||
| 8 | + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||
| 9 | + ) -> Bool { | ||
| 10 | + GeneratedPluginRegistrant.register(with: self) | ||
| 11 | + let controller : FlutterViewController = window?.rootViewController as! FlutterViewController | ||
| 12 | + _ = VoiceXSMessageChannel(messager: controller.binaryMessenger) | ||
| 13 | + return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||
| 14 | + } | ||
| 13 | } | 15 | } |
ios/Runner/Runner-Bridging-Header.h
ios/Runner/VoiceXSMessageChannel.swift
0 → 100644
| 1 | +// | ||
| 2 | +// VoiceXSMessageChannel.swift | ||
| 3 | +// Runner | ||
| 4 | +// | ||
| 5 | +// Created by MacBook Pro on 2023/6/28. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +import UIKit | ||
| 9 | + | ||
| 10 | +class VoiceXSMessageChannel: NSObject,SSOralEvaluatingManagerDelegate { | ||
| 11 | + var resultData:Dictionary<String, Any>? | ||
| 12 | + var channel:FlutterBasicMessageChannel? | ||
| 13 | + init(messager:FlutterBinaryMessenger) { | ||
| 14 | + super.init() | ||
| 15 | + resultData = Dictionary() | ||
| 16 | + self.setEvaluateConfig() | ||
| 17 | + channel = FlutterBasicMessageChannel(name: "com.owEnglish.voiceXs.BasicMessageChannel", binaryMessenger: messager) | ||
| 18 | + channel!.setMessageHandler { message, reply in | ||
| 19 | + if let dict = message as? Dictionary<String, Any> { | ||
| 20 | + self.evaluateVioce(dict: dict); | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + //配置评测信息 | ||
| 26 | + func setEvaluateConfig() { | ||
| 27 | + let config = SSOralEvaluatingManagerConfig.init() | ||
| 28 | + config.appKey = "a418" | ||
| 29 | + config.secretKey = "1a16f31f2611bf32fb7b3fc38f5b2c81" | ||
| 30 | + config.vad = true | ||
| 31 | + config.frontTime = 3 | ||
| 32 | + config.backTime = 3 | ||
| 33 | + config.isOutputLog = false | ||
| 34 | + SSOralEvaluatingManager.register(config) | ||
| 35 | + SSOralEvaluatingManager.share().register(.line, userId: "321") | ||
| 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 | + //评测结果回调 | ||
| 56 | + func evaluateResult() { | ||
| 57 | + channel!.sendMessage(resultData) {(reply) in | ||
| 58 | + self.resultData?.removeAll() | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + //SSOralEvaluatingManagerDelegate | ||
| 63 | + /** | ||
| 64 | + 评测开始 | ||
| 65 | + */ | ||
| 66 | + func oralEvaluatingDidStart() { | ||
| 67 | + print("评测开始") | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + 评测停止 | ||
| 72 | + */ | ||
| 73 | + func oralEvaluatingDidStop() { | ||
| 74 | + print("评测结束") | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + 评测完成后的结果 | ||
| 79 | + */ | ||
| 80 | + func oralEvaluatingDidEnd(withResult result: [AnyHashable : Any]?, requestId request_id: String?) { | ||
| 81 | + print("评测完成结果") | ||
| 82 | + let resultDict:Dictionary<String, Any> = result?["result"] as! Dictionary | ||
| 83 | + resultData!["result"] = "1" | ||
| 84 | + //分数 | ||
| 85 | + resultData!["overall"] = resultDict["overall"] | ||
| 86 | + self.evaluateResult() | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + 评测失败回调 | ||
| 91 | + */ | ||
| 92 | + func oralEvaluatingDidEndError(_ error: Error?, requestId request_id: String?) { | ||
| 93 | + print("评测失败") | ||
| 94 | + resultData!["result"] = "0" | ||
| 95 | + self.evaluateResult() | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + /** | ||
| 99 | + VAD(前置时间)超时回调 | ||
| 100 | + */ | ||
| 101 | + func oralEvaluatingDidVADFrontTimeOut() { | ||
| 102 | + print("前置超时--->取消") | ||
| 103 | + SSOralEvaluatingManager.share().cancelEvaluate() | ||
| 104 | + if(resultData?.keys.count == 0) { | ||
| 105 | + resultData!["result"] = "0" | ||
| 106 | + self.evaluateResult(); | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + /** | ||
| 111 | + VAD(后置时间)超时回调 | ||
| 112 | + */ | ||
| 113 | + func oralEvaluatingDidVADBackTimeOut() { | ||
| 114 | + print("后置超时--->结束") | ||
| 115 | + ///结束回调 | ||
| 116 | + SSOralEvaluatingManager.share().stopEvaluate(); | ||
| 117 | + } | ||
| 118 | +} |
lib/common/request/dao/listen_dao.dart
| 1 | import 'package:wow_english/common/request/request_client.dart'; | 1 | import 'package:wow_english/common/request/request_client.dart'; |
| 2 | +import 'package:wow_english/models/course_process_entity.dart'; | ||
| 2 | import 'package:wow_english/models/follow_read_entity.dart'; | 3 | import 'package:wow_english/models/follow_read_entity.dart'; |
| 3 | import 'package:wow_english/models/listen_entity.dart'; | 4 | import 'package:wow_english/models/listen_entity.dart'; |
| 4 | 5 | ||
| @@ -14,4 +15,10 @@ class ListenDao { | @@ -14,4 +15,10 @@ class ListenDao { | ||
| 14 | var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead); | 15 | var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead); |
| 15 | return data; | 16 | return data; |
| 16 | } | 17 | } |
| 18 | + | ||
| 19 | + ///课程内容 | ||
| 20 | + static Future<CourseProcessEntity?> process(courseLessonId) async { | ||
| 21 | + var data = await requestClient.get<CourseProcessEntity>(Apis.process,queryParameters: {'courseLessonId':courseLessonId}); | ||
| 22 | + return data; | ||
| 23 | + } | ||
| 17 | } | 24 | } |
lib/generated/json/base/json_convert_content.dart
| @@ -4,9 +4,10 @@ | @@ -4,9 +4,10 @@ | ||
| 4 | 4 | ||
| 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. | 5 | // This file is automatically generated. DO NOT EDIT, all your changes would be lost. |
| 6 | import 'package:flutter/material.dart' show debugPrint; | 6 | import 'package:flutter/material.dart' show debugPrint; |
| 7 | -import 'package:wow_english/models/follow_read_entity.dart'; | ||
| 8 | import 'package:wow_english/models/course_entity.dart'; | 7 | import 'package:wow_english/models/course_entity.dart'; |
| 9 | import 'package:wow_english/models/course_module_entity.dart'; | 8 | import 'package:wow_english/models/course_module_entity.dart'; |
| 9 | +import 'package:wow_english/models/course_process_entity.dart'; | ||
| 10 | +import 'package:wow_english/models/follow_read_entity.dart'; | ||
| 10 | import 'package:wow_english/models/listen_entity.dart'; | 11 | import 'package:wow_english/models/listen_entity.dart'; |
| 11 | import 'package:wow_english/models/user_entity.dart'; | 12 | import 'package:wow_english/models/user_entity.dart'; |
| 12 | 13 | ||
| @@ -16,10 +17,15 @@ typedef EnumConvertFunction<T> = T Function(String value); | @@ -16,10 +17,15 @@ typedef EnumConvertFunction<T> = T Function(String value); | ||
| 16 | 17 | ||
| 17 | class JsonConvert { | 18 | class JsonConvert { |
| 18 | static final Map<String, JsonConvertFunction> convertFuncMap = { | 19 | static final Map<String, JsonConvertFunction> convertFuncMap = { |
| 19 | - (FollowReadEntity).toString(): FollowReadEntity.fromJson, | ||
| 20 | (CourseEntity).toString(): CourseEntity.fromJson, | 20 | (CourseEntity).toString(): CourseEntity.fromJson, |
| 21 | (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, | 21 | (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, |
| 22 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, | 22 | (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, |
| 23 | + (CourseProcessEntity).toString(): CourseProcessEntity.fromJson, | ||
| 24 | + (CourseProcessReadings).toString(): CourseProcessReadings.fromJson, | ||
| 25 | + (CourseProcessTopics).toString(): CourseProcessTopics.fromJson, | ||
| 26 | + (CourseProcessTopicsTopicAnswerList).toString(): CourseProcessTopicsTopicAnswerList.fromJson, | ||
| 27 | + (CourseProcessVideos).toString(): CourseProcessVideos.fromJson, | ||
| 28 | + (FollowReadEntity).toString(): FollowReadEntity.fromJson, | ||
| 23 | (ListenEntity).toString(): ListenEntity.fromJson, | 29 | (ListenEntity).toString(): ListenEntity.fromJson, |
| 24 | (UserEntity).toString(): UserEntity.fromJson, | 30 | (UserEntity).toString(): UserEntity.fromJson, |
| 25 | }; | 31 | }; |
| @@ -100,9 +106,6 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -100,9 +106,6 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
| 100 | 106 | ||
| 101 | //list is returned by type | 107 | //list is returned by type |
| 102 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { | 108 | static M? _getListChildType<M>(List<Map<String, dynamic>> data) { |
| 103 | - if(<FollowReadEntity>[] is M){ | ||
| 104 | - return data.map<FollowReadEntity>((Map<String, dynamic> e) => FollowReadEntity.fromJson(e)).toList() as M; | ||
| 105 | - } | ||
| 106 | if(<CourseEntity>[] is M){ | 109 | if(<CourseEntity>[] is M){ |
| 107 | return data.map<CourseEntity>((Map<String, dynamic> e) => CourseEntity.fromJson(e)).toList() as M; | 110 | return data.map<CourseEntity>((Map<String, dynamic> e) => CourseEntity.fromJson(e)).toList() as M; |
| 108 | } | 111 | } |
| @@ -112,6 +115,24 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -112,6 +115,24 @@ List<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | ||
| 112 | if(<CourseModuleEntity>[] is M){ | 115 | if(<CourseModuleEntity>[] is M){ |
| 113 | return data.map<CourseModuleEntity>((Map<String, dynamic> e) => CourseModuleEntity.fromJson(e)).toList() as M; | 116 | return data.map<CourseModuleEntity>((Map<String, dynamic> e) => CourseModuleEntity.fromJson(e)).toList() as M; |
| 114 | } | 117 | } |
| 118 | + if(<CourseProcessEntity>[] is M){ | ||
| 119 | + return data.map<CourseProcessEntity>((Map<String, dynamic> e) => CourseProcessEntity.fromJson(e)).toList() as M; | ||
| 120 | + } | ||
| 121 | + if(<CourseProcessReadings>[] is M){ | ||
| 122 | + return data.map<CourseProcessReadings>((Map<String, dynamic> e) => CourseProcessReadings.fromJson(e)).toList() as M; | ||
| 123 | + } | ||
| 124 | + if(<CourseProcessTopics>[] is M){ | ||
| 125 | + return data.map<CourseProcessTopics>((Map<String, dynamic> e) => CourseProcessTopics.fromJson(e)).toList() as M; | ||
| 126 | + } | ||
| 127 | + if(<CourseProcessTopicsTopicAnswerList>[] is M){ | ||
| 128 | + return data.map<CourseProcessTopicsTopicAnswerList>((Map<String, dynamic> e) => CourseProcessTopicsTopicAnswerList.fromJson(e)).toList() as M; | ||
| 129 | + } | ||
| 130 | + if(<CourseProcessVideos>[] is M){ | ||
| 131 | + return data.map<CourseProcessVideos>((Map<String, dynamic> e) => CourseProcessVideos.fromJson(e)).toList() as M; | ||
| 132 | + } | ||
| 133 | + if(<FollowReadEntity>[] is M){ | ||
| 134 | + return data.map<FollowReadEntity>((Map<String, dynamic> e) => FollowReadEntity.fromJson(e)).toList() as M; | ||
| 135 | + } | ||
| 115 | if(<ListenEntity>[] is M){ | 136 | if(<ListenEntity>[] is M){ |
| 116 | return data.map<ListenEntity>((Map<String, dynamic> e) => ListenEntity.fromJson(e)).toList() as M; | 137 | return data.map<ListenEntity>((Map<String, dynamic> e) => ListenEntity.fromJson(e)).toList() as M; |
| 117 | } | 138 | } |
lib/generated/json/course_process_entity.g.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_convert_content.dart'; | ||
| 2 | +import 'package:wow_english/models/course_process_entity.dart'; | ||
| 3 | + | ||
| 4 | +CourseProcessEntity $CourseProcessEntityFromJson(Map<String, dynamic> json) { | ||
| 5 | + final CourseProcessEntity courseProcessEntity = CourseProcessEntity(); | ||
| 6 | + final int? currentStep = jsonConvert.convert<int>(json['currentStep']); | ||
| 7 | + if (currentStep != null) { | ||
| 8 | + courseProcessEntity.currentStep = currentStep; | ||
| 9 | + } | ||
| 10 | + final int? currentTime = jsonConvert.convert<int>(json['currentTime']); | ||
| 11 | + if (currentTime != null) { | ||
| 12 | + courseProcessEntity.currentTime = currentTime; | ||
| 13 | + } | ||
| 14 | + final List<CourseProcessReadings>? readings = jsonConvert.convertListNotNull<CourseProcessReadings>(json['readings']); | ||
| 15 | + if (readings != null) { | ||
| 16 | + courseProcessEntity.readings = readings; | ||
| 17 | + } | ||
| 18 | + final List<CourseProcessTopics>? topics = jsonConvert.convertListNotNull<CourseProcessTopics>(json['topics']); | ||
| 19 | + if (topics != null) { | ||
| 20 | + courseProcessEntity.topics = topics; | ||
| 21 | + } | ||
| 22 | + final CourseProcessVideos? videos = jsonConvert.convert<CourseProcessVideos>(json['videos']); | ||
| 23 | + if (videos != null) { | ||
| 24 | + courseProcessEntity.videos = videos; | ||
| 25 | + } | ||
| 26 | + return courseProcessEntity; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +Map<String, dynamic> $CourseProcessEntityToJson(CourseProcessEntity entity) { | ||
| 30 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 31 | + data['currentStep'] = entity.currentStep; | ||
| 32 | + data['currentTime'] = entity.currentTime; | ||
| 33 | + data['readings'] = entity.readings?.map((v) => v.toJson()).toList(); | ||
| 34 | + data['topics'] = entity.topics?.map((v) => v.toJson()).toList(); | ||
| 35 | + data['videos'] = entity.videos?.toJson(); | ||
| 36 | + return data; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +CourseProcessReadings $CourseProcessReadingsFromJson(Map<String, dynamic> json) { | ||
| 40 | + final CourseProcessReadings courseProcessReadings = CourseProcessReadings(); | ||
| 41 | + final String? auditUrl = jsonConvert.convert<String>(json['auditUrl']); | ||
| 42 | + if (auditUrl != null) { | ||
| 43 | + courseProcessReadings.auditUrl = auditUrl; | ||
| 44 | + } | ||
| 45 | + final int? courseLessonId = jsonConvert.convert<int>(json['courseLessonId']); | ||
| 46 | + if (courseLessonId != null) { | ||
| 47 | + courseProcessReadings.courseLessonId = courseLessonId; | ||
| 48 | + } | ||
| 49 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | ||
| 50 | + if (createTime != null) { | ||
| 51 | + courseProcessReadings.createTime = createTime; | ||
| 52 | + } | ||
| 53 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | ||
| 54 | + if (deleted != null) { | ||
| 55 | + courseProcessReadings.deleted = deleted; | ||
| 56 | + } | ||
| 57 | + final String? id = jsonConvert.convert<String>(json['id']); | ||
| 58 | + if (id != null) { | ||
| 59 | + courseProcessReadings.id = id; | ||
| 60 | + } | ||
| 61 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | ||
| 62 | + if (modifyTime != null) { | ||
| 63 | + courseProcessReadings.modifyTime = modifyTime; | ||
| 64 | + } | ||
| 65 | + final String? padPicUrl = jsonConvert.convert<String>(json['padPicUrl']); | ||
| 66 | + if (padPicUrl != null) { | ||
| 67 | + courseProcessReadings.padPicUrl = padPicUrl; | ||
| 68 | + } | ||
| 69 | + final String? picUrl = jsonConvert.convert<String>(json['picUrl']); | ||
| 70 | + if (picUrl != null) { | ||
| 71 | + courseProcessReadings.picUrl = picUrl; | ||
| 72 | + } | ||
| 73 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | ||
| 74 | + if (sortOrder != null) { | ||
| 75 | + courseProcessReadings.sortOrder = sortOrder; | ||
| 76 | + } | ||
| 77 | + final String? word = jsonConvert.convert<String>(json['word']); | ||
| 78 | + if (word != null) { | ||
| 79 | + courseProcessReadings.word = word; | ||
| 80 | + } | ||
| 81 | + return courseProcessReadings; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +Map<String, dynamic> $CourseProcessReadingsToJson(CourseProcessReadings entity) { | ||
| 85 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 86 | + data['auditUrl'] = entity.auditUrl; | ||
| 87 | + data['courseLessonId'] = entity.courseLessonId; | ||
| 88 | + data['createTime'] = entity.createTime; | ||
| 89 | + data['deleted'] = entity.deleted; | ||
| 90 | + data['id'] = entity.id; | ||
| 91 | + data['modifyTime'] = entity.modifyTime; | ||
| 92 | + data['padPicUrl'] = entity.padPicUrl; | ||
| 93 | + data['picUrl'] = entity.picUrl; | ||
| 94 | + data['sortOrder'] = entity.sortOrder; | ||
| 95 | + data['word'] = entity.word; | ||
| 96 | + return data; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +CourseProcessTopics $CourseProcessTopicsFromJson(Map<String, dynamic> json) { | ||
| 100 | + final CourseProcessTopics courseProcessTopics = CourseProcessTopics(); | ||
| 101 | + final String? audioUrl = jsonConvert.convert<String>(json['audioUrl']); | ||
| 102 | + if (audioUrl != null) { | ||
| 103 | + courseProcessTopics.audioUrl = audioUrl; | ||
| 104 | + } | ||
| 105 | + final int? courseLessonId = jsonConvert.convert<int>(json['courseLessonId']); | ||
| 106 | + if (courseLessonId != null) { | ||
| 107 | + courseProcessTopics.courseLessonId = courseLessonId; | ||
| 108 | + } | ||
| 109 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | ||
| 110 | + if (createTime != null) { | ||
| 111 | + courseProcessTopics.createTime = createTime; | ||
| 112 | + } | ||
| 113 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | ||
| 114 | + if (deleted != null) { | ||
| 115 | + courseProcessTopics.deleted = deleted; | ||
| 116 | + } | ||
| 117 | + final String? id = jsonConvert.convert<String>(json['id']); | ||
| 118 | + if (id != null) { | ||
| 119 | + courseProcessTopics.id = id; | ||
| 120 | + } | ||
| 121 | + final String? keyWord = jsonConvert.convert<String>(json['keyWord']); | ||
| 122 | + if (keyWord != null) { | ||
| 123 | + courseProcessTopics.keyWord = keyWord; | ||
| 124 | + } | ||
| 125 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | ||
| 126 | + if (modifyTime != null) { | ||
| 127 | + courseProcessTopics.modifyTime = modifyTime; | ||
| 128 | + } | ||
| 129 | + final String? picUrl = jsonConvert.convert<String>(json['picUrl']); | ||
| 130 | + if (picUrl != null) { | ||
| 131 | + courseProcessTopics.picUrl = picUrl; | ||
| 132 | + } | ||
| 133 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | ||
| 134 | + if (sortOrder != null) { | ||
| 135 | + courseProcessTopics.sortOrder = sortOrder; | ||
| 136 | + } | ||
| 137 | + final int? status = jsonConvert.convert<int>(json['status']); | ||
| 138 | + if (status != null) { | ||
| 139 | + courseProcessTopics.status = status; | ||
| 140 | + } | ||
| 141 | + final List<CourseProcessTopicsTopicAnswerList>? topicAnswerList = jsonConvert.convertListNotNull<CourseProcessTopicsTopicAnswerList>(json['topicAnswerList']); | ||
| 142 | + if (topicAnswerList != null) { | ||
| 143 | + courseProcessTopics.topicAnswerList = topicAnswerList; | ||
| 144 | + } | ||
| 145 | + final int? type = jsonConvert.convert<int>(json['type']); | ||
| 146 | + if (type != null) { | ||
| 147 | + courseProcessTopics.type = type; | ||
| 148 | + } | ||
| 149 | + final String? word = jsonConvert.convert<String>(json['word']); | ||
| 150 | + if (word != null) { | ||
| 151 | + courseProcessTopics.word = word; | ||
| 152 | + } | ||
| 153 | + return courseProcessTopics; | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +Map<String, dynamic> $CourseProcessTopicsToJson(CourseProcessTopics entity) { | ||
| 157 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 158 | + data['audioUrl'] = entity.audioUrl; | ||
| 159 | + data['courseLessonId'] = entity.courseLessonId; | ||
| 160 | + data['createTime'] = entity.createTime; | ||
| 161 | + data['deleted'] = entity.deleted; | ||
| 162 | + data['id'] = entity.id; | ||
| 163 | + data['keyWord'] = entity.keyWord; | ||
| 164 | + data['modifyTime'] = entity.modifyTime; | ||
| 165 | + data['picUrl'] = entity.picUrl; | ||
| 166 | + data['sortOrder'] = entity.sortOrder; | ||
| 167 | + data['status'] = entity.status; | ||
| 168 | + data['topicAnswerList'] = entity.topicAnswerList?.map((v) => v.toJson()).toList(); | ||
| 169 | + data['type'] = entity.type; | ||
| 170 | + data['word'] = entity.word; | ||
| 171 | + return data; | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +CourseProcessTopicsTopicAnswerList $CourseProcessTopicsTopicAnswerListFromJson(Map<String, dynamic> json) { | ||
| 175 | + final CourseProcessTopicsTopicAnswerList courseProcessTopicsTopicAnswerList = CourseProcessTopicsTopicAnswerList(); | ||
| 176 | + final int? correct = jsonConvert.convert<int>(json['correct']); | ||
| 177 | + if (correct != null) { | ||
| 178 | + courseProcessTopicsTopicAnswerList.correct = correct; | ||
| 179 | + } | ||
| 180 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | ||
| 181 | + if (createTime != null) { | ||
| 182 | + courseProcessTopicsTopicAnswerList.createTime = createTime; | ||
| 183 | + } | ||
| 184 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | ||
| 185 | + if (deleted != null) { | ||
| 186 | + courseProcessTopicsTopicAnswerList.deleted = deleted; | ||
| 187 | + } | ||
| 188 | + final String? id = jsonConvert.convert<String>(json['id']); | ||
| 189 | + if (id != null) { | ||
| 190 | + courseProcessTopicsTopicAnswerList.id = id; | ||
| 191 | + } | ||
| 192 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | ||
| 193 | + if (modifyTime != null) { | ||
| 194 | + courseProcessTopicsTopicAnswerList.modifyTime = modifyTime; | ||
| 195 | + } | ||
| 196 | + final String? picUrl = jsonConvert.convert<String>(json['picUrl']); | ||
| 197 | + if (picUrl != null) { | ||
| 198 | + courseProcessTopicsTopicAnswerList.picUrl = picUrl; | ||
| 199 | + } | ||
| 200 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | ||
| 201 | + if (sortOrder != null) { | ||
| 202 | + courseProcessTopicsTopicAnswerList.sortOrder = sortOrder; | ||
| 203 | + } | ||
| 204 | + final int? topicId = jsonConvert.convert<int>(json['topicId']); | ||
| 205 | + if (topicId != null) { | ||
| 206 | + courseProcessTopicsTopicAnswerList.topicId = topicId; | ||
| 207 | + } | ||
| 208 | + final String? word = jsonConvert.convert<String>(json['word']); | ||
| 209 | + if (word != null) { | ||
| 210 | + courseProcessTopicsTopicAnswerList.word = word; | ||
| 211 | + } | ||
| 212 | + return courseProcessTopicsTopicAnswerList; | ||
| 213 | +} | ||
| 214 | + | ||
| 215 | +Map<String, dynamic> $CourseProcessTopicsTopicAnswerListToJson(CourseProcessTopicsTopicAnswerList entity) { | ||
| 216 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 217 | + data['correct'] = entity.correct; | ||
| 218 | + data['createTime'] = entity.createTime; | ||
| 219 | + data['deleted'] = entity.deleted; | ||
| 220 | + data['id'] = entity.id; | ||
| 221 | + data['modifyTime'] = entity.modifyTime; | ||
| 222 | + data['picUrl'] = entity.picUrl; | ||
| 223 | + data['sortOrder'] = entity.sortOrder; | ||
| 224 | + data['topicId'] = entity.topicId; | ||
| 225 | + data['word'] = entity.word; | ||
| 226 | + return data; | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | +CourseProcessVideos $CourseProcessVideosFromJson(Map<String, dynamic> json) { | ||
| 230 | + final CourseProcessVideos courseProcessVideos = CourseProcessVideos(); | ||
| 231 | + final int? courseLessonId = jsonConvert.convert<int>(json['courseLessonId']); | ||
| 232 | + if (courseLessonId != null) { | ||
| 233 | + courseProcessVideos.courseLessonId = courseLessonId; | ||
| 234 | + } | ||
| 235 | + final String? createTime = jsonConvert.convert<String>(json['createTime']); | ||
| 236 | + if (createTime != null) { | ||
| 237 | + courseProcessVideos.createTime = createTime; | ||
| 238 | + } | ||
| 239 | + final String? deleted = jsonConvert.convert<String>(json['deleted']); | ||
| 240 | + if (deleted != null) { | ||
| 241 | + courseProcessVideos.deleted = deleted; | ||
| 242 | + } | ||
| 243 | + final String? id = jsonConvert.convert<String>(json['id']); | ||
| 244 | + if (id != null) { | ||
| 245 | + courseProcessVideos.id = id; | ||
| 246 | + } | ||
| 247 | + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']); | ||
| 248 | + if (modifyTime != null) { | ||
| 249 | + courseProcessVideos.modifyTime = modifyTime; | ||
| 250 | + } | ||
| 251 | + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']); | ||
| 252 | + if (sortOrder != null) { | ||
| 253 | + courseProcessVideos.sortOrder = sortOrder; | ||
| 254 | + } | ||
| 255 | + final String? subtitleUrl = jsonConvert.convert<String>(json['subtitleUrl']); | ||
| 256 | + if (subtitleUrl != null) { | ||
| 257 | + courseProcessVideos.subtitleUrl = subtitleUrl; | ||
| 258 | + } | ||
| 259 | + final String? videoUrl = jsonConvert.convert<String>(json['videoUrl']); | ||
| 260 | + if (videoUrl != null) { | ||
| 261 | + courseProcessVideos.videoUrl = videoUrl; | ||
| 262 | + } | ||
| 263 | + return courseProcessVideos; | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +Map<String, dynamic> $CourseProcessVideosToJson(CourseProcessVideos entity) { | ||
| 267 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
| 268 | + data['courseLessonId'] = entity.courseLessonId; | ||
| 269 | + data['createTime'] = entity.createTime; | ||
| 270 | + data['deleted'] = entity.deleted; | ||
| 271 | + data['id'] = entity.id; | ||
| 272 | + data['modifyTime'] = entity.modifyTime; | ||
| 273 | + data['sortOrder'] = entity.sortOrder; | ||
| 274 | + data['subtitleUrl'] = entity.subtitleUrl; | ||
| 275 | + data['videoUrl'] = entity.videoUrl; | ||
| 276 | + return data; | ||
| 277 | +} | ||
| 0 | \ No newline at end of file | 278 | \ No newline at end of file |
lib/generated/json/user_entity.g.dart
| @@ -59,4 +59,4 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | @@ -59,4 +59,4 @@ Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | ||
| 59 | data['nowCourseModuleId'] = entity.nowCourseModuleId; | 59 | data['nowCourseModuleId'] = entity.nowCourseModuleId; |
| 60 | data['effectiveDate'] = entity.effectiveDate; | 60 | data['effectiveDate'] = entity.effectiveDate; |
| 61 | return data; | 61 | return data; |
| 62 | -} | 62 | -} |
| 63 | +} | ||
| 63 | \ No newline at end of file | 64 | \ No newline at end of file |
lib/models/course_process_entity.dart
0 → 100644
| 1 | +import 'package:wow_english/generated/json/base/json_field.dart'; | ||
| 2 | +import 'package:wow_english/generated/json/course_process_entity.g.dart'; | ||
| 3 | +import 'dart:convert'; | ||
| 4 | + | ||
| 5 | +@JsonSerializable() | ||
| 6 | +class CourseProcessEntity { | ||
| 7 | + int? currentStep; | ||
| 8 | + int? currentTime; | ||
| 9 | + List<CourseProcessReadings>? readings; | ||
| 10 | + List<CourseProcessTopics>? topics; | ||
| 11 | + CourseProcessVideos? videos; | ||
| 12 | + | ||
| 13 | + CourseProcessEntity(); | ||
| 14 | + | ||
| 15 | + factory CourseProcessEntity.fromJson(Map<String, dynamic> json) => $CourseProcessEntityFromJson(json); | ||
| 16 | + | ||
| 17 | + Map<String, dynamic> toJson() => $CourseProcessEntityToJson(this); | ||
| 18 | + | ||
| 19 | + @override | ||
| 20 | + String toString() { | ||
| 21 | + return jsonEncode(this); | ||
| 22 | + } | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +@JsonSerializable() | ||
| 26 | +class CourseProcessReadings { | ||
| 27 | + String? auditUrl; | ||
| 28 | + int? courseLessonId; | ||
| 29 | + String? createTime; | ||
| 30 | + String? deleted; | ||
| 31 | + String? id; | ||
| 32 | + String? modifyTime; | ||
| 33 | + String? padPicUrl; | ||
| 34 | + String? picUrl; | ||
| 35 | + int? sortOrder; | ||
| 36 | + String? word; | ||
| 37 | + | ||
| 38 | + CourseProcessReadings(); | ||
| 39 | + | ||
| 40 | + factory CourseProcessReadings.fromJson(Map<String, dynamic> json) => $CourseProcessReadingsFromJson(json); | ||
| 41 | + | ||
| 42 | + Map<String, dynamic> toJson() => $CourseProcessReadingsToJson(this); | ||
| 43 | + | ||
| 44 | + @override | ||
| 45 | + String toString() { | ||
| 46 | + return jsonEncode(this); | ||
| 47 | + } | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +@JsonSerializable() | ||
| 51 | +class CourseProcessTopics { | ||
| 52 | + String? audioUrl; | ||
| 53 | + int? courseLessonId; | ||
| 54 | + String? createTime; | ||
| 55 | + String? deleted; | ||
| 56 | + String? id; | ||
| 57 | + String? keyWord; | ||
| 58 | + String? modifyTime; | ||
| 59 | + String? picUrl; | ||
| 60 | + int? sortOrder; | ||
| 61 | + int? status; | ||
| 62 | + List<CourseProcessTopicsTopicAnswerList>? topicAnswerList; | ||
| 63 | + int? type; | ||
| 64 | + String? word; | ||
| 65 | + | ||
| 66 | + CourseProcessTopics(); | ||
| 67 | + | ||
| 68 | + factory CourseProcessTopics.fromJson(Map<String, dynamic> json) => $CourseProcessTopicsFromJson(json); | ||
| 69 | + | ||
| 70 | + Map<String, dynamic> toJson() => $CourseProcessTopicsToJson(this); | ||
| 71 | + | ||
| 72 | + @override | ||
| 73 | + String toString() { | ||
| 74 | + return jsonEncode(this); | ||
| 75 | + } | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +@JsonSerializable() | ||
| 79 | +class CourseProcessTopicsTopicAnswerList { | ||
| 80 | + int? correct; | ||
| 81 | + String? createTime; | ||
| 82 | + String? deleted; | ||
| 83 | + String? id; | ||
| 84 | + String? modifyTime; | ||
| 85 | + String? picUrl; | ||
| 86 | + int? sortOrder; | ||
| 87 | + int? topicId; | ||
| 88 | + String? word; | ||
| 89 | + | ||
| 90 | + CourseProcessTopicsTopicAnswerList(); | ||
| 91 | + | ||
| 92 | + factory CourseProcessTopicsTopicAnswerList.fromJson(Map<String, dynamic> json) => $CourseProcessTopicsTopicAnswerListFromJson(json); | ||
| 93 | + | ||
| 94 | + Map<String, dynamic> toJson() => $CourseProcessTopicsTopicAnswerListToJson(this); | ||
| 95 | + | ||
| 96 | + @override | ||
| 97 | + String toString() { | ||
| 98 | + return jsonEncode(this); | ||
| 99 | + } | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +@JsonSerializable() | ||
| 103 | +class CourseProcessVideos { | ||
| 104 | + int? courseLessonId; | ||
| 105 | + String? createTime; | ||
| 106 | + String? deleted; | ||
| 107 | + String? id; | ||
| 108 | + String? modifyTime; | ||
| 109 | + int? sortOrder; | ||
| 110 | + String? subtitleUrl; | ||
| 111 | + String? videoUrl; | ||
| 112 | + | ||
| 113 | + CourseProcessVideos(); | ||
| 114 | + | ||
| 115 | + factory CourseProcessVideos.fromJson(Map<String, dynamic> json) => $CourseProcessVideosFromJson(json); | ||
| 116 | + | ||
| 117 | + Map<String, dynamic> toJson() => $CourseProcessVideosToJson(this); | ||
| 118 | + | ||
| 119 | + @override | ||
| 120 | + String toString() { | ||
| 121 | + return jsonEncode(this); | ||
| 122 | + } | ||
| 123 | +} | ||
| 0 | \ No newline at end of file | 124 | \ No newline at end of file |
lib/pages/practice/bloc/topic_picture_bloc.dart
| 1 | +import 'package:audioplayers/audioplayers.dart'; | ||
| 1 | import 'package:flutter/cupertino.dart'; | 2 | import 'package:flutter/cupertino.dart'; |
| 3 | +import 'package:flutter/foundation.dart'; | ||
| 4 | +import 'package:flutter/services.dart'; | ||
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 5 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 6 | +import 'package:flutter_easyloading/flutter_easyloading.dart'; | ||
| 7 | +import 'package:wow_english/common/request/dao/listen_dao.dart'; | ||
| 8 | +import 'package:wow_english/common/request/exception.dart'; | ||
| 9 | +import 'package:wow_english/models/course_process_entity.dart'; | ||
| 10 | +import 'package:wow_english/utils/loading.dart'; | ||
| 3 | 11 | ||
| 4 | part 'topic_picture_event.dart'; | 12 | part 'topic_picture_event.dart'; |
| 5 | part 'topic_picture_state.dart'; | 13 | part 'topic_picture_state.dart'; |
| @@ -12,25 +20,70 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -12,25 +20,70 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 12 | 20 | ||
| 13 | int _currentPage = 0; | 21 | int _currentPage = 0; |
| 14 | 22 | ||
| 15 | - int _selectItem = 0; | 23 | + int _selectItem = -1; |
| 24 | + | ||
| 25 | + CourseProcessEntity? _entity; | ||
| 26 | + | ||
| 27 | + ///正在评测 | ||
| 28 | + bool _isVoicing = false; | ||
| 29 | + | ||
| 30 | + CourseProcessEntity? get entity => _entity; | ||
| 16 | 31 | ||
| 17 | int get currentPage => _currentPage + 1; | 32 | int get currentPage => _currentPage + 1; |
| 18 | 33 | ||
| 19 | int get selectItem => _selectItem; | 34 | int get selectItem => _selectItem; |
| 20 | 35 | ||
| 36 | + bool get isVoicing => _isVoicing; | ||
| 37 | + | ||
| 38 | + var messageChannel = const BasicMessageChannel('com.owEnglish.voiceXs.BasicMessageChannel', StandardMessageCodec()); | ||
| 39 | + | ||
| 40 | + final audioPlayer = AudioPlayer(); | ||
| 41 | + | ||
| 21 | TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) { | 42 | TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) { |
| 22 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); | 43 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); |
| 44 | + on<InitMessageChannelEvent>(_initMessageChannelCall); | ||
| 45 | + on<RequestDataEvent>(_requestData); | ||
| 23 | on<SelectItemEvent>(_selectItemLoad); | 46 | on<SelectItemEvent>(_selectItemLoad); |
| 47 | + on<VoiceXsTestEvent>(_voiceXsTest); | ||
| 48 | + on<VoiceResultEvent>(_voiceResult); | ||
| 49 | + on<TopicPictureEvent>((event, emit) { | ||
| 50 | + | ||
| 51 | + }); | ||
| 24 | } | 52 | } |
| 25 | 53 | ||
| 26 | @override | 54 | @override |
| 27 | Future<void> close() { | 55 | Future<void> close() { |
| 28 | pageController.dispose(); | 56 | pageController.dispose(); |
| 57 | + audioPlayer.dispose(); | ||
| 29 | return super.close(); | 58 | return super.close(); |
| 30 | } | 59 | } |
| 31 | 60 | ||
| 61 | + void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 62 | + try { | ||
| 63 | + await loading(() async { | ||
| 64 | + _entity = await ListenDao.process('8'); | ||
| 65 | + emitter(RequestDataState()); | ||
| 66 | + }); | ||
| 67 | + } catch (e) { | ||
| 68 | + if (e is ApiException) { | ||
| 69 | + EasyLoading.showToast(e.message??'请求失败,请检查网络连接'); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 32 | void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { | 74 | void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { |
| 33 | _currentPage = event.pageIndex; | 75 | _currentPage = event.pageIndex; |
| 76 | + final topics = _entity?.topics?[_currentPage]; | ||
| 77 | + if (topics?.type == 1 || topics?.type == 2) { | ||
| 78 | + if (topics?.audioUrl != null) { | ||
| 79 | + final urlStr = topics?.audioUrl??''; | ||
| 80 | + if (urlStr.isNotEmpty) { | ||
| 81 | + audioPlayer.play(UrlSource(urlStr)); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + } else { | ||
| 85 | + audioPlayer.stop(); | ||
| 86 | + } | ||
| 34 | emitter(CurrentPageIndexState()); | 87 | emitter(CurrentPageIndexState()); |
| 35 | } | 88 | } |
| 36 | 89 | ||
| @@ -38,4 +91,47 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -38,4 +91,47 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 38 | _selectItem = event.selectIndex; | 91 | _selectItem = event.selectIndex; |
| 39 | emitter(SelectItemChangeState()); | 92 | emitter(SelectItemChangeState()); |
| 40 | } | 93 | } |
| 94 | + | ||
| 95 | + ///messageChannel回调 | ||
| 96 | + Future messageResultHandler(message,Emitter<TopicPictureState> emitter) async { | ||
| 97 | + EasyLoading.dismiss(); | ||
| 98 | + final Map args = message as Map; | ||
| 99 | + final result = args['result'] as String; | ||
| 100 | + if (result == '1') { | ||
| 101 | + final overall = args['overall'].toString(); | ||
| 102 | + EasyLoading.showToast('测评成功,分数是$overall',duration: const Duration(seconds: 10)); | ||
| 103 | + } else { | ||
| 104 | + EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10)); | ||
| 105 | + } | ||
| 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; | ||
| 135 | + emitter(VoiceXsTestState()); | ||
| 136 | + } | ||
| 41 | } | 137 | } |
lib/pages/practice/bloc/topic_picture_event.dart
| @@ -3,6 +3,21 @@ part of 'topic_picture_bloc.dart'; | @@ -3,6 +3,21 @@ part of 'topic_picture_bloc.dart'; | ||
| 3 | @immutable | 3 | @immutable |
| 4 | abstract class TopicPictureEvent {} | 4 | abstract class TopicPictureEvent {} |
| 5 | 5 | ||
| 6 | +class RequestDataEvent extends TopicPictureEvent {} | ||
| 7 | + | ||
| 8 | +///初始化消息回调 | ||
| 9 | +class InitMessageChannelEvent extends TopicPictureEvent {} | ||
| 10 | + | ||
| 11 | +class VoiceResultEvent extends TopicPictureEvent {} | ||
| 12 | + | ||
| 13 | +///先声测试 | ||
| 14 | +class VoiceXsTestEvent extends TopicPictureEvent { | ||
| 15 | + final String testWord; | ||
| 16 | + final int type; | ||
| 17 | + final int userId; | ||
| 18 | + VoiceXsTestEvent(this.testWord,this.type,this.userId); | ||
| 19 | +} | ||
| 20 | + | ||
| 6 | class CurrentPageIndexChangeEvent extends TopicPictureEvent { | 21 | class CurrentPageIndexChangeEvent extends TopicPictureEvent { |
| 7 | final int pageIndex; | 22 | final int pageIndex; |
| 8 | CurrentPageIndexChangeEvent(this.pageIndex); | 23 | CurrentPageIndexChangeEvent(this.pageIndex); |
lib/pages/practice/bloc/topic_picture_state.dart
| @@ -3,6 +3,10 @@ part of 'topic_picture_bloc.dart'; | @@ -3,6 +3,10 @@ part of 'topic_picture_bloc.dart'; | ||
| 3 | @immutable | 3 | @immutable |
| 4 | abstract class TopicPictureState {} | 4 | abstract class TopicPictureState {} |
| 5 | 5 | ||
| 6 | +class RequestDataState extends TopicPictureState {} | ||
| 7 | + | ||
| 8 | +class VoiceXsTestState extends TopicPictureState {} | ||
| 9 | + | ||
| 6 | class TopicPictureInitial extends TopicPictureState {} | 10 | class TopicPictureInitial extends TopicPictureState {} |
| 7 | 11 | ||
| 8 | class CurrentPageIndexState extends TopicPictureState {} | 12 | class CurrentPageIndexState extends TopicPictureState {} |
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/extension/string_extension.dart'; | 5 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 5 | 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'; | ||
| 6 | 8 | ||
| 7 | import 'bloc/topic_picture_bloc.dart'; | 9 | import 'bloc/topic_picture_bloc.dart'; |
| 8 | import 'widgets/practice_header_widget.dart'; | 10 | import 'widgets/practice_header_widget.dart'; |
| @@ -13,7 +15,12 @@ class TopicPicturePage extends StatelessWidget { | @@ -13,7 +15,12 @@ class TopicPicturePage extends StatelessWidget { | ||
| 13 | @override | 15 | @override |
| 14 | Widget build(BuildContext context) { | 16 | Widget build(BuildContext context) { |
| 15 | return BlocProvider( | 17 | return BlocProvider( |
| 16 | - create: (context) => TopicPictureBloc(PageController(),3), | 18 | + create: (context) => TopicPictureBloc( |
| 19 | + PageController(), | ||
| 20 | + 3 | ||
| 21 | + ) | ||
| 22 | + ..add(RequestDataEvent()) | ||
| 23 | + ..add(InitMessageChannelEvent()), | ||
| 17 | child: _TopicPicturePage(), | 24 | child: _TopicPicturePage(), |
| 18 | ); | 25 | ); |
| 19 | } | 26 | } |
| @@ -23,13 +30,16 @@ class _TopicPicturePage extends StatelessWidget { | @@ -23,13 +30,16 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 23 | @override | 30 | @override |
| 24 | Widget build(BuildContext context) { | 31 | Widget build(BuildContext context) { |
| 25 | return BlocListener<TopicPictureBloc,TopicPictureState>( | 32 | return BlocListener<TopicPictureBloc,TopicPictureState>( |
| 26 | - listener: (context, state){}, | 33 | + listener: (context, state){ |
| 34 | + if (state is RequestDataState) { | ||
| 35 | + context.read<TopicPictureBloc>().add(CurrentPageIndexChangeEvent(0)); | ||
| 36 | + } | ||
| 37 | + }, | ||
| 27 | child: _topicPictureView(), | 38 | child: _topicPictureView(), |
| 28 | ); | 39 | ); |
| 29 | } | 40 | } |
| 30 | 41 | ||
| 31 | Widget _topicPictureView() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 42 | Widget _topicPictureView() => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 32 | - buildWhen: (_,s) => s is CurrentPageIndexState, | ||
| 33 | builder: (context,state){ | 43 | builder: (context,state){ |
| 34 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 44 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 35 | return Container( | 45 | return Container( |
| @@ -39,28 +49,29 @@ class _TopicPicturePage extends StatelessWidget { | @@ -39,28 +49,29 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 39 | Column( | 49 | Column( |
| 40 | children: [ | 50 | children: [ |
| 41 | PracticeHeaderWidget( | 51 | PracticeHeaderWidget( |
| 42 | - title: '${bloc.currentPage}/8', | 52 | + title: '${bloc.currentPage}/${bloc.entity?.topics?.length}', |
| 43 | onTap: (){Navigator.pop(context);}, | 53 | onTap: (){Navigator.pop(context);}, |
| 44 | ), | 54 | ), |
| 45 | Expanded( | 55 | Expanded( |
| 46 | child: PageView.builder( | 56 | child: PageView.builder( |
| 47 | - itemCount: 8, | 57 | + itemCount: bloc.entity?.topics?.length, |
| 48 | scrollDirection: Axis.horizontal, | 58 | scrollDirection: Axis.horizontal, |
| 49 | controller: bloc.pageController, | 59 | controller: bloc.pageController, |
| 50 | onPageChanged: (int index) { | 60 | onPageChanged: (int index) { |
| 51 | bloc.add(CurrentPageIndexChangeEvent(index)); | 61 | bloc.add(CurrentPageIndexChangeEvent(index)); |
| 52 | }, | 62 | }, |
| 53 | itemBuilder: (BuildContext context,int index){ | 63 | itemBuilder: (BuildContext context,int index){ |
| 54 | - if (index % 5 == 0) { | ||
| 55 | - return _pageViewWordItemWidget(); | ||
| 56 | - } else if (index % 5 == 1) { | ||
| 57 | - return _pageViewItemWidget(); | ||
| 58 | - } else if (index % 5 == 2){ | ||
| 59 | - return _pageViewVoicePictureItemWidget(); | ||
| 60 | - } else if (index % 5 == 3){ | ||
| 61 | - return _voiceAnswerItem(); | ||
| 62 | - } else { | ||
| 63 | - return _pageViewVoiceWordItemWidget(); | 64 | + CourseProcessTopics? topics = bloc.entity?.topics![index]; |
| 65 | + if (topics?.type == 1) {//听音选图 | ||
| 66 | + return _pageViewVoicePictureItemWidget(topics); | ||
| 67 | + } else if (topics?.type == 2) {//听音选字 | ||
| 68 | + return _pageViewVoiceWordItemWidget(topics); | ||
| 69 | + } else if (topics?.type == 3) {//看题选字 | ||
| 70 | + return _pageViewWordItemWidget(topics); | ||
| 71 | + } else if (topics?.type == 4) {//看题选图 | ||
| 72 | + return _pageViewItemWidget(topics); | ||
| 73 | + } else {//语音问答 | ||
| 74 | + return _voiceAnswerItem(topics); | ||
| 64 | } | 75 | } |
| 65 | }), | 76 | }), |
| 66 | ) | 77 | ) |
| @@ -78,9 +89,8 @@ class _TopicPicturePage extends StatelessWidget { | @@ -78,9 +89,8 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 78 | }); | 89 | }); |
| 79 | 90 | ||
| 80 | ///看题选图 | 91 | ///看题选图 |
| 81 | - Widget _pageViewItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 92 | + Widget _pageViewItemWidget(CourseProcessTopics? topics) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 82 | builder: (context, state){ | 93 | builder: (context, state){ |
| 83 | - final bloc = BlocProvider.of<TopicPictureBloc>(context); | ||
| 84 | return SafeArea( | 94 | return SafeArea( |
| 85 | child: Column( | 95 | child: Column( |
| 86 | children: [ | 96 | children: [ |
| @@ -93,27 +103,16 @@ class _TopicPicturePage extends StatelessWidget { | @@ -93,27 +103,16 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 93 | ) | 103 | ) |
| 94 | ), | 104 | ), |
| 95 | 26.verticalSpace, | 105 | 26.verticalSpace, |
| 96 | - Row( | ||
| 97 | - mainAxisAlignment: MainAxisAlignment.center, | ||
| 98 | - children: [ | ||
| 99 | - Offstage( | ||
| 100 | - offstage: (bloc.modelCount < 1), | ||
| 101 | - child: _decodeImageWidget(1), | ||
| 102 | - ), | ||
| 103 | - Offstage( | ||
| 104 | - offstage: (bloc.modelCount < 2), | ||
| 105 | - child: _decodeImageWidget(2), | ||
| 106 | - ), | ||
| 107 | - Offstage( | ||
| 108 | - offstage: (bloc.modelCount < 3), | ||
| 109 | - child: _decodeImageWidget(3), | ||
| 110 | - ), | ||
| 111 | - Offstage( | ||
| 112 | - offstage: (bloc.modelCount < 4), | ||
| 113 | - child: _decodeImageWidget(4), | ||
| 114 | - ) | ||
| 115 | - ], | ||
| 116 | - ) | 106 | + SizedBox( |
| 107 | + height: 143.h, | ||
| 108 | + width: 143.w * (topics?.topicAnswerList?.length??0), | ||
| 109 | + child: ListView.builder( | ||
| 110 | + itemCount: topics?.topicAnswerList?.length??0, | ||
| 111 | + scrollDirection: Axis.horizontal, | ||
| 112 | + itemBuilder: (context,index){ | ||
| 113 | + return _decodeImageWidget(index); | ||
| 114 | + }), | ||
| 115 | + ), | ||
| 117 | ], | 116 | ], |
| 118 | ), | 117 | ), |
| 119 | ); | 118 | ); |
| @@ -123,28 +122,31 @@ class _TopicPicturePage extends StatelessWidget { | @@ -123,28 +122,31 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 123 | buildWhen: (_, s) => s is SelectItemChangeState, | 122 | buildWhen: (_, s) => s is SelectItemChangeState, |
| 124 | builder: (context,state){ | 123 | builder: (context,state){ |
| 125 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 124 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 126 | - return GestureDetector( | ||
| 127 | - onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 128 | - child: Container( | ||
| 129 | - padding: const EdgeInsets.all(4.5), | ||
| 130 | - decoration: BoxDecoration( | ||
| 131 | - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 132 | - borderRadius: BorderRadius.circular(15), | ||
| 133 | - ), | ||
| 134 | - height: 143.h, | ||
| 135 | - width: 143.w, | 125 | + return Container( |
| 126 | + padding: EdgeInsets.symmetric(horizontal: 10.w), | ||
| 127 | + child: GestureDetector( | ||
| 128 | + onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 136 | child: Container( | 129 | child: Container( |
| 130 | + padding: const EdgeInsets.all(4.5), | ||
| 137 | decoration: BoxDecoration( | 131 | decoration: BoxDecoration( |
| 138 | - color: Colors.white, | ||
| 139 | - borderRadius: BorderRadius.circular(15), | ||
| 140 | - border: Border.all( | ||
| 141 | - width: 1.0, | ||
| 142 | - color: const Color(0xFF140C10) | ||
| 143 | - ), | ||
| 144 | - image: const DecorationImage( | ||
| 145 | - fit: BoxFit.fitWidth, | ||
| 146 | - image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714') | ||
| 147 | - ) | 132 | + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, |
| 133 | + borderRadius: BorderRadius.circular(15), | ||
| 134 | + ), | ||
| 135 | + height: 143.h, | ||
| 136 | + width: 143.w, | ||
| 137 | + child: Container( | ||
| 138 | + decoration: BoxDecoration( | ||
| 139 | + color: Colors.white, | ||
| 140 | + borderRadius: BorderRadius.circular(15), | ||
| 141 | + border: Border.all( | ||
| 142 | + width: 1.0, | ||
| 143 | + color: const Color(0xFF140C10) | ||
| 144 | + ), | ||
| 145 | + image: const DecorationImage( | ||
| 146 | + fit: BoxFit.fitWidth, | ||
| 147 | + image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714') | ||
| 148 | + ) | ||
| 149 | + ), | ||
| 148 | ), | 150 | ), |
| 149 | ), | 151 | ), |
| 150 | ), | 152 | ), |
| @@ -152,7 +154,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -152,7 +154,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 152 | }); | 154 | }); |
| 153 | 155 | ||
| 154 | ///看题选字 | 156 | ///看题选字 |
| 155 | - Widget _pageViewWordItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 157 | + Widget _pageViewWordItemWidget(CourseProcessTopics? topics) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 156 | builder: (context, state){ | 158 | builder: (context, state){ |
| 157 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 159 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 158 | return SafeArea( | 160 | return SafeArea( |
| @@ -167,27 +169,16 @@ class _TopicPicturePage extends StatelessWidget { | @@ -167,27 +169,16 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 167 | ) | 169 | ) |
| 168 | ), | 170 | ), |
| 169 | 26.verticalSpace, | 171 | 26.verticalSpace, |
| 170 | - Row( | ||
| 171 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| 172 | - children: [ | ||
| 173 | - Offstage( | ||
| 174 | - offstage: (bloc.modelCount < 1), | ||
| 175 | - child: _decodeWordWidget(1), | ||
| 176 | - ), | ||
| 177 | - Offstage( | ||
| 178 | - offstage: (bloc.modelCount < 2), | ||
| 179 | - child: _decodeWordWidget(2), | ||
| 180 | - ), | ||
| 181 | - Offstage( | ||
| 182 | - offstage: (bloc.modelCount < 3), | ||
| 183 | - child: _decodeWordWidget(3), | ||
| 184 | - ), | ||
| 185 | - Offstage( | ||
| 186 | - offstage: (bloc.modelCount < 4), | ||
| 187 | - child: _decodeWordWidget(4), | ||
| 188 | - ) | ||
| 189 | - ], | ||
| 190 | - ) | 172 | + SizedBox( |
| 173 | + height: 143.h, | ||
| 174 | + width: 143.w * (topics?.topicAnswerList?.length??0), | ||
| 175 | + child: ListView.builder( | ||
| 176 | + itemCount: topics?.topicAnswerList?.length??0, | ||
| 177 | + scrollDirection: Axis.horizontal, | ||
| 178 | + itemBuilder: (context,index){ | ||
| 179 | + return _decodeWordWidget(index); | ||
| 180 | + }), | ||
| 181 | + ), | ||
| 191 | ], | 182 | ], |
| 192 | ), | 183 | ), |
| 193 | ); | 184 | ); |
| @@ -197,57 +188,60 @@ class _TopicPicturePage extends StatelessWidget { | @@ -197,57 +188,60 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 197 | buildWhen: (_, s) => s is SelectItemChangeState, | 188 | buildWhen: (_, s) => s is SelectItemChangeState, |
| 198 | builder: (context,state){ | 189 | builder: (context,state){ |
| 199 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 190 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 200 | - return GestureDetector( | ||
| 201 | - onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 202 | - child: Container( | ||
| 203 | - width: 143.w, | ||
| 204 | - height: 143.h, | ||
| 205 | - padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h), | ||
| 206 | - decoration: BoxDecoration( | ||
| 207 | - color: Colors.white, | ||
| 208 | - borderRadius: BorderRadius.circular(15), | ||
| 209 | - border: Border.all( | ||
| 210 | - width: 1.0, | ||
| 211 | - color: const Color(0xFF140C10) | 191 | + return Container( |
| 192 | + padding: EdgeInsets.symmetric(horizontal: 10.w), | ||
| 193 | + child: GestureDetector( | ||
| 194 | + onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 195 | + child: Container( | ||
| 196 | + width: 143.w, | ||
| 197 | + height: 143.h, | ||
| 198 | + padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h), | ||
| 199 | + decoration: BoxDecoration( | ||
| 200 | + color: Colors.white, | ||
| 201 | + borderRadius: BorderRadius.circular(15), | ||
| 202 | + border: Border.all( | ||
| 203 | + width: 1.0, | ||
| 204 | + color: const Color(0xFF140C10) | ||
| 205 | + ), | ||
| 212 | ), | 206 | ), |
| 213 | - ), | ||
| 214 | - child: Column( | ||
| 215 | - mainAxisAlignment: MainAxisAlignment.end, | ||
| 216 | - children: [ | ||
| 217 | - Expanded( | ||
| 218 | - child: Container( | ||
| 219 | - alignment: Alignment.center, | ||
| 220 | - child: Text( | ||
| 221 | - 'yellow', | ||
| 222 | - style: TextStyle( | ||
| 223 | - fontSize: 20.sp, | ||
| 224 | - color: const Color(0xFF333333) | ||
| 225 | - ) | 207 | + child: Column( |
| 208 | + mainAxisAlignment: MainAxisAlignment.end, | ||
| 209 | + children: [ | ||
| 210 | + Expanded( | ||
| 211 | + child: Container( | ||
| 212 | + alignment: Alignment.center, | ||
| 213 | + child: Text( | ||
| 214 | + 'yellow', | ||
| 215 | + style: TextStyle( | ||
| 216 | + fontSize: 20.sp, | ||
| 217 | + color: const Color(0xFF333333) | ||
| 218 | + ) | ||
| 219 | + ), | ||
| 226 | ), | 220 | ), |
| 227 | ), | 221 | ), |
| 228 | - ), | ||
| 229 | - Container( | ||
| 230 | - height: 30.h, | ||
| 231 | - width: double.infinity, | ||
| 232 | - decoration: BoxDecoration( | ||
| 233 | - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 234 | - borderRadius: BorderRadius.circular(15.r), | ||
| 235 | - border: Border.all( | ||
| 236 | - width: 1.5, | ||
| 237 | - color: const Color(0xFF140C10) | 222 | + Container( |
| 223 | + height: 30.h, | ||
| 224 | + width: double.infinity, | ||
| 225 | + decoration: BoxDecoration( | ||
| 226 | + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 227 | + borderRadius: BorderRadius.circular(15.r), | ||
| 228 | + border: Border.all( | ||
| 229 | + width: 1.5, | ||
| 230 | + color: const Color(0xFF140C10) | ||
| 231 | + ), | ||
| 238 | ), | 232 | ), |
| 239 | - ), | ||
| 240 | - alignment: Alignment.center, | ||
| 241 | - child: Image.asset('choose'.assetPng), | ||
| 242 | - ) | ||
| 243 | - ], | 233 | + alignment: Alignment.center, |
| 234 | + child: Image.asset('choose'.assetPng), | ||
| 235 | + ) | ||
| 236 | + ], | ||
| 237 | + ), | ||
| 244 | ), | 238 | ), |
| 245 | ), | 239 | ), |
| 246 | ); | 240 | ); |
| 247 | }); | 241 | }); |
| 248 | 242 | ||
| 249 | ///听音选图 | 243 | ///听音选图 |
| 250 | - Widget _pageViewVoicePictureItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 244 | + Widget _pageViewVoicePictureItemWidget(CourseProcessTopics? topics) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 251 | builder: (context, state){ | 245 | builder: (context, state){ |
| 252 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 246 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 253 | return SafeArea( | 247 | return SafeArea( |
| @@ -268,58 +262,51 @@ class _TopicPicturePage extends StatelessWidget { | @@ -268,58 +262,51 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 268 | ], | 262 | ], |
| 269 | ), | 263 | ), |
| 270 | 26.verticalSpace, | 264 | 26.verticalSpace, |
| 271 | - Row( | ||
| 272 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| 273 | - children: [ | ||
| 274 | - Offstage( | ||
| 275 | - offstage: (bloc.modelCount < 1), | ||
| 276 | - child: _decodeVoiceImageWidget(1), | ||
| 277 | - ), | ||
| 278 | - Offstage( | ||
| 279 | - offstage: (bloc.modelCount < 2), | ||
| 280 | - child: _decodeVoiceImageWidget(2), | ||
| 281 | - ), | ||
| 282 | - Offstage( | ||
| 283 | - offstage: (bloc.modelCount < 3), | ||
| 284 | - child: _decodeVoiceImageWidget(3), | ||
| 285 | - ), | ||
| 286 | - Offstage( | ||
| 287 | - offstage: (bloc.modelCount < 4), | ||
| 288 | - child: _decodeVoiceImageWidget(4), | ||
| 289 | - ) | ||
| 290 | - ], | 265 | + SizedBox( |
| 266 | + height: 143.h, | ||
| 267 | + width: 163.w * (topics?.topicAnswerList?.length??0), | ||
| 268 | + child: ListView.builder( | ||
| 269 | + scrollDirection: Axis.horizontal, | ||
| 270 | + itemCount: topics?.topicAnswerList?.length??0, | ||
| 271 | + itemBuilder: (BuildContext context,int index){ | ||
| 272 | + return _decodeVoiceImageWidget(1,topics?.topicAnswerList?[index]); | ||
| 273 | + }) | ||
| 274 | + , | ||
| 291 | ) | 275 | ) |
| 292 | ], | 276 | ], |
| 293 | ), | 277 | ), |
| 294 | ); | 278 | ); |
| 295 | }); | 279 | }); |
| 296 | 280 | ||
| 297 | - Widget _decodeVoiceImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 281 | + Widget _decodeVoiceImageWidget(int index,CourseProcessTopicsTopicAnswerList? answerList) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 298 | buildWhen: (_, s) => s is SelectItemChangeState, | 282 | buildWhen: (_, s) => s is SelectItemChangeState, |
| 299 | builder: (context,state){ | 283 | builder: (context,state){ |
| 300 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 284 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 301 | - return GestureDetector( | ||
| 302 | - onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 303 | - child: Container( | ||
| 304 | - padding: const EdgeInsets.all(4.5), | ||
| 305 | - decoration: BoxDecoration( | ||
| 306 | - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 307 | - borderRadius: BorderRadius.circular(15), | ||
| 308 | - ), | ||
| 309 | - height: 143.h, | ||
| 310 | - width: 143.w, | 285 | + return Container( |
| 286 | + padding: EdgeInsets.symmetric(horizontal: 10.w), | ||
| 287 | + child: GestureDetector( | ||
| 288 | + onTap: () => bloc.add(SelectItemEvent(index)), | ||
| 311 | child: Container( | 289 | child: Container( |
| 290 | + padding: const EdgeInsets.all(4.5), | ||
| 312 | decoration: BoxDecoration( | 291 | decoration: BoxDecoration( |
| 313 | - color: Colors.white, | ||
| 314 | - borderRadius: BorderRadius.circular(15), | ||
| 315 | - border: Border.all( | ||
| 316 | - width: 1.0, | ||
| 317 | - color: const Color(0xFF140C10) | ||
| 318 | - ), | ||
| 319 | - image: const DecorationImage( | ||
| 320 | - fit: BoxFit.fitWidth, | ||
| 321 | - image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714') | ||
| 322 | - ) | 292 | + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, |
| 293 | + borderRadius: BorderRadius.circular(15), | ||
| 294 | + ), | ||
| 295 | + height: 143.h, | ||
| 296 | + width: 143.w, | ||
| 297 | + child: Container( | ||
| 298 | + decoration: BoxDecoration( | ||
| 299 | + color: Colors.white, | ||
| 300 | + borderRadius: BorderRadius.circular(15), | ||
| 301 | + border: Border.all( | ||
| 302 | + width: 1.0, | ||
| 303 | + color: const Color(0xFF140C10) | ||
| 304 | + ), | ||
| 305 | + image: const DecorationImage( | ||
| 306 | + fit: BoxFit.fitWidth, | ||
| 307 | + image: NetworkImage('https://img1.baidu.com/it/u=3392591833,1640391553&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=714') | ||
| 308 | + ) | ||
| 309 | + ), | ||
| 323 | ), | 310 | ), |
| 324 | ), | 311 | ), |
| 325 | ), | 312 | ), |
| @@ -327,7 +314,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -327,7 +314,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 327 | }); | 314 | }); |
| 328 | 315 | ||
| 329 | ///听音选字 | 316 | ///听音选字 |
| 330 | - Widget _pageViewVoiceWordItemWidget() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 317 | + Widget _pageViewVoiceWordItemWidget(CourseProcessTopics? topics) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 331 | builder: (context, state){ | 318 | builder: (context, state){ |
| 332 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 319 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 333 | return SafeArea( | 320 | return SafeArea( |
| @@ -335,114 +322,138 @@ class _TopicPicturePage extends StatelessWidget { | @@ -335,114 +322,138 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 335 | children: [ | 322 | children: [ |
| 336 | Image.asset('voice'.assetPng,height: 33.h,width: 30.w,), | 323 | Image.asset('voice'.assetPng,height: 33.h,width: 30.w,), |
| 337 | 26.verticalSpace, | 324 | 26.verticalSpace, |
| 338 | - Row( | ||
| 339 | - mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| 340 | - children: [ | ||
| 341 | - Offstage( | ||
| 342 | - offstage: (bloc.modelCount < 1), | ||
| 343 | - child: _decodeVoiceWordImageWidget(1), | ||
| 344 | - ), | ||
| 345 | - Offstage( | ||
| 346 | - offstage: (bloc.modelCount < 2), | ||
| 347 | - child: _decodeVoiceWordImageWidget(2), | ||
| 348 | - ), | ||
| 349 | - Offstage( | ||
| 350 | - offstage: (bloc.modelCount < 3), | ||
| 351 | - child: _decodeVoiceWordImageWidget(3), | ||
| 352 | - ), | ||
| 353 | - Offstage( | ||
| 354 | - offstage: (bloc.modelCount < 4), | ||
| 355 | - child: _decodeVoiceWordImageWidget(4), | ||
| 356 | - ) | ||
| 357 | - ], | ||
| 358 | - ) | 325 | + SizedBox( |
| 326 | + width: 163.w * (topics?.topicAnswerList?.length??0), | ||
| 327 | + height: 143.h, | ||
| 328 | + child: ListView.builder( | ||
| 329 | + itemCount: topics?.topicAnswerList?.length, | ||
| 330 | + scrollDirection: Axis.horizontal, | ||
| 331 | + itemBuilder: (BuildContext context,int index){ | ||
| 332 | + return _decodeVoiceWordImageWidget(index, topics!.topicAnswerList![index]); | ||
| 333 | + }), | ||
| 334 | + ), | ||
| 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 | + // ) | ||
| 359 | ], | 356 | ], |
| 360 | ), | 357 | ), |
| 361 | ); | 358 | ); |
| 362 | }); | 359 | }); |
| 363 | 360 | ||
| 364 | - Widget _decodeVoiceWordImageWidget(int index) => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 361 | + Widget _decodeVoiceWordImageWidget(int index,CourseProcessTopicsTopicAnswerList answerList) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 365 | buildWhen: (_, s) => s is SelectItemChangeState, | 362 | buildWhen: (_, s) => s is SelectItemChangeState, |
| 366 | builder: (context,state){ | 363 | builder: (context,state){ |
| 367 | final bloc = BlocProvider.of<TopicPictureBloc>(context); | 364 | final bloc = BlocProvider.of<TopicPictureBloc>(context); |
| 368 | return GestureDetector( | 365 | return GestureDetector( |
| 369 | onTap: () => bloc.add(SelectItemEvent(index)), | 366 | onTap: () => bloc.add(SelectItemEvent(index)), |
| 370 | child: Container( | 367 | child: Container( |
| 371 | - width: 143.w, | 368 | + width: 163.w, |
| 372 | height: 143.h, | 369 | height: 143.h, |
| 373 | - padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h), | ||
| 374 | - decoration: BoxDecoration( | ||
| 375 | - color: Colors.white, | ||
| 376 | - borderRadius: BorderRadius.circular(15), | ||
| 377 | - border: Border.all( | ||
| 378 | - width: 1.0, | ||
| 379 | - color: const Color(0xFF140C10) | 370 | + padding: EdgeInsets.symmetric(horizontal: 10.w), |
| 371 | + child: Container( | ||
| 372 | + width: 143.w, | ||
| 373 | + height: 143.h, | ||
| 374 | + padding: EdgeInsets.only(left: 13.w,right: 13.w,top: 13.h,bottom: 13.h), | ||
| 375 | + decoration: BoxDecoration( | ||
| 376 | + color: Colors.white, | ||
| 377 | + borderRadius: BorderRadius.circular(15), | ||
| 378 | + border: Border.all( | ||
| 379 | + width: 1.0, | ||
| 380 | + color: const Color(0xFF140C10) | ||
| 381 | + ), | ||
| 380 | ), | 382 | ), |
| 381 | - ), | ||
| 382 | - child: Column( | ||
| 383 | - mainAxisAlignment: MainAxisAlignment.end, | ||
| 384 | - children: [ | ||
| 385 | - Expanded( | ||
| 386 | - child: Container( | ||
| 387 | - alignment: Alignment.center, | ||
| 388 | - child: Text( | ||
| 389 | - 'yellow', | ||
| 390 | - style: TextStyle( | ||
| 391 | - fontSize: 20.sp, | ||
| 392 | - color: const Color(0xFF333333) | ||
| 393 | - ) | 383 | + child: Column( |
| 384 | + mainAxisAlignment: MainAxisAlignment.end, | ||
| 385 | + children: [ | ||
| 386 | + Expanded( | ||
| 387 | + child: Container( | ||
| 388 | + alignment: Alignment.center, | ||
| 389 | + child: Text( | ||
| 390 | + answerList.word??'', | ||
| 391 | + style: TextStyle( | ||
| 392 | + fontSize: 20.sp, | ||
| 393 | + color: const Color(0xFF333333) | ||
| 394 | + ) | ||
| 395 | + ), | ||
| 394 | ), | 396 | ), |
| 395 | ), | 397 | ), |
| 396 | - ), | ||
| 397 | - Container( | ||
| 398 | - height: 30.h, | ||
| 399 | - width: double.infinity, | ||
| 400 | - decoration: BoxDecoration( | ||
| 401 | - color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 402 | - borderRadius: BorderRadius.circular(15.r), | ||
| 403 | - border: Border.all( | ||
| 404 | - width: 1.5, | ||
| 405 | - color: const Color(0xFF140C10) | 398 | + Container( |
| 399 | + height: 30.h, | ||
| 400 | + width: double.infinity, | ||
| 401 | + decoration: BoxDecoration( | ||
| 402 | + color: bloc.selectItem == index?const Color(0xFF00B6F1):Colors.white, | ||
| 403 | + borderRadius: BorderRadius.circular(15.r), | ||
| 404 | + border: Border.all( | ||
| 405 | + width: 1.5, | ||
| 406 | + color: const Color(0xFF140C10) | ||
| 407 | + ), | ||
| 406 | ), | 408 | ), |
| 407 | - ), | ||
| 408 | - alignment: Alignment.center, | ||
| 409 | - child: Image.asset('choose'.assetPng), | ||
| 410 | - ) | ||
| 411 | - ], | 409 | + alignment: Alignment.center, |
| 410 | + child: Image.asset('choose'.assetPng), | ||
| 411 | + ) | ||
| 412 | + ], | ||
| 413 | + ), | ||
| 412 | ), | 414 | ), |
| 413 | ), | 415 | ), |
| 414 | ); | 416 | ); |
| 415 | }); | 417 | }); |
| 416 | 418 | ||
| 417 | ///语音问答 | 419 | ///语音问答 |
| 418 | - Widget _voiceAnswerItem() => BlocBuilder<TopicPictureBloc,TopicPictureState>( | 420 | + Widget _voiceAnswerItem(CourseProcessTopics? topics) => BlocBuilder<TopicPictureBloc,TopicPictureState>( |
| 419 | builder: (context, state) { | 421 | builder: (context, state) { |
| 422 | + final bloc = BlocProvider.of<TopicPictureBloc>(context); | ||
| 420 | return Row( | 423 | return Row( |
| 421 | - mainAxisAlignment: MainAxisAlignment.center, | ||
| 422 | - children: [ | ||
| 423 | - OwImageWidget( | ||
| 424 | - name:'https://up.enterdesk.com/edpic_source/16/e7/0d/16e70d550daff77cbac31fae5e1651d4.jpg', | ||
| 425 | - height: 186.h, | ||
| 426 | - width: 186.w, | ||
| 427 | - ), | ||
| 428 | - 160.horizontalSpace, | ||
| 429 | - Column( | ||
| 430 | mainAxisAlignment: MainAxisAlignment.center, | 424 | mainAxisAlignment: MainAxisAlignment.center, |
| 431 | children: [ | 425 | children: [ |
| 432 | - Image.asset( | ||
| 433 | - 'voice'.assetPng, | ||
| 434 | - height: 52.h, | ||
| 435 | - width: 46.w, | 426 | + OwImageWidget( |
| 427 | + name:'https://up.enterdesk.com/edpic_source/16/e7/0d/16e70d550daff77cbac31fae5e1651d4.jpg', | ||
| 428 | + height: 186.h, | ||
| 429 | + width: 186.w, | ||
| 436 | ), | 430 | ), |
| 437 | - 70.verticalSpace, | ||
| 438 | - Image.asset( | ||
| 439 | - 'micro_phone'.assetPng, | ||
| 440 | - height: 75.w, | ||
| 441 | - width: 75.w, | 431 | + 160.horizontalSpace, |
| 432 | + Column( | ||
| 433 | + mainAxisAlignment: MainAxisAlignment.center, | ||
| 434 | + children: [ | ||
| 435 | + Image.asset( | ||
| 436 | + 'voice'.assetPng, | ||
| 437 | + height: 52.h, | ||
| 438 | + width: 46.w, | ||
| 439 | + ), | ||
| 440 | + 70.verticalSpace, | ||
| 441 | + GestureDetector( | ||
| 442 | + onTap: () { | ||
| 443 | + if (bloc.isVoicing) { | ||
| 444 | + return; | ||
| 445 | + } | ||
| 446 | + bloc.add(VoiceXsTestEvent('Hello', 0,context.read<CacheBloc>().userEntity!.id)); | ||
| 447 | + }, | ||
| 448 | + child: Image.asset( | ||
| 449 | + 'micro_phone'.assetPng, | ||
| 450 | + height: 75.w, | ||
| 451 | + width: 75.w, | ||
| 452 | + ), | ||
| 453 | + ) | ||
| 454 | + ], | ||
| 442 | ) | 455 | ) |
| 443 | ], | 456 | ], |
| 444 | - ) | ||
| 445 | - ], | ||
| 446 | - ); | ||
| 447 | - }); | 457 | + ); |
| 458 | + }); | ||
| 448 | } | 459 | } |
| 449 | \ No newline at end of file | 460 | \ No newline at end of file |