1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-22 16:45:58 +01:00

improve html interface, add custom controls for video

This commit is contained in:
Alain Takoudjou 2020-09-28 17:00:25 +02:00
parent aae6b460f7
commit fa694e67bf
3 changed files with 164 additions and 25 deletions

View file

@ -12,7 +12,7 @@
.topnav { .topnav {
padding-left: 0; padding-left: 0;
height: 4rem; height: 3.5rem;
z-index: 1039; z-index: 1039;
} }
@ -61,7 +61,7 @@
} }
.navbar { .navbar {
position: relative; position: relative;
padding: .5rem; padding: .1rem;
} }
.topnav .navbar-brand { .topnav .navbar-brand {
@ -192,7 +192,7 @@
.full-width { .full-width {
width: calc(100vw - 200px); width: calc(100vw - 200px);
height: calc(var(--vh, 1vh) * 100 - 64px); height: calc(var(--vh, 1vh) * 100 - 56px);
} }
.full-width-active { .full-width-active {
@ -204,7 +204,7 @@
} }
.users-header { .users-header {
height: 4rem; height: 3.5rem;
padding: 10px; padding: 10px;
background: #610a86; background: #610a86;
font-size: .95rem; font-size: .95rem;
@ -221,7 +221,7 @@
} }
.reply { .reply {
height: 60px; height: 53px;
width: 100%; width: 100%;
background-color: #eae7e5; background-color: #eae7e5;
padding: 10px 5px 10px 5px; padding: 10px 5px 10px 5px;
@ -242,7 +242,7 @@
} }
textarea.form-reply { textarea.form-reply {
height: 2.6em; height: 2.1em;
margin-right: .5em; margin-right: .5em;
} }
@ -290,7 +290,7 @@ textarea.form-reply {
word-wrap: break-word; word-wrap: break-word;
display: inline-block; display: inline-block;
margin: 1em 0 0; margin: 1em 0 0;
max-width: 80%; max-width: 90%;
} }
.message-sender { .message-sender {
@ -345,7 +345,7 @@ textarea.form-reply {
} }
.video-container { .video-container {
height: calc(var(--vh, 1vh) * 100 - 64px); height: calc(var(--vh, 1vh) * 100 - 56px);
position: relative; position: relative;
background: rgba(0, 0, 0, 0.91); background: rgba(0, 0, 0, 0.91);
/* Display only when showing video */ /* Display only when showing video */
@ -376,12 +376,52 @@ textarea.form-reply {
opacity: 0; opacity: 0;
} }
.video-controls {
position: absolute;
width: 100%;
left: 0;
bottom: 40px;
text-align: center;
color: #e1e1e1;
font-size: 2.3em;
transition: all .5s ease-out;
opacity: 0;
}
.peer:hover > .video-controls {
opacity: 1;
transition: all .7s ease-out;
}
.video-controls span {
margin-right: 30px;
transition: all .5s ease-out;
opacity: .5;
cursor: pointer;
text-shadow: 2px 2px 4px rgba(123, 123, 123, 0.65);
}
.video-controls span:last-child {
margin-right: 0;
}
.video-controls span:hover {
opacity: 1;
transition: opacity .5s ease-out;
}
.video-controls .volume {
width: 44px;
display: inline-block;
text-align: center;
}
.mobile-container { .mobile-container {
display: block !important; display: block !important;
} }
.login-container { .login-container {
height: calc(var(--vh, 1vh) * 100 - 64px); height: calc(var(--vh, 1vh) * 100 - 56px);
position: relative; position: relative;
display: block; display: block;
} }
@ -566,6 +606,7 @@ h1 {
/* force to fill height */ /* force to fill height */
height: 100% !important; height: 100% !important;
min-width: 300px; min-width: 300px;
overflow: hidden;
} }
#inputform { #inputform {
@ -574,7 +615,7 @@ h1 {
#box { #box {
overflow: auto; overflow: auto;
height: calc(100% - 60px); height: calc(100% - 53px);
padding: 10px; padding: 10px;
} }
@ -641,7 +682,8 @@ h1 {
.media { .media {
width: 100%; width: 100%;
max-height: calc(var(--vh, 1vh) * 100 - 84px); min-width: 220px; /* min-size for controls buttons */
max-height: calc(var(--vh, 1vh) * 100 - 76px);
padding-bottom: 20px; padding-bottom: 20px;
object-fit: contain; object-fit: contain;
} }
@ -672,13 +714,13 @@ h1 {
} }
.sidenav a { .sidenav a {
padding: 10px; padding: 10px 20px;
text-decoration: none; text-decoration: none;
font-size: 30px; font-size: 30px;
color: #dbd9d9; color: #dbd9d9;
display: block; display: block;
transition: 0.3s; transition: 0.3s;
line-height: 1.2; line-height: 1.0;
} }
.sidenav a:hover { .sidenav a:hover {
@ -689,7 +731,8 @@ h1 {
cursor: pointer; cursor: pointer;
position: absolute; position: absolute;
top: 0; top: 0;
right: 5px; right: 0;
height: 56px;
} }
.sidenav label{ .sidenav label{
@ -702,12 +745,16 @@ h1 {
margin-top: 15px; margin-top: 15px;
} }
.sidenav-header {
height: 56px;
}
.sidenav-header h2{ .sidenav-header h2{
color: #fff; color: #fff;
padding: 10px; padding: 10px;
margin: 0; margin: 0;
max-width: 70%; max-width: 70%;
line-height: 44px; line-height: 36px;
} }
.sidenav-content { .sidenav-content {
@ -841,13 +888,14 @@ header .collapse {
cursor: pointer; cursor: pointer;
padding-top: 5px; padding-top: 5px;
margin-right: 20px; margin-right: 20px;
margin-left: 5px;
} }
.sfu-header { .sfu-header {
font-size: 1.3rem; font-size: 1.3rem;
font-weight: 900; font-weight: 900;
color: #dbd9d9; color: #dbd9d9;
line-height: 44px; line-height: 34px;
} }
.header-sep { .header-sep {
@ -934,14 +982,6 @@ header .collapse {
display: none; display: none;
} }
.topnav {
height: 3.5rem;
}
.users-header {
height: 3.5rem;
}
.full-width { .full-width {
height: calc(var(--vh, 1vh) * 100 - 56px); height: calc(var(--vh, 1vh) * 100 - 56px);
} }
@ -955,6 +995,10 @@ header .collapse {
margin-bottom: 60px; margin-bottom: 60px;
} }
.video-controls {
opacity: 1;
}
.login-container { .login-container {
position: fixed; position: fixed;
height: calc(var(--vh, 1vh) * 100 - 56px); height: calc(var(--vh, 1vh) * 100 - 56px);
@ -1010,6 +1054,8 @@ header .collapse {
display: block; display: block;
} }
.sidenav a {padding: 10px 5px;}
.sidenav-header h2 { .sidenav-header h2 {
line-height: 36px; line-height: 36px;
} }

View file

@ -186,6 +186,14 @@
</div> </div>
</div> </div>
<div id="videocontrols-template" class="invisible">
<div class="video-controls">
<span class="volume"><i class="fa fa-volume-up" data-type="bt-volume" aria-hidden="true"></i></span>
<span class="pip"><i class="fa fa-clone" data-type="bt-pip" aria-hidden="true"></i></span>
<span class="fullscreen"><i class="fa fa-arrows-alt" data-type="bt-fullscreen" aria-hidden="true"></i></span>
</div>
</div>
<script src="/protocol.js" defer></script> <script src="/protocol.js" defer></script>
<script src="/scripts/toastify.js" defer></script> <script src="/scripts/toastify.js" defer></script>
<script src="/sfu.js" defer></script> <script src="/sfu.js" defer></script>

View file

@ -953,7 +953,7 @@ function setMedia(c, isUp) {
media.autoplay = true; media.autoplay = true;
/** @ts-ignore */ /** @ts-ignore */
media.playsinline = true; media.playsinline = true;
media.controls = true; media.controls = false;
if(isUp) if(isUp)
media.muted = true; media.muted = true;
div.appendChild(media); div.appendChild(media);
@ -967,14 +967,99 @@ function setMedia(c, isUp) {
div.appendChild(label); div.appendChild(label);
} }
let template = document.getElementById('videocontrols-template').firstElementChild;
let controls = document.getElementById('controls-' + c.id);
if (template && !controls) {
controls = template.cloneNode(true);
controls.id = 'controls-' + c.id;
div.appendChild(controls);
if(media.muted) {
let volume = controls.querySelector(".fa-volume-up");
if (volume) {
volume.classList.remove("fa-volume-up");
volume.classList.add("fa-volume-off");
}
}
}
media.srcObject = c.stream; media.srcObject = c.stream;
setLabel(c); setLabel(c);
setMediaStatus(c); setMediaStatus(c);
showVideo(); showVideo();
resizePeers(); resizePeers();
registerControlEvent(div.id);
} }
/**
* @param {HTMLVideoElement} video
*/
async function videoPIP(video) {
if (video.requestPictureInPicture) {
await video.requestPictureInPicture();
} else {
displayWarning("Video PIP Mode not supported!");
}
}
/**
* @param {HTMLElement} target
*/
function getParentVideo(target) {
// target is the <i> element, parent the div <div><span><i/></span></div>
let control = target.parentElement.parentElement;
let hash = control.id.split('-')[1];
let media = /** @type {HTMLVideoElement} */
(document.getElementById('media-' + hash));
if (!media) {
displayWarning("Cannot find media!");
}
return media;
}
/**
* @param {string} peerid
*/
function registerControlEvent(peerid) {
let peer = document.getElementById(peerid);
let control_list = peer.querySelectorAll("span");
function control_event(event) {
event.preventDefault();
let control_type = event.target.getAttribute("data-type");
let video = getParentVideo(event.target);
switch (control_type) {
case "bt-volume":
if (event.target.className.indexOf("fa-volume-off") !== -1) {
event.target.classList.remove("fa-volume-off");
event.target.classList.add("fa-volume-up");
video.muted = false;
} else {
event.target.classList.remove("fa-volume-up");
event.target.classList.add("fa-volume-off");
// mute video sound
video.muted = true;
}
break;
case "bt-pip":
videoPIP(video);
break;
case "bt-fullscreen":
if (video.requestFullscreen) {
video.requestFullscreen();
} else {
displayWarning("Video Fullscreen not supported!");
}
break;
}
}
for (let i = 0; i < control_list.length; i += 1) {
control_list[i].onclick = control_event;
}
}
/** /**
* @param {string} id * @param {string} id
*/ */