diff --git a/cmd/tui/main.go b/cmd/tui/main.go index c4f8118..83eaf0a 100644 --- a/cmd/tui/main.go +++ b/cmd/tui/main.go @@ -107,6 +107,7 @@ type model struct { rooms []string // "general" always first; DM rooms appended activeRoom int messages map[string][]entry + unread map[string]bool // rooms with messages since last viewed peers map[proto.PeerID]string // connected peers: id → alias peerOrder []proto.PeerID @@ -131,6 +132,7 @@ func newModel(ipcPort int, network string) model { networkName: network, rooms: []string{"general"}, messages: make(map[string][]entry), + unread: make(map[string]bool), peers: make(map[proto.PeerID]string), input: ti, status: "connecting…", @@ -215,9 +217,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m, cmds = m.doSend(cmds) case msg.Type == tea.KeyTab: m.activeRoom = (m.activeRoom + 1) % len(m.rooms) + delete(m.unread, m.activeRoomName()) m = m.refreshViewport() case msg.Type == tea.KeyShiftTab: m.activeRoom = (m.activeRoom - 1 + len(m.rooms)) % len(m.rooms) + delete(m.unread, m.activeRoomName()) m = m.refreshViewport() default: var tiCmd tea.Cmd @@ -303,6 +307,9 @@ func (m model) applyEvent(evt proto.IpcMessage) model { } m.messages[msg.Room] = append(m.messages[msg.Room], e) m = m.addRoom(msg.Room) + if msg.Room != m.activeRoomName() { + m.unread[msg.Room] = true + } m = m.refreshViewport() } } @@ -483,7 +490,11 @@ func (m model) renderRooms(boxH int) string { if i == m.activeRoom { lines = append(lines, styleActive.Width(innerW).Render("▶ "+label)) } else { - lines = append(lines, styleRoom.Width(innerW).Render(" "+label)) + prefix := " " + if m.unread[room] { + prefix = "* " + } + lines = append(lines, styleRoom.Width(innerW).Render(prefix+label)) } } for len(lines) < contentH {