Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117788258
D2329.1775254449.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
22 KB
Referenced Files
None
Subscribers
None
D2329.1775254449.diff
View Options
diff --git a/src/resources/js/meet/app.js b/src/resources/js/meet/app.js
--- a/src/resources/js/meet/app.js
+++ b/src/resources/js/meet/app.js
@@ -96,6 +96,7 @@
* channel - Selected interpreted language channel (two-letter language code)
* languages - Supported languages (code-to-label map)
* chatElement - DOM element for the chat widget,
+ * counterElement - DOM element for the participants counter,
* menuElement - DOM element of the room toolbar,
* queueElement - DOM element for the Q&A queue (users with a raised hand)
* onSuccess - Callback for session connection (join) success
@@ -1387,6 +1388,10 @@
let publishers = $(publishersContainer).find('.meet-video')
let numOfVideos = publishers.length
+ if (sessionData && sessionData.counterElement) {
+ sessionData.counterElement.innerHTML = Object.keys(connections).length + 1
+ }
+
if (!numOfVideos) {
return
}
diff --git a/src/resources/themes/meet.scss b/src/resources/themes/meet.scss
--- a/src/resources/themes/meet.scss
+++ b/src/resources/themes/meet.scss
@@ -176,6 +176,18 @@
flex: 1;
}
+#meet-counter {
+ position: absolute;
+ left: 0;
+ padding: 1.1em 0.6em;
+ color: #808c99;
+
+ svg {
+ font-size: 1.4em;
+ vertical-align: text-bottom;
+ }
+}
+
#meet-session-toolbar {
display: flex;
justify-content: center;
@@ -185,22 +197,38 @@
background: #f6f5f3;
border-radius: 0 2em 2em 0;
margin: 0.25em 0;
+ padding-right: 0.5em;
button {
font-size: 1.3em;
- padding: 0 0.25em;
- margin: 0.5em;
+ margin: 0.4em;
position: relative;
+ color: #4f5963;
+ width: 1.75em;
+ height: 1.75em;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+
+ &.on:not(:disabled) {
+ background: #4f5963;
+ color: white;
+ }
.badge {
font-size: 0.5em;
position: absolute;
right: -0.5em;
+ top: -0.5em;
&:empty {
display: none;
}
}
+
+ svg {
+ width: 1em;
+ }
}
}
@@ -214,7 +242,7 @@
img {
height: 1.25em;
- padding: 0 1.5em;
+ padding: 0 1em 0 1.5em;
}
}
@@ -279,6 +307,8 @@
width: 0;
display: none;
flex-direction: column;
+ background: $body-bg;
+ padding-top: 0.25em;
&.open {
width: 30%;
@@ -287,7 +317,6 @@
.mobile & {
width: 100%;
z-index: 1;
- background: $body-bg;
}
}
@@ -301,7 +330,7 @@
margin: 0 0.5em 0.5em 0.5em;
padding: 0.25em 0.5em;
border-radius: 1em;
- background: $menu-bg-color;
+ background: #fff;
overflow-wrap: break-word;
&.self {
@@ -449,3 +478,16 @@
}
}
}
+
+@include media-breakpoint-down(xs) {
+ #meet-setup {
+ .card-title {
+ text-align: center;
+ }
+ }
+
+ .media-setup-preview {
+ // Fix video element size in Safari/iOS
+ display: block;
+ }
+}
diff --git a/src/resources/vue/Meet/Room.vue b/src/resources/vue/Meet/Room.vue
--- a/src/resources/vue/Meet/Room.vue
+++ b/src/resources/vue/Meet/Room.vue
@@ -1,22 +1,25 @@
<template>
<div id="meet-component">
<div id="meet-session-toolbar" class="hidden">
+ <span id="meet-counter" title="Number of participants"><svg-icon icon="users"></svg-icon> <span></span></span>
<span id="meet-session-logo" v-html="$root.logo()"></span>
<div id="meet-session-menu">
- <button class="btn link-audio" :class="{ 'text-primary' : audioActive }" @click="switchSound" :disabled="!isPublisher()" :title="audioActive ? 'Mute audio' : 'Unmute audio'">
+ <button :class="'btn link-audio' + (audioActive ? '' : ' on')" @click="switchSound" :disabled="!isPublisher()" :title="audioActive ? 'Mute audio' : 'Unmute audio'">
<svg-icon :icon="audioActive ? 'microphone' : 'microphone-slash'"></svg-icon>
</button>
- <button class="btn link-video" :class="{ 'text-primary' : videoActive }" @click="switchVideo" :disabled="!isPublisher()" :title="videoActive ? 'Mute video' : 'Unmute video'">
+ <button :class="'btn link-video' + (videoActive ? '' : ' on')" @click="switchVideo" :disabled="!isPublisher()" :title="videoActive ? 'Mute video' : 'Unmute video'">
<svg-icon :icon="videoActive ? 'video' : 'video-slash'"></svg-icon>
</button>
- <button class="btn link-screen" :class="{ 'text-danger' : screenShareActive }" @click="switchScreen" :disabled="!canShareScreen || !isPublisher()" title="Share screen">
+ <button :class="'btn link-screen' + (screenShareActive ? ' on' : '')" @click="switchScreen" :disabled="!canShareScreen || !isPublisher()" title="Share screen">
<svg-icon icon="desktop"></svg-icon>
</button>
- <button class="btn link-hand" :class="{ 'text-primary' : handRaised }" v-if="!isPublisher()" @click="switchHand" :title="handRaised ? 'Lower hand' : 'Raise hand'">
+ <button :class="'btn link-hand' + (handRaised ? ' on' : '')" v-if="!isPublisher()" @click="switchHand" :title="handRaised ? 'Lower hand' : 'Raise hand'">
<svg-icon icon="hand-paper"></svg-icon>
</button>
<span id="channel-select" :style="'display:' + (channels.length ? '' : 'none')" class="dropdown">
- <button class="btn link-channel" title="Interpreted language channel" aria-haspopup="true" aria-expanded="false" data-toggle="dropdown">
+ <button :class="'btn link-channel' + (session.channel ? ' on' : '')" data-toggle="dropdown"
+ title="Interpreted language channel" aria-haspopup="true" aria-expanded="false"
+ >
<svg-icon icon="headphones"></svg-icon>
<span class="badge badge-danger" v-if="session.channel">{{ session.channel.toUpperCase() }}</span>
</button>
@@ -27,7 +30,7 @@
>{{ languages[code] }}</a>
</div>
</span>
- <button class="btn link-chat" @click="switchChat" title="Chat">
+ <button :class="'btn link-chat' + (chatActive ? ' on' : '')" @click="switchChat" title="Chat">
<svg-icon icon="comment"></svg-icon>
</button>
<button class="btn link-fullscreen closed hidden" @click="switchFullscreen" title="Full screen">
@@ -150,19 +153,19 @@
<form class="media-setup-form">
<div class="media-setup-preview"></div>
<div class="input-group mt-2">
- <label for="setup-microphone" class="input-group-prepend mb-0">
+ <label for="setup-mic" class="input-group-prepend mb-0">
<span class="input-group-text" title="Microphone"><svg-icon icon="microphone"></svg-icon></span>
</label>
- <select class="custom-select" id="setup-microphone" v-model="microphone" @change="setupMicrophoneChange">
+ <select class="custom-select" id="setup-mic" v-model="microphone" @change="setupMicrophoneChange">
<option value="">None</option>
<option v-for="mic in setup.microphones" :value="mic.deviceId" :key="mic.deviceId">{{ mic.label }}</option>
</select>
</div>
<div class="input-group mt-2">
- <label for="setup-camera" class="input-group-prepend mb-0">
+ <label for="setup-cam" class="input-group-prepend mb-0">
<span class="input-group-text" title="Camera"><svg-icon icon="video"></svg-icon></span>
</label>
- <select class="custom-select" id="setup-camera" v-model="camera" @change="setupCameraChange">
+ <select class="custom-select" id="setup-cam" v-model="camera" @change="setupCameraChange">
<option value="">None</option>
<option v-for="cam in setup.cameras" :value="cam.deviceId" :key="cam.deviceId">{{ cam.label }}</option>
</select>
@@ -203,6 +206,7 @@
faMicrophoneAlt,
faPowerOff,
faUser,
+ faUsers,
faVideo,
faVideoSlash,
faVolumeMute
@@ -223,6 +227,7 @@
faMicrophoneAlt,
faPowerOff,
faUser,
+ faUsers,
faVideo,
faVideoSlash,
faVolumeMute
@@ -272,6 +277,7 @@
session: {},
audioActive: false,
videoActive: false,
+ chatActive: false,
handRaised: false,
screenShareActive: false
}
@@ -503,6 +509,7 @@
this.session.menuElement = $('#meet-session-menu')[0]
this.session.chatElement = $('#meet-chat')[0]
this.session.queueElement = $('#meet-queue')[0]
+ this.session.counterElement = $('#meet-counter span')[0]
this.session.onSuccess = () => {
$('#app').addClass('meet')
$('#meet-setup').addClass('hidden')
@@ -663,13 +670,15 @@
switchChat() {
let chat = $('#meet-chat')
let enabled = chat.is('.open')
-
+
chat.toggleClass('open')
if (!enabled) {
chat.find('textarea').focus()
}
+ this.chatActive = !enabled
+
// Trigger resize, so participant matrix can update its layout
window.dispatchEvent(new Event('resize'));
},
@@ -694,12 +703,10 @@
this.updateSelf({ hand: !this.handRaised })
},
switchSound() {
- const enabled = this.meet.switchAudio()
- this.audioActive = enabled
+ this.audioActive = this.meet.switchAudio()
},
switchVideo() {
- const enabled = this.meet.switchVideo()
- this.videoActive = enabled
+ this.videoActive = this.meet.switchVideo()
},
switchScreen() {
const switchScreenAction = () => {
@@ -744,7 +751,6 @@
this.videoActive = isPublisher ? data.videoActive : false
this.audioActive = isPublisher ? data.audioActive : false
-
this.handRaised = data.hand
}
}
diff --git a/src/resources/vue/Meet/RoomOptions.vue b/src/resources/vue/Meet/RoomOptions.vue
--- a/src/resources/vue/Meet/RoomOptions.vue
+++ b/src/resources/vue/Meet/RoomOptions.vue
@@ -41,7 +41,7 @@
<hr>
<form id="room-options-nomedia">
<div id="room-nomedia">
- <label for="room-lock-input">Subscribers only:</label>
+ <label for="room-nomedia-input">Subscribers only:</label>
<input type="checkbox" id="room-nomedia-input" name="lock" value="1" :checked="config.nomedia" @click="nomediaSave">
</div>
<small class="form-text text-muted">
diff --git a/src/tests/Browser/Meet/RoomControlsTest.php b/src/tests/Browser/Meet/RoomControlsTest.php
--- a/src/tests/Browser/Meet/RoomControlsTest.php
+++ b/src/tests/Browser/Meet/RoomControlsTest.php
@@ -105,13 +105,13 @@
// Assert current UI state
$owner->assertToolbar([
- 'audio' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'video' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'audio' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
+ 'video' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'screen' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'chat' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
- 'fullscreen' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'options' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'logout' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'fullscreen' => RoomPage::BUTTON_ENABLED,
+ 'options' => RoomPage::BUTTON_ENABLED,
+ 'logout' => RoomPage::BUTTON_ENABLED,
])
->whenAvailable('div.meet-video.self', function (Browser $browser) {
$browser->waitFor('video')
@@ -134,12 +134,12 @@
// Assert current UI state
$guest->assertToolbar([
- 'audio' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
- 'video' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'audio' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'video' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'screen' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'chat' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
- 'fullscreen' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'logout' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'fullscreen' => RoomPage::BUTTON_ENABLED,
+ 'logout' => RoomPage::BUTTON_ENABLED,
])
->whenAvailable('div.meet-video:not(.self)', function (Browser $browser) {
$browser->waitFor('video')
@@ -166,7 +166,7 @@
// Test muting audio
$owner->click('@menu button.link-audio')
- ->assertToolbarButtonState('audio', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
+ ->assertToolbarButtonState('audio', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
->assertVisible('div.meet-video.self .status .status-audio');
// FIXME: It looks that we can't just check the <video> element state
@@ -175,14 +175,14 @@
// Test unmuting audio
$owner->click('@menu button.link-audio')
- ->assertToolbarButtonState('audio', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
+ ->assertToolbarButtonState('audio', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
->assertMissing('div.meet-video.self .status .status-audio');
$guest->waitUntilMissing('div.meet-video:not(.self) .status .status-audio');
// Test muting audio with a keyboard shortcut (key 'm')
$owner->driver->getKeyboard()->sendKeys('m');
- $owner->assertToolbarButtonState('audio', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
+ $owner->assertToolbarButtonState('audio', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
->assertVisible('div.meet-video.self .status .status-audio');
$guest->waitFor('div.meet-video:not(.self) .status .status-audio')
@@ -190,7 +190,7 @@
// Test unmuting audio with a keyboard shortcut (key 'm')
$owner->driver->getKeyboard()->sendKeys('m');
- $owner->assertToolbarButtonState('audio', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
+ $owner->assertToolbarButtonState('audio', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
->assertMissing('div.meet-video.self .status .status-audio');
$guest->waitUntilMissing('div.meet-video:not(.self) .status .status-audio')
@@ -198,7 +198,7 @@
// Test muting video
$owner->click('@menu button.link-video')
- ->assertToolbarButtonState('video', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
+ ->assertToolbarButtonState('video', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
->assertVisible('div.meet-video.self .status .status-video');
// FIXME: It looks that we can't just check the <video> element state
@@ -207,7 +207,7 @@
// Test unmuting video
$owner->click('@menu button.link-video')
- ->assertToolbarButtonState('video', RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED)
+ ->assertToolbarButtonState('video', RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED)
->assertMissing('div.meet-video.self .status .status-video');
$guest->waitUntilMissing('div.meet-video:not(.self) .status .status-video');
diff --git a/src/tests/Browser/Meet/RoomSetupTest.php b/src/tests/Browser/Meet/RoomSetupTest.php
--- a/src/tests/Browser/Meet/RoomSetupTest.php
+++ b/src/tests/Browser/Meet/RoomSetupTest.php
@@ -180,7 +180,8 @@
->assertMissing('.status .status-audio')
->assertMissing('.status .status-video');
})
- ->assertMissing('#header-menu');
+ ->assertMissing('#header-menu')
+ ->assertSeeIn('@counter', 1);
if (!$browser->isPhone()) {
$browser->assertMissing('#footer-menu');
@@ -213,7 +214,8 @@
->assertMissing('.status .status-audio')
->assertMissing('.status .status-video');
})
- ->assertElementsCount('@session div.meet-video', 2);
+ ->assertElementsCount('@session div.meet-video', 2)
+ ->assertSeeIn('@counter', 2);
// Check guest's elements in the owner's window
$browser
@@ -236,7 +238,8 @@
->assertVisible('#header-menu');
// Expect the participant removed from other users windows
- $browser->waitUntilMissing('@session div.meet-video:not(.self)');
+ $browser->waitUntilMissing('@session div.meet-video:not(.self)')
+ ->assertSeeIn('@counter', 1);
// Join the room as guest again
$guest->visit(new RoomPage('john'))
@@ -301,14 +304,14 @@
->assertElementsCount('@session video', 0)
->assertElementsCount('@session .meet-subscriber', 1)
->assertToolbar([
- 'audio' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
- 'video' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
+ 'audio' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_DISABLED,
+ 'video' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_DISABLED,
'screen' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
'hand' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'chat' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
- 'fullscreen' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'options' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'logout' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'fullscreen' => RoomPage::BUTTON_ENABLED,
+ 'options' => RoomPage::BUTTON_ENABLED,
+ 'logout' => RoomPage::BUTTON_ENABLED,
]);
// After the owner "opened the room" guest should be able to join
@@ -331,14 +334,15 @@
->assertElementsCount('@session div.meet-video', 0)
->assertElementsCount('@session video', 0)
->assertElementsCount('@session div.meet-subscriber', 2)
+ ->assertSeeIn('@counter', 2)
->assertToolbar([
- 'audio' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
- 'video' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
+ 'audio' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_DISABLED,
+ 'video' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_DISABLED,
'screen' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_DISABLED,
'hand' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
'chat' => RoomPage::BUTTON_INACTIVE | RoomPage::BUTTON_ENABLED,
- 'fullscreen' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
- 'logout' => RoomPage::BUTTON_ACTIVE | RoomPage::BUTTON_ENABLED,
+ 'fullscreen' => RoomPage::BUTTON_ENABLED,
+ 'logout' => RoomPage::BUTTON_ENABLED,
]);
// Check guest's elements in the owner's window
@@ -348,7 +352,8 @@
})
->assertElementsCount('@session div.meet-video', 0)
->assertElementsCount('@session video', 0)
- ->assertElementsCount('@session .meet-subscriber', 2);
+ ->assertElementsCount('@session .meet-subscriber', 2)
+ ->assertSeeIn('@counter', 2);
// Test leaving the room
diff --git a/src/tests/Browser/Pages/Meet/Room.php b/src/tests/Browser/Pages/Meet/Room.php
--- a/src/tests/Browser/Pages/Meet/Room.php
+++ b/src/tests/Browser/Pages/Meet/Room.php
@@ -78,6 +78,8 @@
'@menu' => '#meet-session-menu',
+ '@counter' => '#meet-counter',
+
'@session' => '#meet-session',
'@subscribers' => '#meet-subscribers',
'@queue' => '#meet-queue',
@@ -121,11 +123,11 @@
$class = '';
if ($state & self::BUTTON_ACTIVE) {
- $class .= ':not(.text-danger)';
+ $class .= '.on';
}
if ($state & self::BUTTON_INACTIVE) {
- $class .= '.text-danger';
+ $class .= ':not(.on)';
}
if ($state & self::BUTTON_DISABLED) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 3, 10:14 PM (7 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18822788
Default Alt Text
D2329.1775254449.diff (22 KB)
Attached To
Mode
D2329: Meet: Fix toolbar regressions
Attached
Detach File
Event Timeline