1
0
mirror of https://github.com/mrusme/neonmodem.git synced 2024-06-16 06:25:23 +00:00

Implemented Theme, refactored UI style

This commit is contained in:
マリウス 2022-12-31 16:57:11 -05:00
parent 61ed9fde70
commit 54e8f53b77
No known key found for this signature in database
GPG Key ID: 272ED814BF63261F
6 changed files with 244 additions and 80 deletions

View File

@ -5,6 +5,7 @@ import (
"path"
"strings"
"github.com/charmbracelet/lipgloss"
"github.com/pelletier/go-toml/v2"
"github.com/spf13/viper"
)
@ -24,11 +25,46 @@ type SystemConfig struct {
Config map[string]interface{}
}
type ThemeItemConfig struct {
Foreground lipgloss.AdaptiveColor
Background lipgloss.AdaptiveColor
Border struct {
Foreground lipgloss.AdaptiveColor
Background lipgloss.AdaptiveColor
Border lipgloss.Border
Sides []bool
}
Padding []int
Margin []int
}
type Config struct {
Debug bool
Log string
Systems []SystemConfig
Theme struct {
DialogBox struct {
Window ThemeItemConfig
Titlebar ThemeItemConfig
Bottombar ThemeItemConfig
}
PostsList struct {
List ThemeItemConfig
Item ThemeItemConfig
}
Post struct {
Author ThemeItemConfig
Subject ThemeItemConfig
}
Reply struct {
Author ThemeItemConfig
}
}
}
func Load() (Config, error) {
@ -48,6 +84,72 @@ func Load() (Config, error) {
viper.SetDefault("Debug", "true")
viper.SetDefault("Log", path.Join(cacheDir, "gobbs.log"))
// PostsList List
viper.SetDefault("Theme.PostsList.List.Margin",
[]int{0, 0, 0, 0})
viper.SetDefault("Theme.PostsList.List.Padding",
[]int{1, 1, 1, 1})
viper.SetDefault("Theme.PostsList.List.Border.Border",
lipgloss.RoundedBorder())
viper.SetDefault("Theme.PostsList.List.Border.Sides",
[]bool{true, true, true, true},
)
viper.SetDefault("Theme.PostsList.List.Border.Foreground",
lipgloss.AdaptiveColor{Light: "#333333", Dark: "#cccccc"})
// DialogBox Window
viper.SetDefault("Theme.DialogBox.Window.Margin",
[]int{0, 0, 0, 0})
viper.SetDefault("Theme.DialogBox.Window.Padding",
[]int{0, 0, 0, 0})
viper.SetDefault("Theme.DialogBox.Window.Border.Border",
lipgloss.ThickBorder())
viper.SetDefault("Theme.DialogBox.Window.Border.Sides",
[]bool{false, true, true, true},
)
viper.SetDefault("Theme.DialogBox.Window.Border.Foreground",
lipgloss.AdaptiveColor{Light: "#333333", Dark: "#cccccc"})
// DialogBox Titlebar
viper.SetDefault("Theme.DialogBox.Titlebar.Margin",
[]int{0, 0, 1, 0})
viper.SetDefault("Theme.DialogBox.Titlebar.Padding",
[]int{0, 1, 0, 1})
viper.SetDefault("Theme.DialogBox.Titlebar.Foreground",
lipgloss.AdaptiveColor{Light: "#ffffff", Dark: "#000000"})
viper.SetDefault("Theme.DialogBox.Titlebar.Background",
lipgloss.AdaptiveColor{Light: "#333333", Dark: "#cccccc"})
// DialogBox Bottombar
viper.SetDefault("Theme.DialogBox.Bottombar.Margin",
[]int{1, 0, 0, 0})
viper.SetDefault("Theme.DialogBox.Bottombar.Padding",
[]int{0, 1, 0, 1})
viper.SetDefault("Theme.DialogBox.Bottombar.Foreground",
lipgloss.AdaptiveColor{Light: "#aaaaaa", Dark: "#999999"})
// Post Author
viper.SetDefault("Theme.Post.Author.Padding",
[]int{0, 1, 0, 1})
viper.SetDefault("Theme.Post.Author.Foreground",
lipgloss.AdaptiveColor{Light: "#F25D94", Dark: "#F25D94"})
// Post Subject
viper.SetDefault("Theme.Post.Subject.Padding",
[]int{0, 1, 0, 1})
viper.SetDefault("Theme.Post.Subject.Foreground",
lipgloss.AdaptiveColor{Light: "#FFFFFF", Dark: "#FFFFFF"})
viper.SetDefault("Theme.Post.Subject.Background",
lipgloss.AdaptiveColor{Light: "#F25D94", Dark: "#F25D94"})
// Reply Author
viper.SetDefault("Theme.Reply.Author.Padding",
[]int{0, 1, 0, 1})
viper.SetDefault("Theme.Reply.Author.Foreground",
lipgloss.AdaptiveColor{Light: "#000000", Dark: "#00000"})
viper.SetDefault("Theme.Reply.Author.Foreground",
lipgloss.AdaptiveColor{Light: "#874BFD", Dark: "#874BFD"})
viper.SetConfigName("gobbs")
viper.SetConfigType("toml")
viper.AddConfigPath(cfgDir)

View File

@ -41,10 +41,9 @@ func (post Post) Title() string {
func (post Post) Description() string {
return fmt.Sprintf(
"[%s] %s in %s on %s",
post.ID,
post.Author.Name,
"in %s by %s on %s",
post.Forum.Name,
post.CreatedAt.Format("Jan 2 2006"),
post.Author.Name,
post.CreatedAt.Format("02 Jan 06 15:04 MST"),
)
}

View File

@ -3,6 +3,7 @@ package ctx
import (
"github.com/mrusme/gobbs/config"
"github.com/mrusme/gobbs/system"
"github.com/mrusme/gobbs/ui/theme"
"go.uber.org/zap"
)
@ -13,6 +14,7 @@ type Ctx struct {
Systems []*system.System
Loading bool
Logger *zap.SugaredLogger
Theme *theme.Theme
}
func New(
@ -25,6 +27,7 @@ func New(
Config: cfg,
Loading: false,
Logger: logger,
Theme: theme.New(cfg),
}
}

114
ui/theme/theme.go Normal file
View File

@ -0,0 +1,114 @@
package theme
import (
"github.com/charmbracelet/lipgloss"
"github.com/mrusme/gobbs/config"
)
type Theme struct {
DialogBox struct {
Window lipgloss.Style
Titlebar lipgloss.Style
Bottombar lipgloss.Style
}
PostsList struct {
List lipgloss.Style
Item lipgloss.Style
}
Post struct {
Author lipgloss.Style
Subject lipgloss.Style
}
Reply struct {
Author lipgloss.Style
}
}
func New(cfg *config.Config) (*Theme) {
t := new(Theme)
// viewportStyle = lipgloss.NewStyle().
// Margin(0, 0, 0, 0).
// Padding(0, 0).
// BorderTop(false).
// BorderLeft(false).
// BorderRight(false).
// BorderBottom(false)
//
t.PostsList.List = lipgloss.NewStyle().
Margin(cfg.Theme.PostsList.List.Margin...).
Padding(cfg.Theme.PostsList.List.Padding...).
Border(cfg.Theme.PostsList.List.Border.Border, cfg.Theme.PostsList.List.Border.Sides...).
BorderForeground(cfg.Theme.PostsList.List.Border.Foreground).
BorderBackground(cfg.Theme.PostsList.List.Border.Background).
Foreground(cfg.Theme.PostsList.List.Foreground).
Background(cfg.Theme.PostsList.List.Background)
t.PostsList.Item = lipgloss.NewStyle().
Margin(cfg.Theme.PostsList.Item.Margin...).
Padding(cfg.Theme.PostsList.Item.Padding...).
Border(cfg.Theme.PostsList.Item.Border.Border, cfg.Theme.PostsList.Item.Border.Sides...).
BorderForeground(cfg.Theme.PostsList.Item.Border.Foreground).
BorderBackground(cfg.Theme.PostsList.Item.Border.Background).
Foreground(cfg.Theme.PostsList.Item.Foreground).
Background(cfg.Theme.PostsList.Item.Background)
t.DialogBox.Window = lipgloss.NewStyle().
Margin(cfg.Theme.DialogBox.Window.Margin...).
Padding(cfg.Theme.DialogBox.Window.Padding...).
Border(cfg.Theme.DialogBox.Window.Border.Border, cfg.Theme.DialogBox.Window.Border.Sides...).
BorderForeground(cfg.Theme.DialogBox.Window.Border.Foreground).
BorderBackground(cfg.Theme.DialogBox.Window.Border.Background).
Foreground(cfg.Theme.DialogBox.Window.Foreground).
Background(cfg.Theme.DialogBox.Window.Background)
t.DialogBox.Titlebar = lipgloss.NewStyle().
Margin(cfg.Theme.DialogBox.Titlebar.Margin...).
Padding(cfg.Theme.DialogBox.Titlebar.Padding...).
Border(cfg.Theme.DialogBox.Titlebar.Border.Border, cfg.Theme.DialogBox.Titlebar.Border.Sides...).
BorderForeground(cfg.Theme.DialogBox.Titlebar.Border.Foreground).
BorderBackground(cfg.Theme.DialogBox.Titlebar.Border.Background).
Foreground(cfg.Theme.DialogBox.Titlebar.Foreground).
Background(cfg.Theme.DialogBox.Titlebar.Background)
t.DialogBox.Bottombar = lipgloss.NewStyle().
Margin(cfg.Theme.DialogBox.Bottombar.Margin...).
Padding(cfg.Theme.DialogBox.Bottombar.Padding...).
Border(cfg.Theme.DialogBox.Bottombar.Border.Border, cfg.Theme.DialogBox.Bottombar.Border.Sides...).
BorderForeground(cfg.Theme.DialogBox.Bottombar.Border.Foreground).
BorderBackground(cfg.Theme.DialogBox.Bottombar.Border.Background).
Foreground(cfg.Theme.DialogBox.Bottombar.Foreground).
Background(cfg.Theme.DialogBox.Bottombar.Background)
t.Post.Author = lipgloss.NewStyle().
Margin(cfg.Theme.Post.Author.Margin...).
Padding(cfg.Theme.Post.Author.Padding...).
Border(cfg.Theme.Post.Author.Border.Border, cfg.Theme.Post.Author.Border.Sides...).
BorderForeground(cfg.Theme.Post.Author.Border.Foreground).
BorderBackground(cfg.Theme.Post.Author.Border.Background).
Foreground(cfg.Theme.Post.Author.Foreground).
Background(cfg.Theme.Post.Author.Background)
t.Post.Subject = lipgloss.NewStyle().
Margin(cfg.Theme.Post.Subject.Margin...).
Padding(cfg.Theme.Post.Subject.Padding...).
Border(cfg.Theme.Post.Subject.Border.Border, cfg.Theme.Post.Subject.Border.Sides...).
BorderForeground(cfg.Theme.Post.Subject.Border.Foreground).
BorderBackground(cfg.Theme.Post.Subject.Border.Background).
Foreground(cfg.Theme.Post.Subject.Foreground).
Background(cfg.Theme.Post.Subject.Background)
t.Reply.Author = lipgloss.NewStyle().
Margin(cfg.Theme.Reply.Author.Margin...).
Padding(cfg.Theme.Reply.Author.Padding...).
Border(cfg.Theme.Reply.Author.Border.Border, cfg.Theme.Reply.Author.Border.Sides...).
BorderForeground(cfg.Theme.Reply.Author.Border.Foreground).
BorderBackground(cfg.Theme.Reply.Author.Border.Background).
Foreground(cfg.Theme.Reply.Author.Foreground).
Background(cfg.Theme.Reply.Author.Background)
return t
}

View File

@ -18,71 +18,13 @@ import (
)
var (
ViewBorderColor = lipgloss.AdaptiveColor{
Light: "#b0c4de",
Dark: "#b0c4de",
}
DialogBorderColor = lipgloss.AdaptiveColor{
Light: "#b0c4de",
Dark: "#b0c4de",
}
)
var (
listStyle = lipgloss.NewStyle().
Margin(0, 0, 0, 0).
Padding(1, 1).
Border(lipgloss.DoubleBorder()).
BorderForeground(ViewBorderColor).
BorderTop(true).
BorderLeft(true).
BorderRight(true).
BorderBottom(true)
viewportStyle = lipgloss.NewStyle().
Margin(0, 0, 0, 0).
Padding(0, 0).
BorderTop(false).
BorderLeft(false).
BorderRight(false).
BorderBottom(false)
dialogBoxStyle = lipgloss.NewStyle().
Border(lipgloss.ThickBorder()).
BorderForeground(DialogBorderColor).
Padding(0, 0).
Margin(0, 0, 0, 0).
BorderTop(false).
BorderLeft(true).
BorderRight(true).
BorderBottom(true)
dialogBoxTitlebarStyle = lipgloss.NewStyle().
Align(lipgloss.Center).
Background(lipgloss.Color("#87cefa")).
Foreground(lipgloss.Color("#000000")).
Padding(0, 1).
Margin(0, 0, 1, 0)
dialogBoxBottombarStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#999999")).
Padding(0, 1).
Margin(1, 0, 0, 0)
postAuthorStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#F25D94")).
Padding(0, 1)
postSubjectStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#FFFFFF")).
Background(lipgloss.Color("#F25D94")).
Padding(0, 1)
replyAuthorStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("#000000")).
Background(lipgloss.Color("#874BFD")).
Padding(0, 1)
Margin(0, 0, 0, 0).
Padding(0, 0).
BorderTop(false).
BorderLeft(false).
BorderRight(false).
BorderBottom(false)
)
type KeyMap struct {
@ -130,7 +72,8 @@ func NewModel(c *ctx.Ctx) Model {
}
m.list = list.New(m.items, list.NewDefaultDelegate(), 0, 0)
m.list.Title = "Posts"
m.list.SetShowTitle(false)
m.list.SetShowStatusBar(false)
m.ctx = c
m.a, _ = aggregator.New(m.ctx)
@ -167,8 +110,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
viewportWidth := m.ctx.Content[0] - 9
viewportHeight := m.ctx.Content[1] - 10
listStyle.Width(listWidth)
listStyle.Height(listHeight)
m.ctx.Theme.PostsList.List.Width(listWidth)
m.ctx.Theme.PostsList.List.Height(listHeight)
m.list.SetSize(
listWidth-2,
listHeight-2,
@ -196,12 +139,12 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
if m.viewportOpen == false {
// listStyle.BorderForeground(lipgloss.Color("#FFFFFF"))
// m.ctx.Theme.PostsList.List.BorderForeground(lipgloss.Color("#FFFFFF"))
// viewportStyle.BorderForeground(lipgloss.Color("#874BFD"))
m.list, cmd = m.list.Update(msg)
cmds = append(cmds, cmd)
} else if m.viewportOpen == true {
// listStyle.BorderForeground(lipgloss.Color("#874BFD"))
// m.ctx.Theme.PostsList.List.BorderForeground(lipgloss.Color("#874BFD"))
// viewportStyle.BorderForeground(lipgloss.Color("#FFFFFF"))
m.viewport, cmd = m.viewport.Update(msg)
cmds = append(cmds, cmd)
@ -215,15 +158,16 @@ func (m Model) View() string {
view.WriteString(lipgloss.JoinHorizontal(
lipgloss.Top,
listStyle.Render(m.list.View()),
m.ctx.Theme.PostsList.List.Render(m.list.View()),
))
if m.viewportOpen {
titlebar := dialogBoxTitlebarStyle.
titlebar := m.ctx.Theme.DialogBox.Titlebar.
Align(lipgloss.Center).
Width(m.viewport.Width + 4).
Render("Post")
bottombar := dialogBoxBottombarStyle.
bottombar := m.ctx.Theme.DialogBox.Bottombar.
Width(m.viewport.Width + 4).
Render("r reply · esc close")
@ -234,7 +178,9 @@ func (m Model) View() string {
bottombar,
)
return helpers.PlaceOverlay(3, 2, dialogBoxStyle.Render(ui), view.String(), true)
return helpers.PlaceOverlay(3, 2,
m.ctx.Theme.DialogBox.Window.Render(ui),
view.String(), true)
}
return view.String()
@ -288,10 +234,10 @@ func (m *Model) renderViewport(p *post.Post) string {
}
out += fmt.Sprintf(
" %s\n %s\n%s",
postAuthorStyle.Render(
m.ctx.Theme.Post.Author.Render(
fmt.Sprintf("%s %s:", p.Author.Name, adj),
),
postSubjectStyle.Render(p.Subject),
m.ctx.Theme.Post.Subject.Render(p.Subject),
body,
)
@ -331,7 +277,7 @@ func (m *Model) renderReplies(
}
out += fmt.Sprintf(
"\n\n %s %s\n%s",
replyAuthorStyle.Render(
m.ctx.Theme.Reply.Author.Render(
author,
),
lipgloss.NewStyle().Foreground(lipgloss.Color("#874BFD")).Render(