Implement spacer skipping in navigation tree

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-17 00:58:55 +01:00
parent 3a57f41fc2
commit c1bb24473e

View File

@@ -31,6 +31,14 @@ type ListItem struct {
User *UserNode
}
func (l ListItem) IsSpacer() bool {
if l.IsUser || l.Channel == nil {
return false
}
// TeamSpeak spacers usually look like [spacer0], [*spacer1], etc.
return strings.Contains(strings.ToLower(l.Channel.Name), "[spacer")
}
// ChatMessage represents a message in the chat
type ChatMessage struct {
Time time.Time
@@ -503,6 +511,35 @@ func (m *Model) updateChannelList(channels []*ts3client.Channel) {
}
}
}
// Ensure selectedIdx is valid (not on a spacer)
if len(m.items) > 0 {
if m.selectedIdx >= len(m.items) {
m.selectedIdx = len(m.items) - 1
}
// If current is a spacer, find next valid one
if m.items[m.selectedIdx].IsSpacer() {
found := false
// Try going down
for i := m.selectedIdx; i < len(m.items); i++ {
if !m.items[i].IsSpacer() {
m.selectedIdx = i
found = true
break
}
}
// If not found, try going up
if !found {
for i := m.selectedIdx; i >= 0; i-- {
if !m.items[i].IsSpacer() {
m.selectedIdx = i
break
}
}
}
}
}
}
func (m *Model) handleKeyPress(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
@@ -673,17 +710,37 @@ func (m *Model) handleUserViewKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
func (m *Model) handleChannelKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
switch msg.String() {
case "up", "k":
if m.selectedIdx > 0 {
for m.selectedIdx > 0 {
m.selectedIdx--
if !m.items[m.selectedIdx].IsSpacer() {
break
}
// If we hit the top and it's a spacer, we might need to go down to find the first valid one
if m.selectedIdx == 0 && m.items[m.selectedIdx].IsSpacer() {
// Search forward for the first valid one
for i := 0; i < len(m.items); i++ {
if !m.items[i].IsSpacer() {
m.selectedIdx = i
break
}
}
break
}
}
case "down", "j":
if m.selectedIdx < len(m.items)-1 {
for m.selectedIdx < len(m.items)-1 {
m.selectedIdx++
if !m.items[m.selectedIdx].IsSpacer() {
break
}
}
case "enter":
// Join selected channel OR open user view
if m.selectedIdx < len(m.items) && m.client != nil {
item := m.items[m.selectedIdx]
if item.IsSpacer() {
return m, nil // Do nothing for spacers
}
if !item.IsUser {
// Channel
ch := item.Channel