LANCommander/LANCommander.Launcher/UI/MainLayout.razor
2025-09-27 16:39:54 -05:00

287 lines
No EOL
11 KiB
Text

@using System.Management.Automation.Remoting
@using LANCommander.Launcher.Models
@using LANCommander.SDK
@using LANCommander.SDK.Rpc.Client
@using Photino.Blazor.CustomWindow.Components
@using ConnectionState = LANCommander.Launcher.Models.ConnectionState
@inherits LayoutComponentBase
@inject ImportService ImportService
@inject ProfileService ProfileService
@inject AuthenticationService AuthenticationService
@inject KeepAliveService KeepAliveService
@inject IMessageService MessageService
@inject NavigationManager NavigationManager
@inject ModalService ModalService
@inject LANCommander.SDK.Client LANCommander
@inject IJSRuntime JS
@inject ILogger<MainLayout> Logger
@inject ImportManagerService ImportManagerService
@inject LocalizationService LocalizationService
@inject IRpcClient RpcClient
<CustomWindow HeaderHeight="37">
<HeaderExtraControlsLayout>
<Space Direction="SpaceDirection.Horizontal">
<AuthenticatedView NoAutoValidate="true">
<Authenticated>
<SpaceItem>
@if (ImportStatus.IsActive)
{
<Popover Placement="Placement.BottomRight" IsButton Trigger="new[] { Trigger.Hover }">
<ChildContent>
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.Sync" Loading="true"/>
</ChildContent>
<ContentTemplate>
<ImportProgressDisplay
Index="@ImportStatus.Index"
Total="@ImportStatus.Total"
CurrentItem="@(_importProgress?.CurrentItem)"
/>
</ContentTemplate>
</Popover>
}
else if (ConnectionState.IsConnected)
{
<Tooltip Title="@LocalizationService.GetString("ReimportLibrary")" MouseEnterDelay="0.5">
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.Sync" OnClick="@ImportHandler.Import"/>
</Tooltip>
}
else if (!string.IsNullOrEmpty(Settings.Authentication.AccessToken))
{
<Tooltip Title="@LocalizationService.GetString("ReconnectToServer")" MouseEnterDelay="0.5">
<Button Type="@ButtonType.Text" Icon="@IconType.Outline.CloudSync" OnClick="Connect" Loading="@Connecting" Danger/>
</Tooltip>
}
</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="@LocalizationService.GetString("LauncherCrashed")">
<Body>
<AuthenticatedView NoAutoValidate="false">
<Authenticated>
@Body
@if (Settings.Debug.EnableScriptDebugging)
{
<PowerShellConsole/>
}
<KeepAliveContainer/>
</Authenticated>
<NotAuthenticated>
<AuthenticationForm/>
</NotAuthenticated>
</AuthenticatedView>
<ImportHandler @ref="ImportHandler" Progress="OnImportProcess" />
<UpdateChecker/>
<AntContainer/>
</Body>
<Extra>
<Button Type="ButtonType.Primary" OnClick="@(() => NavigationManager.NavigateTo("/", true))">@LocalizationService.GetString("ViewLibrary")</Button>
</Extra>
</ErrorHandler>
</WindowContent>
</CustomWindow>
@code {
Models.Settings Settings = null;
public bool Importing;
public bool Connecting;
public ConnectionState ConnectionState = default!;
public IMessageService Messages { get; set; }
ImportHandler ImportHandler;
ImportHandler.ImportProgressEventArgs ImportStatus = new();
private ImportProgress _importProgress => ImportService.Progress;
string RandomQuip = "";
string[] _crashQuips;
protected override async Task OnInitializedAsync()
{
Settings = SettingService.GetSettings();
ConnectionState = KeepAliveService.GetConnectionState();
Messages = MessageService;
AuthenticationService.OnOfflineModeChanged += OnOfflineModeChanged;
var token = new SDK.Models.AuthToken
{
AccessToken = Settings.Authentication.AccessToken,
RefreshToken = Settings.Authentication.RefreshToken
};
if (await LANCommander.Authentication.ValidateTokenAsync())
{
ConnectionState.IsStartup = true;
await AuthenticationService.Login();
await ProfileService.DownloadProfileInfoAsync();
ConnectionState.IsConnected = true;
ConnectionState.OfflineModeEnabled = false;
ConnectionState.IsStartup = false;
await ImportManagerService.RequestImport();
await InvokeAsync(StateHasChanged);
}
await RpcClient.ConnectAsync();
_crashQuips = new[]
{
LocalizationService.GetString("CrashQuip_YouDied"),
LocalizationService.GetString("CrashQuip_Snake"),
LocalizationService.GetString("CrashQuip_Wasted"),
LocalizationService.GetString("CrashQuip_MajorFracture"),
LocalizationService.GetString("CrashQuip_PastIsGapingHole"),
LocalizationService.GetString("CrashQuip_TownCenterDestroyed"),
LocalizationService.GetString("CrashQuip_ForcesUnderAttack"),
LocalizationService.GetString("CrashQuip_LostLead"),
LocalizationService.GetString("CrashQuip_TerroristsWin"),
LocalizationService.GetString("CrashQuip_WarNeverChanges"),
LocalizationService.GetString("CrashQuip_DiedOfDysentery"),
LocalizationService.GetString("CrashQuip_FailedToRestoreBooks"),
LocalizationService.GetString("CrashQuip_PlayerSplattered"),
LocalizationService.GetString("CrashQuip_BlameISP"),
LocalizationService.GetString("CrashQuip_BabaNoMore"),
LocalizationService.GetString("CrashQuip_GuestsLost"),
LocalizationService.GetString("CrashQuip_DarknessOvercome"),
LocalizationService.GetString("CrashQuip_GordonFreemanTerminated"),
LocalizationService.GetString("CrashQuip_MissionFailedSpotted"),
LocalizationService.GetString("CrashQuip_CriticalDamageEject"),
LocalizationService.GetString("CrashQuip_MinionsUnhappy"),
LocalizationService.GetString("CrashQuip_EmpireTriumphed"),
LocalizationService.GetString("CrashQuip_QuestEndedFailure"),
LocalizationService.GetString("CrashQuip_EatenByGrue"),
LocalizationService.GetString("CrashQuip_NoMessWithLoWang"),
LocalizationService.GetString("CrashQuip_SamKilled"),
LocalizationService.GetString("CrashQuip_AlienBastardsPay")
};
var randIndex = new Random().Next(0, _crashQuips.Length - 1);
RandomQuip = _crashQuips[randIndex];
}
public void Dispose()
{
if (AuthenticationService != null)
{
AuthenticationService.OnOfflineModeChanged -= OnOfflineModeChanged;
}
}
async void OnOfflineModeChanged(bool state)
{
ConnectionState.OfflineModeEnabled = state;
ConnectionState.IsConnected = LANCommander.Connection.IsConnected();
await InvokeAsync(StateHasChanged);
}
async void OnImportProcess(ImportHandler.ImportProgressEventArgs importProgress)
{
ImportStatus = importProgress;
await InvokeAsync(StateHasChanged);
}
async Task CopyError(Exception ex)
{
await JS.InvokeVoidAsync("navigator.clipboard.writeText", ex.Message + "\n" + ex.StackTrace);
MessageService.Info(LocalizationService.GetString("ErrorCopiedToClipboard"));
}
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.Authentication.ValidateTokenAsync())
{
await AuthenticationService.Login();
await ProfileService.DownloadProfileInfoAsync();
MessageService.Success(LocalizationService.GetString("BackOnline"));
ConnectionState.IsConnected = true;
ConnectionState.OfflineModeEnabled = false;
await InvokeAsync(StateHasChanged);
}
else
{
if (await LANCommander.Connection.PingAsync())
{
await Logout();
}
else
{
await ModalService.ConfirmAsync(new ConfirmOptions()
{
Title = LocalizationService.GetString("CouldNotReconnect"),
Icon = @<Icon Type="@IconType.Outline.ExclamationCircle"></Icon>,
Content = LocalizationService.GetString("CouldNotReconnectMessage"),
OkText = LocalizationService.GetString("Logout"),
CancelText = LocalizationService.GetString("StayOffline"),
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");
}
}
<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>