Change-Id: I1d8ae9dc2b241c392e450d02c3aa5eeab7eabd50pull/13/head
parent
9da0c00285
commit
73ba4fa869
@ -1,219 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="col-xs-10 col-sm-8 col-md-4 csc-opt-center"
|
||||
>
|
||||
<csc-inline-alert-info
|
||||
v-if="!hasRtcEngineCapabilityEnabled"
|
||||
class="q-mb-lg"
|
||||
>
|
||||
{{ $t('You can not join a conference, since the RTC:engine is not active. If you operate a C5 CE then first upgrade to a C5 PRO to be able to use the RTC:engine.') }}
|
||||
</csc-inline-alert-info>
|
||||
<div
|
||||
class="text-h6 text-center q-mb-lg"
|
||||
>
|
||||
{{ $t('Join conference with name') }}
|
||||
</div>
|
||||
<q-input
|
||||
ref="conferenceName"
|
||||
class="q-mb-lg"
|
||||
:value="conferenceIdInput"
|
||||
:placeholder="$t('Conference name')"
|
||||
:disable="isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
@input="conferenceIdChanged"
|
||||
>
|
||||
<template
|
||||
v-slot:prepend
|
||||
>
|
||||
<q-icon
|
||||
name="meeting_room"
|
||||
size="24px"
|
||||
/>
|
||||
</template>
|
||||
<template
|
||||
v-slot:append
|
||||
>
|
||||
<q-btn
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
:color="shareButtonColor"
|
||||
:label="$t('Share')"
|
||||
flat
|
||||
dense
|
||||
icon="link"
|
||||
@click="showShareDialog"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<div
|
||||
class="row justify-center"
|
||||
>
|
||||
<q-btn
|
||||
:color="joinButtonColor"
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
icon="login"
|
||||
text-color="dark"
|
||||
unelevated
|
||||
round
|
||||
size="large"
|
||||
@click="join"
|
||||
/>
|
||||
</div>
|
||||
<csc-object-spinner
|
||||
:loading="isJoining"
|
||||
/>
|
||||
<csc-share-conference-dialog
|
||||
ref="shareDialog"
|
||||
:conference-url="conferenceUrl"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
randInRange
|
||||
} from 'src/helpers/math-helper'
|
||||
import CscShareConferenceDialog from './CscShareConferenceDialog'
|
||||
import CscObjectSpinner from '../../CscObjectSpinner'
|
||||
import CscInlineAlertInfo from 'components/CscInlineAlertInfo'
|
||||
import { showGlobalError } from 'src/helpers/ui'
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'CscConferenceJoin',
|
||||
components: {
|
||||
CscInlineAlertInfo,
|
||||
CscObjectSpinner,
|
||||
CscShareConferenceDialog
|
||||
},
|
||||
props: {
|
||||
conferenceId: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
hasConferenceId: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
conferenceUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
localMediaStream: {
|
||||
type: MediaStream,
|
||||
default: null
|
||||
},
|
||||
isMicrophoneEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isCameraEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isScreenEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isJoining: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isJoined: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
hasRtcEngineCapabilityEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
conferenceIdInput: this.conferenceId
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('conference', [
|
||||
'localMediaError'
|
||||
]),
|
||||
contentClasses () {
|
||||
const classes = ['col', 'col-md-4', 'text-center']
|
||||
if (this.isCameraEnabled) {
|
||||
classes.push('csc-camera-background')
|
||||
} else if (this.isScreenEnabled) {
|
||||
classes.push('csc-screen-background')
|
||||
}
|
||||
return classes
|
||||
},
|
||||
joinButtonColor () {
|
||||
return 'primary'
|
||||
},
|
||||
shareButtonColor () {
|
||||
if (this.hasConferenceId) {
|
||||
return 'primary'
|
||||
} else {
|
||||
return 'grey'
|
||||
}
|
||||
},
|
||||
isMediaEnabled () {
|
||||
return this.isCameraEnabled || this.isScreenEnabled || this.isMicrophoneEnabled
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
conferenceId (value) {
|
||||
this.conferenceIdInput = value
|
||||
},
|
||||
localMediaError (error) {
|
||||
if (error !== null && error !== undefined) {
|
||||
showGlobalError(error)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (!this.conferenceId) {
|
||||
this.conferenceIdChanged(this.createConferenceId())
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
join () {
|
||||
this.$emit('join', this.conferenceId)
|
||||
},
|
||||
conferenceIdChanged (value) {
|
||||
try {
|
||||
this.$router.push({
|
||||
path: '/conference/' + value
|
||||
})
|
||||
this.conferenceIdInput = value
|
||||
} catch (err) {
|
||||
this.conferenceIdInput = this.conferenceId
|
||||
}
|
||||
},
|
||||
showShareDialog () {
|
||||
this.$refs.shareDialog.open()
|
||||
},
|
||||
createConferenceId () {
|
||||
const prefixes = ['conf', 'room', 'space']
|
||||
const randPrefixIndex = randInRange(0, prefixes.length - 1)
|
||||
const randSuffix = randInRange(100000, 999999)
|
||||
return prefixes[randPrefixIndex] + randSuffix
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
.csc-conf-alert
|
||||
margin-bottom $flex-gutter-md
|
||||
#csc-conf-link-input
|
||||
margin-bottom $flex-gutter-md
|
||||
#csc-conf-join-text
|
||||
margin-bottom $flex-gutter-md
|
||||
font-weight bold
|
||||
font-size 1rem
|
||||
#csc-conf-join-content
|
||||
padding $flex-gutter-md
|
||||
position relative
|
||||
z-index 2
|
||||
#csc-conf-join-content.csc-camera-background
|
||||
background-color alpha($main-menu-background, 0.5)
|
||||
#csc-conf-join-content.csc-screen-background
|
||||
background-color alpha($main-menu-background, 0.5)
|
||||
</style>
|
@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CscConferenceJoined',
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
</style>
|
@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<q-card
|
||||
class="bg-transparent"
|
||||
flat
|
||||
>
|
||||
<q-card-section
|
||||
v-if="!localMediaStream || localMediaStream && (!isCameraEnabled && !isScreenEnabled)"
|
||||
class="bg-black text-center"
|
||||
style="height: 100px"
|
||||
>
|
||||
<q-avatar
|
||||
class="absolute-center"
|
||||
style="top: 40px"
|
||||
>
|
||||
<q-icon
|
||||
name="person"
|
||||
size="32px"
|
||||
/>
|
||||
</q-avatar>
|
||||
</q-card-section>
|
||||
<q-card-section
|
||||
v-show="localMediaStream && (isCameraEnabled || isScreenEnabled)"
|
||||
class="relative-position bg-black text-center full-width no-padding"
|
||||
style="height: 100px"
|
||||
>
|
||||
<csc-media
|
||||
ref="cscMedia"
|
||||
:preview="false"
|
||||
:muted="true"
|
||||
:stream="localMediaStream"
|
||||
/>
|
||||
</q-card-section>
|
||||
<div
|
||||
class="absolute-bottom text-center bg-main-menu q-pa-xs"
|
||||
>
|
||||
{{ localParticipant.displayName }}
|
||||
</div>
|
||||
<!-- <q-card-section-->
|
||||
<!-- class="bg-black text-subtitle2 text-center q-pb-sm q-pr-sm q-pl-sm q-pt-none"-->
|
||||
<!-- >-->
|
||||
<!-- {{ localParticipant.displayName }}-->
|
||||
<!-- </q-card-section>-->
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscMedia from '../../CscMedia'
|
||||
export default {
|
||||
name: 'CscConferenceLocalParticipant',
|
||||
components: {
|
||||
CscMedia
|
||||
},
|
||||
props: {
|
||||
localParticipant: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
displayName: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
localMediaStream: {
|
||||
type: MediaStream,
|
||||
default: null
|
||||
},
|
||||
isMicrophoneEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isCameraEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isScreenEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
localMediaStream (stream) {
|
||||
this.assignStream(stream)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.assignStream(this.localMediaStream)
|
||||
},
|
||||
methods: {
|
||||
assignStream (stream) {
|
||||
if (this.$refs.cscMedia) {
|
||||
this.$refs.cscMedia.assignStream(stream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
id="csc-conf-participants-cont"
|
||||
class="row justify-right items-center"
|
||||
>
|
||||
<csc-conference-local-participant
|
||||
ref="localParticipant"
|
||||
:local-participant="localParticipant"
|
||||
:local-media-stream="localMediaStream"
|
||||
:is-microphone-enabled="isMicrophoneEnabled"
|
||||
:is-camera-enabled="isCameraEnabled"
|
||||
:is-screen-enabled="isScreenEnabled"
|
||||
@click.native="setSelectedParticipant('local')"
|
||||
/>
|
||||
<div
|
||||
id="csc-conf-remote-participants-cont"
|
||||
>
|
||||
<csc-conference-remote-participant
|
||||
v-for="participantId in participantsList"
|
||||
:key="participantId"
|
||||
:remote-participant="remoteParticipant(participantId)"
|
||||
:has-remote-video="hasRemoteVideo(participantId)"
|
||||
:remote-media-stream="remoteMediaStream"
|
||||
:remote-media-streams="remoteMediaStreams"
|
||||
@click.native="setSelectedParticipant(participantId)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters,
|
||||
mapState
|
||||
} from 'vuex'
|
||||
import CscConferenceRemoteParticipant from './CscConferenceRemoteParticipant'
|
||||
import CscConferenceLocalParticipant from './CscConferenceLocalParticipant'
|
||||
|
||||
export default {
|
||||
name: 'CscConferenceParticipants',
|
||||
components: {
|
||||
CscConferenceRemoteParticipant,
|
||||
CscConferenceLocalParticipant
|
||||
},
|
||||
computed: {
|
||||
...mapState('conference', [
|
||||
'remoteMediaStreams'
|
||||
]),
|
||||
...mapGetters('conference', [
|
||||
'participantsList',
|
||||
'localParticipant',
|
||||
'localMediaStream',
|
||||
'isMicrophoneEnabled',
|
||||
'isCameraEnabled',
|
||||
'isScreenEnabled',
|
||||
'remoteParticipant',
|
||||
'remoteMediaStream',
|
||||
'hasRemoteVideo'
|
||||
])
|
||||
},
|
||||
watch: {
|
||||
localMediaStream (stream) {
|
||||
this.assignLocalMediaStream(stream)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.assignLocalMediaStream(this.localMediaStream)
|
||||
},
|
||||
methods: {
|
||||
assignLocalMediaStream (stream) {
|
||||
if (this.$refs.localParticipant) {
|
||||
this.$refs.localParticipant.assignStream(stream)
|
||||
}
|
||||
},
|
||||
setSelectedParticipant (participant) {
|
||||
this.$store.commit('conference/setSelectedParticipant', participant)
|
||||
this.$store.commit('conference/setManualSelection', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
#csc-conf-participants-cont
|
||||
padding 0px 20px 10px 20px
|
||||
display list-item
|
||||
height calc(100vh - 150px)
|
||||
overflow hidden
|
||||
@media (max-width: $breakpoint-sm)
|
||||
font-size 73px
|
||||
left -18px
|
||||
top -2px
|
||||
</style>
|
@ -1,172 +0,0 @@
|
||||
<template>
|
||||
<q-card
|
||||
class="bg-transparent"
|
||||
flat
|
||||
>
|
||||
<q-card-section
|
||||
class="relative-position bg-black text-center full-width no-padding"
|
||||
style="height: 100px"
|
||||
>
|
||||
<q-icon
|
||||
v-ripple
|
||||
name="more_vert"
|
||||
class="absolute-left"
|
||||
style="z-index: 1; padding-top: 3px;"
|
||||
>
|
||||
<csc-popup-menu>
|
||||
<csc-popup-menu-item
|
||||
color="primary"
|
||||
dense
|
||||
:label="audioLabel()"
|
||||
@click="toggleAudio()"
|
||||
/>
|
||||
</csc-popup-menu>
|
||||
</q-icon>
|
||||
<q-icon
|
||||
v-show="isAudioMuted"
|
||||
v-ripple
|
||||
name="volume_off"
|
||||
class="absolute-right"
|
||||
:style="audioIconStyle"
|
||||
/>
|
||||
<q-icon
|
||||
v-show="!isAudioMuted"
|
||||
v-ripple
|
||||
name="volume_up"
|
||||
class="absolute-right"
|
||||
:style="audioIconStyle"
|
||||
/>
|
||||
<q-avatar
|
||||
v-show="!hasRemoteVideo"
|
||||
class="absolute-center"
|
||||
style="top: 40px"
|
||||
>
|
||||
<q-icon
|
||||
name="person"
|
||||
size="32px"
|
||||
/>
|
||||
</q-avatar>
|
||||
<csc-media
|
||||
v-show="hasRemoteVideo"
|
||||
ref="cscMedia"
|
||||
class="csc-media-cont"
|
||||
:preview="false"
|
||||
:muted="true"
|
||||
/>
|
||||
</q-card-section>
|
||||
<div
|
||||
class="absolute-bottom text-center bg-main-menu q-pa-xs"
|
||||
>
|
||||
{{ remoteParticipant.displayName }}
|
||||
</div>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import CscMedia from '../../CscMedia'
|
||||
import CscPopupMenu from 'components/CscPopupMenu'
|
||||
import CscPopupMenuItem from 'components/CscPopupMenuItem'
|
||||
import {
|
||||
TouchHold
|
||||
} from 'quasar'
|
||||
import {
|
||||
mapGetters,
|
||||
mapState
|
||||
} from 'vuex'
|
||||
export default {
|
||||
name: 'CscConferenceRemoteParticipant',
|
||||
directives: {
|
||||
TouchHold
|
||||
},
|
||||
components: {
|
||||
CscMedia,
|
||||
CscPopupMenu,
|
||||
CscPopupMenuItem
|
||||
},
|
||||
props: {
|
||||
remoteParticipant: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
displayName: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
remoteMediaStream: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
remoteMediaStreams: {
|
||||
type: Object,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
hasRemoteVideo: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
isAudioMuted: false,
|
||||
localMediaStream: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState('conference', [
|
||||
'manualSelection'
|
||||
]),
|
||||
...mapGetters('conference', [
|
||||
'selectedParticipant',
|
||||
'mutedState'
|
||||
]),
|
||||
audioIconStyle () {
|
||||
return 'z-index: 1; padding-top: 3px; padding-right: 3px;'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
remoteMediaStreams () {
|
||||
this.assignStream()
|
||||
},
|
||||
mutedState () {
|
||||
this.isAudioMuted = _.has(this.mutedState, this.remoteParticipant.id)
|
||||
this.$refs.cscMedia.toggleAudio(this.isAudioMuted)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.assignStream()
|
||||
if (!this.manualSelection && this.remoteParticipant) {
|
||||
this.$store.commit('conference/setSelectedParticipant', this.remoteParticipant.id)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
assignStream () {
|
||||
if (this.$refs.cscMedia && _.has(this.remoteMediaStreams, this.remoteParticipant.id)) {
|
||||
this.localMediaStream = this.remoteMediaStream(this.remoteParticipant.id)
|
||||
this.$refs.cscMedia.assignStream(this.localMediaStream)
|
||||
if (this.selectedParticipant === this.remoteParticipant.id) {
|
||||
this.$store.commit('conference/setSelectedParticipant', 'local') // TODO improve (workaround to reset the mediaStream)
|
||||
this.$store.commit('conference/setSelectedParticipant', this.remoteParticipant.id)
|
||||
}
|
||||
} else if (this.$refs.cscMedia) {
|
||||
this.$refs.cscMedia.reset()
|
||||
}
|
||||
},
|
||||
toggleAudio () {
|
||||
this.isAudioMuted
|
||||
? this.$store.commit('conference/removeMutedState', this.remoteParticipant.id)
|
||||
: this.$store.commit('conference/addMutedState', this.remoteParticipant.id)
|
||||
},
|
||||
audioLabel () {
|
||||
return this.isAudioMuted
|
||||
? this.$t('Unmute')
|
||||
: this.$t('Mute')
|
||||
},
|
||||
showMenu () {
|
||||
this.$refs.popover.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<csc-dialog
|
||||
ref="dialogComp"
|
||||
:title="$t('Share conference')"
|
||||
:title-icon="'link'"
|
||||
>
|
||||
<div
|
||||
slot="content"
|
||||
>
|
||||
<q-input
|
||||
ref="conferenceUrlInput"
|
||||
:value="conferenceUrl"
|
||||
readonly
|
||||
@focus="selectConferenceUrl"
|
||||
/>
|
||||
</div>
|
||||
<q-btn
|
||||
slot="actions"
|
||||
color="primary"
|
||||
flat
|
||||
icon="link"
|
||||
@click="copy"
|
||||
>
|
||||
{{ $t('Copy link') }}
|
||||
</q-btn>
|
||||
</csc-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CscDialog from '../../CscDialog'
|
||||
export default {
|
||||
name: 'CscShareConferenceDialog',
|
||||
components: {
|
||||
CscDialog
|
||||
},
|
||||
props: {
|
||||
conferenceUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted () {
|
||||
this.selectConferenceUrl()
|
||||
},
|
||||
methods: {
|
||||
open () {
|
||||
this.$refs.dialogComp.open()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.conferenceUrlInput.focus()
|
||||
})
|
||||
},
|
||||
close () {
|
||||
this.$refs.dialogComp.close()
|
||||
},
|
||||
copy () {
|
||||
this.$refs.conferenceUrlInput.select()
|
||||
document.execCommand('copy')
|
||||
this.close()
|
||||
},
|
||||
selectConferenceUrl () {
|
||||
if (this.$refs.conferenceUrlInput) {
|
||||
this.$refs.conferenceUrlInput.select()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
</style>
|
@ -1,417 +0,0 @@
|
||||
<template>
|
||||
<q-layout
|
||||
id="csc-layout-conference"
|
||||
view="lHh lpR lFf"
|
||||
>
|
||||
<q-header
|
||||
id="csc-header-conference"
|
||||
class="bg-transparent"
|
||||
>
|
||||
<q-toolbar
|
||||
id="csc-header-toolbar-conference"
|
||||
class="bg-transparent"
|
||||
>
|
||||
<div
|
||||
v-if="isJoined"
|
||||
class="q-mr-md text-h6"
|
||||
>
|
||||
<q-icon
|
||||
name="meeting_room"
|
||||
size="24px"
|
||||
/>
|
||||
{{ conferenceId }}
|
||||
</div>
|
||||
<q-space />
|
||||
<div
|
||||
v-if="isJoined"
|
||||
class="q-mr-md text-h6"
|
||||
>
|
||||
<q-icon
|
||||
name="person"
|
||||
size="24px"
|
||||
/>
|
||||
{{ selectedParticipantName }}
|
||||
</div>
|
||||
<q-space />
|
||||
<q-btn
|
||||
color="tertiary"
|
||||
icon="clear"
|
||||
unelevated
|
||||
dense
|
||||
@click="close()"
|
||||
/>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
<q-page-container
|
||||
id="csc-page-conference"
|
||||
>
|
||||
<q-page
|
||||
class="full-width row wrap justify-center items-start content-center"
|
||||
>
|
||||
<csc-conference-join
|
||||
v-if="!isJoined"
|
||||
class="bg-main-menu q-pa-lg"
|
||||
style="z-index: 11"
|
||||
:conference-id="conferenceId"
|
||||
:has-conference-id="hasConferenceId"
|
||||
:conference-url="conferenceUrl"
|
||||
:local-media-stream="localMediaStream"
|
||||
:is-microphone-enabled="isMicrophoneEnabled"
|
||||
:is-camera-enabled="isCameraEnabled"
|
||||
:is-screen-enabled="isScreenEnabled"
|
||||
:is-media-enabled="isMediaEnabled"
|
||||
:is-joining="isJoining"
|
||||
:is-joined="isJoined"
|
||||
:has-rtc-engine-capability-enabled="hasRtcEngineCapabilityEnabled"
|
||||
@join="join"
|
||||
/>
|
||||
<csc-conference-joined
|
||||
v-if="!isJoining && isJoined"
|
||||
style="z-index: 10"
|
||||
/>
|
||||
<div
|
||||
class="absolute-full"
|
||||
>
|
||||
<csc-media
|
||||
v-show="showMainMedia"
|
||||
ref="localMedia"
|
||||
:muted="true"
|
||||
:stream="localMediaStream"
|
||||
:preview="false"
|
||||
/>
|
||||
</div>
|
||||
<csc-confirm-dialog
|
||||
ref="confirmDialog"
|
||||
title-icon="exit_to_app"
|
||||
:title="$t('Leave conference')"
|
||||
:message="$t('Leave current conference now!')"
|
||||
@confirm="leave"
|
||||
/>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
<q-drawer
|
||||
id="csc-conference-participants"
|
||||
side="right"
|
||||
:value="isJoined"
|
||||
:width="150"
|
||||
:mini-width="50"
|
||||
>
|
||||
<csc-conference-participants
|
||||
ref="confParticipants"
|
||||
class="no-margin q-mb-lg"
|
||||
/>
|
||||
</q-drawer>
|
||||
<q-footer
|
||||
id="csc-footer-conference"
|
||||
class="bg-footer"
|
||||
>
|
||||
<q-toolbar>
|
||||
<q-space />
|
||||
<q-btn
|
||||
:color="microphoneButtonColor"
|
||||
class="text-dark q-mr-md"
|
||||
style="margin-top: -60px"
|
||||
icon="mic"
|
||||
round
|
||||
size="large"
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
@click="toggleMicrophone()"
|
||||
/>
|
||||
<q-btn
|
||||
:color="cameraButtonColor"
|
||||
class="text-dark q-mr-md"
|
||||
style="margin-top: -60px"
|
||||
icon="videocam"
|
||||
round
|
||||
size="large"
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
@click="toggleCamera()"
|
||||
/>
|
||||
<q-btn
|
||||
:color="screenButtonColor"
|
||||
class="text-dark q-mr-md"
|
||||
style="margin-top: -60px"
|
||||
icon="screen_share"
|
||||
round
|
||||
size="large"
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
@click="toggleScreen()"
|
||||
/>
|
||||
<q-btn
|
||||
v-if="isJoined"
|
||||
:color="screenButtonColor"
|
||||
style="margin-top: -60px"
|
||||
icon="more_vert"
|
||||
round
|
||||
size="large"
|
||||
:disable="!hasConferenceId || isJoining || !hasRtcEngineCapabilityEnabled"
|
||||
>
|
||||
<q-menu
|
||||
ref="popover"
|
||||
:auto-close="true"
|
||||
:disable="conferenceHasParticipants"
|
||||
>
|
||||
<q-list
|
||||
link
|
||||
class="no-border"
|
||||
>
|
||||
<q-item
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<q-item-section
|
||||
@click="toggleMuteAll()"
|
||||
>
|
||||
<q-item-label>{{ muteLabel }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
<q-space />
|
||||
</q-toolbar>
|
||||
</q-footer>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import {
|
||||
mapGetters,
|
||||
mapState,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import CscConferenceJoin from 'components/pages/Conference/CscConferenceJoin'
|
||||
import CscConferenceJoined from 'components/pages/Conference/CscConferenceJoined'
|
||||
import CscMedia from 'components/CscMedia'
|
||||
import CscConfirmDialog from 'components/CscConfirmationDialog'
|
||||
import CscConferenceParticipants from 'components/pages/Conference/CscConferenceParticipants'
|
||||
|
||||
export default {
|
||||
name: 'CscConferenceLayout',
|
||||
components: {
|
||||
CscConferenceParticipants,
|
||||
CscConfirmDialog,
|
||||
CscMedia,
|
||||
CscConferenceJoin,
|
||||
CscConferenceJoined
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
selectedMediaStream: null,
|
||||
selectedParticipantName: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('call', [
|
||||
'hasRtcEngineCapabilityEnabled'
|
||||
]),
|
||||
...mapState('conference', [
|
||||
'selectedParticipant'
|
||||
]),
|
||||
...mapGetters('conference', [
|
||||
'conferenceId',
|
||||
'conferenceUrl',
|
||||
'hasConferenceId',
|
||||
'isConferencingEnabled',
|
||||
'isJoined',
|
||||
'isJoining',
|
||||
'isMicrophoneEnabled',
|
||||
'isCameraEnabled',
|
||||
'isScreenEnabled',
|
||||
'isMediaEnabled',
|
||||
'localParticipant',
|
||||
'localMediaStream',
|
||||
'participantsList',
|
||||
'remoteParticipant',
|
||||
'remoteMediaStream',
|
||||
'remoteMediaStreams',
|
||||
'hasRemoteVideo',
|
||||
'mutedState'
|
||||
]),
|
||||
...mapGetters('user', [
|
||||
'getUsername'
|
||||
]),
|
||||
microphoneButtonColor () {
|
||||
if (this.isMicrophoneEnabled) {
|
||||
return 'primary'
|
||||
} else {
|
||||
return 'grey'
|
||||
}
|
||||
},
|
||||
cameraButtonColor () {
|
||||
if (this.isCameraEnabled) {
|
||||
return 'primary'
|
||||
} else {
|
||||
return 'grey'
|
||||
}
|
||||
},
|
||||
screenButtonColor () {
|
||||
if (this.isScreenEnabled) {
|
||||
return 'primary'
|
||||
} else {
|
||||
return 'grey'
|
||||
}
|
||||
},
|
||||
selectedHasVideo () {
|
||||
if (this.selectedParticipant === 'local') {
|
||||
return this.isVideoEnabled
|
||||
} else {
|
||||
return this.hasRemoteVideo(this.selectedParticipant)
|
||||
}
|
||||
},
|
||||
showMainMedia () {
|
||||
return (!this.isJoined && this.isVideoEnabled) || this.selectedHasVideo
|
||||
},
|
||||
isVideoEnabled () {
|
||||
return this.isMediaEnabled && (this.isCameraEnabled || this.isScreenEnabled)
|
||||
},
|
||||
conferenceHasParticipants () {
|
||||
return Object.keys(this.participantsList).length < 1
|
||||
},
|
||||
muteLabel () {
|
||||
return _.isEmpty(this.mutedState)
|
||||
? this.$t('Mute all')
|
||||
: this.$t('Unmute all')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
hasConferenceId (value) {
|
||||
if (!value) {
|
||||
this.$store.commit('conference/disposeLocalMedia')
|
||||
}
|
||||
},
|
||||
selectedParticipant: {
|
||||
handler: function (participant) {
|
||||
if (participant) {
|
||||
this.showSelectedParticipant(participant)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
localMediaStream (stream) {
|
||||
if (this.$refs.localMedia && (stream === null || stream === undefined)) {
|
||||
this.$refs.localMedia.reset()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('conference', [
|
||||
'leave'
|
||||
]),
|
||||
close () {
|
||||
if (!this.isJoined) {
|
||||
this.$router.push({ path: '/user/dashboard' })
|
||||
this.$store.commit('conference/disposeLocalMedia')
|
||||
} else {
|
||||
this.$refs.confirmDialog.open()
|
||||
}
|
||||
},
|
||||
toggleMicrophone () {
|
||||
if (this.hasConferenceId) {
|
||||
this.$store.dispatch('conference/toggleMicrophone')
|
||||
}
|
||||
},
|
||||
toggleCamera () {
|
||||
if (this.hasConferenceId) {
|
||||
this.$store.dispatch('conference/toggleCamera')
|
||||
}
|
||||
},
|
||||
toggleScreen () {
|
||||
if (this.hasConferenceId) {
|
||||
this.$store.dispatch('conference/toggleScreen')
|
||||
}
|
||||
},
|
||||
toggleMuteAll () {
|
||||
if (_.isEmpty(this.mutedState)) {
|
||||
this.$store.dispatch('conference/muteAll')
|
||||
} else {
|
||||
this.$store.dispatch('conference/unMuteAll')
|
||||
}
|
||||
},
|
||||
async join (conferenceId) {
|
||||
if (this.hasConferenceId) {
|
||||
await this.$store.dispatch('conference/join', conferenceId)
|
||||
}
|
||||
},
|
||||
showSelectedParticipant (participant) {
|
||||
if (this.$refs.localMedia) {
|
||||
switch (participant) {
|
||||
case 'local':
|
||||
if (this.localParticipant) {
|
||||
this.selectedParticipantName = this.localParticipant.displayName
|
||||
this.selectedMediaStream = this.localMediaStream
|
||||
this.$refs.localMedia.assignStream(this.selectedMediaStream)
|
||||
}
|
||||
break
|
||||
default:
|
||||
this.selectedMediaStream = this.remoteMediaStream(participant)
|
||||
this.$refs.localMedia.assignStream(this.selectedMediaStream)
|
||||
this.selectedParticipantName = this.remoteParticipant(participant) ? this.remoteParticipant(participant).displayName : ''
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" rel="stylesheet/stylus">
|
||||
#csc-conf-selected-participant-name
|
||||
position absolute
|
||||
top 20px
|
||||
bottom 0
|
||||
right 0
|
||||
left 0
|
||||
z-index 2
|
||||
background-color $conf-participant-box-color
|
||||
color $primary
|
||||
font-size 20px
|
||||
width 130px
|
||||
height 45px
|
||||
padding 10px
|
||||
@media (max-width: $breakpoint-sm)
|
||||
font-size 16px
|
||||
width 100px
|
||||
height 36px
|
||||
padding 8px
|
||||
#csc-conf-main-media
|
||||
position absolute
|
||||
top 0
|
||||
bottom 0
|
||||
right 0
|
||||
left 0
|
||||
z-index 1
|
||||
background-color black
|
||||
font-size 0
|
||||
|
||||
#csc-conf-header
|
||||
z-index 2
|
||||
top 0
|
||||
left 0
|
||||
right 0
|
||||
position fixed
|
||||
background-color transparent
|
||||
height $call-footer-height
|
||||
.csc-conf-button.q-btn
|
||||
.q-btn-inner
|
||||
color white
|
||||
#csc-conf-body
|
||||
position relative
|
||||
z-index 2
|
||||
top $call-footer-height
|
||||
#csc-conf-footer
|
||||
z-index 2
|
||||
bottom 0
|
||||
left 0
|
||||
right 0
|
||||
position fixed
|
||||
background-color $layout-aside-background
|
||||
height $call-footer-height
|
||||
|
||||
#csc-conf-actions
|
||||
margin: -28px
|
||||
.q-btn:last-child
|
||||
margin-right 0
|
||||
.q-btn
|
||||
margin-right $flex-gutter-sm
|
||||
</style>
|
@ -1,54 +0,0 @@
|
||||
import loadScript from 'load-script'
|
||||
|
||||
const RTC_ENGINE_LIBRARY_ID = 'ngcp-rtc-engine-library'
|
||||
|
||||
export const LocalMedia = {
|
||||
audioOnly: 'audioOnly',
|
||||
audioVideo: 'audioVideo',
|
||||
videoOnly: 'videoOnly',
|
||||
audioScreen: 'audioScreen',
|
||||
screenOnly: 'screenOnly'
|
||||
}
|
||||
|
||||
export function loadRtcEngineLibrary ({ scriptUrl }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.getElementById(RTC_ENGINE_LIBRARY_ID)
|
||||
if (!script) {
|
||||
loadScript(scriptUrl, {
|
||||
attrs: {
|
||||
id: RTC_ENGINE_LIBRARY_ID
|
||||
}
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
reject(new Error('Unable to load RTC:Engine client library'))
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function unloadRtcEngineLibrary () {
|
||||
const script = document.getElementById(RTC_ENGINE_LIBRARY_ID)
|
||||
if (script) {
|
||||
script.remove()
|
||||
}
|
||||
}
|
||||
|
||||
export async function rtcEngineCreateMedia (localMedia) {
|
||||
// eslint-disable-next-line no-undef
|
||||
const localMediaBuilder = cdk.media.create()
|
||||
if (localMedia === LocalMedia.audioOnly || localMedia === LocalMedia.audioVideo ||
|
||||
localMedia === LocalMedia.audioScreen) {
|
||||
localMediaBuilder.enableMicrophone()
|
||||
}
|
||||
if (localMedia === LocalMedia.audioVideo || localMedia === LocalMedia.videoOnly) {
|
||||
localMediaBuilder.enableCamera()
|
||||
} else if (localMedia === LocalMedia.audioScreen || localMedia === LocalMedia.screenOnly) {
|
||||
localMediaBuilder.enableScreen()
|
||||
}
|
||||
return await localMediaBuilder.build()
|
||||
}
|
@ -1,432 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import {
|
||||
RequestState
|
||||
} from './common'
|
||||
|
||||
const MediaTypes = {
|
||||
mic: 'mic',
|
||||
micCam: 'micCam',
|
||||
cam: 'cam',
|
||||
micScreen: 'micScreen',
|
||||
screen: 'screen'
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
conferencingEnabled: false,
|
||||
microphoneEnabled: false,
|
||||
cameraEnabled: false,
|
||||
screenEnabled: false,
|
||||
localMediaState: RequestState.initiated,
|
||||
localMediaError: null,
|
||||
joinState: RequestState.initiated,
|
||||
joinError: null,
|
||||
leaveState: RequestState.initiated,
|
||||
leaveError: null,
|
||||
participants: [],
|
||||
mutedState: {},
|
||||
remoteMediaStreams: {},
|
||||
selectedParticipant: null,
|
||||
manualSelection: false
|
||||
},
|
||||
getters: {
|
||||
username (state, getters, rootState, rootGetters) {
|
||||
return rootGetters['user/getUsername']
|
||||
},
|
||||
conferenceId (state, getters, rootState, rootGetters) {
|
||||
return rootGetters.conferenceId
|
||||
},
|
||||
conferenceUrl (state, getters, rootState, rootGetters) {
|
||||
return rootGetters.conferenceUrl
|
||||
},
|
||||
hasConferenceId (state, getters, rootState, rootGetters) {
|
||||
return rootGetters.hasConferenceId
|
||||
},
|
||||
isJoined (state) {
|
||||
return state.joinState === RequestState.succeeded
|
||||
},
|
||||
isJoining (state) {
|
||||
return state.joinState === RequestState.requesting
|
||||
},
|
||||
isLeft (state) {
|
||||
return state.leaveState === RequestState.succeeded
|
||||
},
|
||||
isLeaving (state) {
|
||||
return state.leaveState === RequestState.requesting
|
||||
},
|
||||
isConferencingEnabled (state) {
|
||||
return state.conferencingEnabled
|
||||
},
|
||||
isMicrophoneEnabled (state) {
|
||||
return state.microphoneEnabled
|
||||
},
|
||||
isCameraEnabled (state) {
|
||||
return state.cameraEnabled
|
||||
},
|
||||
isScreenEnabled (state) {
|
||||
return state.screenEnabled
|
||||
},
|
||||
isMediaEnabled (state) {
|
||||
return (state.localMediaState === RequestState.succeeded ||
|
||||
state.localMediaState === RequestState.requesting) && Vue.$conference.hasLocalMediaStream()
|
||||
},
|
||||
localMediaStream (state) {
|
||||
if ((state.localMediaState === RequestState.succeeded ||
|
||||
state.localMediaState === RequestState.requesting) && Vue.$conference.hasLocalMediaStream()) {
|
||||
return Vue.$conference.getLocalMediaStreamNative()
|
||||
}
|
||||
return null
|
||||
},
|
||||
hasLocalMediaStream (state) {
|
||||
return (state.localMediaState === RequestState.succeeded ||
|
||||
state.localMediaState === RequestState.requesting) && Vue.$conference.hasLocalMediaStream()
|
||||
},
|
||||
localParticipant (state) {
|
||||
if (state.joinState === RequestState.succeeded) {
|
||||
return Vue.$conference.getLocalParticipant()
|
||||
}
|
||||
},
|
||||
remoteParticipant: () => (participantId) => {
|
||||
return Vue.$conference.getRemoteParticipant(participantId)
|
||||
},
|
||||
remoteMediaStream: () => (participantId) => {
|
||||
const participant = Vue.$conference.getRemoteParticipant(participantId)
|
||||
if (participant) {
|
||||
return participant.mediaStream ? participant.mediaStream.getStream() : null
|
||||
}
|
||||
return null
|
||||
},
|
||||
participantsList (state) {
|
||||
return state.participants
|
||||
},
|
||||
mutedState (state) {
|
||||
return state.mutedState
|
||||
},
|
||||
remoteMediaStreams (state) {
|
||||
return state.remoteMediaStreams
|
||||
},
|
||||
hasRemoteVideo: () => (participantId) => {
|
||||
const participant = Vue.$conference.getRemoteParticipant(participantId)
|
||||
if (participant) {
|
||||
return participant.mediaStream ? participant.mediaStream.hasVideo() : false
|
||||
}
|
||||
return false
|
||||
},
|
||||
selectedParticipant (state) {
|
||||
return state.selectedParticipant
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
enableConferencing (state) {
|
||||
state.conferencingEnabled = true
|
||||
},
|
||||
disableConferencing (state) {
|
||||
state.conferencingEnabled = false
|
||||
},
|
||||
enableMicrophone (state) {
|
||||
state.microphoneEnabled = true
|
||||
},
|
||||
disableMicrophone (state) {
|
||||
state.microphoneEnabled = false
|
||||
},
|
||||
enableCamera (state) {
|
||||
state.cameraEnabled = true
|
||||
},
|
||||
disableCamera (state) {
|
||||
state.cameraEnabled = false
|
||||
},
|
||||
enableScreen (state) {
|
||||
state.screenEnabled = true
|
||||
},
|
||||
disableScreen (state) {
|
||||
state.screenEnabled = false
|
||||
},
|
||||
localMediaRequesting (state) {
|
||||
state.localMediaState = RequestState.requesting
|
||||
state.localMediaError = null
|
||||
},
|
||||
localMediaSucceeded (state) {
|
||||
state.localMediaState = RequestState.succeeded
|
||||
state.localMediaError = null
|
||||
},
|
||||
localMediaFailed (state, error) {
|
||||
state.localMediaState = RequestState.failed
|
||||
state.localMediaError = error
|
||||
},
|
||||
isLocalMediaRequesting (state) {
|
||||
return state.localMediaState === RequestState.requesting
|
||||
},
|
||||
disposeLocalMedia (state) {
|
||||
Vue.$conference.removeLocalMediaStream()
|
||||
state.cameraEnabled = false
|
||||
state.microphoneEnabled = false
|
||||
state.screenEnabled = false
|
||||
},
|
||||
addRemoteMedia (state, participantId) {
|
||||
Vue.set(state.remoteMediaStreams, participantId, participantId)
|
||||
},
|
||||
removeRemoteMedia (state, participantId) {
|
||||
Vue.delete(state.remoteMediaStreams, participantId)
|
||||
},
|
||||
joinRequesting (state) {
|
||||
state.joinState = RequestState.requesting
|
||||
state.joinError = null
|
||||
},
|
||||
joinSucceeded (state) {
|
||||
state.joinState = RequestState.succeeded
|
||||
state.joinError = null
|
||||
state.leaveState = null
|
||||
state.selectedParticipant = 'local'
|
||||
},
|
||||
joinFailed (state, error) {
|
||||
state.joinState = RequestState.failed
|
||||
state.joinError = error
|
||||
},
|
||||
leaveRequesting (state) {
|
||||
state.leaveState = RequestState.requesting
|
||||
state.leaveError = null
|
||||
state.joinState = null
|
||||
},
|
||||
leaveSucceeded (state) {
|
||||
state.leaveState = RequestState.succeeded
|
||||
state.leaveError = null
|
||||
state.joinState = RequestState.initiated
|
||||
state.joinError = null
|
||||
state.selectedParticipant = null
|
||||
state.remoteMediaStreams = {}
|
||||
state.manualSelection = false
|
||||
state.participants = []
|
||||
state.mutedState = {}
|
||||
},
|
||||
leaveFailed (state, error) {
|
||||
state.leaveState = RequestState.failed
|
||||
state.leaveError = error
|
||||
},
|
||||
participantJoined (state, participant) {
|
||||
if (state.participants.includes(participant.getId())) {
|
||||
state.participants = state.participants.filter(($participant) => {
|
||||
return participant.getId() !== $participant
|
||||
})
|
||||
}
|
||||
state.participants.push(participant.getId())
|
||||
},
|
||||
participantLeft (state, participant) {
|
||||
state.participants = state.participants.filter(($participant) => {
|
||||
return participant.getId() !== $participant
|
||||
})
|
||||
},
|
||||
setSelectedParticipant (state, participant) {
|
||||
if (state.selectedParticipant === 'local' && !state.joinState === RequestState.succeeded) {
|
||||
state.selectedParticipant = null
|
||||
} else if (state.selectedParticipant === participant && !state.participants.includes(participant)) {
|
||||
state.selectedParticipant = 'local'
|
||||
state.manualSelection = false
|
||||
} else {
|
||||
state.selectedParticipant = participant
|
||||
}
|
||||
},
|
||||
setManualSelection (state, val) {
|
||||
state.manualSelection = val
|
||||
},
|
||||
addMutedState (state, participantId) {
|
||||
Vue.set(state.mutedState, participantId, participantId)
|
||||
},
|
||||
removeMutedState (state, participantId) {
|
||||
Vue.delete(state.mutedState, participantId)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
createLocalMedia (context, type) {
|
||||
const media = Vue.$rtcEngine.createMedia()
|
||||
context.commit('localMediaRequesting')
|
||||
switch (type) {
|
||||
default:
|
||||
case MediaTypes.mic:
|
||||
media.enableMicrophone()
|
||||
break
|
||||
case MediaTypes.micCam:
|
||||
media.enableMicrophone()
|
||||
media.enableCamera()
|
||||
break
|
||||
case MediaTypes.micScreen:
|
||||
media.enableMicrophone()
|
||||
media.enableScreen()
|
||||
break
|
||||
case MediaTypes.cam:
|
||||
media.enableCamera()
|
||||
break
|
||||
case MediaTypes.screen:
|
||||
media.enableScreen()
|
||||
break
|
||||
}
|
||||
let localMediaStream
|
||||
return media.build().then(($localMediaStream) => {
|
||||
localMediaStream = $localMediaStream
|
||||
Vue.$conference.setLocalMediaStream(localMediaStream)
|
||||
switch (type) {
|
||||
default:
|
||||
case MediaTypes.mic:
|
||||
context.commit('enableMicrophone')
|
||||
context.commit('disableCamera')
|
||||
context.commit('disableScreen')
|
||||
break
|
||||
case MediaTypes.micCam:
|
||||
context.commit('enableMicrophone')
|
||||
context.commit('enableCamera')
|
||||
context.commit('disableScreen')
|
||||
break
|
||||
case MediaTypes.micScreen:
|
||||
context.commit('enableMicrophone')
|
||||
context.commit('disableCamera')
|
||||
context.commit('enableScreen')
|
||||
break
|
||||
case MediaTypes.cam:
|
||||
context.commit('disableMicrophone')
|
||||
context.commit('enableCamera')
|
||||
context.commit('disableScreen')
|
||||
break
|
||||
case MediaTypes.screen:
|
||||
context.commit('disableMicrophone')
|
||||
context.commit('disableCamera')
|
||||
context.commit('enableScreen')
|
||||
break
|
||||
}
|
||||
return Promise.resolve()
|
||||
}).then(() => {
|
||||
if (context.getters.isJoined) {
|
||||
return Vue.$conference.changeConferenceMedia()
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
}).then(() => {
|
||||
context.commit('localMediaSucceeded', localMediaStream)
|
||||
}).catch((err) => {
|
||||
if (!context.getters.hasLocalMediaStream) {
|
||||
context.commit('localMediaFailed', err.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
async enableMicrophone (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
let mediaType = MediaTypes.mic
|
||||
if (context.getters.isCameraEnabled) {
|
||||
mediaType = MediaTypes.micCam
|
||||
} else if (context.getters.isScreenEnabled) {
|
||||
mediaType = MediaTypes.micScreen
|
||||
}
|
||||
await context.dispatch('createLocalMedia', mediaType)
|
||||
}
|
||||
},
|
||||
disableMicrophone (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
let mediaType = null
|
||||
if (context.getters.isCameraEnabled) {
|
||||
mediaType = MediaTypes.cam
|
||||
} else if (context.getters.isScreenEnabled) {
|
||||
mediaType = MediaTypes.screen
|
||||
}
|
||||
if (mediaType === null) {
|
||||
context.commit('disposeLocalMedia')
|
||||
} else {
|
||||
context.dispatch('createLocalMedia', mediaType)
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleMicrophone (context) {
|
||||
if (!context.getters.isMicrophoneEnabled) {
|
||||
context.dispatch('enableMicrophone')
|
||||
} else {
|
||||
context.dispatch('disableMicrophone')
|
||||
}
|
||||
},
|
||||
enableCamera (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
context.dispatch('createLocalMedia', MediaTypes.micCam)
|
||||
}
|
||||
},
|
||||
disableCamera (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
let mediaType = null
|
||||
if (context.getters.isMicrophoneEnabled) {
|
||||
mediaType = MediaTypes.mic
|
||||
}
|
||||
if (mediaType === null) {
|
||||
context.commit('disposeLocalMedia')
|
||||
} else {
|
||||
context.dispatch('createLocalMedia', mediaType)
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleCamera (context) {
|
||||
if (!context.getters.isCameraEnabled) {
|
||||
context.dispatch('enableCamera')
|
||||
} else {
|
||||
context.dispatch('disableCamera')
|
||||
}
|
||||
},
|
||||
enableScreen (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
context.dispatch('createLocalMedia', MediaTypes.micScreen)
|
||||
}
|
||||
},
|
||||
disableScreen (context) {
|
||||
if (!context.getters.isLocalMediaRequesting) {
|
||||
let mediaType = null
|
||||
if (context.getters.isMicrophoneEnabled) {
|
||||
mediaType = MediaTypes.mic
|
||||
}
|
||||
if (mediaType === null) {
|
||||
context.commit('disposeLocalMedia')
|
||||
} else {
|
||||
context.dispatch('createLocalMedia', mediaType)
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleScreen (context) {
|
||||
if (!context.getters.isScreenEnabled) {
|
||||
context.dispatch('enableScreen')
|
||||
} else {
|
||||
context.dispatch('disableScreen')
|
||||
}
|
||||
},
|
||||
async join (context, conferenceId) {
|
||||
try {
|
||||
if (!Vue.$conference.hasLocalMediaStream()) {
|
||||
await context.dispatch('enableMicrophone')
|
||||
}
|
||||
context.commit('joinRequesting')
|
||||
await Vue.$conference.joinConference({
|
||||
conferenceName: conferenceId,
|
||||
displayName: context.getters.username
|
||||
})
|
||||
context.commit('joinSucceeded')
|
||||
} catch (err) {
|
||||
context.commit('joinFailed', err.message)
|
||||
}
|
||||
},
|
||||
async leave (context) {
|
||||
if (context.getters.isJoined) {
|
||||
try {
|
||||
context.commit('leaveRequesting')
|
||||
await Vue.$conference.leaveConference()
|
||||
context.commit('leaveSucceeded')
|
||||
} catch (err) {
|
||||
context.commit('leaveFailed', err.message)
|
||||
} finally {
|
||||
context.commit('disposeLocalMedia')
|
||||
}
|
||||
}
|
||||
},
|
||||
muteAll (context) {
|
||||
for (const participant of context.getters.participantsList) {
|
||||
context.commit('addMutedState', participant)
|
||||
}
|
||||
},
|
||||
unMuteAll (context) {
|
||||
for (const participant of context.getters.participantsList) {
|
||||
context.commit('removeMutedState', participant)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue