presence.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. const presence = new Presence({
  2. clientId: "691080074006495303",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. const enum Assets {
  6. Logo = "https://cdn.rcd.gg/PreMiD/websites/N/Nuxt.js/assets/0.png",
  7. }
  8. async function getStrings() {
  9. return presence.getStrings(
  10. {
  11. browse: "general.browsing",
  12. search: "general.searchFor",
  13. viewHome: "general.viewHome",
  14. buttonReadArticle: "general.buttonReadArticle",
  15. buttonViewPage: "general.buttonViewPage",
  16. buttonViewProfile: "general.buttonViewProfile",
  17. },
  18. await presence.getSetting<string>("lang").catch(() => "en")
  19. );
  20. }
  21. function capitalizeFirstLetter(string: string) {
  22. if (!string) return "Undefined";
  23. return (
  24. string.trim().charAt(0).toUpperCase() + string.trim().slice(1).toLowerCase()
  25. );
  26. }
  27. function imgPath(path: string, hostname: string) {
  28. if (!path) return Assets.Logo;
  29. if (path.includes(hostname)) return `https://${path.replace("//", "")}`;
  30. else return `https://${hostname}${path}`;
  31. }
  32. let strings: Awaited<ReturnType<typeof getStrings>>,
  33. oldLang: string = null;
  34. presence.on("UpdateData", async () => {
  35. let presenceData: PresenceData = {
  36. startTimestamp: browsingTimestamp,
  37. largeImageKey: Assets.Logo,
  38. };
  39. const [newLang, privacy, buttons, covers] = await Promise.all([
  40. presence.getSetting<string>("lang").catch(() => "en"),
  41. presence.getSetting<boolean>("privacy"),
  42. presence.getSetting<boolean>("buttons"),
  43. presence.getSetting<boolean>("covers"),
  44. ]),
  45. search = document.querySelector<HTMLInputElement>(
  46. 'input[id="docsearch-input"]'
  47. ),
  48. ogTitle = document
  49. .querySelector('meta[property="og:title"]')
  50. ?.getAttribute("content")
  51. ?.toLowerCase(),
  52. docTitle = document.querySelector('[class="d-heading-title"]'),
  53. subActive = document.querySelector('[class*="-text-active"]'),
  54. docusContent = !document.querySelector('[class*="docus-content"]'),
  55. { pathname, hostname, href } = document.location;
  56. if (oldLang !== newLang || !strings) {
  57. oldLang = newLang;
  58. strings = await getStrings();
  59. }
  60. if (privacy) {
  61. presenceData.details = strings.browse;
  62. presence.setActivity(presenceData);
  63. return;
  64. }
  65. if (search?.value) {
  66. presenceData.details = strings.search;
  67. presenceData.state = search.value;
  68. presenceData.smallImageKey = Assets.Search;
  69. presence.setActivity(presenceData);
  70. return;
  71. }
  72. switch (pathname.split("/")[1].replace(/-/gm, "")) {
  73. case "casestudies": {
  74. if (!docusContent) {
  75. presenceData.smallImageKey = Assets.Reading;
  76. presenceData.details = "Reading a case studie about";
  77. presenceData.state = ogTitle;
  78. presenceData.buttons = [
  79. {
  80. label: "Read Case Studie",
  81. url: href,
  82. },
  83. ];
  84. } else presenceData.details = "Viewing all case studies";
  85. break;
  86. }
  87. case "deployments": {
  88. if (!docusContent) {
  89. presenceData.smallImageKey = Assets.Reading;
  90. presenceData.details = `Reading about ${ogTitle} nuxt deployment`;
  91. if (subActive?.textContent) presenceData.state = subActive.textContent;
  92. presenceData.buttons = [
  93. {
  94. label: strings.buttonReadArticle,
  95. url: href,
  96. },
  97. ];
  98. } else presenceData.details = "Viewing all deployment options";
  99. break;
  100. }
  101. case "announcements": {
  102. if (!docusContent) {
  103. presenceData.smallImageKey = Assets.Reading;
  104. presenceData.details = "Reading announcement about";
  105. if (subActive?.textContent)
  106. presenceData.state = `${ogTitle} - ${subActive.textContent}`;
  107. else presenceData.state = ogTitle;
  108. presenceData.buttons = [
  109. {
  110. label: strings.buttonReadArticle,
  111. url: href,
  112. },
  113. ];
  114. presenceData.largeImageKey = imgPath(
  115. document.querySelector('[class="object-cover"]')?.getAttribute("src"),
  116. hostname
  117. );
  118. } else presenceData.details = "Viewing all announcements";
  119. break;
  120. }
  121. case "docs": {
  122. if (!docusContent && docTitle) {
  123. presenceData.details = "Reading documentation about";
  124. presenceData.state = `${document
  125. .querySelector('li[class="active"] > h5')
  126. ?.textContent?.trim()} - ${docTitle.textContent}`;
  127. presenceData.buttons = [
  128. {
  129. label: strings.buttonReadArticle,
  130. url: href,
  131. },
  132. ];
  133. } else presenceData.details = "Browsing the docs";
  134. break;
  135. }
  136. case "examples": {
  137. if (!docusContent && docTitle) {
  138. presenceData.details = "Viewing an example about";
  139. presenceData.state = `${document
  140. .querySelector('li[class="active"] > h5')
  141. ?.textContent?.trim()} - ${docTitle.textContent}`;
  142. presenceData.buttons = [
  143. {
  144. label: strings.buttonReadArticle,
  145. url: href,
  146. },
  147. ];
  148. } else presenceData.details = "Browsing examples";
  149. break;
  150. }
  151. case "tutorials": {
  152. if (!docusContent) {
  153. presenceData.details = "Reading a tutorial about";
  154. presenceData.state = capitalizeFirstLetter(ogTitle);
  155. presenceData.buttons = [
  156. {
  157. label: "View Tutorial",
  158. url: href,
  159. },
  160. ];
  161. } else presenceData.details = "Viewing all tutorials";
  162. break;
  163. }
  164. default: {
  165. const pages: Record<string, PresenceData> = {
  166. "": {
  167. details: strings.viewHome,
  168. },
  169. design: {
  170. details: "Viewing design options",
  171. },
  172. faq: {
  173. details: "Viewing FAQs",
  174. },
  175. partners: {
  176. details: "Viewing partners",
  177. },
  178. support: {
  179. details: "Viewing the support page",
  180. },
  181. teams: {
  182. details: "Viewing the Nuxt.js team",
  183. },
  184. videocourses: {
  185. details: "Viewing all video coruses",
  186. },
  187. sponsors: {
  188. details: "Viewing all sponsors",
  189. },
  190. releases: {
  191. details: "Viewing all releases",
  192. },
  193. themes: {
  194. details: "Viewing all themes",
  195. },
  196. testimonials: {
  197. smallImageKey: Assets.Reading,
  198. details: "Reading all testimonials",
  199. buttons: [
  200. {
  201. label: "Read Testimonials",
  202. url: href,
  203. },
  204. ],
  205. },
  206. showcase: {
  207. details: `Viewing ${document
  208. .querySelector('button[class*="rounded-md"]')
  209. ?.textContent?.toLowerCase()} showcases`,
  210. },
  211. };
  212. for (const [path, data] of Object.entries(pages)) {
  213. if (pathname.replace(/-/gm, "").includes(path))
  214. presenceData = { ...presenceData, ...data };
  215. }
  216. }
  217. }
  218. if (buttons && !presenceData.buttons && pathname !== "/") {
  219. presenceData.buttons = [
  220. {
  221. label: strings.buttonViewPage,
  222. url: href,
  223. },
  224. ];
  225. }
  226. if (!buttons && presenceData.buttons) delete presenceData.buttons;
  227. if (!covers && presenceData.largeImageKey !== Assets.Logo)
  228. presenceData.largeImageKey = Assets.Logo;
  229. if (presenceData.details) presence.setActivity(presenceData);
  230. else presence.setActivity();
  231. });