presence.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. const presence = new Presence({
  2. clientId: "684124119146692619",
  3. });
  4. // Timestamp
  5. function getTimeStamp() {
  6. return Math.floor(Date.now() / 1000);
  7. }
  8. // Variables
  9. let Routes: string[],
  10. Queries,
  11. DiscussionTitle: string,
  12. DiscussionAuthor: string,
  13. NewsTitle: string,
  14. PeopleName: string,
  15. TeamName: string,
  16. UserName: string,
  17. BookmarkType: string,
  18. BookmarkSize: string;
  19. presence.on("UpdateData", async () => {
  20. // Presence Data
  21. const presenceData: PresenceData = {
  22. largeImageKey:
  23. "https://cdn.rcd.gg/PreMiD/websites/M/Mangalib/assets/logo.png",
  24. };
  25. // Setup Routes & Query
  26. Routes = document.location.href
  27. .replace(document.location.search, "")
  28. .split("/")
  29. .splice(3);
  30. Queries = Object.fromEntries(
  31. document.location.search
  32. .slice(1)
  33. .split("&")
  34. .map((k, _, a) => {
  35. const item: string[] = k.replace(/\[(.*?)\]+/g, "").split("="),
  36. Keys = a
  37. .map(i => i.replace(/\[(.*?)\]+/g, "").split("="))
  38. .filter(i => i[0] === item[0]);
  39. if (Keys.length === 1) return item;
  40. else return [item[0], Keys.map(i => i[1])];
  41. })
  42. );
  43. // Website Pages
  44. switch (Routes[0]) {
  45. case "": {
  46. // Homepage
  47. presenceData.smallImageText = "reading";
  48. presenceData.smallImageKey = Assets.Search;
  49. presenceData.details = "Главная";
  50. presenceData.startTimestamp = 0;
  51. // Page Section
  52. if (Queries.section === "my-updates")
  53. presenceData.state = "Мои обновления";
  54. else presenceData.state = "Все обновления";
  55. break;
  56. }
  57. case "manga-list": {
  58. // List of mangas
  59. presenceData.smallImageText = "reading";
  60. presenceData.smallImageKey = Assets.Search;
  61. presenceData.details = "Каталог манги";
  62. if (!Array.isArray(Queries.types)) Queries.types = [Queries.types];
  63. // Search Types
  64. if (Queries.types && Queries.types.length === 1) {
  65. // Types size === 1
  66. switch (Queries.types[0]) {
  67. case "4":
  68. presenceData.state = "Ищет OEL-мангу";
  69. break;
  70. case "5":
  71. presenceData.state = "Ищет Манхву";
  72. break;
  73. case "6":
  74. presenceData.state = "Ищет Маньхуа";
  75. break;
  76. case "8":
  77. presenceData.state = "Ищет Румангу";
  78. break;
  79. case "9":
  80. presenceData.state = "Ищет Западный комикс";
  81. break;
  82. default:
  83. presenceData.state = "Ищет Мангу";
  84. break;
  85. }
  86. } else if (Queries.types && Queries.types.length > 1) {
  87. // Types size > 1
  88. const mangas: string[] = [];
  89. for (const item in Queries.types.sort()) {
  90. switch (item) {
  91. case "4":
  92. mangas.push("OEL-мангу");
  93. break;
  94. case "5":
  95. mangas.push("Манхву");
  96. break;
  97. case "6":
  98. mangas.push("Маньхуа");
  99. break;
  100. case "8":
  101. mangas.push("Румангу");
  102. break;
  103. case "9":
  104. mangas.push("Западный комикс");
  105. break;
  106. default:
  107. mangas.push("Мангу");
  108. break;
  109. }
  110. }
  111. presenceData.state = `Ищет: ${mangas.join(", ")}`;
  112. } else presenceData.state = "Ищет Мангу";
  113. break;
  114. }
  115. case "forum": {
  116. // Forum page
  117. presenceData.details = "Форум";
  118. // Subpages of forums
  119. switch (Routes[1]) {
  120. case "": {
  121. // Main forum page
  122. presenceData.smallImageText = "Читает";
  123. presenceData.smallImageKey = Assets.Reading;
  124. if (Queries.subscription) presenceData.state = "Мои подписки";
  125. if (Queries.user_id) presenceData.state = "Мои темы";
  126. switch (Queries.category) {
  127. case "all":
  128. presenceData.state = "Все категории";
  129. break;
  130. case "1":
  131. presenceData.state = "Баги и проблемы";
  132. break;
  133. case "2":
  134. presenceData.state = "Предложения для сайта";
  135. break;
  136. case "3":
  137. presenceData.state = "Поиск тайтлов";
  138. break;
  139. case "4":
  140. presenceData.state = "Поиск кадров";
  141. break;
  142. case "5":
  143. presenceData.state = "Обсуждение Манги";
  144. break;
  145. case "6":
  146. presenceData.state = "Обсуждение Аниме";
  147. break;
  148. case "7":
  149. presenceData.state = "Обсуждение Ранобэ";
  150. break;
  151. case "8":
  152. presenceData.state = "Видеоигры";
  153. break;
  154. case "9":
  155. presenceData.state = "Переводчикам";
  156. break;
  157. case "10":
  158. presenceData.state = "Как переводить мангу";
  159. break;
  160. case "11":
  161. presenceData.state = "Как рисовать мангу";
  162. break;
  163. case "12":
  164. presenceData.state = "Общение";
  165. break;
  166. case "13":
  167. presenceData.state = "Другое";
  168. break;
  169. }
  170. break;
  171. }
  172. case "discussion-create": {
  173. // Discussion create
  174. presenceData.smallImageText = "Пишет";
  175. presenceData.smallImageKey = Assets.Writing;
  176. presenceData.state = "Создает новую тему";
  177. break;
  178. }
  179. case "discussion": {
  180. // Discussion page
  181. if (Routes[2] && !Routes[3]) {
  182. // Opened discussion
  183. presenceData.smallImageText = "Читает";
  184. presenceData.smallImageKey = Assets.Reading;
  185. const titleElement = document.querySelector(
  186. ".discussion .discussion__title"
  187. ),
  188. authorElement = document.querySelector(
  189. ".discussion .discussion-creator__username"
  190. );
  191. DiscussionTitle = titleElement && titleElement.textContent;
  192. DiscussionAuthor = authorElement && authorElement.textContent;
  193. if (DiscussionAuthor && DiscussionTitle)
  194. presenceData.state = `Тема: ${DiscussionTitle}| Автор: ${DiscussionAuthor}`;
  195. } else if (Routes[3] && Routes[3] === "edit") {
  196. // Editor discussion
  197. presenceData.smallImageText = "Пишет";
  198. presenceData.smallImageKey = Assets.Writing;
  199. presenceData.state = DiscussionTitle
  200. ? `Редактирует тему: ${DiscussionTitle}`
  201. : "Редактирует тему";
  202. }
  203. break;
  204. }
  205. // No default
  206. }
  207. break;
  208. }
  209. case "faq": {
  210. // Faq page
  211. if (Routes[1] === "article") {
  212. // Faq Editor
  213. presenceData.details = "Faq";
  214. presenceData.smallImageText = "Редактирует";
  215. presenceData.smallImageKey = Assets.Writing;
  216. presenceData.state = `Редактирует: ${Queries.article} вопрос`;
  217. } else {
  218. // Faq Sections
  219. presenceData.details = "Faq";
  220. presenceData.smallImageText = "Читает";
  221. presenceData.smallImageKey = Assets.Reading;
  222. switch (Queries.section) {
  223. case "1":
  224. presenceData.state = "Манга";
  225. break;
  226. case "2":
  227. presenceData.state = "Общие вопросы";
  228. break;
  229. case "3":
  230. presenceData.state = "Профиль пользователя";
  231. break;
  232. case "4":
  233. presenceData.state = "Чтение манги";
  234. break;
  235. case "5":
  236. presenceData.state = "Комментарии";
  237. break;
  238. case "6":
  239. presenceData.state = "Мини-чат";
  240. break;
  241. case "7":
  242. presenceData.state = "Решение проблем";
  243. break;
  244. case "8":
  245. presenceData.state = "Правила";
  246. break;
  247. case "9":
  248. presenceData.state = "Форум";
  249. break;
  250. }
  251. }
  252. break;
  253. }
  254. case "news": {
  255. // News page
  256. presenceData.details = "Новости";
  257. presenceData.smallImageText = "Читает";
  258. presenceData.smallImageKey = Assets.Reading;
  259. if (Routes[1]) {
  260. // Opened News
  261. const titleElement = document.querySelector(".news__title");
  262. NewsTitle = titleElement && titleElement.textContent;
  263. if (NewsTitle) presenceData.state = NewsTitle;
  264. } else {
  265. // News List
  266. presenceData.details = "Новости";
  267. presenceData.smallImageText = "Читает";
  268. presenceData.smallImageKey = Assets.Reading;
  269. presenceData.state = "Список новостей";
  270. }
  271. break;
  272. }
  273. case "notification": {
  274. // Notification list
  275. presenceData.details = "Уведомления";
  276. presenceData.smallImageText = "Читает";
  277. presenceData.smallImageKey = Assets.Reading;
  278. switch (Queries.type) {
  279. case "chapter":
  280. presenceData.state = "Главы";
  281. break;
  282. case "comments":
  283. presenceData.state = "Комментарии";
  284. break;
  285. case "message":
  286. presenceData.state = "Сообщения";
  287. break;
  288. case "friend":
  289. presenceData.state = "Заявки в друзья";
  290. break;
  291. case "other":
  292. presenceData.state = "Другое";
  293. break;
  294. case "all":
  295. presenceData.state = "Все";
  296. break;
  297. }
  298. break;
  299. }
  300. case "contact-us": {
  301. // Contact page
  302. presenceData.details = "Контакты";
  303. presenceData.smallImageText = "Пишет";
  304. presenceData.smallImageKey = Assets.Writing;
  305. presenceData.state = "info@mangalib.me";
  306. break;
  307. }
  308. case "messages": {
  309. // Messages page
  310. presenceData.details = "Личные сообщения";
  311. presenceData.smallImageText = "Пишет";
  312. presenceData.smallImageKey = Assets.Writing;
  313. presenceData.startTimestamp = getTimeStamp();
  314. break;
  315. }
  316. case "people": {
  317. // Authors (Moderation) page
  318. if (Routes[1] === "create") {
  319. presenceData.details = "Добавляет автора";
  320. presenceData.smallImageText = "Добавляет автора";
  321. presenceData.smallImageKey = Assets.Writing;
  322. PeopleName = document.querySelector("#name").textContent;
  323. if (PeopleName.length > 1) presenceData.state = PeopleName;
  324. else presenceData.state = "Имя автора не задано";
  325. }
  326. break;
  327. }
  328. case "team": {
  329. // Team page
  330. if (Routes[1] === "create") {
  331. // Create New Team
  332. presenceData.details = "Добавляет команду";
  333. presenceData.smallImageText = "Добавляет команду";
  334. presenceData.smallImageKey = Assets.Writing;
  335. TeamName = document.querySelector("#name").textContent;
  336. if (TeamName.length > 1) presenceData.state = TeamName;
  337. else presenceData.state = "Имя команды не задано";
  338. } else if (!Routes[2]) {
  339. presenceData.details = "Команда перевода";
  340. presenceData.smallImageText = "Смотрит переводчика";
  341. presenceData.smallImageKey = Assets.Reading;
  342. const title = document.querySelector(".team-profile__name");
  343. TeamName = title && title.textContent.replace("редактировать", "");
  344. if (TeamName) presenceData.state = TeamName;
  345. } else if (Routes[2] === "edit") {
  346. presenceData.details = "Команда перевода";
  347. presenceData.smallImageText = "Редактирует переводчика";
  348. presenceData.smallImageKey = Assets.Writing;
  349. switch (Queries.section) {
  350. case "info":
  351. presenceData.state = "Редактирует информацию команды";
  352. break;
  353. case "users":
  354. presenceData.state = "Редактирует участников команды";
  355. break;
  356. }
  357. }
  358. break;
  359. }
  360. case "moderation": {
  361. // Moderation page
  362. presenceData.details = "Модерация";
  363. presenceData.smallImageText = "Управляет сайтом";
  364. presenceData.smallImageKey = Assets.Reading;
  365. if (!Routes[1]) presenceData.state = "Модерация глав";
  366. else {
  367. switch (Routes[1]) {
  368. case "manga": {
  369. if (Routes[2] === "rejected")
  370. presenceData.state = "Отклоненные манги";
  371. else presenceData.state = "Модерация манги";
  372. break;
  373. }
  374. case "manga-edit": {
  375. presenceData.state = "Изменения манги";
  376. break;
  377. }
  378. case "author": {
  379. presenceData.state = "Новые Авторы";
  380. break;
  381. }
  382. case "publisher": {
  383. presenceData.state = "Новые Издательства";
  384. break;
  385. }
  386. case "comments": {
  387. presenceData.state = "Жалобы на комментарии";
  388. break;
  389. }
  390. case "forum-posts": {
  391. presenceData.state = "Жалобы на форуме";
  392. break;
  393. }
  394. case "comments-list": {
  395. if (Routes[2] === "all") presenceData.state = "Список комментариев";
  396. else if (Routes[2] === "sticky")
  397. presenceData.state = "Закрепленные комментарии";
  398. break;
  399. }
  400. case "ban-list": {
  401. presenceData.state = "Баны";
  402. break;
  403. }
  404. case "other":
  405. {
  406. presenceData.state = "Другое";
  407. // No default
  408. }
  409. break;
  410. }
  411. }
  412. break;
  413. }
  414. case "user": {
  415. // User page
  416. presenceData.smallImageText = "Смотрит профиль пользователя";
  417. presenceData.smallImageKey = Assets.Reading;
  418. const username = document.querySelector(".profile-user__username span");
  419. UserName = username && username.textContent;
  420. if (UserName) presenceData.details = `Профиль:${UserName}`;
  421. if (Routes[1] === "content") {
  422. presenceData.details = "Мои добавления";
  423. presenceData.smallImageText = "Пишет";
  424. presenceData.smallImageKey = Assets.Writing;
  425. presenceData.startTimestamp = 0;
  426. if (!Routes[2]) presenceData.state = "Добавленные тайтлы";
  427. else {
  428. switch (Routes[2]) {
  429. case "moderation": {
  430. presenceData.state = "Тайтлы на модерации";
  431. break;
  432. }
  433. case "rejected": {
  434. presenceData.state = "Тайтлы не прошедшие модерацию";
  435. break;
  436. }
  437. case "chapters":
  438. {
  439. presenceData.state = "Главы на модерации";
  440. // No default
  441. }
  442. break;
  443. }
  444. }
  445. } else if (Routes[1] === "edit") {
  446. presenceData.details = "Мои настройки";
  447. presenceData.smallImageText = "Настраивает";
  448. presenceData.smallImageKey = Assets.Writing;
  449. presenceData.startTimestamp = 0;
  450. switch (Queries.section) {
  451. case "info":
  452. presenceData.state = "Информация";
  453. break;
  454. case "site-settings":
  455. presenceData.state = "Настройки сайта";
  456. break;
  457. case "notifications":
  458. presenceData.state = "Уведомления";
  459. break;
  460. case "password":
  461. presenceData.state = "Безопасность";
  462. break;
  463. }
  464. } else if (!Routes[2]) {
  465. // Main user page
  466. const size = document.querySelector(
  467. ".bookmark-menu .menu__item.is-active .bookmark-menu__label"
  468. ),
  469. title = document.querySelector(
  470. ".bookmark-menu .menu__item.is-active .bookmark-menu__name"
  471. );
  472. BookmarkSize = size && size.textContent;
  473. BookmarkType =
  474. title &&
  475. title.textContent.charAt(0).toUpperCase() +
  476. title.textContent.slice(1);
  477. presenceData.details = `Закладки ${UserName}`;
  478. presenceData.state = `${BookmarkType.trim()}: ${BookmarkSize}`;
  479. presenceData.smallImageText = "Читает";
  480. presenceData.smallImageKey = Assets.Reading;
  481. presenceData.startTimestamp = 0;
  482. } else {
  483. switch (Routes[2]) {
  484. case "comment": {
  485. presenceData.details = `Профиль: ${UserName}`;
  486. let commentType;
  487. switch (Queries.commentType) {
  488. case "manga": {
  489. commentType = "Комментарии к манге";
  490. break;
  491. }
  492. case "chapter": {
  493. commentType = "Комментарии к главам";
  494. break;
  495. }
  496. case "post": {
  497. commentType = "Комментарии к новостям";
  498. break;
  499. }
  500. default:
  501. commentType = "Все комментарии";
  502. }
  503. presenceData.state = commentType;
  504. break;
  505. }
  506. case "following": {
  507. presenceData.details = `Профиль: ${UserName}`;
  508. presenceData.state = "Список друзей";
  509. break;
  510. }
  511. case "mutual-friends": {
  512. presenceData.details = `Профиль: ${UserName}`;
  513. presenceData.state = "Общие друзья";
  514. break;
  515. }
  516. case "ignore": {
  517. presenceData.details = `Профиль: ${UserName}`;
  518. presenceData.state = "Игнор-лист";
  519. break;
  520. }
  521. case "ban": {
  522. presenceData.details = "Мой профиль";
  523. presenceData.state = "История банов";
  524. break;
  525. }
  526. // No default
  527. }
  528. }
  529. break;
  530. }
  531. case "manga": {
  532. // Manga page
  533. if (Routes[1] === "create") {
  534. // create new manga
  535. presenceData.details = "Добавляет мангу";
  536. presenceData.smallImageText = "Пишет";
  537. presenceData.smallImageKey = Assets.Writing;
  538. const title = <HTMLInputElement>document.querySelector("#rus_name");
  539. if (title.value.length > 1) presenceData.state = title.value;
  540. else presenceData.state = "Имя тайтла не задано";
  541. } else {
  542. switch (Routes[2]) {
  543. case "edit": {
  544. // edit
  545. presenceData.smallImageText = "Редактирует";
  546. presenceData.smallImageKey = Assets.Writing;
  547. presenceData.details = document.querySelector(
  548. ".section__header .breadcrumb a"
  549. ).textContent;
  550. switch (Queries.section) {
  551. case "media-edit":
  552. presenceData.state = "Редактирование";
  553. break;
  554. case "changes":
  555. presenceData.state = "Список изменений";
  556. break;
  557. case "related-items":
  558. presenceData.state = "Связанные тайтлы";
  559. break;
  560. }
  561. break;
  562. }
  563. case "bulk-create": {
  564. // bulk create
  565. presenceData.details = "Добавляет главы";
  566. presenceData.smallImageText = "Добавляет";
  567. presenceData.smallImageKey = Assets.Uploading;
  568. presenceData.state = `Манга: ${
  569. document.querySelector(".section__header .breadcrumb a")
  570. .textContent
  571. }`;
  572. break;
  573. }
  574. case "add-chapter": {
  575. // add chapter
  576. presenceData.details = "Добавляет главу";
  577. presenceData.smallImageText = "Добавляет";
  578. presenceData.smallImageKey = Assets.Uploading;
  579. presenceData.state = `Манга: ${
  580. document.querySelector(".section__header .breadcrumb a")
  581. .textContent
  582. }`;
  583. break;
  584. }
  585. default: {
  586. presenceData.details = "Редактирует главу";
  587. presenceData.smallImageText = "Пишет";
  588. presenceData.smallImageKey = Assets.Writing;
  589. presenceData.state = `Манга: ${
  590. document.querySelector(".section__header .breadcrumb a")
  591. .textContent
  592. }`;
  593. }
  594. }
  595. }
  596. break;
  597. }
  598. default:
  599. if (document.querySelector(".reader")) {
  600. presenceData.details = "Читает тайтл";
  601. presenceData.state = document.title.split(" ").slice(2, -4).join(" ");
  602. presenceData.smallImageText = "Читает";
  603. presenceData.smallImageKey = Assets.Reading;
  604. presenceData.startTimestamp = getTimeStamp();
  605. } else {
  606. presenceData.details = "Смотрит тайтл";
  607. presenceData.state = document.title
  608. .split("/")[0]
  609. .split(" ")
  610. .slice(1)
  611. .join(" ");
  612. presenceData.smallImageText = "Читает";
  613. presenceData.smallImageKey = Assets.Reading;
  614. }
  615. }
  616. presence.setActivity(presenceData, true);
  617. });