Blame view

lib/pages/practice/bloc/topic_picture_bloc.dart 4.75 KB
2eb67dd4   liangchengyou   feat:调整代码
1
  import 'package:audioplayers/audioplayers.dart';
688b7b5c   liangchengyou   feat:更新文件结构
2
  import 'package:flutter/cupertino.dart';
2eb67dd4   liangchengyou   feat:调整代码
3
4
  import 'package:flutter/foundation.dart';
  import 'package:flutter/services.dart';
688b7b5c   liangchengyou   feat:更新文件结构
5
  import 'package:flutter_bloc/flutter_bloc.dart';
2eb67dd4   liangchengyou   feat:调整代码
6
7
8
9
10
  import 'package:flutter_easyloading/flutter_easyloading.dart';
  import 'package:wow_english/common/request/dao/listen_dao.dart';
  import 'package:wow_english/common/request/exception.dart';
  import 'package:wow_english/models/course_process_entity.dart';
  import 'package:wow_english/utils/loading.dart';
7652f701   liangchengyou   feat:课程购买UI逻辑
11
12
  
  part 'topic_picture_event.dart';
688b7b5c   liangchengyou   feat:更新文件结构
13
  part 'topic_picture_state.dart';
7652f701   liangchengyou   feat:课程购买UI逻辑
14
15
  
  class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> {
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
16
17
18
  
    final PageController pageController;
  
608c05b4   liangchengyou   feat:兑换课程
19
    final String courseLessonId;
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
20
21
22
  
    int _currentPage = 0;
  
2eb67dd4   liangchengyou   feat:调整代码
23
24
25
26
27
28
29
30
    int _selectItem = -1;
  
    CourseProcessEntity? _entity;
  
    ///正在评测
    bool _isVoicing = false;
  
    CourseProcessEntity? get entity => _entity;
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
31
32
33
34
35
  
    int get currentPage => _currentPage + 1;
  
    int get selectItem => _selectItem;
  
2eb67dd4   liangchengyou   feat:调整代码
36
37
    bool get isVoicing => _isVoicing;
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
38
    late MethodChannel methodChannel;
2eb67dd4   liangchengyou   feat:调整代码
39
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
40
    late AudioPlayer audioPlayer;
2eb67dd4   liangchengyou   feat:调整代码
41
  
608c05b4   liangchengyou   feat:兑换课程
42
    TopicPictureBloc(this.pageController, this.courseLessonId) : super(TopicPictureInitial()) {
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
43
      on<CurrentPageIndexChangeEvent>(_pageControllerChange);
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
44
      on<SelectItemEvent>(_selectItemLoad);
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
45
46
47
48
      on<RequestDataEvent>(_requestData);
      on<XSVoiceTestEvent>(_voiceXsTest);
      on<XSVoiceResultEvent>(_voiceXsResult);
      on<XSVoiceInitEvent>(_initVoiceSdk);
2eb67dd4   liangchengyou   feat:调整代码
49
      on<TopicPictureEvent>((event, emit) {
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
50
51
52
        //音频播放器
        audioPlayer = AudioPlayer();
        audioPlayer.onPlayerStateChanged.listen((event) {
b90a1518   liangchengyou   feat:练习接口逻辑完成
53
54
55
          if (event == PlayerState.completed) {
            if (kDebugMode) {
              print('播放完成');
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
56
  
b90a1518   liangchengyou   feat:练习接口逻辑完成
57
            }}
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
58
59
        });
  
2eb67dd4   liangchengyou   feat:调整代码
60
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
61
        methodChannel = const MethodChannel('wow_english/sing_sound_method_channely');
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
62
        methodChannel.setMethodCallHandler((call) async {
b90a1518   liangchengyou   feat:练习接口逻辑完成
63
          if (call.method == 'voiceResult') {//评测结果
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
64
            add(XSVoiceResultEvent(call.arguments));
b90a1518   liangchengyou   feat:练习接口逻辑完成
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
            return;
          }
  
          if (call.method == 'voiceStart') {//评测开始
            if (kDebugMode) {
              print('评测开始');
            }
            return;
          }
  
          if (call.method == 'voiceEnd') {//评测结束
            if (kDebugMode) {
              print('评测结束');
            }
            return;
          }
  
          if (call.method == 'voiceFail') {//评测失败
            EasyLoading.showToast('评测失败');
            return;
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
85
86
          }
        });
2eb67dd4   liangchengyou   feat:调整代码
87
      });
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
88
89
90
91
92
    }
  
    @override
    Future<void> close() {
      pageController.dispose();
2eb67dd4   liangchengyou   feat:调整代码
93
      audioPlayer.dispose();
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
94
95
96
      return super.close();
    }
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
97
    ///请求数据
2eb67dd4   liangchengyou   feat:调整代码
98
99
100
    void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async {
      try {
        await loading(() async {
608c05b4   liangchengyou   feat:兑换课程
101
          _entity = await ListenDao.process(courseLessonId);
2eb67dd4   liangchengyou   feat:调整代码
102
103
104
105
106
107
108
109
110
          emitter(RequestDataState());
        });
      } catch (e) {
        if (e is ApiException) {
          EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
        }
      }
    }
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
111
112
113
114
115
116
    ///初始化SDK
    _initVoiceSdk(XSVoiceInitEvent event,Emitter<TopicPictureState> emitter) async {
      methodChannel.invokeMethod('initVoiceSdk',event.data);
    }
  
    ///页面切换
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
117
118
    void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async {
      _currentPage = event.pageIndex;
2eb67dd4   liangchengyou   feat:调整代码
119
      final topics = _entity?.topics?[_currentPage];
b90a1518   liangchengyou   feat:练习接口逻辑完成
120
121
      if (topics?.type == 1 || topics?.type == 2 || topics?.type == 5) {
        audioPlayer.stop();
2eb67dd4   liangchengyou   feat:调整代码
122
123
124
125
126
127
128
129
130
        if (topics?.audioUrl != null) {
          final urlStr = topics?.audioUrl??'';
          if (urlStr.isNotEmpty) {
            audioPlayer.play(UrlSource(urlStr));
          }
        }
      } else {
        audioPlayer.stop();
      }
b90a1518   liangchengyou   feat:练习接口逻辑完成
131
      _selectItem = -1;
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
132
133
134
      emitter(CurrentPageIndexState());
    }
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
135
    ///选择
624214d0   liangchengyou   feat:看题选字/选图UI和部分逻辑
136
137
138
    void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async {
      _selectItem = event.selectIndex;
      emitter(SelectItemChangeState());
7652f701   liangchengyou   feat:课程购买UI逻辑
139
    }
2eb67dd4   liangchengyou   feat:调整代码
140
  
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
141
142
143
144
    ///先声测试
    void _voiceXsTest(XSVoiceTestEvent event,Emitter<TopicPictureState> emitter) async {
      EasyLoading.show(status: '录音中....');
      methodChannel.invokeMethod(
b90a1518   liangchengyou   feat:练习接口逻辑完成
145
          'starVoice',
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
146
147
148
149
150
151
152
153
          {'word':event.testWord,'type':event.type,'userId':event.userId.toString()}
      );
      _isVoicing = true;
      emitter(XSVoiceTestState());
    }
  
    void _voiceXsResult(XSVoiceResultEvent event,Emitter<TopicPictureState> emitter) async {
      final Map args = event.message as Map;
2eb67dd4   liangchengyou   feat:调整代码
154
155
156
157
158
159
160
      final result = args['result'] as String;
      if (result == '1') {
        final overall = args['overall'].toString();
        EasyLoading.showToast('测评成功,分数是$overall',duration: const Duration(seconds: 10));
      } else {
        EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10));
      }
2eb67dd4   liangchengyou   feat:调整代码
161
      _isVoicing = false;
e3c2820c   liangchengyou   feat:先声SDK逻辑调整
162
      emitter(XSVoiceTestState());
2eb67dd4   liangchengyou   feat:调整代码
163
    }
7652f701   liangchengyou   feat:课程购买UI逻辑
164
  }