@inherits ShadcnBlazor.Extras.Dialogs.DialogBase @using System.Text.Json @using LucideBlazor @using Moonlight.Shared.Http.Events @using ShadcnBlazor.Buttons @using ShadcnBlazor.Dialogs @using ShadcnBlazor.Progresses @using ShadcnBlazor.Spinners @inject HttpClient HttpClient Updating instance...
@for (var i = 0; i < Steps.Length; i++) { if (CurrentStep == i) {
@Steps[i]
} else { if (i < CurrentStep) {
@Steps[i]
} else {
@Steps[i]
} } }
@for (var i = LogLines.Count - 1; i >= 0; i--) {
@LogLines[i]
}
@if (CurrentStep == Steps.Length) { } else { } @code { private int Progress; private int CurrentStep; private readonly string[] Steps = [ "Checking", // 0 "Updating configuration files", // 1 "Starting rebuild task", // 2 "Building docker image", // 3 "Redeploying container instance", // 4 "Waiting for container instance to start up", // 5 "Update complete" // 6 ]; private readonly List LogLines = new(); protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) return; // Checking CurrentStep = 0; Progress = 0; await InvokeAsync(StateHasChanged); await Task.Delay(2000); // Update configuration CurrentStep = 1; Progress = 20; await InvokeAsync(StateHasChanged); await Task.Delay(2000); // Starting rebuild task CurrentStep = 2; Progress = 30; await InvokeAsync(StateHasChanged); var response = await HttpClient.SendAsync( new HttpRequestMessage(HttpMethod.Post, "api/admin/ch/rebuild"), HttpCompletionOption.ResponseHeadersRead ); await using var responseStream = await response.Content.ReadAsStreamAsync(); using var streamReader = new StreamReader(responseStream); do { try { var line = await streamReader.ReadLineAsync(); if (line == null) break; if (string.IsNullOrWhiteSpace(line)) continue; var data = line.Trim("data: "); var deserializedData = JsonSerializer.Deserialize(data, Constants.SerializerOptions); switch (deserializedData.Type) { case RebuildEventType.Log: LogLines.Add(deserializedData.Data); break; case RebuildEventType.Step: switch (deserializedData.Data) { case "BuildImage": // Building docker image CurrentStep = 3; Progress = 40; await InvokeAsync(StateHasChanged); break; case "ServiceDown": // Redeploying container instance CurrentStep = 4; Progress = 60; await InvokeAsync(StateHasChanged); break; } break; } await InvokeAsync(StateHasChanged); } catch (Exception) { break; } } while (true); // Waiting for container instance to start up CurrentStep = 5; Progress = 90; await InvokeAsync(StateHasChanged); // Wait some time for instance to shut down await Task.Delay(TimeSpan.FromSeconds(5)); // Ping instance until its reachable again while (true) { try { await HttpClient.GetStringAsync("api/ping"); break; } catch (Exception) { // Ignored } await Task.Delay(3000); } // Update complete CurrentStep = 7; Progress = 100; await InvokeAsync(StateHasChanged); } }