feat(studio): real install progress in the store dialog and the wizard
Both surfaces showed an indeterminate spinner for the whole install, because the hub only offered a unary call. They now follow HubAdmin/InstallModuleStream: - The store's install dialog shows the phase in plain language, the overall percentage, megabytes while the size is known, and a seconds counter. The counter is the second, independent signal: it keeps running even if the hub goes quiet, which is what tells 'slow' apart from 'stuck'. - The setup wizard shows the same bar per module instead of a spinner inside the button. - New strings in both locales for the phases, the byte line and the elapsed counter. progress_bar_visual_test writes the four waiting states to build/progress/ in either theme, so the result can be judged without launching the desktop app. Writing it turned up a real trap worth recording: awaiting toImage() directly in a widget test leaves the binding waiting forever - the file passed in six seconds, then sat there until the ten-minute timeout failed the whole suite. tester.runAsync() is the fix. Full suite: 186 passed. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
2bc556e0f5
commit
1549334767
9 changed files with 490 additions and 74 deletions
|
|
@ -972,6 +972,34 @@ class HubService {
|
|||
return (name: r.name, version: r.version);
|
||||
}
|
||||
|
||||
/// Install a module while watching it happen.
|
||||
///
|
||||
/// Emits one [InstallStep] per phase change and, during the
|
||||
/// download, as bytes arrive. Completes when the install
|
||||
/// succeeds; throws the hub's error otherwise, exactly like
|
||||
/// [installModule]. [onFinished] receives name and version.
|
||||
Stream<InstallStep> installModuleStreaming({
|
||||
required String source,
|
||||
void Function(({String name, String version}) result)? onFinished,
|
||||
}) {
|
||||
return _client
|
||||
.installModuleStreaming(
|
||||
source: source,
|
||||
onFinished: (r) => onFinished?.call((name: r.name, version: r.version)),
|
||||
)
|
||||
.map(
|
||||
(u) => InstallStep(
|
||||
phase: u.phase,
|
||||
// `percent` is absent while the extent is unknowable; the
|
||||
// bar shows that as indeterminate rather than as zero.
|
||||
percent: u.hasPercent() ? u.percent : null,
|
||||
bytesReceived: u.bytesReceived.toInt(),
|
||||
bytesTotal: u.bytesTotal.toInt(),
|
||||
phaseDone: u.phaseDone,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// The shared hub's project registry (`general` first) — the
|
||||
/// lightweight labels grouping flows, runs, approvals and audit
|
||||
/// events. Sealed areas never appear here: they are their own
|
||||
|
|
@ -1545,6 +1573,40 @@ class ModuleSummary {
|
|||
/// slug plus renamable presentation metadata. `isolation` is
|
||||
/// `open` (pure label) or `protected` (logically separated — no
|
||||
/// hard process barrier; every UI keeps that honest wording).
|
||||
/// One observation while a module installs.
|
||||
///
|
||||
/// [percent] is the overall value across all phases and may stand
|
||||
/// still for a long time during a big download; that is expected and
|
||||
/// is why the bar carries its own sign of life. A null [percent]
|
||||
/// means the extent isn't knowable yet.
|
||||
class InstallStep {
|
||||
/// Stable phase id: `resolve`, `download` or `install`.
|
||||
final String phase;
|
||||
|
||||
/// Overall progress 0..100, or null while indeterminate.
|
||||
final double? percent;
|
||||
|
||||
/// Bytes received so far (download phase only).
|
||||
final int bytesReceived;
|
||||
|
||||
/// Total bytes announced by the server; 0 when unknown.
|
||||
final int bytesTotal;
|
||||
|
||||
/// This phase just finished.
|
||||
final bool phaseDone;
|
||||
|
||||
const InstallStep({
|
||||
required this.phase,
|
||||
required this.percent,
|
||||
required this.bytesReceived,
|
||||
required this.bytesTotal,
|
||||
required this.phaseDone,
|
||||
});
|
||||
|
||||
/// True while the server told us how big the download is.
|
||||
bool get hasSize => bytesTotal > 0;
|
||||
}
|
||||
|
||||
class ProjectRef {
|
||||
final String slug;
|
||||
final String name;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue