-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat(Primeshows): add activity #10303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
429ae6e
42e03ff
2d826ae
ef8ca56
4236163
dc15efc
673b662
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| { | ||
| "$schema": "https://schemas.premid.app/metadata/1.16", | ||
| "apiVersion": 1, | ||
| "author": { | ||
| "id": "1203605618745933880", | ||
| "name": "friday.su" | ||
| }, | ||
| "service": "Primeshows", | ||
| "description": { | ||
| "en": "Enjoy unlimited streaming of movies, TV shows, and anime in HD & 4K, completely free! Primeshows offers a seamless experience with multi-language support and auto-next playback, ensuring you never miss a moment. Watch your favorite content anytime, anywhere!" | ||
| }, | ||
| "url": "www.primeshows.live", | ||
| "regExp": "^https?[:][/][/]([a-z0-9-]+[.])*primeshows[.]live[/]", | ||
| "version": "1.0.0", | ||
| "logo": "https://i.ibb.co/fdn3gFWS/logo.png", | ||
| "thumbnail": "https://i.ibb.co/7NtK5cn6/image.png", | ||
| "color": "#121212", | ||
| "category": "videos", | ||
| "tags": [ | ||
| "video", | ||
| "streaming", | ||
| "movies", | ||
| "anime", | ||
| "tv" | ||
| ], | ||
| "settings": [ | ||
| { | ||
| "id": "lang", | ||
| "multiLanguage": true | ||
| }, | ||
| { | ||
| "id": "privacy", | ||
| "title": "Privacy Mode", | ||
| "icon": "fas fa-user-secret", | ||
| "value": false | ||
| }, | ||
| { | ||
| "id": "showButtons", | ||
| "title": "Show Buttons", | ||
| "icon": "fas fa-compress-arrows-alt", | ||
| "value": true | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,297 @@ | ||
| import { ActivityType, Assets } from 'premid' | ||
|
|
||
| const presence = new Presence({ | ||
| clientId: '1369156087340728350', | ||
| }) | ||
|
|
||
| const browsingTimestamp = Math.floor(Date.now() / 1000) | ||
|
|
||
| enum ActivityAssets { | ||
| Logo = 'https://i.ibb.co/fdn3gFWS/logo.png', | ||
| } | ||
|
|
||
| /** | ||
| * Formats a slug into a readable name. | ||
| * e.g., "66732-stranger-things" -> "Stranger Things" | ||
| */ | ||
| const formatSlug = (slug: string | undefined): string => { | ||
Check failureCode scanning / ESLint Enforce top-level functions to be declared with function keyword Error
Top-level functions should be declared with function keyword
|
||
| if (!slug) return '' | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| return slug | ||
| .split('-') | ||
| .map(word => { | ||
Check failureCode scanning / ESLint Require parentheses around arrow function arguments Error
Expected parentheses around arrow function argument having a body with curly braces.
|
||
| if (/^\d+$/.test(word)) return '' // Skip IDs | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| return word.charAt(0).toUpperCase() + word.slice(1) | ||
| }) | ||
| .filter(Boolean) | ||
| .join(' ') | ||
| } | ||
|
|
||
| /** | ||
| * Attempts to retrieve a name/title from the DOM if the URL slug is insufficient. | ||
| */ | ||
| const getNameFromDOM = (): string | null => { | ||
Check failureCode scanning / ESLint Enforce top-level functions to be declared with function keyword Error
Top-level functions should be declared with function keyword
|
||
| const selectors = [ | ||
| 'h1.text-white', | ||
| '.movie-title', | ||
| '.show-title', | ||
| 'h1', | ||
| 'header h1', | ||
| '#Movie\\ Name', | ||
| '#TV\\ Shows\\ Name' | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| for (const selector of selectors) { | ||
| const el = document.querySelector(selector) | ||
| if (el && el.textContent) return el.textContent.trim() | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| } | ||
| return null | ||
| } | ||
|
|
||
| /** | ||
| * Robustly fetches the rating from the page. | ||
| */ | ||
| const getRating = (): string => { | ||
Check failureCode scanning / ESLint Enforce top-level functions to be declared with function keyword Error
Top-level functions should be declared with function keyword
|
||
| const ratingEl = document.querySelector('.radial-progress span.text-white') || | ||
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| document.querySelector('[class*="radial-progress"] span') || | ||
Check failureCode scanning / ESLint Indentation for binary operators Error
Expected indentation of 4 spaces
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
|
||
| document.querySelector('.rating-value') | ||
| const rating = ratingEl?.textContent?.trim() || 'N/A' | ||
| return rating === '0' || rating === '0.0' ? 'N/A' : rating | ||
| } | ||
|
|
||
| /** | ||
| * Robustly fetches the release date from the page. | ||
| */ | ||
| const getReleaseDate = (type: 'movie' | 'tv'): string => { | ||
Check failureCode scanning / ESLint Enforce top-level functions to be declared with function keyword Error
Top-level functions should be declared with function keyword
|
||
| const selector = type === 'movie' ? '#Movie\\ Release\\ Date time p' : '#TV\\ Shows\\ Air\\ Date time' | ||
| let date = document.querySelector(selector)?.textContent?.trim() || | ||
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| document.querySelector('time')?.textContent?.trim() || | ||
Check failureCode scanning / ESLint Indentation for binary operators Error
Expected indentation of 4 spaces
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| 'N/A' | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| // Format long dates like "Sunday, October 12, 2014" to "October 2014" | ||
| if (date !== 'N/A') { | ||
| const dateParts = date.split(', ') | ||
| const p0 = dateParts[0] | ||
| const p1 = dateParts[1] | ||
| const p2 = dateParts[2] | ||
|
|
||
| if (dateParts.length === 3 && p1 && p2) { | ||
| date = `${p1} ${p2}` | ||
| } else if (dateParts.length === 2 && type === 'tv' && p0 && p1) { | ||
Check failureCode scanning / ESLint Enforce consistent brace style for blocks Error
Closing curly brace appears on the same line as the subsequent block.
|
||
| const monthYear = p0.split(' ')[0] | ||
| if (monthYear) { | ||
| date = `${monthYear} ${p1}` | ||
| } | ||
| } | ||
| } | ||
| return date | ||
| } | ||
|
|
||
| presence.on('UpdateData', async () => { | ||
| let presenceData: PresenceData = { | ||
| largeImageKey: ActivityAssets.Logo, | ||
| startTimestamp: browsingTimestamp, | ||
| details: 'Unsupported Page', | ||
| } | ||
|
|
||
| const { pathname, search, href } = document.location | ||
| const urlParams = new URLSearchParams(search) | ||
|
|
||
| const privacy = await presence.getSetting<boolean>('privacy') | ||
| const showButtons = await presence.getSetting<boolean>('showButtons') | ||
|
|
||
| if (privacy) { | ||
| presenceData.details = 'Watching Primeshows 🔒' | ||
| presence.setActivity(presenceData) | ||
| return | ||
| } | ||
|
|
||
| // Static Pages | ||
| const pages: Record<string, PresenceData> = { | ||
| '/': { | ||
| details: 'Viewing HomePage 🏠', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/profile': { | ||
| details: 'Viewing Profile 👤', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/tv': { | ||
| details: 'Browsing TV Shows 📺', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/movies': { | ||
| details: 'Browsing Movies 🎬', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/trending': { | ||
| details: 'Browsing Trending 🔥', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/search': { | ||
| details: 'Browsing Search 🔎', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/livetv': { | ||
| details: 'Browsing Live TV 📶', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| '/sports': { | ||
| details: 'Live Sports ⚽', | ||
| smallImageKey: Assets.Viewing, | ||
| }, | ||
| } | ||
|
|
||
| if (pages[pathname]) { | ||
| presenceData = { | ||
| ...presenceData, | ||
| ...pages[pathname], | ||
| type: ActivityType.Watching, | ||
| } | ||
| } | ||
|
|
||
| // Handle Dynamic Routes | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| // 1. TV Info Page: /tv/{id}-{slug} | ||
| if (pathname.startsWith('/tv/') && pathname !== '/tv') { | ||
| const match = pathname.match(/\/tv\/(\d+)(?:-([^/]+))?/) | ||
Check failureCode scanning / ESLint disallow unused capturing group Error
Capturing group number 1 is defined but never used.
|
||
| if (match) { | ||
| const showName = formatSlug(match[2]) || getNameFromDOM() || 'Unknown Show' | ||
| presenceData.details = `Viewing ${showName} 📺` | ||
| presenceData.type = ActivityType.Watching | ||
| presenceData.smallImageKey = Assets.Viewing | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| const rating = getRating() | ||
| const releaseDate = getReleaseDate('tv') | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| const stateParts = [] | ||
| if (rating !== 'N/A') stateParts.push(`⭐ ${rating}`) | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| if (releaseDate !== 'N/A') stateParts.push(`🗓️ ${releaseDate}`) | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| presenceData.state = stateParts.length > 0 ? stateParts.join(' • ') : 'Viewing Details' | ||
| presenceData.largeImageKey = document.querySelector<HTMLImageElement>('section.md\\:col-\\[1\\/4\\] img')?.src || | ||
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| document.querySelector<HTMLImageElement>('img[alt*="Poster"]')?.src || | ||
Check failureCode scanning / ESLint Indentation for binary operators Error
Expected indentation of 8 spaces
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
|
||
| ActivityAssets.Logo | ||
|
|
||
| if (showButtons) { | ||
| presenceData.buttons = [ | ||
| { label: 'View Show 📺', url: href } | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| // 2. Movie Info Page: /movies/{id}-{slug} | ||
| if (pathname.startsWith('/movies/') && pathname !== '/movies') { | ||
| const match = pathname.match(/\/movies\/(\d+)(?:-([^/]+))?/) | ||
Check failureCode scanning / ESLint disallow unused capturing group Error
Capturing group number 1 is defined but never used.
|
||
| if (match) { | ||
| const movieName = formatSlug(match[2]) || getNameFromDOM() || 'Unknown Movie' | ||
| presenceData.details = `Viewing ${movieName} 🎬` | ||
| presenceData.type = ActivityType.Watching | ||
| presenceData.smallImageKey = Assets.Viewing | ||
|
|
||
| const rating = getRating() | ||
| const runtime = document.querySelector('#Movie\\ Runtime time p')?.textContent?.match(/\d+/)?.[0] || 'N/A' | ||
| const releaseDate = getReleaseDate('movie') | ||
|
|
||
| const stateParts = [] | ||
| if (rating !== 'N/A') stateParts.push(`⭐ ${rating}`) | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| if (runtime !== 'N/A') stateParts.push(`🕒 ${runtime}m`) | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| if (releaseDate !== 'N/A') stateParts.push(`🗓️ ${releaseDate}`) | ||
Check failureCode scanning / ESLint Newline after if Error
Expect newline after if
|
||
| presenceData.state = stateParts.length > 0 ? stateParts.join(' • ') : 'Viewing Details' | ||
| presenceData.largeImageKey = document.querySelector<HTMLImageElement>('figure img.object-cover')?.src || | ||
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| document.querySelector<HTMLImageElement>('img[alt*="Poster"]')?.src || | ||
Check failureCode scanning / ESLint Indentation for binary operators Error
Expected indentation of 8 spaces
Check failureCode scanning / ESLint Enforce consistent linebreak style for operators Error
'||' should be placed at the beginning of the line.
|
||
| ActivityAssets.Logo | ||
|
|
||
| if (showButtons) { | ||
| presenceData.buttons = [ | ||
| { label: 'View Movie 🎬', url: href } | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| // 3. Watch TV: /watch/tv/{id} | ||
| if (pathname.startsWith('/watch/tv/')) { | ||
| const match = pathname.match(/\/watch\/tv\/(\d+)/) | ||
| if (match) { | ||
| const tmdbId = match[1] | ||
| const showName = getNameFromDOM() || 'Unknown Show' | ||
|
|
||
| const season = urlParams.get('season') | ||
| const episode = urlParams.get('episode') | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| let seasonNo = '1' | ||
| let episodeNo = '1' | ||
|
|
||
| if (season && episode) { | ||
| seasonNo = season | ||
| episodeNo = episode | ||
| } else { | ||
Check failureCode scanning / ESLint Enforce consistent brace style for blocks Error
Closing curly brace appears on the same line as the subsequent block.
|
||
| const watchHistory = JSON.parse(localStorage.getItem('watch-history') || '{}') | ||
| const showData = (tmdbId ? watchHistory[tmdbId] : null) || { last_season_watched: '1', last_episode_watched: '1' } | ||
| seasonNo = showData.last_season_watched | ||
| episodeNo = showData.last_episode_watched | ||
| } | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| presenceData.details = `Watching ${showName} 🍿` | ||
| presenceData.state = `S${seasonNo} E${episodeNo} • Streaming 📺` | ||
| presenceData.type = ActivityType.Watching | ||
| presenceData.smallImageKey = Assets.Play | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| presenceData.largeImageKey = document.querySelector<HTMLImageElement>('img.poster')?.src || ActivityAssets.Logo | ||
|
|
||
| if (showButtons) { | ||
| presenceData.buttons = [ | ||
| { label: 'Watch Now 🍿', url: href } | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| // 4. Watch Movie: /watch/movie/{id} | ||
| if (pathname.startsWith('/watch/movie/')) { | ||
| const movieName = getNameFromDOM() || 'Unknown Movie' | ||
| presenceData.details = `Watching ${movieName} 🎬` | ||
| presenceData.state = `Enjoying Movie 🍿` | ||
| presenceData.type = ActivityType.Watching | ||
| presenceData.smallImageKey = Assets.Play | ||
| presenceData.largeImageKey = document.querySelector<HTMLImageElement>('img.poster')?.src || ActivityAssets.Logo | ||
|
|
||
| if (showButtons) { | ||
| presenceData.buttons = [ | ||
| { label: 'Watch Now 🍿', url: href } | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| } | ||
| } | ||
|
|
||
| // 5. Watch Sports: /watch/sports/{details} | ||
| if (pathname.startsWith('/watch/sports/')) { | ||
| const sportsSlug = pathname.split('/').pop() || '' | ||
| const sportsName = formatSlug(sportsSlug) || 'Live Sports' | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| presenceData.details = `Watching ${sportsName} 🏆` | ||
| presenceData.type = ActivityType.Watching | ||
| presenceData.smallImageKey = Assets.Play | ||
| presenceData.state = 'Live Sports Event 📶' | ||
|
|
||
| if (showButtons) { | ||
| presenceData.buttons = [ | ||
| { label: 'Watch Live 📶', url: href } | ||
| ] | ||
Check failureCode scanning / ESLint Require or disallow trailing commas Error
Missing trailing comma.
|
||
| } | ||
| } | ||
|
|
||
| // 6. Search Page | ||
| if (pathname.includes('/search')) { | ||
| const query = urlParams.get('q') || document.querySelector('input')?.getAttribute('value') | ||
|
|
||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| presenceData.details = 'Searching Primeshows 🔎' | ||
| if (query) { | ||
| presenceData.state = `Looking for: ${query} ✨` | ||
| } | ||
| presenceData.smallImageKey = Assets.Search | ||
| } | ||
|
|
||
| if (presenceData.details !== 'Unsupported Page') | ||
| presence.setActivity(presenceData) | ||
| else | ||
Check failureCode scanning / ESLint Disallow trailing whitespace at the end of lines Error
Trailing spaces not allowed.
|
||
| presence.setActivity() | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
clearActivityinstead to hide the Activity.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed