presence.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. const presence = new Presence({
  2. clientId: "1248642612169150594",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. const enum Assets { // Other default assets can be found at index.d.ts
  6. Logo = "https://cdn.rcd.gg/PreMiD/websites/C/Codeberg/assets/logo.png",
  7. }
  8. presence.on("UpdateData", async () => {
  9. let presenceData: PresenceData = {
  10. largeImageKey: Assets.Logo,
  11. startTimestamp: browsingTimestamp,
  12. };
  13. const pages: Record<string, PresenceData> = {
  14. pulls: {
  15. details: "Viewing pull requests",
  16. },
  17. notifications: {
  18. details: "Viewing notifications",
  19. },
  20. issues: {
  21. details: "Viewing issues",
  22. },
  23. milestones: {
  24. details: "Viewing milestones",
  25. },
  26. "notifications/subscriptions": {
  27. details: "Viewing subscribed notifications",
  28. },
  29. "user/settings": {
  30. details: "Editing user settings",
  31. },
  32. "user/login": {
  33. details: "Logging in",
  34. },
  35. "user/cbrgp/0XUjCUW": {
  36. details: "Signing up",
  37. },
  38. "explore/repos": {
  39. details: "Exploring repositories",
  40. },
  41. "explore/users": {
  42. details: "Exploring users",
  43. },
  44. "explore/organizations": {
  45. details: "Exploring organizations",
  46. },
  47. "org/create": {
  48. details: "Creating an organization",
  49. },
  50. "repo/create": {
  51. details: "Creating a repository",
  52. },
  53. "repo/migrate": {
  54. details: "Migrating a repository",
  55. },
  56. },
  57. { href } = document.location;
  58. for (const [path, data] of Object.entries(pages)) {
  59. if (
  60. `/${path}` === document.querySelector(".active.item").getAttribute("href")
  61. )
  62. presenceData = { ...presenceData, ...data };
  63. }
  64. // Handle users
  65. if (
  66. document.querySelector(".user.profile") &&
  67. !document.querySelector(".user.profile.settings")
  68. ) {
  69. const profileDisplayName = document
  70. .querySelector(".profile-avatar-name")
  71. .querySelector(".header")?.textContent,
  72. // Returns as {name} · {pronouns} so I have to split it
  73. profileName = document
  74. .querySelector(".profile-avatar-name")
  75. .querySelector(".username")
  76. .textContent.split(" ")[0];
  77. let name: string;
  78. if (!profileDisplayName) name = profileName;
  79. else name = `${profileDisplayName} (${profileName})`;
  80. const tabParam = new URL(href).searchParams.get("tab");
  81. if (tabParam) {
  82. switch (tabParam) {
  83. case "stars": {
  84. presenceData.details = `Viewing ${profileName}'s starred repositories`;
  85. break;
  86. }
  87. case "activity": {
  88. presenceData.details = `Viewing ${profileName}'s public activity`;
  89. break;
  90. }
  91. case "repositories": {
  92. presenceData.details = `Viewing ${profileName}'s repositories`;
  93. break;
  94. }
  95. // No default
  96. }
  97. } else if (href.includes("/-/projects"))
  98. presenceData.details = `Viewing ${profileName}'s projects`;
  99. else if (href.includes("/-/packages"))
  100. presenceData.details = `Viewing ${profileName}'s packages`;
  101. else presenceData.details = `Viewing profile: ${name}`;
  102. presenceData.buttons = [
  103. {
  104. label: "View Profile",
  105. url: href,
  106. },
  107. ];
  108. presenceData.largeImageKey = document
  109. .querySelector("#profile-avatar")
  110. .querySelector("img").src;
  111. presenceData.smallImageKey = Assets.Logo;
  112. }
  113. // Handle repos
  114. if (
  115. document.querySelector(".repository") &&
  116. !document.querySelector(".repository.new")
  117. ) {
  118. const repoAvatar = document
  119. .querySelector(".flex-item-leading")
  120. .querySelector("img"),
  121. repoTitle = document
  122. .querySelector(".flex-item-main")
  123. .querySelector(".flex-item-title")
  124. .textContent.trim();
  125. if (repoAvatar) {
  126. presenceData.largeImageKey = repoAvatar.src;
  127. presenceData.smallImageKey = Assets.Logo;
  128. } else presenceData.largeImageKey = Assets.Logo;
  129. presenceData.buttons = [
  130. {
  131. label: "View Repository",
  132. url: href,
  133. },
  134. ];
  135. const repoPages: Record<string, PresenceData> = {
  136. "": {
  137. details: `Viewing repository: ${repoTitle}`,
  138. },
  139. issues: {
  140. details: `Viewing ${repoTitle}'s issues`,
  141. },
  142. pulls: {
  143. details: `Viewing ${repoTitle}'s pull requests`,
  144. },
  145. activity: {
  146. details: `Viewing ${repoTitle}'s public activity`,
  147. },
  148. settings: {
  149. details: `Editing ${repoTitle}'s settings`,
  150. },
  151. releases: {
  152. details: `Viewing ${repoTitle}'s releases`,
  153. },
  154. projects: {
  155. details: `Viewing ${repoTitle}'s projects`,
  156. },
  157. actions: {
  158. details: `Viewing ${repoTitle}'s actions`,
  159. },
  160. packages: {
  161. details: `Viewing ${repoTitle}'s packages`,
  162. },
  163. branches: {
  164. details: `Viewing ${repoTitle}'s branches`,
  165. },
  166. tags: {
  167. details: `Viewing ${repoTitle}'s tags`,
  168. },
  169. forks: {
  170. details: `Viewing ${repoTitle}'s forks`,
  171. },
  172. watchers: {
  173. details: `Viewing ${repoTitle}'s watchers`,
  174. },
  175. stars: {
  176. details: `Viewing ${repoTitle}'s stargazers`,
  177. },
  178. };
  179. for (const [path, data] of Object.entries(repoPages)) {
  180. if (
  181. `/${path}` ===
  182. document.querySelector(".active.item").getAttribute("href")
  183. ) {
  184. presenceData = {
  185. ...data,
  186. ...presenceData,
  187. };
  188. }
  189. }
  190. }
  191. // Handle orgs
  192. if (document.querySelector(".organization.page-content")) {
  193. const orgAvatar = document
  194. .querySelector(".organization")
  195. .querySelector("img"),
  196. orgName = orgAvatar.title;
  197. if (href.includes("/-/projects"))
  198. presenceData.details = `Viewing ${orgName}'s projects`;
  199. else if (href.includes("/-/packages"))
  200. presenceData.details = `Viewing ${orgName}'s packages`;
  201. else if (href.includes("/org"))
  202. presenceData.details = `Viewing ${orgName}'s teams/members`;
  203. else presenceData.details = `Viewing organization: ${orgName}`;
  204. presenceData.buttons = [
  205. {
  206. label: "View Organization",
  207. url: href,
  208. },
  209. ];
  210. presenceData.largeImageKey = orgAvatar.src;
  211. presenceData.smallImageKey = Assets.Logo;
  212. }
  213. presence.setActivity(presenceData);
  214. });