Twitch Multi-Redirect

Redirect Twitch with options

  1. // ==UserScript==
  2. // @name Twitch Multi-Redirect
  3. // @namespace RexOmni
  4. // @version 1.2
  5. // @description Redirect Twitch with options
  6. // @author RexOmniFurtim
  7. // @match https://www.twitch.tv/*
  8. // @exclude https://www.twitch.tv/directory/*
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @run-at document-start
  12. // @noframes
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // if not top frame, stop
  19. if (frameElement) {
  20. return;
  21. }
  22.  
  23. ///////////
  24. // SETUP //
  25. ///////////
  26. let tmr = { };
  27. tmr.intervals = [];
  28. tmr.elements = [];
  29. tmr.options = [
  30. 'TwitchLS',
  31. 'Multitwitch'
  32. ];
  33. tmr.redirects = { // Redirect functions
  34. 'TwitchLS' : ()=> { window.location.replace('http://twitchls.com/' + tmr.channel); },
  35. 'Multitwitch' : ()=>{ window.location.replace('http://multitwitch.tv/' + tmr.channel); }
  36. };
  37.  
  38. tmr.settings = { };
  39. // load settings
  40. tmr.settings.redirectTarget = GM_getValue("tmr-redirectTarget", 'TwitchLS');
  41. tmr.settings.redirectTimer = GM_getValue("tmr-redirectTimer", 2000);
  42.  
  43. tmr.channel = window.location.pathname.substring(1, window.location.pathname.length);
  44.  
  45. ///////////
  46. // START //
  47. ///////////
  48.  
  49. // redirect immediately if redirect set to 0
  50. if(tmr.settings.redirectTimer === 0 && shouldRedirect()){
  51. console.log('redirecting early');
  52. redirect();
  53. return;
  54. }
  55. else{
  56. document.addEventListener("DOMContentLoaded", ()=> {
  57. createBlock();
  58. // If the url says not to redirect, stop the redirect
  59. if( !urlParamRedirect() ){
  60. tmr.elements.container.click();
  61. }
  62. });
  63. }
  64.  
  65. ///////////////
  66. // FUNCTIONS //
  67. ///////////////
  68.  
  69. // redirect to the target
  70. function redirect(){
  71. tmr.redirects[tmr.settings.redirectTarget]();
  72. }
  73.  
  74. function setRedirectTimeout(){
  75. tmr.intervals.redirect = setTimeout(()=>{
  76.  
  77. // if the redirect target function is found is found
  78. if( tmr.redirects[tmr.settings.redirectTarget] !== null ){
  79.  
  80. // let the user know navigation has begun
  81. tmr.elements.warning.style.background = 'black';
  82.  
  83. // activate naviagtion function
  84. redirect();
  85. }
  86. else{
  87. console.log("TMR: redirection target funciton not found");
  88. cancelRedirect();
  89. }
  90. }, tmr.settings.redirectTimer);
  91. }
  92.  
  93. function cancelRedirect(){
  94. clearTimeout(tmr.intervals.redirect);
  95. tmr.intervals.redirect = null;
  96.  
  97. tmr.elements.container.onclick = null;
  98. console.log('%cStopping Redirect', 'background: #3333ff; color: #fff; font-size: 22px;');
  99.  
  100. tmr.elements.warning.style.display = 'none';
  101. tmr.elements.container.style.display = 'none';
  102. tmr.elements.settings.style.display = 'block';
  103.  
  104. addGear();
  105. }
  106.  
  107. function createBlock(){
  108. // create and add div
  109. tmr.elements.container = document.createElement('div');
  110. tmr.elements.container.innerHTML = ' <div style="width:100%;height:100%;position:absolute;background:rgba(255,0,0,0.5);z-index:99999;text-align:center;cursor:pointer;"> <div style="background:white;padding: 2rem;margin: 2rem;"> <p style="font-size:6rem;">Twitch Multi-Redirect</p> <hr style="margin-top: 3rem;"> <div id="TMR-Warning" style="margin-top:2rem;display:block;"> <p style="font-size: 2rem; background: rgba(0,0,255,.4); padding-bottom: 0.5rem;">Click anywhere to stop redirecting</p> </div> <div id="TMR-Settings" style="margin-top:2rem;display:none"> <p style="font-size:4rem;background:rgba(0,125,125,.5);padding-bottom:2rem;padding-top:1rem;">Settings</p> <div style="width: 100%;margin-top: 2rem;"> <span style="padding-right:.7rem">Redirection target</span><select id="TMR-Select"> </select><br><span style="padding-right:.7rem">Wait (ms)</span><input type=Number value=850 id="TMR-Timer"/> <br> <input id="TMR-Savebtn" type="button" value="Save"> </div> </div> </div> </div>';
  111. document.body.insertBefore(tmr.elements.container, document.body.firstChild);
  112.  
  113. tmr.elements.warning = document.getElementById("TMR-Warning");
  114. tmr.elements.settings = document.getElementById("TMR-Settings");
  115. tmr.elements.select = document.getElementById("TMR-Select");
  116. tmr.elements.timer = document.getElementById('TMR-Timer');
  117. tmr.elements.savebtn = document.getElementById('TMR-Savebtn');
  118.  
  119. // populate the drop-down, select
  120. let numOptions = tmr.options.length;
  121. for (let i = 0; i < numOptions; i++) {
  122. let option = document.createElement("option");
  123. option.text = tmr.options[i];
  124. option.value = tmr.options[i];
  125. //option.setAttribute("id", "TMR-" + tmr.options[i]);
  126. tmr.elements.select.add(option);
  127. }
  128.  
  129. // set the setting elements to setting values
  130. // TODO: Get the value of select to equal the right element
  131. //tmr.elements.select.value = document.getElementById("TMR-" + tmr.settings.redirectTarget);
  132. //console.log(document.getElementById("TMR-" + tmr.settings.redirectTarget));
  133. tmr.elements.select.selectedIndex = tmr.options.indexOf(tmr.settings.redirectTarget);
  134. tmr.elements.timer.value = Number(tmr.settings.redirectTimer);
  135.  
  136. // save the selection
  137. tmr.elements.savebtn.onclick = ()=>{
  138. //save the data
  139. GM_setValue("tmr-redirectTarget", tmr.elements.select.value);
  140. GM_setValue("tmr-redirectTimer", tmr.elements.timer.value);
  141. tmr.elements.container.style.display = 'none';
  142. };
  143.  
  144. // start the redirect Timeout
  145. setRedirectTimeout();
  146.  
  147. // on click anywhere stop redirect
  148. tmr.elements.container.onclick = ()=>{cancelRedirect();};
  149. }
  150.  
  151. // Return the redirect url param as bool
  152. function urlParamRedirect(){
  153. let pathArray = /redirect=([^&]+)/.exec(window.location.href);
  154.  
  155. // deault behavior
  156. if (pathArray === null){
  157. return true;
  158. }
  159.  
  160. return ( pathArray[1] === '0' ) ? false : true;
  161. }
  162.  
  163. // Returns whether the page should redirect
  164. // Keep for inclusion of other checks when they are ported.
  165. function shouldRedirect(){
  166. return urlParamRedirect();
  167. }
  168.  
  169. // add the gear when the hcat popup is available
  170. function addGear(){
  171. // wait until chat popup available
  172. let gearInterval = setInterval(()=>{
  173. let chatpopup = document.getElementsByClassName('chat-settings chat-menu dropmenu');
  174. if(chatpopup.length > 0){
  175. clearInterval(gearInterval);
  176. gearInterval = null;
  177.  
  178. tmr.elements.gear = document.createElement('div');
  179. tmr.elements.gear.innerHTML = '<div style="cursor:pointer;background: rgba(237,237,237,0.7);padding: 0.5rem 10rem 0.2rem 1.3rem;"> <img src="data:image/png;base64,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" style=" width: 15%;"> <span style="">TMR Settings</span> </div>';
  180.  
  181. chatpopup[0].insertBefore(tmr.elements.gear, chatpopup[0].firstChild);
  182.  
  183. // Gear onclick function;
  184. tmr.elements.gear.addEventListener('click', ()=>{
  185. tmr.elements.container.style.display = 'block';
  186. });
  187. }
  188. }, 100);
  189. }
  190.  
  191. console.log('%c AutotwitchLS loaded! ', 'background: #333; color: #fff; font-size: 2em;');
  192. })();