Random episode chooser

Highlight a random episode in homepage

  1. // ==UserScript==
  2. // @name Random episode chooser
  3. // @description Highlight a random episode in homepage
  4. // @match https://www.tvtime.com/*
  5. // @version 1.2.2
  6. // @run-at document-end
  7. // @grant none
  8. // @license MIT
  9. // @author Morryx
  10. // @namespace https://greasyfork.org/users/807892
  11. // ==/UserScript==
  12.  
  13. // Direct link (find a way to save it easily, some share place)
  14.  
  15. random = function (max = 1, min = 0) {
  16. return Math.floor(Math.random() * (max - min + 1)) + min;
  17. };
  18. is_numeric = function (c) {
  19. return /^\d+$/.test(c);
  20. };
  21. toint_string = function (str) {
  22. var new_str = '';
  23. if (str == '' || str == null) return 0;
  24. for (i = 0; i < str.length; i++) {
  25. var char = str.charAt(i);
  26. if (is_numeric(char)) new_str += char;
  27. }
  28. return +new_str;
  29. };
  30. addCss = function (code, append) {
  31. if (code !== '') add_css += '' + code;
  32.  
  33. if (typeof append != 'undefined' && append) appendCss();
  34. };
  35. appendCss = function () {
  36. $('#customStyle').remove();
  37. if (add_css !== '')
  38. $body.append($('<style id="customStyle">' + add_css + '</style>'));
  39. };
  40.  
  41. // Settings
  42. var storage_key = 'RandomEpisode_Settings',
  43. default_settings = {
  44. filter: [],
  45. };
  46. save_settings = function (settings) {
  47. window.localStorage.setItem(storage_key, JSON.stringify(settings));
  48. };
  49. clear_settings = function () {
  50. window.localStorage.removeItem(storage_key);
  51. };
  52. get_settings = function () {
  53. var settings = window.localStorage.getItem(storage_key),
  54. default_settings_length = Object.keys(default_settings).length,
  55. last_added_settings = Object.keys(default_settings)[default_settings_length - 1],
  56. key = false;
  57.  
  58. if (settings === null) settings = {};
  59. else settings = JSON.parse(settings);
  60.  
  61. if (!settings.hasOwnProperty(last_added_settings) || default_settings_length != Object.keys(settings).length) {
  62. for (key in default_settings) {
  63. if (!settings.hasOwnProperty(key)) settings[key] = default_settings[key];
  64. }
  65. }
  66.  
  67. for (key in settings) {
  68. if (!default_settings.hasOwnProperty(key)) delete settings[key];
  69. }
  70.  
  71. save_settings(settings);
  72. return settings;
  73. };
  74. change_settings = function (key, value) {
  75. settings[key] = value;
  76. save_settings(settings);
  77. };
  78.  
  79. var settings = get_settings(),
  80. add_css = '',
  81. $body = false;
  82. $(function () {
  83. $body = $('body[id]');
  84. if ($body.hasClass('home')) {
  85. var img_selector = '.image-crop img',
  86. $episodes = $('.to-watch-list').first().find('li[id]'),
  87. previous_show = '',
  88. tries = 0,
  89. get_id_show = function ($episode) {
  90. var id_show = '',
  91. url = $episode.find('.nb-reviews-link.secondary-link').attr('href'),
  92. regex = /\/[0-9]+/g,
  93. founds = url.match(regex);
  94.  
  95. if (founds !== null && founds.length)
  96. id_show = toint_string(founds[0]);
  97.  
  98. return id_show;
  99. },
  100. choose = function () {
  101. var random_episode = random($episodes.length - 1),
  102. $episode = $episodes.eq(random_episode),
  103. id_show = get_id_show($episode);
  104.  
  105. if (settings.filter.includes(id_show) ||
  106. previous_show == id_show) {
  107. tries++;
  108. if (tries < 50)
  109. choose();
  110. return;
  111. }
  112.  
  113. previous_show = id_show;
  114. $episodes
  115. .removeClass('ep_choosed')
  116. .find(img_selector).css('opacity', '0.75');
  117. $episode
  118. .addClass('ep_choosed')
  119. .find('.to-watch-icon').click(function () {
  120. $t = $(this);
  121. setInterval(function () {
  122. if ($t.parent().hasClass('watched'))
  123. location.reload();
  124. }, 2500);
  125. });
  126. },
  127. add_filter = function ($episode) {
  128. var id_show = get_id_show($episode),
  129. txt = 'Add to filter',
  130. filter_class = 'green',
  131. click = function () {
  132. settings.filter.push(id_show);
  133. change_settings('filter', settings.filter);
  134. add_filter($episode);
  135. };
  136.  
  137. if (settings.filter.includes(id_show)) {
  138. txt = 'Remove to filter';
  139. filter_class = 'orange';
  140. click = function () {
  141. var index = settings.filter.indexOf(id_show);
  142. if (index > -1)
  143. settings.filter.splice(index, 1);
  144. change_settings('filter', settings.filter);
  145. add_filter($episode);
  146. };
  147. }
  148.  
  149. var $nav = $episode.find('.nav'),
  150. $filter = $('<a class="filter ' + filter_class + '">' + txt + '</a>');
  151. $nav.find('.filter').remove();
  152. $filter.click(click);
  153. $nav.append($filter);
  154. };
  155.  
  156. $('#home').dblclick(function () {
  157. tries = 0;
  158. $episodes = $('.to-watch-list').first().find('li[id]');
  159. choose();
  160. });
  161. choose();
  162.  
  163. $episodes.each(function () {
  164. add_filter($(this));
  165. });
  166.  
  167. addCss(
  168. '.nav .filter{' +
  169. ' float: left;' +
  170. ' cursor: pointer;' +
  171. '}' +
  172. '.nav .filter.orange{color:orange}' +
  173. '.nav .filter.green{color:green;font-weight:bold}' +
  174. '.ep_choosed{' +
  175. ' transform: translateY(-20px) scale(1.2);' +
  176. ' background-color: #ffd700;' +
  177. ' border-radius: 10px;' +
  178. ' box-shadow: 0 0 10px -5px black;' +
  179. '}' +
  180. '.ep_choosed ' + img_selector + '{opacity:1!important}'
  181. );
  182. }
  183.  
  184. appendCss();
  185. });