fix(tui): render selected chat bubbles clearly
This commit is contained in:
parent
5a04347124
commit
8d641e7c30
@ -34,5 +34,6 @@
|
||||
- Bring shared TUI detail and sort behavior closer to `gitcrawl`: archives open newest-first, group count headers sort like `cnt*`, selected chat messages render before surrounding conversation context, document previews appear before metadata, and detail fields use `key: value` labels.
|
||||
- Keep split-width member tables readable by rendering compact dates instead of truncated ISO timestamps.
|
||||
- Prioritize gitcrawl-style footer muscle-memory controls in compact tmux panes before app-specific extras.
|
||||
- Render selected chat message bodies with the same transcript marker as their speaker line so detail panes read more like chat.
|
||||
- Force the Bubble Tea program to shut down on terminal signals so interrupted TUIs restore terminal modes and do not leave orphaned tmux panes.
|
||||
- Rename the public package nouns to `config`, `store`, `snapshot`, `mirror`, `state`, `output`, `tui`, and `cache`.
|
||||
|
||||
24
tui/tui.go
24
tui/tui.go
@ -3699,7 +3699,7 @@ func (m model) chatDetailLines(item Item, width int) []string {
|
||||
lines = append(lines, dim(meta))
|
||||
}
|
||||
if message := chatBodyText(item); message != "" {
|
||||
lines = append(lines, "", dim(tuiRule(width)), bold("Message"))
|
||||
lines = append(lines, "", dim(tuiRule(width)), bold("Selected Message"))
|
||||
lines = appendLimitedDetailLines(lines, chatBubbleLines(item, message, true, width), detailBodyLimit(m.compactDetail))
|
||||
}
|
||||
if title, thread := m.threadSection(item, width); len(thread) > 0 {
|
||||
@ -3896,6 +3896,20 @@ func indentMarkdownLines(value string, indent, width int) []string {
|
||||
return out
|
||||
}
|
||||
|
||||
func prefixedMarkdownLines(value, prefix string, width int) []string {
|
||||
prefix = strings.TrimRight(prefix, "\t")
|
||||
raw := markdownLines(value, maxInt(8, width-lipgloss.Width(prefix)))
|
||||
out := make([]string, 0, len(raw))
|
||||
for _, line := range raw {
|
||||
if line == "" {
|
||||
out = append(out, strings.TrimRight(prefix, " "))
|
||||
continue
|
||||
}
|
||||
out = append(out, prefix+line)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func detailContextLines(item Item, includeTitle bool) []string {
|
||||
var lines []string
|
||||
fields := []string{
|
||||
@ -4043,16 +4057,18 @@ func sortChatIndexesByTime(items []Item, indexes []int) {
|
||||
func chatBubbleLines(item Item, text string, selected bool, width int) []string {
|
||||
var lines []string
|
||||
prefix := " "
|
||||
bodyPrefix := " "
|
||||
if selected {
|
||||
prefix = "> "
|
||||
bodyPrefix = "> "
|
||||
}
|
||||
header := joinNonEmpty([]string{itemAuthor(item), shortTimestamp(firstNonEmpty(item.CreatedAt, item.UpdatedAt))}, " ")
|
||||
header := joinNonEmpty([]string{itemAuthor(item), shortTimestamp(firstNonEmpty(item.CreatedAt, item.UpdatedAt)), rowAge(item)}, " ")
|
||||
if header != "" {
|
||||
lines = append(lines, prefix+header)
|
||||
}
|
||||
body := indentMarkdownLines(text, lipgloss.Width(prefix)+2, width)
|
||||
body := prefixedMarkdownLines(text, bodyPrefix, width)
|
||||
if len(body) == 0 {
|
||||
body = []string{strings.Repeat(" ", lipgloss.Width(prefix)+2) + "(empty)"}
|
||||
body = []string{bodyPrefix + "(empty)"}
|
||||
}
|
||||
lines = append(lines, body...)
|
||||
return lines
|
||||
|
||||
@ -481,7 +481,7 @@ func TestChatDetailUsesTranscriptShapeBeforeMetadata(t *testing.T) {
|
||||
}
|
||||
lines := m.detailLines(item)
|
||||
joined := strings.Join(lines, "\n")
|
||||
for _, want := range []string{"general bob", "Thread 1-2/2", "alice", "root message", "> bob", "reply message", "Properties", "url: https://example.com/thread", "IDs", "parent: m1"} {
|
||||
for _, want := range []string{"general bob", "Selected Message", "Thread 1-2/2", "alice", "root message", "> bob", "> reply message", "Properties", "url: https://example.com/thread", "IDs", "parent: m1"} {
|
||||
if !strings.Contains(joined, want) {
|
||||
t.Fatalf("chat detail missing %q:\n%s", want, joined)
|
||||
}
|
||||
@ -510,7 +510,7 @@ func TestChatDetailRendersMarkdownTranscriptLikeGitcrawl(t *testing.T) {
|
||||
t.Fatal("missing selected item")
|
||||
}
|
||||
joined := stripANSI(strings.Join(m.detailLinesForWidth(item, 52), "\n"))
|
||||
for _, want := range []string{"Plan", "- ship columns", "polish preview <https://example.com>", "> agreed", "done", "Properties", "IDs"} {
|
||||
for _, want := range []string{"Plan", "- ship columns", "polish preview <https://example.com>", "> > agreed", "> done", "Properties", "IDs"} {
|
||||
if !strings.Contains(joined, want) {
|
||||
t.Fatalf("markdown chat detail missing %q:\n%s", want, joined)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user