fix: consolidate file picker image select logic for all three usages

tauraamui created

Change summary

internal/tui/components/chat/editor/editor.go                 | 11 +++++
internal/tui/components/dialogs/filepicker/filepicker.go      |  6 +-
internal/tui/components/dialogs/filepicker/filepicker_test.go |  4 
3 files changed, 16 insertions(+), 5 deletions(-)

Detailed changes

internal/tui/components/chat/editor/editor.go 🔗

@@ -240,6 +240,10 @@ func isExtOfAllowedImageType(path string) bool {
 
 type ResolveAbs func(path string) (string, error)
 
+func onPaste(msg tea.PasteMsg) tea.Msg {
+	return filepicker.OnPaste(filepicker.ResolveFS, string(msg))
+}
+
 func activeModelHasImageSupport() (bool, string) {
 	agentCfg := config.Get().Agents["coder"]
 	model := config.Get().GetModelByType(agentCfg.Model)
@@ -279,6 +283,13 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	case OpenEditorMsg:
 		m.textarea.SetValue(msg.Text)
 		m.textarea.MoveToEnd()
+	case tea.PasteMsg:
+		agentCfg := config.Get().Agents["coder"]
+		model := config.Get().GetModelByType(agentCfg.Model)
+		if !model.SupportsImages {
+			return m, util.ReportWarn("File attachments are not supported by the current model: " + model.Name)
+		}
+		return m, util.CmdHandler(onPaste(msg)) // inject fsys accessible from PWD
 	case commands.ToggleYoloModeMsg:
 		m.setEditorPrompt()
 		return m, nil

internal/tui/components/dialogs/filepicker/filepicker.go 🔗

@@ -130,7 +130,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		// Get the path of the selected file.
 		return m, tea.Sequence(
 			util.CmdHandler(dialogs.CloseDialogMsg{}),
-			onPaste(resolveFS, path),
+			OnPaste(ResolveFS, path),
 		)
 	}
 	m.image, cmd = m.image.Update(msg)
@@ -138,11 +138,11 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	return m, tea.Batch(cmds...)
 }
 
-func resolveFS(baseDirPath string) fs.FS {
+func ResolveFS(baseDirPath string) fs.FS {
 	return os.DirFS(baseDirPath)
 }
 
-func onPaste(resolveFsys func(path string) fs.FS, path string) func() tea.Msg {
+func OnPaste(resolveFsys func(path string) fs.FS, path string) func() tea.Msg {
 	fsys := resolveFsys(filepath.Dir(path))
 	name := filepath.Base(path)
 	return func() tea.Msg {

internal/tui/components/dialogs/filepicker/filepicker_test.go 🔗

@@ -35,7 +35,7 @@ func TestOnPasteMockFSWithValidPath(t *testing.T) {
 	}
 
 	// Test with the first file
-	cmd := onPaste(resolveTestFS, makePathCanonical("/home/testuser/images/image1.png"))
+	cmd := OnPaste(resolveTestFS, makePathCanonical("/home/testuser/images/image1.png"))
 	msg := cmd()
 
 	assert.Equal(t, makePathCanonical("/home/testuser/images"), mockedFSPath)
@@ -61,7 +61,7 @@ func TestOnPasteMockFSWithInvalidPath(t *testing.T) {
 	}
 
 	// Test with the first file
-	cmd, ok := onPaste(resolveTestFS, makePathCanonical("/home/testuser/images/nonexistent.png"))().(tea.Cmd)
+	cmd, ok := OnPaste(resolveTestFS, makePathCanonical("/home/testuser/images/nonexistent.png"))().(tea.Cmd)
 	require.True(t, ok)
 
 	msg := cmd()