ryd.content-script.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import {
  2. getButtons,
  3. getLikeButton,
  4. getDislikeButton,
  5. checkForSignInButton,
  6. } from "./src/buttons";
  7. import {
  8. isMobile,
  9. isVideoDisliked,
  10. isVideoLiked,
  11. getState,
  12. setLikes,
  13. setDislikes,
  14. getLikeCountFromButton,
  15. LIKED_STATE,
  16. DISLIKED_STATE,
  17. NEUTRAL_STATE,
  18. } from "./src/state";
  19. import { numberFormat, getBrowser, cLog } from "./src/utils";
  20. import { createRateBar } from "./src/bar";
  21. let storedData = {
  22. likes: 0,
  23. dislikes: 0,
  24. previousState: NEUTRAL_STATE,
  25. };
  26. function processResponse(response) {
  27. const formattedDislike = numberFormat(response.dislikes);
  28. setDislikes(formattedDislike);
  29. storedData.dislikes = parseInt(response.dislikes);
  30. storedData.likes = getLikeCountFromButton() || parseInt(response.likes);
  31. createRateBar(storedData.likes, storedData.dislikes);
  32. }
  33. function setState() {
  34. storedData.previousState = isVideoDisliked()
  35. ? DISLIKED_STATE
  36. : isVideoLiked()
  37. ? LIKED_STATE
  38. : NEUTRAL_STATE;
  39. let statsSet = false;
  40. getBrowser().runtime.sendMessage(
  41. {
  42. message: "set_state",
  43. videoId: getVideoId(window.location.href),
  44. state: getState(storedData).current,
  45. likeCount: getLikeCountFromButton() || null,
  46. },
  47. function (response) {
  48. cLog("response from api:");
  49. cLog(JSON.stringify(response));
  50. if (response !== undefined && !("traceId" in response) && !statsSet) {
  51. processResponse(response);
  52. } else {
  53. }
  54. }
  55. );
  56. }
  57. function sendVote(vote) {
  58. getBrowser().runtime.sendMessage({
  59. message: "send_vote",
  60. vote: vote,
  61. videoId: getVideoId(window.location.href),
  62. });
  63. }
  64. function likeClicked() {
  65. if (checkForSignInButton() === false) {
  66. if (storedData.previousState === DISLIKED_STATE) {
  67. sendVote(1);
  68. storedData.dislikes--;
  69. storedData.likes++;
  70. createRateBar(storedData.likes, storedData.dislikes);
  71. setDislikes(numberFormat(storedData.dislikes));
  72. storedData.previousState = LIKED_STATE;
  73. } else if (storedData.previousState === NEUTRAL_STATE) {
  74. sendVote(1);
  75. storedData.likes++;
  76. createRateBar(storedData.likes, storedData.dislikes);
  77. storedData.previousState = LIKED_STATE;
  78. } else if ((storedData.previousState = LIKED_STATE)) {
  79. sendVote(0);
  80. storedData.likes--;
  81. createRateBar(storedData.likes, storedData.dislikes);
  82. storedData.previousState = NEUTRAL_STATE;
  83. }
  84. }
  85. }
  86. function dislikeClicked() {
  87. if (checkForSignInButton() == false) {
  88. if (storedData.previousState === NEUTRAL_STATE) {
  89. sendVote(-1);
  90. storedData.dislikes++;
  91. setDislikes(numberFormat(storedData.dislikes));
  92. createRateBar(storedData.likes, storedData.dislikes);
  93. storedData.previousState = DISLIKED_STATE;
  94. } else if (storedData.previousState === DISLIKED_STATE) {
  95. sendVote(0);
  96. storedData.dislikes--;
  97. setDislikes(numberFormat(storedData.dislikes));
  98. createRateBar(storedData.likes, storedData.dislikes);
  99. storedData.previousState = NEUTRAL_STATE;
  100. } else if (storedData.previousState === LIKED_STATE) {
  101. sendVote(-1);
  102. storedData.likes--;
  103. storedData.dislikes++;
  104. setDislikes(numberFormat(storedData.dislikes));
  105. createRateBar(storedData.likes, storedData.dislikes);
  106. storedData.previousState = DISLIKED_STATE;
  107. }
  108. }
  109. }
  110. function setInitialState() {
  111. setState();
  112. setTimeout(() => {
  113. sendVideoIds();
  114. }, 1500);
  115. }
  116. function getVideoId(url) {
  117. const urlObject = new URL(url);
  118. const pathname = urlObject.pathname;
  119. if (pathname.startsWith("/clip")) {
  120. return document.querySelector("meta[itemprop='videoId']").content;
  121. } else {
  122. return urlObject.searchParams.get("v");
  123. }
  124. }
  125. function isVideoLoaded() {
  126. const videoId = getVideoId(window.location.href);
  127. return (
  128. document.querySelector(`ytd-watch-flexy[video-id='${videoId}']`) !== null ||
  129. // mobile: no video-id attribute
  130. document.querySelector('#player[loading="false"]:not([hidden])') !== null
  131. );
  132. }
  133. let jsInitChecktimer = null;
  134. function setEventListeners(evt) {
  135. function checkForJS_Finish() {
  136. if (getButtons()?.offsetParent && isVideoLoaded()) {
  137. clearInterval(jsInitChecktimer);
  138. jsInitChecktimer = null;
  139. const buttons = getButtons();
  140. if (!window.returnDislikeButtonlistenersSet) {
  141. buttons.children[0].addEventListener("click", likeClicked);
  142. buttons.children[1].addEventListener("click", dislikeClicked);
  143. window.returnDislikeButtonlistenersSet = true;
  144. }
  145. setInitialState();
  146. }
  147. }
  148. if (window.location.href.indexOf("watch?") >= 0) {
  149. jsInitChecktimer = setInterval(checkForJS_Finish, 111);
  150. }
  151. }
  152. function sendVideoIds() {
  153. let links = Array.from(
  154. document.getElementsByClassName(
  155. "yt-simple-endpoint ytd-compact-video-renderer"
  156. )
  157. ).concat(
  158. Array.from(
  159. document.getElementsByClassName("yt-simple-endpoint ytd-thumbnail")
  160. )
  161. );
  162. // Also try mobile
  163. if (links.length < 1)
  164. links = Array.from(
  165. document.querySelectorAll(
  166. ".large-media-item-metadata > a, a.large-media-item-thumbnail-container"
  167. )
  168. );
  169. const ids = links
  170. .filter((x) => x.href && x.href.indexOf("/watch?v=") > 0)
  171. .map((x) => getVideoId(x.href));
  172. getBrowser().runtime.sendMessage({
  173. message: "send_links",
  174. videoIds: ids,
  175. });
  176. }
  177. setEventListeners();
  178. document.addEventListener("yt-navigate-finish", function (event) {
  179. if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer);
  180. window.returnDislikeButtonlistenersSet = false;
  181. setEventListeners();
  182. });
  183. setTimeout(() => sendVideoIds(), 2500);