Search: Enter now opens the first match. Properties: directory size calculates in the background instead of blocking the dialog open

This commit is contained in:
sarah committed 2026-10-09 13:46:17 +02:00
1 parent 00780a4578
commit a00047e3b9
1 file changed
+32 -4
+32 -4
View File
@@ -356,6 +356,7 @@ class Browser(ft.Row):
expand=True,
border=ft.InputBorder.OUTLINE,
on_change=self._OnSearchChanged,
on_submit=self._OnSearchSubmit,
on_focus=lambda e: self._SetShortcutsPaused(True),
on_blur=lambda e: self._SetShortcutsPaused(False),
)
@@ -1027,6 +1028,17 @@ class Browser(ft.Row):
self.SearchText = self.SearchField.value or ""
self._RefreshEntries()
def _OnSearchSubmit(self, Event: ft.ControlEvent) -> None:
"""Enter in the search field. The filter itself is already live
(on_change, every keystroke) — this is purely about Enter visibly
*doing* something instead of nothing: opens the first match, the
same "type to filter, Enter to go" pattern as VS Code's Quick Open
or a browser's address bar. (Feedback: "I can type my query, but
nothing happens when I hit enter" — true before this, the field had
no on_submit handler at all.)"""
if self.SearchText and self.CurrentEntries:
self.OpenEntry(self.CurrentEntries[0])
def _ToggleMatchCase(self, Event: ft.ControlEvent) -> None:
self.MatchCase = not self.MatchCase
self.MatchCaseButton.style = self._SearchToggleStyle(self.MatchCase)
@@ -2132,16 +2144,22 @@ class Browser(ft.Row):
ft.Text(f"Path: {Entry}", selectable=True, size=12, color=Palette.Text),
]
SizeText: Optional[ft.Text] = None
if Entry.is_dir():
try:
ItemCount = sum(1 for _ in Entry.iterdir())
Rows.append(ft.Text(f"Contains: {ItemCount} item(s)", size=12, color=Palette.Text))
except OSError:
Rows.append(ft.Text("Contains: can't read (permission denied)", size=12, color=Palette.Overlay0))
# The one place a full recursive walk still happens — a single,
# deliberate "show me" click on one directory, not every row of
# every list render (see _EntrySize).
Rows.append(ft.Text(f"Size: {HumanSize(_DirectorySize(Entry))}", size=12, color=Palette.Text))
# Feedback: "if a directory is big, entering properties takes
# forever... maybe do the calculation while showing the
# properties window?" — the dialog now opens immediately with a
# placeholder; the one remaining full recursive walk (still only
# a single, deliberate "show me" click, never per list row — see
# _EntrySize) runs off the UI thread afterward and fills this in
# once it's done, same pattern as thumbnails/folder fullness.
SizeText = ft.Text("Size: Calculating…", size=12, color=Palette.Text)
Rows.append(SizeText)
else:
Rows.append(ft.Text(f"Size: {HumanSize(Stat.st_size)}", size=12, color=Palette.Text))
@@ -2187,6 +2205,16 @@ class Browser(ft.Row):
actions=Actions,
)
self._ShowDialog(Dialog)
if SizeText is not None:
self.page.run_task(self._FillDirectorySizeAsync, Entry, SizeText)
async def _FillDirectorySizeAsync(self, Entry: Path, SizeText: ft.Text) -> None:
Size = await asyncio.to_thread(_DirectorySize, Entry)
SizeText.value = f"Size: {HumanSize(Size)}"
try:
SizeText.update()
except Exception:
pass # the dialog was closed before the walk finished — nothing to update
def _ShowAggregatePropertiesDialog(self, Entries: list[Path]) -> None:
TotalSize = 0