refactor(ui): pass app.App to common.Common and access config via common

Ayman Bagabas created

Change summary

internal/cmd/root.go         |  4 ++--
internal/ui/common/common.go | 12 +++++++++---
internal/ui/model/editor.go  | 11 ++++-------
internal/ui/model/sidebar.go |  2 +-
internal/ui/model/ui.go      |  9 +++------
5 files changed, 19 insertions(+), 19 deletions(-)

Detailed changes

internal/cmd/root.go 🔗

@@ -87,8 +87,8 @@ crush -y
 
 		// Set up the TUI.
 		var env uv.Environ = os.Environ()
-		com := common.DefaultCommon(app.Config())
-		ui := ui.New(com, app)
+		com := common.DefaultCommon(app)
+		ui := ui.New(com)
 		ui.QueryVersion = shouldQueryTerminalVersion(env)
 		program := tea.NewProgram(
 			ui,

internal/ui/common/common.go 🔗

@@ -3,6 +3,7 @@ package common
 import (
 	"image"
 
+	"github.com/charmbracelet/crush/internal/app"
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/ui/styles"
 	uv "github.com/charmbracelet/ultraviolet"
@@ -10,15 +11,20 @@ import (
 
 // Common defines common UI options and configurations.
 type Common struct {
-	Config *config.Config
+	App    *app.App
 	Styles *styles.Styles
 }
 
+// Config returns the configuration associated with this [Common] instance.
+func (c *Common) Config() *config.Config {
+	return c.App.Config()
+}
+
 // DefaultCommon returns the default common UI configurations.
-func DefaultCommon(cfg *config.Config) *Common {
+func DefaultCommon(app *app.App) *Common {
 	s := styles.DefaultStyles()
 	return &Common{
-		Config: cfg,
+		App:    app,
 		Styles: &s,
 	}
 }

internal/ui/model/editor.go 🔗

@@ -6,7 +6,6 @@ import (
 	"charm.land/bubbles/v2/key"
 	"charm.land/bubbles/v2/textarea"
 	tea "charm.land/bubbletea/v2"
-	"github.com/charmbracelet/crush/internal/app"
 	"github.com/charmbracelet/crush/internal/ui/common"
 )
 
@@ -61,7 +60,6 @@ func DefaultEditorKeyMap() EditorKeyMap {
 // EditorModel represents the editor UI model.
 type EditorModel struct {
 	com *common.Common
-	app *app.App
 
 	keyMap   EditorKeyMap
 	textarea *textarea.Model
@@ -73,7 +71,7 @@ type EditorModel struct {
 }
 
 // NewEditorModel creates a new instance of EditorModel.
-func NewEditorModel(com *common.Common, app *app.App) *EditorModel {
+func NewEditorModel(com *common.Common) *EditorModel {
 	ta := textarea.New()
 	ta.SetStyles(com.Styles.TextArea)
 	ta.ShowLineNumbers = false
@@ -82,7 +80,6 @@ func NewEditorModel(com *common.Common, app *app.App) *EditorModel {
 	ta.Focus()
 	e := &EditorModel{
 		com:      com,
-		app:      app,
 		keyMap:   DefaultEditorKeyMap(),
 		textarea: ta,
 	}
@@ -108,12 +105,12 @@ func (m *EditorModel) Update(msg tea.Msg) (*EditorModel, tea.Cmd) {
 	cmds = append(cmds, cmd)
 
 	// Textarea placeholder logic
-	if m.app.AgentCoordinator != nil && m.app.AgentCoordinator.IsBusy() {
+	if m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
 		m.textarea.Placeholder = m.workingPlaceholder
 	} else {
 		m.textarea.Placeholder = m.readyPlaceholder
 	}
-	if m.app.Permissions.SkipRequests() {
+	if m.com.App.Permissions.SkipRequests() {
 		m.textarea.Placeholder = "Yolo mode!"
 	}
 
@@ -183,7 +180,7 @@ func (m *EditorModel) SetSize(width, height int) {
 }
 
 func (m *EditorModel) setEditorPrompt() {
-	if m.app.Permissions.SkipRequests() {
+	if m.com.App.Permissions.SkipRequests() {
 		m.textarea.SetPromptFunc(4, m.yoloPromptFunc)
 		return
 	}

internal/ui/model/sidebar.go 🔗

@@ -32,7 +32,7 @@ func NewSidebarModel(com *common.Common) *SidebarModel {
 	return &SidebarModel{
 		com:     com,
 		compact: true,
-		cwd:     com.Config.WorkingDir(),
+		cwd:     com.Config().WorkingDir(),
 	}
 }
 

internal/ui/model/ui.go 🔗

@@ -10,7 +10,6 @@ import (
 	"charm.land/bubbles/v2/key"
 	tea "charm.land/bubbletea/v2"
 	"charm.land/lipgloss/v2"
-	"github.com/charmbracelet/crush/internal/app"
 	"github.com/charmbracelet/crush/internal/ui/common"
 	"github.com/charmbracelet/crush/internal/ui/dialog"
 	uv "github.com/charmbracelet/ultraviolet"
@@ -27,7 +26,6 @@ const (
 
 // UI represents the main user interface model.
 type UI struct {
-	app *app.App
 	com *common.Common
 
 	state uiState
@@ -52,13 +50,12 @@ type UI struct {
 }
 
 // New creates a new instance of the [UI] model.
-func New(com *common.Common, app *app.App) *UI {
+func New(com *common.Common) *UI {
 	return &UI{
-		app:    app,
 		com:    com,
 		dialog: dialog.NewOverlay(),
 		keyMap: DefaultKeyMap(),
-		editor: NewEditorModel(com, app),
+		editor: NewEditorModel(com),
 		side:   NewSidebarModel(com),
 		help:   help.New(),
 	}
@@ -183,7 +180,7 @@ func (m *UI) View() tea.View {
 	layers = append(layers, mainLayer)
 
 	v.Content = lipgloss.NewCanvas(layers...)
-	if m.sendProgressBar && m.app != nil && m.app.AgentCoordinator != nil && m.app.AgentCoordinator.IsBusy() {
+	if m.sendProgressBar && m.com.App != nil && m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
 		// HACK: use a random percentage to prevent ghostty from hiding it
 		// after a timeout.
 		v.ProgressBar = tea.NewProgressBar(tea.ProgressBarIndeterminate, rand.Intn(100))