Implement spacer skipping in navigation tree
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user