Переглянути джерело

fix(TUI): make it less shimmer (#2076)

Timo Clasen 6 місяців тому
батько
коміт
4913ee6afd

+ 4 - 10
packages/tui/internal/components/chat/editor.go

@@ -382,11 +382,9 @@ func (m *editorComponent) Content() string {
 			status = "waiting for permission"
 		}
 		if m.interruptKeyInDebounce && m.app.CurrentPermission.ID == "" {
-			bright := t.Accent()
-			if status == "waiting for permission" {
-				bright = t.Warning()
-			}
-			hint = util.Shimmer(status, t.Background(), t.TextMuted(), bright) + m.spinner.View() + muted(
+			hint = muted(
+				status,
+			) + m.spinner.View() + muted(
 				"  ",
 			) + base(
 				keyText+" again",
@@ -394,11 +392,7 @@ func (m *editorComponent) Content() string {
 				" interrupt",
 			)
 		} else {
-			bright := t.Accent()
-			if status == "waiting for permission" {
-				bright = t.Warning()
-			}
-			hint = util.Shimmer(status, t.Background(), t.TextMuted(), bright) + m.spinner.View()
+			hint = muted(status) + m.spinner.View()
 			if m.app.CurrentPermission.ID == "" {
 				hint += muted("  ") + base(keyText) + muted(" interrupt")
 			}

+ 7 - 1
packages/tui/internal/components/chat/message.go

@@ -213,6 +213,7 @@ func renderText(
 	extra string,
 	isThinking bool,
 	isQueued bool,
+	shimmer bool,
 	fileParts []opencode.FilePart,
 	agentParts []opencode.AgentPart,
 	toolCalls ...opencode.ToolPart,
@@ -234,7 +235,12 @@ func renderText(
 		}
 		content = util.ToMarkdown(text, width, backgroundColor)
 		if isThinking {
-			label := util.Shimmer("Thinking...", backgroundColor, t.TextMuted(), t.Accent())
+			var label string
+			if shimmer {
+				label = util.Shimmer("Thinking...", backgroundColor, t.TextMuted(), t.Accent())
+			} else {
+				label = styles.NewStyle().Background(backgroundColor).Foreground(t.TextMuted()).Render("Thinking...")
+			}
 			label = styles.NewStyle().Background(backgroundColor).Width(width - 6).Render(label)
 			content = label + "\n\n" + content
 		} else if strings.TrimSpace(text) == "Generating..." {

+ 25 - 0
packages/tui/internal/components/chat/messages.go

@@ -336,6 +336,25 @@ func (m *messagesComponent) renderView() tea.Cmd {
 
 		width := m.width // always use full width
 
+		// Find the last streaming ReasoningPart to only shimmer that one
+		lastStreamingReasoningID := ""
+		if m.showThinkingBlocks {
+			for mi := len(m.app.Messages) - 1; mi >= 0 && lastStreamingReasoningID == ""; mi-- {
+				if _, ok := m.app.Messages[mi].Info.(opencode.AssistantMessage); !ok {
+					continue
+				}
+				parts := m.app.Messages[mi].Parts
+				for pi := len(parts) - 1; pi >= 0; pi-- {
+					if rp, ok := parts[pi].(opencode.ReasoningPart); ok {
+						if strings.TrimSpace(rp.Text) != "" && rp.Time.End == 0 {
+							lastStreamingReasoningID = rp.ID
+							break
+						}
+					}
+				}
+			}
+		}
+
 		reverted := false
 		revertedMessageCount := 0
 		revertedToolCount := 0
@@ -437,6 +456,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 								files,
 								false,
 								isQueued,
+								false,
 								fileParts,
 								agentParts,
 							)
@@ -513,6 +533,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 									"",
 									false,
 									false,
+									false,
 									[]opencode.FilePart{},
 									[]opencode.AgentPart{},
 									toolCallParts...,
@@ -530,6 +551,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 								"",
 								false,
 								false,
+								false,
 								[]opencode.FilePart{},
 								[]opencode.AgentPart{},
 								toolCallParts...,
@@ -600,6 +622,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 						}
 						if part.Text != "" {
 							text := part.Text
+							shimmer := part.Time.End == 0 && part.ID == lastStreamingReasoningID
 							content = renderText(
 								m.app,
 								message.Info,
@@ -610,6 +633,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 								"",
 								true,
 								false,
+								shimmer,
 								[]opencode.FilePart{},
 								[]opencode.AgentPart{},
 							)
@@ -644,6 +668,7 @@ func (m *messagesComponent) renderView() tea.Cmd {
 						"",
 						false,
 						false,
+						false,
 						[]opencode.FilePart{},
 						[]opencode.AgentPart{},
 					)