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 text

    • intent: 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 text

    • style: 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 text

    • style: 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 text

    • for: 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 text

    • intent: 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 text

    • style: 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 text

    • type : "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