presence.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. const enum Assets {
  2. Logo = "https://cdn.rcd.gg/PreMiD/websites/N/Necord/assets/0.png",
  3. Idle = "https://cdn.rcd.gg/PreMiD/websites/N/Necord/assets/1.png",
  4. }
  5. const presence = new Presence({
  6. clientId: "1081479845940314114",
  7. }),
  8. browsingTimestamp = Math.floor(Date.now() / 1000),
  9. IDLE_TIMEOUT = 10 * 60 * 1000,
  10. settings = [
  11. "search",
  12. "docs-page",
  13. "docs-page-content",
  14. "docs-page-sidebar",
  15. "idling",
  16. ];
  17. let sidebar: string = null,
  18. lastActivity: number = Date.now();
  19. presence.on("UpdateData", async () => {
  20. const presenceData: PresenceData = {
  21. largeImageKey: Assets.Logo,
  22. startTimestamp: browsingTimestamp,
  23. },
  24. { href, pathname, search } = document.location,
  25. title = document.title.split(" | ")[0],
  26. privacy = await presence.getSetting("privacy"),
  27. [
  28. isSearchPublic,
  29. isCurrentPagePublic,
  30. isCurrentContentPublic,
  31. isSidebarPublic,
  32. isIdlingPublic,
  33. ] = await Promise.all(
  34. !privacy
  35. ? settings.map(setting => presence.getSetting(setting))
  36. : Array(settings.length).fill(false)
  37. );
  38. switch (true) {
  39. case lastActivity + IDLE_TIMEOUT < Date.now() && isIdlingPublic: {
  40. presenceData.smallImageKey = Assets.Idle;
  41. presenceData.smallImageText = "Idling";
  42. presenceData.details = "Idling at page: ";
  43. presenceData.state = title;
  44. presenceData.startTimestamp = Math.floor(lastActivity / 1000);
  45. break;
  46. }
  47. case pathname.startsWith("/search"): {
  48. presenceData.smallImageKey = Assets.Search;
  49. presenceData.smallImageText = "Searching";
  50. presenceData.details = "Searching for something";
  51. if (search && isSearchPublic) {
  52. presenceData.details = "Searching for:";
  53. presenceData.state = [
  54. search.split("q=")[1],
  55. `(${
  56. document.querySelector<HTMLDivElement>("main")?.childElementCount ??
  57. 0
  58. } results)`,
  59. ].join(" ");
  60. presenceData.buttons = [
  61. {
  62. label: "Show Results",
  63. url: href,
  64. },
  65. ];
  66. }
  67. break;
  68. }
  69. case !!sidebar && isSidebarPublic: {
  70. presenceData.smallImageKey = Assets.Search;
  71. presenceData.smallImageText = "Searching";
  72. presenceData.details = "Selecting a category:";
  73. presenceData.state = sidebar;
  74. break;
  75. }
  76. default: {
  77. const topmostElem =
  78. document.querySelector<HTMLLinkElement>(
  79. ".table-of-contents__link--active"
  80. ) ??
  81. document.querySelector<HTMLLinkElement>(".table-of-contents__link");
  82. presenceData.smallImageKey = Assets.Reading;
  83. presenceData.smallImageText = "Reading";
  84. presenceData.details = `Reading ${
  85. isCurrentPagePublic ? title : "a"
  86. } page${isCurrentContentPublic ? ":" : ""}`;
  87. presenceData.state = isCurrentContentPublic
  88. ? `${topmostElem.textContent} (${getScrollPercentage().toFixed(2)}%)`
  89. : null;
  90. presenceData.buttons = [
  91. {
  92. label: "Read Page",
  93. url: topmostElem.href,
  94. },
  95. ];
  96. break;
  97. }
  98. }
  99. if (presenceData.details) presence.setActivity(presenceData);
  100. else presence.setActivity();
  101. });
  102. document.addEventListener("mouseover", e => {
  103. const target = e.target as HTMLElement;
  104. if (target.classList.contains("menu__link")) sidebar = target.textContent;
  105. else if (!target.classList.contains("menu")) sidebar = null;
  106. lastActivity = Date.now();
  107. });
  108. function getScrollPercentage() {
  109. const { scrollY, innerHeight } = window,
  110. { scrollHeight } = document.body,
  111. percentage = (scrollY / (scrollHeight - innerHeight)) * 100;
  112. return percentage === 0 ? 0 : percentage || 100;
  113. }