ProgressDemo.vala 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using Spry;
  2. using Inversion;
  3. /**
  4. * ProgressDemo - A progress bar demo for the Continuations documentation
  5. *
  6. * Demonstrates:
  7. * - spry-continuation attribute for SSE
  8. * - spry-dynamic for updatable sections
  9. * - continuation() method for real-time updates
  10. * - ContinuationContext API
  11. */
  12. public class ProgressDemo : Component {
  13. public int percent { get; set; default = 0; }
  14. public string status { get; set; default = "Ready"; }
  15. public bool is_running { get; set; default = false; }
  16. public override string markup { get {
  17. return """
  18. <div sid="progress" spry-continuation class="demo-progress">
  19. <div spry-dynamic="progress-bar" class="progress-bar-container">
  20. <div sid="progress-bar" class="progress-bar"
  21. style-width-expr='format("%i%%", this.percent)'>
  22. </div>
  23. </div>
  24. <div spry-dynamic="status" class="progress-info">
  25. <span sid="percent-text" class="progress-percent" spry-unique content-expr='format("%i%%", this.percent)'>0%</span>
  26. <span sid="status-text" class="progress-status" spry-unique content-expr="this.status">Ready</span>
  27. </div>
  28. <div class="progress-controls">
  29. <button sid="start-btn" spry-action=":Start" spry-target="progress"
  30. class="progress-btn">Start Task</button>
  31. <button sid="reset-btn" spry-action=":Reset" spry-target="progress"
  32. class="progress-btn secondary">Reset</button>
  33. </div>
  34. </div>
  35. """;
  36. }}
  37. public override async void prepare() throws Error {
  38. this["status-text"].text_content = status;
  39. this["percent-text"].text_content = @"$percent%";
  40. if (is_running) {
  41. this["start-btn"].set_attribute("disabled", "disabled");
  42. this["start-btn"].text_content = "Running...";
  43. } else {
  44. this["start-btn"].remove_attribute("disabled");
  45. this["start-btn"].text_content = percent >= 100 ? "Complete!" : "Start Task";
  46. }
  47. }
  48. public async override void handle_action(string action) throws Error {
  49. switch (action) {
  50. case "Start":
  51. if (!is_running && percent < 100) {
  52. is_running = true;
  53. status = "Starting...";
  54. }
  55. break;
  56. case "Reset":
  57. percent = 0;
  58. status = "Ready";
  59. is_running = false;
  60. break;
  61. }
  62. }
  63. public async override void continuation(ContinuationContext ctx) throws Error {
  64. if (!is_running) return;
  65. for (int i = percent; i <= 100; i += 5) {
  66. percent = i;
  67. if (i < 30) {
  68. status = @"Processing... $i%";
  69. } else if (i < 60) {
  70. status = @"Building... $i%";
  71. } else if (i < 90) {
  72. status = @"Finalizing... $i%";
  73. } else {
  74. status = @"Almost done... $i%";
  75. }
  76. // Send updates via SSE to the dynamic sections
  77. yield ctx.send_dynamic("progress-bar");
  78. yield ctx.send_dynamic("status");
  79. // Simulate work
  80. Timeout.add(200, () => {
  81. continuation.callback();
  82. return false;
  83. });
  84. yield;
  85. }
  86. percent = 100;
  87. status = "Complete!";
  88. is_running = false;
  89. yield ctx.send_dynamic("progress-bar");
  90. yield ctx.send_dynamic("status");
  91. }
  92. }