Documentation
¶
Overview ¶
Package themes implements theme discovery, installation, and custom theme uploads.
Index ¶
- type ConfigTheme
- type Manager
- func (m *Manager) DeleteCustomTheme(name, username string, isAdmin bool) (found bool, err error)
- func (m *Manager) GetAll(username string, isAdmin bool) []ConfigTheme
- func (m *Manager) GetByName(name string) (Theme, bool)
- func (m *Manager) LoadInstalledThemes(packagesPath string) error
- func (m *Manager) LoadLocalThemes(builtinThemesDir string) error
- func (m *Manager) LoadUserThemes() error
- func (m *Manager) SaveCustomTheme(displayName, css, username string, isAdmin bool) (Theme, error)
- type Theme
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConfigTheme ¶
type ConfigTheme struct {
CanDelete bool `json:"canDelete,omitempty"`
Category string `json:"category"`
DisplayName string `json:"displayName"`
Name string `json:"name"`
ThemeColor *string `json:"themeColor"`
UserDefined bool `json:"userDefined,omitempty"`
}
ConfigTheme mirrors client/js/types/config.ts's ConfigTheme - the shape exposed to clients (no filesystem paths, and CanDelete is requester-specific so it can't live on the stored Theme itself).
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager mirrors themes.ts's module-level `themes` Map plus its static methods, wrapped in a struct (rather than package state) for the same reason internal/shortlinks.Store and internal/uploads.TokenStore are - tests need independent instances.
func NewManager ¶
NewManager constructs an empty Manager. userThemesPath is Config.getUserThemesPath() (server/config.ts) - internal/config.Loaded's UserThemesPath().
func (*Manager) DeleteCustomTheme ¶
DeleteCustomTheme mirrors themes.ts's deleteCustomTheme. found reports whether a theme by that name existed at all (mirroring the `false` return for "not found", distinct from the thrown-error permission cases).
func (*Manager) GetAll ¶
func (m *Manager) GetAll(username string, isAdmin bool) []ConfigTheme
GetAll mirrors themes.ts's getAll: every registered theme, sorted by display name, with CanDelete computed per-requester.
func (*Manager) LoadInstalledThemes ¶
LoadInstalledThemes registers every package installed via `relay install` (internal/packages.Install) under packagesPath, reading each one's theme.json - the Go-native replacement for themes.ts's addTheme(), which registered a theme from an npm package's package.json.
Must run after both LoadLocalThemes and LoadUserThemes, and - matching addTheme's own unconditional `themes.set(theme.name, theme)`, which has no existence check at all - a name collision here always overwrites whatever LoadLocalThemes/LoadUserThemes already registered, rather than being skipped. This mirrors real Node behavior: server.ts calls loadLocalThemes()/loadUserThemes() synchronously at startup, then fires `void packages.loadPackages()` afterwards (fire-and-forget, so its addTheme calls land strictly later) - an installed package genuinely can shadow a built-in or custom theme sharing its name. LoadUserThemes's own "never shadow" skip-if-exists check is only ever evaluated against LoadLocalThemes's registrations at that point in real Node's timing too, never against installed packages.
Unlike Node's loadPackages, which also fs.watches packages/package.json and hot-registers any newly-installed theme without a restart, this is called once at startup only (internal/session.NewManager) - `relay install` while the server is already running requires a restart before the new theme is selectable. Documented, accepted gap: hot-reload is a minor convenience on top of the actual startup wiring, which previously didn't exist at all (LoadInstalledThemes was implemented and tested but never called from anywhere in production code).
func (*Manager) LoadLocalThemes ¶
LoadLocalThemes mirrors themes.ts's loadLocalThemes: register every bundled *.css theme found in builtinThemesDir (server/config.js's `public/themes`, the client build's static theme directory).
func (*Manager) LoadUserThemes ¶
LoadUserThemes mirrors themes.ts's loadUserThemes: register every custom theme saved under m.userThemesPath, skipping any name a bundled or installed theme already occupies (custom themes must never shadow those).
func (*Manager) SaveCustomTheme ¶
SaveCustomTheme mirrors themes.ts's saveCustomTheme, including its exact ownership-conflict error messages (surfaced to the client verbatim by the theme:upload socket handler).
type Theme ¶
type Theme struct {
Category string
DisplayName string
Filename string // absolute path to the theme's .css file; empty for the bundled default theme entry
Name string
Owner string // only set for UserDefined themes with a known owner
ThemeColor *string
UserDefined bool
}
Theme mirrors themes.ts's ThemeForClient.