import ' dart:convert ' ;
import ' dart:core ' ;
import ' dart:io ' ;
import ' dart:ui ' ;
import ' package:diplomaticquarterapp/app_state/app_state.dart ' ;
import ' package:diplomaticquarterapp/voipcall/consts.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/call.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/get_single_user_chat_call.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/get_user_login_token.dart ' ;
import ' package:diplomaticquarterapp/voipcall/model/incoming_call_model.dart ' ;
import ' package:diplomaticquarterapp/voipcall/provider/chat_call_provider.dart ' ;
import ' package:draggable_widget/draggable_widget.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter_svg/flutter_svg.dart ' ;
import ' package:flutter_webrtc/flutter_webrtc.dart ' ;
import ' package:provider/provider.dart ' ;
bool isCallConnected = false ;
class StartCallPage extends StatefulWidget {
IosCallPayload ? payload ;
StartCallPage ( { this . payload } ) ;
@ override
_StartCallPageState createState ( ) = > _StartCallPageState ( ) ;
}
class _StartCallPageState extends State < StartCallPage > {
DragController dragController = DragController ( ) ;
ChatCallProvider ? cProv ;
@ override
void initState ( ) {
super . initState ( ) ;
}
@ override
void dispose ( ) {
super . dispose ( ) ;
}
void startCall ( ) async {
IncomingCallModel ? sessionData ;
// dynamic calls = await FlutterCallkitIncoming.activeCalls();
// if (calls.isNotEmpty) {
// sessionData.extra.callerDetails = {"id":341682,"userName":"Aamir.Muhammad","email":"Aamir.Muhammad@cloudsolutions.com.sa","phone":null,"title":"Aamir Saleem Ahmad Dost Muhammad","token":"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIzNDE2ODIiLCJlbWFpbCI6IkFhbWlyLk11aGFtbWFkQGNsb3Vkc29sdXRpb25zLmNvbS5zYSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvdXNlcmRhdGEiOiJBYW1pci5NdWhhbW1hZCIsIm5iZiI6MTcwNzIwNTAyMywiZXhwIjoxNzA3MjkxNDIzLCJpYXQiOjE3MDcyMDUwMjN9.Zz2bcsMwiLAAWGZh2E_p5Qs6ItMt0JHhDFI_0DLdggCQtt6HHcT4n8nvqMZx-uYr3jLwqhA_IAjTuaCeSE15sw","isDomainUser":true,"isActiveCode":false,"encryptedUserId":"nn7RkYzbnQc=","encryptedUserName":"/QruOyp4QMcmNXKZlljUgg=="};
// sessionData = IncomingCallModel.fromRawJson(jsonEncode(calls[0]));
if ( kDebugMode ) {
print ( sessionData ! . toRawJson ( ) ) ;
}
if ( cProv ! . isUserOnline ) {
AppState ( ) . isBackgroundCall = true ;
if ( kDebugMode ) {
print ( " ====== Processing Incoming Call in Online State ========= " ) ;
}
await cProv ! . startIncomingCallViaKit ( inCallData: sessionData ! . extra ! . callerDetails ! . toJson ( ) , isVCall: sessionData . extra ! . callType = = " video " ? true : false ) ;
cProv ! . init ( ) ;
isCallConnected = true ;
} else {
AppState ( ) . isBackgroundCall = true ;
if ( kDebugMode ) {
print ( " ====== Processing Incoming Call ========= " ) ;
}
// cProv.isUserOnline = provider.isUserOnline;
await cProv ! . startIncomingCallViaKit ( inCallData: sessionData ! . extra ! . callerDetails ! . toJson ( ) , isVCall: sessionData ! . extra ! . callType = = " video " ? true : false ) ;
try {
AppState ( ) . setchatUserDetails = UserAutoLoginModel ( response: Response . fromJson ( sessionData . extra ! . loginDetails ! . toJson ( ) ) , errorResponses: null ) ;
// await cProv!.buildHubConnection().whenComplete(() {
// cProv!.init();
// isCallConnected = true;
// });
} catch ( e ) {
print ( e ) ;
}
}
//}
// cProv.startRecording();
}
void startIosCall ( ) async {
IosCallPayload iosCallPayload = widget . payload ! ;
var userID = iosCallPayload . incomingCallReciverId ;
var callType = iosCallPayload . incomingCallType ;
SingleUserChatModel inCallData = SingleUserChatModel (
targetUserName: iosCallPayload . incomingCallerName ,
chatEventId: 3 ,
targetUserId: int . parse ( iosCallPayload . incomingCallerId ! ) ,
currentUserId: int . parse ( userID . toString ( ) ) ,
) ;
if ( cProv ! . isUserOnline ) {
AppState ( ) . isBackgroundCall = true ;
if ( kDebugMode ) {
print ( " ====== Processing Incoming Call in Online State ========= " ) ;
}
await cProv ! . startIncomingCallViaKit ( inCallData: inCallData . toJson ( ) , isVCall: callType = = " video " ? true : false ) ;
cProv ! . init ( ) ;
isCallConnected = true ;
} else {
if ( kDebugMode ) {
print ( " ====== Processing Incoming Call ========= " ) ;
}
AppState ( ) . isBackgroundCall = true ;
UserAutoLoginModel userLoginResponse = await ChatService ( ) . getUserCallToken ( userid: userID . toString ( ) ) ;
if ( userLoginResponse . response ! = null ) {
AppState ( ) . setchatUserDetails = userLoginResponse ;
AppSharedPrefs ( ) . setStringFromPrefs ( " userLoginChatDetails " , jsonEncode ( userLoginResponse . response ) ) ;
await cProv ! . startIncomingCallViaKit ( inCallData: inCallData . toJson ( ) , isVCall: callType = = " video " ? true : false ) ;
try {
AppState ( ) . setchatUserDetails = UserAutoLoginModel ( response: userLoginResponse . response , errorResponses: null ) ;
// await cProv!.buildHubConnection().whenComplete(() {
// cProv!.init();
// isCallConnected = true;
// });
} catch ( e ) {
print ( e ) ;
}
}
}
}
@ override
Widget build ( BuildContext context ) {
cProv = context . read < ChatCallProvider > ( ) ;
if ( ! cProv ! . isOutGoingCall ) {
if ( Platform . isAndroid ) {
startCall ( ) ;
} else if ( Platform . isIOS ) {
// cProv!.buildHubConnection();
// startIosCall();
}
}
return Scaffold (
extendBody: true ,
body: Consumer < ChatCallProvider > (
builder: ( BuildContext context , ChatCallProvider prov , Widget ? child ) {
return prov . isIncomingCallLoader
? const SizedBox (
width: double . infinity ,
height: double . infinity ,
child: Center ( child: CircularProgressIndicator ( ) ) ,
)
: prov . isIncomingCall
? Container (
width: double . infinity ,
height: double . infinity ,
color: Colors . black ,
child: Stack (
alignment: FractionalOffset . center ,
children: < Widget > [
if ( ! prov . isAudioCall & & prov . isVideoCall )
RTCVideoView (
prov . remoteRenderer ! ,
objectFit: RTCVideoViewObjectFit . RTCVideoViewObjectFitContain ,
key: const Key ( ' remote ' ) ,
) ,
if ( prov . 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 (
prov . localVideoRenderer ! ,
mirror: true ,
// filterQuality: FilterQuality.high,
objectFit: RTCVideoViewObjectFit . RTCVideoViewObjectFitCover ,
) ,
) ,
) ,
if ( ! prov . 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: < Widget > [
SizedBox (
height: 40 ,
) ,
Row (
crossAxisAlignment: CrossAxisAlignment . center ,
mainAxisAlignment: MainAxisAlignment . center ,
children: < Widget > [
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: < Widget > [
SvgPicture . asset (
" assets/images/user.svg " ,
height: 70 ,
width: 70 ,
fit: BoxFit . cover ,
) ,
SizedBox (
height: 10 ,
) ,
Text (
prov . incomingCallData ! . targetUserName ? ? " " ,
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: < Widget > [
// if (provider.isVideoCall)
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . loudOn ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . 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 ,
) ,
) ,
if ( prov . isVideoCall )
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . camOff ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isCamOff ? MyColors . textMixColor : Colors . grey ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isCamOff ? Icons . videocam_off : Icons . videocam ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
if ( prov . isVideoCall )
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . switchCamera ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isFrontCamera ? Colors . grey : MyColors . textMixColor ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isFrontCamera ? Icons . switch_camera_outlined : Icons . switch_camera ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . micOff ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isMicOff ? MyColors . textMixColor : Colors . grey ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isMicOff ? Icons . mic_off : Icons . mic ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . endCall ( isUserOnline: prov . 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 ,
) ,
) ,
] ,
) ,
) ,
) ,
] ,
) ,
)
: prov . isOutGoingCall
? Container (
width: double . infinity ,
height: double . infinity ,
color: Colors . black ,
child: Stack (
alignment: FractionalOffset . center ,
children: < Widget > [
if ( ! prov . isAudioCall & & prov . isVideoCall )
RTCVideoView (
prov . remoteRenderer ! ,
objectFit: RTCVideoViewObjectFit . RTCVideoViewObjectFitContain ,
key: const Key ( ' remote ' ) ,
) ,
if ( prov . 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 (
prov . localVideoRenderer ! ,
mirror: true ,
objectFit: RTCVideoViewObjectFit . RTCVideoViewObjectFitCover ,
) ,
) ,
) ,
if ( ! prov . 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: < Widget > [
SizedBox (
height: 40 ,
) ,
Row (
crossAxisAlignment: CrossAxisAlignment . center ,
mainAxisAlignment: MainAxisAlignment . center ,
children: < Widget > [
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: < Widget > [
SvgPicture . asset (
" assets/images/user.svg " ,
height: 70 ,
width: 70 ,
fit: BoxFit . cover ,
) ,
SizedBox (
height: 10 ,
) ,
Text (
prov . 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: < Widget > [
// if (provider.isVideoCall)
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . loudOn ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . 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 ,
) ,
) ,
if ( prov . isVideoCall )
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . camOff ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isCamOff ? MyColors . textMixColor : Colors . grey ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isCamOff ? Icons . videocam_off : Icons . videocam ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
if ( prov . isVideoCall )
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . switchCamera ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isFrontCamera ? Colors . grey : MyColors . textMixColor ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isFrontCamera ? Icons . switch_camera_outlined : Icons . switch_camera ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . micOff ( ) ;
} ,
elevation: 2.0 ,
fillColor: prov . isMicOff ? MyColors . textMixColor : Colors . grey ,
padding: const EdgeInsets . all (
10.0 ,
) ,
shape: const CircleBorder ( ) ,
child: Icon (
prov . isMicOff ? Icons . mic_off : Icons . mic ,
color: MyColors . white ,
size: 30.0 ,
) ,
) ,
RawMaterialButton (
constraints: const BoxConstraints ( ) ,
onPressed: ( ) {
prov . endCall ( isUserOnline: prov . 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 ( ) ;
} ,
) ,
) ;
}
}