fix: resolve navigation and file content loading issues

This commit is contained in:
Greg Pomerantz 2026-06-02 10:23:43 -04:00
parent ec87e95b35
commit b838b4c75f
5 changed files with 69 additions and 13 deletions

View File

@ -1,6 +1,7 @@
package browser package browser
import ( import (
"fmt"
"path/filepath" "path/filepath"
"strings" "strings"
@ -76,9 +77,11 @@ func HandleBrowserTap(bm *BrowserManager, s *BrowserState, index int) {
} else { } else {
// Open file // Open file
s.SelectedIndex = index s.SelectedIndex = index
fmt.Printf("HandleBrowserTap: Opening file %s\n", entry.Path)
ui.OpenFile(entry.Path) ui.OpenFile(entry.Path)
// Dispatch ReadFileTask to the worker pool // Dispatch ReadFileTask to the worker pool
task := pool.NewReadFileTask(entry.Path, bm.fs) task := pool.NewReadFileTask(entry.Path, bm.fs)
fmt.Printf("HandleBrowserTap: Dispatching ReadFileTask for %s\n", entry.Path)
bm.workerPool.Dispatch(task) bm.workerPool.Dispatch(task)
} }
} }

View File

@ -15,7 +15,6 @@ type BrowserManager struct {
state *BrowserState state *BrowserState
workerPool *pool.WorkerPool workerPool *pool.WorkerPool
fs *mock.FileSystem fs *mock.FileSystem
dirPath string
} }
func NewBrowserManager(state *BrowserState, wp *pool.WorkerPool, fs *mock.FileSystem) (*BrowserManager, error) { func NewBrowserManager(state *BrowserState, wp *pool.WorkerPool, fs *mock.FileSystem) (*BrowserManager, error) {
@ -28,7 +27,7 @@ func NewBrowserManager(state *BrowserState, wp *pool.WorkerPool, fs *mock.FileSy
func (bm *BrowserManager) NavigateTo(dirPath string) { func (bm *BrowserManager) NavigateTo(dirPath string) {
fmt.Printf("NavigateTo: %s\n", dirPath) fmt.Printf("NavigateTo: %s\n", dirPath)
bm.dirPath = dirPath bm.state.CurrentPath = dirPath
navigateToDirectory(bm.state, dirPath) navigateToDirectory(bm.state, dirPath)
bm.state.Loading = true bm.state.Loading = true
@ -57,7 +56,7 @@ func (bm *BrowserManager) OnScroll() {
// Dispatch LoadPagesTask for unloaded pages // Dispatch LoadPagesTask for unloaded pages
if len(pagesToLoad) > 0 { if len(pagesToLoad) > 0 {
fmt.Printf("OnScroll: Dispatching LoadPagesTask for pages %v\n", pagesToLoad) fmt.Printf("OnScroll: Dispatching LoadPagesTask for pages %v\n", pagesToLoad)
task := pool.NewLoadPagesTask(bm.dirPath, pagesToLoad, bm.fs) task := pool.NewLoadPagesTask(bm.state.CurrentPath, pagesToLoad, bm.fs)
bm.workerPool.Dispatch(task) bm.workerPool.Dispatch(task)
} }
@ -96,9 +95,9 @@ func (bm *BrowserManager) handleBuildIndexSuccess(result pool.Result) {
var browserEntries []Entry var browserEntries []Entry
// Add ".." entry if not at root // Add ".." entry if not at root
if bm.dirPath != "/" && bm.dirPath != "." { if bm.state.CurrentPath != "/" && bm.state.CurrentPath != "." {
browserEntries = append(browserEntries, Entry{ browserEntries = append(browserEntries, Entry{
Path: filepath.Dir(bm.dirPath), Path: filepath.Dir(bm.state.CurrentPath),
Name: "..", Name: "..",
Size: 0, Size: 0,
ModTime: time.Now(), ModTime: time.Now(),
@ -109,7 +108,7 @@ func (bm *BrowserManager) handleBuildIndexSuccess(result pool.Result) {
for _, e := range entries { for _, e := range entries {
info, _ := e.Info() info, _ := e.Info()
browserEntries = append(browserEntries, Entry{ browserEntries = append(browserEntries, Entry{
Path: filepath.Join(bm.dirPath, e.Name()), Path: filepath.Join(bm.state.CurrentPath, e.Name()),
Name: e.Name(), Name: e.Name(),
Size: info.Size(), Size: info.Size(),
ModTime: info.ModTime(), ModTime: info.ModTime(),
@ -119,7 +118,7 @@ func (bm *BrowserManager) handleBuildIndexSuccess(result pool.Result) {
// Build the sorted index with position maps // Build the sorted index with position maps
bm.state.SortIndex = &DirectoryIndex{ bm.state.SortIndex = &DirectoryIndex{
Path: bm.dirPath, Path: bm.state.CurrentPath,
EntryCount: len(browserEntries), EntryCount: len(browserEntries),
Entries: browserEntries, Entries: browserEntries,
SortOrders: make(map[string][]int), SortOrders: make(map[string][]int),
@ -159,7 +158,7 @@ func (bm *BrowserManager) handleError(result pool.Result) {
bm.state.Loading = false bm.state.Loading = false
// For now, just reset the state or log the error. // For now, just reset the state or log the error.
// In production, we'd show a toast or error message. // In production, we'd show a toast or error message.
if bm.state.CurrentPath == bm.dirPath { if bm.state.CurrentPath == bm.state.CurrentPath {
bm.state.Reset() bm.state.Reset()
} }
} }

View File

@ -28,10 +28,6 @@ func TestNewBrowserManager(t *testing.T) {
if bm.state != state { if bm.state != state {
t.Errorf("BrowserManager.state = %p, want %p", bm.state, state) t.Errorf("BrowserManager.state = %p, want %p", bm.state, state)
} }
if bm.dirPath != "" {
t.Errorf("BrowserManager.dirPath = %q, want empty string", bm.dirPath)
}
} }
// TestNavigateTo verifies that NavigateTo dispatches a BuildIndexTask // TestNavigateTo verifies that NavigateTo dispatches a BuildIndexTask

View File

@ -93,6 +93,7 @@ func NewBrowserState() *BrowserState {
SelectedIndex: -1, SelectedIndex: -1,
SortMode: SortModeNameAsc, // Default sort mode SortMode: SortModeNameAsc, // Default sort mode
EntryHeight: 48.0, EntryHeight: 48.0,
CurrentPath: "/",
} }
} }
@ -145,9 +146,10 @@ func (s *BrowserState) GetScrollIndex() int {
// Reset clears all browser state for navigation. // Reset clears all browser state for navigation.
func (s *BrowserState) Reset() { func (s *BrowserState) Reset() {
s.CurrentPath = ""
s.Pages = make(map[int]*Page) s.Pages = make(map[int]*Page)
s.ScrollOffset = 0 s.ScrollOffset = 0
s.SelectedIndex = -1 s.SelectedIndex = -1
s.SearchResults = nil s.SearchResults = nil
s.Query = "" s.Query = ""
} }

View File

@ -0,0 +1,56 @@
package editor
import (
"testing"
"time"
"pad/internal/browser"
"pad/internal/io/pool"
"pad/internal/io/pool/mock"
)
func TestOpenFileIntegration(t *testing.T) {
// 1. Setup Logic
// We need to re-create the setup logic to control the environment
mockFS := mock.NewFileSystem()
// Add a file
filename := "/README.md"
content := "Hello World"
mockFS.AddFile(filename, []byte(content), time.Now())
wp := pool.NewWorkerPool(4)
wp.Start()
// Initialize state manually
state := NewState()
TheState = state // Initialize global state
state.Browser.CurrentPath = "/"
_, _ = browser.NewBrowserManager(&state.Browser, wp, mockFS)
// 2. Simulate File Tap
// We need to trigger the file tap, which dispatches a ReadFileTask
// and calls OpenFile(filename).
// OpenFile sets filename and changes page
OpenFile(filename)
// Dispatch ReadFileTask
task := pool.NewReadFileTask(filename, mockFS)
wp.Dispatch(task)
// 3. Process the Result
// The logic loop would normally do this, we do it manually for the test
res := <-wp.ResultChan()
// Apply result
if res.Success {
if content, ok := res.Data.([]byte); ok {
state.ActiveFileContent = string(content)
}
}
// 4. Assert
if state.ActiveFileContent != content {
t.Errorf("Expected content %q, got %q", content, state.ActiveFileContent)
}
}