|
@@ -1,80 +1,64 @@
|
|
<template>
|
|
<template>
|
|
<div class="login-box">
|
|
<div class="login-box">
|
|
<div class="login-logo auth-branding text-center border-0">
|
|
<div class="login-logo auth-branding text-center border-0">
|
|
- <span class="brand-text font-weight-light text-white">Welcome to <b>Dr. Smith & Dr. Brown's Office</b>!</span>
|
|
|
|
|
|
+ <span class="brand-text font-weight-light text-white">
|
|
|
|
+ Welcome to
|
|
|
|
+ <!-- <b>Dr. Smith & Dr. Brown's Office</b>! -->
|
|
|
|
+ <b>{{ lobbyProp.name }}</b>
|
|
|
|
+ </span>
|
|
</div>
|
|
</div>
|
|
- <v-stepper v-model="stepper">
|
|
|
|
- <v-stepper-header>
|
|
|
|
- <v-stepper-step :complete="stepper > 1" step="1">Check In</v-stepper-step>
|
|
|
|
|
|
+ <v-stepper v-model="stepper">
|
|
|
|
+ <v-stepper-header>
|
|
|
|
+ <v-stepper-step :complete="stepper > 1" step="1">Check In</v-stepper-step>
|
|
|
|
|
|
- <v-divider></v-divider>
|
|
|
|
|
|
+ <v-divider></v-divider>
|
|
|
|
|
|
- <v-stepper-step :complete="stepper > 2" step="2">Test your webcam</v-stepper-step>
|
|
|
|
|
|
+ <v-stepper-step :complete="stepper > 2" step="2">Test your webcam</v-stepper-step>
|
|
|
|
|
|
- <v-divider></v-divider>
|
|
|
|
|
|
+ <v-divider></v-divider>
|
|
|
|
|
|
- <v-stepper-step step="3">Meet your Doctor</v-stepper-step>
|
|
|
|
- </v-stepper-header>
|
|
|
|
|
|
+ <v-stepper-step step="3">Meet your Doctor</v-stepper-step>
|
|
|
|
+ </v-stepper-header>
|
|
|
|
|
|
- <v-stepper-items>
|
|
|
|
- <v-stepper-content step="1">
|
|
|
|
|
|
+ <v-stepper-items>
|
|
|
|
+ <v-stepper-content step="1">
|
|
|
|
+ <v-card class="mb-12" color="grey lighten-1" height="200px">
|
|
|
|
+ <div class="checkin-form d-flex justify-content-center align-items-center">
|
|
|
|
+ <div>
|
|
|
|
+ <!-- <input type="hidden" name="lobbyUid" value />
|
|
|
|
+ <input type="hidden" name="_api" value="/api/meeting/createAsStrangerPerformer" />
|
|
|
|
+ <input type="hidden" name="_success" value="/pro/login" />
|
|
|
|
+ <input type="hidden" name="_return" value="/" />-->
|
|
|
|
|
|
- <v-card
|
|
|
|
- class="mb-12"
|
|
|
|
- color="grey lighten-1"
|
|
|
|
- height="200px"
|
|
|
|
- >
|
|
|
|
- <div class="checkin-form d-flex justify-content-center align-items-center">
|
|
|
|
- <form action="/post-to-api"
|
|
|
|
- method="post"
|
|
|
|
- enctype="multipart/form-data">
|
|
|
|
-
|
|
|
|
- <input type="hidden" name="lobbyUid" value=""/>
|
|
|
|
- <input type="hidden" name="_api" value="/api/session/proRequestSmsTokenToLogIn">
|
|
|
|
- <input type="hidden" name="_success" value="/pro/login">
|
|
|
|
- <input type="hidden" name="_return" value="/">
|
|
|
|
-
|
|
|
|
- <div class="row mb-3">
|
|
|
|
- <div class="col">
|
|
|
|
- <input type="text" name="strangerFirstName" class="form-control" placeholder="First Name" required>
|
|
|
|
- </div>
|
|
|
|
- <div class="col">
|
|
|
|
- <input type="text" name="strangerLastName" class="form-control" placeholder="Last Name" required>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div class="row mb-3">
|
|
|
|
+ <div class="col">
|
|
|
|
+ <input type="text" name="strangerFirstName" class="form-control" placeholder="First Name" v-model="user.firstName" required />
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <div class="input-group mb-3">
|
|
|
|
- <input type="date" name="strangerDob" class="form-control" placeholder="Date of Birth" required>
|
|
|
|
|
|
+ <div class="col">
|
|
|
|
+ <input type="text" name="strangerLastName" class="form-control" placeholder="Last Name" v-model="user.lastName" required />
|
|
</div>
|
|
</div>
|
|
- </form>
|
|
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="input-group mb-3">
|
|
|
|
+ <input type="date" name="strangerDob" class="form-control" placeholder="Date of Birth" v-model="user.dateOfBirth" required />
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </v-card>
|
|
|
|
|
|
+ </div>
|
|
|
|
+ </v-card>
|
|
|
|
|
|
- <v-btn
|
|
|
|
- color="primary"
|
|
|
|
- @click="checkIn"
|
|
|
|
- :loading="loading"
|
|
|
|
- >
|
|
|
|
- Continue
|
|
|
|
- </v-btn>
|
|
|
|
-
|
|
|
|
- </v-stepper-content>
|
|
|
|
-
|
|
|
|
- <v-stepper-content step="2">
|
|
|
|
- <p>
|
|
|
|
- Please make sure your webcam is working. Accept the access request to your hardware on the top left to continue.
|
|
|
|
- <br>
|
|
|
|
- Then, someone should be with you shortly.
|
|
|
|
- </p>
|
|
|
|
-
|
|
|
|
- <v-card
|
|
|
|
- class="mb-12"
|
|
|
|
- color="grey lighten-1"
|
|
|
|
- height="200px"
|
|
|
|
- >
|
|
|
|
|
|
+ <v-btn color="primary" @click="checkIn" :loading="loading">Continue</v-btn>
|
|
|
|
+ </v-stepper-content>
|
|
|
|
+
|
|
|
|
+ <v-stepper-content step="2">
|
|
|
|
+ <p>
|
|
|
|
+ Please make sure your webcam is working. Accept the access request to your hardware on the top left to continue.
|
|
|
|
+ <br />Then, someone should be with you shortly.
|
|
|
|
+ </p>
|
|
|
|
+
|
|
|
|
+ <v-card class="mb-12" color="grey lighten-1" height="200px">
|
|
<grid-layout
|
|
<grid-layout
|
|
- :layout="videoGrid"
|
|
|
|
- :key="uniqueId"
|
|
|
|
|
|
+ :layout="videoGridPreview"
|
|
|
|
+ :key="`preview_${uniqueId}`"
|
|
:col-num="maxCols"
|
|
:col-num="maxCols"
|
|
:max-rows="maxRows"
|
|
:max-rows="maxRows"
|
|
:row-height="rowHeight"
|
|
:row-height="rowHeight"
|
|
@@ -84,32 +68,19 @@
|
|
:margin="[gridPadding, gridPadding]"
|
|
:margin="[gridPadding, gridPadding]"
|
|
:use-css-transforms="true"
|
|
:use-css-transforms="true"
|
|
>
|
|
>
|
|
- <grid-item v-for="video in videoGrid" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i">
|
|
|
|
- </grid-item>
|
|
|
|
|
|
+ <grid-item v-for="video in videoGridPreview" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i"></grid-item>
|
|
</grid-layout>
|
|
</grid-layout>
|
|
- </v-card>
|
|
|
|
|
|
+ </v-card>
|
|
|
|
|
|
- <v-btn
|
|
|
|
- color="primary"
|
|
|
|
- @click="stepper = 3"
|
|
|
|
- :disabled="!cameraWorkingConfirmed"
|
|
|
|
- >
|
|
|
|
- Continue
|
|
|
|
- </v-btn>
|
|
|
|
|
|
+ <v-btn color="primary" @click="gotoStep3" :disabled="!cameraWorkingConfirmed">Continue</v-btn>
|
|
|
|
|
|
- <v-btn text @click="stepper = 1">Cancel</v-btn>
|
|
|
|
- </v-stepper-content>
|
|
|
|
|
|
+ <v-btn text @click="stepper = 1">Cancel</v-btn>
|
|
|
|
+ </v-stepper-content>
|
|
|
|
|
|
- <v-stepper-content step="3">
|
|
|
|
- <p>
|
|
|
|
- Great!
|
|
|
|
- </p>
|
|
|
|
|
|
+ <v-stepper-content step="3">
|
|
|
|
+ <p>Great!</p>
|
|
|
|
|
|
- <v-card
|
|
|
|
- class="mb-12"
|
|
|
|
- color="grey lighten-1"
|
|
|
|
- height="200px"
|
|
|
|
- >
|
|
|
|
|
|
+ <v-card class="mb-12" color="grey lighten-1" height="200px">
|
|
<grid-layout
|
|
<grid-layout
|
|
:layout="videoGrid"
|
|
:layout="videoGrid"
|
|
:key="uniqueId"
|
|
:key="uniqueId"
|
|
@@ -122,29 +93,24 @@
|
|
:margin="[gridPadding, gridPadding]"
|
|
:margin="[gridPadding, gridPadding]"
|
|
:use-css-transforms="true"
|
|
:use-css-transforms="true"
|
|
>
|
|
>
|
|
- <grid-item v-for="video in videoGrid" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i">
|
|
|
|
- </grid-item>
|
|
|
|
|
|
+ <grid-item v-for="video in videoGrid" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i"></grid-item>
|
|
</grid-layout>
|
|
</grid-layout>
|
|
- </v-card>
|
|
|
|
|
|
+ </v-card>
|
|
|
|
|
|
- <v-btn
|
|
|
|
- color="primary"
|
|
|
|
- @click="stepper = 1"
|
|
|
|
- >
|
|
|
|
- Continue
|
|
|
|
- </v-btn>
|
|
|
|
|
|
+ <v-btn color="primary" @click="stepper = 1">Continue</v-btn>
|
|
|
|
|
|
- <v-btn text @click="stepper = 2">Cancel</v-btn>
|
|
|
|
- </v-stepper-content>
|
|
|
|
- </v-stepper-items>
|
|
|
|
- </v-stepper>
|
|
|
|
|
|
+ <v-btn text @click="stepper = 2">Cancel</v-btn>
|
|
|
|
+ </v-stepper-content>
|
|
|
|
+ </v-stepper-items>
|
|
|
|
+ </v-stepper>
|
|
|
|
+ <div style="display: none" ref="otContainer"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
-import { mapState } from "vuex"
|
|
|
|
|
|
+import { mapState } from "vuex";
|
|
|
|
|
|
-import VueGridLayout from "vue-grid-layout"
|
|
|
|
|
|
+import VueGridLayout from "vue-grid-layout";
|
|
|
|
|
|
export default {
|
|
export default {
|
|
components: {
|
|
components: {
|
|
@@ -152,13 +118,24 @@ export default {
|
|
GridItem: VueGridLayout.GridItem
|
|
GridItem: VueGridLayout.GridItem
|
|
},
|
|
},
|
|
props: {
|
|
props: {
|
|
- lobby_uid: {
|
|
|
|
- type: String,
|
|
|
|
|
|
+ lobbyProp: {
|
|
|
|
+ type: Object,
|
|
required: true
|
|
required: true
|
|
}
|
|
}
|
|
|
|
+ // ,
|
|
|
|
+ // lobby_uid: {
|
|
|
|
+ // type: String,
|
|
|
|
+ // required: true
|
|
|
|
+ // }
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
|
|
+ user: {
|
|
|
|
+ firstName: "",
|
|
|
|
+ lastName: "",
|
|
|
|
+ dateOfBirth: null
|
|
|
|
+ },
|
|
|
|
+ meetingUid: "",
|
|
stepper: 1,
|
|
stepper: 1,
|
|
cameraWorkingConfirmed: false,
|
|
cameraWorkingConfirmed: false,
|
|
loading: false,
|
|
loading: false,
|
|
@@ -171,136 +148,218 @@ export default {
|
|
screenPublisher: null,
|
|
screenPublisher: null,
|
|
subscribers: [],
|
|
subscribers: [],
|
|
publisherReady: false,
|
|
publisherReady: false,
|
|
|
|
+ sessionConnected: false,
|
|
accessDialogShown: false,
|
|
accessDialogShown: false,
|
|
videos: [],
|
|
videos: [],
|
|
videoGrid: [],
|
|
videoGrid: [],
|
|
|
|
+ videoGridPreview: [],
|
|
maxCols: 12,
|
|
maxCols: 12,
|
|
maxRows: 4,
|
|
maxRows: 4,
|
|
rowHeight: 240,
|
|
rowHeight: 240,
|
|
gridPadding: 8,
|
|
gridPadding: 8,
|
|
loadingInProgress: false
|
|
loadingInProgress: false
|
|
- }
|
|
|
|
|
|
+ };
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
- checkIn(){
|
|
|
|
- //ajax logic
|
|
|
|
-
|
|
|
|
- this.stepper = 2
|
|
|
|
|
|
+ checkIn() {
|
|
|
|
+ this.loading = true;
|
|
|
|
+ $.ajax({
|
|
|
|
+ url: "/post-to-api",
|
|
|
|
+ method: "POST",
|
|
|
|
+ headers: {
|
|
|
|
+ "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
|
|
|
|
+ },
|
|
|
|
+ dataType: "json",
|
|
|
|
+ data: {
|
|
|
|
+ _api: "/api/meeting/createAsStrangerPerformer",
|
|
|
|
+ lobbyUid: this.lobbyProp.uid,
|
|
|
|
+ title: `${this.user.firstName} ${this.user.lastName} ${this.user.dateOfBirth}`,
|
|
|
|
+ strangerFirstName: this.user.firstName,
|
|
|
|
+ strangerLastName: this.user.lastName,
|
|
|
|
+ strangerDob: this.user.dateOfBirth
|
|
|
|
+ },
|
|
|
|
+ success: data => {
|
|
|
|
+ this.stepper = 2;
|
|
|
|
+ this.meetingUid = data.data;
|
|
|
|
+ this.$nextTick(this.initializePublisher);
|
|
|
|
+ },
|
|
|
|
+ error: jXhr => {},
|
|
|
|
+ complete: () => {
|
|
|
|
+ this.loading = false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ initializePublisher() {
|
|
|
|
+ this.publisher = OT.initPublisher(
|
|
|
|
+ this.$refs.otContainer,
|
|
|
|
+ {
|
|
|
|
+ insertMode: "append",
|
|
|
|
+ width: "100%",
|
|
|
|
+ height: "100%",
|
|
|
|
+ resolution: "1280x720",
|
|
|
|
+ frameRate: 30,
|
|
|
|
+ name: `${this.user.firstName} ${this.user.lastName}`,
|
|
|
|
+ style: {
|
|
|
|
+ nameDisplayMode: "on",
|
|
|
|
+ archiveStatusDisplayMode: "off"
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ error => {
|
|
|
|
+ if (error) {
|
|
|
|
+ alert(error.message);
|
|
|
|
+ } else {
|
|
|
|
+ this.publisherReady = true;
|
|
|
|
+ const cont = this.createVideoContainer(true);
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ cont.el = $(`#${cont.id}`)[0];
|
|
|
|
+ cont.el.appendChild(this.publisher.element);
|
|
|
|
+ cont.obj = this.publisher;
|
|
|
|
+ this.$set(cont, "self", true);
|
|
|
|
+ this.cameraWorkingConfirmed = true;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ this.publisher.on({
|
|
|
|
+ accessDialogOpened: e => {
|
|
|
|
+ this.accessDialogShown = true;
|
|
|
|
+ },
|
|
|
|
+ accessDialogClosed: e => {
|
|
|
|
+ this.accessDialogShown = false;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ gotoStep3() {
|
|
|
|
+ this.stepper = 3;
|
|
|
|
+ this.videoGridPreview = [];
|
|
|
|
+ this.adjustVideoContainers();
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ const cont = this.videos[0];
|
|
|
|
+ cont.el = $(`#${cont.id}`)[0];
|
|
|
|
+ cont.el.appendChild(cont.obj.element);
|
|
|
|
+ this.getToken();
|
|
|
|
+ });
|
|
},
|
|
},
|
|
/* Copied */
|
|
/* Copied */
|
|
disconnect() {
|
|
disconnect() {
|
|
- if (!this.openTokSession) return
|
|
|
|
- this.openTokSession.disconnect()
|
|
|
|
- this.openTokSession.off()
|
|
|
|
- this.videos = []
|
|
|
|
- this.publisher.destroy()
|
|
|
|
- this.publisher = null
|
|
|
|
- this.subscribers = []
|
|
|
|
- this.publisherReady = false
|
|
|
|
- this.$store.commit("setSessionConnectivityState", false)
|
|
|
|
- this.openTokSession = null
|
|
|
|
|
|
+ if (!this.openTokSession) return;
|
|
|
|
+ this.openTokSession.disconnect();
|
|
|
|
+ this.openTokSession.off();
|
|
|
|
+ this.videos = [];
|
|
|
|
+ this.publisher.destroy();
|
|
|
|
+ this.publisher = null;
|
|
|
|
+ this.subscribers = [];
|
|
|
|
+ this.publisherReady = false;
|
|
|
|
+ this.$store.commit("setSessionConnectivityState", false);
|
|
|
|
+ this.openTokSession = null;
|
|
if (this.screenPublisher) {
|
|
if (this.screenPublisher) {
|
|
- this.screenPublisher.destroy()
|
|
|
|
- this.screenPublisher = null
|
|
|
|
- this.$store.commit("setScreenShareState", null)
|
|
|
|
|
|
+ this.screenPublisher.destroy();
|
|
|
|
+ this.screenPublisher = null;
|
|
|
|
+ this.$store.commit("setScreenShareState", null);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- getToken(data, isAssociate) {
|
|
|
|
- if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date() && (this.user.type === "guest" || !confirm("Meeting not started. Start it now?")))
|
|
|
|
- return
|
|
|
|
- data.meetingId = this.meeting.id
|
|
|
|
- data.userUid = this.user.UID
|
|
|
|
|
|
+ getToken() {
|
|
|
|
+ // if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date() && (this.user.type === "guest" || !confirm("Meeting not started. Start it now?")))
|
|
|
|
+ // return;
|
|
$.ajax({
|
|
$.ajax({
|
|
- url: isAssociate ? "/associate/token" : "/token",
|
|
|
|
|
|
+ url: "/post-to-api",
|
|
method: "POST",
|
|
method: "POST",
|
|
headers: {
|
|
headers: {
|
|
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
|
|
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
|
|
},
|
|
},
|
|
- data,
|
|
|
|
|
|
+ data: {
|
|
|
|
+ _api: "/api/meeting/getToken",
|
|
|
|
+ uid: this.meetingUid
|
|
|
|
+ },
|
|
success: data => {
|
|
success: data => {
|
|
- this.$refs.initialModal.hide()
|
|
|
|
- if (!isAssociate) {
|
|
|
|
- const user = Object.assign({}, this.user)
|
|
|
|
- user.id = data.participantId
|
|
|
|
- user.name = data.participantName
|
|
|
|
- user.pin = data.participantPin
|
|
|
|
- this.$store.commit("setUser", user)
|
|
|
|
- }
|
|
|
|
- this.initializeOpenTok(data.apiKey, data.sessionId, data.token)
|
|
|
|
|
|
+ // this.$refs.initialModal.hide();
|
|
|
|
+ // if (!isAssociate) {
|
|
|
|
+ // const user = Object.assign({}, this.user);
|
|
|
|
+ // user.id = data.participantId;
|
|
|
|
+ // user.name = data.participantName;
|
|
|
|
+ // user.pin = data.participantPin;
|
|
|
|
+ // this.$store.commit("setUser", user);
|
|
|
|
+ // }
|
|
|
|
+ this.initializeOpenTok(data.data.apiKey, data.data.sessionId, data.data.token);
|
|
},
|
|
},
|
|
error: jXhr => {
|
|
error: jXhr => {
|
|
if (jXhr.responseJSON && jXhr.responseJSON.errorCode) {
|
|
if (jXhr.responseJSON && jXhr.responseJSON.errorCode) {
|
|
switch (jXhr.responseJSON.errorCode) {
|
|
switch (jXhr.responseJSON.errorCode) {
|
|
case "LM-1":
|
|
case "LM-1":
|
|
- alert("Meeting not started yet.")
|
|
|
|
- break
|
|
|
|
|
|
+ alert("Meeting not started yet.");
|
|
|
|
+ break;
|
|
case "LM-2":
|
|
case "LM-2":
|
|
- alert("You was kicked from this meeting.")
|
|
|
|
- window.location = "/"
|
|
|
|
- break
|
|
|
|
|
|
+ alert("You was kicked from this meeting.");
|
|
|
|
+ window.location = "/";
|
|
|
|
+ break;
|
|
case "LM-3":
|
|
case "LM-3":
|
|
- alert("Wrong password")
|
|
|
|
- this.$refs.initialModal.disableWaiting()
|
|
|
|
- break
|
|
|
|
|
|
+ alert("Wrong password");
|
|
|
|
+ this.$refs.initialModal.disableWaiting();
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- this.$refs.initialModal.disableWaiting()
|
|
|
|
- alert(getSingleError(jXhr))
|
|
|
|
|
|
+ // this.$refs.initialModal.disableWaiting();
|
|
|
|
+ alert(jXhr.responseJSON.message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ });
|
|
},
|
|
},
|
|
- createVideoContainer() {
|
|
|
|
- let videoCont = {}
|
|
|
|
- videoCont.id = `${this.uniqueId}_video_${this.counter++}`
|
|
|
|
|
|
+ createVideoContainer(preview = false) {
|
|
|
|
+ let videoCont = {};
|
|
|
|
+ videoCont.id = `${this.uniqueId}_video_${this.counter++}`;
|
|
|
|
|
|
- this.videos.push(videoCont)
|
|
|
|
- this.adjustVideoContainers()
|
|
|
|
|
|
+ this.videos.push(videoCont);
|
|
|
|
+ this.adjustVideoContainers(preview);
|
|
|
|
|
|
- return videoCont
|
|
|
|
|
|
+ return videoCont;
|
|
},
|
|
},
|
|
- adjustVideoContainers() {
|
|
|
|
- this.videoGrid = []
|
|
|
|
|
|
+ adjustVideoContainers(preview = false) {
|
|
|
|
+ let videoGrid;
|
|
|
|
+ if (preview) {
|
|
|
|
+ videoGrid = this.videoGridPreview = [];
|
|
|
|
+ } else {
|
|
|
|
+ videoGrid = this.videoGrid = [];
|
|
|
|
+ }
|
|
|
|
|
|
- let windowHeight = window.innerHeight
|
|
|
|
- this.rowHeight = (windowHeight - this.gridPadding * (this.maxRows + 1)) / this.maxRows
|
|
|
|
|
|
+ let windowHeight = window.innerHeight;
|
|
|
|
+ this.rowHeight = (windowHeight - this.gridPadding * (this.maxRows + 1)) / this.maxRows;
|
|
|
|
|
|
- let cols = Math.ceil(Math.sqrt(this.videos.length))
|
|
|
|
- let rows = Math.ceil(this.videos.length / cols)
|
|
|
|
|
|
+ let cols = Math.ceil(Math.sqrt(this.videos.length));
|
|
|
|
+ let rows = Math.ceil(this.videos.length / cols);
|
|
|
|
|
|
- let elementsLastRow = this.videos.length % cols
|
|
|
|
- let lastNormalIndex = this.videos.length - elementsLastRow
|
|
|
|
|
|
+ let elementsLastRow = this.videos.length % cols;
|
|
|
|
+ let lastNormalIndex = this.videos.length - elementsLastRow;
|
|
|
|
|
|
if (elementsLastRow) {
|
|
if (elementsLastRow) {
|
|
- this.maxCols = cols * elementsLastRow
|
|
|
|
|
|
+ this.maxCols = cols * elementsLastRow;
|
|
} else {
|
|
} else {
|
|
- this.maxCols = cols
|
|
|
|
|
|
+ this.maxCols = cols;
|
|
}
|
|
}
|
|
|
|
|
|
- let colsPerElement = this.maxCols / cols
|
|
|
|
- let rowsPerElement = this.maxRows / rows
|
|
|
|
|
|
+ let colsPerElement = this.maxCols / cols;
|
|
|
|
+ let rowsPerElement = this.maxRows / rows;
|
|
|
|
|
|
- let colsLastRow = Math.ceil(this.maxCols / elementsLastRow)
|
|
|
|
|
|
+ let colsLastRow = Math.ceil(this.maxCols / elementsLastRow);
|
|
|
|
|
|
- let cntX = 0
|
|
|
|
- let cntY = 0
|
|
|
|
|
|
+ let cntX = 0;
|
|
|
|
+ let cntY = 0;
|
|
|
|
|
|
for (let [index, video] of this.videos.entries()) {
|
|
for (let [index, video] of this.videos.entries()) {
|
|
- video.i = index
|
|
|
|
- video.x = cntX
|
|
|
|
- video.y = cntY
|
|
|
|
- video.h = rowsPerElement
|
|
|
|
- video.w = colsPerElement
|
|
|
|
- cntX += colsPerElement
|
|
|
|
|
|
+ video.i = index;
|
|
|
|
+ video.x = cntX;
|
|
|
|
+ video.y = cntY;
|
|
|
|
+ video.h = rowsPerElement;
|
|
|
|
+ video.w = colsPerElement;
|
|
|
|
+ cntX += colsPerElement;
|
|
|
|
|
|
if (cntX >= this.maxCols) {
|
|
if (cntX >= this.maxCols) {
|
|
- cntX = 0
|
|
|
|
- cntY += rowsPerElement
|
|
|
|
|
|
+ cntX = 0;
|
|
|
|
+ cntY += rowsPerElement;
|
|
}
|
|
}
|
|
|
|
|
|
- let videoTemp = Object.assign({}, video)
|
|
|
|
- videoTemp.video = video
|
|
|
|
- this.videoGrid.push(videoTemp)
|
|
|
|
|
|
+ let videoTemp = Object.assign({}, video);
|
|
|
|
+ videoTemp.video = video;
|
|
|
|
+ videoGrid.push(videoTemp);
|
|
}
|
|
}
|
|
|
|
|
|
/* OLD IMPLEMENTATION */
|
|
/* OLD IMPLEMENTATION */
|
|
@@ -338,214 +397,217 @@ export default {
|
|
} */
|
|
} */
|
|
},
|
|
},
|
|
initializeOpenTok(apiKey, sessionId, token) {
|
|
initializeOpenTok(apiKey, sessionId, token) {
|
|
- this.openTokSession = OT.initSession(apiKey, sessionId)
|
|
|
|
|
|
+ this.openTokSession = OT.initSession(apiKey, sessionId);
|
|
|
|
|
|
this.openTokSession.on({
|
|
this.openTokSession.on({
|
|
sessionDisconnected: event => {
|
|
sessionDisconnected: event => {
|
|
if (event.reason === "forceDisconnected") {
|
|
if (event.reason === "forceDisconnected") {
|
|
- alert("You were kicked.")
|
|
|
|
- if (this.user.type === "associate") {
|
|
|
|
- this.disconnect()
|
|
|
|
- this.$store.dispatch("leaveMeeting")
|
|
|
|
- } else {
|
|
|
|
- window.location = "/"
|
|
|
|
- }
|
|
|
|
|
|
+ alert("You were kicked.");
|
|
|
|
+ //TODO: Kicked
|
|
|
|
+ // if (this.user.type === "associate") {
|
|
|
|
+ // this.disconnect();
|
|
|
|
+ // this.$store.dispatch("leaveMeeting");
|
|
|
|
+ // } else {
|
|
|
|
+ // window.location = "/";
|
|
|
|
+ // }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ });
|
|
|
|
|
|
// Create a publisher
|
|
// Create a publisher
|
|
- this.publisher = OT.initPublisher(
|
|
|
|
- this.$refs.otContainer,
|
|
|
|
- {
|
|
|
|
- insertMode: "append",
|
|
|
|
- width: "100%",
|
|
|
|
- height: "100%",
|
|
|
|
- resolution: "1280x720",
|
|
|
|
- frameRate: 30,
|
|
|
|
- name: this.user.name,
|
|
|
|
- style: {
|
|
|
|
- nameDisplayMode: "on",
|
|
|
|
- archiveStatusDisplayMode: "off"
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- error => {
|
|
|
|
- if (error) {
|
|
|
|
- alert(error.message)
|
|
|
|
- } else {
|
|
|
|
- this.publisherReady = true
|
|
|
|
- const cont = this.createVideoContainer()
|
|
|
|
- this.$nextTick(() => {
|
|
|
|
- cont.el = $(`#${cont.id}`)[0]
|
|
|
|
- cont.el.appendChild(this.publisher.element)
|
|
|
|
- cont.obj = this.publisher
|
|
|
|
- this.$set(cont, "self", true)
|
|
|
|
- //cont.self = true
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- this.publisher.on({
|
|
|
|
- accessDialogOpened: e => {
|
|
|
|
- this.accessDialogShown = true
|
|
|
|
- },
|
|
|
|
- accessDialogClosed: e => {
|
|
|
|
- this.accessDialogShown = false
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ // this.publisher = OT.initPublisher(
|
|
|
|
+ // this.$refs.otContainer,
|
|
|
|
+ // {
|
|
|
|
+ // insertMode: "append",
|
|
|
|
+ // width: "100%",
|
|
|
|
+ // height: "100%",
|
|
|
|
+ // resolution: "1280x720",
|
|
|
|
+ // frameRate: 30,
|
|
|
|
+ // name: this.user.name,
|
|
|
|
+ // style: {
|
|
|
|
+ // nameDisplayMode: "on",
|
|
|
|
+ // archiveStatusDisplayMode: "off"
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
|
|
+ // error => {
|
|
|
|
+ // if (error) {
|
|
|
|
+ // alert(error.message);
|
|
|
|
+ // } else {
|
|
|
|
+ // this.publisherReady = true;
|
|
|
|
+ // const cont = this.createVideoContainer();
|
|
|
|
+ // this.$nextTick(() => {
|
|
|
|
+ // cont.el = $(`#${cont.id}`)[0];
|
|
|
|
+ // cont.el.appendChild(this.publisher.element);
|
|
|
|
+ // cont.obj = this.publisher;
|
|
|
|
+ // this.$set(cont, "self", true);
|
|
|
|
+ // //cont.self = true
|
|
|
|
+ // });
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // );
|
|
|
|
+
|
|
|
|
+ // this.publisher.on({
|
|
|
|
+ // accessDialogOpened: e => {
|
|
|
|
+ // this.accessDialogShown = true;
|
|
|
|
+ // },
|
|
|
|
+ // accessDialogClosed: e => {
|
|
|
|
+ // this.accessDialogShown = false;
|
|
|
|
+ // }
|
|
|
|
+ // });
|
|
|
|
|
|
this.openTokSession.on("streamCreated", event => {
|
|
this.openTokSession.on("streamCreated", event => {
|
|
//console.log("stream Created event")
|
|
//console.log("stream Created event")
|
|
- let container
|
|
|
|
|
|
+ let container;
|
|
if (event.stream.videoType === "screen") {
|
|
if (event.stream.videoType === "screen") {
|
|
- //TODO: This is
|
|
|
|
|
|
+ //TODO: This is screenshare
|
|
}
|
|
}
|
|
const subscriber = this.openTokSession.subscribe(
|
|
const subscriber = this.openTokSession.subscribe(
|
|
- event.stream,
|
|
|
|
- this.$refs.otContainer,
|
|
|
|
- {
|
|
|
|
- insertMode: "append",
|
|
|
|
- width: "100%",
|
|
|
|
- height: "100%",
|
|
|
|
- style: { nameDisplayMode: "on" }
|
|
|
|
- },
|
|
|
|
- error => {
|
|
|
|
- if (error) {
|
|
|
|
- alert(error.message)
|
|
|
|
- } else {
|
|
|
|
- const cont = this.createVideoContainer()
|
|
|
|
- this.$nextTick(() => {
|
|
|
|
- cont.el = $(`#${cont.id}`)[0]
|
|
|
|
- cont.el.appendChild(subscriber.element)
|
|
|
|
- cont.obj = subscriber
|
|
|
|
- container = cont
|
|
|
|
- })
|
|
|
|
|
|
+ event.stream,
|
|
|
|
+ this.$refs.otContainer,
|
|
|
|
+ {
|
|
|
|
+ insertMode: "append",
|
|
|
|
+ width: "100%",
|
|
|
|
+ height: "100%",
|
|
|
|
+ style: { nameDisplayMode: "on" }
|
|
|
|
+ },
|
|
|
|
+ error => {
|
|
|
|
+ if (error) {
|
|
|
|
+ alert(error.message);
|
|
|
|
+ } else {
|
|
|
|
+ const cont = this.createVideoContainer();
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ cont.el = $(`#${cont.id}`)[0];
|
|
|
|
+ cont.el.appendChild(subscriber.element);
|
|
|
|
+ cont.obj = subscriber;
|
|
|
|
+ container = cont;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- )
|
|
|
|
|
|
+ );
|
|
subscriber.on({
|
|
subscriber.on({
|
|
- destroyed: e => {
|
|
|
|
- container.el.remove()
|
|
|
|
- const index = this.videos.findIndex(v => v.id == container.id)
|
|
|
|
- if (index >= 0) this.videos.splice(index, 1)
|
|
|
|
- this.adjustVideoContainers()
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- this.subscribers.push(subscriber)
|
|
|
|
- })
|
|
|
|
|
|
+ destroyed: e => {
|
|
|
|
+ container.el.remove();
|
|
|
|
+ const index = this.videos.findIndex(v => v.id == container.id);
|
|
|
|
+ if (index >= 0) this.videos.splice(index, 1);
|
|
|
|
+ this.adjustVideoContainers();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ this.subscribers.push(subscriber);
|
|
|
|
+ });
|
|
|
|
|
|
|
|
+ console.log(sessionId);
|
|
|
|
+ console.log(token);
|
|
|
|
+ console.log(apiKey);
|
|
this.openTokSession.connect(token, error => {
|
|
this.openTokSession.connect(token, error => {
|
|
// If the connection is successful, publish to the session
|
|
// If the connection is successful, publish to the session
|
|
if (error) {
|
|
if (error) {
|
|
- alert(error.message)
|
|
|
|
|
|
+ alert(error.message);
|
|
} else {
|
|
} else {
|
|
- this.$store.commit("setSessionConnectivityState", true)
|
|
|
|
|
|
+ this.sessionConnected = true;
|
|
}
|
|
}
|
|
- })
|
|
|
|
- this.loadingInProgress = false
|
|
|
|
|
|
+ });
|
|
|
|
+ this.loadingInProgress = false;
|
|
},
|
|
},
|
|
publishToSession() {
|
|
publishToSession() {
|
|
this.openTokSession.publish(this.publisher, error => {
|
|
this.openTokSession.publish(this.publisher, error => {
|
|
- if (error) {
|
|
|
|
- alert(error.message)
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ if (error) {
|
|
|
|
+ alert(error.message);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
},
|
|
},
|
|
ready() {
|
|
ready() {
|
|
this.$nextTick(function() {
|
|
this.$nextTick(function() {
|
|
- this.readyForUse = true
|
|
|
|
|
|
+ this.readyForUse = true;
|
|
if (this.user.type === "associate") {
|
|
if (this.user.type === "associate") {
|
|
- if (!this.meeting.id || this.active_menu_item.template !== "room") return
|
|
|
|
- this.getToken({}, true)
|
|
|
|
- return
|
|
|
|
|
|
+ if (!this.meeting.id || this.active_menu_item.template !== "room") return;
|
|
|
|
+ this.getToken({}, true);
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date()) {
|
|
if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date()) {
|
|
- alert("Meeting not started.")
|
|
|
|
- return
|
|
|
|
|
|
+ alert("Meeting not started.");
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- let participantId = this.user.id
|
|
|
|
|
|
+ let participantId = this.user.id;
|
|
if (!participantId) {
|
|
if (!participantId) {
|
|
- this.$refs.initialModal.show(this.meeting.passwordRequired)
|
|
|
|
- return
|
|
|
|
|
|
+ this.$refs.initialModal.show(this.meeting.passwordRequired);
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
this.getToken({
|
|
this.getToken({
|
|
participantId
|
|
participantId
|
|
- })
|
|
|
|
- })
|
|
|
|
|
|
+ });
|
|
|
|
+ });
|
|
}
|
|
}
|
|
},
|
|
},
|
|
watch: {
|
|
watch: {
|
|
publisherReady(val) {
|
|
publisherReady(val) {
|
|
- if (val && this.session.sessionConnected) this.publishToSession()
|
|
|
|
|
|
+ if (val && this.sessionConnected) this.publishToSession();
|
|
},
|
|
},
|
|
- "session.sessionConnected"(val) {
|
|
|
|
- if (val && this.publisherReady) this.publishToSession()
|
|
|
|
|
|
+ sessionConnected(val) {
|
|
|
|
+ if (val && this.publisherReady) this.publishToSession();
|
|
},
|
|
},
|
|
"user.is_active_and_visible"(val) {
|
|
"user.is_active_and_visible"(val) {
|
|
- if (!this.publisher || !this.publisher.publishVideo) return
|
|
|
|
- this.publisher.publishVideo(val)
|
|
|
|
- this.publisher.publishAudio(val)
|
|
|
|
|
|
+ if (!this.publisher || !this.publisher.publishVideo) return;
|
|
|
|
+ this.publisher.publishVideo(val);
|
|
|
|
+ this.publisher.publishAudio(val);
|
|
},
|
|
},
|
|
"meeting.id"(val) {
|
|
"meeting.id"(val) {
|
|
- if (this.loadingInProgress) return
|
|
|
|
- this.loadingInProgress = true
|
|
|
|
- this.disconnect()
|
|
|
|
|
|
+ if (this.loadingInProgress) return;
|
|
|
|
+ this.loadingInProgress = true;
|
|
|
|
+ this.disconnect();
|
|
|
|
|
|
if (val) {
|
|
if (val) {
|
|
- this.getToken({}, true)
|
|
|
|
|
|
+ this.getToken({}, true);
|
|
} else {
|
|
} else {
|
|
- this.loadingInProgress = false
|
|
|
|
|
|
+ this.loadingInProgress = false;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
"active_menu_item.template"(val) {
|
|
"active_menu_item.template"(val) {
|
|
- if (this.loadingInProgress || val !== "room" || !this.meeting.id || this.openTokSession) return
|
|
|
|
- this.loadingInProgress = true
|
|
|
|
- this.getToken({}, true)
|
|
|
|
|
|
+ if (this.loadingInProgress || val !== "room" || !this.meeting.id || this.openTokSession) return;
|
|
|
|
+ this.loadingInProgress = true;
|
|
|
|
+ this.getToken({}, true);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
- let self = this
|
|
|
|
|
|
+ let self = this;
|
|
|
|
|
|
this.$eventBus.$on("meetingRejoin", () => {
|
|
this.$eventBus.$on("meetingRejoin", () => {
|
|
- this.loadingInProgress = true
|
|
|
|
- this.disconnect()
|
|
|
|
- this.getToken({}, true)
|
|
|
|
- })
|
|
|
|
|
|
+ this.loadingInProgress = true;
|
|
|
|
+ this.disconnect();
|
|
|
|
+ this.getToken({}, true);
|
|
|
|
+ });
|
|
|
|
|
|
- let width = $(window).width()
|
|
|
|
- let height = $(window).height()
|
|
|
|
|
|
+ let width = $(window).width();
|
|
|
|
+ let height = $(window).height();
|
|
|
|
|
|
window.addEventListener("resize", function() {
|
|
window.addEventListener("resize", function() {
|
|
- let new_width = $(window).width()
|
|
|
|
- let new_height = $(window).height()
|
|
|
|
|
|
+ let new_width = $(window).width();
|
|
|
|
+ let new_height = $(window).height();
|
|
|
|
|
|
- if (width !== new_width || height !== new_height) {
|
|
|
|
- self.adjustVideoContainers()
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ if (width !== new_width || height !== new_height) {
|
|
|
|
+ self.adjustVideoContainers();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
|
|
this.$eventBus.$on("leaveMeeting", () => {
|
|
this.$eventBus.$on("leaveMeeting", () => {
|
|
$.ajax({
|
|
$.ajax({
|
|
url: "/associate/meeting/leave",
|
|
url: "/associate/meeting/leave",
|
|
method: "POST",
|
|
method: "POST",
|
|
headers: {
|
|
headers: {
|
|
- "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
|
|
|
|
|
|
+ "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
|
|
},
|
|
},
|
|
error: jXhr => {
|
|
error: jXhr => {
|
|
- console.error(getSingleError(jXhr))
|
|
|
|
|
|
+ console.error(getSingleError(jXhr));
|
|
}
|
|
}
|
|
- })
|
|
|
|
- this.$store.dispatch("leaveMeeting")
|
|
|
|
- this.disconnect()
|
|
|
|
- })
|
|
|
|
|
|
+ });
|
|
|
|
+ this.$store.dispatch("leaveMeeting");
|
|
|
|
+ this.disconnect();
|
|
|
|
+ });
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+};
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
-
|
|
|
|
.login-box {
|
|
.login-box {
|
|
width: 100%;
|
|
width: 100%;
|
|
}
|
|
}
|
|
@@ -557,5 +619,4 @@ export default {
|
|
width: 75%;
|
|
width: 75%;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
</style>
|
|
</style>
|