mirror of
https://github.com/mrusme/neonmodem.git
synced 2024-12-04 14:46:37 -05:00
Implemented draft PopupList
This commit is contained in:
parent
9b56ea8d07
commit
dbaeadf833
@ -86,6 +86,23 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopupList struct {
|
||||||
|
List struct {
|
||||||
|
Focused ThemeItemConfig
|
||||||
|
Blurred ThemeItemConfig
|
||||||
|
}
|
||||||
|
Item struct {
|
||||||
|
Focused ThemeItemConfig
|
||||||
|
Blurred ThemeItemConfig
|
||||||
|
Selected ThemeItemConfig
|
||||||
|
}
|
||||||
|
ItemDetail struct {
|
||||||
|
Focused ThemeItemConfig
|
||||||
|
Blurred ThemeItemConfig
|
||||||
|
Selected ThemeItemConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Post struct {
|
Post struct {
|
||||||
Author ThemeItemConfig
|
Author ThemeItemConfig
|
||||||
Subject ThemeItemConfig
|
Subject ThemeItemConfig
|
||||||
@ -165,6 +182,7 @@ func SetDefaults(cacheDir string) {
|
|||||||
viper.SetDefault("Debug", "true")
|
viper.SetDefault("Debug", "true")
|
||||||
viper.SetDefault("Log", path.Join(cacheDir, "gobbs.log"))
|
viper.SetDefault("Log", path.Join(cacheDir, "gobbs.log"))
|
||||||
|
|
||||||
|
// --- DialogBox ---
|
||||||
// DialogBox Window:Focused
|
// DialogBox Window:Focused
|
||||||
viper.SetDefault("Theme.DialogBox.Window.Focused.Margin",
|
viper.SetDefault("Theme.DialogBox.Window.Focused.Margin",
|
||||||
[]int{0, 0, 0, 0})
|
[]int{0, 0, 0, 0})
|
||||||
@ -219,6 +237,7 @@ func SetDefaults(cacheDir string) {
|
|||||||
viper.SetDefault("Theme.DialogBox.Bottombar.Foreground",
|
viper.SetDefault("Theme.DialogBox.Bottombar.Foreground",
|
||||||
lipgloss.AdaptiveColor{Light: "#aaaaaa", Dark: "#999999"})
|
lipgloss.AdaptiveColor{Light: "#aaaaaa", Dark: "#999999"})
|
||||||
|
|
||||||
|
// --- ErrorDialogBox ---
|
||||||
// ErrorDialogBox Window:Focused
|
// ErrorDialogBox Window:Focused
|
||||||
viper.SetDefault("Theme.ErrorDialogBox.Window.Focused.Margin",
|
viper.SetDefault("Theme.ErrorDialogBox.Window.Focused.Margin",
|
||||||
[]int{0, 0, 0, 0})
|
[]int{0, 0, 0, 0})
|
||||||
@ -273,6 +292,7 @@ func SetDefaults(cacheDir string) {
|
|||||||
viper.SetDefault("Theme.ErrorDialogBox.Bottombar.Foreground",
|
viper.SetDefault("Theme.ErrorDialogBox.Bottombar.Foreground",
|
||||||
lipgloss.AdaptiveColor{Light: "#aaaaaa", Dark: "#999999"})
|
lipgloss.AdaptiveColor{Light: "#aaaaaa", Dark: "#999999"})
|
||||||
|
|
||||||
|
// --- PostsList ---
|
||||||
// PostsList List:Focused
|
// PostsList List:Focused
|
||||||
viper.SetDefault("Theme.PostsList.List.Focused.Margin",
|
viper.SetDefault("Theme.PostsList.List.Focused.Margin",
|
||||||
[]int{0, 0, 0, 0})
|
[]int{0, 0, 0, 0})
|
||||||
@ -349,6 +369,84 @@ func SetDefaults(cacheDir string) {
|
|||||||
viper.SetDefault("Theme.PostsList.ItemDetail.Selected.Foreground",
|
viper.SetDefault("Theme.PostsList.ItemDetail.Selected.Foreground",
|
||||||
lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"})
|
lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"})
|
||||||
|
|
||||||
|
// --- PopupList ---
|
||||||
|
// PopupList List:Focused
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Focused.Margin",
|
||||||
|
[]int{0, 0, 0, 0})
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Focused.Padding",
|
||||||
|
[]int{1, 1, 1, 1})
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Focused.Border.Border",
|
||||||
|
lipgloss.HiddenBorder())
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Focused.Border.Sides",
|
||||||
|
[]bool{true, true, true, true},
|
||||||
|
)
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Focused.Border.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#00ffff", Dark: "#00ffff"})
|
||||||
|
|
||||||
|
// PopupList List:Blurred
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Blurred.Margin",
|
||||||
|
[]int{0, 0, 0, 0})
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Blurred.Padding",
|
||||||
|
[]int{1, 1, 1, 1})
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Blurred.Border.Border",
|
||||||
|
lipgloss.HiddenBorder())
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Blurred.Border.Sides",
|
||||||
|
[]bool{true, true, true, true},
|
||||||
|
)
|
||||||
|
viper.SetDefault("Theme.PopupList.List.Blurred.Border.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#cccccc", Dark: "#333333"})
|
||||||
|
|
||||||
|
// PopupList Item:Focused
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Focused.Padding",
|
||||||
|
[]int{0, 0, 0, 2})
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Focused.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#333333", Dark: "#cccccc"})
|
||||||
|
|
||||||
|
// PopupList Item:Blurred
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Blurred.Padding",
|
||||||
|
[]int{0, 0, 0, 2})
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Blurred.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#cccccc", Dark: "#333333"})
|
||||||
|
|
||||||
|
// PopupList Item:Selected
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Selected.Padding",
|
||||||
|
[]int{0, 0, 0, 1})
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Selected.Border.Border",
|
||||||
|
lipgloss.NormalBorder())
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Selected.Border.Sides",
|
||||||
|
[]bool{false, false, false, true},
|
||||||
|
)
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Selected.Border.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#ffd500", Dark: "#ffd500"})
|
||||||
|
viper.SetDefault("Theme.PopupList.Item.Selected.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#F25D94", Dark: "#F25D94"})
|
||||||
|
|
||||||
|
// PopupList ItemDetail:Focused
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Focused.Padding",
|
||||||
|
[]int{0, 0, 0, 2})
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Focused.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#666666", Dark: "#4d4d4d"})
|
||||||
|
|
||||||
|
// PopupList ItemDetail:Blurred
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Blurred.Padding",
|
||||||
|
[]int{0, 0, 0, 2})
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Blurred.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#666666", Dark: "#4d4d4d"})
|
||||||
|
|
||||||
|
// PopupList ItemDetail:Selected
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Selected.Padding",
|
||||||
|
[]int{0, 0, 0, 1})
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Selected.Border.Border",
|
||||||
|
lipgloss.NormalBorder())
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Selected.Border.Sides",
|
||||||
|
[]bool{false, false, false, true},
|
||||||
|
)
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Selected.Border.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#ffd500", Dark: "#ffd500"})
|
||||||
|
viper.SetDefault("Theme.PopupList.ItemDetail.Selected.Foreground",
|
||||||
|
lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"})
|
||||||
|
|
||||||
|
// --- Post ---
|
||||||
// Post Author
|
// Post Author
|
||||||
viper.SetDefault("Theme.Post.Author.Padding",
|
viper.SetDefault("Theme.Post.Author.Padding",
|
||||||
[]int{0, 1, 0, 1})
|
[]int{0, 1, 0, 1})
|
||||||
|
@ -30,6 +30,23 @@ type Theme struct {
|
|||||||
Bottombar lipgloss.Style
|
Bottombar lipgloss.Style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopupList struct {
|
||||||
|
List struct {
|
||||||
|
Focused lipgloss.Style
|
||||||
|
Blurred lipgloss.Style
|
||||||
|
}
|
||||||
|
Item struct {
|
||||||
|
Focused lipgloss.Style
|
||||||
|
Blurred lipgloss.Style
|
||||||
|
Selected lipgloss.Style
|
||||||
|
}
|
||||||
|
ItemDetail struct {
|
||||||
|
Focused lipgloss.Style
|
||||||
|
Blurred lipgloss.Style
|
||||||
|
Selected lipgloss.Style
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PostsList struct {
|
PostsList struct {
|
||||||
List struct {
|
List struct {
|
||||||
Focused lipgloss.Style
|
Focused lipgloss.Style
|
||||||
@ -99,6 +116,23 @@ func New(cfg *config.Config) *Theme {
|
|||||||
t.PostsList.ItemDetail.Selected =
|
t.PostsList.ItemDetail.Selected =
|
||||||
t.fromConfig(&cfg.Theme.PostsList.ItemDetail.Selected)
|
t.fromConfig(&cfg.Theme.PostsList.ItemDetail.Selected)
|
||||||
|
|
||||||
|
t.PopupList.List.Focused =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.List.Focused)
|
||||||
|
t.PopupList.List.Blurred =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.List.Blurred)
|
||||||
|
t.PopupList.Item.Focused =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.Item.Focused)
|
||||||
|
t.PopupList.Item.Blurred =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.Item.Blurred)
|
||||||
|
t.PopupList.Item.Selected =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.Item.Selected)
|
||||||
|
t.PopupList.ItemDetail.Focused =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.ItemDetail.Focused)
|
||||||
|
t.PopupList.ItemDetail.Blurred =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.ItemDetail.Blurred)
|
||||||
|
t.PopupList.ItemDetail.Selected =
|
||||||
|
t.fromConfig(&cfg.Theme.PopupList.ItemDetail.Selected)
|
||||||
|
|
||||||
t.Post.Author =
|
t.Post.Author =
|
||||||
t.fromConfig(&cfg.Theme.Post.Author)
|
t.fromConfig(&cfg.Theme.Post.Author)
|
||||||
t.Post.Subject =
|
t.Post.Subject =
|
||||||
|
55
ui/windows/popuplist/handlers.go
Normal file
55
ui/windows/popuplist/handlers.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package popuplist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/mrusme/gobbs/ui/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleSelect(mi interface{}) (bool, []tea.Cmd) {
|
||||||
|
var m *Model = mi.(*Model)
|
||||||
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
|
cmds = append(cmds, cmd.New(
|
||||||
|
cmd.WMCloseWin,
|
||||||
|
WIN_ID,
|
||||||
|
cmd.Arg{Name: "selectionID", Value: m.selectionID},
|
||||||
|
cmd.Arg{Name: "selected", Value: m.list.SelectedItem()},
|
||||||
|
).Tea())
|
||||||
|
return true, cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleViewResize(mi interface{}) (bool, []tea.Cmd) {
|
||||||
|
var m *Model = mi.(*Model)
|
||||||
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
|
m.ctx.Logger.Debugf("received WindowSizeMsg: %vx%v\n", m.tk.ViewWidth(), m.tk.ViewHeight())
|
||||||
|
listWidth := m.tk.ViewWidth() - 2
|
||||||
|
listHeight := m.tk.ViewHeight() - 1
|
||||||
|
|
||||||
|
m.ctx.Theme.PopupList.List.Focused.Width(listWidth)
|
||||||
|
m.ctx.Theme.PopupList.List.Blurred.Width(listWidth)
|
||||||
|
m.ctx.Theme.PopupList.List.Focused.Height(listHeight)
|
||||||
|
m.ctx.Theme.PopupList.List.Blurred.Height(listHeight)
|
||||||
|
m.list.SetSize(
|
||||||
|
listWidth-2,
|
||||||
|
listHeight-2,
|
||||||
|
)
|
||||||
|
|
||||||
|
return false, cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleWinOpenCmd(mi interface{}, c cmd.Command) (bool, []tea.Cmd) {
|
||||||
|
var m *Model = mi.(*Model)
|
||||||
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
|
if c.Target == WIN_ID {
|
||||||
|
m.ctx.Logger.Debug("got own WinOpen command")
|
||||||
|
m.selectionID = c.GetArg("selectionID").(string)
|
||||||
|
m.items = c.GetArg("items").([]list.Item)
|
||||||
|
m.list.SetItems(m.items)
|
||||||
|
return true, cmds
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, cmds
|
||||||
|
}
|
84
ui/windows/popuplist/popuplist.go
Normal file
84
ui/windows/popuplist/popuplist.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package popuplist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/mrusme/gobbs/aggregator"
|
||||||
|
"github.com/mrusme/gobbs/ui/ctx"
|
||||||
|
"github.com/mrusme/gobbs/ui/toolkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
WIN_ID = "popuplist"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
ctx *ctx.Ctx
|
||||||
|
tk *toolkit.ToolKit
|
||||||
|
|
||||||
|
selectionID string
|
||||||
|
list list.Model
|
||||||
|
items []list.Item
|
||||||
|
|
||||||
|
a *aggregator.Aggregator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Init() tea.Cmd {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModel(c *ctx.Ctx) Model {
|
||||||
|
m := Model{
|
||||||
|
ctx: c,
|
||||||
|
tk: toolkit.New(
|
||||||
|
WIN_ID,
|
||||||
|
c.Theme,
|
||||||
|
c.Logger,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
listDelegate := list.NewDefaultDelegate()
|
||||||
|
listDelegate.Styles.NormalTitle = m.ctx.Theme.PopupList.Item.Focused
|
||||||
|
listDelegate.Styles.DimmedTitle = m.ctx.Theme.PopupList.Item.Blurred
|
||||||
|
listDelegate.Styles.SelectedTitle = m.ctx.Theme.PopupList.Item.Selected
|
||||||
|
listDelegate.Styles.NormalDesc = m.ctx.Theme.PopupList.ItemDetail.Focused
|
||||||
|
listDelegate.Styles.DimmedDesc = m.ctx.Theme.PopupList.ItemDetail.Blurred
|
||||||
|
listDelegate.Styles.SelectedDesc = m.ctx.Theme.PopupList.ItemDetail.Selected
|
||||||
|
|
||||||
|
m.list = list.New(m.items, listDelegate, 0, 0)
|
||||||
|
m.list.SetShowTitle(false)
|
||||||
|
m.list.SetShowStatusBar(false)
|
||||||
|
|
||||||
|
m.tk.KeymapAdd("enter", "choose selection", "enter")
|
||||||
|
|
||||||
|
m.a, _ = aggregator.New(m.ctx)
|
||||||
|
|
||||||
|
m.tk.SetViewFunc(buildView)
|
||||||
|
m.tk.SetMsgHandling(toolkit.MsgHandling{
|
||||||
|
OnKeymapKey: []toolkit.MsgHandlingKeymapKey{
|
||||||
|
{
|
||||||
|
ID: "enter",
|
||||||
|
Handler: handleSelect,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OnViewResize: handleViewResize,
|
||||||
|
OnWinOpenCmd: handleWinOpenCmd,
|
||||||
|
})
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
|
ret, cmds := m.tk.HandleMsg(&m, msg)
|
||||||
|
if ret {
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd tea.Cmd
|
||||||
|
m.list, cmd = m.list.Update(msg)
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
return m, tea.Batch(cmds...)
|
||||||
|
}
|
32
ui/windows/popuplist/view.go
Normal file
32
ui/windows/popuplist/view.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package popuplist
|
||||||
|
|
||||||
|
import "github.com/charmbracelet/lipgloss"
|
||||||
|
|
||||||
|
func (m Model) View() string {
|
||||||
|
return m.tk.View(&m, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildView(mi interface{}, cached bool) string {
|
||||||
|
var m *Model = mi.(*Model)
|
||||||
|
|
||||||
|
if vcache := m.tk.DefaultCaching(cached); vcache != "" {
|
||||||
|
m.ctx.Logger.Debugln("Cached View()")
|
||||||
|
return vcache
|
||||||
|
}
|
||||||
|
m.ctx.Logger.Debugln("View()")
|
||||||
|
m.ctx.Logger.Debugf("IsFocused: %v\n", m.tk.IsFocused())
|
||||||
|
|
||||||
|
var style lipgloss.Style
|
||||||
|
if m.tk.IsFocused() {
|
||||||
|
style = m.ctx.Theme.PopupList.List.Focused
|
||||||
|
} else {
|
||||||
|
style = m.ctx.Theme.PopupList.List.Blurred
|
||||||
|
}
|
||||||
|
l := style.Render(m.list.View())
|
||||||
|
|
||||||
|
return m.tk.Dialog(
|
||||||
|
"Select",
|
||||||
|
l,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user