Skip to content

Commit

Permalink
feat(#93): add support for color scheme configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
mk-5 committed Jan 15, 2024
1 parent 962690d commit fc7de56
Show file tree
Hide file tree
Showing 16 changed files with 391 additions and 136 deletions.
53 changes: 53 additions & 0 deletions assets/colors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
default:
background: "#161616"
foreground: "#c7c7c7"
foreground2: "#FFFFFF"

finder:
cursor: "#8B0000"
title: "#E9CE58"
match: "#90EE90"
highlight:
background: "#3A3A3A"
foreground: "#FFFFFF"
match: "#E0FFFF"

navigation:
top:
background: "#5F875f"
foreground1: "#FFFFFF"
foreground2: "#151515"
bottom:
background: "#5F87AF"
foreground1: "#FFFFFF"
foreground2: "#151515"

details:
foreground: "#696969"

boards:
title:
foreground: "#ecce58"
headers:
background: "#5F87AF"
foreground: "#FFFFFF"
column:
background: "#232323"
foreground: "#ffffff"
highlight:
background: "#484848"
foreground: "#ffffff"
selection:
background: "#8B0000"
foreground: "#ffffff"

spinner:
accent: "#FF0000"

alerts:
success:
background: "#F5F5F5"
foreground: "#006400"
error:
background: "#F5F5F5"
foreground: "#8B0000"
4 changes: 3 additions & 1 deletion internal/app/action_bar.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type ActionBar struct {
items []ActionBarItem
vAlign int
hAlign int
style tcell.Style
}

const (
Expand All @@ -37,6 +38,7 @@ func NewActionBar(vAlign int, hAlign int) *ActionBar {
vAlign: vAlign,
hAlign: hAlign,
items: make([]ActionBarItem, 0, ActionBarMaxItems),
style: DefaultStyle(),
}
}

Expand Down Expand Up @@ -104,7 +106,7 @@ func (b *ActionBar) Draw(screen tcell.Screen) {
for _, item := range b.items {
DrawText(screen, item.x, item.y, item.Text1Style, item.Text1)
DrawText(screen, item.x+len(item.Text1), item.y, item.Text2Style, item.Text2)
DrawText(screen, item.x+len(item.Text1)+len(item.Text2), item.y, DefaultStyle, " ")
DrawText(screen, item.x+len(item.Text1)+len(item.Text2), item.y, b.style, " ")
}
}

Expand Down
21 changes: 13 additions & 8 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type App struct {
runOnAppRoutine []func()
spinner *SpinnerTCell
view View
style tcell.Style
}

const (
Expand All @@ -44,10 +45,8 @@ const (
)

var (
AppBackground = tcell.NewRGBColor(22, 22, 22)
DefaultStyle = tcell.StyleDefault.Background(AppBackground).Foreground(tcell.NewRGBColor(199, 199, 199))
appInstance *App
once sync.Once
appInstance *App
once sync.Once
)

func CreateNewApp() *App {
Expand All @@ -68,6 +67,10 @@ func GetApp() *App {
return appInstance
}

func DefaultStyle() tcell.Style {
return tcell.StyleDefault.Background(Color("default.background")).Foreground(Color("default.foreground"))
}

func initApp() {
screen, err := tcell.NewScreen()
if err != nil {
Expand All @@ -82,10 +85,11 @@ func initAppWithScreen(screen tcell.Screen) {
}
encoding.Register()
tcell.SetEncodingFallback(tcell.EncodingFallbackUTF8)
MustLoadColorScheme()
if err := screen.Init(); err != nil {
log.Fatalf("%+v", err)
}
screen.SetStyle(DefaultStyle)
screen.SetStyle(DefaultStyle())
screen.EnableMouse()
screen.EnablePaste()
screen.Clear()
Expand All @@ -105,6 +109,7 @@ func initAppWithScreen(screen tcell.Screen) {
keepAlive: make(map[interface{}]bool),
dirty: true,
spinner: s,
style: DefaultStyle(),
}
}

Expand Down Expand Up @@ -144,7 +149,7 @@ func (a *App) Render() {
time.Sleep(FPSMilliseconds)
return
}
a.screen.Fill(' ', DefaultStyle)
a.screen.Fill(' ', a.style)
if a.loading {
a.spinner.Draw(a.screen)
}
Expand All @@ -163,7 +168,7 @@ func (a *App) Close() {
}
a.closed = true
a.screen.DisableMouse()
a.screen.Fill(' ', DefaultStyle)
a.screen.Fill(' ', a.style)
a.screen.Show()
a.screen.Fini()
close(a.keyEvent)
Expand Down Expand Up @@ -309,7 +314,7 @@ func (a *App) ClearNow() {
a.clear()
// a.screen.Clear() is preserving terminal buffer (not alternate screen buffer) :/ different then in 1.3
//a.screen.Clear()
a.screen.Fill(' ', DefaultStyle)
a.screen.Fill(' ', a.style)
a.screen.HideCursor()
}

Expand Down
115 changes: 115 additions & 0 deletions internal/app/colors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package app

import (
"fmt"
"github.com/gdamore/tcell/v2"
"gopkg.in/yaml.v3"
"os"
"strings"
)

var (
schemeMap map[string]interface{}
colorsMap = map[string]tcell.Color{}
)

func Color(c string) tcell.Color {
if color, ok := colorsMap[c]; ok {
return color
}
parts := strings.Split(c, ".")
var t interface{}
var hex string
t = schemeMap
for _, p := range parts {
if m, ok := t.(map[string]interface{}); ok {
t = m[p]
}
if h, ok := t.(string); ok {
hex = h
}
}
color := tcell.GetColor(hex)
colorsMap[c] = color
return color
}

func MustLoadColorScheme() map[string]interface{} {
d, _ := os.UserHomeDir()
p := fmt.Sprintf("%s/.fjira/colors.yml", d)
b, err := os.ReadFile(p)
if err != nil {
schemeMap = parseYMLStr(defaultColorsYML())
return schemeMap
}
schemeMap = parseYMLStr(string(b))
return schemeMap
}

func parseYMLStr(y string) map[string]interface{} {
var yml map[string]interface{}
err := yaml.Unmarshal([]byte(y), &yml)
if err != nil {
Error(err.Error())
return map[string]interface{}{}
}
return yml
}

func defaultColorsYML() string {
return `
default:
background: "#161616"
foreground: "#c7c7c7"
foreground2: "#FFFFFF"
finder:
cursor: "#8B0000"
title: "#E9CE58"
match: "#90EE90"
highlight:
background: "#3A3A3A"
foreground: "#FFFFFF"
match: "#E0FFFF"
navigation:
top:
background: "#5F875f"
foreground1: "#FFFFFF"
foreground2: "#151515"
bottom:
background: "#5F87AF"
foreground1: "#FFFFFF"
foreground2: "#151515"
details:
foreground: "#696969"
boards:
title:
foreground: "#ecce58"
headers:
background: "#5F875f"
foreground: "#FFFFFF"
column:
background: "#232323"
foreground: "#ffffff"
highlight:
background: "#484848"
foreground: "#ffffff"
selection:
background: "#8B0000"
foreground: "#ffffff"
spinner:
accent: "#FF0000"
alerts:
success:
background: "#F5F5F5"
foreground: "#006400"
error:
background: "#F5F5F5"
foreground: "#8B0000"
`
}
62 changes: 62 additions & 0 deletions internal/app/colors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package app

import (
"fmt"
os2 "github.com/mk-5/fjira/internal/os"
"github.com/stretchr/testify/assert"
"os"
"testing"
)

func TestColor(t *testing.T) {
MustLoadColorScheme()

type args struct {
c string
}
tests := []struct {
name string
args args
want int32
}{
{"should get color from default colors", args{c: "navigation.top.background"}, 6260575},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, Color(tt.args.c).Hex(), "Color(%v)", tt.args.c)
})
}
}

func TestMustLoadColorScheme(t *testing.T) {
tests := []struct {
name string
}{
{"should load color scheme from user directory"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// given
f := `
navigation:
top:
background: "#0000FF"
foreground1: "#EEEEEE"
`
tempDir := t.TempDir()
_ = os2.SetUserHomeDir(tempDir)
_ = os.MkdirAll(fmt.Sprintf("%s/.fjira", tempDir), os.ModePerm)
p := fmt.Sprintf("%s/.fjira/colors.yml", tempDir)
err := os.WriteFile(p, []byte(f), 0644)
assert.Nil(t, err)

// when
MustLoadColorScheme()

// then
assert.Equalf(t, int32(255), Color("navigation.top.background").Hex(), "MustLoadColorScheme()")
assert.Equalf(t, int32(15658734), Color("navigation.top.foreground1").Hex(), "MustLoadColorScheme()")
})
}
}
24 changes: 12 additions & 12 deletions internal/app/confirmation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
)

type Confirmation struct {
Complete chan bool
message string
screenX int
screenY int
Complete chan bool
message string
screenX int
screenY int
style tcell.Style
questionMarkStyle tcell.Style
}

const (
Expand All @@ -17,10 +19,6 @@ const (
QuestionMark = "? "
)

var (
QuestionMarkStyle = DefaultStyle.Bold(true).Foreground(tcell.ColorYellowGreen)
)

func Confirm(app *App, message string) bool {
confirmation := newConfirmation(message)
app.AddDrawable(confirmation)
Expand All @@ -33,14 +31,16 @@ func Confirm(app *App, message string) bool {

func newConfirmation(message string) *Confirmation {
return &Confirmation{
Complete: make(chan bool),
message: message,
Complete: make(chan bool),
message: message,
style: DefaultStyle(),
questionMarkStyle: DefaultStyle().Bold(true).Foreground(Color("finder.title")),
}
}

func (c *Confirmation) Draw(screen tcell.Screen) {
DrawText(screen, 0, c.screenY-2, QuestionMarkStyle, QuestionMark)
DrawText(screen, 2, c.screenY-2, DefaultStyle, c.message)
DrawText(screen, 0, c.screenY-2, c.questionMarkStyle, QuestionMark)
DrawText(screen, 2, c.screenY-2, c.style, c.message)
}

func (c *Confirmation) Resize(screenX, screenY int) {
Expand Down
Loading

0 comments on commit fc7de56

Please sign in to comment.