fix: resolve navigation and file content loading issues
This commit is contained in:
parent
ec87e95b35
commit
b838b4c75f
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,6 +146,7 @@ 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
|
||||||
|
|
|
||||||
56
internal/editor/integration_test.go
Normal file
56
internal/editor/integration_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user