You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PatientApp-KKUMC/lib/pages/livecare/incoming_call.dart

327 lines
14 KiB
Dart

import 'dart:ui';
import 'package:camera/camera.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/signaling.dart';
import 'package:diplomaticquarterapp/pages/videocall-webrtc-rnd/webrtc/start_video_call.dart';
import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart';
import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import '../../config/config.dart';
import '../videocall-webrtc-rnd/utils/device_info.dart';
class IncomingCall extends StatefulWidget {
IncomingCallData incomingCallData;
IncomingCall({@required this.incomingCallData});
@override
_IncomingCallState createState() => _IncomingCallState();
}
class _IncomingCallState extends State<IncomingCall> with SingleTickerProviderStateMixin {
AnimationController _animationController;
bool openCallInWeb = true;
final player = AudioPlayer();
CameraController _controller;
Future<void> _initializeControllerFuture;
bool isCameraReady = false;
Signaling _signaling;
SessionOneToOne _session;
@override
void initState() {
_animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 500));
//_runAnimation();
connectSignaling();
WidgetsBinding.instance.addPostFrameCallback((_) =>_runAnimation());
super.initState();
}
@override
void dispose() {
_animationController.dispose();
player.stop();
_controller.dispose();
disposeAudioResources();
// _signaling.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AppScaffold(
isShowAppBar: false,
isShowDecPage: false,
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
alignment: FractionalOffset.center,
children: <Widget>[
new Positioned.fill(
child: new AspectRatio(aspectRatio: _controller.value.aspectRatio, child: new CameraPreview(_controller)),
),
new Positioned.fill(
child: new ClipRect(
child: new BackdropFilter(
filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: new Container(
decoration: new BoxDecoration(color: Colors.grey[800].withOpacity(0.8)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Container(
margin: const EdgeInsets.all(21.0),
child: Row(
children: [
Image.asset(
"assets/images/new/logo.png",
height: 70,
width: 70,
),
Container(
margin: const EdgeInsets.only(left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
widget.incomingCallData.doctorname,
style: TextStyle(fontSize: 21, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: -1.26, height: 23 / 12),
),
Text(
TranslationBase.of(context).videoAppo,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xffC6C6C6), letterSpacing: -0.48, height: 23 / 24),
),
SizedBox(height: 2),
],
),
),
],
),
),
Container(
margin: const EdgeInsets.all(21.0),
width: MediaQuery.of(context).size.width,
decoration: cardRadius(15.0, color: Colors.black),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 6.0),
child: Text(
TranslationBase.of(context).appoInfo,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, letterSpacing: -0.64, height: 23 / 12),
),
),
Container(
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
child: Text(
widget.incomingCallData.appointmentdate + ", " + widget.incomingCallData.appointmenttime,
style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600),
),
),
Container(
padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 21.0),
child: Text(
widget.incomingCallData.clinicname,
style: TextStyle(fontSize: 12.0, letterSpacing: -0.48, color: Color(0xff8E8E8E), fontWeight: FontWeight.w600),
),
),
],
),
),
Spacer(),
Container(
margin: EdgeInsets.only(bottom: 70.0, left: 49, right: 49),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RotationTransition(
turns: Tween(begin: 0.0, end: -.1).chain(CurveTween(curve: Curves.elasticIn)).animate(_animationController),
child: Container(
child: RawMaterialButton(
onPressed: () {
_submit();
},
elevation: 2.0,
fillColor: Colors.green,
child: Icon(
Icons.call,
color: Colors.white,
size: 35.0,
),
padding: EdgeInsets.all(15.0),
shape: CircleBorder(),
),
)),
Container(
child: RawMaterialButton(
onPressed: () {
backToHome();
},
elevation: 2.0,
fillColor: Colors.red,
child: Icon(
Icons.call_end,
color: Colors.white,
size: 35.0,
),
padding: EdgeInsets.all(15.0),
shape: CircleBorder(),
),
),
],
),
),
],
),
),
),
),
),
],
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
);
}
void _runAnimation() async {
final cameras = await availableCameras();
final firstCamera = cameras[1];
_controller = CameraController(
firstCamera,
ResolutionPreset.medium,
);
_initializeControllerFuture = _controller.initialize();
setState(() {});
setAudioFile();
for (int i = 0; i < 100; i++) {
await _animationController.forward();
await _animationController.reverse();
}
}
Future<void> _submit() async {
try {
// backToHome();
// final roomModel = RoomModel(name: widget.incomingCallData.name, token: widget.incomingCallData.sessionId, identity: widget.incomingCallData.identity);
await _controller.dispose();
changeCallStatusAPI(4);
if (_session != null && _signaling != null) {
await Navigator.of(context).pushReplacement(
MaterialPageRoute(
// fullscreenDialog: true,
builder: (BuildContext context) {
if (widget.incomingCallData.isWebRTC == "true") {
return StartVideoCall(signaling: _signaling, session: _session);
} else {
return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: widget.incomingCallData.sessionId, token: widget.incomingCallData.token);
}
// return VideoCallWebPage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // Web WebRTC VideoCall
// return CallHomePage(receiverId: widget.incomingCallData.receiverID, callerId: widget.incomingCallData.callerID); // App WebRTC VideoCall
},
),
);
} else {
// Invalid Params/Data
AppToast.showErrorToast(message: "Failed to establish connection with server");
}
} catch (err) {
print(err);
await PlatformExceptionAlertDialog(
exception: err,
).show(context);
}
}
void changeCallStatusAPI(int sessionStatus) {
LiveCareService service = new LiveCareService();
service.endCallAPI(widget.incomingCallData.sessionId, sessionStatus, context).then((res) {}).catchError((err) {
print(err);
});
}
void backToHome() async {
// final connected = await signaling.declineCall(widget.incomingCallData.callerID, widget.incomingCallData.receiverID);
LandingPage.isOpenCallPage = false;
// _signaling
player.stop();
changeCallStatusAPI(3);
_signaling.bye(_session, callRejected: true);
_signaling.callDisconnected(_session, callRejected: true);
Navigator.of(context).pop();
}
disposeAudioResources() async {
await player.dispose();
}
void setAudioFile() async {
player.stop();
await player.setVolume(1.0); // full volume
try {
await player.setAsset('assets/sounds/ring_60Sec.mp3').then((value) {
player.setLoopMode(LoopMode.one); // loop ring sound
player.play();
}).catchError((err) {
print("Error: $err");
});
} catch (e) {
print("Error: $e");
}
}
connectSignaling({@required bool iAmCaller = false}) async {
print("----------------- + Signaling Connection Started ---------------------------");
final caller = widget.incomingCallData.callerID;
final receiver = widget.incomingCallData.receiverID;
final host = widget.incomingCallData.server;
final selfRole = iAmCaller ? "Caller" : "Receiver";
final selfId = iAmCaller ? caller : receiver;
final selfUser = SocketUser(id: selfId, name: "$selfRole-$selfId", userAgent: DeviceInfo.userAgent, moreInfo: {});
final remoteRole = !iAmCaller ? "Caller" : "Receiver";
final remoteId = !iAmCaller ? caller : receiver;
final remoteUser = SocketUser(id: remoteId, name: "$remoteRole-$remoteId", userAgent: DeviceInfo.userAgent, moreInfo: {});
final sessionId = "$caller-$receiver";
_session = SessionOneToOne(id: sessionId, local_user: selfUser, remote_user: remoteUser);
_signaling = Signaling(host, session: _session);
await _signaling.connect();
if (_signaling.state == SignalingState.Open) {
return;
}
}
}