Sfoglia il codice sorgente

Pro meeting room connected.

Kain_Stropov 5 anni fa
parent
commit
e71beed2b7

+ 111 - 89
resources/js/components/partials/LobbyList.vue

@@ -1,104 +1,126 @@
 <template>
-  <div>
-    <v-card v-for="lobby in lobbies" flat :key="lobby.id" :loading="loading">
+    <div>
+        <v-card v-for="lobby in lobbies" flat :key="lobby.id" :loading="loading">
+            <div class="d-flex flex-row justify-content-between">
+                <div>
+                    <v-card-title>{{lobby.name}}</v-card-title>
 
-    <div class="d-flex flex-row justify-content-between">
-        <div>
-            <v-card-title>{{lobby.name}}</v-card-title>
+                    <v-card-text>
+                        <div>{{lobby.description || 'No description available.'}}</div>
+                    </v-card-text>
+                </div>
+            </div>
 
-            <v-card-text>
-                <div>{{lobby.description || 'No description available.'}}</div>
-            </v-card-text>
-        </div>
-    </div>
-
-    <v-divider class="mx-4"></v-divider>
+            <v-divider class="mx-4"></v-divider>
 
-    <v-list dense v-if="meetingListFiltered(lobby.meetings).length">
-        <v-container class="overflow-y-auto px-0 pt-0">
-            <v-subheader class="d-flex flex-row justify-content-between">
-                <span>Meetings ({{meetingListFiltered(lobby.meetings).length}})</span>
-            </v-subheader>
-        </v-container>
-        <v-container style="height: 210px" class="overflow-y-auto">
-            <v-row>
-                <v-list-item-group class="w-100" v-model="lobby.selected_meeting" color="primary">
-                    <v-list-item v-for="(item, i) in meetingListFiltered(lobby.meetings)" :key="i" :value="item">
-                        <v-list-item-icon>
-                            <v-icon v-text="'mdi-clock'"></v-icon>
-                        </v-list-item-icon>
-                        <v-list-item-content>
-                            <v-list-item-title v-text="item.name"></v-list-item-title>
-                            <v-tooltip top v-if="item.pros_online.length > 0">
-                                <template v-slot:activator="{ on }">
-                                    <v-list-item-subtitle
-                                        v-on="on"
-                                        v-text="item.pros_online.length > 0 ? `PROs Connected (${item.pros_online.length})` : 'No PROs Connected'"
-                                    ></v-list-item-subtitle>
-                                </template>
-                                <span v-for="pro in item.pros_online" :key="pro.UID">
-                                    {{pro.name}}
-                                    <br />
-                                </span>
-                            </v-tooltip>
-                            <v-list-item-subtitle v-else v-text="item.pros_online.length > 0 ? `PROs Connected (${item.pros_online.length})` : 'No PROs Connected'"></v-list-item-subtitle>
-                        </v-list-item-content>
-                        <v-list-item-action>
-                            <v-list-item-action-text :class="{'status':true, 'is-active':item.active_members.length > 0}" v-text="'Online: ' + item.active_members.length"></v-list-item-action-text>
-                        </v-list-item-action>
-                    </v-list-item>
-                </v-list-item-group>
-            </v-row>
-        </v-container>
-    </v-list>
+            <v-list dense v-if="meetingListFiltered(lobby.meetings).length">
+                <v-container class="overflow-y-auto px-0 pt-0">
+                    <v-subheader class="d-flex flex-row justify-content-between">
+                        <span>Meetings ({{meetingListFiltered(lobby.meetings).length}})</span>
+                    </v-subheader>
+                </v-container>
+                <v-container style="height: 210px" class="overflow-y-auto">
+                    <v-row>
+                        <v-list-item-group class="w-100" v-model="lobby.selected_meeting" color="primary">
+                            <v-list-item v-for="(item, i) in meetingListFiltered(lobby.meetings)" :key="i" :value="item">
+                                <v-list-item-icon>
+                                    <v-icon v-text="'mdi-clock'"></v-icon>
+                                </v-list-item-icon>
+                                <v-list-item-content>
+                                    <v-list-item-title v-text="item.name"></v-list-item-title>
+                                    <v-tooltip top v-if="item.pros_online.length > 0">
+                                        <template v-slot:activator="{ on }">
+                                            <v-list-item-subtitle v-on="on" v-text="item.pros_online.length > 0 ? `PROs Connected (${item.pros_online.length})` : 'No PROs Connected'"></v-list-item-subtitle>
+                                        </template>
+                                        <span v-for="pro in item.pros_online" :key="pro.UID">
+                                            {{pro.name}}
+                                            <br />
+                                        </span>
+                                    </v-tooltip>
+                                    <v-list-item-subtitle v-else v-text="item.pros_online.length > 0 ? `PROs Connected (${item.pros_online.length})` : 'No PROs Connected'"></v-list-item-subtitle>
+                                </v-list-item-content>
+                                <v-list-item-action>
+                                    <v-list-item-action-text :class="{'status':true, 'is-active':item.active_members.length > 0}" v-text="'Online: ' + item.active_members.length"></v-list-item-action-text>
+                                </v-list-item-action>
+                            </v-list-item>
+                        </v-list-item-group>
+                    </v-row>
+                </v-container>
+            </v-list>
 
-    <v-list v-else>
-        <v-subheader class="d-flex flex-row justify-content-between">
-            <span>Meetings ({{meetingListFiltered(lobby.meetings).length}})</span>
-        </v-subheader>
-        <v-container style="height: 210px" class="overflow-y-auto">
-            <v-row>
-                <v-list-item-group class="w-100 text-center" color="primary">
-                    <v-list-item>
-                        <v-list-item-content>
-                            <v-list-item-title muted v-text="'No Meetings found for this lobby.'"></v-list-item-title>
-                        </v-list-item-content>
-                    </v-list-item>
-                </v-list-item-group>
-            </v-row>
-        </v-container>
-    </v-list>
+            <v-list v-else>
+                <v-subheader class="d-flex flex-row justify-content-between">
+                    <span>Meetings ({{meetingListFiltered(lobby.meetings).length}})</span>
+                </v-subheader>
+                <v-container style="height: 210px" class="overflow-y-auto">
+                    <v-row>
+                        <v-list-item-group class="w-100 text-center" color="primary">
+                            <v-list-item>
+                                <v-list-item-content>
+                                    <v-list-item-title muted v-text="'No Meetings found for this lobby.'"></v-list-item-title>
+                                </v-list-item-content>
+                            </v-list-item>
+                        </v-list-item-group>
+                    </v-row>
+                </v-container>
+            </v-list>
 
-    <transition-expand>
-        <div v-if="meetingListFiltered(lobby.meetings).length">
-            <v-divider class="mx-4"></v-divider>
+            <transition-expand>
+                <div v-if="meetingListFiltered(lobby.meetings).length">
+                    <v-divider class="mx-4"></v-divider>
 
-            <v-card-actions>
-                <v-btn :disabled="lobby.selected_meeting !== 0 && !lobby.selected_meeting" color="deep-purple accent-4" text @click="joinMeeting(lobby)">Join</v-btn>
-                <v-btn :disabled="lobby.selected_meeting !== 0 && !lobby.selected_meeting" color="deep-purple accent-4" text @click="inviteToMeeting(lobby)">Invite</v-btn>
-            </v-card-actions>
-        </div>
-    </transition-expand>
-</v-card>
-  </div>
+                    <v-card-actions>
+                        <v-btn :disabled="lobby.selected_meeting !== 0 && !lobby.selected_meeting" color="deep-purple accent-4" text @click="joinMeeting(lobby)">Join</v-btn>
+                        <v-btn :disabled="lobby.selected_meeting !== 0 && !lobby.selected_meeting" color="deep-purple accent-4" text @click="inviteToMeeting(lobby)">Invite</v-btn>
+                    </v-card-actions>
+                </div>
+            </transition-expand>
+        </v-card>
+    </div>
 </template>
 
 <script>
 import { mapState } from "vuex";
 
 export default {
-  data(){
-    return {
-      loading: false
-    }
-  },
-  computed: {
-    ...mapState(["lobbies", "user"]),
-  },
-  methods: {
-    meetingListFiltered(meetings) {
-      return meetings.filter((x) => x.pros_online.length == 0 || x.pros_online.findIndex((y) => y.uid == this.user.uid) !== -1)
+    data() {
+        return {
+            loading: false
+        };
+    },
+    computed: {
+        ...mapState(["lobbies", "user", "meeting"])
+    },
+    methods: {
+        meetingListFiltered(meetings) {
+            return meetings.filter(x => x.pros_online.length == 0 || x.pros_online.findIndex(y => y.uid == this.user.uid) !== -1);
+        },
+        joinMeeting(lobby) {
+            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/joinAsPro",
+                    uid: lobby.selected_meeting.uid
+                },
+                success: data => {
+                    if (this.meeting.uid === lobby.selected_meeting.uid) {
+                        this.$eventBus.$emit("meetingRejoin");
+                    } else {
+                        this.$store.commit("setMeeting", lobby.selected_meeting);
+                    }
+                },
+                error: jXhr => {},
+                complete: () => {
+                    this.loading = false;
+                }
+            });
+        }
     }
-  }
-}
+};
 </script>

+ 444 - 453
resources/js/components/partials/MeetingRoom.vue

@@ -1,38 +1,38 @@
 <template>
-  <div class="h-100" v-if="meeting.passwordRequired ? meeting.passwordProvided : true">
-    <div v-if="accessDialogShown">Please allow access to camera and microphone</div>
-      <div class="h-100" ref="videos">
-          <transition-group tag="div" class="video-wrapper" name="tiles">
-              <grid-layout
-                  :layout="videoGrid"
-                  :key="uniqueId"
-                  :col-num="maxCols"
-                  :max-rows="maxRows"
-                  :row-height="rowHeight"
-                  :is-draggable="true"
-                  :is-resizable="true"
-                  :verticalCompact="true"
-                  :margin="[gridPadding, gridPadding]"
-                  :use-css-transforms="true"
-              >
-                  <grid-item v-for="(video, index) in videoGrid" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i">
-                      <v-btn :color="'#282e38'" fab large dark class="v-btn--kick" @click="kickParcitipant(video)" v-show="!video.video.self && user.type == 'associate'">
-                          <v-icon>mdi-account-remove</v-icon>
-                      </v-btn>
-                  </grid-item>
-              </grid-layout>
-          </transition-group>
-          <!-- <div v-for="(video, index) in videos" :id="video.id" :key="video.id" @click="switchToFullSize(video, index)" :class="{'selected-high': video.id == bigMembersCountSelectedId, 'selected-low': lowMembersCountSelectedId == video.id}" class="video-container">
-          </div>-->
-      </div>
-      <button class="unscale" @click="bigMembersCountSelectedId = null" v-show="bigMembersCountSelectedId !== null">
-          <i class="mdi mdi-close"></i>
-      </button>
-      <div style="display:none" ref="otContainer">
-          <!-- Container to catch OpenTok Elements before reattaching -->
-      </div>
-      <!-- <modal-questions ref="initialModal" @questionsAnswered="getToken" @ready="ready"></modal-questions> -->
-  </div>
+    <div class="h-100" v-if="meeting.passwordRequired ? meeting.passwordProvided : true">
+        <div v-if="accessDialogShown">Please allow access to camera and microphone</div>
+        <div class="h-100" ref="videos">
+            <transition-group tag="div" class="video-wrapper" name="tiles">
+                <grid-layout
+                    :layout="videoGrid"
+                    :key="uniqueId"
+                    :col-num="maxCols"
+                    :max-rows="maxRows"
+                    :row-height="rowHeight"
+                    :is-draggable="true"
+                    :is-resizable="true"
+                    :verticalCompact="true"
+                    :margin="[gridPadding, gridPadding]"
+                    :use-css-transforms="true"
+                >
+                    <grid-item v-for="(video, index) in videoGrid" :key="video.id" :id="video.id" :x="video.x" :y="video.y" :w="video.w" :h="video.h" :i="video.i">
+                        <v-btn :color="'#282e38'" fab large dark class="v-btn--kick" @click="kickParcitipant(video)" v-show="!video.video.self && user.type == 'associate'">
+                            <v-icon>mdi-account-remove</v-icon>
+                        </v-btn>
+                    </grid-item>
+                </grid-layout>
+            </transition-group>
+            <!-- <div v-for="(video, index) in videos" :id="video.id" :key="video.id" @click="switchToFullSize(video, index)" :class="{'selected-high': video.id == bigMembersCountSelectedId, 'selected-low': lowMembersCountSelectedId == video.id}" class="video-container">
+            </div>-->
+        </div>
+        <button class="unscale" @click="bigMembersCountSelectedId = null" v-show="bigMembersCountSelectedId !== null">
+            <i class="mdi mdi-close"></i>
+        </button>
+        <div style="display:none" ref="otContainer">
+            <!-- Container to catch OpenTok Elements before reattaching -->
+        </div>
+        <!-- <modal-questions ref="initialModal" @questionsAnswered="getToken" @ready="ready"></modal-questions> -->
+    </div>
 </template>
 
 <script>
@@ -41,157 +41,148 @@ import { mapState } from "vuex";
 import VueGridLayout from "vue-grid-layout";
 
 export default {
-  components: {
-    GridLayout: VueGridLayout.GridLayout,
-    GridItem: VueGridLayout.GridItem
-  },
-  data() {
-    return {
-        readyForUse: false,
-        uniqueId: Math.floor(Math.random() * Math.floor(10000)),
-        counter: 1,
-        openTokSession: null,
-        publisher: null,
-        screenPublisher: null,
-        subscribers: [],
-        publisherReady: false,
-        accessDialogShown: false,
-        videos: [],
-        videoGrid: [],
-        bigMembersCountSelectedId: null,
-        lowMembersCountSelectedId: null,
-        maxCols: 12,
-        maxRows: 4,
-        rowHeight: 240,
-        gridPadding: 8,
-        loadingInProgress: false
-    };
-  },
-  computed: {
-    ...mapState(["meeting", "user", "session"])
-  },
-  methods: {
-    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.screenPublisher) {
-            this.screenPublisher.destroy();
-            this.screenPublisher = null;
-            this.$store.commit("setScreenShareState", null);
-        }
+    components: {
+        GridLayout: VueGridLayout.GridLayout,
+        GridItem: VueGridLayout.GridItem
     },
-    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;
-        $.ajax({
-            url: isAssociate ? "/associate/token" : "/token",
-            method: "POST",
-            headers: {
-                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
-            },
-            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);
-            },
-            error: jXhr => {
-                if (jXhr.responseJSON && jXhr.responseJSON.errorCode) {
-                    switch (jXhr.responseJSON.errorCode) {
-                        case "LM-1":
-                            alert("Meeting not started yet.");
-                            break;
-                        case "LM-2":
-                            alert("You was kicked from this meeting.");
-                            window.location = "/";
-                            break;
-                        case "LM-3":
-                            alert("Wrong password");
-                            this.$refs.initialModal.disableWaiting();
-                            break;
+    data() {
+        return {
+            readyForUse: false,
+            uniqueId: Math.floor(Math.random() * Math.floor(10000)),
+            counter: 1,
+            openTokSession: null,
+            publisher: null,
+            screenPublisher: null,
+            subscribers: [],
+            publisherReady: false,
+            accessDialogShown: false,
+            videos: [],
+            videoGrid: [],
+            bigMembersCountSelectedId: null,
+            lowMembersCountSelectedId: null,
+            maxCols: 12,
+            maxRows: 4,
+            rowHeight: 240,
+            gridPadding: 8,
+            loadingInProgress: false
+        };
+    },
+    computed: {
+        ...mapState(["meeting", "user", "session"])
+    },
+    methods: {
+        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.screenPublisher) {
+                this.screenPublisher.destroy();
+                this.screenPublisher = null;
+                this.$store.commit("setScreenShareState", null);
+            }
+        },
+        getToken() {
+            $.ajax({
+                url: "/post-to-api",
+                method: "POST",
+                headers: {
+                    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
+                },
+                data: {
+                    _api: "/api/meeting/getToken",
+                    uid: this.meeting.uid
+                },
+                success: data => {
+                    this.initializeOpenTok(data.data.apiKey, data.data.sessionId, data.data.token);
+                },
+                error: jXhr => {
+                    if (jXhr.responseJSON && jXhr.responseJSON.errorCode) {
+                        switch (jXhr.responseJSON.errorCode) {
+                            case "LM-1":
+                                alert("Meeting not started yet.");
+                                break;
+                            case "LM-2":
+                                alert("You was kicked from this meeting.");
+                                window.location = "/";
+                                break;
+                            case "LM-3":
+                                alert("Wrong password");
+                                this.$refs.initialModal.disableWaiting();
+                                break;
+                        }
+                    } else {
+                        this.$refs.initialModal.disableWaiting();
+                        alert(getSingleError(jXhr));
                     }
-                } else {
-                    this.$refs.initialModal.disableWaiting();
-                    alert(getSingleError(jXhr));
                 }
+            });
+        },
+        createVideoContainer() {
+            let videoCont = {};
+            videoCont.id = `${this.uniqueId}_video_${this.counter++}`;
+            if (this.videos.length == 1 && !this.lowMembersCountSelectedId) {
+                this.lowMembersCountSelectedId = videoCont.id;
             }
-        });
-    },
-    createVideoContainer() {
-        let videoCont = {};
-        videoCont.id = `${this.uniqueId}_video_${this.counter++}`;
-        if (this.videos.length == 1 && !this.lowMembersCountSelectedId) {
-            this.lowMembersCountSelectedId = videoCont.id;
-        }
 
-        this.videos.push(videoCont);
-        this.adjustVideoContainers();
+            this.videos.push(videoCont);
+            this.adjustVideoContainers();
 
-        return videoCont;
-    },
-    adjustVideoContainers() {
-        this.videoGrid = [];
+            return videoCont;
+        },
+        adjustVideoContainers() {
+            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) {
-            this.maxCols = cols * elementsLastRow;
-        } else {
-            this.maxCols = cols;
-        }
+            if (elementsLastRow) {
+                this.maxCols = cols * elementsLastRow;
+            } else {
+                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()) {
-            video.i = index;
-            video.x = cntX;
-            video.y = cntY;
-            video.h = rowsPerElement;
-            video.w = colsPerElement;
-            cntX += colsPerElement;
-
-            if (cntX >= this.maxCols) {
-                cntX = 0;
-                cntY += rowsPerElement;
-            }
+            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;
 
-            let videoTemp = Object.assign({}, video);
-            videoTemp.video = video;
-            this.videoGrid.push(videoTemp);
-        }
+                if (cntX >= this.maxCols) {
+                    cntX = 0;
+                    cntY += rowsPerElement;
+                }
+
+                let videoTemp = Object.assign({}, video);
+                videoTemp.video = video;
+                this.videoGrid.push(videoTemp);
+            }
 
-        /* OLD IMPLEMENTATION */
+            /* OLD IMPLEMENTATION */
 
-        /* for (let [index, video] of this.videos.entries()) {
+            /* for (let [index, video] of this.videos.entries()) {
             video.i = index;
             if (index < lastNormalIndex) {
                 video.x = cntX;
@@ -216,308 +207,308 @@ export default {
             this.videoGrid.push(videoTemp);
         } */
 
-        /* let gridColumn, gridRows = ''
+            /* let gridColumn, gridRows = ''
 
         if(rows && cols){
             gridColumn = `grid-template-columns: repeat(${cols}, minmax(320px, 1fr));`
             gridRows = `grid-template-rows: repeat(${rows}, minmax(240px, 1fr));`
         } */
-    },
-    initializeOpenTok(apiKey, sessionId, token) {
-      this.openTokSession = OT.initSession(apiKey, sessionId);
-
-      this.openTokSession.on({
-          sessionDisconnected: event => {
-              if (event.reason === "forceDisconnected") {
-                  alert("You were kicked.");
-                  if (this.user.type === "associate") {
-                      this.disconnect();
-                      this.$store.dispatch("leaveMeeting");
-                  } else {
-                      window.location = "/";
-                  }
-              }
-          }
-      });
-
-      // 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;
+        },
+        initializeOpenTok(apiKey, sessionId, token) {
+            this.openTokSession = OT.initSession(apiKey, sessionId);
+
+            this.openTokSession.on({
+                sessionDisconnected: event => {
+                    if (event.reason === "forceDisconnected") {
+                        alert("You were kicked.");
+                        if (this.user.type === "associate") {
+                            this.disconnect();
+                            this.$store.dispatch("leaveMeeting");
+                        } else {
+                            window.location = "/";
+                        }
+                    }
+                }
+            });
+
+            // 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.openTokSession.on("streamCreated", event => {
+                //console.log("stream Created event");
+                let container;
+                if (event.stream.videoType === "screen") {
+                    //TODO: This is
+                }
+                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;
+                            });
+                        }
+                    }
+                );
+                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);
+            });
+
+            this.openTokSession.connect(token, error => {
+                // If the connection is successful, publish to the session
+                if (error) {
+                    alert(error.message);
+                } else {
+                    this.$store.commit("setSessionConnectivityState", true);
+                }
+            });
+            this.loadingInProgress = false;
+        },
+        publishToSession() {
+            this.openTokSession.publish(this.publisher, error => {
+                if (error) {
+                    alert(error.message);
+                }
+            });
+        },
+        switchToFullSize(video, index) {
+            if (this.videos.length < 4) {
+                if (this.lowMembersCountSelectedId !== video.id && index !== 0) {
+                    this.lowMembersCountSelectedId = video.id;
+                }
+            } else {
+                this.bigMembersCountSelectedId = video.id;
             }
-          }
-      );
-
-      this.publisher.on({
-          accessDialogOpened: e => {
-            this.accessDialogShown = true;
-          },
-          accessDialogClosed: e => {
-            this.accessDialogShown = false;
-          }
-      });
-
-      this.openTokSession.on("streamCreated", event => {
-        //console.log("stream Created event");
-        let container;
-        if (event.stream.videoType === "screen") {
-          //TODO: This is
+        },
+        ready() {
+            this.$nextTick(function() {
+                this.readyForUse = true;
+                if (this.user.type === "associate") {
+                    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()) {
+                    alert("Meeting not started.");
+                    return;
+                }
+                let participantId = this.user.id;
+                if (!participantId) {
+                    this.$refs.initialModal.show(this.meeting.passwordRequired);
+                    return;
+                }
+                this.getToken({
+                    participantId
+                });
+            });
+        },
+        shareScreen() {
+            if (this.screenPublisher) return;
+            this.screenPublisher = OT.initPublisher(
+                this.$refs.otContainer,
+                {
+                    insertMode: "append",
+                    width: "100%",
+                    height: "100%",
+                    resolution: "1280x720",
+                    frameRate: 30,
+                    videoSource: "screen",
+                    name: this.user.name,
+                    style: {
+                        nameDisplayMode: "on",
+                        archiveStatusDisplayMode: "off"
+                    }
+                },
+                error => {
+                    if (error) {
+                        console.error(error);
+                        if (error.code !== 1500) alert(error.message);
+                        this.screenPublisher = null;
+                    } else {
+                        const cont = this.createVideoContainer();
+                        this.$nextTick(() => {
+                            cont.el = $(`#${cont.id}`)[0];
+                            cont.el.appendChild(this.screenPublisher.element);
+                            cont.obj = this.screenPublisher;
+                            // cont.self = true;
+
+                            this.$set(cont, "self", true);
+                        });
+                        this.screenPublisher.on("streamDestroyed", event => {
+                            cont.el.remove();
+                            const index = this.videos.findIndex(v => v.id == cont.id);
+                            if (index >= 0) this.videos.splice(index, 1);
+                            this.adjustVideoContainers();
+                            this.screenPublisher = null;
+                            this.$store.commit("setScreenShareState", false);
+                        });
+                        this.openTokSession.publish(this.screenPublisher, error => {
+                            if (error) {
+                                alert(error.message);
+                            }
+                        });
+                        this.$store.commit("setScreenShareState", true);
+                    }
+                }
+            );
+        },
+        kickParcitipantContinue(participant) {
+            const connection = participant.video.obj.stream.connection;
+            const [type, id] = connection.data.split(":");
+            this.openTokSession.forceDisconnect(connection, error => {
+                if (error) {
+                    console.error(error);
+                } else {
+                    $.ajax({
+                        url: `/associate/meeting/${this.meeting.id}/kick`,
+                        method: "POST",
+                        headers: {
+                            "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
+                        },
+                        data: {
+                            type,
+                            id
+                        },
+                        error: jXhr => {
+                            console.error(getSingleError(jXhr));
+                        }
+                    });
+                }
+            });
+        },
+        kickParcitipant(participant) {
+            if (confirm("Are you sure want to kick this person out of meeting?")) this.kickParcitipantContinue(participant);
         }
-        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;
-                  });
-              }
-          }
-        );
-        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);
-      });
-
-    this.openTokSession.connect(token, error => {
-        // If the connection is successful, publish to the session
-        if (error) {
-            alert(error.message);
-        } else {
-            this.$store.commit("setSessionConnectivityState", true);
+    },
+    watch: {
+        publisherReady(val) {
+            if (val && this.session.sessionConnected) this.publishToSession();
+        },
+        "session.sessionConnected"(val) {
+            if (val && this.publisherReady) this.publishToSession();
+        },
+        "user.is_active_and_visible"(val) {
+            if (!this.publisher || !this.publisher.publishVideo) return;
+            this.publisher.publishVideo(val);
+            this.publisher.publishAudio(val);
+        },
+        "meeting.uid"(val) {
+            if (this.loadingInProgress) return;
+            this.loadingInProgress = true;
+            this.disconnect();
+
+            if (val) {
+                this.getToken();
+            } else {
+                this.loadingInProgress = false;
+            }
+        },
+        "active_menu_item.template"(val) {
+            if (this.loadingInProgress || val !== "room" || !this.meeting.id || this.openTokSession) return;
+            this.loadingInProgress = true;
+            this.getToken({}, true);
         }
-      });
-      this.loadingInProgress = false;
     },
-    publishToSession() {
-        this.openTokSession.publish(this.publisher, error => {
-          if (error) {
-            alert(error.message);
-          }
+    created() {
+        OT.checkScreenSharingCapability(response => {
+            this.$store.commit("setScreesharingAvailability", response.supported);
         });
     },
-    switchToFullSize(video, index) {
-        if (this.videos.length < 4) {
-          if (this.lowMembersCountSelectedId !== video.id && index !== 0) {
-            this.lowMembersCountSelectedId = video.id;
-          }
-        } else {
-          this.bigMembersCountSelectedId = video.id;
-        }
-    },
-    ready() {
-        this.$nextTick(function() {
-          this.readyForUse = true;
-          if (this.user.type === "associate") {
-            if (!this.meeting.id || this.active_menu_item.template !== "room") return;
+    mounted() {
+        let self = this;
+
+        this.$eventBus.$on("screenShare", this.shareScreen);
+        this.$eventBus.$on("meetingRejoin", () => {
+            this.loadingInProgress = true;
+            this.disconnect();
             this.getToken({}, true);
-            return;
-          }
-
-          if (this.meeting.scheduledDate && !this.meeting.startedAt && this.meeting.scheduledDate > new Date()) {
-            alert("Meeting not started.");
-            return;
-          }
-          let participantId = this.user.id;
-          if (!participantId) {
-            this.$refs.initialModal.show(this.meeting.passwordRequired);
-            return;
-          }
-          this.getToken({
-            participantId
-          });
         });
-    },
-    shareScreen() {
-        if (this.screenPublisher) return;
-        this.screenPublisher = OT.initPublisher(
-          this.$refs.otContainer,
-          {
-            insertMode: "append",
-            width: "100%",
-            height: "100%",
-            resolution: "1280x720",
-            frameRate: 30,
-            videoSource: "screen",
-            name: this.user.name,
-            style: {
-              nameDisplayMode: "on",
-              archiveStatusDisplayMode: "off"
+
+        let width = $(window).width();
+        let height = $(window).height();
+
+        window.addEventListener("resize", function() {
+            let new_width = $(window).width();
+            let new_height = $(window).height();
+
+            if (width !== new_width || height !== new_height) {
+                self.adjustVideoContainers();
             }
-          },
-          error => {
-              if (error) {
-                console.error(error);
-                if (error.code !== 1500) alert(error.message);
-                this.screenPublisher = null;
-              } else {
-                const cont = this.createVideoContainer();
-                this.$nextTick(() => {
-                  cont.el = $(`#${cont.id}`)[0];
-                  cont.el.appendChild(this.screenPublisher.element);
-                  cont.obj = this.screenPublisher;
-                  // cont.self = true;
-
-                  this.$set(cont, "self", true);
-                });
-                this.screenPublisher.on("streamDestroyed", event => {
-                  cont.el.remove();
-                  const index = this.videos.findIndex(v => v.id == cont.id);
-                  if (index >= 0) this.videos.splice(index, 1);
-                  this.adjustVideoContainers();
-                  this.screenPublisher = null;
-                  this.$store.commit("setScreenShareState", false);
-                });
-                this.openTokSession.publish(this.screenPublisher, error => {
-                  if (error) {
-                    alert(error.message);
-                  }
-                });
-                this.$store.commit("setScreenShareState", true);
-              }
-          }
-        );
-    },
-    kickParcitipantContinue(participant) {
-        const connection = participant.video.obj.stream.connection;
-        const [type, id] = connection.data.split(":");
-        this.openTokSession.forceDisconnect(connection, error => {
-          if (error) {
-            console.error(error);
-          } else {
+        });
+
+        this.$eventBus.$on("leaveMeeting", () => {
             $.ajax({
-              url: `/associate/meeting/${this.meeting.id}/kick`,
-              method: "POST",
-              headers: {
-                "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
-              },
-              data: {
-                type,
-                id
-              },
-              error: jXhr => {
-                console.error(getSingleError(jXhr));
-              }
+                url: "/associate/meeting/leave",
+                method: "POST",
+                headers: {
+                    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
+                },
+                error: jXhr => {
+                    console.error(getSingleError(jXhr));
+                }
             });
-          }
+            this.$store.dispatch("leaveMeeting");
+            this.disconnect();
         });
-    },
-    kickParcitipant(participant) {
-      if (confirm("Are you sure want to kick this person out of meeting?")) this.kickParcitipantContinue(participant);
     }
-},
-watch: {
-    publisherReady(val) {
-      if (val && this.session.sessionConnected) this.publishToSession();
-    },
-    "session.sessionConnected"(val) {
-      if (val && this.publisherReady) this.publishToSession();
-    },
-    "user.is_active_and_visible"(val) {
-      if (!this.publisher || !this.publisher.publishVideo) return;
-      this.publisher.publishVideo(val);
-      this.publisher.publishAudio(val);
-    },
-    "meeting.id"(val) {
-      if (this.loadingInProgress) return;
-      this.loadingInProgress = true;
-      this.disconnect();
-
-      if (val) {
-          this.getToken({}, true);
-      } else {
-          this.loadingInProgress = false;
-      }
-    },
-    "active_menu_item.template"(val) {
-      if (this.loadingInProgress || val !== "room" || !this.meeting.id || this.openTokSession) return;
-      this.loadingInProgress = true;
-      this.getToken({}, true);
-    }
-  },
-  created() {
-    OT.checkScreenSharingCapability(response => {
-      this.$store.commit("setScreesharingAvailability", response.supported);
-    });
-  },
-  mounted() {
-    let self = this;
-
-    this.$eventBus.$on("screenShare", this.shareScreen);
-    this.$eventBus.$on("meetingRejoin", () => {
-      this.loadingInProgress = true;
-      this.disconnect();
-      this.getToken({}, true);
-    });
-
-    let width = $(window).width();
-    let height = $(window).height();
-
-    window.addEventListener("resize", function() {
-      let new_width = $(window).width();
-      let new_height = $(window).height();
-
-      if (width !== new_width || height !== new_height) {
-        self.adjustVideoContainers();
-      }
-    });
-
-    this.$eventBus.$on("leaveMeeting", () => {
-      $.ajax({
-        url: "/associate/meeting/leave",
-        method: "POST",
-        headers: {
-          "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
-        },
-        error: jXhr => {
-          console.error(getSingleError(jXhr));
-        }
-      });
-      this.$store.dispatch("leaveMeeting");
-      this.disconnect();
-    });
-  }
-}
+};
 </script>

+ 2 - 0
resources/views/mc.blade.php

@@ -5,6 +5,8 @@
     <meta name="viewport"
           content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <!-- CSRF Token -->
+    <meta name="csrf-token" content="{{ csrf_token() }}">
     <script src="{{ mix('js/app.js') }}" defer></script>
     <link rel="stylesheet" href="/css/bootstrap.min.css">
     <link href="{{ mix('css/app.css') }}" rel="stylesheet">