// ==UserScript==
// @name stream4chan
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Click the button to stream all webms in a 4chan thread
// @author Lauchlan105
// @match http://boards.4chan.org/*/thread/*
// @grant none
// @downloadURL none
// ==/UserScript==
//Settings Header
countStep = 1;
modalSettings_auto = '
Play Automatically';
modalSettings_webms = ' Play Webms';
modalSettings_gifs = ' Play Gifs';
modalSettings_loopAll = ' Loop whole thread';
modalSettings_shuffle = ' Randomize';
modalSettings_duration = ' Gif Duration (Seconds)';
modalSettings = '' + modalSettings_auto + modalSettings_webms + modalSettings_gifs + modalSettings_loopAll + modalSettings_shuffle + modalSettings_duration + '
';
//Content Table
modalContent = '';
modalContent_Left = ' | ';
modalContent_Right = ' | ';
modalContent_Mid = '' + modalSettings + modalContent + ' | ';
modalTable = '' + modalContent_Left + modalContent_Mid + modalContent_Right + '
';
//Main Div
startBtn = '';
resumeBtn = '';
modalMain = '' + modalTable + '
';
//CSS
settingsCSS = '.SFC-settings { opacity: 0.35; display: inline-block; list-style-type: none; width:100%; top: 0; height: 25px; margin: 0em; padding: 0em } .SFC-settings:hover { opacity: 1; }';
settingsLiCSS = '.SFC-li { display: inline-block; padding-left: 1em; color:#9d9393;}';
settingsInputCSS = '.SFC-input { margin: 0em; padding: 0em; padding-top: 0.3em; width: auto; }';
AllSettingsCSS = settingsCSS + settingsLiCSS + settingsInputCSS;
//table
tableCSS = '.SFC_table { max-height: 100vh; min-height: 100vh; max-width: 100vw; min-width: 100vw; } ';
tableRowCSS = '.SFC_table_row { vertical-align: top; }';
arrowCSS = '.SFC_arrow { width: 15px; padding: 15px; height: 100%; background-image: url("http://www.dsetechnology.co.uk/images/disclose-arrow.png"); background-repeat: no-repeat; background-position: center; background-color: rgba(255, 255, 255, 0); background-size: contain; }';
leftCSS = '.SFC_th_left { transform: rotate(180deg); }' + '.SFC_th_left:hover { background-color:rgba(255, 255, 255, 0.6); }';
rightCSS = '.SFC_th_right { }' + '.SFC_th_right:hover { background-color:rgba(255, 255, 255, 0.6); }';
midCSS = '.SFC_th_mid { height: 100vh; }';
allTableCSS = tableCSS + tableRowCSS + arrowCSS + leftCSS + rightCSS + midCSS;
mediaCSS = '.SFC-media { width: 100%; }';
contentCSS = '.SFC-content { display: block; color: white; }';
modalCSS = ' .SFC-modal { display: none; height: 100vh; width: 100vw; position: fixed; z-index: 1; left: 0; top: 0; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); -moz-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75);}';
allModalCSS = mediaCSS + contentCSS + modalCSS;
allCSS = '';
//Media Elements
gifDiv = '
';
webmDiv = '';
//Main
(function() {
injectNewElements();
initVars();
currentVideo = 0;
window.onclick = function(event){if (event.target.id == 'stream4chan-content') { end(); }};
window.onresize = function(){ };
//event for key strokes
document.onkeyup = function(event){
//left arrow
if(event.keyCode == 37 && document.getElementById('stream4chan-modal').style.display == 'block'){
console.log(document.getElementById('stream4chan-modal').style.display);
previousVideo();
//right arrow
}else if(event.keyCode == 39 && document.getElementById('stream4chan-modal').style.display == 'block'){
console.log(document.getElementById('stream4chan-modal').style.display);
nextVideo();
//Escape key
}else if(event.keyCode == 27 && document.getElementById('stream4chan-modal').style.display == 'block'){
end();
//W key
}else if(event.keyCode == 87 && document.getElementById('stream4chan-modal').style.display == 'block'){
playWebms.checked = !playWebms.checked;
//G key
}else if(event.keyCode == 71 && document.getElementById('stream4chan-modal').style.display == 'block'){
playGifs.checked = !playGifs.checked;
//A key
}else if(event.keyCode == 65 && document.getElementById('stream4chan-modal').style.display == 'block'){
autoplay.checked = !autoplay.checked;
//L key
}else if(event.keyCode == 76 && document.getElementById('stream4chan-modal').style.display == 'block'){
loopAll.checked = !loopAll.checked;
//R key
}else if(event.keyCode == 82 && document.getElementById('stream4chan-modal').style.display == 'block'){
random.checked = !random.checked;
}else{
//console.log(event.keyCode);
}
};
document.onkeydown = function(event){
//up arrow
if(event.keyCode == 38 && document.getElementById('stream4chan-modal').style.display == 'block'){
val = parseInt(duration.value, 10);
max = parseInt(duration.max, 10);
val += countStep;
if(val > max){ val = max; }
duration.value = val;
//Down arrow
}else if(event.keyCode == 40 && document.getElementById('stream4chan-modal').style.display == 'block'){
val = parseInt(duration.value, 10);
min = parseInt(duration.min, 10);
val -= countStep;
if(val < min){ val = min; }
duration.value = val;
}
};
startButton.onclick = function(){ start(); };
resumeButton.onclick = function(){ initVars(); start(currentVideo, media.time); };
autoplay.onclick = function(){ updateAutoplay(); };
shuffle.onclick = function(){ initVars(); };
prevBtn.onclick = function(){ previousVideo(); };
nextBtn.onclick = function(){ nextVideo(); };
})();
//insert elements to html doc
function injectNewElements(){
//add start slideshow button to navs
var nav = document.getElementsByClassName("navLinks desktop");
var i;
if(nav){
for(i = 0; i < nav.length; i++){
nav[i].innerHTML += startBtn + resumeBtn;
}
}
//add the modal to thread
var target = document.getElementsByClassName('thread');
for(i = 0; i < target.length; i++){
target[i].innerHTML += modalMain + allCSS;
}
}
//Assign the elemens that don't change to vars
function initVars(){
modal = document.getElementById('stream4chan-modal');
//if(!modal){ console.log('modal not found!');}
startButton = document.getElementById('stream4chan-start');
//if(!startButton){ console.log('Start button not found!');}
resumeButton = document.getElementById('stream4chan-continue');
//if(!resumeButton){ console.log('Resume button not found!');}
table = document.getElementById('stream4chan-table');
//if(!table){ console.log('table not found!');}
prevBtn = document.getElementById('stream4chan-prev');
//if(!prevBtn){ console.log('"Previous" button not found!');}
content = document.getElementById('stream4chan-content');
//if(!content){ console.log('content not found!');}
nextBtn = document.getElementById('stream4chan-next');
//if(!nextBtn){ console.log('"Next" button not found!');}
media = document.getElementById('stream4chan-webm');
if(!media){ media = document.getElementById('stream4chan-gif'); }
//if(!media){ console.log('"Media" could not be found!'); }
//Settings
settings = document.getElementById('stream4chan-settings');
//if(!settings){ console.log('"Settings" could not be found!'); }
autoplay = document.getElementById('stream4chan-auto?');
//if(!autoplay){ console.log('Autoplay checkbox not found!');}
playWebms = document.getElementById('stream4chan-webms?');
//if(!playWebms){ console.log('Player Webms input not found!');}
playGifs = document.getElementById('stream4chan-gifs?');
//if(!playGifs){ console.log('Player Gifs input not found!');}
loopAll = document.getElementById('stream4chan-loopAll?');
//if(!loopAll){ console.log('"loopAll" could not be found!'); }
random = document.getElementById('stream4chan-shuffle?');
//if(!random){ console.log('"random" could not be found!'); }
playSelected = document.getElementById('stream4chan-playSelected?');
//if(!playSelected){ console.log('"play selected" could not be found!'); }
duration = document.getElementById('stream4chan-duration?');
//if(!duration){ console.log('Gif duration input not found!');}
//Misc
currentTimeout = setTimeout(function(){}, (0));
contentHrefs = document.getElementsByClassName("fileThumb");
if(random.selected){ shuffle(contentHrefs); }
}
//start show
function start(position, time) {
initVars();
displayModal();
currentTime = 0;
currentVideo = 0;
if(position){ currentVideo = position - 1; }
if(time){ currentTime = time; }
nextVideo();
}
//end show
function end() {
initVars();
modal.style.display = "none";
var videoToPause = document.getElementById("stream4chan-webm");
if(media){ currentTime = media.currentTime; }
if(videoToPause){ videoToPause.pause(); }
clearTimeout();
var body = document.getElementsByTagName('body');
for(i = 0; i < body.length; i++){
if(body[i]){ body[i].style.overflow = "scroll"; }
}
}
//Display the contents
function displayModal(){
content.innerHTML = '';
modal.style.display = "block";
calcHeight();
content.innerHTML = 'No Video is Playing
';
var body = document.getElementsByTagName('body');
for(i = 0; i < body.length; i++){
if(body[i]){ body[i].style.overflow = "hidden"; }
}
}
//Loads element based on URL
function displayVideo(href){
filetype = getFiletype(href);
media = document.getElementById("stream4chan-" + filetype);
//create media if it's not there
if(!media){
if(filetype == 'gif'){
content.innerHTML = gifDiv;
}else if(filetype == 'webm'){
content.innerHTML = webmDiv;
}
media = document.getElementById("stream4chan-" + filetype);
}
//change to new source, readjust the heigh, resume from last place
media.src = href;
initVars();
calcHeight();
if(filetype == 'webm'){
media.onplay = function(){ calcHeight(); };
media.currentTime = currentTime;
}
}
//play next video
function nextVideo(){
initVars();
//If out of range
if(0 > currentVideo || currentVideo > contentHrefs.length - 1){
if(loopAll.checked){
if(currentVideo < 0){
currentVideo = contentHrefs.length - 1;
}else{
currentVideo = 0;
}
}else{
console.log('out of range');
end();
displayModal();
return;
}
}
//Get filetype -> If its a gif and gifs are asked not to play -> return
filetype = getFiletype(contentHrefs[currentVideo]);
//skip if it can't play the current file
if(!canPlay(currentVideo)){
currentVideo++;
nextVideo();
return;
}
displayVideo(contentHrefs[currentVideo]);
updateAutoplay();
// increment the currentVideo
currentVideo++;
}
//call next video when valid previous video is found
function previousVideo(){
initVars();
currentVideo--;
while(currentVideo > -1){
if(canPlay(currentVideo--)){ break; }
}
nextVideo();
}
//Returns true if current video is gif and gifs are selected etc
function canPlay(arrPosition){
var currType = getFiletype(contentHrefs[arrPosition]);
return !((currType == "gif" && !playGifs.checked) || (currType == "webm" && !playWebms.checked));
}
//Update timeouts and listeners to loop media
function updateAutoplay(){
initVars();
if(media){
filename = getFiletype(media.src);
if(filename == 'gif'){
if(autoplay.checked){
clearTimeout();
currentTimeout = setTimeout(function(){
nextVideo();
}, (duration.value*1000));
}else{
clearTimeout();
}
}else if(filename == 'webm'){
media.loop = !autoplay.checked;
clearTimeout();
media.removeEventListener('ended', function(){ currentTime = 0; nextVideo();}, false);
if(autoplay.checked){
media.addEventListener('ended', function(){ currentTime = 0; nextVideo();}, false);
}
}else{
console.log("Not a valid type! call to update autoplay");
}
}
calcHeight();
}
//Clear Timeout functions to avoid related function calls
function clearTimeout(){
if(currentTimeout){
while(currentTimeout > 0){
currentTimeout--;
window.clearTimeout(currentTimeout);
}
}
}
//Return file extension type
function getFiletype(input){
href = input.toString();
return href.substr(href.lastIndexOf('.') + 1);
}
//Recalc height of content div to fit properly
function calcHeight(){
initVars();
content.style.height = window.innerHeight - settings.offsetHeight + "px";
if(media){
if(media.offsetHeight > (window.innerHeight - settings.offsetHeight)){
media.style.height = '100%';
media.style.width = 'auto';
}
if(media.offsetWidth > (window.innerWidth - (prevBtn.offsetWidth + nextBtn.offsetWidth))){
media.style.width = '100%';
media.style.height = 'auto';
}
}
}
//Shuffles the array of hrefs
function shuffle(input) {
for (var i = input.length-1; i >=0; i--) {
var randomIndex = Math.floor(Math.random()*(i+1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
}