presence.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. const presence = new Presence({
  2. clientId: "733216857724682300",
  3. });
  4. let currentURL = new URL(document.location.href),
  5. currentPath = currentURL.pathname.replace(/^\/|\/$/g, "").split("/");
  6. const browsingTimestamp = Math.floor(Date.now() / 1000);
  7. let presenceData: PresenceData = {
  8. details: "Viewing an unsupported page",
  9. largeImageKey:
  10. "https://cdn.rcd.gg/PreMiD/websites/W/Wikinews/assets/logo.png",
  11. startTimestamp: browsingTimestamp,
  12. };
  13. const updateCallback = {
  14. _function: null as () => void,
  15. get function(): () => void {
  16. return this._function;
  17. },
  18. set function(parameter) {
  19. this._function = parameter;
  20. },
  21. get present(): boolean {
  22. return this._function !== null;
  23. },
  24. },
  25. /**
  26. * Initialize/reset presenceData.
  27. */
  28. resetData = (
  29. defaultData: PresenceData = {
  30. details: "Viewing an unsupported page",
  31. largeImageKey:
  32. "https://cdn.rcd.gg/PreMiD/websites/W/Wikinews/assets/logo.png",
  33. startTimestamp: browsingTimestamp,
  34. }
  35. ): void => {
  36. currentURL = new URL(document.location.href);
  37. currentPath = currentURL.pathname.replace(/^\/|\/$/g, "").split("/");
  38. presenceData = { ...defaultData };
  39. },
  40. /**
  41. * Search for URL parameters.
  42. * @param urlParam The parameter that you want to know about the value.
  43. */
  44. getURLParam = (urlParam: string): string => {
  45. return currentURL.searchParams.get(urlParam);
  46. };
  47. ((): void => {
  48. if (currentURL.hostname === "www.wikinews.org")
  49. presenceData.details = "On the home page";
  50. else {
  51. let title: string;
  52. const actionResult = (): string =>
  53. getURLParam("action") || getURLParam("veaction"),
  54. [lang] = currentURL.hostname.split("."),
  55. titleFromURL = (): string => {
  56. return decodeURI(
  57. (currentPath[1] === "index.php"
  58. ? getURLParam("title")
  59. : currentPath.slice(1).join("/")
  60. ).replaceAll("_", " ")
  61. );
  62. };
  63. try {
  64. title = document.querySelector("h1").textContent;
  65. } catch (e) {
  66. title = titleFromURL();
  67. }
  68. /**
  69. * Returns details based on the namespace.
  70. * @link https://en.wikinews.org/wiki/Special:PrefixIndex
  71. */
  72. const namespaceDetails = (): string => {
  73. const details: { [index: string]: string } = {
  74. "-2": "Viewing a media",
  75. "-1": "Viewing a special page",
  76. 0: "Reading a news article",
  77. 1: "Viewing a talk page",
  78. 2: "Viewing a user page",
  79. 3: "Viewing a user talk page",
  80. 4: "Viewing a project page",
  81. 5: "Viewing a project talk page",
  82. 6: "Viewing a file",
  83. 7: "Viewing a file talk page",
  84. 8: "Viewing an interface page",
  85. 9: "Viewing an interface talk page",
  86. 10: "Viewing a template",
  87. 11: "Viewing a template talk page",
  88. 12: "Viewing a help page",
  89. 13: "Viewing a help talk page",
  90. 14: "Viewing a category",
  91. 15: "Viewing a category talk page",
  92. 100: "Viewing a portal",
  93. 101: "Viewing a portal talk page",
  94. 102: "Viewing comments of an article",
  95. 103: "Viewing a comments talk page",
  96. 828: "Viewing a module",
  97. 829: "Viewing a module talk page",
  98. 2300: "Viewing a gadget",
  99. 2301: "Viewing a gadget talk page",
  100. 2302: "Viewing a gadget definition page",
  101. 2303: "Viewing a gadget definition talk page",
  102. 2600: "Viewing a topic",
  103. };
  104. return (
  105. details[
  106. [...document.querySelector("body").classList]
  107. .find(v => /ns--?\d/.test(v))
  108. .slice(3)
  109. ] || "Viewing a page"
  110. );
  111. };
  112. //
  113. // Important note:
  114. //
  115. // When checking for the current location, avoid using the URL.
  116. // The URL is going to be different in other languages.
  117. // Use the elements on the page instead.
  118. //
  119. if (
  120. (
  121. (document.querySelector("#n-mainpage a") ||
  122. document.querySelector("#p-navigation a") ||
  123. document.querySelector(".mw-wiki-logo")) as HTMLAnchorElement
  124. ).href === currentURL.href
  125. )
  126. presenceData.details = "On the main page";
  127. else if (document.querySelector("#wpLoginAttempt"))
  128. presenceData.details = "Logging in";
  129. else if (document.querySelector("#wpCreateaccount"))
  130. presenceData.details = "Creating an account";
  131. else if (document.querySelector(".searchresults")) {
  132. presenceData.details = "Searching for a page";
  133. presenceData.state = (
  134. document.querySelector("input[type=search]") as HTMLInputElement
  135. ).value;
  136. } else if (actionResult() === "history") {
  137. presenceData.details = "Viewing revision history";
  138. presenceData.state = titleFromURL();
  139. } else if (getURLParam("diff")) {
  140. presenceData.details = "Viewing difference between revisions";
  141. presenceData.state = titleFromURL();
  142. } else if (getURLParam("oldid")) {
  143. presenceData.details = "Viewing an old revision of a page";
  144. presenceData.state = titleFromURL();
  145. } else if (
  146. document.querySelector("#ca-ve-edit") ||
  147. getURLParam("veaction")
  148. ) {
  149. presenceData.state = `${
  150. title.toLowerCase() === titleFromURL().toLowerCase()
  151. ? `${title}`
  152. : `${title} (${titleFromURL()})`
  153. }`;
  154. updateCallback.function = (): void => {
  155. if (actionResult() === "edit" || actionResult() === "editsource")
  156. presenceData.details = "Editing a page";
  157. else presenceData.details = namespaceDetails();
  158. };
  159. } else if (actionResult() === "edit") {
  160. presenceData.details = document.querySelector("#ca-edit")
  161. ? "Editing a page"
  162. : "Viewing source";
  163. presenceData.state = titleFromURL();
  164. } else {
  165. presenceData.details = namespaceDetails();
  166. presenceData.state = `${
  167. title.toLowerCase() === titleFromURL().toLowerCase()
  168. ? `${title}`
  169. : `${title} (${titleFromURL()})`
  170. }`;
  171. }
  172. if (lang !== "en") {
  173. if (presenceData.state) presenceData.state += ` (${lang})`;
  174. else presenceData.details += ` (${lang})`;
  175. }
  176. }
  177. })();
  178. if (updateCallback.present) {
  179. const defaultData = { ...presenceData };
  180. presence.on("UpdateData", async () => {
  181. resetData(defaultData);
  182. updateCallback.function();
  183. presence.setActivity(presenceData);
  184. });
  185. } else {
  186. presence.on("UpdateData", async () => {
  187. presence.setActivity(presenceData);
  188. });
  189. }