feat(ui): dialog: wrap navigation from last to first and vice versa

Ayman Bagabas created

Change summary

internal/ui/dialog/commands.go | 10 ++++++++++
internal/ui/dialog/sessions.go | 10 ++++++++++
internal/ui/list/list.go       | 16 ++++++++++++++++
3 files changed, 36 insertions(+)

Detailed changes

internal/ui/dialog/commands.go 🔗

@@ -133,10 +133,20 @@ func (c *Commands) Update(msg tea.Msg) tea.Msg {
 			return CloseMsg{}
 		case key.Matches(msg, c.keyMap.Previous):
 			c.list.Focus()
+			if c.list.IsSelectedFirst() {
+				c.list.SelectLast()
+				c.list.ScrollToBottom()
+				break
+			}
 			c.list.SelectPrev()
 			c.list.ScrollToSelected()
 		case key.Matches(msg, c.keyMap.Next):
 			c.list.Focus()
+			if c.list.IsSelectedLast() {
+				c.list.SelectFirst()
+				c.list.ScrollToTop()
+				break
+			}
 			c.list.SelectNext()
 			c.list.ScrollToSelected()
 		case key.Matches(msg, c.keyMap.Select):

internal/ui/dialog/sessions.go 🔗

@@ -89,10 +89,20 @@ func (s *Session) Update(msg tea.Msg) tea.Msg {
 			return CloseMsg{}
 		case key.Matches(msg, s.keyMap.Previous):
 			s.list.Focus()
+			if s.list.IsSelectedFirst() {
+				s.list.SelectLast()
+				s.list.ScrollToBottom()
+				break
+			}
 			s.list.SelectPrev()
 			s.list.ScrollToSelected()
 		case key.Matches(msg, s.keyMap.Next):
 			s.list.Focus()
+			if s.list.IsSelectedLast() {
+				s.list.SelectFirst()
+				s.list.ScrollToTop()
+				break
+			}
 			s.list.SelectNext()
 			s.list.ScrollToSelected()
 		case key.Matches(msg, s.keyMap.Select):

internal/ui/list/list.go 🔗

@@ -398,6 +398,22 @@ func (l *List) SetSelected(index int) {
 	}
 }
 
+// Selected returns the index of the currently selected item. It returns -1 if
+// no item is selected.
+func (l *List) Selected() int {
+	return l.selectedIdx
+}
+
+// IsSelectedFirst returns whether the first item is selected.
+func (l *List) IsSelectedFirst() bool {
+	return l.selectedIdx == 0
+}
+
+// IsSelectedLast returns whether the last item is selected.
+func (l *List) IsSelectedLast() bool {
+	return l.selectedIdx == len(l.items)-1
+}
+
 // SelectPrev selects the previous item in the list.
 func (l *List) SelectPrev() {
 	if l.selectedIdx > 0 {