diff --git a/websites/K/KickAssAnime/iframe.ts b/websites/K/KickAssAnime/iframe.ts index 6b21549e6833..440701679dbb 100644 --- a/websites/K/KickAssAnime/iframe.ts +++ b/websites/K/KickAssAnime/iframe.ts @@ -5,10 +5,16 @@ iframe.on("UpdateData", async () => { const video: HTMLVideoElement = document.querySelector("video"); if (video && !isNaN(video.duration)) { iframe.send({ + exists: true, duration: video.duration, currentTime: video.currentTime, paused: video.paused, }); + } else if (video) { + iframe.send({ + exists: true, + paused: true, + }); } } }); diff --git a/websites/K/KickAssAnime/metadata.json b/websites/K/KickAssAnime/metadata.json index 055fd6151ff5..da0a33921b2e 100644 --- a/websites/K/KickAssAnime/metadata.json +++ b/websites/K/KickAssAnime/metadata.json @@ -14,8 +14,8 @@ "kickassanime.lol", "kickassanime.ro" ], - "regExp": "(([a-z0-9-]+[.])*kickassanime([.][a-z]+)+[/])|((www[0-9]*[.])?(kickassanime[.][a-z]+))", - "version": "1.1.9", + "regExp": "(([a-z0-9-]+[.])*kickassanime([.][a-z]+)+)|(kaas[.].*)|((www[0-9]*[.])?(kickassanime[.][a-z]+))", + "version": "1.2.0", "logo": "https://cdn.rcd.gg/PreMiD/websites/K/KickAssAnime/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/K/KickAssAnime/assets/thumbnail.png", "color": "#c7c95b", @@ -39,10 +39,10 @@ "value": true }, { - "id": "cover", - "title": "Show Cover", + "id": "episode-cover", + "title": "Show Episode Thumbnail", "icon": "fad fa-images", - "value": true + "value": false } ] } \ No newline at end of file diff --git a/websites/K/KickAssAnime/presence.ts b/websites/K/KickAssAnime/presence.ts index 8e92249360d9..1541a3f48db4 100644 --- a/websites/K/KickAssAnime/presence.ts +++ b/websites/K/KickAssAnime/presence.ts @@ -1,12 +1,9 @@ const presence = new Presence({ - clientId: "802964241179082822", - }), - nextEpisodeElement = document.querySelector( - "div#sidebar-anime-info > div.border.rounded.mb-3.p-3:nth-child(2) > div:nth-child(1) > a.ka-url-wrapper" - ), - previousEpisodeElement = document.querySelector( - "div#sidebar-anime-info > div.border.rounded.mb-3.p-3:nth-child(2) > div:nth-child(2) > a.ka-url-wrapper" - ); + clientId: "802964241179082822", +}); +const enum Assets { + Logo = "https://cdn.rcd.gg/PreMiD/websites/K/KickAssAnime/assets/logo.png", +} async function getStrings() { return presence.getStrings( @@ -19,6 +16,7 @@ async function getStrings() { viewing: "general.viewing", searching: "general.searchFor", episode: "general.episode", + browse: "general.browsing", }, await presence.getSetting("lang").catch(() => "en") ); @@ -26,64 +24,27 @@ async function getStrings() { let browsingTimestamp = Math.floor(Date.now() / 1000), video = { + exists: false, duration: 0, currentTime: 0, paused: true, }, - currentTime: number, - duration: number, - paused = true, lastPlaybackState: boolean = null, playback: boolean, - currentAnimeTitle: string, - currentAnimeEpisode: string, - isMovie: boolean = null, - episodeNumber, strings: Awaited>, oldLang: string = null; -interface AppData { - anime: { - types?: [ - { - name: string; - } - ]; - }; -} - -function checkIfMovie() { - !nextEpisodeElement && !previousEpisodeElement - ? (isMovie = true) - : nextEpisodeElement && !previousEpisodeElement - ? (isMovie = false) - : !nextEpisodeElement && previousEpisodeElement - ? (isMovie = false) - : nextEpisodeElement && previousEpisodeElement - ? (isMovie = false) - : (isMovie = true); - - !isMovie - ? presence.getPageletiable("appData").then(appData => { - isMovie = appData.anime.types?.find( - (x: { name: string }) => x.name === "Movie" - ) - ? true - : false; - }) - : presence.info( - "Unable to determine if show is a Movie or TV Series.\nYou may be watching an OVA, or this is broken & you need to contact Striker#1337" - ); -} - presence.on( "iFrameData", - (data: { duration: number; currentTime: number; paused: boolean }) => { + (data: { + exists: boolean; + duration: number; + currentTime: number; + paused: boolean; + }) => { video = data; playback = video.duration !== null ? true : false; - if (playback) ({ currentTime, duration, paused } = video); - if (lastPlaybackState !== playback) { lastPlaybackState = playback; browsingTimestamp = Math.floor(Date.now() / 1000); @@ -93,198 +54,105 @@ presence.on( presence.on("UpdateData", async () => { const presenceData: PresenceData = { - largeImageKey: - "https://cdn.rcd.gg/PreMiD/websites/K/KickAssAnime/assets/logo.png", + largeImageKey: Assets.Logo, startTimestamp: browsingTimestamp, }, [buttons, newLang, cover] = await Promise.all([ presence.getSetting("buttons"), presence.getSetting("lang"), - presence.getSetting("cover"), - ]); + presence.getSetting("episode-cover"), + ]), + { pathname, hostname, href } = document.location, + fullUrl = (string: string) => + string ? `https://${hostname}${string}` : Assets.Logo; if (oldLang !== newLang) { oldLang = newLang; strings = await getStrings(); } - - if ( - document.location.pathname.includes("/anime/") && - document.location.pathname.includes("/episode") - ) { - checkIfMovie(); - if (playback && !isNaN(duration)) { - presenceData.smallImageKey = paused ? Assets.Pause : Assets.Play; - presenceData.smallImageText = paused ? strings.pause : strings.play; - [presenceData.startTimestamp, presenceData.endTimestamp] = - presence.getTimestamps(Math.floor(currentTime), Math.floor(duration)); - currentAnimeTitle = - document.querySelector( - "a.ka-url-wrapper" - ).textContent; - [, currentAnimeEpisode] = document.location.pathname - .split("/")[3] - .split("-"); - if (!isMovie) { - if (currentAnimeEpisode[0] === "0") - episodeNumber = currentAnimeEpisode.replace("0", ""); - else episodeNumber = currentAnimeEpisode; - - currentAnimeEpisode = `${strings.episode} ${episodeNumber}`; - - if (buttons) { - presenceData.buttons = [ - { - label: strings.watchEpisode, - url: document.URL, - }, - { - label: strings.viewSeries, - url: document.URL.replace(document.URL.split("/")[5], ""), - }, - ]; - } - - presenceData.largeImageKey = cover - ? document - .querySelector("div.info-header") - .style.backgroundImage.match(/"(.*)"/)[1] - : "kaa"; - } else { - currentAnimeEpisode = "Movie"; - - if (buttons) { - presenceData.buttons = [ - { - label: strings.watchEpisode, - url: document.URL, - }, - { - label: strings.viewMovie, - url: document.URL.replace(document.URL.split("/")[5], ""), - }, - ]; + switch (true) { + case video.exists: { + if (playback && !isNaN(video.duration)) { + presenceData.smallImageKey = video.paused ? Assets.Pause : Assets.Play; + presenceData.smallImageText = video.paused ? "Paused" : "Playing"; + if (!video.paused) { + [, presenceData.endTimestamp] = presence.getTimestamps( + video.currentTime, + video.duration + ); } + presenceData.buttons = [ + { + label: "Watch Video", + url: href, + }, + ]; } - - presenceData.details = currentAnimeTitle; - presenceData.state = currentAnimeEpisode; - - if (paused) { - delete presenceData.startTimestamp; - delete presenceData.endTimestamp; - } - } else { - currentAnimeTitle = - document.querySelector( - "a.ka-url-wrapper" - ).textContent; - [, currentAnimeEpisode] = document.location.pathname - .split("/")[3] - .split("-"); - if (!isMovie) { - if (currentAnimeEpisode[0] === "0") - episodeNumber = currentAnimeEpisode.replace("0", ""); - else episodeNumber = currentAnimeEpisode; - - currentAnimeEpisode = `${strings.episode} ${episodeNumber}`; - - if (buttons) { - presenceData.buttons = [ - { - label: strings.watchEpisode, - url: document.URL, - }, - { - label: strings.viewSeries, - url: document.URL.replace(document.URL.split("/")[5], ""), - }, - ]; - } - } else { - currentAnimeEpisode = "Movie"; - - if (buttons) { - presenceData.buttons = [ - { - label: strings.watchEpisode, - url: document.URL, - }, - { - label: strings.viewMovie, - url: document.URL.replace(document.URL.split("/")[5], ""), - }, - ]; - } - } - - presenceData.details = `${currentAnimeTitle}`; - presenceData.state = `${currentAnimeEpisode}`; - - if (paused) { - delete presenceData.startTimestamp; - delete presenceData.endTimestamp; - } - } - } else if ( - document.location.pathname.includes("/anime/") && - document.location.pathname.includes("/episode") === false - ) { - currentAnimeTitle = - document.querySelector("h1.title").textContent; - presenceData.details = strings.viewing; - presenceData.state = `${currentAnimeTitle}`; - presenceData.smallImageKey = Assets.Search; - presenceData.largeImageKey = cover - ? document - .querySelector("div.poster") - .style.backgroundImage.match(/"(.*)"/)[1] - : "kaa"; - - if (buttons) { + delete presenceData.startTimestamp; + presenceData.details = + document + .querySelector('[name="og:title"]') + ?.getAttribute("content") + ?.split("-")[1] ?? + document + .evaluate( + "//script[contains(., 'layout:')]", + document, + null, + XPathResult.ANY_TYPE, + null + ) + ?.iterateNext() + ?.textContent?.match(/title_en:".{1,256}",/gm)?.[0] + ?.replace(/(title_en:")|(",)/gm, ""); + presenceData.state = document + .querySelector('[name="og:title"]') + ?.getAttribute("content") + ?.split("-")[2]; + presenceData.largeImageKey = fullUrl( + document.querySelector('[name="og:image"]')?.getAttribute("content") + ); presenceData.buttons = [ { label: strings.viewSeries, - url: document.URL, + url: href, }, ]; + break; + } + case pathname.includes("schedule"): { + presenceData.details = strings.viewing; + presenceData.state = "The schedule"; + break; + } + case pathname.includes("recent"): { + presenceData.details = strings.viewing; + presenceData.state = "Recently added anime"; + break; + } + case pathname.includes("popular"): { + presenceData.details = strings.viewing; + presenceData.state = "Popular anime"; + break; + } + case pathname.includes("anime"): { + presenceData.details = strings.viewing; + presenceData.state = "All anime"; + break; + } + case pathname.includes("trending"): { + presenceData.details = strings.viewing; + presenceData.state = "Trending anime"; + break; } - } else if (document.location.pathname.includes("anime-list")) { - presenceData.details = strings.viewing; - presenceData.state = "Anime List"; - presenceData.smallImageKey = Assets.Search; - } else if (document.location.pathname.includes("new-season")) { - presenceData.details = strings.viewing; - presenceData.state = "New Season"; - presenceData.smallImageKey = Assets.Search; - } else if (document.location.pathname.includes("favorites")) { - presenceData.details = strings.viewing; - presenceData.state = "Their Favorites"; - presenceData.smallImageKey = Assets.Search; - } else if (document.location.pathname.includes("watched")) { - presenceData.details = strings.viewing; - presenceData.state = "Watch History"; - presenceData.smallImageKey = Assets.Search; - } else if (document.location.pathname.includes("search")) { - presenceData.details = strings.searching; - presenceData.state = document - .querySelector("#content > h1") - .textContent.split('"')[1]; - presenceData.smallImageKey = Assets.Search; - if (cover) { - presenceData.largeImageKey = document - .querySelector("#content > div > div:nth-child(1) > a") - .style.background.replace('url("', "") - .replace('") center center / cover no-repeat', ""); + default: { + presenceData.details = strings.browse; + break; } - } else if (document.location.pathname === "/") { - presenceData.details = strings.viewing; - presenceData.state = "Home Page"; - presenceData.smallImageKey = Assets.Search; - } else { - presenceData.details = strings.viewing; - presenceData.state = "An Unsupported Page"; } + if (!buttons && presenceData.buttons) delete presenceData.buttons; + if (!cover && presenceData.largeImageKey !== Assets.Logo) + presenceData.largeImageKey = Assets.Logo; presence.setActivity(presenceData); });