mirror of
https://github.com/jech/galene.git
synced 2024-11-23 00:55:58 +01:00
improve html interface, add custom controls for video
This commit is contained in:
parent
aae6b460f7
commit
fa694e67bf
3 changed files with 164 additions and 25 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue