2024-12-19 18:49:09 -06:00

212 lines
5.2 KiB
JavaScript
Executable File

import {q} from "/static/js/elemjs/elemjs.js"
const video = q(".video")
const skipPrompt = q("#sb-skip-prompt")
const reason = q("#sb-skip-prompt #reason")
const timer = q("#sb-skip-prompt #timer")
const btn = q("#sb-skip-prompt #btn")
const countdownTime = 5
let currentSegment
let lastSegmentId = null
let lastAction
let buttonAction
let lastPopupVisible
function getSegmentById(id) {
for (const seg of data.sbData)
if (seg.UUID == id)
return seg
}
const popupVisible = () => !skipPrompt.classList.contains("hidden")
let popupCountdown
function showPopup(reasonText, buttonText, timeOverride) {
skipPrompt.classList.remove("hidden")
lastPopupVisible = true
reason.innerText = reasonText
let secsLeft = timeOverride ?? countdownTime
clearTimeout(popupCountdown)
function tick() {
secsLeft--
timer.innerText = `${Math.floor(secsLeft)} seconds`
if (secsLeft < 0) {
hidePopup()
} else
popupCountdown = setTimeout(tick, 1000)
}
tick()
btn.innerText = `${buttonText} (${sbSettings.sponsorblock_keybind} or click)`
}
function hidePopup() {
skipPrompt.classList.add("hidden")
lastSegmentId = null
lastPopupVisible = false
handleSegmentEnd()
}
function handleSegment() {
const category = currentSegment.category
const setMethod = sbSettings[`sponsorblock_${category}`]
let action = null
if (setMethod != undefined)
switch (setMethod) {
case 0:
if ((["skip", "mute"]).includes(currentSegment.actionType))
action = currentSegment.actionType
break;
case 1:
action = "skip"
break;
case 2:
action = "prompt"
break;
case 3:
action = "mute"
break;
}
lastAction = action
handleAction(action)
}
// fires if currentSegment changes OR popup hides
function handleSegmentEnd() {
if (lastAction == "mute")
video.muted = false
}
function handleAction(action) {
switch (action) {
case "skip":
// If segment has been unskipped, use "prompt" instead
if (!currentSegment.unskipped) {
video.currentTime = currentSegment.segment[1]
video.play()
showPopup(`Skipped ${currentSegment.category}`, "Unskip")
buttonAction = "unskip"
break;
}
case "prompt":
const timeLeft = Math.ceil(currentSegment.segment[1] - video.currentTime)
showPopup(`Skip ${currentSegment.category}? (${timeLeft} secs)`, "Skip", timeLeft)
buttonAction = "skip"
break;
case "mute":
video.muted = true
showPopup(`Muted for ${currentSegment.category}`, "Unmute")
buttonAction = "unmute"
break;
}
}
function handleButtonAction(seg, action) {
switch (action) {
case "unskip":
video.currentTime = seg.segment[0]
video.play()
seg.unskipped = true
showPopup(`Unskipped ${seg.category}`, "Skip")
buttonAction = "skip"
// handleAction("prompt")
break;
case "skip":
video.currentTime = seg.segment[1]
video.play()
showPopup(`Skipped ${seg.category}`, "Unskip")
buttonAction = "unskip"
break;
case "unmute":
video.muted = false
showPopup(`Unmuted`, "Mute")
buttonAction = "mute"
break;
case "mute":
video.muted = true
showPopup(`Muted`, "Unmuted")
buttonAction = "unmute"
break;
}
}
function buttonPress() {
const targetSegment = getSegmentById(lastSegmentId)
if (targetSegment && popupVisible())
handleButtonAction(targetSegment, buttonAction)
}
document.addEventListener("keydown", event => {
if (["INPUT", "SELECT", "BUTTON"].includes(event.target.tagName)) return
if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) return
if (event.key == sbSettings.sponsorblock_keybind) {
event.preventDefault()
buttonPress()
}
})
skipPrompt.addEventListener("click", buttonPress)
// Update
video.addEventListener("timeupdate", () => {
const time = video.currentTime
for (const seg of data.sbData)
if (time >= seg.segment[0] && time < seg.segment[1]) {
currentSegment = seg
if (lastSegmentId != currentSegment.UUID) {
if (lastSegmentId)
handleSegmentEnd()
lastSegmentId = currentSegment.UUID
handleSegment()
}
return
}
}, false)
/////
// On page load, add sponsorblock segments to play bar
const regularBackground = "var(--seek-background)"
const highlightBackground = "var(--sponsorblock-segment-{0})"
// We need to update a CSS style. Yes.
let style = document.createElement("style")
style.setAttribute("type", "text/css")
document.head.appendChild(style)
let gradientString = `${regularBackground} `
let amountPassed = 0
for (const segment of data.sbData.sort((a, b) => b.segment[0] - a.segment[0])) {
const regularStop = `${(segment.segment[0] / data.lengthSeconds) * 100}%`
const stop = `${(segment.segment[1] / data.lengthSeconds) * 100}%`
const color = highlightBackground.replace("{0}", segment.category)
gradientString += `${regularStop}, ${color} ${regularStop}, ${color} ${stop}, ${regularBackground} ${stop}, ${regularBackground} `
amountPassed = segment.segment[1]
}
gradientString += `100%`
style.innerHTML = `
.main-video-section .video-container .videoControls .timeline .seek::-webkit-slider-runnable-track {
background-image: linear-gradient(90deg, ${gradientString})
}
.main-video-section .video-container .videoControls .timeline .seek::-moz-range-track {
background-image: linear-gradient(90deg, ${gradientString})
}`