Implement spacer skipping in navigation tree
This commit is contained in:
@@ -31,6 +31,14 @@ type ListItem struct {
|
|||||||
User *UserNode
|
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
|
// ChatMessage represents a message in the chat
|
||||||
type ChatMessage struct {
|
type ChatMessage struct {
|
||||||
Time time.Time
|
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) {
|
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) {
|
func (m *Model) handleChannelKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||||
switch msg.String() {
|
switch msg.String() {
|
||||||
case "up", "k":
|
case "up", "k":
|
||||||
if m.selectedIdx > 0 {
|
for m.selectedIdx > 0 {
|
||||||
m.selectedIdx--
|
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":
|
case "down", "j":
|
||||||
if m.selectedIdx < len(m.items)-1 {
|
for m.selectedIdx < len(m.items)-1 {
|
||||||
m.selectedIdx++
|
m.selectedIdx++
|
||||||
|
if !m.items[m.selectedIdx].IsSpacer() {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "enter":
|
case "enter":
|
||||||
// Join selected channel OR open user view
|
// Join selected channel OR open user view
|
||||||
if m.selectedIdx < len(m.items) && m.client != nil {
|
if m.selectedIdx < len(m.items) && m.client != nil {
|
||||||
item := m.items[m.selectedIdx]
|
item := m.items[m.selectedIdx]
|
||||||
|
if item.IsSpacer() {
|
||||||
|
return m, nil // Do nothing for spacers
|
||||||
|
}
|
||||||
if !item.IsUser {
|
if !item.IsUser {
|
||||||
// Channel
|
// Channel
|
||||||
ch := item.Channel
|
ch := item.Channel
|
||||||
|
|||||||
Reference in New Issue
Block a user