Upload progress

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
sarahandClaude Opus 5.5 committed 2026-10-13 13:37:47 +02:00
1 parent db81507b7c
commit 843ad1986e
9 files changed
+259 -78

No files matched your search

+34 -4
View File
@@ -84,6 +84,11 @@ class Browser(ft.Column):
spacing=8,
tight=True,
)
# Shown while uploading: which file, how far (Uploads' progress).
self.UploadText = ft.Text("", size=12, color=Palette.Overlay0)
self.UploadBar = ft.ProgressBar(value=0, color=Palette.Mauve, bgcolor=Palette.Surface0, bar_height=4)
self.UploadRow = ft.Container(ft.Column([self.UploadText, self.UploadBar], spacing=4),
padding=ft.Padding.symmetric(horizontal=8, vertical=6), visible=False)
self.EntryList = ft.ListView(expand=True, spacing=2)
# One shared popup host, opened programmatically (see _RequestMenu).
# Its built-in triggers can't be switched off, so they're set to
@@ -103,6 +108,7 @@ class Browser(ft.Column):
# and the breadcrumbs get the rest (and wrap when it's tight).
ft.Row([ft.Container(self.Breadcrumbs, padding=8, expand=True), ft.Container(self.ActionsToolbar, padding=8)]),
ft.Divider(height=1, color=Palette.Surface1),
self.UploadRow,
self.FileArea,
]
self._ShowList(Update=False)
@@ -600,19 +606,43 @@ class Browser(ft.Column):
return
Saved, Failed = 0, []
Server = self.TheApp.Server
for LocalFile in Paths:
if Server:
self.TheApp.Notify(f"Uploading {LocalFile.name} ({HumanSize(LocalFile.stat().st_size)})...", "info")
Sizes = [LocalFile.stat().st_size if LocalFile.is_file() else 0 for LocalFile in Paths]
Total = sum(Sizes)
Verb = "Uploading" if Server else "Copying in"
Shown = [-1, -1] # (file, percent) on screen: redraw only when it changes
def ShowProgress(Index: int, Fraction: float) -> None:
Done = sum(Sizes[:Index]) + Sizes[Index] * Fraction
Percent = int(Done / Total * 100) if Total else 100
if Shown == [Index, Percent]:
return
Shown[:] = [Index, Percent]
Of = f" ({Index + 1} of {len(Paths)})" if len(Paths) > 1 else ""
self.UploadText.value = (f"{Verb} {Paths[Index].name}{Of}: {Percent}% "
f"({HumanSize(int(Done))} of {HumanSize(Total)})")
self.UploadBar.value = Done / Total if Total else 1
self.UploadRow.update()
self.UploadRow.visible = True
for Index, LocalFile in enumerate(Paths):
ShowProgress(Index, 0)
try:
await asyncio.to_thread(self.TheApp.Source.Upload, self.Root, self.Path, LocalFile)
# Large files go up in chunks and report each one; small ones in one go.
await asyncio.to_thread(self.TheApp.Source.Upload, self.Root, self.Path, LocalFile,
lambda Fraction, I=Index: ShowProgress(I, Fraction))
Saved += 1
except SourceError as Error:
if Error.Status == 401:
self.UploadRow.visible = False
self.UploadRow.update()
self.TheApp.HandleError(Error)
return
Failed.append(f"{LocalFile.name}: {Error}")
except OSError as Error:
Failed.append(f"{LocalFile.name}: {Error}")
self.UploadRow.visible = False
self.UploadRow.update()
self.Refresh()
if Failed:
self.TheApp.Notify("Couldn't upload " + "; ".join(Failed), "error")