1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

themes: support for variants

This commit is contained in:
bbedward
2025-12-26 14:00:14 -05:00
parent 06b14a5869
commit ef52ce0990
10 changed files with 514 additions and 348 deletions

View File

@@ -31,7 +31,7 @@ func HandleList(conn net.Conn, req models.Request) {
result := make([]ThemeInfo, len(themeList))
for i, t := range themeList {
installed, _ := manager.IsInstalled(t)
result[i] = ThemeInfo{
info := ThemeInfo{
ID: t.ID,
Name: t.Name,
Version: t.Version,
@@ -42,6 +42,17 @@ func HandleList(conn net.Conn, req models.Request) {
Installed: installed,
FirstParty: isFirstParty(t.Author),
}
if t.Variants != nil && len(t.Variants.Options) > 0 {
info.HasVariants = true
info.Variants = &VariantsInfo{
Default: t.Variants.Default,
Options: make([]VariantInfo, len(t.Variants.Options)),
}
for j, v := range t.Variants.Options {
info.Variants.Options[j] = VariantInfo{ID: v.ID, Name: v.Name}
}
}
result[i] = info
}
models.Respond(conn, req.ID, result)

View File

@@ -8,6 +8,20 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/themes"
)
func addVariantsInfo(info *ThemeInfo, variants *themes.ThemeVariants) {
if variants == nil || len(variants.Options) == 0 {
return
}
info.HasVariants = true
info.Variants = &VariantsInfo{
Default: variants.Default,
Options: make([]VariantInfo, len(variants.Options)),
}
for i, v := range variants.Options {
info.Variants.Options[i] = VariantInfo{ID: v.ID, Name: v.Name}
}
}
func HandleListInstalled(conn net.Conn, req models.Request) {
manager, err := themes.NewManager()
if err != nil {
@@ -46,7 +60,7 @@ func HandleListInstalled(conn net.Conn, req models.Request) {
hasUpdate = hasUpdates
}
result = append(result, ThemeInfo{
info := ThemeInfo{
ID: theme.ID,
Name: theme.Name,
Version: theme.Version,
@@ -55,7 +69,9 @@ func HandleListInstalled(conn net.Conn, req models.Request) {
SourceDir: id,
FirstParty: isFirstParty(theme.Author),
HasUpdate: hasUpdate,
})
}
addVariantsInfo(&info, theme.Variants)
result = append(result, info)
} else {
installed, err := manager.GetInstalledTheme(id)
if err != nil {
@@ -66,7 +82,7 @@ func HandleListInstalled(conn net.Conn, req models.Request) {
})
continue
}
result = append(result, ThemeInfo{
info := ThemeInfo{
ID: installed.ID,
Name: installed.Name,
Version: installed.Version,
@@ -74,7 +90,9 @@ func HandleListInstalled(conn net.Conn, req models.Request) {
Description: installed.Description,
SourceDir: id,
FirstParty: isFirstParty(installed.Author),
})
}
addVariantsInfo(&info, installed.Variants)
result = append(result, info)
}
}

View File

@@ -1,14 +1,26 @@
package themes
type ThemeInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author,omitempty"`
Description string `json:"description,omitempty"`
PreviewPath string `json:"previewPath,omitempty"`
SourceDir string `json:"sourceDir,omitempty"`
Installed bool `json:"installed,omitempty"`
FirstParty bool `json:"firstParty,omitempty"`
HasUpdate bool `json:"hasUpdate,omitempty"`
type VariantInfo struct {
ID string `json:"id"`
Name string `json:"name"`
}
type VariantsInfo struct {
Default string `json:"default,omitempty"`
Options []VariantInfo `json:"options,omitempty"`
}
type ThemeInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author,omitempty"`
Description string `json:"description,omitempty"`
PreviewPath string `json:"previewPath,omitempty"`
SourceDir string `json:"sourceDir,omitempty"`
Installed bool `json:"installed,omitempty"`
FirstParty bool `json:"firstParty,omitempty"`
HasUpdate bool `json:"hasUpdate,omitempty"`
HasVariants bool `json:"hasVariants,omitempty"`
Variants *VariantsInfo `json:"variants,omitempty"`
}

View File

@@ -80,21 +80,35 @@ func (m *Manager) Install(theme Theme, registryThemeDir string) error {
return fmt.Errorf("failed to write theme file: %w", err)
}
for _, preview := range []string{"preview-dark.svg", "preview-light.svg"} {
srcPath := filepath.Join(registryThemeDir, preview)
exists, _ := afero.Exists(m.fs, srcPath)
if !exists {
m.copyPreviewFiles(registryThemeDir, themeDir, theme)
return nil
}
func (m *Manager) copyPreviewFiles(srcDir, dstDir string, theme Theme) {
previews := []string{"preview-dark.svg", "preview-light.svg"}
if theme.Variants != nil {
for _, v := range theme.Variants.Options {
previews = append(previews,
fmt.Sprintf("preview-%s.svg", v.ID),
fmt.Sprintf("preview-%s-dark.svg", v.ID),
fmt.Sprintf("preview-%s-light.svg", v.ID),
)
}
}
for _, preview := range previews {
srcPath := filepath.Join(srcDir, preview)
if exists, _ := afero.Exists(m.fs, srcPath); !exists {
continue
}
data, err := afero.ReadFile(m.fs, srcPath)
if err != nil {
continue
}
dstPath := filepath.Join(themeDir, preview)
dstPath := filepath.Join(dstDir, preview)
_ = afero.WriteFile(m.fs, dstPath, data, 0644)
}
return nil
}
func (m *Manager) InstallFromRegistry(registry *Registry, themeID string) error {

View File

@@ -13,35 +13,49 @@ import (
const registryRepo = "https://github.com/AvengeMedia/dms-plugin-registry.git"
type ColorScheme struct {
Primary string `json:"primary"`
PrimaryText string `json:"primaryText"`
PrimaryContainer string `json:"primaryContainer"`
Secondary string `json:"secondary"`
Surface string `json:"surface"`
SurfaceText string `json:"surfaceText"`
SurfaceVariant string `json:"surfaceVariant"`
SurfaceVariantText string `json:"surfaceVariantText"`
SurfaceTint string `json:"surfaceTint"`
Background string `json:"background"`
BackgroundText string `json:"backgroundText"`
Outline string `json:"outline"`
SurfaceContainer string `json:"surfaceContainer"`
SurfaceContainerHigh string `json:"surfaceContainerHigh"`
Error string `json:"error"`
Warning string `json:"warning"`
Info string `json:"info"`
Primary string `json:"primary,omitempty"`
PrimaryText string `json:"primaryText,omitempty"`
PrimaryContainer string `json:"primaryContainer,omitempty"`
Secondary string `json:"secondary,omitempty"`
Surface string `json:"surface,omitempty"`
SurfaceText string `json:"surfaceText,omitempty"`
SurfaceVariant string `json:"surfaceVariant,omitempty"`
SurfaceVariantText string `json:"surfaceVariantText,omitempty"`
SurfaceTint string `json:"surfaceTint,omitempty"`
Background string `json:"background,omitempty"`
BackgroundText string `json:"backgroundText,omitempty"`
Outline string `json:"outline,omitempty"`
SurfaceContainer string `json:"surfaceContainer,omitempty"`
SurfaceContainerHigh string `json:"surfaceContainerHigh,omitempty"`
SurfaceContainerHighest string `json:"surfaceContainerHighest,omitempty"`
Error string `json:"error,omitempty"`
Warning string `json:"warning,omitempty"`
Info string `json:"info,omitempty"`
}
type ThemeVariant struct {
ID string `json:"id"`
Name string `json:"name"`
Dark ColorScheme `json:"dark,omitempty"`
Light ColorScheme `json:"light,omitempty"`
}
type ThemeVariants struct {
Default string `json:"default,omitempty"`
Options []ThemeVariant `json:"options,omitempty"`
}
type Theme struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author"`
Description string `json:"description"`
Dark ColorScheme `json:"dark"`
Light ColorScheme `json:"light"`
PreviewPath string `json:"-"`
SourceDir string `json:"sourceDir,omitempty"`
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Author string `json:"author"`
Description string `json:"description"`
Dark ColorScheme `json:"dark"`
Light ColorScheme `json:"light"`
Variants *ThemeVariants `json:"variants,omitempty"`
PreviewPath string `json:"-"`
SourceDir string `json:"sourceDir,omitempty"`
}
type GitClient interface {