mirror of
https://git.srhtnin.garden/sarah/SaraFem.git
synced 2026-10-13 18:18:11 +02:00
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:
1 parent
00780a4578
commit
a00047e3b9
1 file changed
+32
-4
+32
-4
@@ -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
|
||||
|
||||
Reference in new issue
Block a user