Working datachannel, youtube support & server fix
This commit is contained in:
49
client/package-lock.json
generated
49
client/package-lock.json
generated
@@ -5727,6 +5727,11 @@
|
|||||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"get-youtube-id": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-youtube-id/-/get-youtube-id-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-5yidLzoLXbtw82a/Wb7LrajkGn29BM6JuLWeHyNfzOGp1weGyW4+7eMz6cP23+etqj27VlOFtq8fFFDMLq/FXQ=="
|
||||||
|
},
|
||||||
"getpass": {
|
"getpass": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||||
@@ -7058,6 +7063,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"load-script": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ="
|
||||||
|
},
|
||||||
"loader-fs-cache": {
|
"loader-fs-cache": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
||||||
@@ -9923,6 +9933,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"sister": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA=="
|
||||||
|
},
|
||||||
"slash": {
|
"slash": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
|
||||||
@@ -11314,6 +11329,15 @@
|
|||||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vue-youtube": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-youtube/-/vue-youtube-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-PCyfGAouSt6rTX0GLUzpdX2XC52zYf7a9mUhdp53jeDlPoU40hpsvyV3Zg2+947pvbv27ORcmtzm2fqO08kh9Q==",
|
||||||
|
"requires": {
|
||||||
|
"get-youtube-id": "^1.0.0",
|
||||||
|
"youtube-player": "^5.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vuex": {
|
"vuex": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
|
||||||
@@ -12328,6 +12352,31 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"youtube-player": {
|
||||||
|
"version": "5.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz",
|
||||||
|
"integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "^2.6.6",
|
||||||
|
"load-script": "^1.0.0",
|
||||||
|
"sister": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"register-service-worker": "^1.7.1",
|
"register-service-worker": "^1.7.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
|
"vue-youtube": "^1.4.0",
|
||||||
"vuex": "^3.4.0"
|
"vuex": "^3.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
13
client/src/components/Player.vue
Normal file
13
client/src/components/Player.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div id="player"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -4,11 +4,13 @@ import './registerServiceWorker'
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import Buefy from 'buefy'
|
import Buefy from 'buefy'
|
||||||
|
import VueYoutube from 'vue-youtube'
|
||||||
|
|
||||||
import 'buefy/dist/buefy.css'
|
import 'buefy/dist/buefy.css'
|
||||||
|
|
||||||
// import './assets/style.scss'
|
// import './assets/style.scss'
|
||||||
|
|
||||||
Vue.use(Buefy)
|
Vue.use(Buefy)
|
||||||
|
Vue.use(VueYoutube)
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
|||||||
@@ -3,7 +3,16 @@ const state = {
|
|||||||
roomStatus: {
|
roomStatus: {
|
||||||
roomName: '',
|
roomName: '',
|
||||||
roomCode: '',
|
roomCode: '',
|
||||||
current: '',
|
player: {
|
||||||
|
timeCode: 0,
|
||||||
|
playing: true
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
link: '',
|
||||||
|
title: '',
|
||||||
|
votes: 0,
|
||||||
|
voters: []
|
||||||
|
},
|
||||||
playlist: []
|
playlist: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +32,35 @@ const actions = {
|
|||||||
},
|
},
|
||||||
setAdmin ({ commit }) {
|
setAdmin ({ commit }) {
|
||||||
commit('SET_ADMIN')
|
commit('SET_ADMIN')
|
||||||
|
},
|
||||||
|
vote ({ commit, dispatch, state }, { link, isPositive, voterName }) {
|
||||||
|
console.log('vote on ' + link + ' (' + isPositive + ') by ' + voterName)
|
||||||
|
if (isPositive) {
|
||||||
|
commit('ADD_VOTE', {
|
||||||
|
link: link,
|
||||||
|
voterName: voterName
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
commit('REMOVE_VOTE', {
|
||||||
|
link: link,
|
||||||
|
voterName: voterName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
||||||
|
},
|
||||||
|
setCurrent ({ commit, dispatch }, { playerStatus, timeCode }) {
|
||||||
|
switch (playerStatus) {
|
||||||
|
case 0:
|
||||||
|
commit('CURRENT_END')
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
commit('CURRENT_PLAY', timeCode)
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
commit('CURRENT_PAUSE', timeCode)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dispatch('rtc/broadcast', { message: state.roomStatus, type: 'status' }, { root: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +77,58 @@ const mutations = {
|
|||||||
SET_ADMIN (state) {
|
SET_ADMIN (state) {
|
||||||
state.admin = true
|
state.admin = true
|
||||||
},
|
},
|
||||||
BROADCAST_ROOMSTATUS (state) {
|
ADD_VOTE (state, { link, voterName }) {
|
||||||
|
var play = state.roomStatus.playlist.find(play => play.link === link)
|
||||||
|
if (play === undefined) {
|
||||||
|
play = {
|
||||||
|
link: link,
|
||||||
|
votes: 1,
|
||||||
|
voters: [
|
||||||
|
voterName
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (state.roomStatus.current.votes === 0) state.roomStatus.current = play
|
||||||
|
else state.roomStatus.playlist.push(play)
|
||||||
|
} else {
|
||||||
|
play.votes++
|
||||||
|
play.voters.push(voterName)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
REMOVE_VOTE (state, { link, voterName }) {
|
||||||
|
var play = state.roomStatus.playlist.find(play => play.link === link)
|
||||||
|
play.votes--
|
||||||
|
const index = play.voters.indexOf(voterName)
|
||||||
|
if (index > -1) {
|
||||||
|
play.voters.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (play.vote === 0) {
|
||||||
|
const index = state.roomStatus.playlist.indexOf(play)
|
||||||
|
if (index > -1) {
|
||||||
|
state.roomStatus.playlist.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CURRENT_END (state) {
|
||||||
|
if (state.roomStatus.playlist.length === 0) {
|
||||||
|
state.roomStatus.current.link = ''
|
||||||
|
state.roomStatus.current.title = ''
|
||||||
|
state.roomStatus.current.votes = 0
|
||||||
|
state.roomStatus.current.voters = []
|
||||||
|
} else {
|
||||||
|
state.roomStatus.playlist.sort((a, b) => {
|
||||||
|
return b.votes - a.votes
|
||||||
|
})
|
||||||
|
state.roomStatus.current = state.roomStatus.playlist.shift()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CURRENT_PAUSE (state, timeCode) {
|
||||||
|
state.roomStatus.player.playing = false
|
||||||
|
state.roomStatus.player.timeCode = timeCode
|
||||||
|
},
|
||||||
|
CURRENT_PLAY (state, timeCode) {
|
||||||
|
state.roomStatus.player.playing = true
|
||||||
|
state.roomStatus.player.timeCode = timeCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ const actions = {
|
|||||||
leave ({ commit }) {
|
leave ({ commit }) {
|
||||||
commit('LEAVE')
|
commit('LEAVE')
|
||||||
},
|
},
|
||||||
broadcast ({ commit }, message) {
|
broadcast ({ commit }, { message, type }) {
|
||||||
commit('BROADCAST', message)
|
commit('BROADCAST', { message: message, type: type })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +79,7 @@ const mutations = {
|
|||||||
var peer = state.peers.find(peer => peer.name === target)
|
var peer = state.peers.find(peer => peer.name === target)
|
||||||
|
|
||||||
peer.dataChannel = peer.connection.createDataChannel('dataChannel')
|
peer.dataChannel = peer.connection.createDataChannel('dataChannel')
|
||||||
|
peer.dataChannel.onmessage = handleDataChannelMessage
|
||||||
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
|
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
|
||||||
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
|
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
|
||||||
|
|
||||||
@@ -127,9 +128,14 @@ const mutations = {
|
|||||||
})
|
})
|
||||||
state.peers = {}
|
state.peers = {}
|
||||||
},
|
},
|
||||||
BROADCAST (state, message) {
|
BROADCAST (state, { message, type }) {
|
||||||
|
const data = JSON.stringify({
|
||||||
|
type: type,
|
||||||
|
message: message
|
||||||
|
})
|
||||||
|
console.log('[RTC] broadcast message ' + data)
|
||||||
state.peers.forEach(peer => {
|
state.peers.forEach(peer => {
|
||||||
peer.dataChannel.send(message)
|
peer.dataChannel.send(data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,17 +173,19 @@ function handleDataChannelCallback (event) {
|
|||||||
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
|
peer.dataChannel.onopen = handleDataChannelStateChangeEvent
|
||||||
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
|
peer.dataChannel.onclose = handleDataChannelStateChangeEvent
|
||||||
|
|
||||||
store.dispatch('rtc/broadcast', store.state.room.roomStatus)
|
store.dispatch('rtc/broadcast', { message: store.state.room.roomStatus, type: 'status' })
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDataChannelMessage (event) {
|
function handleDataChannelMessage (event) {
|
||||||
console.log('[RTC] data channel message ' + event.data)
|
console.log('[RTC] data channel message ' + event.data)
|
||||||
var data = event.data
|
var data = JSON.parse(event.data)
|
||||||
|
console.log('[RTC] data channel message type ' + data.type)
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'status':
|
case 'status':
|
||||||
store.dispatch('room/setRoomStatus', data.message)
|
store.dispatch('room/setRoomStatus', data.message)
|
||||||
break
|
break
|
||||||
case 'vote':
|
case 'vote':
|
||||||
|
store.dispatch('room/vote', { link: data.message.link, isPositive: data.message.isPositive, voterName: data.message.voterName })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,19 @@
|
|||||||
<h2 class="subtitle">{{roomStatus.current.title}}</h2>
|
<h2 class="subtitle">{{roomStatus.current.title}}</h2>
|
||||||
|
|
||||||
<b-tabs>
|
<b-tabs>
|
||||||
|
<b-tab-item label="Player" :visible="settings.showPlayer">
|
||||||
|
<div class="playerDiv">
|
||||||
|
<youtube
|
||||||
|
:video-id="roomStatus.current.link"
|
||||||
|
nocookie="true"
|
||||||
|
ref="youtube"
|
||||||
|
@playing="roomStatus.player.playing"
|
||||||
|
></youtube>
|
||||||
|
</div>
|
||||||
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Playlist">
|
<b-tab-item label="Playlist">
|
||||||
|
<b-button icon-left="plus" @click="addLinkPrompt">Add link</b-button>
|
||||||
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
<b-table :data="roomStatus.playlist" striped hoverable default-sort="vote">
|
||||||
<template slot-scope="props">
|
<template slot-scope="props">
|
||||||
<b-table-column field="title" label="Title">
|
<b-table-column field="title" label="Title">
|
||||||
@@ -16,24 +28,37 @@
|
|||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column field="vote" label="Votes">
|
<b-table-column field="vote" label="Votes">
|
||||||
{{props.row.vote}}
|
{{props.row.votes}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="voters" label="Voters" :visible="isAdmin">
|
||||||
|
{{props.row.voters}}
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column>
|
<b-table-column>
|
||||||
<b-button icon-left="arrow-up-bold-outline" type="is-dark"/>
|
<b-button v-if="hasVoted(props.row)" icon-left="arrow-down-bold-outline" type="is-dark" @click="vote (props.row.link, false)"/>
|
||||||
<b-button icon-left="arrow-down-bold-outline" type="is-dark"/>
|
<b-button v-else icon-left="arrow-up-bold-outline" type="is-dark" @click="vote (props.row.link, true)"/>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
</template>
|
</template>
|
||||||
</b-table>
|
</b-table>
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
<b-tab-item label="Admin" :visible="showAdmin">
|
<b-tab-item label="Admin" :visible="isAdmin">
|
||||||
|
<b-button @click="broadcastStatus">Force status update</b-button>
|
||||||
<b-table :data="usersList" striped hoverable>
|
<b-table :data="usersList" striped hoverable>
|
||||||
<template slot-scope="props">
|
<template slot-scope="props">
|
||||||
<b-table-column field="name" label="Name">
|
<b-table-column field="name" label="Name">
|
||||||
{{props.row.name}}
|
{{props.row.name}}
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="connection" label="Connection">
|
||||||
|
{{props.row.connection.signalingState}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="data" label="DataChannel">
|
||||||
|
{{props.row.dataChannel.readyState}}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column>
|
<b-table-column>
|
||||||
<b-button icon-left="karate" type="is-dark"/>
|
<b-button icon-left="karate" type="is-dark"/>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
@@ -45,7 +70,17 @@
|
|||||||
<h1 class="subtitle">{{roomStatus.roomCode}}</h1>
|
<h1 class="subtitle">{{roomStatus.roomCode}}</h1>
|
||||||
</b-tab-item>
|
</b-tab-item>
|
||||||
|
|
||||||
|
<b-tab-item label="Settings">
|
||||||
|
<div class="field">
|
||||||
|
<b-switch v-model="settings.playLink">Play link</b-switch>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<b-switch v-model="settings.showPlayer" :disabled="!settings.playLink">Show player</b-switch>
|
||||||
|
</div>
|
||||||
|
</b-tab-item>
|
||||||
|
|
||||||
</b-tabs>
|
</b-tabs>
|
||||||
|
<b-loading is-full-page :active.sync="isRoomLoading"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -53,10 +88,13 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Room',
|
name: 'Room',
|
||||||
computed: {
|
computed: {
|
||||||
|
player () {
|
||||||
|
return this.$refs.youtube.player
|
||||||
|
},
|
||||||
roomStatus () {
|
roomStatus () {
|
||||||
return this.$store.state.room.roomStatus
|
return this.$store.state.room.roomStatus
|
||||||
},
|
},
|
||||||
showAdmin () {
|
isAdmin () {
|
||||||
return this.$store.state.room.admin
|
return this.$store.state.room.admin
|
||||||
},
|
},
|
||||||
usersList () {
|
usersList () {
|
||||||
@@ -65,14 +103,86 @@ export default {
|
|||||||
},
|
},
|
||||||
isLoggedIn () {
|
isLoggedIn () {
|
||||||
return this.$store.state.app.loginSuccess
|
return this.$store.state.app.loginSuccess
|
||||||
|
},
|
||||||
|
isRoomLoading () {
|
||||||
|
return this.roomStatus.roomName === ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
settings: {
|
||||||
|
playLink: true,
|
||||||
|
showPlayer: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (!this.isLoggedIn) this.$router.push({ name: 'Home' })
|
if (!this.isLoggedIn) this.$router.push({ name: 'Home' })
|
||||||
|
this.player.addEventListener('onStateChange', this.playerStateChange)
|
||||||
|
this.player.playVideo()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
roomStatus: function (status) {
|
||||||
|
this.player.seekTo(status.player.timeCode, true)
|
||||||
|
if (status.player.playing) this.player.playVideo()
|
||||||
|
else this.player.pauseVideo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
broadcastStatus () {
|
||||||
|
this.$store.dispatch('rtc/broadcast', { message: this.$store.state.room.roomStatus, type: 'status' })
|
||||||
|
},
|
||||||
|
addLinkPrompt () {
|
||||||
|
this.$buefy.dialog.prompt({
|
||||||
|
message: 'Add a youtube link',
|
||||||
|
trapFocus: true,
|
||||||
|
inputAttrs: {
|
||||||
|
placeholder: 'https://www.youtube.com/watch?v=YItIK09bpKk',
|
||||||
|
minlength: 10
|
||||||
|
},
|
||||||
|
cancelText: 'Nah',
|
||||||
|
confirmText: 'Add',
|
||||||
|
onConfirm: (link) => this.addLink(link)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addLink (link) {
|
||||||
|
const linkID = this.$youtube.getIdFromUrl(link)
|
||||||
|
if (linkID === null) {
|
||||||
|
this.$buefy.toast.open('Invalid youtube link')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.isAdmin) {
|
||||||
|
this.$store.dispatch('room/vote', { link: linkID, isPositive: true, voterName: this.$store.state.rtc.name })
|
||||||
|
} else {
|
||||||
|
this.vote(linkID, true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vote (link, isPositive) {
|
||||||
|
const message = {
|
||||||
|
type: 'vote',
|
||||||
|
link: link,
|
||||||
|
isPositive: isPositive,
|
||||||
|
voterName: this.$store.state.rtc.name
|
||||||
|
}
|
||||||
|
this.$store.dispatch('rtc/broadcast', { message: message, type: 'vote' })
|
||||||
|
},
|
||||||
|
hasVoted (play) {
|
||||||
|
return play.voters.includes(this.$store.state.rtc.name)
|
||||||
|
},
|
||||||
|
async playerStateChange (event) {
|
||||||
|
console.log('[PLAYER] Status change ' + event.data)
|
||||||
|
if (this.isAdmin) this.$store.dispatch('room/setCurrent', { playerStatus: event.data, timeCode: await this.$refs.youtube.player.getCurrentTime() })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.room {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerDiv {
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class RoomManager implements IRoomManager{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println("[ROOM] Foward RTC");
|
System.err.println("[ROOM] Foward RTC message");
|
||||||
followMessage(targetSession, message);
|
followMessage(targetSession, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.socket.CloseStatus;
|
||||||
import org.springframework.web.socket.TextMessage;
|
import org.springframework.web.socket.TextMessage;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||||
@@ -22,7 +23,7 @@ public class SocketHandler extends TextWebSocketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
|
||||||
System.err.println("SOCKET MESSAGE :" + message.getPayload());
|
System.err.println("[WS] message :" + message.getPayload());
|
||||||
|
|
||||||
String payload = message.getPayload();
|
String payload = message.getPayload();
|
||||||
JSONObject jsonObject = new JSONObject(payload);
|
JSONObject jsonObject = new JSONObject(payload);
|
||||||
@@ -59,4 +60,11 @@ public class SocketHandler extends TextWebSocketHandler {
|
|||||||
System.err.println("[WS] new connection");
|
System.err.println("[WS] new connection");
|
||||||
sessions.add(session);
|
sessions.add(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
|
||||||
|
System.err.println("[WS] connection closed");
|
||||||
|
sessions.remove(session);
|
||||||
|
roomManager.leave(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user