Action
The ctx.action
API allows your plugin to add UI elements that trigger custom actions to different parts of the Seanime interface.
Core Methods
newAnimePageButton
Creates a button that appears on anime detail pages.
Parameters:
props
: Object containing:label
: String - Button textintent
: String (Optional) - Button style ("primary", "success", "warning", etc.)style
: Object (Optional) - Custom CSS styles
Example:
// Create a play button for anime pages
const playButton = ctx.action.newAnimePageButton({
label: "Play All Episodes",
intent: "primary",
style: { marginRight: "8px" }
})
// Mount the button to make it visible
playButton.mount()
// Handle clicks
playButton.onClick((event) => {
const anime = event.media
console.log(`Play all episodes for: ${anime.title.userPreferred}`)
// Implement playback logic
})
newAnimePageDropdownItem
Creates a dropdown menu item that appears in the anime page's action menu.
Parameters:
props
: Object containing:label
: String - Menu item textstyle
: Object (Optional) - Custom CSS styles
Example:
// Add a download option to anime page dropdown
const downloadItem = ctx.action.newAnimePageDropdownItem({
label: "Download Episodes"
})
downloadItem.mount()
downloadItem.onClick((event) => {
const anime = event.media
console.log(`Preparing download for: ${anime.title.userPreferred}`)
// Show download dialog
})
newAnimeLibraryDropdownItem
Creates a dropdown menu item that appears in the anime library's global action menu.
Parameters:
props
: Object containing:label
: String - Menu item textstyle
: Object (Optional) - Custom CSS styles
Example:
// Add a scan option to library menu
const scanItem = ctx.action.newAnimeLibraryDropdownItem({
label: "Scan for Missing Files"
})
scanItem.mount()
scanItem.onClick(() => {
console.log("Starting library scan")
// Implement scan logic
})
newMediaCardContextMenuItem
Creates a context menu item that appears when right-clicking on media cards.
Parameters:
props
: Object containing:label
: String - Menu item textfor
: String (Optional) - Which media types to show for ("anime", "manga", or "both")style
: Object (Optional) - Custom CSS styles
Example:
// Add a quick-watch option to anime cards
const watchItem = ctx.action.newMediaCardContextMenuItem({
label: "Quick Watch",
for: "anime" // Only show for anime cards
})
watchItem.mount()
watchItem.onClick((event) => {
const media = event.media
console.log(`Quick watching: ${media.title.userPreferred}`)
// Implement quick watch feature
})
newMangaPageButton
Creates a button that appears on manga detail pages.
Parameters:
props
: Object containing:label
: String - Button textintent
: String (Optional) - Button style ("primary", "success", "warning", etc.)style
: Object (Optional) - Custom CSS styles
Example:
// Create a read button for manga pages
const readButton = ctx.action.newMangaPageButton({
label: "Continue Reading",
intent: "primary"
})
readButton.mount()
readButton.onClick((event) => {
const manga = event.media
console.log(`Opening reader for: ${manga.title.userPreferred}`)
// Open manga reader
})
newEpisodeCardContextMenuItem
Creates an item that appears on episode card context menus.
Parameters:
props
: Object containing:label
: String - Button textstyle
: Object (Optional) - Custom CSS styles
const episodeDetailsButton = ctx.action.newEpisodeCardContextMenuItem({
label: "View details",
})
episodeDetailsButton.mount()
episodeDetailsButton.onClick((event) => {
// You get the episode object
const episode = event.episode
})
newEpisodeGridItemMenuItem
Creates an item that appears on episode grid item menus.
Parameters:
props
: Object containing:label
: String - Button texttype
: "library" | "torrentstream" | "debridstream" | "onlinestream" | "undownloaded" | "medialinks" | "mediastream"style
: Object (Optional) - Custom CSS styles
const episodeDetailsButton = ctx.action.newEpisodeGridItemMenuItem({
label: "View details",
type: "library"
})
episodeDetailsButton.mount()
episodeDetailsButton.onClick((event) => {
// You get the episode object
// It is of type [Anime_Episode], unless the chosen type is 'onlinestream',
// in which case it will be of type [Onlinestream_Episode]
const episode = event.episode
})
Action Object Methods
All action objects share these common methods:
mount()
Makes the action visible in the UI.
Example:
const button = ctx.action.newAnimePageButton({ label: "My Button" })
button.mount() // Now visible
unmount()
Removes the action from the UI.
Example:
// Remove when no longer needed
button.unmount()
setLabel(label)
Updates the action's label text.
Parameters:
label
: String - New label text
Example:
// Change button text based on state
if (isDownloading) {
button.setLabel("Downloading...")
} else {
button.setLabel("Download")
}
setStyle(style)
Updates the action's custom CSS styles.
Parameters:
style
: Object - CSS style properties
Example:
// Highlight button when active
if (isActive) {
button.setStyle({ backgroundColor: "#4caf50", color: "white" })
} else {
button.setStyle({})
}
onClick(callback)
Sets a function to be called when the action is clicked.
Parameters:
callback
: Function(event) - Function to call when clicked
Example:
button.onClick((event) => {
// For anime/manga actions, event contains the media object
if (event.media) {
console.log(`Clicked on ${event.media.title.userPreferred}`)
}
// Your custom action logic
performAction()
})
Additional Properties
AnimePageButton and MangaPageButton
These button types have an additional method:
setIntent(intent)
Sets the button's visual style.
Parameters:
intent
: String - Intent style ("primary", "success", "warning", "error", etc.)
Example:
const button = ctx.action.newAnimePageButton({ label: "Watch" })
button.setIntent("primary") // Blue button
// Other options: "primary-subtle", "success", "warning", "alert", etc.
MediaCardContextMenuItem
This action type has an additional method:
setFor(type)
Sets which media types the context menu item appears for.
Parameters:
type
: String - "anime", "manga", or "both"
Example:
const menuItem = ctx.action.newMediaCardContextMenuItem({ label: "Open" })
menuItem.setFor("anime") // Only show for anime cards
Best Practices
Limit Number of Actions
Each plugin is limited to a maximum of 3 actions per type. Choose the most important actions to display.
Dynamic UI Updates
Update action properties based on application state:
// Good: Update button state dynamically
let isProcessing = false
button.onClick((event) => {
if (isProcessing) return
isProcessing = true
button.setLabel("Processing...")
button.setIntent("warning")
button.mount()
performLongOperation().then(() => {
isProcessing = false
button.setLabel("Done!")
button.setIntent("success")
button.mount()
// Reset after a delay
setTimeout(() => {
button.setLabel("Process Again")
button.setIntent("primary")
button.mount()
}, 3000)
})
})
Conditional Mounting
Only mount actions when they're relevant:
// Good: Mount/unmount based on context
function updateButtonVisibility(media) {
if (media.format === "MOVIE") {
watchButton.mount()
episodesButton.unmount() // No episodes for movies
} else {
watchButton.mount()
episodesButton.mount()
}
}
Last updated