Update tui error handling
- Allow each view to position error banners where they choose - Add global 'esc' key handler to dismiss errors
This commit is contained in:
parent
d9d1b02ef3
commit
02228d65ac
@ -13,7 +13,7 @@ type ViewModel interface {
|
||||
// View methods
|
||||
Header(width int) string
|
||||
// Render the view's main content into a container of the given dimensions
|
||||
Content(width, height int) string
|
||||
Content(width, height int, errors string) string
|
||||
Footer(width int) string
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,14 @@ func (m *Model) Init() tea.Cmd {
|
||||
}
|
||||
|
||||
func (m *Model) handleGlobalInput(msg tea.KeyMsg) tea.Cmd {
|
||||
switch msg.String() {
|
||||
case "esc":
|
||||
if len(m.errs) > 0 {
|
||||
m.errs = m.errs[1:]
|
||||
return shared.KeyHandled(msg)
|
||||
}
|
||||
}
|
||||
|
||||
view, cmd := m.views[m.activeView].Update(msg)
|
||||
m.views[m.activeView] = view
|
||||
if cmd != nil {
|
||||
@ -108,10 +116,16 @@ func (m *Model) View() string {
|
||||
errBanners := make([]string, len(m.errs))
|
||||
for idx, err := range m.errs {
|
||||
errBanners[idx] = tuiutil.ErrorBanner(err, m.width)
|
||||
fixedUIHeight += tuiutil.Height(errBanners[idx])
|
||||
}
|
||||
var errors string
|
||||
if len(errBanners) > 0 {
|
||||
errors = lipgloss.JoinVertical(lipgloss.Left, errBanners...)
|
||||
} else {
|
||||
errors = ""
|
||||
}
|
||||
fixedUIHeight += tuiutil.Height(errors)
|
||||
|
||||
content := m.views[m.activeView].Content(m.width, m.height-fixedUIHeight)
|
||||
content := m.views[m.activeView].Content(m.width, m.height-fixedUIHeight, errors)
|
||||
|
||||
sections := make([]string, 0, 4)
|
||||
if header != "" {
|
||||
@ -123,9 +137,6 @@ func (m *Model) View() string {
|
||||
if footer != "" {
|
||||
sections = append(sections, footer)
|
||||
}
|
||||
for _, errBanner := range errBanners {
|
||||
sections = append(sections, errBanner)
|
||||
}
|
||||
return lipgloss.JoinVertical(lipgloss.Left, sections...)
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ type Model struct {
|
||||
stopSignal chan struct{}
|
||||
chatReplyChunks chan provider.Chunk
|
||||
persistence bool // whether we will save new messages in the conversation
|
||||
promptCaching bool // whether prompt caching is enabled
|
||||
|
||||
// UI state
|
||||
focus focusState
|
||||
|
@ -245,7 +245,7 @@ func (m *Model) conversationMessagesView() string {
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (m *Model) Content(width, height int) string {
|
||||
func (m *Model) Content(width, height int, errors string) string {
|
||||
// calculate clamped input height to accomodate input text
|
||||
// minimum 4 lines, maximum half of content area
|
||||
inputHeight := max(4, min(height/2, m.input.LineCount()))
|
||||
@ -255,7 +255,15 @@ func (m *Model) Content(width, height int) string {
|
||||
// remaining height towards content
|
||||
m.content.Width, m.content.Height = width, height-tuiutil.Height(input)
|
||||
content := m.content.View()
|
||||
return lipgloss.JoinVertical(lipgloss.Left, content, input)
|
||||
|
||||
var sections []string
|
||||
if errors != "" {
|
||||
sections = []string{content, errors, input}
|
||||
} else {
|
||||
sections = []string{content, input}
|
||||
}
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Left, sections...)
|
||||
}
|
||||
|
||||
func (m *Model) Header(width int) string {
|
||||
|
@ -218,9 +218,13 @@ func (m *Model) Header(width int) string {
|
||||
return styles.Header.Width(width).Render(header)
|
||||
}
|
||||
|
||||
func (m *Model) Content(width int, height int) string {
|
||||
func (m *Model) Content(width int, height int, errors string) string {
|
||||
m.content.Width, m.content.Height = width, height
|
||||
return m.content.View()
|
||||
content := m.content.View()
|
||||
if errors != "" {
|
||||
content += errors
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
func (m *Model) Footer(width int) string {
|
||||
|
@ -121,11 +121,15 @@ func (m *Model) Header(width int) string {
|
||||
return styles.Header.Width(width).Render(header)
|
||||
}
|
||||
|
||||
func (m *Model) Content(width, height int) string {
|
||||
func (m *Model) Content(width, height int, errors string) string {
|
||||
// TODO: see Header()
|
||||
currentModel := " Active model: " + m.App.ActiveModel(lipgloss.NewStyle())
|
||||
m.modelList.Width, m.modelList.Height = width, height - 2
|
||||
return "\n" + currentModel + "\n" + m.modelList.View()
|
||||
content := "\n" + currentModel + "\n" + m.modelList.View()
|
||||
if errors != "" {
|
||||
content += errors
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
func (m *Model) Footer(width int) string {
|
||||
|
Loading…
Reference in New Issue
Block a user