|
@@ -0,0 +1,611 @@
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
|
|
|
+<head>
|
|
|
|
+ <meta charset="utf-8">
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
|
|
+ <link href="https://fonts.googleapis.com/css?family=Nunito:200,600,700" rel="stylesheet">
|
|
|
|
+ <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
|
|
|
+ <link href="/css/app.css" rel="stylesheet">
|
|
|
|
+ <link rel="stylesheet" href="/fontawesome-free/css/all.min.css">
|
|
|
|
+ <link href="/css/meeting.css" rel="stylesheet">
|
|
|
|
+ <link href="/css/style.css" rel="stylesheet">
|
|
|
|
+ <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
|
|
|
|
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"
|
|
|
|
+ integrity="sha512-5yJ548VSnLflcRxWNqVWYeQZnby8D8fJTmYRLyvs445j1XmzR8cnWi85lcHx3CUEeAX+GrK3TqTfzOO6LKDpdw=="
|
|
|
|
+ crossorigin="anonymous"></script>
|
|
|
|
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"
|
|
|
|
+ integrity="sha512-iKDtgDyTHjAitUDdLljGhenhPwrbBfqTKWO1mkhSFH3A7blITC9MhYon6SjnMhp4o0rADGw9yAC6EW4t5a4K3g=="
|
|
|
|
+ crossorigin="anonymous"></script>
|
|
|
|
+ <script defer src=//download.agora.io/sdk/web/AgoraRTC_N-4.1.0.js></script>
|
|
|
|
+</head>
|
|
|
|
+
|
|
|
|
+<body class="p-0 m-0">
|
|
|
|
+
|
|
|
|
+ <div id="proCallComponent">
|
|
|
|
+
|
|
|
|
+ @if($client)
|
|
|
|
+ <div class="text-center py-2 border-bottom font-weight-normal mcp-theme-1">
|
|
|
|
+ <i class="fa fa-user-injured small mr-2"></i><a href="#" onclick="return window.top.openInLHS('/patients/view/{{$client->uid}}')">
|
|
|
|
+ <span class="font-weight-bold">{{ $client->displayName() }}</span>
|
|
|
|
+ </a>
|
|
|
|
+ </div>
|
|
|
|
+ @endif
|
|
|
|
+
|
|
|
|
+ <div class="py-2 d-flex align-items-center justify-content-center border-bottom">
|
|
|
|
+ <a href="#" v-if="ringer" v-on:click.prevent="toggleRinger()"
|
|
|
|
+ class="font-weight-bold btn btn-sm btn-success">
|
|
|
|
+ Ringer
|
|
|
|
+ <i class="ml-1 fa fa-volume-up"></i>
|
|
|
|
+ </a>
|
|
|
|
+ <a href="#" v-if="!ringer" v-on:click.prevent="toggleRinger()"
|
|
|
|
+ class="font-weight-bold btn btn-sm btn-warning">
|
|
|
|
+ Ringer
|
|
|
|
+ <i class="ml-1 fa fa-volume-mute"></i>
|
|
|
|
+ </a>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="" v-show="false">
|
|
|
|
+ <div class="py-3 text-center" xv-if="started">
|
|
|
|
+ <h6 class="text-black font-weight-bold m-0">Call in progress: @{{ timeDisplay() }}</h6>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="py-3 text-center" v-if="!otherParticipants.length">
|
|
|
|
+ <h6 class="text-black font-weight-bold m-0">No other participants in the call.
|
|
|
|
+ <a href="#" class="text-danger font-weight-bold" v-on:click.prevent="hangUp()">Hang up</a>
|
|
|
|
+ </h6>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="main-view mx-auto">
|
|
|
|
+ <div id="self-view" class="full-view" data-stream="self" data-name="You" data-type="PRO"></div>
|
|
|
|
+ <div class="thumbs">
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+ <button class="btn btn-danger rounded-circle hang-up"
|
|
|
|
+ xv-if="started"
|
|
|
|
+ title="Leave Call"
|
|
|
|
+ v-on:click.prevent="hangUp()">
|
|
|
|
+ <i class="fa fa-phone"></i>
|
|
|
|
+ </button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ @if($client)
|
|
|
|
+ {{--<div class="" v-show="!videoActive">
|
|
|
|
+ <button class="btn btn-sm btn-primary font-weight-bold mx-auto mt-4 d-block"
|
|
|
|
+ v-on:click.prevent="connect()">
|
|
|
|
+ Start video call with {{ $client->displayName() }}
|
|
|
|
+ </button>
|
|
|
|
+ </div>--}}
|
|
|
|
+ @endif
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="border-top patient-queue mcp-theme-1" id="queueComponent">
|
|
|
|
+ <div class="bg-secondary text-white font-weight-bold text-center py-1" v-if="items.length > 0">
|
|
|
|
+ @{{ items.length }} patient@{{ items.length > 1 ? 's' : '' }} in the queue
|
|
|
|
+ </div>
|
|
|
|
+ <div class="bg-secondary text-white font-weight-bold text-center py-1" v-if="items.length === 0">
|
|
|
|
+ No patients in the queue
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="items && items.length" class="d-flex align-items-center my-1">
|
|
|
|
+ <div v-for="item in items">
|
|
|
|
+ <div class="queue-item border border-primary rounded mx-1" :title="item.name">
|
|
|
|
+ <div class="patient-avatar mb-1 text-dark">@{{ item.initials }}</div>
|
|
|
|
+ <div class="font-weight-bold small text-nowrap text-ellipsis">@{{ item.name }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <button class="btn btn-sm btn-primary mt-1 text-white font-weight-bold py-0 mx-auto d-block"
|
|
|
|
+ v-on:click.prevent="claim(item.clientUid)">Claim</button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <script>
|
|
|
|
+ (function () {
|
|
|
|
+ new Vue({
|
|
|
|
+ el: '#proCallComponent',
|
|
|
|
+ delimiters: ['@{{', '}}'],
|
|
|
|
+ data: {
|
|
|
|
+
|
|
|
|
+ // model - declare up-front to make reactive - override with server data on mount
|
|
|
|
+ amIInAMeeting: false,
|
|
|
|
+ meetingType: '', // PRO/CLIENT,
|
|
|
|
+ inMeetingForClientUid: '',
|
|
|
|
+ inMeetingForClient: {
|
|
|
|
+ clientMediaServiceRoomIdentifier: '',
|
|
|
|
+ uid: '',
|
|
|
|
+ displayName: '',
|
|
|
|
+ dob: '',
|
|
|
|
+ },
|
|
|
|
+ myMediaServiceToken: '',
|
|
|
|
+ myMediaServiceIdentifier: '',
|
|
|
|
+ myMedia: {
|
|
|
|
+ isCameraAcquired: false,
|
|
|
|
+ isCameraOn: false,
|
|
|
|
+ isMicrophoneAcquired: false,
|
|
|
|
+ isMicrophoneOn: false,
|
|
|
|
+ },
|
|
|
|
+ otherParticipants: [
|
|
|
|
+ {
|
|
|
|
+ participantType: '', // PRO/CLIENT_GUEST,
|
|
|
|
+ uid: '',
|
|
|
|
+ mediaServiceIdentifier: '',
|
|
|
|
+ displayName: '',
|
|
|
|
+ media: {
|
|
|
|
+ isCameraAcquired: false,
|
|
|
|
+ isCameraOn: false,
|
|
|
|
+ isMicrophoneAcquired: false,
|
|
|
|
+ isMicrophoneOn: false,
|
|
|
|
+ },
|
|
|
|
+ awayMessage: '',
|
|
|
|
+ deviceType: '',
|
|
|
|
+ isMeetingAccessGranted: '',
|
|
|
|
+ isSocketConnected: '',
|
|
|
|
+ }
|
|
|
|
+ ],
|
|
|
|
+ awayMessage: '',
|
|
|
|
+
|
|
|
|
+ // agora
|
|
|
|
+ agoraClient: null, // set on agora init
|
|
|
|
+ appId: '{{ config('app.agora_appid') }}',
|
|
|
|
+ channel: '', // set on mount
|
|
|
|
+ ringer: {{ $pro->is_ring_on ? 'true' : 'false' }},
|
|
|
|
+
|
|
|
|
+ // sockets
|
|
|
|
+ backendWsURL: '{{ config('app.backend_ws_url') }}',
|
|
|
|
+ socketClient: null,
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+
|
|
|
|
+ toggleRinger: function () {
|
|
|
|
+ let self = this, endPoint = this.ringer ? 'turnOffRing' : 'turnOnRing';
|
|
|
|
+ $.post('/api/pro/' + endPoint, function (_data) {
|
|
|
|
+ if (_data && _data.success) {
|
|
|
|
+ self.ringer = !self.ringer;
|
|
|
|
+ } else {
|
|
|
|
+ if (_data.message) {
|
|
|
|
+ toastr.error(_data.message);
|
|
|
|
+ } else {
|
|
|
|
+ toastr.error('Unable to change ringer status');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ connect: function () {
|
|
|
|
+ var self = this;
|
|
|
|
+ self.selfName = '{{ $pro->name_display }}';
|
|
|
|
+ $.get('/api/agora/getClientToken', {
|
|
|
|
+ clientUid: self.clientUid,
|
|
|
|
+ }, function (_data) {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ self.selfToken = _data.data;
|
|
|
|
+ self.initAgora();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ timeDisplay: function () {
|
|
|
|
+ var seconds = this.time / 1000,
|
|
|
|
+ minutes = parseInt(seconds / 60, 10);
|
|
|
|
+ seconds = parseInt(seconds % 60, 10);
|
|
|
|
+ return minutes + " min, " + seconds + " sec";
|
|
|
|
+ },
|
|
|
|
+ hangUp: function () {
|
|
|
|
+ var self = this;
|
|
|
|
+ async function _leave() {
|
|
|
|
+ if(self.agoraClient) {
|
|
|
|
+ await self.agoraClient.leave();
|
|
|
|
+ window.top.hideRHS();
|
|
|
|
+ window.location.reload();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _leave();
|
|
|
|
+ },
|
|
|
|
+ initAgora: function () {
|
|
|
|
+
|
|
|
|
+ let self = this;
|
|
|
|
+
|
|
|
|
+ async function _initAgora(){
|
|
|
|
+
|
|
|
|
+ self.agoraClient = AgoraRTC.createClient({mode:'rtc', codec:'h264'})
|
|
|
|
+ let camera, mic
|
|
|
|
+ try { mic = await AgoraRTC.createMicrophoneAudioTrack() } catch {
|
|
|
|
+ console.log('ALIX: error in getting mic');
|
|
|
|
+ }
|
|
|
|
+ try { camera = await AgoraRTC.createCameraVideoTrack() } catch {
|
|
|
|
+ console.log('ALIX: error in getting camera');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // testing
|
|
|
|
+ @if(config('app.agora_mode') === 'screen')
|
|
|
|
+ try { camera = await AgoraRTC.createScreenVideoTrack() } catch { }
|
|
|
|
+ @endif
|
|
|
|
+
|
|
|
|
+ if (!mic && !camera){
|
|
|
|
+ alert('Do you have camera/mic? Unable to hear or see you.')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Add myself to the page.
|
|
|
|
+ if(camera) {
|
|
|
|
+ camera.play($('#self-view')[0]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // events
|
|
|
|
+ self.agoraClient.on('user-joined', user => {
|
|
|
|
+
|
|
|
|
+ // add a div for remove view
|
|
|
|
+ $('[data-stream="' + user.uid + '"]').remove();
|
|
|
|
+ var remoteViewID = 'remote-view-' + user.uid;
|
|
|
|
+ var remoteElem = $('<div id="' + remoteViewID + '" class="remote-view thumb-view" data-stream="' + user.uid + '"></div>');
|
|
|
|
+ remoteElem.appendTo('.thumbs');
|
|
|
|
+
|
|
|
|
+ if (!self.startTime) {
|
|
|
|
+ self.startTime = new Date().getTime();
|
|
|
|
+ window.setInterval(function () {
|
|
|
|
+ self.time = new Date().getTime() - self.startTime;
|
|
|
|
+ }, 1000);
|
|
|
|
+ self.started = true;
|
|
|
|
+ }
|
|
|
|
+ self.activateParty(user.uid);
|
|
|
|
+ self.noOneElseInCall = false;
|
|
|
|
+ self.resolveParticipantNames();
|
|
|
|
+ })
|
|
|
|
+ self.agoraClient.on('user-left', user => {
|
|
|
|
+
|
|
|
|
+ if ($('.full-view[data-stream="' + user.uid + '"]').length) {
|
|
|
|
+ var allThumbs = $('.thumbs [data-stream]:not([data-stream=""]):not(.disconnected-view):visible');
|
|
|
|
+ if (allThumbs.length) {
|
|
|
|
+ $('.thumbs [data-stream]:not([data-stream=""])').each(function () {
|
|
|
|
+ if ($(this).attr('data-stream') !== user.uid) {
|
|
|
|
+ self.activateParty($(this).attr('data-stream'));
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ self.noOneElseInCall = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $('[data-stream="' + user.uid + '"]').remove();
|
|
|
|
+
|
|
|
|
+ // if no other parties in call, hang up
|
|
|
|
+ if (!$('[data-stream]:not([data-stream="' + {{ $session->id }} + '"])').length) {
|
|
|
|
+ console.warn('No other parties in the call!');
|
|
|
|
+ self.startTime = 0;
|
|
|
|
+ self.started = false;
|
|
|
|
+ self.noOneElseInCall = true;
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ self.agoraClient.on('user-published', async function(user, mediaType){
|
|
|
|
+ await self.agoraClient.subscribe(user, mediaType)
|
|
|
|
+ mediaType === 'audio'
|
|
|
|
+ ? user.audioTrack.play()
|
|
|
|
+ : user.videoTrack.play($('[data-stream="' + user.uid + '"]')[0]);
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ await self.agoraClient.join(self.appId, self.channel, self.selfToken, self.uid)
|
|
|
|
+ await self.agoraClient.publish([mic, camera].filter(Boolean))
|
|
|
|
+
|
|
|
|
+ // assume connected by this point, notify backend & show self video
|
|
|
|
+ if (mic || camera) {
|
|
|
|
+ self.joinMeetingAsPro(self.selfUserType);
|
|
|
|
+ $('#self-view').attr('data-type', 'PRO').show();
|
|
|
|
+ self.activateParty('self');
|
|
|
|
+ self.videoActive = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _initAgora();
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ activateParty: function (_stream = 'self') {
|
|
|
|
+ var current = $('.full-view');
|
|
|
|
+ if (current.attr('data-stream') === _stream) return;
|
|
|
|
+ current.removeClass('full-view').addClass('thumb-view');
|
|
|
|
+ if (current.attr('data-type') === 'CLIENT') {
|
|
|
|
+ current.prependTo('.thumbs');
|
|
|
|
+ } else {
|
|
|
|
+ current.appendTo('.thumbs');
|
|
|
|
+ }
|
|
|
|
+ if (_stream === 'self') {
|
|
|
|
+ $('#self-view')
|
|
|
|
+ .removeClass('thumb-view')
|
|
|
|
+ .removeClass('disconnected-view')
|
|
|
|
+ .addClass('full-view')
|
|
|
|
+ .prependTo('.main-view');
|
|
|
|
+ } else {
|
|
|
|
+ $('div[data-stream="' + _stream + '"]')
|
|
|
|
+ .removeClass('thumb-view')
|
|
|
|
+ .removeClass('disconnected-view')
|
|
|
|
+ .addClass('full-view')
|
|
|
|
+ .prependTo('.main-view');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ enterClientRoomAsPro: function(_done) {
|
|
|
|
+ @if($client)
|
|
|
|
+ $.post('/api/meeting/enterClientRoomAsPro', {clientUid: '{{ $client->uid }}'}, (_data) => {
|
|
|
|
+ // TODO: check success
|
|
|
|
+ console.log(_data);
|
|
|
|
+ _done.call(this);
|
|
|
|
+ });
|
|
|
|
+ @endif
|
|
|
|
+ },
|
|
|
|
+ getMeetingInfo: function(_done) {
|
|
|
|
+ $.post('/api/meeting/getMyMeeting', (_data) => {
|
|
|
|
+ if(_data && _data.success) {
|
|
|
|
+ let state = JSON.parse(_data.data);
|
|
|
|
+ console.log(state);
|
|
|
|
+
|
|
|
|
+ // overwrite model data
|
|
|
|
+ this.amIInAMeeting = state.amIInAMeeting;
|
|
|
|
+ this.inMeetingForClientUid = state.inMeetingForClientUid;
|
|
|
|
+ this.inMeetingForClient.clientMediaServiceRoomIdentifier =
|
|
|
|
+ state.inMeetingForClient.clientMediaServiceRoomIdentifier;
|
|
|
|
+ this.inMeetingForClient.uid = state.inMeetingForClient.uid;
|
|
|
|
+ this.inMeetingForClient.displayName = state.inMeetingForClient.displayName;
|
|
|
|
+ this.inMeetingForClient.dob = state.inMeetingForClient.dob;
|
|
|
|
+ this.meetingType = state.meetingType;
|
|
|
|
+ this.myMediaServiceToken = state.myMediaServiceToken;
|
|
|
|
+ this.myMediaServiceIdentifier = state.myMediaServiceIdentifier;
|
|
|
|
+ this.otherParticipants = state.otherParticipants;
|
|
|
|
+
|
|
|
|
+ // agora stuff
|
|
|
|
+ this.channel = this.inMeetingForClient.clientMediaServiceRoomIdentifier;
|
|
|
|
+
|
|
|
|
+ _done.call(this);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ registerSocket: function() {
|
|
|
|
+ let socket = new SockJS(this.backendWsURL);
|
|
|
|
+ this.socketClient = Stomp.over(socket);
|
|
|
|
+ this.socketClient.connect({}, (frame) => {
|
|
|
|
+ console.log('Connected: ' + frame);
|
|
|
|
+ this.initSocketListeners(); // init listeners
|
|
|
|
+ this.socketClient.send("/app/register", {}, // register self
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ initSocketListeners: function() {
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/newParticipant", function(message) {
|
|
|
|
+ console.log("newParticipant received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myMicrophoneIsAcquired", function(message) {
|
|
|
|
+ console.log("myMicrophoneIsAcquired received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myMicrophoneIsNotAcquired", function(message) {
|
|
|
|
+ console.log("myMicrophoneIsNotAcquired received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myMicrophoneIsOn", function(message) {
|
|
|
|
+ console.log("myMicrophoneIsOn received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myMicrophoneIsOff", function(message) {
|
|
|
|
+ console.log("myMicrophoneIsOff received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myCameraIsAcquired", function(message) {
|
|
|
|
+ console.log("myCameraIsAcquired received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myCameraIsNotAcquired", function(message) {
|
|
|
|
+ console.log("myCameraIsNotAcquired received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myCameraIsOn", function(message) {
|
|
|
|
+ console.log("myCameraIsOn received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/myCameraIsOff", function(message) {
|
|
|
|
+ console.log("myCameraIsOff received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/editMyName", function(message) {
|
|
|
|
+ console.log("editMyName received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/setMyAwayMessage", function(message) {
|
|
|
|
+ console.log("setMyAwayMessage received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/removeMyAwayMessage", function(message) {
|
|
|
|
+ console.log("removeMyAwayMessage received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.socketClient.subscribe("/user/topic/leaveClientRoom", function(message) {
|
|
|
|
+ console.log("leaveClientRoom received:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // start: actions that notify participants via socket
|
|
|
|
+ myMicrophoneIsAcquired: function () {
|
|
|
|
+ self.socketClient.send("/app/myMicrophoneIsAcquired", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myMicrophoneIsNotAcquired: function () {
|
|
|
|
+ self.socketClient.send("/app/myMicrophoneIsNotAcquired", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myMicrophoneIsOn: function () {
|
|
|
|
+ self.socketClient.send("/app/myMicrophoneIsOn", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myMicrophoneIsOff: function () {
|
|
|
|
+ self.socketClient.send("/app/myMicrophoneIsOff", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myCameraIsAcquired: function () {
|
|
|
|
+ self.socketClient.send("/app/myCameraIsAcquired", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myCameraIsNotAcquired: function () {
|
|
|
|
+ self.socketClient.send("/app/myCameraIsNotAcquired", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myCameraIsOn: function () {
|
|
|
|
+ self.socketClient.send("/app/myCameraIsOn", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ myCameraIsOff: function () {
|
|
|
|
+ self.socketClient.send("/app/myCameraIsOff", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ editMyName: function (_myNewName) {
|
|
|
|
+ self.socketClient.send("/app/editMyName", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}',
|
|
|
|
+ myNewName: _myNewName
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ setMyAwayMessage: function (_message) {
|
|
|
|
+ self.socketClient.send("/app/setMyAwayMessage", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}',
|
|
|
|
+ message: _message
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ removeMyAwayMessage: function () {
|
|
|
|
+ self.socketClient.send("/app/removeMyAwayMessage", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ leaveClientRoom: function () {
|
|
|
|
+ self.socketClient.send("/app/leaveClientRoom", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ // end: actions that notify participants via socket
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ mounted: function () {
|
|
|
|
+
|
|
|
|
+ // enter the room
|
|
|
|
+ this.enterClientRoomAsPro(function() {
|
|
|
|
+
|
|
|
|
+ // get meeting info
|
|
|
|
+ this.getMeetingInfo(function() {
|
|
|
|
+
|
|
|
|
+ // register socket
|
|
|
|
+ this.registerSocket();
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ {{--var self = this;--}}
|
|
|
|
+
|
|
|
|
+ {{--$(document).on('click', '.thumbs>div[data-stream]', function () {--}}
|
|
|
|
+ {{-- self.activateParty($(this).attr('data-stream'));--}}
|
|
|
|
+ {{-- return false;--}}
|
|
|
|
+ {{--});--}}
|
|
|
|
+
|
|
|
|
+ {{--@if(isset($client))--}}
|
|
|
|
+ {{-- self.client = true;--}}
|
|
|
|
+ {{-- self.clientUid = '{{ $client->uid }}';--}}
|
|
|
|
+ {{-- self.videoActive = false;--}}
|
|
|
|
+ {{--@endif--}}
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ new Vue({
|
|
|
|
+ el: '#queueComponent',
|
|
|
|
+ data: {
|
|
|
|
+ items: []
|
|
|
|
+ },
|
|
|
|
+ mounted: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ this.refresh();
|
|
|
|
+ window.setInterval(function() {
|
|
|
|
+ self.refresh();
|
|
|
|
+ }, 15000); // once in 15 seconds
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ refresh: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $.get('/patients-in-queue', function(_data) {
|
|
|
|
+ self.items = _data;
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ claim: function(_uid) {
|
|
|
|
+ $.post('/api/mcpRequest/claim', {clientUid: _uid}, function(_data) {
|
|
|
|
+ if(_data && _data.success) {
|
|
|
|
+ // open patient in LHS
|
|
|
|
+ window.top.openInLHS('/patients/view/' + _uid);
|
|
|
|
+ // open patient video in RHS
|
|
|
|
+ window.top.openInRHS('/pro/meet/' + _uid);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (_data.message) {
|
|
|
|
+ window.top.toastr.error(_data.message);
|
|
|
|
+ } else {
|
|
|
|
+ window.top.toastr.error('Unable to claim the patient');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }, 'json');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ })();
|
|
|
|
+ </script>
|
|
|
|
+ <!--
|
|
|
|
+ <script>
|
|
|
|
+ // connect to WS
|
|
|
|
+ self.socket = new SockJS('{{ config('app.backend_ws_url') }}');
|
|
|
|
+ self.socketClient = Stomp.over(self.socket);
|
|
|
|
+ self.socketClient.connect({}, function(frame) {
|
|
|
|
+ console.log('Connected: ' + frame);
|
|
|
|
+
|
|
|
|
+ self.socketClient.subscribe("/user/topic/registration", function(message) {
|
|
|
|
+ console.log("Receiving message")
|
|
|
|
+ console.log("registration result:", message.body);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // join self
|
|
|
|
+ console.log("Sending message")
|
|
|
|
+ self.socketClient.send("/app/register", {},
|
|
|
|
+ JSON.stringify({
|
|
|
|
+ sessionKey: '{{$performer->session_key}}'
|
|
|
|
+ })
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ </script>
|
|
|
|
+ -->
|
|
|
|
+</body>
|
|
|
|
+</html>
|