212 lines
5.2 KiB
JavaScript
Executable File
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})
|
|
}`
|