Plan 016 B4. The catalog artifact is about 0.6 GB and the app fetched it with no awareness of the connection: on a desktop that is a minute of bandwidth, on a phone it can be a month's allowance. It is now skipped on a cellular connection unless `AllowMeteredCatalogDownload` is on, with the toggle in Settings' Search Index section, where the text explaining what the catalog is already lives. The file layout is dictated by the cgo rule rather than by taste. `explore` is imported by `cmd/indexbuild`, which builds with CGO_ENABLED=0 and must not link Wails, so `netpolicy.go` holds the policy and the JSON parsing -- tested on every platform -- and the single platform call is a closure injected from `app.go`, which already names `application` legitimately. Three rules in it are load-bearing. An unknown answer is not a metered one: only mobile answers at all, and treating silence as metered would have disabled the download for every desktop user in the world. Cellular is the only signal available, because the runtime reports `wifi|cellular|ethernet|none` and no metered flag -- so a metered Wi-Fi cannot be detected and is not refused, which is documented rather than implied. And the gate runs before the first status write, so declining is a no-op instead of a job in the indicator and an error tier to dismiss. Two corrections to the plan while implementing it: the portable API is `application.Mobile.NetworkJSON()`, not `application.Android`'s, which exists only under the `android` build tag; and the permission is read at the moment a download would start, so enabling it takes effect on the next attempt rather than the next launch.
92 lines
2.9 KiB
Go
92 lines
2.9 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// DefaultPage identifies which view the app opens to on launch.
|
|
type DefaultPage string
|
|
|
|
// Valid DefaultPage values, matching the frontend's top-level route ids.
|
|
const (
|
|
DefaultPageHome DefaultPage = "home"
|
|
DefaultPageTracks DefaultPage = "tracks"
|
|
DefaultPageAlbums DefaultPage = "albums"
|
|
DefaultPageArtists DefaultPage = "artists"
|
|
DefaultPageGenres DefaultPage = "genres"
|
|
DefaultPagePlaylists DefaultPage = "playlists"
|
|
DefaultPageExplore DefaultPage = "explore"
|
|
DefaultPageDownloads DefaultPage = "downloads"
|
|
DefaultPageAutotag DefaultPage = "autotag"
|
|
DefaultPageJobs DefaultPage = "jobs"
|
|
)
|
|
|
|
// DefaultDefaultPage is the launch page for a fresh install.
|
|
const DefaultDefaultPage = DefaultPageHome
|
|
|
|
var errUnknownDefaultPage = errors.New("unknown default page")
|
|
|
|
// QueueFallback identifies what plays, if anything, once the queue
|
|
// runs out with nothing left to auto-advance to.
|
|
type QueueFallback string
|
|
|
|
// Valid QueueFallback values.
|
|
const (
|
|
QueueFallbackStop QueueFallback = "stop"
|
|
QueueFallbackFavorites QueueFallback = "favorites"
|
|
QueueFallbackDynamicMix QueueFallback = "dynamicMix"
|
|
)
|
|
|
|
// DefaultQueueFallback is the fallback behavior for a fresh install.
|
|
const DefaultQueueFallback = QueueFallbackFavorites
|
|
|
|
var errUnknownQueueFallback = errors.New("unknown queue fallback")
|
|
|
|
// GeneralConfig holds general application preferences that don't
|
|
// belong to a more specific subsystem.
|
|
type GeneralConfig struct {
|
|
DefaultPage DefaultPage `toml:"DefaultPage"`
|
|
QueueFallback QueueFallback `toml:"QueueFallback"`
|
|
// AllowMeteredCatalogDownload permits the ~0.6 GB Explore catalog to
|
|
// be fetched on a connection the platform calls cellular. It defaults
|
|
// to false, which is the whole point: the zero value is the safe one,
|
|
// so an existing config with no such key refuses by default rather
|
|
// than needing a migration to become careful.
|
|
AllowMeteredCatalogDownload bool `toml:"AllowMeteredCatalogDownload"`
|
|
}
|
|
|
|
// ApplyDefaults fills zero-value fields with sensible defaults.
|
|
func (c *GeneralConfig) ApplyDefaults() {
|
|
if c.DefaultPage == "" {
|
|
c.DefaultPage = DefaultDefaultPage
|
|
}
|
|
|
|
if c.QueueFallback == "" {
|
|
c.QueueFallback = DefaultQueueFallback
|
|
}
|
|
}
|
|
|
|
// Validate checks that all values are well-formed.
|
|
func (c *GeneralConfig) Validate() error {
|
|
c.ApplyDefaults()
|
|
|
|
switch c.DefaultPage {
|
|
case DefaultPageHome, DefaultPageTracks, DefaultPageAlbums, DefaultPageArtists,
|
|
DefaultPageGenres, DefaultPagePlaylists, DefaultPageExplore, DefaultPageDownloads,
|
|
DefaultPageAutotag, DefaultPageJobs:
|
|
// Valid.
|
|
default:
|
|
return fmt.Errorf("%w: %q", errUnknownDefaultPage, c.DefaultPage)
|
|
}
|
|
|
|
switch c.QueueFallback {
|
|
case QueueFallbackStop, QueueFallbackFavorites, QueueFallbackDynamicMix:
|
|
// Valid.
|
|
default:
|
|
return fmt.Errorf("%w: %q", errUnknownQueueFallback, c.QueueFallback)
|
|
}
|
|
|
|
return nil
|
|
}
|