feat(tui): add 13 preloaded themes matching web design system #39
@@ -115,7 +115,7 @@ func (d detailModel) previewView(width int) string {
|
|||||||
bodyWidth = 20
|
bodyWidth = 20
|
||||||
}
|
}
|
||||||
r, _ := glamour.NewTermRenderer(
|
r, _ := glamour.NewTermRenderer(
|
||||||
glamour.WithStylePath("dark"),
|
glamour.WithStylePath(glamourStyle()),
|
||||||
glamour.WithWordWrap(bodyWidth),
|
glamour.WithWordWrap(bodyWidth),
|
||||||
)
|
)
|
||||||
rendered, err := r.Render(e.Body)
|
rendered, err := r.Render(e.Body)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ func renderHelp(width, height int) string {
|
|||||||
{"2", "cards view"},
|
{"2", "cards view"},
|
||||||
{"s", "cycle sort (cards)"},
|
{"s", "cycle sort (cards)"},
|
||||||
{"i", "cycle intent (cards)"},
|
{"i", "cycle intent (cards)"},
|
||||||
|
{"T", "cycle theme"},
|
||||||
}},
|
}},
|
||||||
{"Actions", [][2]string{
|
{"Actions", [][2]string{
|
||||||
{"d", "delete (with confirm)"},
|
{"d", "delete (with confirm)"},
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ type keyMap struct {
|
|||||||
Tab key.Binding
|
Tab key.Binding
|
||||||
ToggleRail key.Binding
|
ToggleRail key.Binding
|
||||||
Stumble key.Binding
|
Stumble key.Binding
|
||||||
|
Theme key.Binding
|
||||||
}
|
}
|
||||||
|
|
||||||
var keys = keyMap{
|
var keys = keyMap{
|
||||||
@@ -68,4 +69,5 @@ var keys = keyMap{
|
|||||||
Tab: key.NewBinding(key.WithKeys("tab"), key.WithHelp("tab", "focus cycle")),
|
Tab: key.NewBinding(key.WithKeys("tab"), key.WithHelp("tab", "focus cycle")),
|
||||||
ToggleRail: key.NewBinding(key.WithKeys("ctrl+b"), key.WithHelp("ctrl+b", "toggle tag rail")),
|
ToggleRail: key.NewBinding(key.WithKeys("ctrl+b"), key.WithHelp("ctrl+b", "toggle tag rail")),
|
||||||
Stumble: key.NewBinding(key.WithKeys("S"), key.WithHelp("S", "stumble")),
|
Stumble: key.NewBinding(key.WithKeys("S"), key.WithHelp("S", "stumble")),
|
||||||
|
Theme: key.NewBinding(key.WithKeys("T"), key.WithHelp("T", "theme")),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ type model struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newModel(store *db.Store) model {
|
func newModel(store *db.Store) model {
|
||||||
|
loadTheme()
|
||||||
|
applyTheme()
|
||||||
inp := newInputModel()
|
inp := newInputModel()
|
||||||
inp.ti.Focus()
|
inp.ti.Focus()
|
||||||
return model{
|
return model{
|
||||||
@@ -565,6 +567,10 @@ func (m model) updateBrowse(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
|
|
||||||
|
case "T":
|
||||||
|
t := cycleTheme()
|
||||||
|
return m, m.setStatus("theme: " + t.Name)
|
||||||
|
|
||||||
case "i":
|
case "i":
|
||||||
if m.mode == modeCards && m.state == stateList {
|
if m.mode == modeCards && m.state == stateList {
|
||||||
m.cards.setIntent(m.cards.intent.next())
|
m.cards.setIntent(m.cards.intent.next())
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func (s stumbleModel) view() string {
|
|||||||
bodyWidth = 20
|
bodyWidth = 20
|
||||||
}
|
}
|
||||||
r, _ := glamour.NewTermRenderer(
|
r, _ := glamour.NewTermRenderer(
|
||||||
glamour.WithStylePath("dark"),
|
glamour.WithStylePath(glamourStyle()),
|
||||||
glamour.WithWordWrap(bodyWidth),
|
glamour.WithWordWrap(bodyWidth),
|
||||||
)
|
)
|
||||||
rendered, err := r.Render(e.Body)
|
rendered, err := r.Render(e.Body)
|
||||||
|
|||||||
+93
-143
@@ -3,147 +3,97 @@ package tui
|
|||||||
import "github.com/charmbracelet/lipgloss"
|
import "github.com/charmbracelet/lipgloss"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
subtle = lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#383838"}
|
titleStyle lipgloss.Style
|
||||||
highlight = lipgloss.AdaptiveColor{Light: "#874BFD", Dark: "#7D56F4"}
|
statusStyle lipgloss.Style
|
||||||
dim = lipgloss.AdaptiveColor{Light: "#A49FA5", Dark: "#777777"}
|
listItemStyle lipgloss.Style
|
||||||
|
selectedItemStyle lipgloss.Style
|
||||||
titleStyle = lipgloss.NewStyle().
|
glyphStyle lipgloss.Style
|
||||||
Bold(true).
|
completedGlyphStyle lipgloss.Style
|
||||||
Foreground(highlight).
|
tagStyle lipgloss.Style
|
||||||
PaddingLeft(1)
|
idStyle lipgloss.Style
|
||||||
|
inputPromptStyle lipgloss.Style
|
||||||
statusStyle = lipgloss.NewStyle().
|
detailHeaderStyle lipgloss.Style
|
||||||
Foreground(dim).
|
detailBodyStyle lipgloss.Style
|
||||||
PaddingLeft(1)
|
helpStyle lipgloss.Style
|
||||||
|
errorStyle lipgloss.Style
|
||||||
listItemStyle = lipgloss.NewStyle().
|
dateHeaderStyle lipgloss.Style
|
||||||
PaddingLeft(4)
|
pinnedStyle lipgloss.Style
|
||||||
|
filterPillStyle lipgloss.Style
|
||||||
selectedItemStyle = lipgloss.NewStyle().
|
helpKeyStyle lipgloss.Style
|
||||||
PaddingLeft(1).
|
helpDescStyle lipgloss.Style
|
||||||
Bold(true).
|
affordanceStyle lipgloss.Style
|
||||||
Foreground(highlight).
|
useCountStyle lipgloss.Style
|
||||||
SetString("›")
|
modeStyle lipgloss.Style
|
||||||
|
detailLabelStyle lipgloss.Style
|
||||||
glyphStyle = lipgloss.NewStyle().
|
detailValueStyle lipgloss.Style
|
||||||
Width(2)
|
checkDoneStyle lipgloss.Style
|
||||||
|
checkPendingStyle lipgloss.Style
|
||||||
completedGlyphStyle = lipgloss.NewStyle().
|
searchPillStyle lipgloss.Style
|
||||||
Width(2).
|
gutterStyle lipgloss.Style
|
||||||
Foreground(dim)
|
drawerBorderStyle lipgloss.Style
|
||||||
|
drawerHintsStyle lipgloss.Style
|
||||||
tagStyle = lipgloss.NewStyle().
|
drawerPreviewStyle lipgloss.Style
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"})
|
separatorStyle lipgloss.Style
|
||||||
|
hintKeyStyle lipgloss.Style
|
||||||
idStyle = lipgloss.NewStyle().
|
hintDescStyle lipgloss.Style
|
||||||
Foreground(dim)
|
railHeaderStyle lipgloss.Style
|
||||||
|
railTagStyle lipgloss.Style
|
||||||
inputPromptStyle = lipgloss.NewStyle().
|
railActiveTagStyle lipgloss.Style
|
||||||
Foreground(highlight).
|
railCountStyle lipgloss.Style
|
||||||
Bold(true)
|
stumbleAgeStyle lipgloss.Style
|
||||||
|
|
||||||
detailHeaderStyle = lipgloss.NewStyle().
|
|
||||||
Bold(true).
|
|
||||||
Foreground(highlight).
|
|
||||||
MarginBottom(1)
|
|
||||||
|
|
||||||
detailBodyStyle = lipgloss.NewStyle().
|
|
||||||
PaddingLeft(2).
|
|
||||||
PaddingTop(1)
|
|
||||||
|
|
||||||
helpStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim).
|
|
||||||
PaddingLeft(1)
|
|
||||||
|
|
||||||
errorStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.Color("#FF0000")).
|
|
||||||
PaddingLeft(1)
|
|
||||||
|
|
||||||
dateHeaderStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim).
|
|
||||||
PaddingLeft(1)
|
|
||||||
|
|
||||||
pinnedStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#D4A017", Dark: "#FFD700"})
|
|
||||||
|
|
||||||
filterPillStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"}).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
helpKeyStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(highlight).
|
|
||||||
Bold(true).
|
|
||||||
Width(18)
|
|
||||||
|
|
||||||
helpDescStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
affordanceStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#5B8EF0", Dark: "#7AAFFF"}).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
useCountStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#B07D3A", Dark: "#D4A54A"})
|
|
||||||
|
|
||||||
modeStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
detailLabelStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(highlight).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
detailValueStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#555555", Dark: "#BBBBBB"})
|
|
||||||
|
|
||||||
checkDoneStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"})
|
|
||||||
|
|
||||||
checkPendingStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
searchPillStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#E06C75", Dark: "#E06C75"}).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
gutterStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
drawerBorderStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
drawerHintsStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim).
|
|
||||||
PaddingLeft(2)
|
|
||||||
|
|
||||||
drawerPreviewStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#555555", Dark: "#AAAAAA"}).
|
|
||||||
PaddingLeft(2)
|
|
||||||
|
|
||||||
separatorStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
hintKeyStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(highlight).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
hintDescStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
railHeaderStyle = lipgloss.NewStyle().
|
|
||||||
Bold(true).
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
railTagStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"})
|
|
||||||
|
|
||||||
railActiveTagStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"}).
|
|
||||||
Bold(true)
|
|
||||||
|
|
||||||
railCountStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(dim)
|
|
||||||
|
|
||||||
stumbleAgeStyle = lipgloss.NewStyle().
|
|
||||||
Foreground(lipgloss.AdaptiveColor{Light: "#cc4400", Dark: "#fab387"})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
applyTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyTheme() {
|
||||||
|
t := activeTheme()
|
||||||
|
accent := lipgloss.Color(t.Accent)
|
||||||
|
dim := lipgloss.Color(t.Dim)
|
||||||
|
muted := lipgloss.Color(t.Muted)
|
||||||
|
ok := lipgloss.Color(t.Ok)
|
||||||
|
todo := lipgloss.Color(t.Todo)
|
||||||
|
event := lipgloss.Color(t.Event)
|
||||||
|
remind := lipgloss.Color(t.Remind)
|
||||||
|
danger := lipgloss.Color(t.Danger)
|
||||||
|
|
||||||
|
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(accent).PaddingLeft(1)
|
||||||
|
statusStyle = lipgloss.NewStyle().Foreground(dim).PaddingLeft(1)
|
||||||
|
listItemStyle = lipgloss.NewStyle().PaddingLeft(4)
|
||||||
|
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(1).Bold(true).Foreground(accent).SetString("›")
|
||||||
|
glyphStyle = lipgloss.NewStyle().Width(2)
|
||||||
|
completedGlyphStyle = lipgloss.NewStyle().Width(2).Foreground(dim)
|
||||||
|
tagStyle = lipgloss.NewStyle().Foreground(ok)
|
||||||
|
idStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
inputPromptStyle = lipgloss.NewStyle().Foreground(accent).Bold(true)
|
||||||
|
detailHeaderStyle = lipgloss.NewStyle().Bold(true).Foreground(accent).MarginBottom(1)
|
||||||
|
detailBodyStyle = lipgloss.NewStyle().PaddingLeft(2).PaddingTop(1)
|
||||||
|
helpStyle = lipgloss.NewStyle().Foreground(dim).PaddingLeft(1)
|
||||||
|
errorStyle = lipgloss.NewStyle().Foreground(danger).PaddingLeft(1)
|
||||||
|
dateHeaderStyle = lipgloss.NewStyle().Foreground(dim).PaddingLeft(1)
|
||||||
|
pinnedStyle = lipgloss.NewStyle().Foreground(todo)
|
||||||
|
filterPillStyle = lipgloss.NewStyle().Foreground(ok).Bold(true)
|
||||||
|
helpKeyStyle = lipgloss.NewStyle().Foreground(accent).Bold(true).Width(18)
|
||||||
|
helpDescStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
affordanceStyle = lipgloss.NewStyle().Foreground(event).Bold(true)
|
||||||
|
useCountStyle = lipgloss.NewStyle().Foreground(remind)
|
||||||
|
modeStyle = lipgloss.NewStyle().Foreground(dim).Bold(true)
|
||||||
|
detailLabelStyle = lipgloss.NewStyle().Foreground(accent).Bold(true)
|
||||||
|
detailValueStyle = lipgloss.NewStyle().Foreground(muted)
|
||||||
|
checkDoneStyle = lipgloss.NewStyle().Foreground(ok)
|
||||||
|
checkPendingStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
searchPillStyle = lipgloss.NewStyle().Foreground(danger).Bold(true)
|
||||||
|
gutterStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
drawerBorderStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
drawerHintsStyle = lipgloss.NewStyle().Foreground(dim).PaddingLeft(2)
|
||||||
|
drawerPreviewStyle = lipgloss.NewStyle().Foreground(muted).PaddingLeft(2)
|
||||||
|
separatorStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
hintKeyStyle = lipgloss.NewStyle().Foreground(accent).Bold(true)
|
||||||
|
hintDescStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
railHeaderStyle = lipgloss.NewStyle().Bold(true).Foreground(dim)
|
||||||
|
railTagStyle = lipgloss.NewStyle().Foreground(ok)
|
||||||
|
railActiveTagStyle = lipgloss.NewStyle().Foreground(ok).Bold(true)
|
||||||
|
railCountStyle = lipgloss.NewStyle().Foreground(dim)
|
||||||
|
stumbleAgeStyle = lipgloss.NewStyle().Foreground(remind)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
"github.com/lerko/nib/internal/db"
|
"github.com/lerko/nib/internal/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ func (r tagRailModel) view(focused bool) string {
|
|||||||
|
|
||||||
headerStyle := railHeaderStyle
|
headerStyle := railHeaderStyle
|
||||||
if focused {
|
if focused {
|
||||||
headerStyle = headerStyle.Foreground(highlight)
|
headerStyle = headerStyle.Foreground(lipgloss.Color(activeTheme().Accent))
|
||||||
}
|
}
|
||||||
b.WriteString(headerStyle.Render("tags"))
|
b.WriteString(headerStyle.Render("tags"))
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package tui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Theme struct {
|
||||||
|
Name string
|
||||||
|
Dark bool
|
||||||
|
Accent string
|
||||||
|
Dim string
|
||||||
|
Muted string
|
||||||
|
Ok string
|
||||||
|
Todo string
|
||||||
|
Event string
|
||||||
|
Remind string
|
||||||
|
Danger string
|
||||||
|
}
|
||||||
|
|
||||||
|
var themes = []Theme{
|
||||||
|
{Name: "dark", Dark: true, Accent: "#c8942a", Dim: "#504840", Muted: "#8c8070", Ok: "#7aab72", Todo: "#d4a84b", Event: "#6898c8", Remind: "#c8784a", Danger: "#b85858"},
|
||||||
|
{Name: "tinycard", Dark: true, Accent: "#ad8ee6", Dim: "#555a6a", Muted: "#8b90a0", Ok: "#4ade80", Todo: "#fbbf24", Event: "#22d3ee", Remind: "#e8845a", Danger: "#ef4444"},
|
||||||
|
{Name: "catppuccin", Dark: true, Accent: "#cba6f7", Dim: "#6c7086", Muted: "#a6adc8", Ok: "#a6e3a1", Todo: "#f9e2af", Event: "#89b4fa", Remind: "#fab387", Danger: "#f38ba8"},
|
||||||
|
{Name: "nord", Dark: true, Accent: "#88c0d0", Dim: "#4c566a", Muted: "#d8dee9", Ok: "#a3be8c", Todo: "#ebcb8b", Event: "#81a1c1", Remind: "#d08770", Danger: "#bf616a"},
|
||||||
|
{Name: "dracula", Dark: true, Accent: "#bd93f9", Dim: "#6272a4", Muted: "#bfbfbf", Ok: "#50fa7b", Todo: "#f1fa8c", Event: "#8be9fd", Remind: "#ffb86c", Danger: "#ff5555"},
|
||||||
|
{Name: "gruvbox", Dark: true, Accent: "#fabd2f", Dim: "#665c54", Muted: "#a89984", Ok: "#b8bb26", Todo: "#fabd2f", Event: "#83a598", Remind: "#fe8019", Danger: "#fb4934"},
|
||||||
|
{Name: "rosepine", Dark: true, Accent: "#c4a7e7", Dim: "#6e6a86", Muted: "#908caa", Ok: "#a6da95", Todo: "#f6c177", Event: "#31748f", Remind: "#ea9a97", Danger: "#eb6f92"},
|
||||||
|
{Name: "tokyonight", Dark: true, Accent: "#7aa2f7", Dim: "#565f89", Muted: "#a9b1d6", Ok: "#9ece6a", Todo: "#e0af68", Event: "#7aa2f7", Remind: "#ff9e64", Danger: "#f7768e"},
|
||||||
|
{Name: "solarized", Dark: true, Accent: "#268bd2", Dim: "#586e75", Muted: "#657b83", Ok: "#859900", Todo: "#b58900", Event: "#268bd2", Remind: "#cb4b16", Danger: "#dc322f"},
|
||||||
|
{Name: "paper", Dark: false, Accent: "#8a6018", Dim: "#a09080", Muted: "#6a5e50", Ok: "#2a6828", Todo: "#7a5c00", Event: "#245890", Remind: "#984020", Danger: "#882030"},
|
||||||
|
{Name: "catppuccin-latte", Dark: false, Accent: "#8839ef", Dim: "#9ca0b0", Muted: "#6c6f85", Ok: "#40a02b", Todo: "#df8e1d", Event: "#1e66f5", Remind: "#fe640b", Danger: "#d20f39"},
|
||||||
|
{Name: "rosepine-dawn", Dark: false, Accent: "#907aa9", Dim: "#9893a5", Muted: "#797593", Ok: "#56949f", Todo: "#ea9d34", Event: "#286983", Remind: "#d7827e", Danger: "#b4637a"},
|
||||||
|
{Name: "solarized-light", Dark: false, Accent: "#268bd2", Dim: "#93a1a1", Muted: "#586e75", Ok: "#859900", Todo: "#b58900", Event: "#268bd2", Remind: "#cb4b16", Danger: "#dc322f"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeThemeIndex int
|
||||||
|
|
||||||
|
func activeTheme() Theme {
|
||||||
|
return themes[activeThemeIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
func cycleTheme() Theme {
|
||||||
|
activeThemeIndex = (activeThemeIndex + 1) % len(themes)
|
||||||
|
applyTheme()
|
||||||
|
saveTheme()
|
||||||
|
return themes[activeThemeIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
func glamourStyle() string {
|
||||||
|
if themes[activeThemeIndex].Dark {
|
||||||
|
return "dark"
|
||||||
|
}
|
||||||
|
return "light"
|
||||||
|
}
|
||||||
|
|
||||||
|
func themePath() string {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return filepath.Join(home, ".nib", "theme")
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadTheme() {
|
||||||
|
p := themePath()
|
||||||
|
if p == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(p)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
name := strings.TrimSpace(string(data))
|
||||||
|
for i, t := range themes {
|
||||||
|
if t.Name == name {
|
||||||
|
activeThemeIndex = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveTheme() {
|
||||||
|
p := themePath()
|
||||||
|
if p == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = os.WriteFile(p, []byte(themes[activeThemeIndex].Name+"\n"), 0o644)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user