more UI and change default local user permissions
This commit is contained in:
129
tui.go
129
tui.go
@@ -12,7 +12,9 @@ import (
|
||||
|
||||
type tuiTheme struct {
|
||||
outer lipgloss.Style
|
||||
headerBar lipgloss.Style
|
||||
badge lipgloss.Style
|
||||
chrome lipgloss.Style
|
||||
title lipgloss.Style
|
||||
subtitle lipgloss.Style
|
||||
sectionTitle lipgloss.Style
|
||||
@@ -20,10 +22,15 @@ type tuiTheme struct {
|
||||
muted lipgloss.Style
|
||||
footer lipgloss.Style
|
||||
panel lipgloss.Style
|
||||
panelAccent lipgloss.Style
|
||||
row lipgloss.Style
|
||||
rowSelected lipgloss.Style
|
||||
rowNumber lipgloss.Style
|
||||
rowNumberOn lipgloss.Style
|
||||
rowKey lipgloss.Style
|
||||
rowKeySelected lipgloss.Style
|
||||
rowTitle lipgloss.Style
|
||||
rowTitleOn lipgloss.Style
|
||||
rowHint lipgloss.Style
|
||||
rowHintActive lipgloss.Style
|
||||
statusInfo lipgloss.Style
|
||||
@@ -34,35 +41,44 @@ type tuiTheme struct {
|
||||
}
|
||||
|
||||
func newTUITheme() tuiTheme {
|
||||
border := lipgloss.Color("#4B5D6B")
|
||||
text := lipgloss.Color("#E9E1D4")
|
||||
muted := lipgloss.Color("#9E9385")
|
||||
accent := lipgloss.Color("#D97745")
|
||||
accentSoft := lipgloss.Color("#F4D8BD")
|
||||
panel := lipgloss.Color("#192126")
|
||||
panelAlt := lipgloss.Color("#232E36")
|
||||
info := lipgloss.Color("#7FB0C2")
|
||||
warn := lipgloss.Color("#D7A55A")
|
||||
success := lipgloss.Color("#8AAC83")
|
||||
border := lipgloss.Color("#5A6772")
|
||||
borderSoft := lipgloss.Color("#31414A")
|
||||
text := lipgloss.Color("#ECE4D8")
|
||||
muted := lipgloss.Color("#A49788")
|
||||
accent := lipgloss.Color("#D9733F")
|
||||
accentSoft := lipgloss.Color("#F2D2B5")
|
||||
panel := lipgloss.Color("#161C20")
|
||||
panelAlt := lipgloss.Color("#212A30")
|
||||
panelLift := lipgloss.Color("#2B363D")
|
||||
info := lipgloss.Color("#86B7C6")
|
||||
warn := lipgloss.Color("#D8AB63")
|
||||
success := lipgloss.Color("#91B57F")
|
||||
|
||||
return tuiTheme{
|
||||
outer: lipgloss.NewStyle().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(border).
|
||||
Padding(1, 2),
|
||||
headerBar: lipgloss.NewStyle().
|
||||
Foreground(borderSoft),
|
||||
chrome: lipgloss.NewStyle().
|
||||
Foreground(muted),
|
||||
badge: lipgloss.NewStyle().
|
||||
Foreground(panel).
|
||||
Background(accentSoft).
|
||||
Bold(true).
|
||||
Padding(0, 1),
|
||||
subtitle: lipgloss.NewStyle().
|
||||
Foreground(muted),
|
||||
title: lipgloss.NewStyle().
|
||||
Foreground(text).
|
||||
Bold(true),
|
||||
subtitle: lipgloss.NewStyle().
|
||||
Foreground(muted),
|
||||
sectionTitle: lipgloss.NewStyle().
|
||||
Foreground(accentSoft).
|
||||
Bold(true).
|
||||
Border(lipgloss.NormalBorder(), false, false, true, false).
|
||||
BorderForeground(borderSoft).
|
||||
PaddingBottom(0).
|
||||
MarginBottom(1),
|
||||
body: lipgloss.NewStyle().
|
||||
Foreground(text),
|
||||
@@ -71,26 +87,50 @@ func newTUITheme() tuiTheme {
|
||||
footer: lipgloss.NewStyle().
|
||||
Foreground(muted).
|
||||
Border(lipgloss.NormalBorder(), true, false, false, false).
|
||||
BorderForeground(border).
|
||||
PaddingTop(1),
|
||||
BorderForeground(borderSoft).
|
||||
PaddingTop(1).
|
||||
MarginTop(1),
|
||||
panel: lipgloss.NewStyle().
|
||||
Border(lipgloss.NormalBorder(), false, false, false, true).
|
||||
BorderForeground(border).
|
||||
PaddingLeft(1),
|
||||
row: lipgloss.NewStyle().
|
||||
BorderForeground(borderSoft).
|
||||
PaddingLeft(1).
|
||||
MarginBottom(1),
|
||||
panelAccent: lipgloss.NewStyle().
|
||||
Border(lipgloss.ThickBorder(), false, false, false, true).
|
||||
BorderForeground(panelAlt).
|
||||
PaddingLeft(1),
|
||||
BorderForeground(accent).
|
||||
PaddingLeft(1).
|
||||
MarginBottom(1),
|
||||
row: lipgloss.NewStyle().
|
||||
Border(lipgloss.NormalBorder(), false, false, false, true).
|
||||
BorderForeground(panelLift).
|
||||
Padding(0, 1).
|
||||
MarginBottom(1),
|
||||
rowSelected: lipgloss.NewStyle().
|
||||
Border(lipgloss.ThickBorder(), false, false, false, true).
|
||||
BorderForeground(accent).
|
||||
Background(panel).
|
||||
PaddingLeft(1),
|
||||
Padding(0, 1).
|
||||
MarginBottom(1),
|
||||
rowNumber: lipgloss.NewStyle().
|
||||
Foreground(muted),
|
||||
rowNumberOn: lipgloss.NewStyle().
|
||||
Foreground(accentSoft).
|
||||
Bold(true),
|
||||
rowKey: lipgloss.NewStyle().
|
||||
Foreground(accent).
|
||||
Bold(true),
|
||||
Bold(true).
|
||||
Background(panelAlt).
|
||||
Padding(0, 1),
|
||||
rowKeySelected: lipgloss.NewStyle().
|
||||
Foreground(accentSoft).
|
||||
Background(panelLift).
|
||||
Bold(true).
|
||||
Padding(0, 1),
|
||||
rowTitle: lipgloss.NewStyle().
|
||||
Foreground(text).
|
||||
Bold(true),
|
||||
rowTitleOn: lipgloss.NewStyle().
|
||||
Foreground(text).
|
||||
Bold(true),
|
||||
rowHint: lipgloss.NewStyle().
|
||||
Foreground(muted),
|
||||
@@ -111,7 +151,8 @@ func newTUITheme() tuiTheme {
|
||||
inputBox: lipgloss.NewStyle().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(border).
|
||||
Padding(0, 1),
|
||||
Padding(0, 1).
|
||||
Background(panelAlt),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,10 +185,11 @@ func (t tuiTheme) renderFrame(width int, title, subtitle, body, footer string) s
|
||||
placeWidth = frameWidth
|
||||
}
|
||||
|
||||
sections := []string{
|
||||
t.badge.Render("SAMBA CONFIGER"),
|
||||
t.title.Width(contentWidth).Render(title),
|
||||
}
|
||||
headerLeft := lipgloss.JoinHorizontal(lipgloss.Top, t.badge.Render("SAMBA CONFIGER"), " ", t.chrome.Render("share editor"))
|
||||
headerRule := t.headerBar.Render(strings.Repeat("─", max(0, contentWidth-lipgloss.Width(headerLeft)-1)))
|
||||
header := lipgloss.JoinHorizontal(lipgloss.Center, headerLeft, " ", headerRule)
|
||||
|
||||
sections := []string{header, t.title.Width(contentWidth).Render(title)}
|
||||
if subtitle != "" {
|
||||
sections = append(sections, t.subtitle.Width(contentWidth).Render(subtitle))
|
||||
}
|
||||
@@ -172,7 +214,7 @@ func (t tuiTheme) renderSection(width int, title string, lines []string) string
|
||||
rendered = append(rendered, t.sectionTitle.Width(contentWidth).Render(title))
|
||||
}
|
||||
for _, line := range lines {
|
||||
rendered = append(rendered, t.panel.Width(contentWidth).Render(t.body.Width(contentWidth-2).Render(line)))
|
||||
rendered = append(rendered, t.panel.Width(contentWidth).Render(t.body.Width(max(1, contentWidth-2)).Render(line)))
|
||||
}
|
||||
return strings.Join(rendered, "\n")
|
||||
}
|
||||
@@ -190,6 +232,13 @@ func (t tuiTheme) renderMessage(width int, kind, text string) string {
|
||||
)
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
type menuOption struct {
|
||||
Key string
|
||||
Value string
|
||||
@@ -260,17 +309,29 @@ func (m menuModel) View() string {
|
||||
for i, option := range m.options {
|
||||
rowStyle := m.theme.row
|
||||
keyStyle := m.theme.rowKey
|
||||
titleStyle := m.theme.rowTitle
|
||||
hintStyle := m.theme.rowHint
|
||||
prefix := m.theme.muted.Render(fmt.Sprintf("%02d", i+1))
|
||||
numberStyle := m.theme.rowNumber
|
||||
prefix := numberStyle.Render(fmt.Sprintf("%02d", i+1))
|
||||
if i == m.cursor {
|
||||
rowStyle = m.theme.rowSelected
|
||||
keyStyle = m.theme.rowKeySelected
|
||||
titleStyle = m.theme.rowTitleOn
|
||||
hintStyle = m.theme.rowHintActive
|
||||
prefix = keyStyle.Render(">>")
|
||||
numberStyle = m.theme.rowNumberOn
|
||||
prefix = numberStyle.Render(">>")
|
||||
}
|
||||
|
||||
label := fmt.Sprintf("%s %s %s", prefix, keyStyle.Render("["+option.Key+"]"), option.Label)
|
||||
rowLines := []string{label}
|
||||
top := lipgloss.JoinHorizontal(
|
||||
lipgloss.Center,
|
||||
prefix,
|
||||
" ",
|
||||
keyStyle.Render(strings.ToUpper(option.Key)),
|
||||
" ",
|
||||
titleStyle.Render(option.Label),
|
||||
)
|
||||
|
||||
rowLines := []string{top}
|
||||
if option.Description != "" {
|
||||
rowLines = append(rowLines, hintStyle.Render(option.Description))
|
||||
}
|
||||
@@ -360,10 +421,8 @@ func (m textPromptModel) View() string {
|
||||
width := clampFrameWidth(m.width)
|
||||
contentWidth := innerWidth(width)
|
||||
|
||||
lines := []string{
|
||||
m.theme.inputLabel.Width(contentWidth).Render(m.label),
|
||||
m.theme.inputBox.Width(contentWidth).Render(m.input.View()),
|
||||
}
|
||||
lines := []string{m.theme.inputLabel.Width(contentWidth).Render(m.label)}
|
||||
lines = append(lines, m.theme.panelAccent.Width(contentWidth).Render(m.theme.inputBox.Width(max(8, contentWidth-2)).Render(m.input.View())))
|
||||
if m.defaultValue != "" {
|
||||
lines = append(lines, m.theme.muted.Width(contentWidth).Render("Enter keeps: "+m.defaultValue))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user