@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 = State switch { ServerState.Installing => "bg-primary-500", ServerState.Offline => "bg-danger-500", ServerState.Starting => "bg-warning-500", ServerState.Stopping => "bg-warning-500", ServerState.Online => "bg-success-500", _ => "bg-gray-500" }; }
@if (State == ServerState.Offline) { Start } else { } @if (State == ServerState.Starting || State == ServerState.Online) { Stop } else { }
}
@code { [Parameter] public int ServerId { get; set; } private ServerDetailResponse Server; private bool NotFound = false; private ServerState State; private string InitialConsoleMessage; // TODO: When moving to a single component, fail safe when failed to load private XtermConsole? XtermConsole; private HubConnection WebSocketConnection; 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" ); State = status.State; // Load initial messages var initialLogs = await ApiClient.GetJson( $"api/servers/{ServerId}/logs" ); InitialConsoleMessage = ""; foreach (var message in initialLogs.Messages) InitialConsoleMessage += message; // Load websocket meta var websocketDetails = await ApiClient.GetJson( $"api/servers/{ServerId}/ws" ); // Build signal r WebSocketConnection = new HubConnectionBuilder() .WithUrl(websocketDetails.Target) .Build(); // Define handlers WebSocketConnection.On("StateChanged", async stateStr => { if (!Enum.TryParse(stateStr, out ServerState receivedState)) return; State = receivedState; await InvokeAsync(StateHasChanged); }); WebSocketConnection.On("ConsoleOutput", async content => { if (XtermConsole != null) await XtermConsole.Write(content); await InvokeAsync(StateHasChanged); }); // Connect await WebSocketConnection.StartAsync(); // Authenticate await WebSocketConnection.SendAsync("Authenticate", websocketDetails.AccessToken); } catch (HttpApiException e) { if (e.Status == 404) NotFound = true; else throw; } } private async Task OnAfterConsoleInitialized() { await XtermConsole!.Write(InitialConsoleMessage); } private async Task Start() { await ApiClient.Post($"api/servers/{Server.Id}/start"); } private async Task Stop() { await ApiClient.Post($"api/servers/{Server.Id}/stop"); } public async ValueTask DisposeAsync() { if (WebSocketConnection.State == HubConnectionState.Connected) await WebSocketConnection.StopAsync(); await WebSocketConnection.DisposeAsync(); } }