Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Commit

Permalink
add node view
Browse files Browse the repository at this point in the history
  • Loading branch information
ingbyr committed Sep 7, 2022
1 parent c5849af commit eec5d5d
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 48 deletions.
1 change: 1 addition & 0 deletions config/config.go
Expand Up @@ -8,6 +8,7 @@ type config struct {
BaseDir string
DBFile string
SysHostFile string
LineBreak string
}

const (
Expand Down
1 change: 1 addition & 0 deletions config/unix.go
Expand Up @@ -20,5 +20,6 @@ func New() *config {
BaseDir: baseDir,
DBFile: filepath.Join(baseDir, name+".db"),
SysHostFile: "/etc/hosts",
LineBreak: "\n",
}
}
1 change: 1 addition & 0 deletions config/windows.go
Expand Up @@ -20,5 +20,6 @@ func New() *config {
BaseDir: baseDir,
DBFile: filepath.Join(baseDir, name+".db"),
SysHostFile: "C:\\Windows\\System32\\drivers\\etc\\hosts",
LineBreak: "\r\n",
}
}
13 changes: 7 additions & 6 deletions tui/editor_view.go
Expand Up @@ -40,7 +40,7 @@ func (v *EditorView) Init() tea.Cmd {
}
}

func (v *EditorView) Update(msg tea.Msg) []tea.Cmd {
func (v *EditorView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
switch m := msg.(type) {
Expand All @@ -55,25 +55,26 @@ func (v *EditorView) Update(msg tea.Msg) []tea.Cmd {
v.host.SetContent([]byte(v.hostEditor.Value()))
err := gohost.GetService().UpdateHost(v.host)
if err != nil {
v.model.Log(err.Error())
v.model.log(err.Error())
} else {
v.SetSaved()
}
} else {
v.statusLine = "Can not edit this host"
v.model.log("Can not edit this")
}
case key.Matches(m, keys.Esc):
v.model.SwitchState(groupViewState)
v.model.switchState(treeViewState)
}
} else {
// Disable key
msg = nil
}
v.statusLine = "hit key: " + m.String()
}
//v.RefreshStatusLine()
v.RefreshStatusLine()
v.hostEditor, cmd = v.hostEditor.Update(msg)
return append(cmds, cmd)
cmds = append(cmds, cmd)
return v, tea.Batch(cmds...)
}

func (v *EditorView) View() string {
Expand Down
4 changes: 2 additions & 2 deletions tui/help_view.go
Expand Up @@ -23,7 +23,7 @@ func (h *HelpView) Init() tea.Cmd {
return nil
}

func (h *HelpView) Update(msg tea.Msg) []tea.Cmd {
func (h *HelpView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
h.view.Width = msg.Width
Expand All @@ -33,7 +33,7 @@ func (h *HelpView) Update(msg tea.Msg) []tea.Cmd {
h.view.ShowAll = !h.view.ShowAll
}
}
return nil
return h, nil
}

func (h *HelpView) View() string {
Expand Down
6 changes: 4 additions & 2 deletions tui/keymap.go
Expand Up @@ -2,6 +2,8 @@ package tui

import "github.com/charmbracelet/bubbles/key"

var keys = newKeys()

type keyMaps struct {
Up key.Binding
Down key.Binding
Expand All @@ -16,8 +18,8 @@ type keyMaps struct {
New key.Binding
}

func newKeys() keyMaps {
return keyMaps{
func newKeys() *keyMaps {
return &keyMaps{
Up: key.NewBinding(
key.WithKeys("up", "k"),
key.WithHelp("↑/k", "move up"),
Expand Down
53 changes: 30 additions & 23 deletions tui/model.go
Expand Up @@ -4,41 +4,38 @@ import (
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"gohost/tui/styles"
"strconv"
)

type sessionState int

const (
groupViewState = iota
treeViewState = iota
editorViewState
nodeViewState
lastState
)

var (
modelStyle = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.HiddenBorder())
focusedModelStyle = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.NormalBorder()).BorderForeground(lipgloss.Color("69"))
keys = newKeys()
)

type Model struct {
state sessionState
helpView *HelpView
groupView *GroupView
groupView *TreeView
editorView *EditorView
nodeView *NodeView
reservedHeight int
quitting bool
}

func NewModel() (*Model, error) {
model := &Model{
state: 0,
state: nodeViewState,
reservedHeight: 6,
}
model.helpView = NewHelpView(model)
model.groupView = NewGroupView(model)
model.groupView = NewTreeView(model)
model.editorView = NewTextView(model)
model.nodeView = NewNodeView(model)
return model, nil
}

Expand All @@ -61,40 +58,50 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, tea.Quit)
}
}
cmds = append(cmds, m.groupView.Update(msg)...)
cmds = append(cmds, m.editorView.Update(msg)...)
cmds = append(cmds, m.helpView.Update(msg)...)
m.updateView(msg, &cmds, m.groupView)
m.updateView(msg, &cmds, m.editorView)
m.updateView(msg, &cmds, m.nodeView)
m.updateView(msg, &cmds, m.helpView)
return m, tea.Batch(cmds...)
}

func (m *Model) View() string {
var str string
switch m.state {
case groupViewState:
case treeViewState:
str = lipgloss.JoinHorizontal(lipgloss.Top,
focusedModelStyle.Render(m.groupView.View()),
modelStyle.Render(m.editorView.View()))
styles.FocusedView.Render(m.groupView.View()),
styles.DefaultView.Render(m.editorView.View()))
case editorViewState:
str = lipgloss.JoinHorizontal(lipgloss.Top,
modelStyle.Render(m.groupView.View()),
focusedModelStyle.Render(m.editorView.View()))
styles.DefaultView.Render(m.groupView.View()),
styles.FocusedView.Render(m.editorView.View()))
case nodeViewState:
str = lipgloss.JoinHorizontal(lipgloss.Top,
styles.DefaultView.Render(m.groupView.View()),
styles.FocusedView.Render(m.nodeView.View()),
)
}
str = lipgloss.JoinVertical(lipgloss.Left, str, m.helpView.View())
//str += "\n" + m.helpView.View()
return str
}

func (m *Model) Log(msg string) {
func (m *Model) updateView(msg tea.Msg, cmds *[]tea.Cmd, view tea.Model) {
_, cmd := view.Update(msg)
*cmds = append(*cmds, cmd)
}

func (m *Model) log(msg string) {
m.helpView.debug = msg
}

func (m *Model) switchNextState() sessionState {
m.SwitchState((m.state + 1) % lastState)
m.Log("state:" + strconv.Itoa(int(m.state)))
m.switchState((m.state + 1) % lastState)
m.log("state:" + strconv.Itoa(int(m.state)))
return m.state
}

func (m *Model) SwitchState(state sessionState) {
func (m *Model) switchState(state sessionState) {
if state == editorViewState {
m.editorView.Focus()
} else {
Expand Down
54 changes: 54 additions & 0 deletions tui/node_view.go
@@ -1,4 +1,58 @@
package tui

import (
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"gohost/config"
"gohost/tui/styles"
"strings"
)

type NodeView struct {
model *Model
focusIdx int
inputs []textinput.Model
labels []string
}

func NewNodeView(model *Model) *NodeView {
nodeNameTextInput := textinput.New()
nodeNameTextInput.Prompt = "Name: "
nodeNameTextInput.CursorStyle = styles.FocusedView.Copy()
nodeNameTextInput.Focus()

descTextInput := textinput.New()
descTextInput.Prompt = "Description: "

view := &NodeView{
model: model,
inputs: []textinput.Model{nodeNameTextInput, descTextInput},
}

return view
}

func (v *NodeView) Init() tea.Cmd {
return nil
}

func (v *NodeView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
for i := range v.inputs {
v.inputs[i], cmd = v.inputs[i].Update(msg)
cmds = append(cmds, cmd)
}
return v, cmd
}

func (v *NodeView) View() string {
var b strings.Builder
for i := range v.inputs {
b.WriteString(v.inputs[i].View())
if i < len(v.inputs)-1 {
b.WriteString(config.Instance().LineBreak)
}
}
return b.String()
}
8 changes: 8 additions & 0 deletions tui/styles/default.go
@@ -0,0 +1,8 @@
package styles

import "github.com/charmbracelet/lipgloss"

var (
DefaultView = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.HiddenBorder())
FocusedView = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.NormalBorder()).BorderForeground(lipgloss.Color("69"))
)
31 changes: 16 additions & 15 deletions tui/group_view.go → tui/tree_view.go
Expand Up @@ -48,8 +48,8 @@ func (d groupItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
return nil
}

// GroupView is tui view for nodes tree
type GroupView struct {
// TreeView is tui view for nodes tree
type TreeView struct {
model *Model
groupList list.Model
selectedNode *gohost.TreeNode
Expand All @@ -60,7 +60,7 @@ type GroupView struct {
service *gohost.Service
}

func NewGroupView(model *Model) *GroupView {
func NewTreeView(model *Model) *TreeView {
// Get nodes service
service := gohost.GetService()
service.Load()
Expand All @@ -75,19 +75,19 @@ func NewGroupView(model *Model) *GroupView {
groupList.Title = "Groups"
groupList.SetShowHelp(false)

return &GroupView{
return &TreeView{
model: model,
groupList: groupList,
selectedNode: treeNodes[0],
service: service,
}
}

func (v *GroupView) Init() tea.Cmd {
func (v *TreeView) Init() tea.Cmd {
return nil
}

func (v *GroupView) Update(msg tea.Msg) []tea.Cmd {
func (v *TreeView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
switch m := msg.(type) {
Expand All @@ -96,7 +96,7 @@ func (v *GroupView) Update(msg tea.Msg) []tea.Cmd {
v.groupList.SetWidth(m.Width / 3)
v.model.helpView.debug = fmt.Sprintf("w %d h %d, w %d h %d", m.Width, m.Height, v.groupList.Width(), v.groupList.Height())
case tea.KeyMsg:
if v.model.state == groupViewState {
if v.model.state == treeViewState {
switch {
case key.Matches(m, keys.Enter):
selectedItem := v.groupList.SelectedItem()
Expand All @@ -117,14 +117,15 @@ func (v *GroupView) Update(msg tea.Msg) []tea.Cmd {
}
}
v.groupList, cmd = v.groupList.Update(msg)
return append(cmds, cmd)
cmds = append(cmds, cmd)
return v, tea.Batch(cmds...)
}

func (v *GroupView) View() string {
func (v *TreeView) View() string {
return v.groupList.View()
}

func (v *GroupView) onGroupNodeEnterClick(cmds *[]tea.Cmd) {
func (v *TreeView) onGroupNodeEnterClick(cmds *[]tea.Cmd) {
v.selectedGroup = v.selectedNode.Node.(*gohost.Group)
if v.selectedNode.IsFolded {
v.unfoldSelectedGroup(cmds)
Expand All @@ -134,7 +135,7 @@ func (v *GroupView) onGroupNodeEnterClick(cmds *[]tea.Cmd) {
v.selectedNode.IsFolded = !v.selectedNode.IsFolded
}

func (v *GroupView) unfoldSelectedGroup(cmds *[]tea.Cmd) {
func (v *TreeView) unfoldSelectedGroup(cmds *[]tea.Cmd) {
subGroups := v.service.ChildNodes(v.selectedNode.GetID())
idx := v.selectedIndex
for i := range subGroups {
Expand All @@ -148,7 +149,7 @@ func (v *GroupView) unfoldSelectedGroup(cmds *[]tea.Cmd) {
}
}

func (v *GroupView) foldSelectedGroup() {
func (v *TreeView) foldSelectedGroup() {
items := v.groupList.Items()
next := v.selectedIndex + 1
for i := next; i < len(items); i++ {
Expand All @@ -165,9 +166,9 @@ func (v *GroupView) foldSelectedGroup() {
}
}

func (v *GroupView) onHostNodeSelected(cmds *[]tea.Cmd) {
func (v *TreeView) onHostNodeSelected(cmds *[]tea.Cmd) {
v.selectedHost = v.selectedNode.Node.(gohost.Host)
v.model.Log("select host: " + v.selectedHost.Title())
v.model.SwitchState(editorViewState)
v.model.log("select host: " + v.selectedHost.Title())
v.model.switchState(editorViewState)
v.model.editorView.SetHost(v.selectedHost)
}

0 comments on commit eec5d5d

Please sign in to comment.