123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- import 'package:flutter/material.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
- import 'package:youtube/data/models/call_model.dart';
- import 'package:youtube/presentaion/cubit/call/call_cubit.dart';
- import '../../shared/constats.dart';
- import '../../shared/shared_widgets.dart';
- import '../cubit/call/call_state.dart';
- import '../widgets/call_widgets/default_circle_image.dart';
- import '../widgets/call_widgets/user_info_header.dart';
- import 'package:agora_rtc_engine/rtc_local_view.dart' as rtc_local_view;
- import 'package:agora_rtc_engine/rtc_remote_view.dart' as rtc_remote_view;
- import 'package:permission_handler/permission_handler.dart';
- class CallScreen extends StatefulWidget {
- final bool isReceiver;
- final CallModel callModel;
- const CallScreen({Key? key, required this.isReceiver, required this.callModel}) : super(key: key);
- @override
- State<CallScreen> createState() => _CallScreenState();
- }
- class _CallScreenState extends State<CallScreen> {
- late CallCubit _callCubit;
- @override
- void initState() {
- super.initState();
- _callCubit = CallCubit.get(context);
- rePermission();
- _callCubit.listenToCallStatus(callModel: widget.callModel, context: context,isReceiver: widget.isReceiver);
- if(!widget.isReceiver){ //Caller
- _callCubit.initAgoraAndJoinChannel(channelToken: widget.callModel.token!,channelName: widget.callModel.channelName!,isCaller:true);
- }else{ //Receiver
- _callCubit.playContactingRing(isCaller: false);
- }
- }
- @override
- void dispose() {
- if(_callCubit.engine!=null){
- _callCubit.engine!.destroy();
- }
- _callCubit.assetsAudioPlayer.dispose();
- if(!widget.isReceiver){ //Sender
- _callCubit.countDownTimer.cancel();
- }
- _callCubit.performEndCall(callModel: widget.callModel);
- super.dispose();
- }
- Future<void> rePermission() async {
- // retrieve permissions
- await [Permission.microphone, Permission.camera].request();
- }
- @override
- Widget build(BuildContext context) {
- return BlocConsumer<CallCubit,CallState>(
- listener: (BuildContext context, Object? state) {
- if(state is ErrorUnAnsweredVideoChatState){
- showToast(msg: 'UnExpected Error!: ${state.error}');
- }
- if(state is DownCountCallTimerFinishState){
- if(_callCubit.remoteUid==null){
- _callCubit.updateCallStatusToUnAnswered(callId: widget.callModel.id);
- }
- }
- if(state is AgoraRemoteUserJoinedEvent){
- //remote user join channel
- if(!widget.isReceiver){ //Caller
- _callCubit.countDownTimer.cancel();
- }
- _callCubit.assetsAudioPlayer.stop(); //Sender, Receiver
- }
- //Call States
- if(state is CallNoAnswerState){
- if(!widget.isReceiver){ //Caller
- showToast(msg: 'No response!');
- }
- Navigator.pop(context);
- }
- if(state is CallCancelState){
- if(widget.isReceiver){ //Receiver
- showToast(msg: 'Caller cancel the call!');
- }
- Navigator.pop(context);
- }
- if(state is CallRejectState){
- if(!widget.isReceiver){ //Caller
- showToast(msg: 'Receiver reject the call!');
- }
- Navigator.pop(context);
- }
- if(state is CallEndState){
- showToast(msg: 'Call ended!');
- Navigator.pop(context);
- }
- },
- builder: (BuildContext context, state) {
- var cubit = CallCubit.get(context);
- return ModalProgressHUD(
- inAsyncCall: false,
- child: WillPopScope(
- onWillPop: () async { return false; },
- child: Scaffold(
- body: Stack(
- alignment: AlignmentDirectional.center,
- children: [
- cubit.remoteUid == null ? !widget.isReceiver ? Container(color: Colors.red,child: const rtc_local_view.SurfaceView()) : Container( //res
- decoration: BoxDecoration(
- image: DecorationImage(
- image: widget.callModel.callerAvatar!.isNotEmpty ? NetworkImage(
- widget.callModel.callerAvatar!,
- ) : const NetworkImage(
- 'https://picsum.photos/200/300',
- ),
- fit: BoxFit.cover,
- ),
- ),
- ) : Stack(
- children: [
- Center(
- child: _remoteVideo(remoteUserId: cubit.remoteUid!),
- ),
- const Align(
- alignment: Alignment.bottomRight,
- child: SizedBox(
- width: 122,
- height: 219.0,
- child: Center(
- child: rtc_local_view.SurfaceView(),
- ),
- ),
- ),
- ],
- ),
- Container(
- padding: const EdgeInsets.all(15.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- const SizedBox(height: 50.0,),
- !widget.isReceiver ? UserInfoHeader( //Caller -> Show Receiver INFO
- avatar: widget.callModel.receiverAvatar!,
- name: widget.callModel.receiverName!,
- ) : UserInfoHeader( //Receiver -> Show Caller INFO
- avatar: widget.callModel.callerAvatar!,
- name: widget.callModel.callerName!,
- ),
- const SizedBox(height: 30.0,),
- cubit.remoteUid ==null ? Expanded(
- child: widget.isReceiver ? Text('${widget.callModel.callerName} is calling you..',style: const TextStyle(color: Colors.white,fontSize: 39.0),)
- :const Text('Contacting..',style: TextStyle(color: Colors.white,fontSize: 39.0),),
- ) : Expanded(child: Container()),
- cubit.remoteUid ==null ? Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- widget.isReceiver ? Expanded(
- child: InkWell(
- onTap: (){
- //receiverAcceptVideoChat
- _callCubit.updateCallStatusToAccept(callModel: widget.callModel);
- },
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(15.0),
- color: Colors.green,
- ),
- child: const Center(
- child: Padding(
- padding: EdgeInsets.symmetric(horizontal: 30.0,vertical: 8.0),
- child: Text('Acceptance',style: TextStyle(color: Colors.white,fontSize: 13.0),),
- ),
- ),
- ),
- ),
- ) : Container(),
- widget.isReceiver ? const SizedBox(width: 15.0,) : Container(),
- Expanded(
- child: InkWell(
- onTap: (){
- if(widget.isReceiver){
- //receiverRejectVideoChat
- _callCubit.updateCallStatusToReject(callId: widget.callModel.id);
- }else{
- //callerCancelVideoChat
- _callCubit.updateCallStatusToCancel(callId: widget.callModel.id);
- }
- },
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(15.0),
- color: Colors.red,
- ),
- child: Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 30.0,vertical: 8.0),
- child: Text(widget.isReceiver ? 'Reject' : 'Cancel',style: const TextStyle(color: Colors.white,fontSize: 13.0),),
- ),
- ),
- ),
- ),
- )
- ],
- )
- : Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Expanded(
- child: GestureDetector(
- onTap: (){
- cubit.switchCamera();
- },
- child: const DefaultCircleImage(bgColor: Colors.white ,image: Icon(Icons.switch_camera_outlined,color: Colors.black,),center: true,width: 42,height: 42,),
- ),
- ),
- Expanded(
- child: GestureDetector(
- onTap: (){
- cubit.updateCallStatusToEnd(callId: widget.callModel.id);
- },
- child: const DefaultCircleImage(bgColor: Colors.red ,image: Icon(Icons.call_end_rounded,color: Colors.white,),center: true,width: 55,height: 55,)
- ),
- ),
- Expanded(
- child: GestureDetector(
- onTap: (){
- cubit.toggleMuted();
- },
- child: DefaultCircleImage(bgColor: Colors.white ,image: cubit.muteIcon ,center: true,width: 42,height: 42,),
- ),
- ),
- ],
- ),
- ],
- ),
- ),
- ],
- ) ,
- ),
- ),
- );
- },
- );
- }
- // Display remote user's video
- Widget _remoteVideo({required int remoteUserId}) {
- return rtc_remote_view.SurfaceView(uid: remoteUserId,channelId: /*widget.callModel.channelName!*/ agoraTestChannelName,);
- }
- }
|