task<T> method
Runs work while showing a spinner. The future's value is returned;
thrown errors propagate to the caller after the terminal is restored.
Implementation
Future<T> task<T>(
String description,
Future<T> Function() work,
) async {
T? result;
Object? caughtError;
StackTrace? caughtStack;
final key = Key.symbol(#__inline_task);
await runTerminal<Object?>(
initialState: null,
theme: _theme,
terminal: _terminal(),
mode: const RenderMode.flow(height: 1, autoGrow: true),
allowNonInteractive: _allowNonInteractive,
enableMouse: false,
onEvent: (_, event, handle) {
if (event is AsyncResolvedEvent && event.key == key) {
handle.stop();
}
},
render: (ctx, _) {
ctx.draw(
Async<T>(
key: key,
future: () async {
try {
final v = await work();
result = v;
return v;
} catch (e, st) {
caughtError = e;
caughtStack = st;
rethrow;
}
},
onLoading: () => Spinner(label: description),
onSuccess: (_) => Text(
'✓ $description',
style: Style(fg: ctx.theme.colors.success, bold: true),
),
onError: (e, _) => Text(
'✗ $description: $e',
style: Style(fg: ctx.theme.colors.error, bold: true),
),
),
Rect(ctx.area.x, ctx.area.y, ctx.area.width, 1),
);
},
);
if (caughtError != null) {
Error.throwWithStackTrace(
caughtError!, caughtStack ?? StackTrace.current);
}
return result as T;
}