state.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { getLikeButton, getDislikeButton, getButtons } from "./buttons";
  2. import { createRateBar } from "./bar";
  3. import { getBrowser, getVideoId, cLog, numberFormat } from "./utils";
  4. import { sendVideoIds } from "./events";
  5. //TODO: Do not duplicate here and in ryd.background.js
  6. const apiUrl = "https://returnyoutubedislikeapi.com";
  7. const LIKED_STATE = "LIKED_STATE";
  8. const DISLIKED_STATE = "DISLIKED_STATE";
  9. const NEUTRAL_STATE = "NEUTRAL_STATE";
  10. const DISLIKES_DISABLED_TEXT = "DISLIKES DISABLED";
  11. let extConfig = {
  12. disableVoteSubmission: false,
  13. };
  14. let storedData = {
  15. likes: 0,
  16. dislikes: 0,
  17. previousState: NEUTRAL_STATE,
  18. };
  19. let likesDisabledState = true;
  20. function isMobile() {
  21. return location.hostname == "m.youtube.com";
  22. }
  23. function isVideoLiked() {
  24. if (isMobile()) {
  25. return (
  26. getLikeButton().querySelector("button").getAttribute("aria-label") ==
  27. "true"
  28. );
  29. }
  30. return getLikeButton().classList.contains("style-default-active");
  31. }
  32. function isVideoDisliked() {
  33. if (isMobile()) {
  34. return (
  35. getDislikeButton().querySelector("button").getAttribute("aria-label") ==
  36. "true"
  37. );
  38. }
  39. return getDislikeButton().classList.contains("style-default-active");
  40. }
  41. function getState(storedData) {
  42. if (isVideoLiked()) {
  43. return { current: LIKED_STATE, previous: storedData.previousState };
  44. }
  45. if (isVideoDisliked()) {
  46. return { current: DISLIKED_STATE, previous: storedData.previousState };
  47. }
  48. return { current: NEUTRAL_STATE, previous: storedData.previousState };
  49. }
  50. //--- Sets The Likes And Dislikes Values ---//
  51. function setLikes(likesCount) {
  52. getButtons().children[0].querySelector("#text").innerText = likesCount;
  53. }
  54. function setDislikes(dislikesCount) {
  55. if (!likesDisabledState) {
  56. if (isMobile()) {
  57. getButtons().children[1].querySelector(
  58. ".button-renderer-text"
  59. ).innerText = dislikesCount;
  60. return;
  61. }
  62. getButtons().children[1].querySelector("#text").innerText = dislikesCount;
  63. } else {
  64. cLog("likes count diabled by creator");
  65. if (isMobile()) {
  66. getButtons().children[1].querySelector(
  67. ".button-renderer-text"
  68. ).innerText = DISLIKES_DISABLED_TEXT;
  69. return;
  70. }
  71. getButtons().children[1].querySelector("#text").innerText =
  72. DISLIKES_DISABLED_TEXT;
  73. }
  74. }
  75. function getLikeCountFromButton() {
  76. let likesStr = getLikeButton()
  77. .querySelector("button")
  78. .getAttribute("aria-label")
  79. .replace(/\D/g, "");
  80. return likesStr.length > 0 ? parseInt(likesStr) : false;
  81. }
  82. function processResponse(response, storedData) {
  83. const formattedDislike = numberFormat(response.dislikes);
  84. setDislikes(formattedDislike);
  85. storedData.dislikes = parseInt(response.dislikes);
  86. storedData.likes = getLikeCountFromButton() || parseInt(response.likes);
  87. createRateBar(storedData.likes, storedData.dislikes);
  88. }
  89. async function setState(storedData) {
  90. storedData.previousState = isVideoDisliked()
  91. ? DISLIKED_STATE
  92. : isVideoLiked()
  93. ? LIKED_STATE
  94. : NEUTRAL_STATE;
  95. let statsSet = false;
  96. let videoId = getVideoId(window.location.href);
  97. let likeCount = getLikeCountFromButton() || null;
  98. let response = await fetch(
  99. `${apiUrl}/votes?videoId=${videoId}&likeCount=${likeCount || ""}`,
  100. {
  101. method: "GET",
  102. headers: {
  103. Accept: "application/json",
  104. },
  105. }
  106. )
  107. .then((response) => response.json())
  108. .catch();
  109. cLog("response from api:");
  110. cLog(JSON.stringify(response));
  111. likesDisabledState =
  112. numberFormat(response.dislikes) == 0 &&
  113. numberFormat(response.likes) == 0 &&
  114. numberFormat(response.viewCount) == 0;
  115. if (response !== undefined && !("traceId" in response) && !statsSet) {
  116. processResponse(response, storedData);
  117. }
  118. }
  119. function setInitialState() {
  120. setState(storedData);
  121. setTimeout(() => {
  122. sendVideoIds();
  123. }, 1500);
  124. }
  125. function initExtConfig() {
  126. initializeDisableVoteSubmission();
  127. }
  128. function initializeDisableVoteSubmission() {
  129. getBrowser().storage.sync.get(["disableVoteSubmission"], (res) => {
  130. if (res.disableVoteSubmission === undefined) {
  131. getBrowser().storage.sync.set({ disableVoteSubmission: false });
  132. } else {
  133. extConfig.disableVoteSubmission = res.disableVoteSubmission;
  134. }
  135. });
  136. }
  137. export {
  138. isMobile,
  139. isVideoDisliked,
  140. isVideoLiked,
  141. getState,
  142. setState,
  143. setInitialState,
  144. setLikes,
  145. setDislikes,
  146. getLikeCountFromButton,
  147. LIKED_STATE,
  148. DISLIKED_STATE,
  149. NEUTRAL_STATE,
  150. extConfig,
  151. initExtConfig,
  152. storedData,
  153. likesDisabledState,
  154. };