diff options
author | Minteck <contact@minteck.org> | 2023-02-23 19:34:56 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-02-23 19:34:56 +0100 |
commit | 3d1cd02f27518f1a04374c7c8320cd5d82ede6e9 (patch) | |
tree | 75be5fba4368472fb11c8015aee026b2b9a71888 /pages/together.inc | |
parent | 8cc1f13c17fa2fb5a4410542d39e650e02945634 (diff) | |
download | pluralconnect-3d1cd02f27518f1a04374c7c8320cd5d82ede6e9.tar.gz pluralconnect-3d1cd02f27518f1a04374c7c8320cd5d82ede6e9.tar.bz2 pluralconnect-3d1cd02f27518f1a04374c7c8320cd5d82ede6e9.zip |
Updated 40 files, added 37 files, deleted 1103 files and renamed 3905 files (automated)
Diffstat (limited to 'pages/together.inc')
-rw-r--r-- | pages/together.inc | 940 |
1 files changed, 0 insertions, 940 deletions
diff --git a/pages/together.inc b/pages/together.inc deleted file mode 100644 index c210fa5..0000000 --- a/pages/together.inc +++ /dev/null @@ -1,940 +0,0 @@ -<?php - -$_GET['old'] = ""; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages; -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; - -global $WebSocketAddress; - -if (!isset($WebSocketAddress)) { - $WebSocketAddress = "wss://ponies.equestria.horse/_WatchTogether-WebSocket-EntryPoint/socket"; -} - -?> - -<style> - .list-group-item { - color: #fff; - background-color: #222; - border: 1px solid rgba(255, 255, 255, .125); - } - - .list-group-item.disabled { - color: #fff; - background-color: #222; - border-color: rgba(255, 255, 255, .125); - opacity: .75; - } - - .list-group-item-action:hover { - background-color: #252525; - color: #ddd; - } - - .list-group-item-action:active, .list-group-item-action:focus { - background-color: #272727; - color: #bbb; - } - - .video-queue-item { - display: grid; - grid-template-columns: 1fr max-content; - grid-gap: 10px; - cursor: pointer; - } - - .video-queue-item-status { - filter: invert(1); - display: block; - height: 32px; - width: 32px; - } - - .video-queue-item-part { - display: flex; - align-items: center; - } - - .video-queue-item-metadata { - width: 100%; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - - .video-queue-item-title-outer, .video-queue-item-author-outer { - display: flex; - align-items: center; - } - - .video-queue-item-title, .video-queue-item-title-outer, .video-queue-item-author, .video-queue-item-author-outer { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - width: 100%; - } - - .modal-header { - border-bottom: 1px solid #353738; - } - - .modal-content { - border: 1px solid rgba(255, 255, 255, .2); - background-color: #111; - } - - .btn-close { - filter: invert(1); - } - - .user-ping { - float: right; - display: inline-block; - width: 16px; - height: 16px; - border-radius: 999px; - position: relative; - top: 5px; - } - - .control-item { - display: inline-block; - cursor: pointer; - border-radius: 999px; - background-color: rgba(0, 0, 0, 0); - border: 1px solid rgba(255, 255, 255, 0); - transition: background-color 200ms, border-color 200ms; - } - - .control-item:hover { - background-color: rgba(0, 0, 0, .25); - border-color: rgba(255, 255, 255, .1); - } - - .control-item:active { - background-color: rgba(0, 0, 0, .5); - border-color: rgba(255, 255, 255, .25); - } - - .control-icon { - filter: invert(1); - width: 24px; - height: 24px; - margin: 12px; - pointer-events: none; - } - - body.hide-controls * { - cursor: none; - } - - #controls-outer { - opacity: 1; - transition: opacity 500ms; - } - - .navbar, #sidebar { - opacity: 1; - transition: opacity 500ms; - } - - body.hide-controls #controls-outer { - opacity: 0; - } - - body.hide-controls .navbar, body.hide-controls #sidebar { - opacity: .25; - } - - body.fullscreen #app-container { - grid-template-columns: 1fr !important; - } - - body.fullscreen .navbar, body.fullscreen #sidebar { - display: none; - } - - body.fullscreen #app-container div, body.fullscreen #app-container video { - height: 100vh !important; - } - - body.fullscreen #controls-outer, body.fullscreen #notification { - inset: 0 !important; - } - - #notification { - opacity: 0; - pointer-events: none; - transition: opacity 200ms; - } - - #video-title { - opacity: 1; - transition: opacity 200ms; - } - - body.notification #notification { - opacity: 1; - } - - body.notification #video-title { - opacity: 0; - } - - body.skipper #skipper { - opacity: 1 !important; - pointer-events: initial !important; - } - - #skipper { - opacity: 0; - pointer-events: none; - transition: opacity 200ms; - position: fixed; - bottom: 79px; - z-index: 999; - background: rgba(0, 0, 0, .5); - border-radius: 10px; - padding: 10px 20px; - left: 20px; - border: 1px solid rgba(255, 255, 255, .25); - cursor: pointer; - } - - #skipper:hover { - background: rgba(0, 0, 0, .75) !important; - } - - #skipper:active { - background: rgba(0, 0, 0, 1) !important; - } -</style> - -<script src="/assets/editor/thing.js"></script> - -<div class="modal fade" id="error" data-bs-backdrop="static" data-bs-keyboard="false" style="z-index: 99999;"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title">An error occurred</h4> - </div> - - <div class="modal-body"> - <div class="alert alert-danger" id="error-message"></div> - </div> - </div> - </div> -</div> - -<div class="modal fade" id="add" data-bs-backdrop="static" data-bs-keyboard="false"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title">Add new video</h4> - </div> - - <div class="modal-body"> - <p>Enter a YouTube video ID to add to the queue:</p> - <input type="text" class="form-control" id="add-id" placeholder="e.g. K9tUKbOFots" style="color:white;background:#111;border-color:#222;"> - <p style="margin-top:10px;margin-bottom: 0;"> - <div class="btn-group"> - <span onclick="doAdd();" id="add-btn-yes" class="btn btn-primary">Add</span> - <span onclick="closeAdd();" id="add-btn-no" class="btn btn-secondary">Cancel</span> - </div> - <a href="#" onclick="document.getElementById('add-id').value = 'K9tUKbOFots';">test</a> - </p> - </div> - </div> - </div> -</div> - -<div class="modal fade" id="welcome" data-bs-backdrop="static" data-bs-keyboard="false"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h4 class="modal-title">Welcome to Watch Together!</h4> - </div> - - <div class="modal-body"> - <h5>Host a new session</h5> - <p>You will be given an invite code to share with your partner·s.</p> - <span class="btn btn-primary" id="host-start" onclick="hostSession();">Start</span> - - <hr> - - <h5>Join an existing session</h5> - <p>Enter the invite code your partner has given you:</p> - <div style="display:grid;grid-template-columns: repeat(8, 1fr);grid-gap:10px;"> - <input type="text" class="form-control" id="invite-input-1" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-2" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-3" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-4" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-5" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-6" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-7" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - <input type="text" class="form-control" id="invite-input-8" style="text-align: center;color:white;background:#111;border-color:#222;" onchange="processInviteCode(event);" onkeydown="processInviteCode(event);" onkeyup="processInviteCode(event);" maxlength="1"> - </div> - </div> - </div> - </div> -</div> -<script> - document.getElementById("invite-input-1").disabled = true; - document.getElementById("invite-input-2").disabled = true; - document.getElementById("invite-input-3").disabled = true; - document.getElementById("invite-input-4").disabled = true; - document.getElementById("invite-input-5").disabled = true; - document.getElementById("invite-input-6").disabled = true; - document.getElementById("invite-input-7").disabled = true; - document.getElementById("invite-input-8").disabled = true; - document.getElementById("host-start").classList.add("disabled"); - - let modal = new bootstrap.Modal(document.getElementById('welcome')); - modal.show(); - document.getElementById("invite-input-1").focus(); - - window.modalAdd = new bootstrap.Modal(document.getElementById('add')); - - function openAdd() { - modalAdd.show(); - } - - function closeAdd() { - document.getElementById("add-id").value = ""; - modalAdd.hide(); - } - - function doAdd() { - document.getElementById("add-id").disabled = true; - document.getElementById("add-btn-yes").classList.add("disabled"); - document.getElementById("add-btn-no").classList.add("disabled"); - - socket.send(JSON.stringify({ - task: "UPDATE_QUEUE", - payload: { - operation: "+", - video: document.getElementById("add-id").value - } - })) - } - - function toPrettyTime(seconds) { - let parts = new Date(seconds * 1000).toUTCString().split(" ")[4].split(":"); - parts[0] = parseInt(parts[0]).toString(); - - if (parts[0] === "0") { - parts[1] = parseInt(parts[1]).toString(); - parts.shift(); - } - - return parts.join(":"); - } - - function processInviteCode(event) { - let i1 = document.getElementById("invite-input-1").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i2 = document.getElementById("invite-input-2").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i3 = document.getElementById("invite-input-3").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i4 = document.getElementById("invite-input-4").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i5 = document.getElementById("invite-input-5").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i6 = document.getElementById("invite-input-6").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i7 = document.getElementById("invite-input-7").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - let i8 = document.getElementById("invite-input-8").value.trim().toLowerCase().replace(/[^\da-z]+/gm, ""); - - document.getElementById("invite-input-1").value = i1; - document.getElementById("invite-input-2").value = i2; - document.getElementById("invite-input-3").value = i3; - document.getElementById("invite-input-4").value = i4; - document.getElementById("invite-input-5").value = i5; - document.getElementById("invite-input-6").value = i6; - document.getElementById("invite-input-7").value = i7; - document.getElementById("invite-input-8").value = i8; - - if (i8 === "") { - document.getElementById("invite-input-8").focus(); - } - if (i7 === "") { - document.getElementById("invite-input-7").focus(); - } - if (i6 === "") { - document.getElementById("invite-input-6").focus(); - } - if (i5 === "") { - document.getElementById("invite-input-5").focus(); - } - if (i4 === "") { - document.getElementById("invite-input-4").focus(); - } - if (i3 === "") { - document.getElementById("invite-input-3").focus(); - } - if (i2 === "") { - document.getElementById("invite-input-2").focus(); - } - if (i1 === "") { - document.getElementById("invite-input-1").focus(); - } - - if (event instanceof KeyboardEvent) { - if (event.code === "Backspace" && event.type === "keydown") { - let el = event.target; - let ep = document.getElementById("invite-input-" + (el['id'].split("-")[2] - 1)); - - if (ep !== null) { - if (el.value.trim() === "") { - ep.value = ""; - ep.focus(); - } else { - el.value = ""; - ep.focus(); - } - } - } - } - - if (i1.length === 1 && i2.length === 1 && i3.length === 1 && i4.length === 1 && i5.length === 1 && i6.length === 1 && i7.length === 1 && i8.length === 1 && ((event.type && event.type === "keyup") || !event.type)) { - joinSession(i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8); - } - } - - async function joinSession(code) { - document.getElementById("invite-input-1").disabled = true; - document.getElementById("invite-input-2").disabled = true; - document.getElementById("invite-input-3").disabled = true; - document.getElementById("invite-input-4").disabled = true; - document.getElementById("invite-input-5").disabled = true; - document.getElementById("invite-input-6").disabled = true; - document.getElementById("invite-input-7").disabled = true; - document.getElementById("invite-input-8").disabled = true; - document.getElementById("host-start").classList.add("disabled"); - - window.inviteCode = code; - - startSession(); - } - - async function hostSession() { - document.getElementById("invite-input-1").disabled = true; - document.getElementById("invite-input-2").disabled = true; - document.getElementById("invite-input-3").disabled = true; - document.getElementById("invite-input-4").disabled = true; - document.getElementById("invite-input-5").disabled = true; - document.getElementById("invite-input-6").disabled = true; - document.getElementById("invite-input-7").disabled = true; - document.getElementById("invite-input-8").disabled = true; - document.getElementById("host-start").classList.add("disabled"); - - window.inviteCode = null; - - startSession(); - } - - window.terminated = false; - window.users = null; - window.queue = null; - window.segments = []; - window.originalTitle = document.title; - - async function connect() { - window.identity = JSON.parse(await (await window.fetch("/api/me")).text()); - window.sessionToken = await (await window.fetch("/api/token")).text(); - - window.socket = new WebSocket("<?= $WebSocketAddress ?>"); - - socket.onclose = (event) => { - console.log("[ws:close] ",event); - - if (window.terminated) { - modal.hide(); - return; - } - - if (event.wasClean) { - document.getElementById('error-message').innerText = "Connection closed"; - } else { - if (event.reason) { - document.getElementById('error-message').innerText = "Connection closed unexpectedly with code " + event.code + ": " + event.reason; - } else { - document.getElementById('error-message').innerText = "Connection closed unexpectedly with code " + event.code; - } - } - - let errorModal = new bootstrap.Modal(document.getElementById('error')); - errorModal.show(); - modal.hide(); - } - - socket.onmessage = async (event) => { - let data = JSON.parse(event.data); - if (data.task !== "HEARTBEAT_ACK") console.log("[ws:message]", data); - - if (data.task === "CONFIG") { - document.getElementById("invite-input-1").disabled = false; - document.getElementById("invite-input-2").disabled = false; - document.getElementById("invite-input-3").disabled = false; - document.getElementById("invite-input-4").disabled = false; - document.getElementById("invite-input-5").disabled = false; - document.getElementById("invite-input-6").disabled = false; - document.getElementById("invite-input-7").disabled = false; - document.getElementById("invite-input-8").disabled = false; - document.getElementById("host-start").classList.remove("disabled"); - - setInterval(() => { - socket.send(JSON.stringify({ - task: "HEARTBEAT", - payload: { - videoPositon: document.getElementById("video").currentTime - } - })); - }, data.payload.heartbeatInterval); - - return; - } - - if (data.task === "SESSION") { - window.users = data.payload.users; - window.queue = data.payload.queue; - - updateQueue(); - - document.getElementById("participants").innerHTML = ""; - for (let user of data.payload.users) { - document.getElementById("participants").innerHTML += "<li class='list-group-item'>" + user.id + "<span id='user-" + user.id + "-ping' class='bg-primary user-ping'></span></li>"; - } - - document.getElementById("invite-code").innerText = data.payload.code; - } - - if (data.task === "VIDEO_UPDATE") { - if (data.payload.id !== null) { - try { - window.segments = JSON.parse(await (await window.fetch("https://sponsor.ajay.app/api/skipSegments/" + data.payload.sha.substring(0, 32) + '?categories=["sponsor","intro","outro","music_offtopic"]')).text()).filter(i => i['videoID'] === data.payload.id)[0].segments; - notification("This video is enhanced by smart playback", "success"); - } catch (e) { - notification("This video is not compatible with smart playback", "warning"); - window.segments = []; - } - } - - if (data.payload.url) document.getElementById("video").src = data.payload.url; - - if (data.payload.state === 1) { - document.getElementById("video").play(); - } else if (!!data.payload.state) { - document.getElementById("video").pause(); - } - - if (data.payload.title && data.payload.title.trim() !== "") { - document.getElementById("video-title").innerText = data.payload.title; - document.title = data.payload.title + " · " + window.originalTitle; - } else { - if (data.payload.title) { - document.getElementById("video-title").innerText = ""; - document.title = window.originalTitle; - } - } - - document.getElementById("video").currentTime = data.payload.position; - } - - if (data.task === "UPDATE_USERS") { - window.users = data.payload.users; - - document.getElementById("participants").innerHTML = ""; - for (let user of data.payload.users) { - document.getElementById("participants").innerHTML += "<li class='list-group-item'>" + user.id + "<span id='user-" + user.id + "-ping' class='bg-primary user-ping'></span></li>"; - } - } - - if (data.task === "UPDATE_QUEUE") { - window.queue = data.payload.queue; - - if (data.payload.poster === identity.id) { - document.getElementById("add-id").disabled = false; - document.getElementById("add-id").value = ""; - document.getElementById("add-btn-yes").classList.remove("disabled"); - document.getElementById("add-btn-no").classList.remove("disabled"); - - modalAdd.hide(); - } - - updateQueue(); - } - - if (data.task === "HEARTBEAT_ACK") { - for (let user of Object.keys(data.payload.delays)) { - let abs = Math.abs(data.payload.delays[user]); - let color = "primary"; - - if (abs >= 500) color = "warning"; - if (abs >= 1000) color = "danger"; - if (abs < 500) color = "success"; - - let sign = "±"; - if (data.payload.delays[user] < 0) sign = "-"; - if (data.payload.delays[user] > 0) sign = "+"; - - document.getElementById("user-" + user + "-ping").title = sign + abs + " ms"; - document.getElementById("user-" + user + "-ping").classList.remove("bg-primary"); - document.getElementById("user-" + user + "-ping").classList.remove("bg-danger"); - document.getElementById("user-" + user + "-ping").classList.remove("bg-warning"); - document.getElementById("user-" + user + "-ping").classList.remove("bg-green"); - document.getElementById("user-" + user + "-ping").classList.add("bg-" + color); - } - } - - if (data.task === "TERMINATE" || data.task === "FAILURE") { - window.terminated = true; - - if (data.payload.code) { - if (data.payload.reason) { - document.getElementById('error-message').innerText = data.payload.code + ": " + data.payload.reason; - let errorModal = new bootstrap.Modal(document.getElementById('error')); - errorModal.show(); - } else { - document.getElementById('error-message').innerText = data.payload.code; - let errorModal = new bootstrap.Modal(document.getElementById('error')); - errorModal.show(); - } - } else { - document.getElementById('error-message').innerText = "Error"; - let errorModal = new bootstrap.Modal(document.getElementById('error')); - errorModal.show(); - } - - if (data.task === "FAILURE") socket.close(); - } - } - - socket.onopen = (event) => { - console.log("[ws:open] ", event); - - socket.send(JSON.stringify({ - task: "IDENTIFY", - payload: { - token: window.sessionToken - } - })) - } - } - - function updateQueue() { - document.getElementById("queue").innerHTML = ""; - - for (let video of window.queue) { - document.getElementById("queue").innerHTML += ` -<li class="list-group-item list-group-item-action video-queue-item"> - <div class="video-queue-item-part video-queue-item-metadata"> - <div> - <div class="video-queue-item-title-outer"> - <span class="video-queue-item-title">${video.title}</span> - </div> - <div class="video-queue-item-author-outer"> - <span class="video-queue-item-author text-muted">${video.author}</span> - </div> - </div> - </div> - <div class="video-queue-item-part text-muted">${video['duration_pretty'] ?? toPrettyTime(video.duration)}</div> -</li> -`; - } - } - - function startSession() { - socket.send(JSON.stringify({ - task: "SESSION", - payload: { - id: window.inviteCode - } - })) - - modal.hide(); - } - - connect(); -</script> - -<div style="height:calc(100vh - 60px);display:grid;grid-template-columns: 3fr 1.5fr;" id="app-container"> - <div style="height:calc(100vh - 60px);"> - <video id="video" style="width:100%;height:calc(100vh - 60px);"></video> - </div> - <script> - - document.getElementById("video").onplay = () => { - console.log("play"); - - if (socket) socket.send(JSON.stringify({ - task: "VIDEO_UPDATE", - payload: { - state: 1, - position: document.getElementById("video").currentTime - } - })); - } - - document.getElementById("video").onpause = () => { - console.log("pause"); - - if (socket) socket.send(JSON.stringify({ - task: "VIDEO_UPDATE", - payload: { - state: 0, - position: document.getElementById("video").currentTime - } - })); - } - - let controlsFadeInterval; - document.body.classList.remove("hide-controls"); - - document.body.onmousemove = document.body.onmouseup = () => { - document.body.classList.remove("hide-controls"); - try { clearTimeout(controlsFadeInterval) } catch (e) {} - controlsFadeInterval = setTimeout(() => { - if (!document.getElementById("video").paused) document.body.classList.add("hide-controls"); - }, 5000); - } - - </script> - <div class="container" id="sidebar" style="border-left:1px solid rgba(255, 255, 255, .25);"> - <br> - <h4>Participants</h4> - <ul class="list-group" id="participants"></ul> - <p style="margin-top:10px;margin-bottom:0;">Invite new participants with this invite code: <code id="invite-code">--------</code></p> - - <br> - <h4>Queue</h4> - <ul class="list-group" id="queue"></ul> - <p style="margin-top:10px;margin-bottom:0;"> - <span class="btn btn-primary" onclick="openAdd()">Add video</span> - </p> - </div> -</div> - -<div id="notification" style="z-index:999;padding: 15px 20px;font-size: 20px;position: fixed;top: 60px;left:0;text-shadow: 0 0 10px black;"> - Notification. -</div> -<a onclick="controls_skipIntroOutro();" id="skipper">Skip</a> -<div id="controls-outer" style="position:fixed;background: linear-gradient(180deg, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%);top: 60px;left: 0;right: 0;bottom: 0;"> - <div id="video-title" style="padding: 15px 20px;font-size: 20px;"></div> - <div id="controls" style="position: fixed;bottom: 20px;height: 50px;left: 15px;display:grid;grid-template-columns: max-content 1fr max-content;"> - <div> - <a id="control-play" onclick="controls_playPause();" class="control-item"> - <img alt="" src="/assets/icons/together/play.svg" id="control-play-icon" class="control-icon"> - </a> - <a id="control-next" onclick="controls_next();" class="control-item"> - <img alt="" src="/assets/icons/together/next.svg" id="control-next-icon" class="control-icon"> - </a> - </div> - <div style="display: flex;align-items: center;padding-left:15px;padding-right:15px;"> - <div style="padding: 22px 0;width:100%;" id="seek-bar"> - <div style="height:6px;width:100%;background:rgba(255, 255, 255, .1);border-radius:999px;pointer-events: none;"> - <div style="height:6px;width:0;background:rgba(255, 255, 255, .75);border-radius:999px;" id="control-progress"></div> - </div> - </div> - </div> - <div> - <div style="display: inline-flex;align-items: center;"> - <span id="time-remaining" style="font-family:monospace;">-0:00</span> - </div> - <a id="control-full" onclick="controls_fullscreen();" class="control-item"> - <img alt="" src="/assets/icons/together/full-on.svg" id="control-full-icon" class="control-icon"> - </a> - </div> - </div> - <div id="seek-bar-dot" style="position: fixed;bottom: 38px;width: 12px;height: 12px;background: white;border-radius: 999px;pointer-events: none;display:none;"></div> -</div> -<script> - document.getElementById("controls").style.width = (document.getElementById("video").clientWidth - 30) + "px"; - document.getElementById("controls-outer").style.right = (window.innerWidth - document.getElementById("video").clientWidth) + "px"; - document.getElementById("notification").style.right = (window.innerWidth - document.getElementById("video").clientWidth) + "px"; - - let notificationDecayTimeout; - - function notification(text, color) { - document.getElementById("notification").innerText = text; - document.getElementById("notification").classList.add("text-" + color); - document.body.classList.add("notification"); - - try { clearTimeout(notificationDecayTimeout) } catch (e) {} - - notificationDecayTimeout = setTimeout(() => { - document.body.classList.remove("notification"); - setTimeout(() => { - document.getElementById("notification").innerText = "Notification."; - document.getElementById("notification").classList.remove("text-" + color); - }, 200); - }, 5000) - } - - window.onresize = () => { - document.getElementById("controls").style.width = (document.getElementById("video").clientWidth - 30) + "px"; - document.getElementById("controls-outer").style.right = (window.innerWidth - document.getElementById("video").clientWidth) + "px"; - document.getElementById("notification").style.right = (window.innerWidth - document.getElementById("video").clientWidth) + "px"; - } - - function controls_playPause() { - if (document.getElementById("video").src.trim() === "") return; - - if (document.getElementById("video").paused) { - document.getElementById("video").play(); - } else { - document.getElementById("video").pause(); - } - } - - function controls_fullscreen() { - if (document.fullscreen) { - document.exitFullscreen(); - } else { - document.documentElement.requestFullscreen(); - } - } - - function controls_next() { - document.getElementById("video").play(); - document.getElementById("video").currentTime = document.getElementById("video").duration; - } - - window.seeking = false; - window.seekPosition = 0; - - document.getElementById("controls-outer").onclick = (event) => { - if (event.target === document.getElementById("controls-outer")) controls_playPause(); - } - - document.getElementById("controls-outer").ondblclick = (event) => { - if (event.target === document.getElementById("controls-outer")) controls_fullscreen(); - } - - document.getElementById("seek-bar").onmouseenter = () => { - document.getElementById("seek-bar-dot").style.display = ""; - console.log("> ENTER <"); - window.seeking = true; - } - - document.getElementById("seek-bar").onclick = (event) => { - let percentage = (event.offsetX / document.getElementById("seek-bar").clientWidth) * 100; - let multiplier = event.offsetX / document.getElementById("seek-bar").clientWidth; - - document.getElementById("seek-bar-dot").style.left = event.clientX + "px"; - - console.log(" CLICK: ", event.offsetX, "(" + percentage.toFixed(3) + "%, " + toPrettyTime(document.getElementById("video").duration * multiplier) + ")"); - window.seekPosition = document.getElementById("video").duration * multiplier; - - document.getElementById("video").pause(); - document.getElementById("video").currentTime = window.seekPosition; - document.getElementById("video").play(); - } - - document.getElementById("seek-bar").onmouseleave = () => { - document.getElementById("seek-bar-dot").style.display = "none"; - console.log("< LEAVE >"); - window.seeking = false; - } - - function controls_skipIntroOutro() { - let skipper = null; - - for (let segment of window.segments.filter(i => i['category'] === "intro")) { - if (segment.segment) { - if (document.getElementById("video").currentTime >= segment.segment[0] && document.getElementById("video").currentTime < segment.segment[1]) { - skipper = segment.segment[1]; - } - } - } - for (let segment of window.segments.filter(i => i['category'] === "outro")) { - if (segment.segment) { - if (document.getElementById("video").currentTime >= segment.segment[0] && document.getElementById("video").currentTime < segment.segment[1]) { - skipper = segment.segment[1]; - } - } - } - - if (skipper) { - document.getElementById("video").pause(); - document.getElementById("video").currentTime = skipper; - document.getElementById("video").play(); - } - } - - document.getElementById("seek-bar").onmousemove = (event) => { - let percentage = (event.offsetX / document.getElementById("seek-bar").clientWidth) * 100; - let multiplier = event.offsetX / document.getElementById("seek-bar").clientWidth; - - document.getElementById("seek-bar-dot").style.left = event.clientX + "px"; - - console.log(" POS: ", event.offsetX, "(" + percentage.toFixed(3) + "%, " + toPrettyTime(document.getElementById("video").duration * multiplier) + ")"); - window.seekPosition = document.getElementById("video").duration * multiplier; - } - - setInterval(() => { - if (document.getElementById("video").src.trim() === "") { - document.getElementById("controls").style.display = "none"; - } else { - document.getElementById("controls").style.display = "grid"; - } - - document.getElementById("control-play-icon").src = document.getElementById("video").paused ? "/assets/icons/together/play.svg" : "/assets/icons/together/pause.svg"; - document.getElementById("control-full-icon").src = document.fullscreen ? "/assets/icons/together/full-off.svg" : "/assets/icons/together/full-on.svg"; - document.getElementById("control-progress").style.width = ((document.getElementById("video").currentTime / document.getElementById("video").duration) * 100) + "%"; - - if (document.fullscreen) { - document.body.classList.add("fullscreen"); - } else { - document.body.classList.remove("fullscreen"); - } - - if (window.seeking) { - document.getElementById("time-remaining").classList.add("text-warning"); - document.getElementById("time-remaining").innerText = toPrettyTime(window.seekPosition); - } else { - document.getElementById("time-remaining").classList.remove("text-warning"); - - if (!isNaN(document.getElementById("video").duration)) { - document.getElementById("time-remaining").innerText = "-" + toPrettyTime(Math.round(document.getElementById("video").duration) - Math.round(document.getElementById("video").currentTime)); - } else { - document.getElementById("time-remaining").innerText = "-0:00"; - } - } - }) - - setInterval(() => { - if (!document.getElementById("video").paused) { - for (let segment of window.segments.filter(i => i['category'] === "sponsor")) { - if (segment.segment) { - if (document.getElementById("video").currentTime >= segment.segment[0] && document.getElementById("video").currentTime < segment.segment[1]) { - document.getElementById("video").pause(); - document.getElementById("video").currentTime = segment.segment[1]; - document.getElementById("video").play(); - notification("Advert skipped by smart playback", "primary"); - } - } - } - - let skipper = false; - - for (let segment of window.segments.filter(i => i['category'] === "intro")) { - if (segment.segment) { - if (document.getElementById("video").currentTime >= segment.segment[0] && document.getElementById("video").currentTime < segment.segment[1]) { - skipper = true; - document.getElementById("skipper").innerText = "Skip intro"; - document.body.classList.add("skipper"); - } - } - } - for (let segment of window.segments.filter(i => i['category'] === "outro")) { - if (segment.segment) { - if (document.getElementById("video").currentTime >= segment.segment[0] && document.getElementById("video").currentTime < segment.segment[1]) { - skipper = true; - document.getElementById("skipper").innerText = "Skip to the end"; - document.body.classList.add("skipper"); - } - } - } - - if (!skipper) { - document.body.classList.remove("skipper"); - } - } - }) -</script>
\ No newline at end of file |