presence.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. const presence = new Presence({
  2. clientId: "1036066765735727144",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. presence.on("UpdateData", async () => {
  6. const presenceData: PresenceData = {
  7. largeImageKey:
  8. "https://cdn.rcd.gg/PreMiD/websites/F/Fly.io/assets/logo.png",
  9. startTimestamp: browsingTimestamp,
  10. },
  11. { pathname, href, hostname } = window.location,
  12. pathSplit = pathname.split("/").slice(1),
  13. privacyMode = await presence.getSetting<boolean>("privacyMode");
  14. function useBlogPostState(namespace: string): void {
  15. if (pathSplit[1] === "page" || pathSplit[1] === "")
  16. presenceData.details = `Browsing ${namespace} posts`;
  17. else {
  18. presenceData.details = `Reading a ${namespace} post`;
  19. presenceData.state = document.querySelector("h1").textContent;
  20. presenceData.buttons = [{ label: "Read Post", url: href }];
  21. presenceData.largeImageKey =
  22. document.querySelector<HTMLImageElement>(".post-cover").src;
  23. }
  24. }
  25. switch (hostname) {
  26. case "fly.io":
  27. case "www.fly.io": {
  28. switch (pathSplit[0]) {
  29. case "": {
  30. presenceData.details = "Browsing the homepage";
  31. break;
  32. }
  33. case "blog": {
  34. useBlogPostState("blog");
  35. break;
  36. }
  37. case "phoenix-files": {
  38. useBlogPostState("Phoenix Files");
  39. break;
  40. }
  41. case "laravel-bytes": {
  42. useBlogPostState("Laravel Bytes");
  43. break;
  44. }
  45. case "ruby-dispatch": {
  46. useBlogPostState("Ruby Dispatch");
  47. break;
  48. }
  49. case "docs": {
  50. presenceData.details = "Reading the documentation";
  51. presenceData.state = document.querySelector("h1").textContent;
  52. break;
  53. }
  54. case "jobs": {
  55. if (pathSplit[1]) {
  56. presenceData.details = "Viewing a job posting";
  57. presenceData.state = document.querySelector("h1").textContent;
  58. } else presenceData.details = "Browsing jobs";
  59. break;
  60. }
  61. case "dashboard": {
  62. presenceData.details = "Using the dashboard";
  63. switch (pathSplit[2]) {
  64. case "billing": {
  65. presenceData.state = "Viewing billing information";
  66. break;
  67. }
  68. case "team": {
  69. presenceData.state = "Viewing team members";
  70. break;
  71. }
  72. case "documents": {
  73. presenceData.state = "Viewing documents";
  74. break;
  75. }
  76. case "settings": {
  77. presenceData.state = "Viewing settings";
  78. break;
  79. }
  80. case "launch": {
  81. presenceData.state = "Launching an app";
  82. break;
  83. }
  84. }
  85. break;
  86. }
  87. case "apps": {
  88. const details: Record<string, string> = {
  89. "": "Viewing app dashboard",
  90. monitoring: "Viewing app logs",
  91. metrics: "Viewing app metrics",
  92. certificates: "Viewing app certificates",
  93. scale: "Viewing app scaling",
  94. activity: "Viewing app activity",
  95. secrets: "Viewing app secrets",
  96. volumes: "Viewing app volumes",
  97. machines: "Viewing app machines",
  98. settings: "Viewing app settings",
  99. };
  100. presenceData.details = details[pathSplit[2] ?? ""];
  101. if (!privacyMode) {
  102. presenceData.state = document
  103. .querySelector('[aria-label="Breadcrumb"] li:nth-child(3)')
  104. .textContent.trim();
  105. }
  106. break;
  107. }
  108. case "organizations": {
  109. if (pathSplit[1] === "new")
  110. presenceData.details = "Creating an organization";
  111. else presenceData.details = "Browsing their organizations";
  112. break;
  113. }
  114. case "launch": {
  115. if (pathSplit[1]) {
  116. presenceData.details = `Launching a ${
  117. document.querySelector("h1 > strong").textContent
  118. }`;
  119. } else {
  120. presenceData.details = "Reading the documentation";
  121. presenceData.state = document.querySelector("h1").textContent;
  122. }
  123. break;
  124. }
  125. case "user": {
  126. presenceData.details = "Managing their account";
  127. break;
  128. }
  129. default: {
  130. presenceData.details = "Browsing";
  131. presenceData.state = document.title.match(/^(.*)( · .*?)?$/)[1];
  132. break;
  133. }
  134. }
  135. break;
  136. }
  137. case "community.fly.io": {
  138. presenceData.details = "Browsing community forums";
  139. switch (pathSplit[0]) {
  140. case "top": {
  141. presenceData.state = "Top posts";
  142. break;
  143. }
  144. case "categories": {
  145. presenceData.state = "Categories";
  146. break;
  147. }
  148. case "c": {
  149. presenceData.details = "Browsing forum category";
  150. presenceData.state =
  151. document.querySelector<HTMLSpanElement>(
  152. ".category-name"
  153. ).textContent;
  154. break;
  155. }
  156. case "u": {
  157. presenceData.details = `Viewing ${document
  158. .querySelector<HTMLHeadingElement>(".username")
  159. .textContent.trim()}'s profile`;
  160. presenceData.state = document.querySelector<HTMLAnchorElement>(
  161. ".user-nav > li > a.active"
  162. ).textContent;
  163. presenceData.smallImageKey = document.querySelector<HTMLImageElement>(
  164. ".user-profile-avatar .avatar"
  165. ).src;
  166. break;
  167. }
  168. case "badges": {
  169. presenceData.details = "Viewing forum badges";
  170. if (pathSplit[1]) {
  171. presenceData.state =
  172. document.querySelector<HTMLAnchorElement>(
  173. ".badge-link"
  174. ).textContent;
  175. }
  176. break;
  177. }
  178. case "t": {
  179. presenceData.details = "Viewing a forum topic";
  180. presenceData.state = document
  181. .querySelector<HTMLAnchorElement>(".fancy-title")
  182. .textContent.trim();
  183. presenceData.buttons = [{ label: "View Topic", url: href }];
  184. break;
  185. }
  186. case "tag": {
  187. if (pathSplit[1]) {
  188. presenceData.details = "Viewing forum posts by tag";
  189. presenceData.state = document
  190. .querySelector(".tag-drop-header")
  191. .textContent.trim();
  192. } else presenceData.details = "Browsing forum tags";
  193. break;
  194. }
  195. default: {
  196. presenceData.state = document.title.match(/^(.*)( - Fly\.io)?$/)[1];
  197. }
  198. }
  199. break;
  200. }
  201. }
  202. presence.setActivity(presenceData);
  203. });