|
@@ -22,6 +22,32 @@ using Spry;
|
|
|
*/
|
|
*/
|
|
|
class ProgressComponent : Component {
|
|
class ProgressComponent : Component {
|
|
|
|
|
|
|
|
|
|
+ private int _percent = 0;
|
|
|
|
|
+ private string _status = "Initializing...";
|
|
|
|
|
+
|
|
|
|
|
+ public int percent {
|
|
|
|
|
+ get { return _percent; }
|
|
|
|
|
+ set {
|
|
|
|
|
+ _percent = value;
|
|
|
|
|
+ var progress_bar = this["progress-bar"];
|
|
|
|
|
+ if (progress_bar != null) {
|
|
|
|
|
+ progress_bar.set_attribute("style", @"width: $(_percent)%");
|
|
|
|
|
+ progress_bar.text_content = @"$(_percent)%";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public string status {
|
|
|
|
|
+ get { return _status; }
|
|
|
|
|
+ set {
|
|
|
|
|
+ _status = value;
|
|
|
|
|
+ var status_el = this["status"];
|
|
|
|
|
+ if (status_el != null) {
|
|
|
|
|
+ status_el.text_content = @"Status: $(_status)";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public override string markup { get {
|
|
public override string markup { get {
|
|
|
return """
|
|
return """
|
|
|
<!DOCTYPE html>
|
|
<!DOCTYPE html>
|
|
@@ -76,17 +102,17 @@ class ProgressComponent : Component {
|
|
|
|
|
|
|
|
<div spry-continuation>
|
|
<div spry-continuation>
|
|
|
<div class="progress-container" sse-swap="progress">
|
|
<div class="progress-container" sse-swap="progress">
|
|
|
- <div class="progress-bar" id="progress-bar" style="width: 0%">
|
|
|
|
|
|
|
+ <div class="progress-bar" id="progress-bar" sid="progress-bar" style="width: 0%">
|
|
|
0%
|
|
0%
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <div class="status" sse-swap="status">
|
|
|
|
|
|
|
+ <div class="status" sse-swap="status" sid="status" hx-swap="outerHTML">
|
|
|
<strong>Status:</strong> Initializing...
|
|
<strong>Status:</strong> Initializing...
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="log" id="log">
|
|
<div class="log" id="log">
|
|
|
- <div sse-swap="log">Waiting for task to start...</div>
|
|
|
|
|
|
|
+ <div sse-swap="log" hx-swap="afterbegin">Waiting for task to start...</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</body>
|
|
</body>
|
|
@@ -101,7 +127,7 @@ class ProgressComponent : Component {
|
|
|
* The event data should be HTML content that will be swapped into elements
|
|
* The event data should be HTML content that will be swapped into elements
|
|
|
* with matching sse-swap="eventname" attributes.
|
|
* with matching sse-swap="eventname" attributes.
|
|
|
*/
|
|
*/
|
|
|
- public async override void continuation(SseStream stream) throws Error {
|
|
|
|
|
|
|
+ public async override void continuation(ContinuationContext continuation_context) throws Error {
|
|
|
// Simulate a long-running task with progress updates
|
|
// Simulate a long-running task with progress updates
|
|
|
var steps = new string[] {
|
|
var steps = new string[] {
|
|
|
"Initializing task...",
|
|
"Initializing task...",
|
|
@@ -119,20 +145,18 @@ class ProgressComponent : Component {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
for (int i = 0; i < steps.length; i++) {
|
|
for (int i = 0; i < steps.length; i++) {
|
|
|
- // Calculate progress percentage
|
|
|
|
|
- int percent = (int)(((i + 1) / (double)steps.length) * 100);
|
|
|
|
|
|
|
+ // Update the template
|
|
|
|
|
+ percent = (int)(((i + 1) / (double)steps.length) * 100);
|
|
|
|
|
+ status = steps[i];
|
|
|
|
|
|
|
|
// Send progress bar update - HTML that will be swapped into the progress bar
|
|
// Send progress bar update - HTML that will be swapped into the progress bar
|
|
|
- yield stream.send_event(new SseEvent.with_type("progress",
|
|
|
|
|
- @"<div class=\"progress-bar\" id=\"progress-bar\" style=\"width: $percent%\">$percent%</div>"));
|
|
|
|
|
|
|
+ yield continuation_context.send_fragment("progress", "progress-bar");
|
|
|
|
|
|
|
|
// Send status update - HTML that will be swapped into the status div
|
|
// Send status update - HTML that will be swapped into the status div
|
|
|
- yield stream.send_event(new SseEvent.with_type("status",
|
|
|
|
|
- @"<strong>Status:</strong> $(steps[i])"));
|
|
|
|
|
|
|
+ yield continuation_context.send_fragment("status", "status");
|
|
|
|
|
|
|
|
// Send log message - HTML that will be appended to the log
|
|
// Send log message - HTML that will be appended to the log
|
|
|
- yield stream.send_event(new SseEvent.with_type("log",
|
|
|
|
|
- @"<div class=\"log-entry\">$(steps[i])</div>"));
|
|
|
|
|
|
|
+ yield continuation_context.send_string("log", @"<div class=\"log-entry\">$(steps[i])</div>");
|
|
|
|
|
|
|
|
// Simulate work being done (500ms per step)
|
|
// Simulate work being done (500ms per step)
|
|
|
Timeout.add(500, () => {
|
|
Timeout.add(500, () => {
|
|
@@ -143,12 +167,11 @@ class ProgressComponent : Component {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Send final completion messages
|
|
// Send final completion messages
|
|
|
- yield stream.send_event(new SseEvent.with_type("progress",
|
|
|
|
|
- "<div class=\"progress-bar\" id=\"progress-bar\" style=\"width: 100%\">100% ✓</div>"));
|
|
|
|
|
- yield stream.send_event(new SseEvent.with_type("status",
|
|
|
|
|
- "<strong>Status:</strong> Task completed successfully!"));
|
|
|
|
|
- yield stream.send_event(new SseEvent.with_type("log",
|
|
|
|
|
- "<div class=\"log-entry\">✓ All tasks completed!</div>"));
|
|
|
|
|
|
|
+ percent = 100;
|
|
|
|
|
+ status = "Task completed successfully!";
|
|
|
|
|
+ yield continuation_context.send_fragment("progress", "progress-bar");
|
|
|
|
|
+ yield continuation_context.send_fragment("status", "status");
|
|
|
|
|
+ yield continuation_context.send_string("log", "<div class=\"log-entry\">✓ All tasks completed!</div>");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|