|
| 1 | +--- |
| 2 | +description: Supply dashboard content: top tracks, trending artists, curated playlists, and more. |
| 3 | +--- |
| 4 | + |
| 5 | +# Dashboard |
| 6 | + |
| 7 | +## Dashboard Providers |
| 8 | + |
| 9 | +Dashboard providers supply Nuclear's home screen with content like charts, trending artists, new releases, and curated playlists. When you open the player, Nuclear calls each registered dashboard provider and assembles the results into an overview. Without a dashboard provider, the dashboard shows an empty state prompting the user to enable a plugin. |
| 10 | + |
| 11 | +Plugins can either add a new dashboard provider, or consume dashboard data from existing providers. |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +## Implementing a provider |
| 16 | + |
| 17 | +### Minimal example |
| 18 | + |
| 19 | +You register dashboard providers with `api.Providers.register()` just like any other provider. It needs an `id`, `kind: 'dashboard'`, a `name`, a `metadataProviderId`, and a list of `capabilities` declaring which content it can supply: |
| 20 | + |
| 21 | +```typescript |
| 22 | +import type { DashboardProvider, NuclearPlugin, NuclearPluginAPI } from '@nuclearplayer/plugin-sdk'; |
| 23 | + |
| 24 | +const provider: DashboardProvider = { |
| 25 | + id: 'acme-dashboard', |
| 26 | + kind: 'dashboard', |
| 27 | + name: 'Acme Music', |
| 28 | + |
| 29 | + metadataProviderId: 'acme-metadata', |
| 30 | + capabilities: ['topTracks', 'newReleases'], |
| 31 | + |
| 32 | + async fetchTopTracks() { |
| 33 | + // Call your API, return Track[] |
| 34 | + }, |
| 35 | + async fetchNewReleases() { |
| 36 | + // Call your API, return AlbumRef[] |
| 37 | + }, |
| 38 | +}; |
| 39 | + |
| 40 | +const plugin: NuclearPlugin = { |
| 41 | + onEnable(api: NuclearPluginAPI) { |
| 42 | + api.Providers.register(provider); |
| 43 | + }, |
| 44 | + onDisable(api: NuclearPluginAPI) { |
| 45 | + api.Providers.unregister('acme-dashboard'); |
| 46 | + }, |
| 47 | +}; |
| 48 | + |
| 49 | +export default plugin; |
| 50 | +``` |
| 51 | + |
| 52 | +{% hint style="warning" %} |
| 53 | +Always unregister your provider in `onDisable`. If you don't, it stays registered and Nuclear will keep calling it after the plugin is disabled. |
| 54 | +{% endhint %} |
| 55 | + |
| 56 | +### Capabilities |
| 57 | + |
| 58 | +Capabilities tell Nuclear which content your provider can fetch. Nuclear only calls methods for capabilities you declare. If you don't list `'topArtists'`, `fetchTopArtists` is never called even if you define it. |
| 59 | + |
| 60 | +| Capability | Method called | Returns | Widget | |
| 61 | +|------------|--------------|---------|--------| |
| 62 | +| `'topTracks'` | `fetchTopTracks()` | `Track[]` | Track table with playback controls | |
| 63 | +| `'topArtists'` | `fetchTopArtists()` | `ArtistRef[]` | Artist card row | |
| 64 | +| `'topAlbums'` | `fetchTopAlbums()` | `AlbumRef[]` | Album card row | |
| 65 | +| `'editorialPlaylists'` | `fetchEditorialPlaylists()` | `PlaylistRef[]` | Playlist card row | |
| 66 | +| `'newReleases'` | `fetchNewReleases()` | `AlbumRef[]` | Album card row | |
| 67 | + |
| 68 | +{% hint style="info" %} |
| 69 | +Nuclear only calls methods for declared capabilities. Declare only the ones you actually implement. |
| 70 | +{% endhint %} |
| 71 | + |
| 72 | +Note that `fetchTopTracks` returns full `Track[]` objects, not `TrackRef[]`. The dashboard track table needs complete track data (title, artist, duration, thumbnail) to render without additional lookups. |
| 73 | + |
| 74 | +--- |
| 75 | + |
| 76 | +## The `metadataProviderId` field |
| 77 | + |
| 78 | +Every dashboard provider must specify a `metadataProviderId`. This tells Nuclear which metadata provider can look up the entities your dashboard returns. |
| 79 | + |
| 80 | +When a user clicks an artist or album on the dashboard, Nuclear navigates to a detail page. It needs to know which metadata provider can fetch that entity's full details, that's what `metadataProviderId` is for. If you set it to a provider that doesn't exist or can't resolve your IDs, artist and album links from the dashboard will fail. |
| 81 | + |
| 82 | +Typically, your plugin registers both a metadata provider and a dashboard provider, and they share the same underlying API. Point `metadataProviderId` at your metadata provider's `id`. |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +## Attributed results |
| 87 | + |
| 88 | +When multiple dashboard providers are registered, Nuclear will render results from all of them. The API wraps each provider's data in an `AttributedResult<T>`: |
| 89 | + |
| 90 | +```typescript |
| 91 | +type AttributedResult<T> = { |
| 92 | + providerId: string; |
| 93 | + metadataProviderId: string; |
| 94 | + providerName: string; |
| 95 | + items: T[]; |
| 96 | +}; |
| 97 | +``` |
| 98 | + |
| 99 | +Each attributed result carries the provider's name and IDs, so Nuclear can render labeled sections (e.g. "Top Tracks - Acme Music") and route navigation to the correct metadata provider. |
| 100 | + |
| 101 | +--- |
| 102 | + |
| 103 | +## Using dashboard data |
| 104 | + |
| 105 | +Plugins can consume dashboard data from all registered providers via `api.Dashboard.*`: |
| 106 | + |
| 107 | +```typescript |
| 108 | +export default { |
| 109 | + async onEnable(api: NuclearPluginAPI) { |
| 110 | + const topTracks = await api.Dashboard.fetchTopTracks(); |
| 111 | + |
| 112 | + for (const result of topTracks) { |
| 113 | + console.log(`${result.providerName}: ${result.items.length} tracks`); |
| 114 | + } |
| 115 | + }, |
| 116 | +}; |
| 117 | +``` |
| 118 | + |
| 119 | +### Consumer reference |
| 120 | + |
| 121 | +```typescript |
| 122 | +api.Dashboard.fetchTopTracks(providerId?: string): Promise<AttributedResult<Track>[]> |
| 123 | +api.Dashboard.fetchTopArtists(providerId?: string): Promise<AttributedResult<ArtistRef>[]> |
| 124 | +api.Dashboard.fetchTopAlbums(providerId?: string): Promise<AttributedResult<AlbumRef>[]> |
| 125 | +api.Dashboard.fetchEditorialPlaylists(providerId?: string): Promise<AttributedResult<PlaylistRef>[]> |
| 126 | +api.Dashboard.fetchNewReleases(providerId?: string): Promise<AttributedResult<AlbumRef>[]> |
| 127 | +``` |
| 128 | + |
| 129 | +All methods accept an optional `providerId`. If omitted, Nuclear queries all registered dashboard providers and returns an array with one `AttributedResult` per provider. If provided, only that provider is queried. |
| 130 | + |
| 131 | +--- |
0 commit comments