meeting.blade.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. @extends('layouts.pro')
  2. @section('content')
  3. <div id="meetingComponent">
  4. <h5 class="bg-dark font-weight-bold text-white m-0 py-3 px-4 d-flex">
  5. <span>Meeting</span>
  6. <span class="ml-auto" v-if="!started">
  7. Connecting...
  8. </span>
  9. <span class="ml-auto" v-if="started">
  10. <i class="fa fa-clock mr-1 text-light"></i>
  11. @{{ timeDisplay() }}
  12. </span>
  13. </h5>
  14. <div class="d-flex align-items-stretch mt-4 justify-content-center flex-nowrap">
  15. <div class="tp-bar">
  16. <div v-for="(pro, index) of pros"
  17. class="tp-item mb-4"
  18. :class="activeParticipant && activeType === 'pro' && activeParticipant.id === pro.id ? 'active' : ''"
  19. v-on:click="setActiveView('pro', pro)">
  20. <div v-if="pro.status === 'active'">
  21. <img :src="pro.image" alt="" class="w-100">
  22. <p class="font-weight-bold text-center mt-1 mb-0">@{{ pro.name }}</p>
  23. <p class="font-weight-normal text-center">@{{ pro.type }}</p>
  24. </div>
  25. <div v-if="pro.status === 'connecting'">
  26. <img src="/images/person/connecting.jpg" alt="" class="w-100">
  27. <p class="font-weight-normal text-center mt-1 d-flex align-items-center justify-content-center">
  28. <img src="/images/loading.gif" class="mr-1">
  29. Connecting
  30. </p>
  31. </div>
  32. </div>
  33. <div class="tp-item mb-4">
  34. <img src="/images/person/guest.png" alt="" class="w-100">
  35. <p class="font-weight-bold text-center mt-1">Invite Pro</p>
  36. </div>
  37. </div>
  38. <div class="main-view" style="width: 800px; min-height: 600px;">
  39. <div class="p-4 w-100 h-100 d-flex align-items-stretch justify-content-stretch flex-column">
  40. <img :src="activeParticipant.image" class="d-block mw-100 mh-100 mx-auto">
  41. <p class="font-weight-bold text-center text-white mt-2">Feed from @{{ activeParticipant.name }}</p>
  42. </div>
  43. </div>
  44. <div class="tp-bar">
  45. <div v-for="(guest, index) of guests"
  46. class="tp-item mb-4"
  47. :class="activeParticipant && activeType === 'guest' && activeParticipant.id === guest.id ? 'active' : ''"
  48. v-on:click="setActiveView('guest', guest)">
  49. <img :src="guest.image" alt="" class="w-100">
  50. <p class="font-weight-bold text-center mt-1 mb-0">@{{ guest.name }}</p>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. <script>
  56. new Vue({
  57. el: '#meetingComponent',
  58. delimiters: ['@{{', '}}'],
  59. data: {
  60. meetingID: '<?= $meetingID ?>',
  61. socket: null,
  62. stompClient: null,
  63. time: 0,
  64. startTime: 0,
  65. started: false,
  66. guest: false,
  67. activeType: false,
  68. activeParticipant: false,
  69. guests: [
  70. {
  71. id: 1,
  72. name: 'You',
  73. image: '/images/person/you.jpg',
  74. status: 'connecting',
  75. },
  76. ],
  77. pros: [
  78. {
  79. id: 1,
  80. name: 'Nancy Drew',
  81. type: 'Receptionist',
  82. image: '/images/person/nancy.jpg',
  83. status: 'connecting',
  84. }
  85. ]
  86. },
  87. methods: {
  88. setActiveView: function(_type, _participant) {
  89. if(_participant.status === 'active') {
  90. this.activeType = _type;
  91. this.activeParticipant = _participant;
  92. }
  93. },
  94. timeDisplay: function() {
  95. // this.time = new Date().getTime() - this.startTime;
  96. var seconds = this.time / 1000,
  97. minutes = parseInt(seconds / 60, 10);
  98. seconds = parseInt(seconds % 60, 10);
  99. return minutes + " min, " + seconds + " sec";
  100. },
  101. connectToFirstPro: function() {
  102. console.log('Connecting to first pro ...');
  103. this.pros = [];
  104. this.addPro();
  105. $.post('/api/meeting/request-dial-pro', {
  106. meetingUid: this.meetingID,
  107. }, function(_data) {
  108. console.log('Response to /api/meeting/request-dial-pro');
  109. console.log(_data);
  110. }, 'json');
  111. },
  112. addPro: function() {
  113. this.pros.push({
  114. id: '0',
  115. name: 'Pro',
  116. type: 'Receptionist',
  117. image: '/images/person/nancy.jpg',
  118. status: 'connecting',
  119. });
  120. return this.pros[this.pros.length - 1];
  121. },
  122. onProJoined: function(_pID) {
  123. var found = false;
  124. // find pro with participant id
  125. var pro = this.pros.filter(function(_pro) {
  126. return _pro.id === _pID;
  127. });
  128. // no pro with id, find first one with id = 0
  129. if(!pro.length) {
  130. pro = this.pros.filter(function(_pro) {
  131. return _pro.id === "0";
  132. });
  133. }
  134. // no pro with id = 0, create one
  135. if(!pro.length) {
  136. pro = this.addPro();
  137. }
  138. else {
  139. pro = pro[0];
  140. }
  141. pro.id = _pID;
  142. pro.status = 'active';
  143. // TODO: init pro stream
  144. },
  145. },
  146. mounted: function() {
  147. this.pros = [];
  148. // this.playDemo();
  149. var self = this;
  150. // connect to WS
  151. self.socket = new SockJS('http://localhost:8080/ws');
  152. self.stompClient = Stomp.over(self.socket);
  153. self.stompClient.connect({}, function (frame) {
  154. console.log('Connected: ' + frame);
  155. // join self
  156. // this is called everytime the pro call page is refreshed
  157. self.stompClient.send("/app/pro-join-meeting", {},
  158. JSON.stringify({
  159. sessionKey: "<?= $sessionKey ?>",
  160. meetingUid: "<?= $meetingID ?>",
  161. }));
  162. /*
  163. // set self as active
  164. self.guests[0].id = '';
  165. self.guests[0].status = 'active';
  166. // TODO: init own stream
  167. // attempt to connect to first pro if "start"
  168. @if(request('start'))
  169. self.connectToFirstPro();
  170. @endif
  171. // subscribe to on pro joined WS event
  172. self.stompClient.subscribe("/topic/on-pro-join-meeting", function(message){
  173. console.log("on-pro-join-meeting:", message);
  174. message = JSON.parse(message.body);
  175. console.log(message.meetingParticipantUid);
  176. self.onProJoined(message.meetingParticipantUid);
  177. });
  178. */
  179. });
  180. }
  181. });
  182. </script>
  183. @endsection