topic_picture_bloc.dart 4.75 KB
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
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';

part 'topic_picture_event.dart';
part 'topic_picture_state.dart';

class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> {

  final PageController pageController;

  final String courseLessonId;

  int _currentPage = 0;

  int _selectItem = -1;

  CourseProcessEntity? _entity;

  ///正在评测
  bool _isVoicing = false;

  CourseProcessEntity? get entity => _entity;

  int get currentPage => _currentPage + 1;

  int get selectItem => _selectItem;

  bool get isVoicing => _isVoicing;

  late MethodChannel methodChannel;

  late AudioPlayer audioPlayer;

  TopicPictureBloc(this.pageController, this.courseLessonId) : super(TopicPictureInitial()) {
    on<CurrentPageIndexChangeEvent>(_pageControllerChange);
    on<SelectItemEvent>(_selectItemLoad);
    on<RequestDataEvent>(_requestData);
    on<XSVoiceTestEvent>(_voiceXsTest);
    on<XSVoiceResultEvent>(_voiceXsResult);
    on<XSVoiceInitEvent>(_initVoiceSdk);
    on<TopicPictureEvent>((event, emit) {
      //音频播放器
      audioPlayer = AudioPlayer();
      audioPlayer.onPlayerStateChanged.listen((event) {
        if (event == PlayerState.completed) {
          if (kDebugMode) {
            print('播放完成');

          }}
      });


      methodChannel = const MethodChannel('wow_english/sing_sound_method_channely');
      methodChannel.setMethodCallHandler((call) async {
        if (call.method == 'voiceResult') {//评测结果
          add(XSVoiceResultEvent(call.arguments));
          return;
        }

        if (call.method == 'voiceStart') {//评测开始
          if (kDebugMode) {
            print('评测开始');
          }
          return;
        }

        if (call.method == 'voiceEnd') {//评测结束
          if (kDebugMode) {
            print('评测结束');
          }
          return;
        }

        if (call.method == 'voiceFail') {//评测失败
          EasyLoading.showToast('评测失败');
          return;
        }
      });
    });
  }

  @override
  Future<void> close() {
    pageController.dispose();
    audioPlayer.dispose();
    return super.close();
  }

  ///请求数据
  void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async {
    try {
      await loading(() async {
        _entity = await ListenDao.process(courseLessonId);
        emitter(RequestDataState());
      });
    } catch (e) {
      if (e is ApiException) {
        EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
      }
    }
  }

  ///初始化SDK
  _initVoiceSdk(XSVoiceInitEvent event,Emitter<TopicPictureState> emitter) async {
    methodChannel.invokeMethod('initVoiceSdk',event.data);
  }

  ///页面切换
  void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async {
    _currentPage = event.pageIndex;
    final topics = _entity?.topics?[_currentPage];
    if (topics?.type == 1 || topics?.type == 2 || topics?.type == 5) {
      audioPlayer.stop();
      if (topics?.audioUrl != null) {
        final urlStr = topics?.audioUrl??'';
        if (urlStr.isNotEmpty) {
          audioPlayer.play(UrlSource(urlStr));
        }
      }
    } else {
      audioPlayer.stop();
    }
    _selectItem = -1;
    emitter(CurrentPageIndexState());
  }

  ///选择
  void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async {
    _selectItem = event.selectIndex;
    emitter(SelectItemChangeState());
  }

  ///先声测试
  void _voiceXsTest(XSVoiceTestEvent event,Emitter<TopicPictureState> emitter) async {
    EasyLoading.show(status: '录音中....');
    methodChannel.invokeMethod(
        'startVoice',
        {'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;
    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));
    }
    _isVoicing = false;
    emitter(XSVoiceTestState());
  }
}