using Spry;
using Inversion;
/**
* ProgressDemo - A progress bar demo for the Continuations documentation
*
* Demonstrates:
* - spry-continuation attribute for SSE
* - spry-dynamic for updatable sections
* - continuation() method for real-time updates
* - ContinuationContext API
*/
public class ProgressDemo : Component {
public int percent { get; set; default = 0; }
public string status { get; set; default = "Ready"; }
public bool is_running { get; set; default = false; }
public override string markup { get {
return """
0%Ready
""";
}}
public override async void prepare() throws Error {
this["status-text"].text_content = status;
this["percent-text"].text_content = @"$percent%";
if (is_running) {
this["start-btn"].set_attribute("disabled", "disabled");
this["start-btn"].text_content = "Running...";
} else {
this["start-btn"].remove_attribute("disabled");
this["start-btn"].text_content = percent >= 100 ? "Complete!" : "Start Task";
}
}
public async override void handle_action(string action) throws Error {
switch (action) {
case "Start":
if (!is_running && percent < 100) {
is_running = true;
status = "Starting...";
}
break;
case "Reset":
percent = 0;
status = "Ready";
is_running = false;
break;
}
}
public async override void continuation(ContinuationContext ctx) throws Error {
if (!is_running) return;
for (int i = percent; i <= 100; i += 5) {
percent = i;
if (i < 30) {
status = @"Processing... $i%";
} else if (i < 60) {
status = @"Building... $i%";
} else if (i < 90) {
status = @"Finalizing... $i%";
} else {
status = @"Almost done... $i%";
}
// Send updates via SSE to the dynamic sections
yield ctx.send_dynamic("progress-bar");
yield ctx.send_dynamic("status");
// Simulate work
Timeout.add(200, () => {
continuation.callback();
return false;
});
yield;
}
percent = 100;
status = "Complete!";
is_running = false;
yield ctx.send_dynamic("progress-bar");
yield ctx.send_dynamic("status");
}
}