fix: make sure to make rendered string concurrency sage

Kujtim Hoxha created

Change summary

internal/tui/exp/list/list.go | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

Detailed changes

internal/tui/exp/list/list.go 🔗

@@ -3,6 +3,7 @@ package list
 import (
 	"slices"
 	"strings"
+	"sync"
 
 	"github.com/charmbracelet/bubbles/v2/key"
 	tea "github.com/charmbracelet/bubbletea/v2"
@@ -90,6 +91,7 @@ type list[T Item] struct {
 
 	renderedItems *csync.Map[string, renderedItem]
 
+	renderMu sync.Mutex
 	rendered string
 
 	movingByItem bool
@@ -328,7 +330,9 @@ func (l *list[T]) render() tea.Cmd {
 	// we are not rendering the first time
 	if l.rendered != "" {
 		// rerender everything will mostly hit cache
+		l.renderMu.Lock()
 		l.rendered, _ = l.renderIterator(0, false, "")
+		l.renderMu.Unlock()
 		if l.direction == DirectionBackward {
 			l.recalculateItemPositions()
 		}
@@ -338,9 +342,10 @@ func (l *list[T]) render() tea.Cmd {
 		}
 		return focusChangeCmd
 	}
+	l.renderMu.Lock()
 	rendered, finishIndex := l.renderIterator(0, true, "")
 	l.rendered = rendered
-
+	l.renderMu.Unlock()
 	// recalculate for the initial items
 	if l.direction == DirectionBackward {
 		l.recalculateItemPositions()
@@ -348,7 +353,10 @@ func (l *list[T]) render() tea.Cmd {
 	renderCmd := func() tea.Msg {
 		l.offset = 0
 		// render the rest
+
+		l.renderMu.Lock()
 		l.rendered, _ = l.renderIterator(finishIndex, false, l.rendered)
+		l.renderMu.Unlock()
 		// needed for backwards
 		if l.direction == DirectionBackward {
 			l.recalculateItemPositions()
@@ -357,7 +365,6 @@ func (l *list[T]) render() tea.Cmd {
 		if l.focused {
 			l.scrollToSelection()
 		}
-
 		return nil
 	}
 	return tea.Batch(focusChangeCmd, renderCmd)