소스 검색

Enforced update on widgets, moved IC keyhandling to IC.update

arianagiroux 2 주 전
부모
커밋
02144c3032
2개의 변경된 파일58개의 추가작업 그리고 47개의 파일을 삭제
  1. 0 1
      Readme.md
  2. 58 46
      tui.go

+ 0 - 1
Readme.md

@@ -20,7 +20,6 @@ go install cmd/issues.go
 - `io.go:func DeleteIssue(issue Issue) (success bool, err error) { return false, nil } // TODO: implement`
 - `tui.go:// TODO enable collection recursing (i.e, embedded collections)`
 - `tui.go:// TODO enable scroll/viewport logic`
-- `tui.go:	case IssueCollection: // TODO handle updates to IssueCollection widgets in its own update func`
 - `tui.go:// TODO(create widget) handle reset on esc`
 - `tui.go:// TODO(create widget) implement description field in create.create`
 

+ 58 - 46
tui.go

@@ -69,47 +69,11 @@ func (m Model) Init() tea.Cmd { return m.load }
 
 // Core tea.Model update loop
 func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
-	// widget specifc keyhandling
 	var cmds []tea.Cmd
-	switch m.widget.(type) {
-	case IssueCollection: // TODO handle updates to IssueCollection widgets in its own update func
-		if msg, ok := msg.(tea.KeyMsg); ok {
-			switch msg.String() {
-			case "j":
-				if collection, ok := m.widget.(IssueCollection); ok {
-					if collection.selection+1 < len(collection.Collection) {
-						collection.selection = collection.selection + 1
-					} else {
-						collection.selection = 0
-					}
-					m.widget = collection
-					return m, collection.render
-				}
-			case "k":
-				// do something only if widget is collection
-				if collection, ok := m.widget.(IssueCollection); ok {
-					if collection.selection != 0 {
-						collection.selection = collection.selection - 1
-					} else {
-						collection.selection = len(collection.Collection) - 1
-					}
-					m.widget = collection
-					return m, collection.render
-				}
-			case "enter":
-				if _, ok := m.widget.(IssueCollection); ok {
-					m.Path = m.widget.(IssueCollection).Collection[m.widget.(IssueCollection).selection].Path
-					return m, m.load
-				}
-			case "q":
-				cmds = append(cmds, tea.Quit)
-			}
-		}
-	}
 
 	// general message handling
 	switch msg := msg.(type) {
-	case tea.KeyMsg: // keymsg capture that is always present
+	case tea.KeyMsg: // KeyMsg capture that is always present
 		switch msg.String() {
 		case "ctrl+c":
 			cmds = append(cmds, tea.Quit)
@@ -123,15 +87,25 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			m.widget = T
 			cmds = append(cmds, T.render)
 		}
+	case loadPath:
+		m.Path = string(msg)
+		return m, m.load
 	case string:
 		m.content = msg
 	}
 
-	// finally, handle input updates if any
-	if w, ok := m.widget.(create); ok {
-		var cmd tea.Cmd
+	// finally, pass msg to widget
+	var cmd tea.Cmd
+	switch w := m.widget.(type) {
+	case create:
 		m.widget, cmd = w.update(msg)
 		cmds = append(cmds, cmd, w.render)
+	case Issue:
+		m.widget, cmd = w.update(msg)
+		cmds = append(cmds, cmd)
+	case IssueCollection:
+		m.widget, cmd = w.update(msg)
+		cmds = append(cmds, cmd)
 	}
 
 	return m, tea.Batch(cmds...)
@@ -153,8 +127,9 @@ func (m Model) View() string {
 
 // interface definition for widgets
 type widget interface {
-	render() tea.Msg // renders content
-	keyhelp() string // renders key usage
+	update(tea.Msg) (widget, tea.Cmd) // implements widget specific update life cycles
+	render() tea.Msg                  // renders content
+	keyhelp() string                  // renders key usage
 }
 
 // -------- create widget definitions -----------------------------------------
@@ -220,9 +195,7 @@ func initialCreateWidget(path string, placeholder string) create {
 }
 
 // init cmd for create widget
-func (c create) init() tea.Cmd {
-	return textinput.Blink
-}
+func (c create) init() tea.Cmd { return textinput.Blink }
 
 type ( // Type definitions for use in tea.Msg life cycle for create widget.
 	createResult Issue    // type wrapper for create.create() result
@@ -234,7 +207,7 @@ type ( // Type definitions for use in tea.Msg life cycle for create widget.
 )
 
 // update cmd for create widget
-func (c create) update(msg tea.Msg) (create, tea.Cmd) {
+func (c create) update(msg tea.Msg) (widget, tea.Cmd) {
 	var cmds []tea.Cmd
 	var cmd tea.Cmd
 
@@ -453,6 +426,9 @@ func (c create) keyhelp() string {
 // -------- Issue widget definitions ------------------------------------------
 // ----------------------------------------------------------------------------
 
+// enforce widget interface compliance
+func (i Issue) update(tea.Msg) (widget, tea.Cmd) { return i, nil }
+
 // render cmd for Issue widget
 func (i Issue) render() tea.Msg {
 	var output string
@@ -502,6 +478,42 @@ func (i Issue) keyhelp() string {
 // -------- IssueCollection widget definitions --------------------------------
 // ----------------------------------------------------------------------------
 
+type ( // Type definitions for use in tea.Msg life cycle for IssueCollection widget.
+	loadPath string // thrown when user selects a path to load.
+)
+
+// enforce widget interface compliance
+func (ic IssueCollection) update(msg tea.Msg) (widget, tea.Cmd) {
+	switch msg := msg.(type) {
+	case tea.KeyMsg:
+		switch msg.String() {
+		case "j":
+			if ic.selection+1 < len(ic.Collection) {
+				ic.selection = ic.selection + 1
+			} else {
+				ic.selection = 0
+			}
+			return ic, ic.render
+		case "k":
+			if ic.selection != 0 {
+				ic.selection = ic.selection - 1
+			} else {
+				ic.selection = len(ic.Collection) - 1
+			}
+			return ic, ic.render
+		case "enter":
+			ic.Path = ic.Collection[ic.selection].Path
+			return ic, ic.sendLoad
+		case "q":
+			return ic, tea.Quit
+		}
+	}
+
+	return ic, nil
+}
+
+func (ic IssueCollection) sendLoad() tea.Msg { return loadPath(ic.Path) }
+
 // render cmd for IssueCollection widget
 func (ic IssueCollection) render() tea.Msg {
 	var output string