reading_bloc.dart 5 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/pages/reading/widgets/ReadingModeType.dart';

import '../../../common/request/dao/listen_dao.dart';
import '../../../common/request/exception.dart';
import '../../../models/course_process_entity.dart';
import '../../../utils/loading.dart';

part 'reading_event.dart';
part 'reading_state.dart';

class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> {
  final PageController pageController;

  ///当前页索引
  int _currentPage = 0;

  ///当前播放模式
  ReadingModeType _currentMode = ReadingModeType.auto;

  int get currentPage => _currentPage + 1;

  ReadingModeType get currentMode => _currentMode;

  CourseProcessEntity? _entity;

  CourseProcessEntity? get entity => _entity;

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

  bool get isRecording => _isRecording;

  late MethodChannel methodChannel;

  late AudioPlayer audioPlayer;

  ReadingPageBloc(this.pageController) : super(ReadingPageInitial()) {
    on<CurrentPageIndexChangeEvent>(_pageControllerChange);
    on<CurrentModeChangeEvent>(_selectItemLoad);
    // pageController.addListener(() {
    //   _currentPage = pageController.page!.round();
    // });
    on<RequestDataEvent>(_requestData);
    on<ReadingPageEvent>((event, emit) {
      //音频播放器
      audioPlayer = AudioPlayer();
      audioPlayer.onPlayerStateChanged.listen((event) {
        if (event == PlayerState.completed) {
          if (kDebugMode) {
            print('绘本播放完成');

          }
        }
      });

      methodChannel = const MethodChannel('sing_sound_method_channel');
      methodChannel.invokeMethod('initVoiceSdk',{});
      methodChannel.setMethodCallHandler((call) async {
        if (call.method == 'voiceResult') {//评测结束
          // add(XSVoiceResultEvent(call.arguments));
        }
      });
    });
    on<PlayOriginalAudioEvent>(_playOriginalAudio);
    on<XSVoiceTestEvent>(_voiceXsTest);
    on<XSVoiceResultEvent>(_voiceXsResult);
  }

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

  void _pageControllerChange(CurrentPageIndexChangeEvent event,
      Emitter<ReadingPageState> emitter) async {
    _currentPage = event.pageIndex;
    _playOriginVoice(null);
    emitter(CurrentPageIndexState());
  }

  void _selectItemLoad(
      CurrentModeChangeEvent event, Emitter<ReadingPageState> emitter) async {
    if (_currentMode == ReadingModeType.auto) {
      _currentMode = ReadingModeType.manual;
    } else {
      _currentMode = ReadingModeType.auto;
    }
    emitter(CurrentModeState());
  }

  ///请求数据
  void _requestData(
      RequestDataEvent event, Emitter<ReadingPageState> emitter) async {
    try {
      await loading(() async {
        _entity = await ListenDao.process('1');
        print("reading page entity: ${_entity!.toJson()}");
        emitter(RequestDataState());
      });
    } catch (e) {
      if (e is ApiException) {
        EasyLoading.showToast(e.message ?? '请求失败,请检查网络连接');
      }
    }
  }

  void _playOriginalAudio(PlayOriginalAudioEvent event, Emitter<ReadingPageState> emitter) async {
    print("_playOriginalAudio");
    _playOriginVoice(event.url);
  }

  /// 播放绘本原音
  void _playOriginVoice(String? audioUrl) async {
    audioPlayer.stop();
    final readingData = currentPageData();
    if (readingData?.audioUrl != null) {
      final urlStr = audioUrl ?? readingData?.audioUrl ?? '';
      if (urlStr.isNotEmpty) {
        audioPlayer.play(UrlSource(urlStr));
      }
    }
  }

  int dataCount() {
    // print("dataCount=${_entity?.readings?.length ?? 0}");
    return _entity?.readings?.length ?? 0;
  }

  CourseProcessReadings? currentPageData() {
    return _entity?.readings?[_currentPage];
  }

  ///先声测试
  void _voiceXsTest(XSVoiceTestEvent event, Emitter<ReadingPageState> emitter) async {
    startRecord(event.content);
    emitter(XSVoiceTestState());
  }

  void startRecord(String content) async {
    if (_isRecording == true) {
      return;
    }
    EasyLoading.show(status: '录音中....');
    methodChannel.invokeMethod(
        'startVoice',
        {'word':'how old are you','type':'0','userId':'1'}
    );
    _isRecording = true;
  }

  void _voiceXsResult(XSVoiceResultEvent event,Emitter<ReadingPageState> 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));
    }
    _isRecording = false;
    emitter(XSVoiceTestState());
  }
}