123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- const presence: Presence = new Presence({
- clientId: "800166344023867443",
- }),
- browsingTimestamp = Math.floor(Date.now() / 1000);
- const enum Assets {
- Logo = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/logo.png",
- Avatar = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/0.png",
- Kanji = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/1.png",
- Radical = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/2.png",
- Vocabulary = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/3.png",
- Lessons0 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/4.png",
- Lessons1 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/5.png",
- Lessons25 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/6.png",
- Lessons50 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/7.png",
- Lessons100 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/8.png",
- Lessons250 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/9.png",
- Lessons500 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/10.png",
- Reviews0 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/11.png",
- Reviews1 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/12.png",
- Reviews50 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/13.png",
- Reviews100 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/14.png",
- Reviews250 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/15.png",
- Reviews500 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/16.png",
- Reviews1000 = "https://cdn.rcd.gg/PreMiD/websites/W/WaniKani/assets/17.png",
- }
- function capitalize(string: string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
- }
- function getTypeAsset(string: string) {
- switch (string.toLowerCase()) {
- case "kanji":
- return Assets.Kanji;
- case "radical":
- return Assets.Radical;
- case "vocabulary":
- return Assets.Vocabulary;
- default:
- return null;
- }
- }
- function getReviewPresence(): PresenceData {
- const data: PresenceData = {},
- characterType = [
- ...document.querySelector<HTMLDivElement>(
- '[data-quiz-header-base-class="character-header"]'
- ).classList,
- ]
- .find(cls => cls.startsWith("character-header--"))
- .split("--")[1],
- completeCount = document.querySelector<HTMLDivElement>(
- '[data-quiz-statistics-target="completeCount"]'
- );
- data.state = `${
- document.querySelector<HTMLDivElement>(
- '[data-quiz-header-target="characters"]'
- ).textContent
- } | ${capitalize(characterType)} ${capitalize(
- document.querySelector<HTMLDivElement>(
- '[data-quiz-input-target="questionTypeContainer"]'
- ).dataset.questionType
- )}`;
- if (completeCount) {
- data.smallImageText = `${completeCount.textContent} complete, ${
- document.querySelector<HTMLDivElement>(
- '[data-quiz-statistics-target="remainingCount"]'
- ).textContent
- } remaining. (${
- document.querySelector<HTMLDivElement>(
- '[data-quiz-statistics-target="percentCorrect"]'
- ).textContent
- }%)`;
- }
- data.smallImageKey = getTypeAsset(characterType);
- return data;
- }
- function getLessonPresence(): PresenceData {
- const presenceData: PresenceData = {},
- totalStats = document.querySelectorAll<HTMLDivElement>(
- '[data-controller="subject-count-statistics"] [data-subject-count-statistics-target="count"]'
- );
- presenceData.state = `${
- document.querySelector<HTMLDivElement>(
- '[data-quiz-header-target="characters"]'
- ).textContent
- } - ${
- document.querySelector<HTMLDivElement>(
- '[data-quiz-header-target="meaning"]'
- ).textContent
- }`;
- presenceData.smallImageKey = getTypeAsset(
- [
- ...document.querySelector<HTMLDivElement>(
- '[data-quiz-header-base-class="character-header"]'
- ).classList,
- ]
- .find(cls => cls.startsWith("character-header--"))
- .split("--")[1]
- );
- if (totalStats.length === 3)
- presenceData.smallImageText = `${totalStats[0].textContent} radicals | ${totalStats[1].textContent} kanji | ${totalStats[2].textContent} vocab`;
- return presenceData;
- }
- presence.on("UpdateData", () => {
- const { hostname, pathname } = document.location,
- presenceData: PresenceData = {
- largeImageKey: Assets.Logo,
- startTimestamp: browsingTimestamp,
- };
- switch (hostname) {
- case "wanikani.com":
- case "www.wanikani.com": {
- switch (pathname) {
- case "/":
- case "/dashboard":
- case "/login": {
- const buttons = document.querySelector(
- ".lessons-and-reviews"
- ).children;
- if (buttons.length === 2) {
- const lessons =
- +buttons[0].querySelector<HTMLSpanElement>("[class*=__count]")
- .textContent,
- reviews =
- +buttons[1].querySelector<HTMLSpanElement>("[class*=__count]")
- .textContent;
- presenceData.details = "Viewing Dashboard";
- presenceData.state = `${lessons} lessons | ${reviews} reviews`;
- presenceData.smallImageText =
- document.querySelector<HTMLAnchorElement>(
- ".user-summary__attribute > a"
- ).textContent;
- if (lessons > reviews) {
- if (lessons < 25) presenceData.smallImageKey = Assets.Lessons1;
- else if (lessons < 50)
- presenceData.smallImageKey = Assets.Lessons25;
- else if (lessons < 100)
- presenceData.smallImageKey = Assets.Lessons50;
- else if (lessons < 250)
- presenceData.smallImageKey = Assets.Lessons100;
- else if (lessons < 500)
- presenceData.smallImageKey = Assets.Lessons250;
- else presenceData.smallImageKey = Assets.Lessons500;
- } else if (reviews < 1)
- presenceData.smallImageKey = Assets.Reviews0;
- else if (reviews < 50) presenceData.smallImageKey = Assets.Reviews1;
- else if (reviews < 100)
- presenceData.smallImageKey = Assets.Reviews50;
- else if (reviews < 250)
- presenceData.smallImageKey = Assets.Reviews100;
- else if (reviews < 500)
- presenceData.smallImageKey = Assets.Reviews250;
- else if (reviews < 1000)
- presenceData.smallImageKey = Assets.Reviews500;
- else presenceData.smallImageKey = Assets.Reviews1000;
- } else {
- presenceData.details = "Browsing";
- presenceData.state = "Viewing Home Page";
- }
- break;
- }
- case "/subject-lessons/picker": {
- presenceData.details = "Choosing Lessons";
- break;
- }
- case "/subjects/extra_study": {
- presenceData.details = `Doing ${
- document.querySelector<HTMLDivElement>(
- ".character-header__menu-title"
- ).textContent
- }`;
- Object.assign(presenceData, getReviewPresence());
- break;
- }
- case pathname.match(/^\/recent-mistakes\/.*?\/quiz$/)?.input: {
- presenceData.details = "Doing Extra Study: Recent Mistakes";
- Object.assign(presenceData, getReviewPresence());
- break;
- }
- case pathname.match(/^\/recent-mistakes\/.*?\/subjects\/\d+\/lesson$/)
- ?.input: {
- presenceData.details = "Doing Extra Study: Recent Mistakes Lessons";
- Object.assign(presenceData, getLessonPresence());
- break;
- }
- case "/subjects/review": {
- presenceData.details = "Doing Reviews";
- Object.assign(presenceData, getReviewPresence());
- break;
- }
- case pathname.match(/^\/subject-lessons\/[-\d/]+\/quiz$/)?.input: {
- presenceData.details = "Practicing Lessons";
- Object.assign(presenceData, getReviewPresence());
- break;
- }
- case pathname.match(/^\/subject-lessons\/[-\d/]+/)?.input: {
- presenceData.details = "Learning Lessons";
- Object.assign(presenceData, getLessonPresence());
- break;
- }
- case pathname.match(/^\/(radicals|kanji|vocabulary)\/.+$/)?.input: {
- const [, type] = pathname.split("/");
- let textDescription =
- document.querySelector<HTMLElement>(
- ".mnemonic-content"
- ).textContent;
- if (textDescription.length >= 50)
- textDescription = `${textDescription.substring(0, 50)}...`;
- presenceData.details = `Browsing ${capitalize(type)}`;
- presenceData.state = `${
- document.querySelector<HTMLSpanElement>(
- `.${type.replace(/s$/, "")}-icon`
- ).textContent
- } | ${
- document.querySelector<HTMLSpanElement>(
- `.${type.replace(/s$/, "")}-icon`
- ).parentNode.childNodes[4].textContent
- }`;
- presenceData.smallImageText = textDescription;
- presenceData.smallImageKey = getTypeAsset(type.replace(/s$/, ""));
- break;
- }
- case pathname.match(/^\/users\/.+$/)?.input: {
- presenceData.details = "Viewing User Profile";
- presenceData.state =
- document.querySelector<HTMLSpanElement>(".username").textContent;
- presenceData.smallImageKey = Assets.Avatar;
- break;
- }
- default: {
- presenceData.details = "Browsing";
- presenceData.state = `Viewing ${document.title
- .split(" / ")
- .slice(1)
- .join(" / ")}`;
- }
- }
- break;
- }
- case "knowledge.wanikani.com": {
- presenceData.details = "Browsing WaniKani Knowledge";
- presenceData.state = document.title.split(" | ")[0];
- break;
- }
- case "community.wanikani.com": {
- if (/^\/u\/.+$/.test(pathname)) {
- presenceData.details = "Viewing User Profile";
- presenceData.smallImageKey = Assets.Avatar;
- presenceData.state =
- document.querySelector<HTMLHeadingElement>(".username").textContent;
- break;
- }
- presenceData.details = "Browsing WaniKani Community";
- presenceData.state = document.title.split(" - ")[0];
- break;
- }
- }
- presence.setActivity(presenceData);
- });
|