diff --git a/content.css b/content.css index 1d118fcf..c05f2f16 100644 --- a/content.css +++ b/content.css @@ -1,3 +1,21 @@ +#previewbar { + overflow: visible; + padding: 0; + margin: 0; + position: absolute; + width: 100%; + pointer-events: none; + + height: 100%; + transform: scaleY(0.6) translateY(-30%) translateY(1.5px); + z-index: 40; +} + +.previewbar { + display: inline-block; + height: 100%; +} + .popup { z-index: 10; width: 100%; diff --git a/content.js b/content.js index 3ee26aeb..1e1d5d2a 100644 --- a/content.js +++ b/content.js @@ -19,6 +19,10 @@ var channelURL; //is this channel whitelised from getting sponsors skipped var channelWhitelisted = false; +// create preview bar +let progressBar = document.getElementsByClassName("ytp-progress-bar-container")[0] || document.getElementsByClassName("no-model cue-range-markers")[0]; +var previewBar = new PreviewBar(progressBar); + if(id = getYouTubeVideoID(document.URL)){ // Direct Links videoIDChange(id); } @@ -310,6 +314,10 @@ function sponsorsLookup(id) { sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes; UUIDs = JSON.parse(xmlhttp.responseText).UUIDs; + //update the preview bar + //leave the type blank for now until categories are added + previewBar.set(sponsorTimes, [], v.duration); + getChannelID(); sponsorLookupRetries = 0; diff --git a/manifest.json b/manifest.json index 23204e4b..cc9f4000 100644 --- a/manifest.json +++ b/manifest.json @@ -11,6 +11,7 @@ "all_frames": true, "js": [ "config.js", + "utils/previewBar.js", "utils.js", "content.js", "popup.js" diff --git a/utils/previewBar.js b/utils/previewBar.js new file mode 100644 index 00000000..95454e9d --- /dev/null +++ b/utils/previewBar.js @@ -0,0 +1,86 @@ +/* + This is based on code from VideoSegments. + https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd51f62a4e7fef4d4/segmentsbar/segmentsbar.js +*/ + +'use strict'; + +let barTypes = { + "undefined": { + color: "#00d400", + opacity: "0.5" + }, + "sponsor": { + color: "#00d400", + opacity: "0.5" + } +}; + +class PreviewBar { + constructor(parent) { + this.container = document.createElement('ul'); + this.container.id = 'previewbar'; + this.parent = parent; + this.bars = [] + + this.updatePosition(); + } + + updatePosition() { + //below the seek bar + // this.parent.insertAdjacentElement("afterEnd", this.container); + + //on the seek bar + this.parent.insertAdjacentElement("afterBegin", this.container); + } + + updateColor(segment, color, opacity) { + let bars = document.querySelectorAll('[data-vs-segment-type=' + segment + ']'); + for (let bar of bars) { + bar.style.backgroundColor = color; + bar.style.opacity = opacity; + } + } + + set(timestamps, types, duration) { + while (this.container.firstChild) { + this.container.removeChild(this.container.firstChild); + } + + if (!timestamps || !types) { + return; + } + + // to avoid rounding error resulting in width more than 100% + duration = Math.floor(duration * 100) / 100; + let width; + for (let i = 0; i < timestamps.length; i++) { + width = (timestamps[i][1] - timestamps[i][0]) / duration * 100; + width = Math.floor(width * 100) / 100; + + let bar = this.createBar(); + bar.setAttribute('data-vs-segment-type', types[i]); + + bar.style.backgroundColor = barTypes[types[i]].color; + bar.style.opacity = barTypes[types[i]].opacity; + bar.style.width = width + '%'; + bar.style.left = (timestamps[i][0] / duration * 100) + "%"; + bar.style.position = "absolute" + + this.container.insertAdjacentElement('beforeEnd', bar); + this.bars[i] = bar; + } + } + + createBar() { + let bar = document.createElement('li'); + bar.classList.add('previewbar'); + bar.innerHTML = ' '; + return bar; + } + + remove() { + this.container.remove(); + this.container = undefined; + } +} \ No newline at end of file