presence.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. const presence = new Presence({
  2. clientId: "921861694190407730",
  3. });
  4. async function getStrings() {
  5. return presence.getStrings(
  6. {
  7. play: "general.playing",
  8. pause: "general.paused",
  9. viewAlbum: "general.buttonViewAlbum",
  10. viewPlaylist: "general.buttonViewPlaylist",
  11. },
  12. await presence.getSetting<string>("lang").catch(() => "en")
  13. );
  14. }
  15. let strings: Awaited<ReturnType<typeof getStrings>> = null,
  16. oldLang: string = null;
  17. const enum Assets {
  18. Logo = "https://cdn.rcd.gg/PreMiD/websites/Q/Qobuz/assets/logo.png",
  19. }
  20. presence.on("UpdateData", async () => {
  21. if (!document.querySelector("#root"))
  22. return presence.setActivity({ largeImageKey: Assets.Logo });
  23. const [newLang, timestamps, cover] = await Promise.all([
  24. presence.getSetting<string>("lang").catch(() => "en"),
  25. presence.getSetting<boolean>("timestamps"),
  26. presence.getSetting<boolean>("cover"),
  27. ]);
  28. if (oldLang !== newLang) {
  29. oldLang = newLang;
  30. strings = await getStrings();
  31. }
  32. const presenceData: PresenceData = {
  33. largeImageKey: cover
  34. ? document
  35. .querySelector<HTMLImageElement>(
  36. 'div[class="player__track-cover"] img'
  37. )
  38. .src.replaceAll("230", "600")
  39. : Assets.Logo,
  40. },
  41. songTitle = document.querySelector<HTMLAnchorElement>(
  42. 'a[class="player__track-name"]'
  43. ),
  44. fromPlaylist = !!document.querySelectorAll(
  45. 'div[class="player__track-album"] a'
  46. )[2],
  47. currentTimeSec = presence.timestampFromFormat(
  48. document.querySelector<HTMLElement>(
  49. 'span[class="player__track-time-text"]'
  50. ).textContent
  51. ),
  52. endTimeSec = presence.timestampFromFormat(
  53. document.querySelectorAll<HTMLElement>(
  54. 'span[class="player__track-time-text"]'
  55. )[1].textContent
  56. ),
  57. paused = !!document.querySelector(
  58. 'span[class="player__action-play pct pct-player-play "] '
  59. ),
  60. elm = document.querySelector(".player__action-repeat.pct"),
  61. obj = {
  62. repeatType: elm.classList.contains("pct-repeat-once")
  63. ? "loopTrack"
  64. : elm.classList.contains("player__action-repeat--active")
  65. ? "loopQueue"
  66. : "deactivated",
  67. songPlaylist: document.querySelectorAll<HTMLAnchorElement>(
  68. 'div[class="player__track-album"] a'
  69. )[2],
  70. };
  71. let playliststring = "";
  72. if (fromPlaylist) playliststring = ` | From: ${obj.songPlaylist.textContent}`;
  73. presenceData.details = songTitle.textContent;
  74. presenceData.state =
  75. document.querySelector('div[class="player__track-album"] > a').textContent +
  76. playliststring;
  77. if (currentTimeSec > 0 || !paused) {
  78. [presenceData.startTimestamp, presenceData.endTimestamp] =
  79. presence.getTimestamps(currentTimeSec, endTimeSec);
  80. presenceData.smallImageKey = paused ? Assets.Pause : Assets.Play;
  81. presenceData.smallImageText = paused ? strings.pause : strings.play;
  82. }
  83. if (paused || !timestamps) {
  84. delete presenceData.startTimestamp;
  85. delete presenceData.endTimestamp;
  86. }
  87. if (obj.repeatType !== "deactivated" && !paused) {
  88. presenceData.smallImageKey =
  89. obj.repeatType === "loopQueue" ? Assets.Repeat : Assets.RepeatOne;
  90. presenceData.smallImageText =
  91. obj.repeatType === "loopQueue" ? Assets.Repeat : Assets.RepeatOne;
  92. }
  93. presenceData.buttons = [
  94. {
  95. label: strings.viewAlbum,
  96. url: songTitle.href,
  97. },
  98. ];
  99. if (fromPlaylist) {
  100. presenceData.buttons.push({
  101. label: strings.viewPlaylist,
  102. url: obj.songPlaylist.href,
  103. });
  104. }
  105. presence.setActivity(presenceData);
  106. });