The durable "I asked for this" record was called Want, and the one-shot search-and-grab attempt was called Request — names that didn't match what either actually did. Want is now Request, and the old Request/Item is now Download/DownloadItem, with a table-rename migration (download_wants -> download_requests, old download_requests -> download_downloads) safe against both fresh installs and existing data. Every anchored manual download now upserts/reuses a durable Request before running, so a "download now" that finds nothing is picked up by the background reconciler automatically instead of just failing with no trace — the gap that caused this session's repeated "no candidates found" failures on the same album. Also adds auto-download guardrails (file-size min/max with a preferred target, allowed file types) that gate what the pipeline may grab unattended, live-editable from a new settings section. The frontend's wanted-view becomes downloads-view, with a new Downloads tab showing attempt/transfer history that previously had no UI at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y2Agd9af5hE7qzti2ackiS
138 lines
4.9 KiB
Go
138 lines
4.9 KiB
Go
// Package events contains centralized event name constants for
|
|
// Wails frontend/backend communication. These names must match
|
|
// the corresponding event names in the TypeScript frontend.
|
|
package events
|
|
|
|
//go:generate go run ./cmd/genevents -source events.go -output ../../frontend/src/events.ts
|
|
|
|
// Playback events (backend → frontend push).
|
|
const (
|
|
PlaybackStateChanged = "PlaybackStateChanged"
|
|
PlaybackFinished = "PlaybackFinished"
|
|
TrackChanged = "TrackChanged"
|
|
SeekFailed = "SeekFailed"
|
|
VolumeChanged = "VolumeChanged"
|
|
)
|
|
|
|
// Queue events (backend → frontend push).
|
|
const (
|
|
QueueChanged = "QueueChanged"
|
|
QueueIndexChanged = "QueueIndexChanged"
|
|
QueueModeChanged = "QueueModeChanged"
|
|
QueueTracksModified = "QueueTracksModified"
|
|
)
|
|
|
|
// Config events.
|
|
const (
|
|
LibraryConfigChanged = "LibraryConfigChanged"
|
|
ThemeConfigChanged = "ThemeConfigChanged"
|
|
TrackListConfigChanged = "TrackListConfigChanged"
|
|
FavoritesConfigChanged = "FavoritesConfigChanged"
|
|
ShortcutsConfigChanged = "ShortcutsConfigChanged"
|
|
)
|
|
|
|
// Playlist events.
|
|
const (
|
|
PlaylistCreated = "PlaylistCreated"
|
|
PlaylistDeleted = "PlaylistDeleted"
|
|
PlaylistRenamed = "PlaylistRenamed"
|
|
PlaylistTracksChanged = "PlaylistTracksChanged"
|
|
PlaylistsRestored = "PlaylistsRestored"
|
|
DefaultPlaylistChanged = "DefaultPlaylistChanged"
|
|
)
|
|
|
|
// Library events.
|
|
const (
|
|
LibraryScanStarted = "LibraryScanStarted"
|
|
LibraryScanProgress = "LibraryScanProgress"
|
|
LibraryScanComplete = "LibraryScanComplete"
|
|
)
|
|
|
|
// Scan control events.
|
|
const (
|
|
LibraryScanCancelled = "LibraryScanCancelled"
|
|
LibraryScanPaused = "LibraryScanPaused"
|
|
LibraryScanResumed = "LibraryScanResumed"
|
|
)
|
|
|
|
// Scan queue events.
|
|
const (
|
|
LibraryScanQueued = "LibraryScanQueued"
|
|
LibraryScanQueueDrained = "LibraryScanQueueDrained"
|
|
)
|
|
|
|
// Library CRUD events.
|
|
const (
|
|
LibraryAdded = "LibraryAdded"
|
|
LibraryRenamed = "LibraryRenamed"
|
|
LibraryRemoved = "LibraryRemoved"
|
|
)
|
|
|
|
// Tag writing events.
|
|
const (
|
|
TrackMetadataChanged = "TrackMetadataChanged"
|
|
BatchWriteProgress = "BatchWriteProgress"
|
|
)
|
|
|
|
// Autotag apply events — emitted while an async ApplyAsync job is in flight so the review UI can render per-folder progress.
|
|
const (
|
|
AutotagApplyStarted = "AutotagApplyStarted" // {groupKey: string, total: int}
|
|
AutotagApplyProgress = "AutotagApplyProgress" // {groupKey, current, total, succeeded, failed}
|
|
AutotagApplyFinished = "AutotagApplyFinished" // {groupKey, succeeded, failed, error}
|
|
)
|
|
|
|
// Autotag prefetch events — emitted by the background worker that scores pending tagging items so sidebar pills populate without the user having to open each folder.
|
|
const (
|
|
AutotagPrefetchProgress = "AutotagPrefetchProgress" // {processed, total} — debounce on frontend
|
|
AutotagPrefetchFinished = "AutotagPrefetchFinished" // {processed, total}
|
|
)
|
|
|
|
// Background job events.
|
|
const (
|
|
// JobsChanged carries a full snapshot of every known background job
|
|
// (see backend/jobs). A full snapshot rather than a delta means a
|
|
// component mounting mid-scan is correct from its first event.
|
|
// Emitted coalesced, at most every 250ms.
|
|
JobsChanged = "JobsChanged"
|
|
)
|
|
|
|
// Explore / search index events.
|
|
const (
|
|
IndexStatusChanged = "IndexStatusChanged"
|
|
|
|
// ArtistDiscographyReady fires (payload: artist MBID string) after a
|
|
// lazy background discography fetch persists into the index, so the
|
|
// artist detail page can re-fetch its top tracks / top releases
|
|
// without the initial request having blocked on a live fetch.
|
|
ArtistDiscographyReady = "ArtistDiscographyReady"
|
|
|
|
// ArtistSimilarReady fires (payload: artist MBID string) after a lazy
|
|
// background similar-artists fetch persists into similar_artist_map,
|
|
// so the artist detail page can re-fetch that section without the
|
|
// initial request having blocked on a live LB labs call.
|
|
ArtistSimilarReady = "ArtistSimilarReady"
|
|
|
|
// AlbumReleasesReady fires (payload: release-group MBID string) after a
|
|
// lazy background BrowseReleases fetch populates the response cache, so
|
|
// the album detail page can re-fetch its versions / tracklist without
|
|
// the initial request having blocked on a live MusicBrainz browse.
|
|
AlbumReleasesReady = "AlbumReleasesReady"
|
|
|
|
// DownloadProvidersChanged fires after a download client is added,
|
|
// edited, enabled/disabled or removed, so the settings page and any
|
|
// open download picker re-read the provider list.
|
|
DownloadProvidersChanged = "DownloadProvidersChanged"
|
|
|
|
// DownloadsChanged fires when the set of downloads changes (started,
|
|
// picked, cancelled, cleared). Per-transfer progress does not use
|
|
// this — it flows through the jobs registry's JobsChanged, which
|
|
// already coalesces high-frequency updates.
|
|
DownloadsChanged = "DownloadsChanged"
|
|
|
|
// RequestsChanged fires when the request list gains, loses or
|
|
// retires an entry — including from a background reconcile pass,
|
|
// which is why the list is event-driven rather than fetched once on
|
|
// mount.
|
|
RequestsChanged = "RequestsChanged"
|
|
)
|