From 279b6b6b79fd8d77c96c3cf15408e8d1fd03eb4d Mon Sep 17 00:00:00 2001 From: SeMiD Date: Wed, 15 Jan 2025 20:50:42 +0000 Subject: [PATCH 01/20] chore(Claude): update assets (#9162) --- websites/C/Claude/metadata.json | 6 +++--- websites/C/Claude/presence.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/websites/C/Claude/metadata.json b/websites/C/Claude/metadata.json index 8ce8260effbc..3f381c89118a 100644 --- a/websites/C/Claude/metadata.json +++ b/websites/C/Claude/metadata.json @@ -12,9 +12,9 @@ "ja_JP": "Claude(クロード)とは、Anthropic社が開発した大規模言語モデルを用いた対話型生成AIである。2023年3月14日に一般公開され、以降複数のバージョンがリリースされている。\n\n2024年3月に公開されたClaude 3 OpusはメンサのIQテストでIQスコア101を記録した。「フレンドリーで熱心な同僚」をコンセプトの一つとしている。" }, "url": "claude.ai", - "version": "1.0.0", - "logo": "https://i.imgur.com/t2w5Nso.png", - "thumbnail": "https://i.imgur.com/qFa0XUT.jpeg", + "version": "1.0.1", + "logo": "https://cdn.rcd.gg/PreMiD/websites/C/Claude/assets/logo.png", + "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/C/Claude/assets/thumbnail.jpeg", "color": "#DA7756", "category": "other", "tags": [ diff --git a/websites/C/Claude/presence.ts b/websites/C/Claude/presence.ts index d241c157b9a1..5a7e7c51aefa 100644 --- a/websites/C/Claude/presence.ts +++ b/websites/C/Claude/presence.ts @@ -20,8 +20,8 @@ let oldLang: string = null, strings: Awaited>; const enum Assets { - Logo = "https://i.imgur.com/t2w5Nso.png", - Talking = "https://i.imgur.com/rnAQvqx.png", + Logo = "https://cdn.rcd.gg/PreMiD/websites/C/Claude/assets/logo.png", + Talking = "https://cdn.rcd.gg/PreMiD/websites/C/Claude/assets/0.png", } presence.on("UpdateData", async () => { From 39a9e91293f5a42731190d53b0336503acbfb58a Mon Sep 17 00:00:00 2001 From: SeMiD Date: Wed, 15 Jan 2025 20:50:58 +0000 Subject: [PATCH 02/20] chore(Phira): update assets (#9163) --- websites/P/Phira/metadata.json | 6 +++--- websites/P/Phira/presence.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/websites/P/Phira/metadata.json b/websites/P/Phira/metadata.json index 7194e5e202f2..3f09ac053144 100644 --- a/websites/P/Phira/metadata.json +++ b/websites/P/Phira/metadata.json @@ -10,9 +10,9 @@ "en": "Phigros Fanmade Community" }, "url": "phira.moe", - "version": "1.0.0", - "logo": "https://i.imgur.com/viZUl3y.png", - "thumbnail": "https://i.imgur.com/y3VWKWK.png", + "version": "1.0.1", + "logo": "https://cdn.rcd.gg/PreMiD/websites/P/Phira/assets/logo.png", + "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/P/Phira/assets/thumbnail.png", "color": "#6419e6", "category": "games", "tags": [ diff --git a/websites/P/Phira/presence.ts b/websites/P/Phira/presence.ts index 0c46801f37cc..826bde314a28 100644 --- a/websites/P/Phira/presence.ts +++ b/websites/P/Phira/presence.ts @@ -4,7 +4,7 @@ const presence = new Presence({ browsingTimestamp = Math.floor(Date.now() / 1000); const enum Assets { - Logo = "https://i.imgur.com/viZUl3y.png", + Logo = "https://cdn.rcd.gg/PreMiD/websites/P/Phira/assets/logo.png", } presence.on("UpdateData", async () => { From f6b73795276f7e8a65f3d4a4a3205838f7435606 Mon Sep 17 00:00:00 2001 From: darkitxu84 <76633266+darkitxu84@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:13:52 -0300 Subject: [PATCH 03/20] feat(PikiDiary): add activity (#9147) Signed-off-by: darkitxu84 <76633266+darkitxu84@users.noreply.github.com> Co-authored-by: Bas van Zanten Co-authored-by: github plz bring back DarkVIllager --- websites/P/PikiDiary/metadata.json | 23 +++++++ websites/P/PikiDiary/presence.ts | 107 +++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 websites/P/PikiDiary/metadata.json create mode 100644 websites/P/PikiDiary/presence.ts diff --git a/websites/P/PikiDiary/metadata.json b/websites/P/PikiDiary/metadata.json new file mode 100644 index 000000000000..1ec1cc48e675 --- /dev/null +++ b/websites/P/PikiDiary/metadata.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.12", + "apiVersion": 1, + "author": { + "id": "302505485519683585", + "name": "darkitxu84" + }, + "service": "PikiDiary", + "description": { + "en": "PikiDiary is a microblogging platform where you can record fun memories and share them with everyone!" + }, + "url": "pikidiary.lol", + "version": "1.0.0", + "logo": "https://i.imgur.com/R0nvAIA.png", + "thumbnail": "https://f.feridinha.com/ees9N.png", + "color": "#ABD022", + "category": "socials", + "tags": [ + "social", + "media", + "pikidiary" + ] +} \ No newline at end of file diff --git a/websites/P/PikiDiary/presence.ts b/websites/P/PikiDiary/presence.ts new file mode 100644 index 000000000000..068899759a59 --- /dev/null +++ b/websites/P/PikiDiary/presence.ts @@ -0,0 +1,107 @@ +const presence = new Presence({ + clientId: "1327078556802482206", + }), + getElement = (query: string): string | undefined => { + return document.querySelector(query)?.textContent; + }, + browsingTimestamp = Math.floor(Date.now() / 1000), + BROWSING_TEXTS = new Map([ + ["following", "their following posts..."], + ["me", "their own posts..."], + ["explore", "users posts..."], + ["tagged", "their tagged posts..."], + ]); + +const enum Assets { + Logo = "https://i.imgur.com/R0nvAIA.png", +} + +presence.on("UpdateData", async () => { + const presenceData: PresenceData = { + name: "PikiDiary", + type: ActivityType.Playing, + largeImageKey: Assets.Logo, + startTimestamp: browsingTimestamp, + }, + { pathname, search, href } = document.location; + + if (pathname === "/") presenceData.details = "Viewing home page"; + else if (pathname.includes("@")) { + // the @ means that we're in a user page + if (!document.querySelector(".info > a")) { + presenceData.details = `Viewing ${getElement(".info > span")} profile`; + presenceData.largeImageKey = + document.querySelector(".bar > div > img") ?? + Assets.Logo; + presenceData.buttons = [ + { + label: "View Profile", + url: href, + }, + ]; + } else { + // self profile + let slicedSearch = ""; + search ? (slicedSearch = search.slice(5)) : (slicedSearch = "following"); + presenceData.details = "Browsing through"; + presenceData.state = BROWSING_TEXTS.get(slicedSearch); + } + } else if (pathname.includes("live")) { + if (pathname.includes("studio")) { + const viewCount = getElement("#view-count"); + if (viewCount === "0") { + // not streaming yet + presenceData.details = "Managing their live..."; + presenceData.smallImageKey = Assets.Reading; + presenceData.smallImageText = "Setting up..."; + } else { + presenceData.details = + document.querySelector("#title-text").textContent; + presenceData.state = `Live on PikiDiary // ${viewCount} viewers`; + presenceData.largeImageKey = + document.querySelector(".avatar-small") ?? + Assets.Logo; // user avatar + presenceData.smallImageKey = Assets.Live; + presenceData.smallImageText = "Live"; + presenceData.buttons = [ + { + label: "Watch Live", + url: getElement("#share-link"), + }, + ]; + } + } else { + presenceData.type = ActivityType.Watching; + presenceData.details = getElement("#title-text"); // live name + presenceData.state = document.querySelectorAll("a")[4].textContent; // user name + presenceData.largeImageKey = + document.querySelector(".avatar-small") ?? + Assets.Logo; // user avatar + presenceData.smallImageKey = Assets.Live; + presenceData.smallImageText = "Live"; + presenceData.buttons = [ + { + label: "Watch Live", + url: href, + }, + ]; + } + } else if (pathname.includes("settings")) { + presenceData.details = "Setting up"; + presenceData.state = "their profile"; + } else if (pathname.includes("posts")) { + presenceData.details = `Reading a post of ${getElement(".post-name")}`; + presenceData.state = `${getElement(".like-count")} likes // ${ + document.querySelectorAll(".post-button")[1].textContent + } replys`; + presenceData.buttons = [ + { + label: "View Post", + url: href, + }, + ]; + } else if (pathname.includes("login")) presenceData.details = "Logging in"; + else if (pathname.includes("signup")) presenceData.details = "Signing up"; + + presence.setActivity(presenceData); +}); From 5d8bdc085130d2054b1304806ef738ce48091978 Mon Sep 17 00:00:00 2001 From: Anaxes <68460474+DiscordAnaxes@users.noreply.github.com> Date: Fri, 17 Jan 2025 05:00:39 +1000 Subject: [PATCH 04/20] feat(Freek): implement season and episode text through largeImageText (#9150) * feat(Freek): implement season and episode text through largeImageText * fix(fFreek): type error * chore(Freek): lint * fix(Freek): eslint error --------- Co-authored-by: Anaxes --- websites/F/Freek/metadata.json | 2 +- websites/F/Freek/presence.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/websites/F/Freek/metadata.json b/websites/F/Freek/metadata.json index e85e17475ca8..f678d3007fcd 100644 --- a/websites/F/Freek/metadata.json +++ b/websites/F/Freek/metadata.json @@ -10,7 +10,7 @@ "en": "Freek.to is a free movie, tv show and more streaming application, supporting high quality streams and friendly UI and UX experiences." }, "url": "freek.to", - "version": "1.0.2", + "version": "1.0.3", "logo": "https://cdn.rcd.gg/PreMiD/websites/F/Freek/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/F/Freek/assets/thumbnail.png", "color": "#121212", diff --git a/websites/F/Freek/presence.ts b/websites/F/Freek/presence.ts index 992111fa4c36..015c30210ac0 100644 --- a/websites/F/Freek/presence.ts +++ b/websites/F/Freek/presence.ts @@ -37,7 +37,6 @@ presence.on("UpdateData", async () => { let presenceData: PresenceData = { largeImageKey: Assets.Logo, startTimestamp: browsingTimestamp, - type: ActivityType.Watching, details: "Unsupported Page", }; @@ -73,8 +72,10 @@ presence.on("UpdateData", async () => { }, }; - for (const [path, data] of Object.entries(pages)) - if (pathname.includes(path)) presenceData = { ...presenceData, ...data }; + for (const [path, data] of Object.entries(pages)) { + if (pathname.includes(path)) + presenceData = { ...presenceData, ...data, type: ActivityType.Watching }; + } const pageNumber = href.includes("?page=") ? href.split("?page=")[1] : 1, searchInput = document.querySelector("input") @@ -127,9 +128,12 @@ presence.on("UpdateData", async () => { presenceData.details = steamTitle; presenceData.state = `📺 ${ episodeName - ? `${episodeNumber}. ${episodeName?.textContent}` + ? `${episodeName?.textContent}` : `Episode ${episodeNumber}` }`; + presenceData.largeImageText = `Season ${ + href.includes("?season=") ? href.split("?season=")[1] : 1 + }, Episode ${episodeNumber}`; presenceData.largeImageKey = document .querySelector( "div.flex > div.false > span.lazy-load-image-background > img" From c4ecd5b80368de1ca63ae49b34a1c82e14164c4c Mon Sep 17 00:00:00 2001 From: Nam Anh Date: Fri, 17 Jan 2025 02:02:15 +0700 Subject: [PATCH 05/20] feat(YouTube Music): utilize `largeImageText` for albums (#9156) * feat(YouTube Music): utilize `largeImageText` for albums * chore: bump version --------- Signed-off-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> Co-authored-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> --- websites/Y/YouTube Music/metadata.json | 2 +- websites/Y/YouTube Music/presence.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/websites/Y/YouTube Music/metadata.json b/websites/Y/YouTube Music/metadata.json index 7ceb95fc9db4..8ce62d1cb3a8 100644 --- a/websites/Y/YouTube Music/metadata.json +++ b/websites/Y/YouTube Music/metadata.json @@ -20,7 +20,7 @@ "vi_VN": "Một dịch vụ phát nhạc với các album, đĩa đơn, video, bản remix, và các tiết mục trực tiếp chính thức và hơn nữa cho Android, iOS và máy tính. Tất cả đều tại đây." }, "url": "music.youtube.com", - "version": "3.0.26", + "version": "3.0.27", "logo": "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/thumbnail.png", "color": "#E40813", diff --git a/websites/Y/YouTube Music/presence.ts b/websites/Y/YouTube Music/presence.ts index 338061a7f716..a54c473a67ae 100644 --- a/websites/Y/YouTube Music/presence.ts +++ b/websites/Y/YouTube Music/presence.ts @@ -129,8 +129,9 @@ presence.on("UpdateData", async () => { ? mediaSession?.metadata?.artwork?.at(-1)?.src ?? "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/1.png" : "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/1.png", - details: mediaSession.metadata.album, + details: mediaSession.metadata.title, state: mediaSession.metadata.artist, + largeImageText: mediaSession.metadata.album, ...(showButtons && { buttons, }), From dfcdefa731465402748dfea6d2e833e925ff6457 Mon Sep 17 00:00:00 2001 From: darkitxu84 <76633266+darkitxu84@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:05:11 -0300 Subject: [PATCH 06/20] fix(Twitch): %title% placeholder doesn't work with lives (#9168) * fix(Twitch): %title% placeholder doesn't work in lives * chore(Twitch): bump version * style(Twitch): use correct code style Co-authored-by: Bas van Zanten Signed-off-by: darkitxu84 <76633266+darkitxu84@users.noreply.github.com> --------- Signed-off-by: darkitxu84 <76633266+darkitxu84@users.noreply.github.com> Co-authored-by: Bas van Zanten --- websites/T/Twitch/metadata.json | 2 +- websites/T/Twitch/presence.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/websites/T/Twitch/metadata.json b/websites/T/Twitch/metadata.json index eaf38a8ffb36..8787be141899 100644 --- a/websites/T/Twitch/metadata.json +++ b/websites/T/Twitch/metadata.json @@ -46,7 +46,7 @@ "devstatus.twitch.tv", "status.twitch.tv" ], - "version": "3.2.25", + "version": "3.2.26", "logo": "https://cdn.rcd.gg/PreMiD/websites/T/Twitch/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/T/Twitch/assets/thumbnail.png", "color": "#9146FF", diff --git a/websites/T/Twitch/presence.ts b/websites/T/Twitch/presence.ts index a4c5cb7f64d7..46dc5c4719d5 100644 --- a/websites/T/Twitch/presence.ts +++ b/websites/T/Twitch/presence.ts @@ -458,7 +458,7 @@ presence.on("UpdateData", async () => { if (showLive && live) { //* Live - const title = getElement(".channel-info-content h2"), + const title = getElement("p[data-a-target='stream-title']"), streamer = document.querySelector(".channel-info-content h1")?.textContent ?? document From de12cfd7f0dd3dd7828d5cda38b62809c59000eb Mon Sep 17 00:00:00 2001 From: "Jules K." <89418218+julesk1702@users.noreply.github.com> Date: Thu, 16 Jan 2025 22:41:12 +0100 Subject: [PATCH 07/20] feat(Timeguessr): add activity (#9155) Signed-off-by: Jules K. <89418218+julesk1702@users.noreply.github.com> Co-authored-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> --- websites/T/Timeguessr/metadata.json | 31 +++++++++++ websites/T/Timeguessr/presence.ts | 81 +++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 websites/T/Timeguessr/metadata.json create mode 100644 websites/T/Timeguessr/presence.ts diff --git a/websites/T/Timeguessr/metadata.json b/websites/T/Timeguessr/metadata.json new file mode 100644 index 000000000000..19fb79dbe56a --- /dev/null +++ b/websites/T/Timeguessr/metadata.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.12", + "apiVersion": 1, + "author": { + "id": "408597063098695692", + "name": "happypossum" + }, + "service": "Timeguessr", + "description": { + "en": "Timeguessr is an interactive game that challenges you to guess the approximate year and location of a historical photo or event.", + "nl": "Timeguessr is een interactief spel dat je uitdaagt om het geschatte jaar en de locatie van een historische foto of gebeurtenis te raden." + }, + "url": "timeguessr.com", + "version": "1.0.0", + "logo": "https://i.imgur.com/4B7bshL.jpeg", + "thumbnail": "https://i.imgur.com/9z0xNOJ.png", + "color": "#DB5049", + "category": "games", + "tags": [ + "games", + "timeguessr" + ], + "settings": [ + { + "id": "privacy", + "title": "Privacy Mode", + "icon": "fad fa-shield-alt", + "value": false + } + ] +} \ No newline at end of file diff --git a/websites/T/Timeguessr/presence.ts b/websites/T/Timeguessr/presence.ts new file mode 100644 index 000000000000..d58474fc072d --- /dev/null +++ b/websites/T/Timeguessr/presence.ts @@ -0,0 +1,81 @@ +const presence = new Presence({ + clientId: "1327710845546922075", + }), + browsingTimestamp = Math.floor(Date.now() / 1000); + +presence.on("UpdateData", async () => { + const presenceData: PresenceData = { + largeImageKey: "https://i.imgur.com/4B7bshL.jpeg", + startTimestamp: browsingTimestamp, + }, + privacy = await presence.getSetting("privacy"), + { pathname } = document.location; + + if (!privacy) { + switch (pathname) { + case "/": + presenceData.details = "Warming up the time machine"; + break; + case "/privacypolicy": + presenceData.details = "Reading the fine print of time travel"; + break; + case "/login": + presenceData.details = "Logging into the past"; + break; + case "/createaccount": + presenceData.details = "Joining the timeguessers"; + break; + case "/submit": + presenceData.details = "Contributing to the time vault"; + break; + case "/game-settings": + presenceData.details = "Tuning the time machine"; + break; + case "/account": + presenceData.details = "Managing their historical identity"; + break; + case "/friends": + presenceData.details = "Catching up with fellow guessers"; + break; + case "/subscriptions": + presenceData.details = "Supporting the time machine"; + break; + } + + if (/\/round(one|two|three|four|five)(daily)?/.test(pathname)) { + presenceData.details = "Pinpointing moments in history"; + presenceData.state = `${ + document.querySelector(".progressBarText2")?.textContent + } | Score: ${ + document.querySelector("#insertScore")?.textContent ?? 0 + } | Mode: ${ + pathname + .match(/round(one|two|three|four|five)(daily)?/)[0] + .includes("daily") + ? "Daily" + : "Normal" + }`; + } else if ( + pathname === "/roundresults" || + pathname === "/dailyroundresults" + ) { + presenceData.details = `Round results | Total score: ${ + document.querySelector("#insertTotal")?.textContent ?? 0 + }`; + presenceData.state = `Year: ${ + document.querySelector("#insertYearScore")?.textContent || "0" + } | Location: ${ + document.querySelector("#insertLocationScore")?.textContent || "0" + }`; + } else if (pathname === "/finalscore" || pathname === "/finalscoredaily") { + presenceData.details = "Guessed all the places and times"; + presenceData.state = `Final score: ${ + document.querySelector("#totalText")?.textContent + }/50,000`; + } + } else { + presenceData.details = "Playing timeguessr under the radar"; + delete presenceData.state; + } + presence.setActivity(presenceData); +}); From 2b4aeff41dfddcd48c19b07ba01505286cec3b5a Mon Sep 17 00:00:00 2001 From: SeMiD Date: Thu, 16 Jan 2025 21:41:30 +0000 Subject: [PATCH 08/20] chore(PikiDiary): update assets (#9169) * chore: update assets Signed-off-by: SeMiD * chore: revert to initial version Signed-off-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> * chore: cast type --------- Signed-off-by: SeMiD Signed-off-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> Co-authored-by: Daniel Lau <32113157+theusaf@users.noreply.github.com> Co-authored-by: Bas950 --- websites/P/PikiDiary/metadata.json | 4 ++-- websites/P/PikiDiary/presence.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/websites/P/PikiDiary/metadata.json b/websites/P/PikiDiary/metadata.json index 1ec1cc48e675..903e24dbfad4 100644 --- a/websites/P/PikiDiary/metadata.json +++ b/websites/P/PikiDiary/metadata.json @@ -11,8 +11,8 @@ }, "url": "pikidiary.lol", "version": "1.0.0", - "logo": "https://i.imgur.com/R0nvAIA.png", - "thumbnail": "https://f.feridinha.com/ees9N.png", + "logo": "https://cdn.rcd.gg/PreMiD/websites/P/PikiDiary/assets/logo.png", + "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/P/PikiDiary/assets/thumbnail.png", "color": "#ABD022", "category": "socials", "tags": [ diff --git a/websites/P/PikiDiary/presence.ts b/websites/P/PikiDiary/presence.ts index 068899759a59..c18f581f25bf 100644 --- a/websites/P/PikiDiary/presence.ts +++ b/websites/P/PikiDiary/presence.ts @@ -13,7 +13,7 @@ const presence = new Presence({ ]); const enum Assets { - Logo = "https://i.imgur.com/R0nvAIA.png", + Logo = "https://cdn.rcd.gg/PreMiD/websites/P/PikiDiary/assets/logo.png", } presence.on("UpdateData", async () => { @@ -71,7 +71,7 @@ presence.on("UpdateData", async () => { ]; } } else { - presenceData.type = ActivityType.Watching; + (presenceData as PresenceData).type = ActivityType.Watching; presenceData.details = getElement("#title-text"); // live name presenceData.state = document.querySelectorAll("a")[4].textContent; // user name presenceData.largeImageKey = From 43f984bab54369883893de8415a36e77cf4874b2 Mon Sep 17 00:00:00 2001 From: Bruno Ramos <37979213+Kuriel23@users.noreply.github.com> Date: Thu, 16 Jan 2025 21:41:51 +0000 Subject: [PATCH 09/20] feat(Eurogamer): add activity (#9159) --- websites/E/Eurogamer/metadata.json | 43 +++++++ websites/E/Eurogamer/presence.ts | 182 +++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 websites/E/Eurogamer/metadata.json create mode 100644 websites/E/Eurogamer/presence.ts diff --git a/websites/E/Eurogamer/metadata.json b/websites/E/Eurogamer/metadata.json new file mode 100644 index 000000000000..a26dda3663c4 --- /dev/null +++ b/websites/E/Eurogamer/metadata.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.12", + "apiVersion": 1, + "author": { + "id": "354233941550694400", + "name": "kuriel." + }, + "service": "Eurogamer", + "description": { + "en": "Your trusted source for video game news, reviews and guides, since 1999.", + "de": "Eurogamer.de berichtet über PC- und Videospiele mit aktuellen News und Tests, Kommentaren, Tipps und Reportagen.", + "pt": "Eurogamer.pt é o maior website nacional sobre videojogos pertencente à maior rede europeia, Gamer Network.", + "pt_BR": "Eurogamer.pt é o maior website nacional sobre videojogos pertencente à maior rede europeia, Gamer Network.", + "nl": "Eurogamer.nl is de grootste nationale website over videogames van het grootste Europese netwerk, Gamer Network.", + "cs_CZ": "Eurogamer.cz je největší národní web o videohrách patřících do největší evropské sítě Gamer Network.", + "es": "Eurogamer.es es el sitio web nacional más grande sobre videojuegos que pertenecen a la red europea más grande, Gamer Network.", + "pl": "Eurogamer.pl to największa krajowa strona internetowa o grach wideo należących do największej sieci europejskiej, Gamer Network." + }, + "url": [ + "www.eurogamer.net", + "www.eurogamer.pt", + "www.eurogamer.cz", + "www.eurogamer.de", + "www.eurogamer.es", + "www.eurogamer.nl", + "www.eurogamer.pl" + ], + "version": "1.0.0", + "logo": "https://i.imgur.com/L2r2n5e.png", + "thumbnail": "https://i.imgur.com/TtRjcA3.png", + "color": "#007cbf", + "category": "games", + "tags": [ + "news", + "gaming" + ], + "settings": [ + { + "id": "lang", + "multiLanguage": true + } + ] +} \ No newline at end of file diff --git a/websites/E/Eurogamer/presence.ts b/websites/E/Eurogamer/presence.ts new file mode 100644 index 000000000000..3dc301011396 --- /dev/null +++ b/websites/E/Eurogamer/presence.ts @@ -0,0 +1,182 @@ +const presence = new Presence({ + clientId: "1328434205486612582", + }), + browsingTimestamp = Math.floor(Date.now() / 1000); + +const enum Assets { + Logo = "https://i.imgur.com/L2r2n5e.png", +} + +async function getStrings() { + return presence.getStrings({ + search: "general.searchFor", + viewHome: "general.viewHome", + buttonViewPage: "general.buttonViewPage", + read: "general.readingArticle", + thread: "general.readingThread", + viewList: "general.viewList", + viewMovie: "general.viewMovie", + viewGenre: "general.viewGenre", + viewing: "general.viewing", + viewCategory: "general.viewCategory", + support: "general.support", + viewProfile: "general.viewProfile", + }); +} + +let strings: Awaited>, + oldLang: string = null; + +presence.on("UpdateData", async () => { + const presenceData: PresenceData = { + largeImageKey: Assets.Logo, + startTimestamp: browsingTimestamp, + }, + newLang = await presence.getSetting("lang").catch(() => "en"), + { pathname, href, search } = document.location; + + if (oldLang !== newLang || !strings) { + oldLang = newLang; + strings = await getStrings(); + } + + switch (pathname.split("/")[1]) { + case "latest": { + presenceData.details = "Viewing latest articles"; + break; + } + case "companies": { + presenceData.details = "Viewing company:"; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "community": { + presenceData.details = strings.viewProfile; + presenceData.state = document.querySelector(".page_title"); + presenceData.largeImageKey = + document.querySelector(".avatar_image")?.src ?? + Assets.Logo; + break; + } + case "pc": + case "nintendo": + case "playstation": + case "xbox": + case "digital-foundry": + case "news": + case "reviews": + case "videos": + case "features": + case "guides": + case "deals": { + presenceData.details = strings.viewCategory; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "platforms": { + presenceData.details = "Viewing platform:"; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "genres": { + presenceData.details = strings.viewGenre; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "topics": { + presenceData.details = "Viewing topic:"; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "movies": { + presenceData.details = strings.viewMovie; + presenceData.state = document.querySelector(".page_title"); + presenceData.largeImageKey = + document.querySelector(".cover_image")?.src ?? + Assets.Logo; + break; + } + case "video-game-franchises": { + presenceData.details = strings.viewList; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "games": { + presenceData.details = "Viewing game:"; + presenceData.state = document.querySelector(".page_title"); + presenceData.largeImageKey = + document.querySelector(".cover_image")?.src ?? + Assets.Logo; + break; + } + case "authors": { + presenceData.details = "Viewing author:"; + presenceData.state = document.querySelector(".page_title"); + break; + } + case "archive": { + presenceData.details = "Viewing a archive"; + break; + } + case "about-us": { + presenceData.details = "Viewing about us page"; + break; + } + case "contact-us": { + presenceData.details = "Viewing contact us page"; + break; + } + case "subscribe": { + presenceData.details = strings.viewing; + presenceData.state = strings.support; + break; + } + case "code-of-conduct": + case "editorial-policy": + case "review-policy": + case "terms-and-conditions": { + presenceData.details = strings.viewing; + presenceData.state = document.querySelector(".section_title"); + break; + } + case "maps": { + presenceData.details = "Viewing interactive maps"; + if (pathname.split("/")[2]) { + presenceData.details = "Viewing interactive map:"; + presenceData.state = document.querySelector(".section_title"); + } + break; + } + case "search": { + presenceData.details = strings.search; + presenceData.state = decodeURIComponent( + search.split("=")[1].replaceAll("+", " ") + ); + break; + } + default: { + if (pathname.split("/")[1].length >= 1) { + if (search && search.split("=")[1].includes("comments")) { + presenceData.details = strings.thread; + presenceData.state = document + .querySelector(".page_title") + .textContent.replace(/.*["](.*?)["]$/, "$1") + .trim(); + } else { + presenceData.details = strings.read; + presenceData.state = document.querySelector(".title"); + presenceData.buttons = [ + { + label: strings.buttonViewPage, + url: href, + }, + ]; + } + } else presenceData.details = strings.viewHome; + + break; + } + } + + presence.setActivity(presenceData); +}); From 7ca7a5d6b552fc72b113688fdeba1f44f80c338d Mon Sep 17 00:00:00 2001 From: Kito Date: Fri, 17 Jan 2025 10:39:23 +0300 Subject: [PATCH 10/20] chore(AnimeLib): cache current dub (#9165) --- websites/A/AnimeLib/metadata.json | 20 +++++++++++++------- websites/A/AnimeLib/presence.ts | 25 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/websites/A/AnimeLib/metadata.json b/websites/A/AnimeLib/metadata.json index 56ec41c1381c..3dbef3ee869a 100644 --- a/websites/A/AnimeLib/metadata.json +++ b/websites/A/AnimeLib/metadata.json @@ -14,19 +14,25 @@ "ru": "Смотрите аниме онлайн на русском" }, "url": "anilib.me", - "version": "1.0.5", + "version": "1.0.6", "logo": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeLib/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeLib/assets/thumbnail.png", "color": "#A020F0", "category": "anime", "tags": [ "anime", - "video", - "community" + "community", + "lib" ], "iframe": true, "iFrameRegExp": "kodik[.]info", "settings": [ + { + "id": "privacy", + "title": "Privacy Mode", + "icon": "fad fa-shield-alt", + "value": false + }, { "id": "buttons", "title": "Show Buttons", @@ -34,10 +40,10 @@ "value": true }, { - "id": "privacy", - "title": "Privacy Mode", - "icon": "fad fa-user-secret", + "id": "titleAsPresence", + "title": "Show Anime Title As Presence", + "icon": "fad fa-user-edit", "value": false } ] -} \ No newline at end of file +} diff --git a/websites/A/AnimeLib/presence.ts b/websites/A/AnimeLib/presence.ts index 6fea0b8b06f3..20253257b26b 100644 --- a/websites/A/AnimeLib/presence.ts +++ b/websites/A/AnimeLib/presence.ts @@ -37,7 +37,7 @@ const isPrivacyMode = (setting: boolean, ageRestriction?: AgeRestriction) => cleanUrl = (location: Location) => location.href.replace(location.search, "").replace("/watch", ""); -let iFrameVideo: IFrameVideo; +let iFrameVideo: IFrameVideo, currentDub: string; presence.on("iFrameData", (data: IFrameVideo) => { iFrameVideo = data; @@ -51,9 +51,10 @@ presence.on("UpdateData", async () => { largeImageText: "AnimeLib", smallImageText: "AnimeLib", }, - [privacySetting, buttonsSetting] = await Promise.all([ + [privacySetting, buttonsSetting, titleSetting] = await Promise.all([ presence.getSetting("privacy"), presence.getSetting("buttons"), + presence.getSetting("titleAsPresence"), ]), path = document.location.pathname; @@ -115,15 +116,25 @@ presence.on("UpdateData", async () => { .querySelectorAll(".btn.is-outline")[7] ?.querySelector("span")?.textContent; - if (dub) { - presenceData.details = + if (dub || currentDub) { + /** + * This makes sure that the dub will always be defined. + * When user changes menu between dubs/subs, the menu items are different, + * so it's not possible to get the current active item if it's in a different menu. + */ + if (dub) currentDub = dub; + + const title = animeData.rus_name !== "" ? animeData.rus_name : animeData.name; + + titleSetting + ? (presenceData.name = title) + : (presenceData.details = title); presenceData.state = `${ episode ? (episode.includes("эпизод") ? episode : "Фильм") : "Фильм" - } | ${dub}`; + } | ${currentDub}`; presenceData.largeImageKey = animeData.cover.default; - presenceData.largeImageText = - animeData.rus_name !== "" ? animeData.rus_name : animeData.name; + presenceData.largeImageText = title; presenceData.buttons = [ { label: "Открыть аниме", From 153e661355c9c65aca38cd32a15cac9c90f2b9f1 Mon Sep 17 00:00:00 2001 From: Slowlife Date: Fri, 17 Jan 2025 23:46:40 +0700 Subject: [PATCH 11/20] fix(YouTube Music): only set largeImageText when needed (#9176) --- websites/Y/YouTube Music/metadata.json | 2 +- websites/Y/YouTube Music/presence.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/websites/Y/YouTube Music/metadata.json b/websites/Y/YouTube Music/metadata.json index 8ce62d1cb3a8..64edb54ed239 100644 --- a/websites/Y/YouTube Music/metadata.json +++ b/websites/Y/YouTube Music/metadata.json @@ -20,7 +20,7 @@ "vi_VN": "Một dịch vụ phát nhạc với các album, đĩa đơn, video, bản remix, và các tiết mục trực tiếp chính thức và hơn nữa cho Android, iOS và máy tính. Tất cả đều tại đây." }, "url": "music.youtube.com", - "version": "3.0.27", + "version": "3.0.28", "logo": "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/thumbnail.png", "color": "#E40813", diff --git a/websites/Y/YouTube Music/presence.ts b/websites/Y/YouTube Music/presence.ts index a54c473a67ae..bba9840795d5 100644 --- a/websites/Y/YouTube Music/presence.ts +++ b/websites/Y/YouTube Music/presence.ts @@ -131,7 +131,9 @@ presence.on("UpdateData", async () => { : "https://cdn.rcd.gg/PreMiD/websites/Y/YouTube%20Music/assets/1.png", details: mediaSession.metadata.title, state: mediaSession.metadata.artist, - largeImageText: mediaSession.metadata.album, + ...(mediaSession.metadata.album && { + largeImageText: mediaSession.metadata.album, + }), ...(showButtons && { buttons, }), From f8b4d64f10a140a74cb06570028c55475bdd2f24 Mon Sep 17 00:00:00 2001 From: Florian Metz Date: Fri, 17 Jan 2025 18:16:16 +0100 Subject: [PATCH 12/20] wip: test out security scan Signed-off-by: Florian Metz --- .github/workflows/eslint.yml | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/eslint.yml diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml new file mode 100644 index 000000000000..d6c67210b65e --- /dev/null +++ b/.github/workflows/eslint.yml @@ -0,0 +1,52 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# ESLint is a tool for identifying and reporting on patterns +# found in ECMAScript/JavaScript code. +# More details at https://github.com/eslint/eslint +# and https://eslint.org + +name: ESLint + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '44 1 * * 4' + +jobs: + eslint: + name: Run eslint scanning + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install ESLint + run: | + npm install eslint@8.10.0 + npm install @microsoft/eslint-formatter-sarif@3.1.0 + + - name: Run ESLint + env: + SARIF_ESLINT_IGNORE_SUPPRESSED: "true" + run: npx eslint . + --config .eslintrc.json + --ext .js,.jsx,.ts,.tsx + --format @microsoft/eslint-formatter-sarif + --output-file eslint-results.sarif + continue-on-error: true + + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: eslint-results.sarif + wait-for-processing: true From 019371c4b3c418c2648bb988a2c50a535e931342 Mon Sep 17 00:00:00 2001 From: Florian Metz Date: Fri, 17 Jan 2025 18:18:45 +0100 Subject: [PATCH 13/20] wip: testing --- .github/workflows/eslint.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index d6c67210b65e..bf0d421386a7 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -11,12 +11,12 @@ name: ESLint on: push: - branches: [ "main" ] + branches: ["main"] pull_request: # The branches below must be a subset of the branches above - branches: [ "main" ] + branches: ["main"] schedule: - - cron: '44 1 * * 4' + - cron: "44 1 * * 4" jobs: eslint: @@ -32,17 +32,13 @@ jobs: - name: Install ESLint run: | - npm install eslint@8.10.0 + npm install npm install @microsoft/eslint-formatter-sarif@3.1.0 - name: Run ESLint env: SARIF_ESLINT_IGNORE_SUPPRESSED: "true" - run: npx eslint . - --config .eslintrc.json - --ext .js,.jsx,.ts,.tsx - --format @microsoft/eslint-formatter-sarif - --output-file eslint-results.sarif + run: npx eslint . --config .eslintrc.json --ext .js,.jsx,.ts,.tsx --format @microsoft/eslint-formatter-sarif --output-file eslint-results.sarif continue-on-error: true - name: Upload analysis results to GitHub From dfdc2f6e8e584cd729a3239afdad9b9018e4f924 Mon Sep 17 00:00:00 2001 From: SeMiD Date: Fri, 17 Jan 2025 17:44:29 +0000 Subject: [PATCH 14/20] chore(Timeguessr): update assets (#9173) chore: update assets Signed-off-by: SeMiD --- websites/T/Timeguessr/metadata.json | 6 +++--- websites/T/Timeguessr/presence.ts | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/websites/T/Timeguessr/metadata.json b/websites/T/Timeguessr/metadata.json index 19fb79dbe56a..ee9143f5d2b7 100644 --- a/websites/T/Timeguessr/metadata.json +++ b/websites/T/Timeguessr/metadata.json @@ -11,9 +11,9 @@ "nl": "Timeguessr is een interactief spel dat je uitdaagt om het geschatte jaar en de locatie van een historische foto of gebeurtenis te raden." }, "url": "timeguessr.com", - "version": "1.0.0", - "logo": "https://i.imgur.com/4B7bshL.jpeg", - "thumbnail": "https://i.imgur.com/9z0xNOJ.png", + "version": "1.0.1", + "logo": "https://cdn.rcd.gg/PreMiD/websites/T/Timeguessr/assets/logo.jpeg", + "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/T/Timeguessr/assets/thumbnail.png", "color": "#DB5049", "category": "games", "tags": [ diff --git a/websites/T/Timeguessr/presence.ts b/websites/T/Timeguessr/presence.ts index d58474fc072d..279d3143f1b7 100644 --- a/websites/T/Timeguessr/presence.ts +++ b/websites/T/Timeguessr/presence.ts @@ -5,7 +5,8 @@ const presence = new Presence({ presence.on("UpdateData", async () => { const presenceData: PresenceData = { - largeImageKey: "https://i.imgur.com/4B7bshL.jpeg", + largeImageKey: + "https://cdn.rcd.gg/PreMiD/websites/T/Timeguessr/assets/logo.jpeg", startTimestamp: browsingTimestamp, }, privacy = await presence.getSetting("privacy"), From ccc69a9f9051af89633046f9bb0d8594d93d15d8 Mon Sep 17 00:00:00 2001 From: Bas van Zanten Date: Fri, 17 Jan 2025 19:44:55 +0100 Subject: [PATCH 15/20] feat: send i18n file to extension in dev mode (#9175) Co-authored-by: Florian Metz --- cli/bin/actions/modify.js | 7 ++++++- cli/src/actions/modify.ts | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cli/bin/actions/modify.js b/cli/bin/actions/modify.js index 90432a62cfc3..ee847a1a6b2f 100644 --- a/cli/bin/actions/modify.js +++ b/cli/bin/actions/modify.js @@ -93,6 +93,11 @@ class Compiler { from: resolve(this.cwd, "metadata.json"), to: "metadata.json", }, + { + from: resolve(this.cwd, `${service}.json`), + to: `${service}.json`, + noErrorOnMissing: true, + }, ], }), new webpack.WatchIgnorePlugin({ @@ -243,4 +248,4 @@ async function sendPresenceToExtension(path) { })), })); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kaWZ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FjdGlvbnMvbW9kaWZ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBd0IsTUFBTSxPQUFPLENBQUM7QUFFN0MsT0FBTyxFQUFZLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdkMsT0FBTyxNQUFNLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxlQUFlLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxZQUFZLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTNDLE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUM5QixPQUFPO0tBQ0wsa0JBQWtCLEVBQUU7S0FDcEIsTUFBTSxDQUFDLHlCQUF5QixDQUFDO0tBQ2pDLEtBQUss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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kaWZ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FjdGlvbnMvbW9kaWZ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBd0IsTUFBTSxPQUFPLENBQUM7QUFFN0MsT0FBTyxFQUFZLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdkMsT0FBTyxNQUFNLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxlQUFlLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxZQUFZLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTNDLE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUM5QixPQUFPO0tBQ0wsa0JBQWtCLEVBQUU7S0FDcEIsTUFBTSxDQUFDLHlCQUF5QixDQUFDO0tBQ2pDLEtBQUss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 \ No newline at end of file diff --git a/cli/src/actions/modify.ts b/cli/src/actions/modify.ts index caffab880a0e..4ee9272309a1 100644 --- a/cli/src/actions/modify.ts +++ b/cli/src/actions/modify.ts @@ -117,6 +117,11 @@ class Compiler { from: resolve(this.cwd, "metadata.json"), to: "metadata.json", }, + { + from: resolve(this.cwd, `${service}.json`), + to: `${service}.json`, + noErrorOnMissing: true, + }, ], }), new webpack.WatchIgnorePlugin({ From dc986b83863490fab1248ba08397920499f17602 Mon Sep 17 00:00:00 2001 From: SeMiD Date: Fri, 17 Jan 2025 18:48:21 +0000 Subject: [PATCH 16/20] chore(AnimeLib): format metadata (#9174) --- websites/A/AnimeLib/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/websites/A/AnimeLib/metadata.json b/websites/A/AnimeLib/metadata.json index 3dbef3ee869a..2f8c49888b66 100644 --- a/websites/A/AnimeLib/metadata.json +++ b/websites/A/AnimeLib/metadata.json @@ -14,7 +14,7 @@ "ru": "Смотрите аниме онлайн на русском" }, "url": "anilib.me", - "version": "1.0.6", + "version": "1.0.7", "logo": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeLib/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeLib/assets/thumbnail.png", "color": "#A020F0", @@ -46,4 +46,4 @@ "value": false } ] -} +} \ No newline at end of file From 035f0cee1812aa6c8d3b8e8132347cf4afac81af Mon Sep 17 00:00:00 2001 From: Bruno Ramos <37979213+Kuriel23@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:49:52 +0000 Subject: [PATCH 17/20] feat(Brave Search): use strings (#9166) * feat(Brave Search): use strings * feat(Brave Search): add i18n * feat(Brave Search): formatting i18n file * feat(Brave Search): new setting for multilanguage --- websites/B/Brave Search/Brave Search.json | 42 ++++++++++++++++ websites/B/Brave Search/metadata.json | 6 ++- websites/B/Brave Search/presence.ts | 61 ++++++++++++++++++----- 3 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 websites/B/Brave Search/Brave Search.json diff --git a/websites/B/Brave Search/Brave Search.json b/websites/B/Brave Search/Brave Search.json new file mode 100644 index 000000000000..45bc13dc265d --- /dev/null +++ b/websites/B/Brave Search/Brave Search.json @@ -0,0 +1,42 @@ +{ + "bravesearch.settings": { + "description": "Page name", + "message": "Viewing their settings..." + }, + "bravesearch.help": { + "description": "Page name", + "message": "Help Center" + }, + "bravesearch.searchImgFor": { + "description": "Displayed when the user is searching for an image. The search query will be displayed below.", + "message": "Searching images for:" + }, + "bravesearch.searchImgSomething": { + "description": "Displayed when the user is searching for an image.", + "message": "Searching up images..." + }, + "bravesearch.searchNewsFor": { + "description": "Displayed when the user is searching for a news. The search query will be displayed below.", + "message": "Searching news for:" + }, + "bravesearch.searchNewsSomething": { + "description": "Displayed when the user is searching for a news.", + "message": "Searching up news..." + }, + "bravesearch.searchGogglesFor": { + "description": "Displayed when the user is searching for an goggle. The search query will be displayed below.", + "message": "Searching goggles for:" + }, + "bravesearch.searchGogglesSomething": { + "description": "Displayed when the user is searching for an goggle.", + "message": "Searching up goggles..." + }, + "bravesearch.searchVidFor": { + "description": "Displayed when the user is searching for an video. The search query will be displayed below.", + "message": "Searching videos for:" + }, + "bravesearch.searchVidSomething": { + "description": "Displayed when the user is searching for an video.", + "message": "Searching up videos..." + } +} diff --git a/websites/B/Brave Search/metadata.json b/websites/B/Brave Search/metadata.json index 71278e6703d8..b9729cd0e090 100644 --- a/websites/B/Brave Search/metadata.json +++ b/websites/B/Brave Search/metadata.json @@ -10,7 +10,7 @@ "en": "Search the Web. Privately. Truly useful results, AI-powered answers, & more. All from an independent index. No profiling, no bias, no Big Tech." }, "url": "search.brave.com", - "version": "1.0.2", + "version": "1.0.3", "logo": "https://cdn.rcd.gg/PreMiD/websites/B/Brave%20Search/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/B/Brave%20Search/assets/thumbnail.png", "color": "#FB542B", @@ -24,6 +24,10 @@ "title": "Privacy Mode", "icon": "fad fa-user-secret", "value": false + }, + { + "id": "lang", + "multiLanguage": true } ] } \ No newline at end of file diff --git a/websites/B/Brave Search/presence.ts b/websites/B/Brave Search/presence.ts index 529d6290c19d..e25dda1182c8 100644 --- a/websites/B/Brave Search/presence.ts +++ b/websites/B/Brave Search/presence.ts @@ -7,13 +7,42 @@ const enum Assets { Logo = "https://cdn.rcd.gg/PreMiD/websites/B/Brave%20Search/assets/logo.png", } +async function getStrings() { + return presence.getStrings({ + search: "general.searchFor", + searchPrivate: "general.searchSomething", + home: "general.viewHome", + viewPage: "general.viewPage", + settings: "bravesearch.settings", + help: "bravesearch.help", + searchNews: "bravesearch.searchNewsFor", + searchNewsPrivate: "bravesearch.searchNewsSomething", + searchVid: "bravesearch.searchVidFor", + searchVidPrivate: "bravesearch.searchVidSomething", + searchImg: "bravesearch.searchImgFor", + searchImgPrivate: "bravesearch.searchImgSomething", + searchGoggles: "bravesearch.searchNewsFor", + searchGogglesPrivate: "bravesearch.searchNewsSomething", + }); +} + +let strings: Awaited>, + oldLang: string = null; + presence.on("UpdateData", async () => { + const newLang = await presence.getSetting("lang").catch(() => "en"); + + if (oldLang !== newLang || !strings) { + oldLang = newLang; + strings = await getStrings(); + } + const { pathname } = document.location, privacy = await presence.getSetting("privacy"), presenceData: PresenceData = { largeImageKey: Assets.Logo, startTimestamp: browsingTimestamp, - details: "In Home", + details: strings.home, state: privacy ? // eslint-disable-next-line no-undefined undefined @@ -22,37 +51,43 @@ presence.on("UpdateData", async () => { switch (pathname.split("/")[1]) { case "settings": { - presenceData.details = "Viewing Settings"; + presenceData.details = strings.settings; delete presenceData.state; break; } case "help": { - if (!privacy) { - presenceData.details = "Viewing Help Page:"; - presenceData.state = document - .querySelector(".post-title") - ?.textContent?.trim(); - } else presenceData.details = "Viewing Help Pages"; + presenceData.details = strings.viewPage; + presenceData.state = !privacy + ? document.querySelector(".post-title")?.textContent?.trim() + : strings.help; break; } case "search": { - presenceData.details = `Searching${!privacy ? ":" : "..."}`; + presenceData.details = !privacy ? strings.search : strings.searchPrivate; break; } case "images": { - presenceData.details = `Searching images${!privacy ? ":" : "..."}`; + presenceData.details = !privacy + ? strings.searchImg + : strings.searchImgPrivate; break; } case "news": { - presenceData.details = `Searching news${!privacy ? ":" : "..."}`; + presenceData.details = !privacy + ? strings.searchNews + : strings.searchNewsPrivate; break; } case "videos": { - presenceData.details = `Searching videos${!privacy ? ":" : "..."}`; + presenceData.details = !privacy + ? strings.searchVid + : strings.searchVidPrivate; break; } case "goggles": { - presenceData.details = `Searching goggles${!privacy ? ":" : "..."}`; + presenceData.details = !privacy + ? strings.searchGoggles + : strings.searchGogglesPrivate; break; } default: { From 7cab80bf8ad5524fa9c6c9b3b280884091d725e8 Mon Sep 17 00:00:00 2001 From: Bruno Ramos <37979213+Kuriel23@users.noreply.github.com> Date: Fri, 17 Jan 2025 18:50:48 +0000 Subject: [PATCH 18/20] =?UTF-8?q?chore(Tsuki=20Mang=C3=A1s):=20delete=20ac?= =?UTF-8?q?tivity=20(#9178)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../T/Tsuki Mang\303\241s/metadata.json" | 72 ----- "websites/T/Tsuki Mang\303\241s/presence.ts" | 283 ------------------ 2 files changed, 355 deletions(-) delete mode 100644 "websites/T/Tsuki Mang\303\241s/metadata.json" delete mode 100644 "websites/T/Tsuki Mang\303\241s/presence.ts" diff --git "a/websites/T/Tsuki Mang\303\241s/metadata.json" "b/websites/T/Tsuki Mang\303\241s/metadata.json" deleted file mode 100644 index 34b070560032..000000000000 --- "a/websites/T/Tsuki Mang\303\241s/metadata.json" +++ /dev/null @@ -1,72 +0,0 @@ -{ - "$schema": "https://schemas.premid.app/metadata/1.12", - "apiVersion": 1, - "author": { - "name": "Slowftw", - "id": "325046217904226306" - }, - "service": "Tsuki Mangás", - "description": { - "en": "Tsuki Mangás is an brazilian manga reader; read your favorite mangas in your smartphone, tablet, computer or any other device. Save your favorite characters and follow the latest releases.", - "pt_BR": "Tsuki Mangás é um leitor de mangás brasileiro; leia seus mangás favoritos no seu smartphone, tablet, computador ou qualquer outro dispositivo. Salve seus personagens favoritos e siga os últimos lançamentos.", - "nl": "Tsuki Mangás is een Braziliaanse manga-lezer; lees je favoriete manga's op je smartphone, tablet, computer of een ander apparaat. Sla je favoriete personages op en volg de nieuwste releases." - }, - "url": "tsukimangas.com", - "version": "1.4.25", - "logo": "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/logo.png", - "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/thumbnail.png", - "color": "#161616", - "category": "anime", - "tags": [ - "manga", - "reading" - ], - "settings": [ - { - "id": "showHistory", - "title": "[Global] Mostrar Histórico", - "icon": "fas fa-history", - "value": true - }, - { - "id": "showUserName", - "title": "[Global] Mostrar Username", - "icon": "fas fa-eye", - "value": true - }, - { - "id": "showComment", - "title": "[/leitor] Mostrar Comentário", - "icon": "fas fa-comment", - "value": true - }, - { - "id": "showReport", - "title": "[/leitor] Mostrar Report", - "icon": "fas fa-exclamation-triangle", - "value": true - }, - { - "id": "resetTimestamp", - "title": "[Global] Reiniciar Timestamp", - "icon": "fas fa-hourglass", - "value": false - }, - { - "id": "darkResource", - "title": "[Global] Dark Resources", - "icon": "fas fa-coffee", - "value": false - }, - { - "id": "logo", - "title": "[Global] Logo", - "icon": "fas fa-bookmark", - "value": 0, - "values": [ - "Nuvem", - "Livro" - ] - } - ] -} \ No newline at end of file diff --git "a/websites/T/Tsuki Mang\303\241s/presence.ts" "b/websites/T/Tsuki Mang\303\241s/presence.ts" deleted file mode 100644 index 57ff56df1709..000000000000 --- "a/websites/T/Tsuki Mang\303\241s/presence.ts" +++ /dev/null @@ -1,283 +0,0 @@ -const presence = new Presence({ - clientId: "714001239351885904", -}); - -enum ResourceNames { - logo = "logo", - reading = "reading", - search = "search", - writing = "writing", - history = "history", - info = "info", -} - -/* eslint-disable camelcase */ -const assets = { - logo_cloud_dark: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/0.png", - logo_book_dark: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/1.png", - logo_book: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/2.png", - logo_cloud: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/3.png", - reading_dark: Assets.Reading, - writing: Assets.Writing, - reading: Assets.Reading, - search_dark: Assets.Search, - search: Assets.Search, - writing_dark: Assets.Writing, - history_dark: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/4.png", - history: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/5.png", - info: "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/6.png", - info_dark: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/7.png", - hatsune_miku: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/8.png", - bell: "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/9.png", - bell_dark: - "https://cdn.rcd.gg/PreMiD/websites/T/Tsuki%20Mang%C3%A1s/assets/10.png", -}; -/* eslint-enable camelcase */ - -async function Resource(ResourceSelected: ResourceNames): Promise { - let value = ResourceSelected.toString(); - const logo = await presence.getSetting("logo"), - darkmode = await presence.getSetting("darkResource"); - if (ResourceSelected === ResourceNames.logo) - logo !== 0 ? (value += "_book") : (value += "_cloud"); - if (darkmode) value += "_dark"; - return assets[value as keyof typeof assets]; -} - -function getPagination(pagN: number): number[] { - const pagination = document.querySelectorAll(".pagination")[pagN]; - let current = 1, - max = 1; - if (pagination) { - current = parseInt(pagination.querySelectorAll(".active")[0].textContent); - for (const item of pagination.childNodes) { - if ( - item.nodeName === "LI" && - !isNaN(parseInt(item.textContent)) && - parseInt(item.textContent) > max - ) - max = parseInt(item.textContent); - } - } - return [current, max]; -} -let browsingTimestamp = Math.floor(Date.now() / 1000); -presence.on("UpdateData", async () => { - const pathName = window.location.pathname, - notfound = - window.location.pathname === "/404" || - document.querySelectorAll(".notfound").length !== 0, - presenceData: PresenceData = { - largeImageKey: await Resource(ResourceNames.logo), - }; - if (await presence.getSetting("resetTimestamp")) - browsingTimestamp = Math.floor(Date.now() / 1000); - if (pathName === "/") { - let lancamentos = "..."; - const qlancamentos = document.querySelectorAll("div.leflist > div"); - if (qlancamentos.length > 0) { - for (const item of qlancamentos) { - if (item.className.includes("activedlanca")) - lancamentos = item.textContent; - } - } - presenceData.details = "Início"; - presenceData.state = `Lançamentos: ${lancamentos}`; - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/login") && !notfound) { - presenceData.details = "Logando..."; - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/registrar") && !notfound) { - presenceData.details = "Registrando..."; - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/lista-mangas") && !notfound) { - presenceData.details = `Lista de Mangás - Página ${getPagination(0)[0]}/${ - getPagination(0)[1] - }`; - let Generos = ""; - const GenerosN = document.querySelectorAll( - "div.multiselect>div>div>span>span" - ); - if (GenerosN.length > 0) { - for (const item of GenerosN) { - if (Generos.length === 0) Generos += item.textContent; - else Generos += `, ${item.textContent}`; - } - } - presenceData.state = `Gêneros: ${!Generos.trim() ? "Todos" : Generos}`; - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/perfil/") && !notfound) { - const username = document.querySelector("#capapl > b"), - [sessionUsername] = ( - document.querySelector("#menu>li>ul>a") as HTMLLinkElement - ).href - .split("/") - .slice(-1), - usernameValue = [0, "...", true]; - if (!(await presence.getSetting("showUserName"))) { - usernameValue[1] = "👁‍🗨👁‍🗨"; - usernameValue[3] = false; - } else usernameValue[3] = true; - if ( - username && - username.textContent.trim() && - pathName.split("/").slice(-1)[0] !== "editar" - ) { - usernameValue[0] = 0; - if (usernameValue[3]) usernameValue[1] = username.textContent; - } else if ( - pathName.split("/").length === 4 && - sessionUsername && - sessionUsername.trim() && - sessionUsername === pathName.split("/").slice(-2)[0] - ) { - usernameValue[0] = 1; - if (usernameValue[3]) usernameValue[1] = sessionUsername; - } else if ( - pathName.split("/").length === 4 && - sessionUsername && - sessionUsername.trim() && - pathName.split("/").slice(-1)[0] === "editar" && - sessionUsername !== pathName.split("/").slice(-2)[0] - ) { - usernameValue[0] = 0; - if (usernameValue[3]) [usernameValue[1]] = pathName.split("/").slice(-2); - } - presenceData.details = - usernameValue[0] === 0 ? "Vizualizando Perfil:" : "Editando Perfil:"; - presenceData.state = usernameValue[1].toString(); - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/manga/") && !notfound) { - const MangaDefaultName = document.querySelector( - "#app > div.manga.mtopmanga > div.all > div.rigt > div.tity > h2 > b" - ), - qMangaAltNames = document.querySelector( - "#app > div.manga.mtopmanga > div.all > div.lef > div.altt" - ); - let MangaAltNames = "", - MangaName = "..."; - if (MangaDefaultName && MangaDefaultName.textContent.trim()) { - if (qMangaAltNames && qMangaAltNames.textContent.trim()) - MangaAltNames = ` (${qMangaAltNames.textContent})`; - MangaName = MangaDefaultName.textContent + MangaAltNames; - } - presenceData.details = "Visualizando Mangá:"; - presenceData.state = MangaName; - const qgender = document.querySelector("div.mtop>span"); - let gender = ""; - if (qgender) { - for (const item of qgender.childNodes) { - if (item.textContent === "Gêneros:") continue; - if (gender !== "") gender += ", "; - gender += item.textContent.replace(/^\s+|\s+$/g, ""); - } - } - if (gender !== "") { - presenceData.smallImageKey = await Resource(ResourceNames.search); - presenceData.smallImageText = gender; - } - presenceData.startTimestamp = browsingTimestamp; - } else if (pathName.startsWith("/leitor/") && !notfound) { - const overlay = document.querySelector( - "#app > div.manga > div.v--modal-overlay" - ), - qmanga = document.querySelector("b.f20"), - qchapter = document.querySelector("b.f14c"), - qpage = document.querySelector("select.backgsla.frightrr"), - manga = qmanga ? qmanga.textContent : "..."; - let chapter = qchapter ? qchapter.textContent : "...", - page = "..."; - if (qpage) { - page = (qpage as HTMLInputElement).value; - isNaN(parseInt(page)) - ? page.trim() - ? (page = " - Páginas abertas") - : (page = "...") - : (page = ` - Página ${page}`); - } - presenceData.smallImageKey = await Resource(ResourceNames.reading); - presenceData.smallImageText = "Lendo..."; - presenceData.details = manga.trim() ? manga : "..."; - if (chapter.trim() && chapter.includes("-")) { - chapter = chapter.replace(/^\s+|\s+$/g, ""); - chapter = `${chapter.split(" - ")[0]} - "${chapter.split(" - ")[1]}"`; - } - presenceData.state = chapter + page; - if ( - (await presence.getSetting("showComment")) && - overlay && - overlay.getAttribute("data-modal").includes("comentarios") - ) { - presenceData.smallImageKey = await Resource(ResourceNames.writing); - presenceData.smallImageText = "Comentando..."; - } else if ( - (await presence.getSetting("showReport")) && - overlay && - overlay.getAttribute("data-modal").includes("report") - ) { - presenceData.smallImageKey = await Resource(ResourceNames.info); - presenceData.smallImageText = "Reportando..."; - } - presenceData.startTimestamp = browsingTimestamp; - } else if ( - pathName.startsWith("/scan/") && - pathName !== "/scan/" && - !notfound - ) { - const scanName = document.querySelector( - "#app > div.scan > div.contentscan > div > h2" - ), - qscanMembers = document.querySelectorAll( - "#app > div.scan > div.contentscan > div > div.membrosscan > b" - ).length; - let scanMembers; - qscanMembers > 0 - ? (scanMembers = ` - ${qscanMembers.toString()} Membros`) - : (scanMembers = " - 0 Membros"); - presenceData.details = "Visualizando Grupo:"; - presenceData.state = `${ - (scanName !== null && scanName.textContent.trim() - ? scanName.textContent - : "...") + scanMembers - } - Página ${getPagination(0)[0]}/${getPagination(0)[1]}`; - presenceData.startTimestamp = browsingTimestamp; - } - if ( - (await presence.getSetting("showHistory")) && - document.querySelectorAll(".historicob").length !== 0 && - parseInt( - document - .querySelectorAll(".historicob")[0] - .parentElement.style.width.replace("%", "") - ) !== 0 - ) { - let hSession; - for (const item of document.querySelectorAll("div.selecths")) { - if (item.classList[item.classList.length - 1].includes("selecths")) - hSession = `${item.childNodes[0].textContent} ${item.childNodes[1].textContent}`; - } - const qUser = document.querySelector("#menu>li>ul>a"); - let user = qUser - ? (qUser as HTMLLinkElement).href.split("/").slice(-1)[0] - : "..."; - presenceData.details = "Vizualizando Histórico:"; - presenceData.state = `${document - .querySelectorAll(".activmancap")[0] - .textContent.replace(/^\s+|\s+$/g, "")} - ${hSession} - Página ${ - getPagination(0)[0] - }/${getPagination(0)[1]}`; - if (!(await presence.getSetting("showUserName"))) user = "👁‍🗨👁‍🗨"; - presenceData.smallImageKey = await Resource(ResourceNames.history); - presenceData.smallImageText = `Username: ${user}`; - } - if (!presenceData.details) presence.setActivity(); - else presence.setActivity(presenceData); -}); From 9ee4bc65e1329be46c37de6fb725a5dce69a7f83 Mon Sep 17 00:00:00 2001 From: Florian Metz Date: Fri, 17 Jan 2025 22:07:03 +0100 Subject: [PATCH 19/20] chore: remove eslint from lint:ci --- .github/workflows/eslint.yml | 2 -- package.json | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index bf0d421386a7..1ea6e0fa5dac 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -15,8 +15,6 @@ on: pull_request: # The branches below must be a subset of the branches above branches: ["main"] - schedule: - - cron: "44 1 * * 4" jobs: eslint: diff --git a/package.json b/package.json index d828f4c1f4f8..2314fb685a62 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "pmd -m", "lint": "eslint --cache --fix . && prettier --cache --write .", - "lint:ci": "eslint --cache . && prettier --cache --check .", + "lint:ci": "prettier --cache --check .", "format": "npm run metadataSorter && npm run lint", "schemaEnforcer": "npm run format && npm run bumpChanged", "compileTools": "tsc -p tools/tsconfig.json", @@ -56,4 +56,4 @@ "pmd": "file:cli", "prettier": "2.8.1" } -} +} \ No newline at end of file From ce59ef35974db1340886976a6a9ef63550efbd9e Mon Sep 17 00:00:00 2001 From: Kuriel <37979213+Kuriel23@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:52:58 +0000 Subject: [PATCH 20/20] feat(Pi Fansubs): add activity --- websites/P/Pi Fansubs/iframe.ts | 22 ++++ websites/P/Pi Fansubs/metadata.json | 29 +++++ websites/P/Pi Fansubs/presence.ts | 175 ++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 websites/P/Pi Fansubs/iframe.ts create mode 100644 websites/P/Pi Fansubs/metadata.json create mode 100644 websites/P/Pi Fansubs/presence.ts diff --git a/websites/P/Pi Fansubs/iframe.ts b/websites/P/Pi Fansubs/iframe.ts new file mode 100644 index 000000000000..d396fb96ba9a --- /dev/null +++ b/websites/P/Pi Fansubs/iframe.ts @@ -0,0 +1,22 @@ +const iframe = new iFrame(); + +iframe.on("UpdateData", async () => { + let video: HTMLVideoElement; + + if (document.querySelector(".jw-video")) + video = document.querySelector(".jw-video"); + else if (document.querySelector(".html5-video-container")) + video = document.querySelector(".html5-video-container > video"); + + if (video && !isNaN(video.duration)) { + iframe.send({ + iframeVideo: { + iFrameVideo: true, + currTime: video.currentTime, + dur: video.duration, + paused: video.paused, + }, + }); + } +}); + diff --git a/websites/P/Pi Fansubs/metadata.json b/websites/P/Pi Fansubs/metadata.json new file mode 100644 index 000000000000..02dbe4c229a9 --- /dev/null +++ b/websites/P/Pi Fansubs/metadata.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.12", + "apiVersion": 1, + "author": { + "id": "354233941550694400", + "name": "kuriel." + }, + "service": "Pi Fansubs", + "description": { + "en": "PiFansubs is a free brazilian streaming site where you can watch subtitled bls content.", + "pt": "PiFansubs é um site de streaming gratuito onde você pode assistir a conteúdos bls legendados.", + "pt_BR": "PiFansubs é um site de streaming gratuito onde você pode assistir a conteúdos bls legendados." + }, + "url": [ + "pifansubs.club", + "www.pifansubs.club" + ], + "version": "1.0.0", + "logo": "https://i.imgur.com/RNFFxad.jpeg", + "thumbnail": "https://i.imgur.com/sGD1G3v.png", + "color": "#00be08", + "category": "videos", + "tags": [ + "series", + "movies" + ], + "iframe": true, + "iFrameRegExp": "blsplayer[.]com|csst[.]online|pifansubs[.]club" +} \ No newline at end of file diff --git a/websites/P/Pi Fansubs/presence.ts b/websites/P/Pi Fansubs/presence.ts new file mode 100644 index 000000000000..8b946681534e --- /dev/null +++ b/websites/P/Pi Fansubs/presence.ts @@ -0,0 +1,175 @@ +const presence = new Presence({ + clientId: "1329883342132351058", + }), + strings = presence.getStrings({ + playing: "general.playing", + paused: "general.paused", + searchFor: "general.searchFor", + viewHome: "general.viewHome", + viewGenre: "general.viewGenre", + viewPage: "general.viewPage", + viewSeries: "general.viewSeries", + viewMovie: "general.viewMovie", + buttonViewSeries: "general.buttonViewSeries", + buttonViewEpisode: "general.buttonViewEpisode", + buttonWatchMovie: "general.buttonWatchMovie", + viewCategory: "general.viewCategory", + }), + browsingTimestamp = Math.floor(Date.now() / 1000); + +const enum Assets { + Logo = "https://i.imgur.com/RNFFxad.jpeg", +} + +let iFrameVideo: boolean, currentTime: number, duration: number; + +interface IFrameData { + iframeVideo: { + iFrameVideo: boolean; + currTime: number; + dur: number | null; + }; +} + +presence.on("iFrameData", (data: IFrameData) => { + if (data.iframeVideo.dur) { + ({ iFrameVideo } = data.iframeVideo); + currentTime = data.iframeVideo.currTime; + duration = data.iframeVideo.dur; + } +}); + +function textContent(tags: string) { + return document.querySelector(tags)?.textContent?.trim(); +} + +function getImage(tags: string) { + return document.querySelector(tags)?.src ?? Assets.Logo; +} + +presence.on("UpdateData", async () => { + const { pathname, href, search } = document.location, + path = pathname.split("/"), + presenceData: PresenceData = { + largeImageKey: Assets.Logo, + startTimestamp: browsingTimestamp, + details: (await strings).viewHome, + type: ActivityType.Watching, + }; + + switch (path[1]) { + case "release": { + presenceData.details = "Vendo lançamentos de:"; + presenceData.state = textContent(".heading-archive"); + break; + } + case "genre": { + presenceData.details = (await strings).viewGenre; + presenceData.state = textContent(".heading-archive"); + break; + } + case "series-de-tv": { + if (path[2] && path[2] !== "page") { + presenceData.details = (await strings).viewSeries; + presenceData.state = textContent( + ".sheader > div:nth-child(2) > h1:nth-child(1)" + ); + presenceData.largeImageKey = getImage(".poster > img:nth-child(1)"); + presenceData.buttons = [ + { + label: (await strings).buttonViewSeries, + url: href, + }, + ]; + } else presenceData.details = "Explorando Séries"; + break; + } + case "filmes": { + if (path[2] && path[2] !== "page") { + presenceData.details = (await strings).viewMovie; + presenceData.state = textContent( + ".sheader > div:nth-child(2) > h1:nth-child(1)" + ); + presenceData.largeImageKey = getImage(".poster > img:nth-child(1)"); + if (iFrameVideo && !isNaN(duration)) { + [presenceData.startTimestamp, presenceData.endTimestamp] = + presence.getTimestamps( + Math.floor(currentTime), + Math.floor(duration) + ); + presenceData.smallImageKey = Assets.Play; + presenceData.smallImageText = (await strings).playing; + } else { + presenceData.smallImageKey = Assets.Pause; + presenceData.smallImageText = (await strings).paused; + } + presenceData.buttons = [ + { + label: (await strings).buttonWatchMovie, + url: href, + }, + ]; + } else presenceData.details = "Explorando Filmes"; + break; + } + case "episodios": { + if (path[2] && path[2] !== "page") { + const match = textContent(".epih1").match(/(\d+)x(\d+)/); + + presenceData.details = (await strings).viewSeries; + presenceData.state = textContent(".epih1").replace(/: (\d+)x(\d+)/, ""); + presenceData.largeImageKey = getImage( + ".mark-1 > div:nth-child(1) > img:nth-child(1)" + ); + presenceData.largeImageText = match + ? `Season ${match[1]}, Episode ${match[2]}` + : textContent(".epih1"); + if (iFrameVideo && !isNaN(duration)) { + [presenceData.startTimestamp, presenceData.endTimestamp] = + presence.getTimestamps( + Math.floor(currentTime), + Math.floor(duration) + ); + presenceData.smallImageKey = Assets.Play; + presenceData.smallImageText = (await strings).playing; + } else { + presenceData.smallImageKey = Assets.Pause; + presenceData.smallImageText = (await strings).paused; + } + presenceData.buttons = [ + { + label: (await strings).buttonViewEpisode, + url: href, + }, + ]; + } else presenceData.details = "Explorando Episódios"; + break; + } + case "avisos-e-informacoes": { + presenceData.details = (await strings).viewPage; + presenceData.state = "Avisos"; + break; + } + case "category": { + presenceData.details = (await strings).viewCategory; + presenceData.state = textContent( + ".content > header:nth-child(1) > h1:nth-child(1)" + ).replace("Category Archives: ", ""); + break; + } + default: { + if (search) { + presenceData.details = (await strings).searchFor; + presenceData.state = decodeURI(search.split("=")[1]).replaceAll( + "+", + " " + ); + } else if (path[1].length >= 1) { + presenceData.details = (await strings).viewPage; + presenceData.state = textContent(".titl"); + } + break; + } + } + presence.setActivity(presenceData); +});