Nothing it carried is gone -- the two commits before this put all of it somewhere the work is already being done. A retired destination is the one shape #25's storage decision does not make free. A visibility entry is a map key and an unknown key is dropped on load; a launch page is a *value*, and an unknown one fails validation -- which on the load path means the app refuses to start for whoever had Jobs selected. `RetiredViews` is that list, read by `ApplyDefaults`, which treats a retired name as a zero value. An unknown-but-not-retired name still errors, because that is a typo and saying so is the useful answer.
104 lines
4.0 KiB
Go
104 lines
4.0 KiB
Go
package config
|
|
|
|
import "errors"
|
|
|
|
var (
|
|
errUnknownView = errors.New("unknown view")
|
|
errViewNotHideable = errors.New("view cannot be hidden")
|
|
errViewIsLaunchPage = errors.New("view is the launch page")
|
|
)
|
|
|
|
// View identifies one of the shell's primary destinations -- the
|
|
// things the sidebar lists and `index.ts` knows as `VIEW_TAGS`.
|
|
type View string
|
|
|
|
// The primary views, in no particular order: the sidebar owns the order
|
|
// it draws them in, because that is presentation.
|
|
const (
|
|
ViewHome View = "home"
|
|
ViewPlaylists View = "playlists"
|
|
ViewArtists View = "artists"
|
|
ViewGenres View = "genres"
|
|
ViewAlbums View = "albums"
|
|
ViewTracks View = "tracks"
|
|
ViewExplore View = "explore"
|
|
ViewDownloads View = "downloads"
|
|
ViewAutotag View = "autotag"
|
|
ViewSettings View = "settings"
|
|
)
|
|
|
|
// RetiredViews are destinations that used to exist and no longer do.
|
|
//
|
|
// A *visibility* entry for a removed view needs no such list: it is a
|
|
// key in a map, and an unknown key is dropped on load. A `DefaultPage`
|
|
// is a **value**, and an unknown one fails validation -- which on the
|
|
// load path means the app refuses to start rather than a setting being
|
|
// ignored. So the one shape that cannot be retired for free is named
|
|
// here and reset to the default instead.
|
|
//
|
|
// `jobs` was folded into Settings by #27: library scans under
|
|
// Libraries, index work under Search Index, downloads under the
|
|
// download clients, and the autotag apply into the Autotag view.
|
|
var RetiredViews = map[View]struct{}{
|
|
"jobs": {},
|
|
}
|
|
|
|
// ViewSpec is what the backend knows about a destination. The label and
|
|
// the icon are deliberately absent: those are presentation, they live
|
|
// beside the rest of the app's icon vocabulary in
|
|
// `frontend/src/utils/icon-language.ts`, and a Go copy of them would be
|
|
// a second thing to keep in step for nothing.
|
|
type ViewSpec struct {
|
|
// ID is the view name the frontend navigates by.
|
|
ID View
|
|
// VisibleByDefault is what an install gets when the config says
|
|
// nothing about this view -- which is every install until somebody
|
|
// changes it, and every view added after this one shipped.
|
|
VisibleByDefault bool
|
|
// Hideable is false for Settings alone. It is a property of the
|
|
// view rather than a check in the setter because `config.toml` is
|
|
// hand-editable, and an app that can be locked out of its own
|
|
// Settings by a typo is a support problem nobody can debug
|
|
// remotely.
|
|
Hideable bool
|
|
// CanLaunch reports whether the view may be the launch page.
|
|
// Settings is the only one that may not, which is the shape the
|
|
// DefaultPage enum already had.
|
|
CanLaunch bool
|
|
}
|
|
|
|
// Views is the one list of primary destinations, in the order Settings
|
|
// offers them.
|
|
//
|
|
// It is the single source for three things that used to be written down
|
|
// separately: which views exist, which of them may be the launch page
|
|
// (`DefaultPage`'s validation reads it), and what an unconfigured
|
|
// install shows.
|
|
//
|
|
// Autotag is the one view hidden by default: it rewrites tags on disk,
|
|
// which is not what most libraries want on day one, and #25 asks for it
|
|
// to be turned on deliberately.
|
|
var Views = []ViewSpec{
|
|
{ID: ViewHome, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewPlaylists, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewArtists, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewGenres, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewAlbums, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewTracks, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewExplore, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewDownloads, VisibleByDefault: true, Hideable: true, CanLaunch: true},
|
|
{ID: ViewAutotag, VisibleByDefault: false, Hideable: true, CanLaunch: true},
|
|
{ID: ViewSettings, VisibleByDefault: true, Hideable: false, CanLaunch: false},
|
|
}
|
|
|
|
// LookupView returns the spec for a view id.
|
|
func LookupView(id string) (ViewSpec, bool) {
|
|
for _, v := range Views {
|
|
if string(v.ID) == id {
|
|
return v, true
|
|
}
|
|
}
|
|
|
|
return ViewSpec{}, false
|
|
}
|