presence.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. const presence = new Presence({
  2. clientId: "830504223153717311",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. let prevURL: string;
  6. const enum Assets {
  7. Logo = "https://cdn.rcd.gg/PreMiD/websites/R/Replit/assets/logo.png",
  8. CodeLine = "https://cdn.rcd.gg/PreMiD/websites/R/Replit/assets/0.png",
  9. }
  10. presence.on("UpdateData", async () => {
  11. const presenceData: PresenceData = {
  12. largeImageKey: Assets.Logo,
  13. startTimestamp: browsingTimestamp,
  14. },
  15. { href, hash, pathname } = document.location,
  16. buttons = await presence.getSetting<boolean>("buttons"),
  17. title = document
  18. .querySelector("title")
  19. ?.textContent?.split("- Replit")?.[0],
  20. isReplit =
  21. !!document.evaluate(
  22. "//span[text()='Made with']",
  23. document,
  24. null,
  25. XPathResult.FIRST_ORDERED_NODE_TYPE,
  26. null
  27. )?.singleNodeValue ||
  28. hash.includes(".") ||
  29. document
  30. .querySelector('[id="__NEXT_DATA__"]')
  31. ?.textContent?.toLowerCase()
  32. ?.includes("editor");
  33. if (!prevURL) prevURL = href;
  34. else if (prevURL !== href) delete presenceData.startTimestamp;
  35. switch (true) {
  36. case pathname === "/~":
  37. case pathname === "/": {
  38. presenceData.details = "Viewing the homepage";
  39. break;
  40. }
  41. case pathname.startsWith("/@"): {
  42. if (isReplit) {
  43. const lineNumbers = document
  44. .querySelector(".cm-lineNumbers")
  45. ?.querySelectorAll(".cm-gutterElement"),
  46. activeLine = document
  47. .querySelector(".cm-lineNumbers")
  48. ?.querySelector(".cm-activeLineGutter")?.textContent;
  49. presenceData.details = hash.split("#")?.[1]
  50. ? `Viewing REPL: ${title} | File: ${hash.split("#")?.[1]}`
  51. : `Viewing REPL: ${title}`;
  52. presenceData.state = `Created by: ${pathname.split("/")[1]}`;
  53. presenceData.buttons = [{ label: "View REPL", url: href }];
  54. if (activeLine || lineNumbers) {
  55. presenceData.smallImageKey = Assets.CodeLine;
  56. presenceData.smallImageText =
  57. !activeLine && lineNumbers
  58. ? `Total lines ${
  59. lineNumbers?.[lineNumbers?.length - 1]?.textContent
  60. }`
  61. : `Line ${activeLine} / ${
  62. lineNumbers?.[lineNumbers?.length - 1]?.textContent
  63. }`;
  64. }
  65. } else {
  66. presenceData.details = "Viewing a user's profile";
  67. presenceData.state = title;
  68. presenceData.buttons = [{ label: "View Profile", url: href }];
  69. }
  70. break;
  71. }
  72. case pathname === "/notifications": {
  73. presenceData.details = "Viewing their notifications";
  74. break;
  75. }
  76. case pathname === "/repls": {
  77. presenceData.details = "Viewing their repls";
  78. break;
  79. }
  80. case pathname === "/my-deployments": {
  81. presenceData.details = "Viewing deployments";
  82. break;
  83. }
  84. case pathname === "/my-teams": {
  85. presenceData.details = "Viewing teams";
  86. break;
  87. }
  88. case pathname === "/usage": {
  89. presenceData.details = "Viewing usage";
  90. break;
  91. }
  92. case pathname.includes("/templates"): {
  93. const templateSearch = document.querySelector<HTMLInputElement>(
  94. '[aria-label="Search Templates"]'
  95. )?.value;
  96. if (!templateSearch) presenceData.details = "Viewing all templates";
  97. else {
  98. presenceData.details = "Searching templates for:";
  99. presenceData.state = templateSearch;
  100. presenceData.smallImageKey = Assets.Search;
  101. }
  102. break;
  103. }
  104. case pathname.includes("/community"): {
  105. const communitySearch =
  106. document.querySelector<HTMLInputElement>("input[data-rac]")?.value;
  107. if (communitySearch) {
  108. presenceData.details = "Searching in the community for:";
  109. presenceData.state = communitySearch;
  110. presenceData.smallImageKey = Assets.Search;
  111. } else presenceData.details = "Browsing through the community";
  112. break;
  113. }
  114. default: {
  115. presenceData.details = "Viewing an unsupported page";
  116. }
  117. }
  118. if (!buttons && presenceData.buttons) delete presenceData.buttons;
  119. presence.setActivity(presenceData);
  120. });