LANCommander/LANCommander.Launcher/UI/MainLayout.razor
2025-02-06 20:54:03 -06:00

299 lines
No EOL
10 KiB
Text

@using System.Management.Automation.Remoting
@using LANCommander.Launcher.Models
@using LANCommander.SDK
@using Photino.Blazor.CustomWindow.Components
@using ConnectionState = LANCommander.Launcher.Models.ConnectionState
@inherits LayoutComponentBase
@inject ImportService ImportService
@inject ProfileService ProfileService
@inject AuthenticationService AuthenticationService
@inject IMessageService MessageService
@inject NavigationManager NavigationManager
@inject ModalService ModalService
@inject LANCommander.SDK.Client LANCommander
@inject IJSRuntime JS
@inject ILogger<MainLayout> Logger
@inject ImportManagerService ImportManagerService
<CustomWindow HeaderHeight="37">
<HeaderExtraControlsLayout>
<Space Direction="SpaceDirection.Horizontal">
<AuthenticatedView>
<Authenticated>
<SpaceItem>
@if (Importing)
{
<Popover Placement="Placement.BottomRight" IsButton Trigger="new[] { Trigger.Hover }">
<ChildContent>
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.Sync" Loading="@Importing"/>
</ChildContent>
<ContentTemplate>
<ImportProgressDisplay
Index="@ImportStatusIndex"
Total="@ImportStatusTotal"
CurrentItem="@(_importProgress?.CurrentItem)"
/>
</ContentTemplate>
</Popover>
}
else
{
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.Sync" OnClick="@Import"/>
}
</SpaceItem>
<SpaceItem>
<ProfileButton/>
</SpaceItem>
</Authenticated>
<NotAuthenticated>
<SpaceItem>
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.CloudSync" OnClick="Connect" Loading="@Connecting" Danger/>
</SpaceItem>
</NotAuthenticated>
</AuthenticatedView>
</Space>
</HeaderExtraControlsLayout>
<WindowContent>
<ErrorHandler Title="Launcher Crashed">
<Body>
<AuthenticatedView>
<Authenticated>
@Body
@if (Settings.Debug.EnableScriptDebugging)
{
<PowerShellConsole/>
}
<KeepAliveContainer/>
</Authenticated>
<NotAuthenticated>
<AuthenticationForm/>
</NotAuthenticated>
</AuthenticatedView>
<UpdateChecker/>
<AntContainer/>
</Body>
<Extra>
<Button Type="ButtonType.Primary" OnClick="@(() => NavigationManager.NavigateTo("/", true))">View Library</Button>
</Extra>
</ErrorHandler>
</WindowContent>
</CustomWindow>
@code {
Models.Settings Settings = null;
public bool Importing;
public bool Connecting;
public ConnectionState ConnectionState = new();
public IMessageService Messages { get; set; }
string RandomQuip = "";
string[] CrashQuips = new[]
{
"You Died.",
"Snake? SNAAAAAAKE!",
"WASTED",
"Major fracture detected",
"The past is a gaping hole. You try to run from it, but the more you run, the deeper, the darker, the bigger it gets.",
"Your town center has been destroyed",
"Your forces are under attack!",
"You have lost the lead",
"Terrorists Win",
"War... War never changes.",
"You have died of dysentery",
"You have failed to restore the books. The Ages are lost.",
"Player was splattered by a demon",
"Sure, blame it on your ISP",
"Baba is no more",
"Guests are complaining they are lost",
"The darkness has overcome you",
"Subject: Gordon Freeman. Status: Terminated",
"Mission failed: You were spotted.",
"Critical damage! Eject, eject!",
"Your minions are unhappy. They are leaving.",
"The Empire has triumphed",
"Your quest has ended in failure",
"You have been eaten by a grue",
"You no mess with Lo Wang!",
"Sam was killed. Serious carnage ensues.",
"Damn, those alien bastards are gonna pay for shooting up my ride"
};
int ImportStatusIndex = 0;
int ImportStatusTotal = 0;
private ImportProgress _importProgress => ImportService.Progress;
protected override async Task OnInitializedAsync()
{
Settings = SettingService.GetSettings();
Messages = MessageService;
ImportManagerService.OnImportRequested += Import;
AuthenticationService.OnOfflineModeChanged += OnOfflineModeChanged;
var randIndex = new Random().Next(0, CrashQuips.Length - 1);
RandomQuip = CrashQuips[randIndex];
}
public void Dispose()
{
if (AuthenticationService != null)
{
AuthenticationService.OnOfflineModeChanged -= OnOfflineModeChanged;
}
if (ImportService != null)
{
ImportService.OnImportComplete -= OnImportCompleteHandler;
ImportService.OnImportUpdated -= OnImportUpdatedHandler;
}
if (ImportManagerService != null)
{
ImportManagerService.OnImportRequested -= Import;
}
}
async void OnOfflineModeChanged(bool state)
{
ConnectionState.OfflineModeEnabled = state;
ConnectionState.IsConnected = LANCommander.IsConnected();
await InvokeAsync(StateHasChanged);
}
async Task CopyError(Exception ex)
{
await JS.InvokeVoidAsync("navigator.clipboard.writeText", ex.Message + "\n" + ex.StackTrace);
MessageService.Info("Error copied to clipboard!");
}
async Task Connect()
{
Connecting = true;
Settings = SettingService.GetSettings();
var token = new SDK.Models.AuthToken
{
AccessToken = Settings.Authentication.AccessToken,
RefreshToken = Settings.Authentication.RefreshToken
};
if (await LANCommander.ValidateTokenAsync(token))
{
await AuthenticationService.Login();
MessageService.Success("Back Online!");
ConnectionState.IsConnected = true;
ConnectionState.OfflineModeEnabled = false;
await InvokeAsync(StateHasChanged);
}
else
{
if (await LANCommander.PingAsync())
{
await Logout();
}
else
{
await ModalService.ConfirmAsync(new ConfirmOptions()
{
Title = "Could Not Reconnect!",
Icon = @<Icon Type="@IconType.Outline.ExclamationCircle"></Icon>,
Content = "The LANCommander server could not be reached. Click stay offline and try later, or logout and enter your credentials.",
OkText = "Logout",
CancelText = "Stay Offline",
Centered = true,
OnOk = async (e) =>
{
await Logout();
}
});
}
}
Connecting = false;
await InvokeAsync(StateHasChanged);
}
async Task Logout()
{
await AuthenticationService.Logout();
ConnectionState.IsConnected = false;
ConnectionState.OfflineModeEnabled = false;
NavigationManager.NavigateTo("/Authenticate");
}
public async Task Import()
{
if (!Importing)
{
Logger?.LogInformation("Starting import process");
// Clear any existing handlers
ImportService.OnImportComplete -= OnImportCompleteHandler;
ImportService.OnImportUpdated -= OnImportUpdatedHandler;
// Add our handlers
ImportService.OnImportComplete += OnImportCompleteHandler;
ImportService.OnImportUpdated += OnImportUpdatedHandler;
// Now start the import process
Importing = true;
ImportStatusIndex = 0;
ImportStatusTotal = 0;
await InvokeAsync(StateHasChanged);
MessageService.Info("Import Started", 2.5);
Logger?.LogInformation("Starting import");
await ImportService.ImportLibraryAsync(); // Call directly instead of using JS
}
}
private async Task OnImportCompleteHandler()
{
Logger?.LogInformation("Import Complete handler called");
Importing = false;
ImportStatusIndex = 0;
ImportStatusTotal = 0;
MessageService.Success("Import Complete", 3);
await InvokeAsync(StateHasChanged);
}
private async Task OnImportUpdatedHandler(ImportStatusUpdate status)
{
Logger?.LogInformation("Import Update handler called: {Index}/{Total}",
status.Index, status.Total);
ImportStatusIndex = status.Index;
ImportStatusTotal = status.Total;
await InvokeAsync(StateHasChanged);
}
}
<style>
.import-progress {
width: 300px; /* Fixed width */
}
.import-progress .downloader-current-upper-status {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
</style>