Activity with Slideshow Example
This page provides an example of a PreMiD Activity that uses the Slideshow class to alternate between different sets of presence data at specific intervals. This is useful for displaying multiple pieces of information in rotation.
Basic Structure
An activity with a slideshow consists of two files:
metadata.json
: Contains information about the activitypresence.ts
: Contains the code for the activity, including the slideshow logic
metadata.json
{
"apiVersion": 1,
"author": {
"name": "Your Name",
"id": "your_discord_id"
},
"service": "SlideshowExample",
"description": {
"en": "SlideshowExample is a website that demonstrates the slideshow feature."
},
"url": "slideshowexample.com",
"version": "1.0.0",
"logo": "https://slideshowexample.com/logo.png",
"thumbnail": "https://slideshowexample.com/thumbnail.png",
"color": "#FF0000",
"category": "other",
"tags": ["example", "slideshow"]
}
presence.ts
import { Assets } from 'premid'
const presence = new Presence({
clientId: 'your_client_id'
})
enum ActivityAssets {
Logo = 'https://example.com/logo.png',
User = 'https://example.com/user.png',
Star = 'https://example.com/star.png',
Trophy = 'https://example.com/trophy.png'
}
const browsingTimestamp = Math.floor(Date.now() / 1000)
// Create a slideshow
const slideshow = presence.createSlideshow()
// Define a constant for slideshow timeout
const SLIDESHOW_TIMEOUT = 5000 // 5 seconds
// Track which slideshow keys we've registered to avoid duplicates
const registeredSlideshowKeys = new Set<string>()
// Helper function to register slideshow keys and avoid duplicates
function registerSlideshowKey(key: string): void {
if (!registeredSlideshowKeys.has(key)) {
registeredSlideshowKeys.add(key)
}
}
presence.on('UpdateData', async () => {
// Base presence data that will be common across slides
const presenceData: PresenceData = {
largeImageKey: ActivityAssets.Logo,
startTimestamp: browsingTimestamp
}
// Get page information
const pageTitle = document.title
const path = document.location.pathname
// Determine what page we're on
if (path.includes('/gallery/')) {
// Gallery page with images
const images = document.querySelectorAll('.gallery img')
// Register a unique key for this gallery page
const galleryPage = document.querySelector('.pagination-active')?.textContent || '1'
registerSlideshowKey(`gallery-page-${galleryPage}`)
// Clear previous slides if we have a new set of images
slideshow.deleteAllSlides()
// Add each image as a slide
for (const [index, image] of images.entries()) {
const imageTitle = image.getAttribute('alt') || `Image ${index + 1}`
slideshow.addSlide(
`image-${index}`,
{
...presenceData,
details: 'Viewing gallery',
state: `${imageTitle} (${index + 1}/${images.length})`,
largeImageKey: image.src,
smallImageKey: Assets.Search, // Search is in the provided Assets enum
smallImageText: 'Browsing images'
},
SLIDESHOW_TIMEOUT
)
}
}
else if (path.includes('/profile/')) {
// Profile page
presenceData.details = 'Viewing profile'
presenceData.state = document.querySelector('.username')?.textContent || 'Unknown user'
// Add user stats slide
slideshow.addSlide(
'profile-main',
{
...presenceData,
smallImageKey: ActivityAssets.User,
smallImageText: 'User profile'
},
SLIDESHOW_TIMEOUT
)
// Add user level slide
const userLevel = document.querySelector('.user-level')?.textContent || 'Unknown level'
slideshow.addSlide(
'profile-level',
{
...presenceData,
details: `Level: ${userLevel}`,
state: `User: ${document.querySelector('.username')?.textContent || 'Unknown user'}`,
smallImageKey: Assets.Star,
smallImageText: 'User level'
},
SLIDESHOW_TIMEOUT
)
// Add achievements if available
const achievements = document.querySelectorAll('.achievement')
if (achievements.length > 0) {
slideshow.addSlide(
'profile-achievements',
{
...presenceData,
details: 'Achievements',
state: `${achievements.length} unlocked`,
smallImageKey: Assets.Trophy,
smallImageText: 'User achievements'
},
SLIDESHOW_TIMEOUT
)
}
}
else {
// Homepage or other pages
presenceData.details = 'Browsing SlideshowExample'
presenceData.state = pageTitle
// Just use a single slide for the homepage
slideshow.addSlide('homepage', presenceData, SLIDESHOW_TIMEOUT)
// Remove any other slides that might exist from previous pages
for (const slide of slideshow.getSlides()) {
if (slide.id !== 'homepage') {
slideshow.deleteSlide(slide.id)
}
}
}
// Add buttons to all slides if needed
const showButtons = await presence.getSetting<boolean>('showButtons')
if (showButtons) {
for (const slide of slideshow.getSlides()) {
const data = slide.data
data.buttons = [
{
label: 'Visit Website',
url: document.location.href
}
]
slide.updateData(data)
}
}
// Set the activity with the slideshow
presence.setActivity(slideshow)
})
How It Works
Creating a Slideshow
In the presence.ts
file, we:
- Create a new
Presence
instance - Create a slideshow using
presence.createSlideshow()
- Define a constant for the slideshow timeout (5000ms)
- Create a helper function to track registered slideshow keys
Managing Slides Based on Page Context
The example demonstrates three different approaches to managing slides based on the current page:
Gallery Page: Creates a dynamic set of slides for each image
- Clears all previous slides with
slideshow.deleteAllSlides()
- Creates a new slide for each image with unique IDs
- Uses the spread operator (
...presenceData
) to maintain common properties
- Clears all previous slides with
Profile Page: Creates multiple slides showing different aspects of the profile
- One slide for basic profile info
- One slide for user level
- One conditional slide for achievements (only if they exist)
Homepage: Uses a single slide
- Adds a simple slide for the homepage
- Removes any other slides that might exist from previous pages
Tracking Slideshow Keys
The registerSlideshowKey
function and registeredSlideshowKeys
Set are used to track which slideshow configurations we've already set up. This is useful when:
- Moving between pages with similar content
- Avoiding duplicate slide creation
- Managing slideshow state across page navigation
Modifying All Slides at Once
The example shows how to modify all slides at once based on user settings:
const showButtons = await presence.getSetting<boolean>('showButtons')
if (showButtons) {
for (const slide of slideshow.getSlides()) {
const data = slide.data
data.buttons = [
{
label: 'Visit Website',
url: document.location.href
}
]
slide.updateData(data)
}
}
This pattern is useful for applying common modifications to all slides based on user preferences.
Testing
To test this activity with a slideshow:
- Make sure the PreMiD extension is installed in your browser.
- Enable developer mode in the extension settings.
- Add your local activity to the extension.
- Visit the website you created the activity for.
- Check your Discord status to see if it's showing the activity and cycling through the slides.
Notes
- The minimum interval between slides is defined by the
MIN_SLIDE_TIME
constant, which is 5000 milliseconds (5 seconds). - Slideshows are useful for displaying different information in rotation, but be careful not to add too many slides or set the intervals too short, as it can be distracting for users.
- Each slide can have completely different presence data, including different images, timestamps, and buttons.
Next Steps
This example shows how to create an activity with a basic slideshow. You can enhance it by:
- Adding more types of slides based on different page states
- Combining the slideshow with settings to allow users to customize what slides are shown
- Using iFrame data in slides to show information from embedded content
- Creating more complex slide logic based on user interactions
Check out the other examples in this section for more advanced usage:
- Basic Activity: Shows how to create a simple activity
- Media Activity: Shows how to create an activity for media websites
- Activity with Settings: Shows how to add customizable settings to your activity
- Activity with iFrames: Shows how to gather information from iFrames