diff --git a/websites/A/AnimeSaturn/iframe.ts b/websites/A/AnimeSaturn/iframe.ts new file mode 100644 index 000000000000..73e7685d1ecd --- /dev/null +++ b/websites/A/AnimeSaturn/iframe.ts @@ -0,0 +1,14 @@ +const iframe = new iFrame() + +iframe.on('UpdateData', async () => { + const video = document.querySelector('video') + if (video && !Number.isNaN(video.duration)) { + iframe.send({ + video: { + paused: video.paused, + currentTime: video.currentTime, + duration: video.duration, + }, + }) + } +}) diff --git a/websites/A/AnimeSaturn/metadata.json b/websites/A/AnimeSaturn/metadata.json index a141996b474d..f63add6f3254 100644 --- a/websites/A/AnimeSaturn/metadata.json +++ b/websites/A/AnimeSaturn/metadata.json @@ -1,18 +1,25 @@ { - "$schema": "https://schemas.premid.app/metadata/1.16", + "$schema": "https://schemas.premid.app/metadata/1.17", "apiVersion": 1, "author": { - "id": "533014724569333770", - "name": "_hikki_" + "id": "671037171611729920", + "name": "Skully" }, + "contributors": [ + { + "id": "533014724569333770", + "name": "_hikki_" + } + ], "service": "AnimeSaturn", "description": { "en": "AnimeSaturn is a streaming website (italian subbed) where you can watch over 62000 episodes and 4200 anime for free", + "fr": "AnimeSaturn est un site de streaming (sous-titré en italien) où vous pouvez regarder plus de 62000 épisodes et 4200 anime gratuitement", "it": "AnimeSaturn è una piattaforma di streaming dove puoi guardare oltre 62.000 episodi e 4200 anime gratuitamente" }, - "url": "www.animesaturn.cx", - "regExp": "^https?[:][/][/](www[.])?animesaturn[.]cx[/]", - "version": "1.1.1", + "url": "www.animesaturn.net", + "regExp": "^https?[:][/][/](www[.])?animesaturn[.]net[/]", + "version": "2.0.0", "logo": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeSaturn/assets/logo.png", "thumbnail": "https://cdn.rcd.gg/PreMiD/websites/A/AnimeSaturn/assets/thumbnail.png", "color": "#ddc6e8", @@ -22,6 +29,8 @@ "sub-ita", "streaming" ], + "iframe": true, + "iFrameRegExp": "^https?[:][/][/]play[.]saturncdn[.]net[/]embed[/]", "settings": [ { "id": "lang", diff --git a/websites/A/AnimeSaturn/presence.ts b/websites/A/AnimeSaturn/presence.ts index 0c0d00669995..a8b178f09930 100644 --- a/websites/A/AnimeSaturn/presence.ts +++ b/websites/A/AnimeSaturn/presence.ts @@ -1,4 +1,4 @@ -import { Assets, getTimestamps } from 'premid' +import { ActivityType, Assets, getTimestamps } from 'premid' const presence = new Presence({ clientId: '1266069361928704072', @@ -8,113 +8,115 @@ enum ActivityAssets { Logo = 'https://cdn.rcd.gg/PreMiD/websites/A/AnimeSaturn/assets/logo.png', } -async function getStrings() { - return presence.getStrings( - { - paused: 'general.paused', - play: 'general.playing', - search: 'general.searchFor', - viewHome: 'general.viewHome', - viewShow: 'general.viewShow', - viewEpisode: 'general.viewEpisode', - buttonViewEpisode: 'general.buttonViewEpisode', - buttonViewShow: 'general.buttonViewShow', - }, - - ) -} +let iFrameData: { + video?: { + paused?: boolean + currentTime?: number + duration?: number + title?: string + } +} = {} -let strings: Awaited> -let oldLang: string | null = null +presence.on('iFrameData', (data) => { + iFrameData = data +}) presence.on('UpdateData', async () => { const presenceData: PresenceData = { + type: ActivityType.Watching, largeImageKey: ActivityAssets.Logo, } - const [newLang, cover] = await Promise.all([ - presence.getSetting('lang').catch(() => 'en'), - presence.getSetting('cover'), - ]) - const { pathname, href } = document.location + const cover = await presence.getSetting('cover') + const { pathname, href, search } = document.location - if (oldLang !== newLang || !strings) { - oldLang = newLang - strings = await getStrings() - } + const strings = await presence.getStrings({ + browsing: 'general.browsing', + paused: 'general.paused', + play: 'general.playing', + search: 'general.search', + searchFor: 'general.searchFor', + viewHome: 'general.viewHome', + viewAnAnime: 'general.viewAnAnime', + viewEpisode: 'general.viewEpisode', + buttonViewEpisode: 'general.buttonViewEpisode', + buttonViewAnime: 'general.buttonViewAnime', + }) - if (document.querySelector('.search-box')?.value) { - presenceData.details = `${strings.search} ${ - document.querySelector('.search-box')?.value - }` + const searchBox = document.querySelector('input[type="search"]') + const searchParams = new URLSearchParams(search) + + if (searchBox?.value || (pathname.startsWith('/filter') && searchParams.get('key'))) { + presenceData.details = `${strings.searchFor} ${searchBox?.value || searchParams.get('key')}` + presenceData.smallImageKey = Assets.Search + } + else if (pathname.startsWith('/filter')) { + presenceData.details = strings.search presenceData.smallImageKey = Assets.Search - presence.setActivity(presenceData) - return } - if (pathname === '/') { + else if (pathname === '/') { presenceData.details = strings.viewHome } - else if (pathname.startsWith('/animelist')) { + else if (pathname.startsWith('/az-list')) { presenceData.details = 'Viewing Archive' presenceData.state = `Filter by: ${document - .querySelector('.badge.badge-saturn > b') + .querySelector('.letter-strip .letter-tab.active') ?.textContent - ?.replace(/\\n|\s/g, '')}` + ?.trim()}` } - else if (pathname.startsWith('/animeincorso')) { + else if (pathname.startsWith('/ongoing')) { presenceData.details = 'Viewing seasonal anime' presenceData.state = `Page ${ - document.querySelector('.active > a')?.textContent + document.querySelector('span.page-num--active')?.textContent }` } - else if (pathname.startsWith('/anime')) { + else if (pathname.startsWith('/anime') && !iFrameData.video) { // view anime presenceData.smallImageKey = Assets.Viewing - presenceData.smallImageText = strings.viewShow + presenceData.smallImageText = strings.viewAnAnime presenceData.details = document.querySelector( - '.anime-title-as > b', + '.anime-grid .ag-head h1', )?.textContent presenceData.state = `Episodes: ${ - document.querySelectorAll( - '.btn-group.episodes-button.episodi-link-button', - )?.length ?? 0 - } | ${ - document - .querySelector('.container.shadow.rounded.text-white') - ?.textContent - ?.split('\n')[1] - }` + document.querySelector('.anime-grid .ag-episodes h2 span')?.textContent?.match(/\((\d+)\)/)?.[1] + || document.querySelectorAll( + '.anime-grid .ag-episodes .ep-tile', + )?.length || 0 + } | ${Array.from(document.querySelectorAll('span')).find(el => el.textContent.includes('Studio'))?.parentElement?.textContent?.replace('Studio', 'Studio:')?.trim()}` presenceData.largeImageKey = cover - ? document.querySelector('.cover-anime')?.src + ? document.querySelector('.anime-grid .ag-poster img')?.src ?? ActivityAssets.Logo : ActivityAssets.Logo presenceData.buttons = [ { - label: strings.buttonViewShow, + label: strings.buttonViewAnime, url: href, }, ] } - else if (pathname.startsWith('/ep')) { + else if (pathname.startsWith('/episode')) { // view episode presenceData.smallImageKey = Assets.Viewing presenceData.smallImageText = strings.viewEpisode presenceData.details = strings.viewEpisode - presenceData.state = document.querySelector('h3')?.textContent + presenceData.state = `${document.querySelector('.ept-title')?.textContent} ${document.querySelector('.ept-sub')?.textContent}` presenceData.largeImageKey = cover - ? document.querySelector('.img-fluid')?.src + ? document.querySelector('.ept-cover img')?.src ?? ActivityAssets.Logo : ActivityAssets.Logo } - else if (pathname.startsWith('/watch')) { + else if (pathname.startsWith('/anime') && iFrameData.video) { // watch anime - delete presenceData.startTimestamp - const video = document.querySelector('video') - presenceData.smallImageKey = video?.paused ? Assets.Pause : Assets.Play - presenceData.smallImageText = video?.paused ? strings.paused : strings.play - presenceData.details = document.querySelector('.text-white.mb-3')?.textContent - if (video && !Number.isNaN(video.duration) && !video.paused) { - [presenceData.startTimestamp, presenceData.endTimestamp] = getTimestamps(video.currentTime, video.duration) + presenceData.smallImageKey = iFrameData.video.paused ? Assets.Pause : Assets.Play + presenceData.smallImageText = iFrameData.video.paused ? strings.paused : strings.play + presenceData.details = document.querySelector('.player-card a[x-text="animeName"]')?.textContent + presenceData.state = document.querySelector('.player-card span[x-text="displayNumber"]')?.textContent + if (iFrameData.video && iFrameData.video.currentTime && iFrameData.video.duration && !iFrameData.video.paused) { + [presenceData.startTimestamp, presenceData.endTimestamp] = getTimestamps(iFrameData.video.currentTime, iFrameData.video.duration) } + presenceData.largeImageKey = cover + ? document.querySelector('[property="og:image"]')?.content + ?? ActivityAssets.Logo + : ActivityAssets.Logo presenceData.buttons = [ { label: strings.buttonViewEpisode, @@ -128,31 +130,41 @@ presence.on('UpdateData', async () => { else if (pathname.startsWith('/upcoming')) { presenceData.details = 'Viewing upcoming anime' } - else if (pathname.startsWith('/calendario')) { + else if (pathname.startsWith('/calendar')) { presenceData.details = 'Viewing Schedule' } else if (pathname.startsWith('/toplist')) { let top3 = '' for (let i = 0; i < 3; i++) { top3 += `${i + 1}° ${ - document.querySelectorAll( - `#${ - document.querySelector('.active.show')?.id - } .margin-top-anime-page > a > img`, - )[i]?.title + document.querySelectorAll('.tl-podium img')[i]?.alt }\n` } presenceData.details = `Viewing top-anime: ${ - document.querySelector('.nav-item.active')?.textContent + document.querySelector('.tab.active')?.textContent }` presenceData.state = top3 } else if (pathname.startsWith('/info')) { presenceData.smallImageKey = Assets.Viewing - presenceData.details = 'Viewing info' - presenceData.state = document.querySelector('.p-3 > b')?.textContent - presenceData.largeImageKey = document.querySelector('.p-3 div > img')?.src - ?? ActivityAssets.Logo + presenceData.details = 'Viewing contact info' + } + else if (pathname.startsWith('/news')) { + presenceData.smallImageKey = Assets.Reading + presenceData.details = 'Reading news' + } + else if (pathname.startsWith('/genres')) { + presenceData.smallImageKey = Assets.Viewing + presenceData.details = 'Viewing genres' + } + else { + presenceData.details = strings.browsing + } + + if (presenceData.details) { + presence.setActivity(presenceData) + } + else { + presence.clearActivity() } - presence.setActivity(presenceData) })