WhspBrd/internal/tui/sidebar.go
copilot-swe-agent[bot] c2607b2860 Implement message selection-based scrolling with j/k keys
Co-authored-by: foglar <82380203+foglar@users.noreply.github.com>
2025-10-09 13:40:31 +00:00

131 lines
2.6 KiB
Go

package tui
import (
"errors"
"fmt"
"log"
"whspbrd/pkg/clean_image"
"whspbrd/pkg/render_image"
"github.com/jroimartin/gocui"
)
const (
sidebarIconColumn = 2
sidebarIconSize = 30
sidebarRowOffset = 3
sidebarRowSpacing = 2
)
func updateContactsView(g *gocui.Gui) error {
v, err := g.View("users")
if err != nil {
return err
}
v.Clear()
clear := cleanimage.NewKittyImageCleaner()
fmt.Print(clear.DeleteByColumn(sidebarIconColumn, false))
if len(users) == 0 {
fmt.Fprintln(v, "No Contacts")
return errors.New("no contacts in the list, find some friends")
}
// Ensure selectedUserIdx is within bounds
if selectedUserIdx < 0 || selectedUserIdx >= len(users) {
selectedUserIdx = 0
}
LoadMessages(users[selectedUserIdx])
_, maxY := g.Size()
h := min(len(users), (maxY/2)-1)
if h <= 0 {
h = 1
}
startI := max(0, min(selectedUserIdx-(h/2), len(users)-h))
fmt.Fprint(v, "\n\n")
for i := startI; i < startI+h && i < len(users); i++ {
u := users[i]
fmt.Fprint(v, "\t\t\t\t")
iconPath := fmt.Sprintf(contactIconPathFmt, u)
render_image.RenderImage(iconPath, sidebarRowOffset+sidebarRowSpacing*(i-startI), sidebarIconColumn, sidebarIconSize, sidebarIconSize, false)
if i == selectedUserIdx {
fmt.Fprintln(v, "\x1b[7m"+u+"\x1b[0m\n")
} else {
fmt.Fprintln(v, u+"\n")
}
}
return nil
}
func nextContact(g *gocui.Gui, v *gocui.View) error {
if len(users) == 0 {
return nil
}
selectedUserIdx++
if selectedUserIdx == len(users) {
selectedUserIdx = 0
}
// Load messages for new contact
LoadMessages(users[selectedUserIdx])
// Select newest message (scroll to bottom)
if len(chatData.Messages) > 0 {
selectedMessageIdx = len(chatData.Messages) - 1
} else {
selectedMessageIdx = 0
}
if err := updateContactsView(g); err != nil {
return err
}
chatView, err := g.View("chat")
if err != nil {
log.Printf("Error getting chat view: %v", err)
return err
}
updateChatView(chatView)
return nil
}
func prevContact(g *gocui.Gui, v *gocui.View) error {
if len(users) == 0 {
return nil
}
selectedUserIdx--
if selectedUserIdx == -1 {
selectedUserIdx = len(users) - 1
}
// Load messages for new contact
LoadMessages(users[selectedUserIdx])
// Select newest message (scroll to bottom)
if len(chatData.Messages) > 0 {
selectedMessageIdx = len(chatData.Messages) - 1
} else {
selectedMessageIdx = 0
}
if err := updateContactsView(g); err != nil {
return err
}
chatView, err := g.View("chat")
if err != nil {
log.Printf("Error getting chat view: %v", err)
return err
}
updateChatView(chatView)
return nil
}