internal/domain/themes.go
Rama main · réplica de lectura del repositorio original.
package domain
import "errors"
// Errors related to custom cloud themes (account.createTheme etc.).
var (
ErrThemeNotFound = errors.New("theme not found")
ErrThemeInvalid = errors.New("theme invalid")
ErrThemeSlugTaken = errors.New("theme slug taken")
ErrThemeFormatInvalid = errors.New("theme format invalid")
)
// ThemeBaseKind corresponds to the five variants of TL baseTheme (classic/day/night/tinted/arctic).
// The client selects the matching ThemeSettings based on the current base theme.
type ThemeBaseKind string
const (
ThemeBaseClassic ThemeBaseKind = "classic"
ThemeBaseDay ThemeBaseKind = "day"
ThemeBaseNight ThemeBaseKind = "night"
ThemeBaseTinted ThemeBaseKind = "tinted"
ThemeBaseArctic ThemeBaseKind = "arctic"
)
// ThemeWallpaperSpec is a pure-gradient wallpaper within a theme setting (corresponding to wallPaperNoFile + wallPaperSettings).
// Custom cloud themes use only solid-color gradients (no download), consistent with the static catalog.
type ThemeWallpaperSpec struct {
BackgroundColors []int `json:"background_colors,omitempty"` // at most 4
Intensity int `json:"intensity,omitempty"`
Rotation int `json:"rotation,omitempty"`
Blur bool `json:"blur,omitempty"`
Motion bool `json:"motion,omitempty"`
Emoticon string `json:"emoticon,omitempty"`
Dark bool `json:"dark,omitempty"`
}
// WallpaperSettings is the domain-only settings for a channel/private-chat wallpaper. The Has* fields keep TL
// conditional-flag semantics so that legally valid values like black (0) are not lost on persistence.
type WallpaperSettings struct {
Blur bool `json:"blur,omitempty"`
Motion bool `json:"motion,omitempty"`
HasBackgroundColor bool `json:"has_background_color,omitempty"`
BackgroundColor int `json:"background_color,omitempty"`
HasSecondBackgroundColor bool `json:"has_second_background_color,omitempty"`
SecondBackgroundColor int `json:"second_background_color,omitempty"`
HasThirdBackgroundColor bool `json:"has_third_background_color,omitempty"`
ThirdBackgroundColor int `json:"third_background_color,omitempty"`
HasFourthBackgroundColor bool `json:"has_fourth_background_color,omitempty"`
FourthBackgroundColor int `json:"fourth_background_color,omitempty"`
HasIntensity bool `json:"has_intensity,omitempty"`
Intensity int `json:"intensity,omitempty"`
HasRotation bool `json:"has_rotation,omitempty"`
Rotation int `json:"rotation,omitempty"`
HasEmoticon bool `json:"has_emoticon,omitempty"`
Emoticon string `json:"emoticon,omitempty"`
}
// Empty reports whether no explicit wallpaper rendering settings are present.
func (s WallpaperSettings) Empty() bool {
return !s.Blur &&
!s.Motion &&
!s.HasBackgroundColor &&
!s.HasSecondBackgroundColor &&
!s.HasThirdBackgroundColor &&
!s.HasFourthBackgroundColor &&
!s.HasIntensity &&
!s.HasRotation &&
!s.HasEmoticon
}
// Wallpaper is the domain-only description of a channel/private-chat's current wallpaper. NoFile=true corresponds to
// wallPaperNoFile; otherwise ID+AccessHash/Slug references a catalog/document wallpaper.
type Wallpaper struct {
ID int64 `json:"id,omitempty"`
AccessHash int64 `json:"access_hash,omitempty"`
Slug string `json:"slug,omitempty"`
NoFile bool `json:"no_file,omitempty"`
Default bool `json:"default,omitempty"`
Pattern bool `json:"pattern,omitempty"`
Dark bool `json:"dark,omitempty"`
Settings WallpaperSettings `json:"settings,omitempty"`
}
// CloneWallpaperPtr returns a detached wallpaper pointer.
func CloneWallpaperPtr(in *Wallpaper) *Wallpaper {
if in == nil {
return nil
}
out := *in
return &out
}
// WallpaperEqual compares optional wallpapers by value.
func WallpaperEqual(a, b *Wallpaper) bool {
if a == nil || b == nil {
return a == nil && b == nil
}
return *a == *b
}
// ThemeSettingsSpec is the color scheme under one base theme (corresponding to themeSettings/inputThemeSettings).
// BaseTheme and AccentColor are required (the TL encoder requires base_theme to be non-empty).
type ThemeSettingsSpec struct {
BaseTheme ThemeBaseKind `json:"base_theme"`
AccentColor int `json:"accent_color"`
OutboxAccentColor int `json:"outbox_accent_color,omitempty"`
HasOutboxAccent bool `json:"has_outbox_accent,omitempty"`
MessageColors []int `json:"message_colors,omitempty"`
MessageColorsAnimated bool `json:"message_colors_animated,omitempty"`
Wallpaper *ThemeWallpaperSpec `json:"wallpaper,omitempty"`
}
// Theme is a persisted custom cloud theme. document_id soft-references documents (no hard foreign key);
// settings is non-empty only for accent themes; a full .attheme theme is downloaded via DocumentID.
type Theme struct {
ID int64
AccessHash int64
CreatorUserID int64
Slug string
Title string
Emoticon string
ForChat bool
DocumentID int64
Settings []ThemeSettingsSpec
InstallsCount int
CreatedAt int64 // unix seconds
}
// Clone deep-copies the slice fields so the in-memory store never exposes internal references.
func (t Theme) Clone() Theme {
out := t
out.Settings = cloneThemeSettings(t.Settings)
return out
}
func cloneThemeSettings(in []ThemeSettingsSpec) []ThemeSettingsSpec {
if in == nil {
return nil
}
out := make([]ThemeSettingsSpec, len(in))
for i, s := range in {
out[i] = s
out[i].MessageColors = append([]int(nil), s.MessageColors...)
if s.Wallpaper != nil {
wp := *s.Wallpaper
wp.BackgroundColors = append([]int(nil), s.Wallpaper.BackgroundColors...)
out[i].Wallpaper = &wp
}
}
return out
}
// IsCreator reports whether userID created the theme (deciding whether a subsequent client upload uses create or update).
func (t Theme) IsCreator(userID int64) bool {
return t.CreatorUserID != 0 && t.CreatorUserID == userID
}
// ThemeRef references a theme: by id+access_hash (inputTheme) or slug (inputThemeSlug, a deep link).
type ThemeRef struct {
ID int64
AccessHash int64
Slug string
}
// IsZero reports whether the reference is empty (neither id nor slug).
func (r ThemeRef) IsZero() bool { return r.ID == 0 && r.Slug == "" }
// ThemeSpec is the input of createTheme. An empty Slug means the server assigns one automatically.
type ThemeSpec struct {
CreatorUserID int64
Slug string
Title string
Emoticon string
ForChat bool
DocumentID int64
Settings []ThemeSettingsSpec
}
// ThemeUpdate is a partial update of updateTheme; a nil field means unchanged.
type ThemeUpdate struct {
Slug *string
Title *string
DocumentID *int64
Settings *[]ThemeSettingsSpec
}