tui: removed confirm before send, dynamic footer
footer now rendered based on model data, instead of being set to a fixed string
This commit is contained in:
parent
3b71f08d19
commit
a5f39f7944
@ -29,13 +29,12 @@ type model struct {
|
||||
err error
|
||||
|
||||
// ui state
|
||||
isWaiting bool
|
||||
confirmPrompt bool
|
||||
isWaiting bool
|
||||
status string // a general status message
|
||||
|
||||
// ui elements
|
||||
content viewport.Model
|
||||
input textarea.Model
|
||||
footer string
|
||||
}
|
||||
|
||||
type message struct {
|
||||
@ -102,7 +101,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.messages[i].Content += chunk
|
||||
default:
|
||||
m.messages = append(m.messages, models.Message{
|
||||
Role: models.MessageRoleAssistant,
|
||||
Role: models.MessageRoleAssistant,
|
||||
Content: chunk,
|
||||
})
|
||||
}
|
||||
@ -111,7 +110,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
cmd = waitForChunk(m.replyChan) // wait for the next chunk
|
||||
case msgResponseEnd:
|
||||
m.isWaiting = false
|
||||
m.footer = "Press Ctrl+S to send, Ctrl+C or 'q' to quit"
|
||||
m.status = "Press ctrl+s to send"
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
@ -146,9 +145,6 @@ func initialModel(ctx *lmcli.Context, convShortname string) model {
|
||||
convShortname: convShortname,
|
||||
|
||||
replyChan: make(chan string),
|
||||
|
||||
isWaiting: false,
|
||||
confirmPrompt: false,
|
||||
}
|
||||
|
||||
m.content = viewport.New(0, 0)
|
||||
@ -162,7 +158,8 @@ func initialModel(ctx *lmcli.Context, convShortname string) model {
|
||||
|
||||
m.updateContent()
|
||||
|
||||
m.footer = "Press Ctrl+S to send, Ctrl+C or 'q' to quit"
|
||||
m.isWaiting = false
|
||||
m.status = "Press ctrl+s to send"
|
||||
|
||||
return m
|
||||
}
|
||||
@ -172,38 +169,25 @@ func (m *model) handleKeyMsg(msg tea.KeyMsg) tea.Cmd {
|
||||
case "ctrl+c", "q":
|
||||
return tea.Quit
|
||||
case "ctrl+s":
|
||||
if !m.isWaiting && !m.confirmPrompt {
|
||||
m.confirmPrompt = true
|
||||
m.footer = "Press 'y' to confirm sending the message, 'n' to cancel"
|
||||
return nil
|
||||
}
|
||||
case "y":
|
||||
if m.confirmPrompt {
|
||||
userInput := m.input.Value()
|
||||
m.input.SetValue("")
|
||||
m.messages = append(m.messages, models.Message{
|
||||
Role: models.MessageRoleUser,
|
||||
Content: userInput,
|
||||
})
|
||||
m.updateContent()
|
||||
m.content.GotoBottom()
|
||||
m.isWaiting = true
|
||||
m.confirmPrompt = false
|
||||
m.footer = "Waiting for response... (Press 's' to stop)"
|
||||
return m.promptLLM()
|
||||
}
|
||||
case "n":
|
||||
if m.confirmPrompt {
|
||||
m.confirmPrompt = false
|
||||
m.footer = "Press Ctrl+S to send, Ctrl+C or 'q' to quit"
|
||||
userInput := strings.TrimSpace(m.input.Value())
|
||||
if strings.TrimSpace(userInput) == "" {
|
||||
return nil
|
||||
}
|
||||
m.input.SetValue("")
|
||||
m.messages = append(m.messages, models.Message{
|
||||
Role: models.MessageRoleUser,
|
||||
Content: userInput,
|
||||
})
|
||||
|
||||
m.updateContent()
|
||||
m.content.GotoBottom()
|
||||
|
||||
m.isWaiting = true
|
||||
m.status = "Waiting for response... (Press 's' to stop)"
|
||||
return m.promptLLM()
|
||||
case "s":
|
||||
if m.isWaiting {
|
||||
m.isWaiting = false
|
||||
m.footer = "Response generation stopped. Press Ctrl+S to send, Ctrl+C or 'q' to quit"
|
||||
return nil
|
||||
}
|
||||
// TOOD: stop response
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -283,7 +267,7 @@ func (m *model) updateContent() {
|
||||
style = assistantStyle
|
||||
}
|
||||
|
||||
sb.WriteString(fmt.Sprintf("%s:\n\n", style.Render(string(message.Role))))
|
||||
sb.WriteString(fmt.Sprintf("%s:\n\n", style.Render(string(message.Role.FriendlyRole()))))
|
||||
|
||||
highlighted, _ := m.ctx.Chroma.HighlightS(message.Content)
|
||||
sb.WriteString(contentStyle.Width(m.content.Width - 5).Render(highlighted))
|
||||
@ -305,10 +289,20 @@ func (m model) inputView() string {
|
||||
}
|
||||
|
||||
func (m model) footerView() string {
|
||||
return footerStyle.
|
||||
Width(m.content.Width).
|
||||
Align(lipgloss.Center).
|
||||
Render(m.footer)
|
||||
left := m.status
|
||||
right := fmt.Sprintf("Model: %s", *m.ctx.Config.Defaults.Model)
|
||||
|
||||
totalWidth := lipgloss.Width(left + right)
|
||||
var padding string
|
||||
if m.content.Width-totalWidth > 0 {
|
||||
padding = strings.Repeat(" ", m.content.Width-totalWidth)
|
||||
} else {
|
||||
padding = ""
|
||||
}
|
||||
|
||||
footer := lipgloss.JoinHorizontal(lipgloss.Center, left, padding, right)
|
||||
|
||||
return footerStyle.Width(m.content.Width).Render(footer)
|
||||
}
|
||||
|
||||
func Launch(ctx *lmcli.Context, convShortname string) error {
|
||||
|
Loading…
Reference in New Issue
Block a user