presence.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. const presence = new Presence({
  2. clientId: "822457774574272592",
  3. }),
  4. getStrings = async () => {
  5. return presence.getStrings(
  6. {
  7. play: "general.playing",
  8. pause: "general.paused",
  9. browse: "general.browsing",
  10. watchingVid: "general.watchingVid",
  11. watching: "general.watching",
  12. search: "general.search",
  13. searchFor: "general.searchFor",
  14. searchSomething: "general.searchSomething",
  15. playingTrivia: "watchmojo.playingTrivia",
  16. trivia: "watchmojo.trivia",
  17. triviaGame: "watchmojo.triviaGame",
  18. article: "general.readingArticle",
  19. category: "general.viewCategory",
  20. viewChannel: "general.viewChannel",
  21. buttonViewChannel: "general.buttonViewChannel",
  22. buttonReadArticle: "general.buttonReadArticle",
  23. buttonWatchVideo: "general.buttonWatchVideo",
  24. buttonPlayTrivia: "watchmojo.buttonPlayTrivia",
  25. },
  26. await presence.getSetting<string>("lang").catch(() => "en")
  27. );
  28. },
  29. capitalize = (s: string) => {
  30. s = s.replace("%20", "-");
  31. if (s.includes("-")) {
  32. let newStr = "";
  33. for (let i = 0; i < s.split("-").length; i++) {
  34. const str = s.split("-")[i];
  35. newStr += `${str.charAt(0).toUpperCase() + str.slice(1)} `;
  36. }
  37. return newStr;
  38. } else return s.charAt(0).toUpperCase() + s.slice(1);
  39. };
  40. let browsingTimestamp = Math.floor(Date.now() / 1000),
  41. prevUrl = document.location.href,
  42. strings: Awaited<ReturnType<typeof getStrings>>,
  43. oldLang: string = null,
  44. iframeDur = 0,
  45. iframeCur = 0,
  46. iframePau = false;
  47. presence.on(
  48. "iFrameData",
  49. (data: {
  50. video: boolean;
  51. duration: number;
  52. currentTime: number;
  53. paused: boolean;
  54. }) => {
  55. if (data.video) {
  56. iframeDur = data.duration;
  57. iframeCur = data.currentTime;
  58. iframePau = data.paused;
  59. }
  60. }
  61. );
  62. presence.on("UpdateData", async () => {
  63. const newLang = await presence.getSetting<string>("lang").catch(() => "en"),
  64. showBrowsing = await presence.getSetting<boolean>("browse"),
  65. showTimestamp = await presence.getSetting<boolean>("timestamp"),
  66. showButtons = await presence.getSetting<boolean>("buttons"),
  67. privacy = await presence.getSetting<boolean>("privacy"),
  68. video = document.querySelector<HTMLVideoElement>("#myDiv_html5");
  69. let presenceData: PresenceData = {
  70. largeImageKey:
  71. "https://cdn.rcd.gg/PreMiD/websites/W/WatchMojo/assets/logo.jpg",
  72. };
  73. if (document.location.href !== prevUrl) {
  74. prevUrl = document.location.href;
  75. browsingTimestamp = Math.floor(Date.now() / 1000);
  76. }
  77. if (oldLang !== newLang || !strings) {
  78. oldLang = newLang;
  79. strings = await getStrings();
  80. }
  81. const statics: {
  82. [name: string]: PresenceData;
  83. } = {
  84. "/": {
  85. details: strings.browse,
  86. },
  87. "/video/id/(\\d*)/": {
  88. details: privacy ? strings.watchingVid : strings.watching,
  89. state: privacy
  90. ? null
  91. : document.querySelector(".brid-poster-title")?.textContent,
  92. smallImageKey: video?.paused ? Assets.Pause : Assets.Play,
  93. smallImageText: video?.paused ? strings.pause : strings.play,
  94. startTimestamp: video?.paused
  95. ? null
  96. : video
  97. ? presence.getTimestampsfromMedia(video)[0]
  98. : null,
  99. endTimestamp: video?.paused
  100. ? null
  101. : video
  102. ? presence.getTimestampsfromMedia(video)[1]
  103. : null,
  104. buttons: [{ label: strings.buttonWatchVideo, url: document.URL }],
  105. },
  106. "/trivia/": {
  107. details: privacy
  108. ? strings.playingTrivia
  109. : strings.trivia.replace(
  110. "{0}",
  111. document.querySelector("#yttitle")?.textContent
  112. ),
  113. state: privacy
  114. ? null
  115. : strings.triviaGame
  116. .replace(
  117. "{0}",
  118. document
  119. .querySelector("#questnum")
  120. ?.textContent.split("of")[0]
  121. .split(" ")[1]
  122. .trim()
  123. )
  124. .replace(
  125. "{1}",
  126. document
  127. .querySelector("#questnum")
  128. ?.textContent.split("of")[1]
  129. .split(" ")[1]
  130. .trim()
  131. )
  132. .replace(
  133. "{2}",
  134. document
  135. .querySelector(".scorequiz > b")
  136. ?.textContent.split("/")[0]
  137. .split(" ")[2]
  138. )
  139. .replace(
  140. "{3}",
  141. document
  142. .querySelector(".scorequiz > b")
  143. ?.textContent.split("/")[1]
  144. ),
  145. smallImageKey: iframePau ? Assets.Pause : Assets.Play,
  146. smallImageText: iframePau ? strings.pause : strings.play,
  147. startTimestamp: iframePau
  148. ? 0
  149. : presence.getTimestamps(iframeCur, iframeDur)[0],
  150. endTimestamp: iframePau
  151. ? 0
  152. : presence.getTimestamps(iframeCur, iframeDur)[1],
  153. buttons: [{ label: strings.buttonPlayTrivia, url: document.URL }],
  154. },
  155. "/blog/(\\d*)/(\\d*)/(\\d*)/": {
  156. details: strings.article,
  157. state: document.querySelector("h1")?.textContent,
  158. buttons: [{ label: strings.buttonReadArticle, url: document.URL }],
  159. },
  160. "/categories/": {
  161. details: strings.category,
  162. state:
  163. typeof location.pathname.split("/")[2] === "string"
  164. ? capitalize(location.pathname.split("/")[2])
  165. : "NEEDS RESET",
  166. },
  167. "/channels/": {
  168. details: strings.viewChannel,
  169. state: location.pathname.split("/")[2],
  170. buttons: [{ label: strings.buttonViewChannel, url: document.URL }],
  171. },
  172. "/search/": {
  173. details: strings.searchFor,
  174. state:
  175. document.querySelector("#result > div > b:nth-child(2)")?.textContent ||
  176. document.querySelector("#resultd > a > span")?.textContent,
  177. smallImageKey: Assets.Search,
  178. smallImageText: strings.search,
  179. },
  180. };
  181. if (showTimestamp) presenceData.startTimestamp = browsingTimestamp;
  182. if (showBrowsing) {
  183. for (const [k, v] of Object.entries(statics)) {
  184. if (
  185. location.href
  186. .replace(/\/?$/, "/")
  187. .replace(`https://${document.location.hostname}`, "")
  188. .replace("?", "/")
  189. .replace("=", "/")
  190. .match(k)
  191. ) {
  192. presenceData.smallImageKey = Assets.Reading;
  193. presenceData.smallImageText = strings.browse;
  194. presenceData = { ...presenceData, ...v };
  195. }
  196. }
  197. }
  198. if (privacy && presenceData.smallImageKey === Assets.Search) {
  199. presenceData.details = strings.searchSomething;
  200. delete presenceData.state;
  201. } else if (privacy && presenceData.smallImageKey === Assets.Reading) {
  202. presenceData.details = strings.browse;
  203. delete presenceData.state;
  204. }
  205. if (!showButtons || privacy) delete presenceData.buttons;
  206. if (!presenceData.details) delete presenceData.details;
  207. if (!presenceData.state) delete presenceData.state;
  208. if (!presenceData.startTimestamp) delete presenceData.startTimestamp;
  209. if (!presenceData.endTimestamp) delete presenceData.endTimestamp;
  210. if (!presenceData.details) presence.setActivity();
  211. else presence.setActivity(presenceData);
  212. });