topic_picture_bloc.dart 4.13 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 int modelCount;

  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;

  var messageChannel = const BasicMessageChannel('com.owEnglish.voiceXs.BasicMessageChannel', StandardMessageCodec());

  final audioPlayer = AudioPlayer();

  TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) {
    on<CurrentPageIndexChangeEvent>(_pageControllerChange);
    on<InitMessageChannelEvent>(_initMessageChannelCall);
    on<RequestDataEvent>(_requestData);
    on<SelectItemEvent>(_selectItemLoad);
    on<VoiceXsTestEvent>(_voiceXsTest);
    on<VoiceResultEvent>(_voiceResult);
    on<TopicPictureEvent>((event, emit) {

    });
  }

  @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('8');
        emitter(RequestDataState());
      });
    } catch (e) {
      if (e is ApiException) {
        EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
      }
    }
  }

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

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

  ///messageChannel回调
  Future messageResultHandler(message,Emitter<TopicPictureState> emitter) async {
     EasyLoading.dismiss();
    final Map args = 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));
    }
    if (kDebugMode) {
      print('是否被移除>>>>>$emitter');
    }
    _isVoicing = false;
  }

  Future _initMessageChannelCall(InitMessageChannelEvent event,Emitter<TopicPictureState> emitter) async {
    messageChannel.setMessageHandler((message) =>
        messageResultHandler(message, emitter)
    );

    audioPlayer.onPlayerStateChanged.listen((event) {
      if (event == PlayerState.stopped) {
        if (kDebugMode) {
          print('播放结束');
        }
      }
    });
  }

  void _voiceXsTest(VoiceXsTestEvent event,Emitter<TopicPictureState> emitter) async {
    EasyLoading.show(status: '录音中....');
    messageChannel.send({'word':event.testWord,'type':event.type,'userId':event.userId.toString()});
    _isVoicing = true;
    emitter(VoiceXsTestState());
  }

  void _voiceResult(VoiceResultEvent event,Emitter<TopicPictureState> emitter) async {
    _isVoicing = false;
    emitter(VoiceXsTestState());
  }
}