feat(branding): add white-label branding system (v0.52.0)
Some checks failed
Go / build-and-release (push) Has been cancelled

Add runtime-customizable branding allowing relay operators to fully
customize UI appearance without rebuilding:

- Custom logo, favicon, and PWA icons
- Full CSS override capability (colors, themes, components)
- Custom app name, title, and NIP-11 relay info
- init-branding command with --style generic|orly options
- Transparent PNG generation for generic branding

New files:
- app/branding/ package (branding.go, init.go, types.go)
- docs/BRANDING_GUIDE.md

Environment variables:
- ORLY_BRANDING_DIR: branding directory path
- ORLY_BRANDING_ENABLED: enable/disable custom branding

Usage: ./orly init-branding --style generic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
woikos
2026-01-16 17:07:00 +01:00
parent 37d4be5e93
commit 7abcbafaf4
10 changed files with 1740 additions and 2 deletions

View File

@@ -10,9 +10,11 @@ import (
"sync"
"time"
"github.com/adrg/xdg"
"golang.org/x/crypto/acme/autocert"
"lol.mleku.dev/chk"
"lol.mleku.dev/log"
"next.orly.dev/app/branding"
"next.orly.dev/app/config"
"next.orly.dev/pkg/acl"
"git.mleku.dev/mleku/nostr/crypto/keys"
@@ -91,6 +93,21 @@ func Run(
db: db,
}
// Initialize branding/white-label manager if enabled
if cfg.BrandingEnabled {
brandingDir := cfg.BrandingDir
if brandingDir == "" {
brandingDir = filepath.Join(xdg.ConfigHome, cfg.AppName, "branding")
}
if _, err := os.Stat(brandingDir); err == nil {
if l.brandingMgr, err = branding.New(brandingDir); err != nil {
log.W.F("failed to load branding from %s: %v", brandingDir, err)
} else {
log.I.F("custom branding loaded from %s", brandingDir)
}
}
}
// Initialize NIP-43 invite manager if enabled
if cfg.NIP43Enabled {
l.InviteManager = nip43.NewInviteManager(cfg.NIP43InviteExpiry)