🧩
Seanime Extensions
🧩
Seanime Extensions
  • Seanime
    • Getting started
    • Core APIs
    • Changelog
  • Content Providers
    • Write, test, share
    • Anime torrent provider
    • Manga provider
    • Online streaming provider
  • Plugins
    • Introduction
    • Write, test, share
    • APIs
      • Helpers
      • Store
      • Storage
      • Database
      • AniList
      • System
        • Permissions
        • OS
        • Filepath
        • Commands
        • Buffers, I/O
        • MIME
    • UI
      • Basics
      • User Interface
        • Tray
        • Toast
        • Screen
        • Command Palette
        • Action
        • DOM
      • Anime/Library
        • Anime
        • Playback
        • Continuity
        • Auto Downloader
        • Auto Scanner
        • Filler Manager
        • External Player Link
      • Downloading
        • Downloader
        • Torrent Client
      • Other
        • Manga
        • Discord
        • MPV
    • Hooks
    • Example
  • Frequently asked
    • Feature requests
Powered by GitBook
On this page
  • What is $ui.register?
  • Fetch
  • States
  • Effects
  • Example
  1. Plugins
  2. UI

Basics

Basics of the UI context.

Difficulty: Moderate

  • Some basic knowledge of reactive UIs and state management is recommended.

What is $ui.register?

You can interact with the user interface and execute business logic via APIs provided to your plugin when you register a UI context.

function init() {
   // This function registers the UI context for your plugin, allowing it to
   // have access to UI APIs
   $ui.register((ctx) => {
      // The 'ctx' objects contains all the APIs
   })
}

Unlike hooks which are called every time a specific event is triggered, the function inside $ui.register is called only once during the lifetime of your plugin, right after init(), in other words, each time your plugin is loaded.

You cannot register hook handlers inside the UI callback.

Fetch

In the UI context, ctx.fetch should be used instead of simply fetch in order to avoid runtime errors caused by concurrency issues.

$ui.register(async (ctx) => {
    const res = await ctx.fetch("https://jsonplaceholder.typicode.com/todos/1")
    const data = res.json()
})

States

State management allows you to keep track of dynamic data within your plugin. This approach not only helps maintain a clear separation of concerns but also enables reactive programming, where UI components like the Tray automatically update in response to changes in states.

//...

const count = ctx.state(0)

ctx.setInterval(() => {
    count.set(c => c+1)
}, 1000)

function resetCount() {
    count.set(0)
}

// Tray will update each time count changes
tray.render(() => tray.text(`Count: ${count.get()}`))

Effects

// Effect registers a callback that runs each time count changes
ctx.effect(() => {
    console.log("count changed, " + count.get())
}, [count])

Example

In this example, we fetch some info from an external API each time the user navigates to an anime page.

Example
const currentMediaId = ctx.state<number | null>(null)
const fetchedData = ctx.state([])

// When the user navigates to an anime, get the media ID
ctx.screen.onNavigate((e) => {
    if (e.pathname === "/entry" && !!e.searchParams.id) {
        const id = parseInt(e.searchParams.id);
        currentMediaId.set(id);
    } else {
        currentMediaId.set(null);
    }
});

// Trigger 'ctx.screen.onNavigate' when the plugin loads 
ctx.screen.loadCurrent()

// Fetch data each time the media ID changes.
ctx.effect(async () => {
    if (!currentMediaId.get()) return
    
    const res = ctx.fetch(`https://example.com/anilistId?=${currentMediaId.get()}`)
    // Store the results
    fetchedData.set(res.json())
}, [currentMediaId])
PreviousUINextUser Interface

Last updated 1 month ago