presence.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. const presence = new Presence({
  2. clientId: "972073369564483584",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. async function getStrings() {
  6. return presence.getStrings(
  7. {
  8. play: "general.playing",
  9. pause: "general.paused",
  10. search: "general.search",
  11. episode: "general.episode",
  12. browsing: "general.browsing",
  13. viewHome: "general.viewHome",
  14. viewChannel: "general.viewChannel",
  15. watchingVid: "general.watchingVid",
  16. viewCategory: "general.viewCategory",
  17. readingAbout: "general.readingAbout",
  18. searchSomething: "general.searchSomething",
  19. buttonWatchVideo: "general.buttonWatchVideo",
  20. buttonViewEpisode: "general.buttonViewEpisode",
  21. },
  22. await presence.getSetting<string>("lang").catch(() => "en")
  23. );
  24. }
  25. let strings: Awaited<ReturnType<typeof getStrings>>,
  26. oldLang: string = null;
  27. presence.on("UpdateData", async () => {
  28. const newLang = await presence.getSetting<string>("lang").catch(() => "en"),
  29. presenceData: PresenceData = {
  30. largeImageKey:
  31. "https://cdn.rcd.gg/PreMiD/websites/B/bilibilitv/assets/logo.png",
  32. startTimestamp: browsingTimestamp,
  33. },
  34. { hostname, href, pathname } = document.location,
  35. pathArray = pathname?.split("/"),
  36. title = document.querySelector(".bstar-meta__title")?.textContent,
  37. playing = !document.querySelector(
  38. "img.player-mobile-icon.player-mobile-pause-icon.player-mobile-active"
  39. ),
  40. thumbnail =
  41. document
  42. .querySelector<HTMLMetaElement>('meta[property="og:image"]')
  43. ?.content?.split("?")?.[0] ??
  44. "https://cdn.rcd.gg/PreMiD/websites/B/bilibilitv/assets/logo.png";
  45. if (oldLang !== newLang || !strings) {
  46. oldLang = newLang;
  47. strings = await getStrings();
  48. }
  49. // Main Site
  50. if (hostname === "www.bilibili.tv") {
  51. const pathKey = isNaN(Number(pathArray[2])) ? pathArray[2] : pathArray[1];
  52. switch (pathKey) {
  53. case "video": {
  54. presenceData.details = strings.watchingVid;
  55. presenceData.state = title;
  56. presenceData.buttons = [
  57. {
  58. label: strings.buttonWatchVideo,
  59. url: href,
  60. },
  61. ];
  62. break;
  63. }
  64. case "play": {
  65. presenceData.details = title;
  66. presenceData.state = `${strings.episode} ${document
  67. .querySelector("a.ep-item.ep-item--active")
  68. .textContent?.replace(/\D/g, "")}`;
  69. presenceData.buttons = [
  70. {
  71. label: strings.buttonViewEpisode,
  72. url: href,
  73. },
  74. ];
  75. break;
  76. }
  77. case "media": {
  78. presenceData.details = strings.readingAbout.replace(":", "");
  79. presenceData.state = document.querySelector(
  80. ".media-detail__title"
  81. ).textContent;
  82. presenceData.smallImageKey = Assets.Reading;
  83. presenceData.smallImageText = strings.browsing;
  84. break;
  85. }
  86. case "popular": {
  87. presenceData.details = strings.viewCategory.replace(":", "");
  88. presenceData.state = "Popular";
  89. presenceData.smallImageKey = Assets.Reading;
  90. presenceData.smallImageText = strings.browsing;
  91. break;
  92. }
  93. case "space": {
  94. presenceData.details = strings.viewChannel.replace(":", "");
  95. presenceData.state =
  96. document.querySelector(".space-info__name")?.textContent ??
  97. strings.searchSomething;
  98. break;
  99. }
  100. case "index": {
  101. presenceData.details = strings.search;
  102. presenceData.state =
  103. document.querySelector(
  104. "a.router-link-exact-active.router-link-active.anime-radio__tag.anime-radio__tag--active"
  105. )?.textContent ?? strings.searchSomething;
  106. presenceData.smallImageKey = Assets.Search;
  107. presenceData.smallImageText = strings.browsing;
  108. break;
  109. }
  110. default: {
  111. presenceData.details = strings.viewHome;
  112. presenceData.smallImageKey = Assets.Reading;
  113. presenceData.smallImageText = strings.browsing;
  114. break;
  115. }
  116. }
  117. if (pathKey === "video" || pathKey === "play") {
  118. presenceData.largeImageKey = thumbnail;
  119. presenceData.smallImageKey = playing ? Assets.Play : Assets.Pause;
  120. if (playing) {
  121. [presenceData.startTimestamp, presenceData.endTimestamp] =
  122. presence.getTimestamps(
  123. presence.timestampFromFormat(
  124. document.querySelector(".player-mobile-time-current-text")
  125. ?.textContent ?? "00:00"
  126. ),
  127. presence.timestampFromFormat(
  128. document.querySelector(".player-mobile-time-total-text")
  129. ?.textContent ?? "00:00"
  130. )
  131. );
  132. }
  133. }
  134. // Studio
  135. } else if (hostname === "studio.bilibili.tv") {
  136. if (pathArray[1])
  137. presenceData.details = document.querySelector(".is-active").textContent;
  138. else {
  139. presenceData.details = document.querySelector(
  140. ".nav-menu__menu-title"
  141. ).textContent;
  142. }
  143. presenceData.state = "Bilibili Studio";
  144. }
  145. if (presenceData.details) presence.setActivity(presenceData);
  146. else presence.setActivity();
  147. });