-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(Media): add activity #10863
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
base: main
Are you sure you want to change the base?
feat(Media): add activity #10863
Changes from 1 commit
d1ffc40
eb770d2
fd25651
84604ee
52bc4a7
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,24 @@ | ||
| { | ||
| "$schema": "https://schemas.premid.app/metadata/1.16", | ||
| "apiVersion": 1, | ||
| "author": { | ||
| "name": "siq", | ||
| "id": "123456789012345678" | ||
| }, | ||
| "service": "Media", | ||
| "description": { | ||
| "en": "Self-hosted media tracking platform for music, books, movies, games, and more." | ||
| }, | ||
| "url": "media.siqnole.dev", | ||
| "regExp": "^(?:https?[:][/][/])?(?:www[.])?(?:media[.]siqnole[.]dev|localhost:5173)[/]", | ||
| "version": "1.0.0", | ||
| "logo": "https://media.siqnole.dev/mydia.png", | ||
Check failureCode scanning / PMD Makes sure all images (logo and URLs) are exactly 512x512 pixels Error
Image URL dimensions must be exactly 512x512 pixels, got 800x800 for URL: https://media.siqnole.dev/mydia.png
|
||
| "thumbnail": "https://media.siqnole.dev/mydia.png", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thumbnail should be a landscape promotional image or screenshot |
||
| "color": "#a688e8", | ||
| "category": "socials", | ||
| "tags": [ | ||
Check failureCode scanning / PMD Makes sure the `tags` don't contain the service name Error
Tags must not contain the service name
|
||
|
github-advanced-security[bot] marked this conversation as resolved.
Fixed
|
||
| "media", | ||
| "tracking", | ||
| "ratings" | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import { ActivityType } from 'premid' | ||
|
|
||
| // NOTE: Since Discord proxies all status images, it cannot fetch local files (like localhost or media.siqnole.dev if it's local). | ||
| // Replace the URL below with a publicly hosted URL of your logo (e.g. uploaded to Imgur or Discord CDN) to resolve "No Image". | ||
| const APP_LOGO_URL = 'https://media.siqnole.dev/mydia.png' | ||
Check failureCode scanning / PMD Makes sure all images (logo and URLs) are exactly 512x512 pixels Error
Image URL dimensions must be exactly 512x512 pixels, got 800x800 for URL: https://media.siqnole.dev/mydia.png
|
||
|
github-advanced-security[bot] marked this conversation as resolved.
Fixed
|
||
|
|
||
| const presence = new Presence({ | ||
| clientId: '1511807266913910855', | ||
| }) | ||
|
|
||
| let browsingTimestamp = Math.floor(Date.now() / 1000) | ||
| let lastPath = '' | ||
|
|
||
| presence.on('UpdateData', async () => { | ||
| const { pathname } = document.location | ||
|
|
||
| // Reset timestamp when switching major pages | ||
| if (pathname !== lastPath) { | ||
| browsingTimestamp = Math.floor(Date.now() / 1000) | ||
| lastPath = pathname | ||
| } | ||
|
|
||
| let presenceData: PresenceData | ||
|
|
||
| // Identify active Now Live items and scrape their cover art URL if available | ||
| let activeMedia: { label: string, title: string, sub: string, coverUrl: string | null } | null = null | ||
|
|
||
| if (pathname.startsWith('/@')) { | ||
| const firstNowItem = document.querySelector('.now-grid .now-item') | ||
| if (firstNowItem) { | ||
| const label = firstNowItem.querySelector('.now-label')?.textContent?.trim().toLowerCase() || '' | ||
| const title = firstNowItem.querySelector('.now-title')?.textContent?.trim() || '' | ||
| const sub = firstNowItem.querySelector('.now-sub')?.textContent?.trim() || '' | ||
|
|
||
| // Scrape cover image if it exists (e.g., Spotify, Steam, or custom reading cover) | ||
| const imgEl = firstNowItem.querySelector('.now-art img') as HTMLImageElement | null | ||
| const coverUrl = (imgEl && imgEl.src) ? imgEl.src : null | ||
|
|
||
| if (title) { | ||
| activeMedia = { label, title, sub, coverUrl } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (activeMedia) { | ||
| const { label, title, sub, coverUrl } = activeMedia | ||
| const profileUser = pathname.substring(2) | ||
| const stateText = sub ? `${title} (${sub})` : title | ||
|
|
||
| // Use the scraped cover art as the large image, and pin the app logo in the corner as the small image! | ||
| const largeImage = coverUrl || APP_LOGO_URL | ||
| const smallImage = coverUrl ? APP_LOGO_URL : undefined | ||
|
|
||
| if (label.includes('listening')) { | ||
| presenceData = { | ||
| largeImageKey: largeImage, | ||
| largeImageText: `Viewing @${profileUser}'s profile`, | ||
| smallImageKey: smallImage, | ||
| smallImageText: 'media.siqnole.dev', | ||
| startTimestamp: browsingTimestamp, | ||
| type: ActivityType.Listening, | ||
| details: `Listening to:`, | ||
| state: stateText, | ||
| } | ||
| } | ||
| else if (label.includes('watching') || label.includes('film') || label.includes('movie')) { | ||
| presenceData = { | ||
| largeImageKey: largeImage, | ||
| largeImageText: `Viewing @${profileUser}'s profile`, | ||
| smallImageKey: smallImage, | ||
| smallImageText: 'media.siqnole.dev', | ||
| startTimestamp: browsingTimestamp, | ||
| type: ActivityType.Watching, | ||
| details: `Watching:`, | ||
| state: stateText, | ||
| } | ||
| } | ||
| else { | ||
| // playing / reading - Non-media (ActivityType.Playing). No largeImageText is allowed in PreMiD. | ||
| presenceData = { | ||
| largeImageKey: largeImage, | ||
| smallImageKey: smallImage, | ||
| smallImageText: 'media.siqnole.dev', | ||
| startTimestamp: browsingTimestamp, | ||
| type: ActivityType.Playing, | ||
| details: label.includes('playing') || label.includes('steam') ? 'Playing:' : 'Reading:', | ||
| state: stateText, | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| // Non-media state (browsing) - No largeImageText allowed! | ||
| let details = 'Browsing' | ||
| let state = 'Home' | ||
|
|
||
| if (pathname === '/') { | ||
| details = 'Browsing Landing Page' | ||
| state = 'Welcome to Media' | ||
| } | ||
| else if (pathname === '/home') { | ||
| details = 'Checking Feed' | ||
| state = 'Browsing recent activity' | ||
| } | ||
| else if (pathname === '/login') { | ||
| details = 'Logging In' | ||
| state = 'Authenticating' | ||
| } | ||
| else if (pathname === '/register') { | ||
| details = 'Creating Account' | ||
| state = 'Joining the platform' | ||
| } | ||
| else if (pathname === '/shop') { | ||
| details = 'Browsing the Shop' | ||
| state = 'Checking out cosmetics' | ||
| } | ||
| else if (pathname === '/admin') { | ||
| details = 'Managing Platform' | ||
| state = 'Admin Dashboard' | ||
| } | ||
| else if (pathname.startsWith('/@')) { | ||
| const profileUser = pathname.substring(2) | ||
| details = `Viewing @${profileUser}'s profile` | ||
| state = 'Viewing profile' | ||
| } | ||
|
|
||
| presenceData = { | ||
| largeImageKey: APP_LOGO_URL, | ||
| startTimestamp: browsingTimestamp, | ||
| type: ActivityType.Playing, | ||
| details, | ||
| state, | ||
| } | ||
| } | ||
|
|
||
| if (presenceData.details) { | ||
| presence.setActivity(presenceData) | ||
| } | ||
| else { | ||
| presence.clearActivity() | ||
| } | ||
| }) | ||
Uh oh!
There was an error while loading. Please reload this page.