ProgressDemo.vala 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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" class="demo-progress">
  19. <div class="progress-header">
  20. <h3>Task Progress</h3>
  21. <span sid="status-text" class="progress-status"></span>
  22. </div>
  23. <div class="progress-bar-container">
  24. <div sid="progress-bar" class="progress-bar"
  25. style-width-expr='format("%i%%", this.percent)'>
  26. </div>
  27. </div>
  28. <div class="progress-info">
  29. <span sid="percent-text" class="progress-percent"></span>
  30. </div>
  31. <div class="progress-controls">
  32. <button sid="start-btn" spry-action=":Start" spry-target="progress"
  33. class="progress-btn">Start Task</button>
  34. <button sid="reset-btn" spry-action=":Reset" spry-target="progress"
  35. class="progress-btn secondary">Reset</button>
  36. </div>
  37. </div>
  38. """;
  39. }}
  40. public override async void prepare() throws Error {
  41. this["status-text"].text_content = status;
  42. this["percent-text"].text_content = @"$percent%";
  43. if (is_running) {
  44. this["start-btn"].set_attribute("disabled", "disabled");
  45. this["start-btn"].text_content = "Running...";
  46. } else {
  47. this["start-btn"].remove_attribute("disabled");
  48. this["start-btn"].text_content = percent >= 100 ? "Complete!" : "Start Task";
  49. }
  50. }
  51. public async override void handle_action(string action) throws Error {
  52. switch (action) {
  53. case "Start":
  54. if (!is_running && percent < 100) {
  55. is_running = true;
  56. status = "Starting...";
  57. }
  58. break;
  59. case "Reset":
  60. percent = 0;
  61. status = "Ready";
  62. is_running = false;
  63. break;
  64. }
  65. }
  66. public async override void continuation(ContinuationContext ctx) throws Error {
  67. if (!is_running) return;
  68. for (int i = percent; i <= 100; i += 5) {
  69. percent = i;
  70. if (i < 30) {
  71. status = @"Processing... $i%";
  72. } else if (i < 60) {
  73. status = @"Building... $i%";
  74. } else if (i < 90) {
  75. status = @"Finalizing... $i%";
  76. } else {
  77. status = @"Almost done... $i%";
  78. }
  79. // Send updates via SSE
  80. yield ctx.send_dynamic("progress");
  81. // Simulate work
  82. Timeout.add(200, () => {
  83. continuation.callback();
  84. return false;
  85. });
  86. yield;
  87. }
  88. percent = 100;
  89. status = "Complete!";
  90. is_running = false;
  91. yield ctx.send_dynamic("progress");
  92. }
  93. }
  94. /**
  95. * ProgressDemoWithSSE - Progress demo with SSE wrapper
  96. *
  97. * This version includes the spry-continuation attribute wrapper
  98. * for demonstrating SSE in the documentation.
  99. */
  100. public class ProgressDemoWithSSE : Component {
  101. public override string markup { get {
  102. return """
  103. <div sid="wrapper" spry-continuation>
  104. <spry-component name="ProgressDemo" sid="progress-demo" spry-dynamic="progress"/>
  105. </div>
  106. """;
  107. }}
  108. }