import 'dart:convert'; import 'dart:core'; import 'dart:ui'; import 'package:draggable_widget/draggable_widget.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/main.dart'; import 'package:mohem_flutter_app/models/chat/call.dart'; import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart'; import 'package:mohem_flutter_app/models/chat/incoming_call_model.dart'; import 'package:mohem_flutter_app/provider/chat_call_provider.dart'; import 'package:mohem_flutter_app/provider/chat_provider_model.dart'; import 'package:provider/provider.dart'; class StartCallPage extends StatefulWidget { @override _StartCallPageState createState() => _StartCallPageState(); } class _StartCallPageState extends State { DragController dragController = DragController(); bool isOutGoingCall = false; bool isIncomingCall = false; late ChatCallProvider cProv; late ChatProviderModel provider; @override void initState() { cProv = Provider.of(context, listen: false); provider = Provider.of(context, listen: false); super.initState(); startCall(); } @override void dispose() { super.dispose(); } void startCall() async { IncomingCallModel? sessionData; dynamic calls = await FlutterCallkitIncoming.activeCalls(); if (calls.isNotEmpty) { sessionData = IncomingCallModel.fromRawJson(jsonEncode(calls[0])); isIncomingCall = sessionData.extra!.isIncomingCall!; } if (isIncomingCall) { if (provider.isUserOnline) { if (kDebugMode) { print("====== Processing Incoming Call in Online State ========="); } await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson()); cProv.init(); } else { if (kDebugMode) { print("====== Processing Incoming Call ========="); } await cProv.startIncomingCallViaKit(inCallData: sessionData!.extra!.callerDetails!.toJson()); try { AppState().setchatUserDetails = UserAutoLoginModel(response: Response.fromJson(sessionData.extra!.loginDetails!.toJson()), errorResponses: null); await provider.buildHubConnection(context: context, ccProvider: cProv).whenComplete(() { cProv.init(); }); } catch (e) { logger.w(e); } if (kDebugMode) { print('========== END =============='); } } } // else if (isOutGoingCall) { // if (kDebugMode) { // print("====== Processing Outgoing Call ========="); // } // // } else { if (kDebugMode) { print("====== Something Wrong With Call ========="); } } } // void connection({required data, required bool isUserOnline}) async { // if (isUserOnline) { // cProv.isUserOnline = isUserOnline; // cProv.startIncomingCallViaKit(inCallData: data); // } else { // dynamic callData = await jsonDecode(data); // AppState().setchatUserDetails = UserAutoLoginModel( // response: Response.fromJson(callData[0]["loginDetails"]), // errorResponses: null, // ); // Utils.saveStringFromPrefs( // "userLoginChatDetails", // UserAutoLoginModel( // response: Response.fromJson(callData[0]["loginDetails"]), // errorResponses: null, // ).toJson().toString()); // cProv.startIncomingCallViaKit(inCallData: data); // try { // await prov.buildHubConnection(context: AppRoutes.navigatorKey.currentContext!, ccProvider: cProv).whenComplete(() { // cProv.init(); // }); // } catch (e) { // logger.w(e); // } // } // } @override Widget build(BuildContext context) { return Scaffold( extendBody: true, body: Consumer2( builder: (BuildContext context, ChatCallProvider provider, ChatProviderModel cpm, Widget? child) { return provider.isIncomingCallLoader ? const SizedBox( width: double.infinity, height: double.infinity, child: Center(child: CircularProgressIndicator()), ) : provider.isIncomingCall ? SizedBox( width: double.infinity, height: double.infinity, child: Stack( alignment: FractionalOffset.center, children: [ if (!provider.isAudioCall && provider.isVideoCall) Positioned.fill( child: RTCVideoView( provider.remoteRenderer, objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, key: const Key('remote'), ), ), if (provider.isVideoCall) DraggableWidget( bottomMargin: 20, topMargin: 40, intialVisibility: true, horizontalSpace: 20, shadowBorderRadius: 50, initialPosition: AnchoringPosition.topLeft, dragController: dragController, normalShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), draggingShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), child: SizedBox( height: 200, width: 140, child: RTCVideoView( provider.localVideoRenderer, mirror: true, objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, ), ), ), if (!provider.isVideoCall) Positioned.fill( child: ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), child: Container( decoration: BoxDecoration( color: MyColors.grey57Color.withOpacity( 0.3, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ 40.height, Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( margin: const EdgeInsets.all(21.0), child: Container( margin: const EdgeInsets.only( left: 10.0, right: 10.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ SvgPicture.asset( "assets/images/user.svg", height: 70, width: 70, fit: BoxFit.cover, ), 10.height, Text( provider.outGoingCallData.receiverName!, style: const TextStyle( fontSize: 21, decoration: TextDecoration.none, fontWeight: FontWeight.bold, color: MyColors.white, letterSpacing: -1.26, height: 23 / 12, ), ), const Text( "On Call", style: TextStyle( fontSize: 16, decoration: TextDecoration.none, fontWeight: FontWeight.w600, color: Color( 0xffC6C6C6, ), letterSpacing: -0.48, height: 23 / 24, ), ), const SizedBox( height: 2, ), ], ), ), ), ], ), ], ), ), ), ), ), Align( alignment: Alignment.bottomCenter, child: Container( padding: const EdgeInsets.only( bottom: 20, left: 40, right: 40, ), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // if (provider.isVideoCall) RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.loudOn(); }, elevation: 2.0, fillColor: provider.isLoudSpeaker ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: const Icon( Icons.volume_up, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.camOff(); }, elevation: 2.0, fillColor: provider.isCamOff ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isCamOff ? Icons.videocam_off : Icons.videocam, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.switchCamera(); }, elevation: 2.0, fillColor: provider.isFrontCamera ? Colors.grey : MyColors.textMixColor, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.micOff(); }, elevation: 2.0, fillColor: provider.isMicOff ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isMicOff ? Icons.mic_off : Icons.mic, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.endCall(isUserOnline: cpm.isUserOnline).then((bool value) { if (value) { Navigator.of(context).pop(); print("Reintiiiiiiitttiiiiiiii"); provider.initStreams(); } }); }, elevation: 2.0, fillColor: MyColors.redA3Color, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: const Icon( Icons.call_end, color: MyColors.white, size: 30.0, ), ), ], ), ), ), ], ), ) : provider.isOutGoingCall ? SizedBox( width: double.infinity, height: double.infinity, child: Stack( alignment: FractionalOffset.center, children: [ if (!provider.isAudioCall && provider.isVideoCall) Positioned.fill( child: RTCVideoView( provider.remoteRenderer, objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, key: const Key('remote'), ), ), if (provider.isVideoCall) DraggableWidget( bottomMargin: 20, topMargin: 40, intialVisibility: true, horizontalSpace: 20, shadowBorderRadius: 50, initialPosition: AnchoringPosition.topLeft, dragController: dragController, normalShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), draggingShadow: const BoxShadow(spreadRadius: 0.0, blurRadius: 0.0), child: SizedBox( height: 200, width: 140, child: RTCVideoView( provider.localVideoRenderer, mirror: true, objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover, ), ), ), if (!provider.isVideoCall) Positioned.fill( child: ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), child: Container( decoration: BoxDecoration( color: MyColors.grey57Color.withOpacity( 0.3, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ 40.height, Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( margin: const EdgeInsets.all(21.0), child: Container( margin: const EdgeInsets.only( left: 10.0, right: 10.0, ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ SvgPicture.asset( "assets/images/user.svg", height: 70, width: 70, fit: BoxFit.cover, ), 10.height, Text( provider.outGoingCallData.receiverName!, style: const TextStyle( fontSize: 21, decoration: TextDecoration.none, fontWeight: FontWeight.bold, color: MyColors.white, letterSpacing: -1.26, height: 23 / 12, ), ), const Text( "On Call", style: TextStyle( fontSize: 16, decoration: TextDecoration.none, fontWeight: FontWeight.w600, color: Color( 0xffC6C6C6, ), letterSpacing: -0.48, height: 23 / 24, ), ), const SizedBox( height: 2, ), ], ), ), ), ], ), ], ), ), ), ), ), Align( alignment: Alignment.bottomCenter, child: Container( padding: const EdgeInsets.only( bottom: 20, left: 40, right: 40, ), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // if (provider.isVideoCall) RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.loudOn(); }, elevation: 2.0, fillColor: provider.isLoudSpeaker ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: const Icon( Icons.volume_up, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.camOff(); }, elevation: 2.0, fillColor: provider.isCamOff ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isCamOff ? Icons.videocam_off : Icons.videocam, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.switchCamera(); }, elevation: 2.0, fillColor: provider.isFrontCamera ? Colors.grey : MyColors.textMixColor, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isFrontCamera ? Icons.switch_camera_outlined : Icons.switch_camera, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.micOff(); }, elevation: 2.0, fillColor: provider.isMicOff ? MyColors.textMixColor : Colors.grey, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: Icon( provider.isMicOff ? Icons.mic_off : Icons.mic, color: MyColors.white, size: 30.0, ), ), RawMaterialButton( constraints: const BoxConstraints(), onPressed: () { provider.endCall(isUserOnline: cpm.isUserOnline).then((bool value) { if (value) { Navigator.of(context).pop(); } }); }, elevation: 2.0, fillColor: MyColors.redA3Color, padding: const EdgeInsets.all( 10.0, ), shape: const CircleBorder(), child: const Icon( Icons.call_end, color: MyColors.white, size: 30.0, ), ), ], ), ), ), ], ), ) : const SizedBox(); }, ), ); } } /// if (Platform.isAndroid) { // SystemNavigator.pop(); // } else if (Platform.isIOS) { // exit(0); // }