Compressing gives no progress feedback. Drop a 2.6 GB folder on the Quick Compress
window or the start page's compress area and nothing happens on screen until the
archive appears — the UI stays responsive, but there is no bar, no byte count, and
no signal that it finished.
Extraction already has all of this: ExtractionProgressCenter drives a window that
auto-shows on an active job, shows a bar, a speed graph and an ETA, auto-closes when
done, and stays open on failure. Compression should reuse it.
Why this is mostly plumbing
ExtractionJob is a byte-transfer model, not an extraction-specific one —
archiveName, destination, itemCount, totalBytes, completedBytes,
state {running, done, failed, cancelled}, speed samples, ETA.
The data already lines up. The center takes:
reportEngineProgress(_ id: UUID, completed: Int64, total: Int64)
and ArchiveState.save() already receives exactly that from 7-Zip, then discards it:
let onWriteProgress: @Sendable (UInt64, UInt64) -> Bool = { completed, total in
let pct = Int((completed * 100) / total) // bytes thrown away here
The progress view needs no wording changes either: its only localized string is
"\(formatDuration(remaining)) left". Everything else is names, sizes and speeds.
Scope
Both surfaces are affected: the Quick Compress window and the start page's compress
area.
Deliberately out of scope
Each of these spills past the plumbing and is worth its own decision:
- Naming. Everything is
Extraction*, including ExtractionProgressCenter.shared.
Compression joining it either lives with the name or forces a rename across every
extraction call site.
- Quit guard.
applicationShouldTerminate refuses on hasActiveJobs with
"An extraction is still in progress". Compress jobs would inherit that wording —
right behaviour, wrong sentence.
- Cancellation. Wireable:
save()'s progress callback returns Bool, and false
aborts the write. But that leaves a partial archive on disk to clean up, which is
new behaviour rather than reuse.
DropJob becomes redundant once the center tracks compress jobs — the drop
window's own row model duplicates it.
Compressing gives no progress feedback. Drop a 2.6 GB folder on the Quick Compress
window or the start page's compress area and nothing happens on screen until the
archive appears — the UI stays responsive, but there is no bar, no byte count, and
no signal that it finished.
Extraction already has all of this:
ExtractionProgressCenterdrives a window thatauto-shows on an active job, shows a bar, a speed graph and an ETA, auto-closes when
done, and stays open on failure. Compression should reuse it.
Why this is mostly plumbing
ExtractionJobis a byte-transfer model, not an extraction-specific one —archiveName,destination,itemCount,totalBytes,completedBytes,state {running, done, failed, cancelled}, speed samples, ETA.The data already lines up. The center takes:
and
ArchiveState.save()already receives exactly that from 7-Zip, then discards it:The progress view needs no wording changes either: its only localized string is
"\(formatDuration(remaining)) left". Everything else is names, sizes and speeds.Scope
ArchiveState.save()reports bytes, not just a percentageDropCompressorcallsbegin()/finish()on the centertotalBytesfrom the dropped files, or passniland letengineTotalBytessupersede it once the engine reports (the model alreadyhandles both)
successes also hides
.running, so theProgressViewinDropJobRowcannever appear
Both surfaces are affected: the Quick Compress window and the start page's compress
area.
Deliberately out of scope
Each of these spills past the plumbing and is worth its own decision:
Extraction*, includingExtractionProgressCenter.shared.Compression joining it either lives with the name or forces a rename across every
extraction call site.
applicationShouldTerminaterefuses onhasActiveJobswith"An extraction is still in progress". Compress jobs would inherit that wording —
right behaviour, wrong sentence.
save()'s progress callback returnsBool, andfalseaborts the write. But that leaves a partial archive on disk to clean up, which is
new behaviour rather than reuse.
DropJobbecomes redundant once the center tracks compress jobs — the dropwindow's own row model duplicates it.