TT#175000 Remove RTCEngine related components

Change-Id: I1d8ae9dc2b241c392e450d02c3aa5eeab7eabd50
pull/13/head
Hans-Peter Herzog 3 years ago
parent 9da0c00285
commit 73ba4fa869

@ -56,9 +56,6 @@ export default {
return {}
},
computed: {
...mapGetters('user', [
'isRtcEngineUiVisible'
]),
items () {
return [
{

@ -47,7 +47,6 @@ export default {
},
computed: {
...mapGetters('user', [
'isRtcEngineUiVisible',
'isPbxEnabled',
'hasFaxCapability',
'hasSubscriberProfileAttribute',

@ -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>

@ -89,12 +89,10 @@
"Close": "Close",
"Close filters": "Close filters",
"Conference": "Conference",
"Conference name": "Conference name",
"Confirm": "Confirm",
"Contact": "Contact",
"Content": "Content",
"Conversations": "Conversations",
"Copy link": "Copy link",
"Cost": "Cost",
"Could not enable incoming call notifications.": "Could not enable incoming call notifications.",
"Could not find any device matching any of the filter criteria": "Could not find any device matching any of the filter criteria",
@ -217,15 +215,12 @@
"Input a valid phone number": "Input a valid phone number",
"Interval when the secret key is automatically renewed.": "Interval when the secret key is automatically renewed.",
"Italian": "Italian",
"Join conference with name": "Join conference with name",
"Lamp/Key": "Lamp/Key",
"Lamps/Keys": "Lamps/Keys",
"Language": "Language",
"Language changed successfully": "Language changed successfully",
"Language for voicemail and app server": "Language for voicemail and app server",
"Last Modify Time": "Last Modify Time",
"Leave conference": "Leave conference",
"Leave current conference now!": "Leave current conference now!",
"List of registered devices for the subscriber": "List of registered devices for the subscriber",
"Local Subscriber": "Local Subscriber",
"Login": "Login",
@ -245,8 +240,6 @@
"Monthly": "Monthly",
"Music on Hold": "Music on Hold",
"Music on hold": "Music on hold",
"Mute": "Mute",
"Mute all": "Mute all",
"MyNumberList": "MyNumberList",
"Name": "Name",
"Name in Fax Header for Sendfax": "Name in Fax Header for Sendfax",
@ -393,8 +386,6 @@
"Set your speed dials": "Set your speed dials",
"Set your voicebox settings": "Set your voicebox settings",
"Settings": "Settings",
"Share": "Share",
"Share conference": "Share conference",
"Shared": "Shared",
"Sign In": "Sign In",
"Slot": "Slot",
@ -444,8 +435,6 @@
"Undo": "Undo",
"Unknown error": "Unknown error",
"Unknown name": "Unknown name",
"Unmute": "Unmute",
"Unmute all": "Unmute all",
"Updated {field} for call queue {callQueue} successfully": "Updated {field} for call queue {callQueue} successfully",
"Updated {field} for device {device} successfully": "Updated {field} for device {device} successfully",
"Updated {field} for manager secretary config {msConfig} successfully": "Updated {field} for manager secretary config {msConfig} successfully",
@ -496,7 +485,6 @@
"You are about to remove this Voicemail": "You are about to remove this Voicemail",
"You are about to reset the custom {type} greeting sound to defaults": "You are about to reset the custom {type} greeting sound to defaults",
"You are now able to start and receive calls": "You are now able to start and receive calls",
"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.": "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.",
"You have blocked incoming call notifications.": "You have blocked incoming call notifications.",
"You have invalid form input. Please check and try again.": "You have invalid form input. Please check and try again.",
"Your SIP password has been changed successfully": "Your SIP password has been changed successfully",

@ -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>

@ -299,7 +299,6 @@ export default {
'hasSendFaxFeature',
'userDataRequesting',
'userDataSucceeded',
'isRtcEngineUiVisible',
'isLogoRequesting',
'isLogoRequested'
]),
@ -393,7 +392,7 @@ export default {
}
},
isCallEnabled (value) {
if (value && this.isRtcEngineUiVisible) {
if (value) {
showToast(this.$i18n.t('You are now able to start and receive calls'))
}
},

@ -1,6 +1,5 @@
import { PROFILE_ATTRIBUTE_MAP, PROFILE_ATTRIBUTES_MAP } from 'src/constants'
import CscLayoutConference from 'src/layouts/CscLayoutConference'
import CscLayoutMain from 'src/layouts/CscLayoutMain'
import CscLayoutLogin from 'src/layouts/CscLayoutLogin'
@ -63,13 +62,6 @@ export default function routes (app) {
get title () {
return i18n.t('Start new call')
}
},
beforeEnter (routeTo, routeFrom, next) {
if (app.store.getters['user/isRtcEngineUiVisible']) {
next()
} else {
next('/user/conversations')
}
}
},
{
@ -411,24 +403,6 @@ export default function routes (app) {
}
}
},
{
path: '/conference',
component: CscLayoutConference,
meta: {
get title () {
return i18n.t('Conference')
}
}
},
{
path: '/conference/:id',
component: CscLayoutConference,
meta: {
get title () {
return i18n.t('Conference')
}
}
},
{
path: '/recoverpassword',
component: CscLayoutLogin,

@ -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()
}

@ -56,12 +56,6 @@ export default {
isEnded (state) {
return state.callState === CallState.ended
},
hasRtcEngineCapability (state, getters, rootState, rootGetters) {
return rootGetters['user/hasRtcEngineCapability']
},
hasRtcEngineCapabilityEnabled (state, getters, rootState, rootGetters) {
return rootGetters['user/hasRtcEngineCapabilityEnabled']
},
hasRemoteVideo (state) {
if (state.remoteMediaStream !== null) {
return callHasRemoteVideo()

@ -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)
}
}
}
}

@ -25,7 +25,6 @@ import UserModule from './user'
import CommunicationModule from './communication'
import FaxModule from './fax'
import VoiceboxModule from './voicebox'
import ConferenceModule from './conference'
import DashboardModule from './dashboard'
import { INTERNAL_DATE_FORMAT_SLASH, INTERNAL_DATE_FORMAT_DASH, INTERNAL_DATE_FORMAT_DASH_HOUR } from 'src/constants'
@ -55,7 +54,6 @@ export default function (/* { ssrContext } */) {
communication: CommunicationModule,
fax: FaxModule,
voicebox: VoiceboxModule,
conference: ConferenceModule,
pbx: PbxModule,
pbxSeats: PbxSeatsModule,
pbxGroups: PbxGroupsModule,

@ -46,8 +46,6 @@ export default {
userDataRequesting: false,
userDataSucceeded: false,
userDataError: null,
rtcEngineInitState: RequestState.initiated,
rtcEngineInitError: null,
changePasswordState: RequestState.initiated,
changePasswordError: null,
newPasswordRequesting: false,
@ -105,15 +103,6 @@ export default {
state.capabilities.faxserver &&
state.capabilities.faxactive
},
hasRtcEngineCapability (state) {
return state.capabilities !== null && _.has(state.capabilities, 'rtcengine')
},
hasRtcEngineCapabilityEnabled (state, getters) {
return getters.hasRtcEngineCapability && state.capabilities.rtcengine === true
},
isRtcEngineUiVisible (state) {
return (state.capabilities !== null && state.capabilities.csc_show_rtcengine_features === true)
},
getSubscriberId (state) {
return state.subscriberId
},
@ -252,16 +241,6 @@ export default {
state.userDataSucceeded = false
state.userDataError = null
},
rtcEngineInitRequesting (state) {
state.rtcEngineInitState = RequestState.requesting
},
rtcEngineInitSucceeded (state) {
state.rtcEngineInitState = RequestState.succeeded
},
rtcEngineInitFailed (state, error) {
state.rtcEngineInitState = RequestState.failed
state.rtcEngineInitError = error
},
userPasswordRequesting (state) {
state.changePasswordState = RequestState.requesting
state.changePasswordError = null
@ -386,8 +365,9 @@ export default {
}
},
async forwardHome (context) {
if (context.rootState.route?.path === '/user/dashboard' && !context.getters.isRtcEngineUiVisible) {
await this.$router.push({ path: '/user/conversations' })
const start = '/user/dashboard'
if (context.rootState.route?.path !== start) {
await this.$router.push({ path: start })
}
},
async getCustomLogo (context) {

Loading…
Cancel
Save