@page "/servers/{ServerId:int}" @using Microsoft.AspNetCore.SignalR.Client @using MoonlightServers.Shared.Http.Responses.Users.Servers @using MoonCore.Blazor.Tailwind.Components @using MoonCore.Exceptions @using MoonCore.Helpers @using MoonlightServers.Shared.Enums @using MoonlightServers.Frontend.UI.Components @inject HttpApiClient ApiClient @implements IAsyncDisposable @if (NotFound) {
Not found illustration

Server not found

The server you requested does not exist

} else {
@{ var bgColor = PowerState switch { ServerPowerState.Installing => "bg-primary-500", ServerPowerState.Offline => "bg-danger-500", ServerPowerState.Starting => "bg-warning-500", ServerPowerState.Stopping => "bg-warning-500", ServerPowerState.Online => "bg-success-500", _ => "bg-gray-500" }; }
@if (!string.IsNullOrEmpty(CurrentTask)) { }
}
@code { [Parameter] public int ServerId { get; set; } private ServerDetailResponse Server; private bool NotFound = false; private ServerPowerState PowerState; private string InitialConsoleMessage; // TODO: When moving to a single component, fail safe when failed to load private string CurrentTask = ""; private XtermConsole? XtermConsole; private HubConnection ConsoleConnection; private async Task Load(LazyLoader _) { try { // Load meta data Server = await ApiClient.GetJson( $"api/servers/{ServerId}" ); // Load initial status for first render var status = await ApiClient.GetJson( $"api/servers/{ServerId}/status" ); PowerState = status.PowerState; // Load initial messages var initialLogs = await ApiClient.GetJson( $"api/servers/{ServerId}/logs" ); InitialConsoleMessage = ""; foreach (var message in initialLogs.Messages) InitialConsoleMessage += message; // Load console meta var consoleDetails = await ApiClient.GetJson( $"api/servers/{ServerId}/console" ); // Build signal r ConsoleConnection = new HubConnectionBuilder() .WithUrl(consoleDetails.Target) .Build(); // Define handlers ConsoleConnection.On("PowerStateChanged", async powerStateStr => { if(!Enum.TryParse(powerStateStr, out ServerPowerState receivedState)) return; PowerState = receivedState; await InvokeAsync(StateHasChanged); }); ConsoleConnection.On("TaskNotify", async task => { await AddTask(Formatter.ConvertCamelCaseToSpaces(task)); }); ConsoleConnection.On("ConsoleOutput", async content => { if (XtermConsole != null) await XtermConsole.Write(content); await InvokeAsync(StateHasChanged); }); // Connect await ConsoleConnection.StartAsync(); // Authenticate await ConsoleConnection.SendAsync("Authenticate", consoleDetails.AccessToken); } catch (HttpApiException e) { if (e.Status == 404) NotFound = true; else throw; } } private async Task OnAfterConsoleInitialized() { await XtermConsole!.Write(InitialConsoleMessage); } private async Task AddTask(string message) { CurrentTask = message; await InvokeAsync(StateHasChanged); Task.Run(async () => { await Task.Delay(3000); if (CurrentTask != message) return; CurrentTask = ""; await InvokeAsync(StateHasChanged); }); } public async ValueTask DisposeAsync() { if (ConsoleConnection.State == HubConnectionState.Connected) await ConsoleConnection.StopAsync(); await ConsoleConnection.DisposeAsync(); } }