Progress
One progress report: how far the operation is (fraction) and what it does now (phase).
Both values live in one object, so a progress bar never shows the fraction of one report with the label of another. You read it from ProgressFuture.progress. You construct it yourself only for withProgress.
Progress(0.42f, "pages") // toString(): "Progress(42%, pages)"
Progress(null) // toString(): "Progress(indeterminate)"Content copied to clipboard
The constructor never throws. A fraction outside 0..1 is clamped, and NaN becomes null. Two reports with equal values are equal, so a StateFlow does not wake its collectors for a repeated report.
Parameters
fraction
the done part of the work, from 0f to 1f, not a percent. null means the total is not known yet (an indeterminate bar).