diff --git a/CHANGELOG.md b/CHANGELOG.md index bd2e424..bd4a658 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,14 @@ - After transfer: `t.program.Send(sftpRefreshMsg{})` triggers re-render - Model stores program reference, passes it to SFTP tab on creation +### SFTP Bug Fixes +- Auto-refresh: clear dirCache before refresh after transfer/delete/mkdir +- Cache was stale after file operations — old entries returned instead of fresh +- Filter mode: allow command keys (c, d, n, r) and navigation (↑↓, Tab) to pass through +- Filter mode no longer blocks transfer, delete, mkdir, or pane switch +- Delete: clear cache + trigger re-render after file removal +- Mkdir: clear cache + trigger re-render after directory creation + ## v1.0.0 (2025-01-30) ### Added diff --git a/pkg/tui/sftp_browser_tab.go b/pkg/tui/sftp_browser_tab.go index 2521cda..86e7ff1 100644 --- a/pkg/tui/sftp_browser_tab.go +++ b/pkg/tui/sftp_browser_tab.go @@ -293,6 +293,10 @@ func (t *SFTPBrowserTab) Update(msg tea.Msg) (Tab, tea.Cmd) { p.filter = p.filter[:len(p.filter)-1] } return t, nil + case "tab", "up", "k", "down", "j": + // Allow navigation and pane switch in filter mode + case "c", "d", "n", "r": + // Allow commands in filter mode default: if len(msg.Runes) == 1 { p.filter += string(msg.Runes[0]) @@ -496,7 +500,15 @@ func (t *SFTPBrowserTab) copyFile(srcType, dstType paneType, srcPath, dstPath, n t.transferring = false t.mu.Unlock() - // Auto-refresh destination pane + // Auto-refresh destination pane (clear cache first) + t.mu.Lock() + if dstType == paneRemote { + delete(t.right.dirCache, t.right.cwd) + } else { + delete(t.left.dirCache, t.left.cwd) + } + t.mu.Unlock() + if dstType == paneRemote { t.refreshRemote() } else { @@ -606,10 +618,24 @@ func (t *SFTPBrowserTab) deleteItem(fullPath string, isDir bool, isRemote bool) t.transferMsg = "" t.mu.Unlock() + // Clear cache and refresh + t.mu.Lock() if isRemote { - go t.refreshRemote() + delete(t.right.dirCache, t.right.cwd) } else { - go t.refreshLocal() + delete(t.left.dirCache, t.left.cwd) + } + t.mu.Unlock() + + if isRemote { + t.refreshRemote() + } else { + t.refreshLocal() + } + + // Trigger re-render + if t.program != nil { + t.program.Send(sftpRefreshMsg{}) } } @@ -630,7 +656,17 @@ func (t *SFTPBrowserTab) mkdirRemote() { t.mu.Unlock() return } + + // Clear cache and refresh + t.mu.Lock() + delete(t.right.dirCache, cwd) + t.mu.Unlock() t.refreshRemote() + + // Trigger re-render + if t.program != nil { + t.program.Send(sftpRefreshMsg{}) + } } func (t *SFTPBrowserTab) View() string {