fix: SFTP auto-refresh after file transfer
- Added program *tea.Program to SFTPBrowserTab and Model
- SetProgram() allows goroutines to send messages to Bubble Tea
- After transfer: program.Send(sftpRefreshMsg{}) triggers re-render
- Model stores program reference, passes to SFTP tab on creation
This commit is contained in:
@@ -53,6 +53,12 @@
|
|||||||
- Auto-refresh destination pane after transfer completes
|
- Auto-refresh destination pane after transfer completes
|
||||||
- Success message shown for 1 second before clearing
|
- Success message shown for 1 second before clearing
|
||||||
|
|
||||||
|
### SFTP Auto-Refresh Fix
|
||||||
|
- Added `program *tea.Program` field to SFTPBrowserTab and Model
|
||||||
|
- `SetProgram()` method allows goroutines to send messages to Bubble Tea
|
||||||
|
- After transfer: `t.program.Send(sftpRefreshMsg{})` triggers re-render
|
||||||
|
- Model stores program reference, passes it to SFTP tab on creation
|
||||||
|
|
||||||
## v1.0.0 (2025-01-30)
|
## v1.0.0 (2025-01-30)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ func runTUI(cmd *cobra.Command, args []string) error {
|
|||||||
model.LoadHosts(hosts)
|
model.LoadHosts(hosts)
|
||||||
|
|
||||||
p := tea.NewProgram(model)
|
p := tea.NewProgram(model)
|
||||||
|
model.SetProgram(p)
|
||||||
if _, err := p.Run(); err != nil {
|
if _, err := p.Run(); err != nil {
|
||||||
return fmt.Errorf("failed to run TUI: %w", err)
|
return fmt.Errorf("failed to run TUI: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ type SFTPBrowserTab struct {
|
|||||||
transferring bool
|
transferring bool
|
||||||
transferMsg string
|
transferMsg string
|
||||||
|
|
||||||
|
program *tea.Program
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
}
|
}
|
||||||
@@ -98,6 +100,10 @@ func NewSFTPBrowserTab(host *models.Host, dataDir string) *SFTPBrowserTab {
|
|||||||
|
|
||||||
func (t *SFTPBrowserTab) Name() string { return "SFTP: " + t.host.Name }
|
func (t *SFTPBrowserTab) Name() string { return "SFTP: " + t.host.Name }
|
||||||
|
|
||||||
|
func (t *SFTPBrowserTab) SetProgram(p *tea.Program) {
|
||||||
|
t.program = p
|
||||||
|
}
|
||||||
|
|
||||||
func (t *SFTPBrowserTab) Init() tea.Cmd {
|
func (t *SFTPBrowserTab) Init() tea.Cmd {
|
||||||
go t.connect()
|
go t.connect()
|
||||||
go t.refreshLocal()
|
go t.refreshLocal()
|
||||||
@@ -497,11 +503,21 @@ func (t *SFTPBrowserTab) copyFile(srcType, dstType paneType, srcPath, dstPath, n
|
|||||||
t.refreshLocal()
|
t.refreshLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trigger re-render in Bubble Tea
|
||||||
|
if t.program != nil {
|
||||||
|
t.program.Send(sftpRefreshMsg{})
|
||||||
|
}
|
||||||
|
|
||||||
// Clear success message after brief delay
|
// Clear success message after brief delay
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
t.transferMsg = ""
|
t.transferMsg = ""
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
|
|
||||||
|
// Trigger re-render again after clearing message
|
||||||
|
if t.program != nil {
|
||||||
|
t.program.Send(sftpRefreshMsg{})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadFile(client *sftp.Client, remotePath, localPath string, progressFn func(int64)) error {
|
func downloadFile(client *sftp.Client, remotePath, localPath string, progressFn func(int64)) error {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ type Model struct {
|
|||||||
Error error
|
Error error
|
||||||
Quit bool
|
Quit bool
|
||||||
dataDir string
|
dataDir string
|
||||||
|
program *tea.Program
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new TUI model
|
// New creates a new TUI model
|
||||||
@@ -47,6 +48,11 @@ func (m *Model) Init() tea.Cmd {
|
|||||||
return m.tabs.Init()
|
return m.tabs.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProgram stores a reference to the tea.Program for sending messages from goroutines
|
||||||
|
func (m *Model) SetProgram(p *tea.Program) {
|
||||||
|
m.program = p
|
||||||
|
}
|
||||||
|
|
||||||
// Update handles messages and updates the model
|
// Update handles messages and updates the model
|
||||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
@@ -82,6 +88,9 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
case openSFTPMsg:
|
case openSFTPMsg:
|
||||||
tab := NewSFTPBrowserTab(msg.host, m.dataDir)
|
tab := NewSFTPBrowserTab(msg.host, m.dataDir)
|
||||||
|
if m.program != nil {
|
||||||
|
tab.SetProgram(m.program)
|
||||||
|
}
|
||||||
cmd := m.tabs.Add(tab)
|
cmd := m.tabs.Add(tab)
|
||||||
return m, cmd
|
return m, cmd
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user