2025-12-31 20:01:04 -06:00
|
|
|
@using LANCommander.Launcher.Data.Models
|
2024-08-04 17:53:19 -05:00
|
|
|
@using LANCommander.Launcher.Models
|
2024-06-10 23:29:19 -05:00
|
|
|
@using System.Diagnostics
|
2025-12-31 20:01:04 -06:00
|
|
|
@namespace LANCommander.Launcher.UI
|
|
|
|
|
@implements IDisposable
|
2024-06-10 23:29:19 -05:00
|
|
|
@inject GameService GameService
|
|
|
|
|
@inject LibraryService LibraryService
|
2026-03-08 14:27:56 -05:00
|
|
|
@inject InstallService InstallService
|
2025-11-29 18:24:27 -06:00
|
|
|
@inject GameClient GameClient
|
|
|
|
|
@inject LobbyClient LobbyClient
|
2024-06-10 23:29:19 -05:00
|
|
|
@inject ModalService ModalService
|
2024-08-01 17:27:35 -05:00
|
|
|
@inject MessageService MessageService
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
@inject LocalizationService LocalizationService
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2025-01-12 21:49:30 -06:00
|
|
|
@if (State == PlayButtonState.Running)
|
2024-06-10 23:29:19 -05:00
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
<Popconfirm Title="@LocalizationService.GetString("DoYouWantToStopGame")" OkText="@LocalizationService.GetString("Yes")" OnConfirm="() => Stop()">
|
|
|
|
|
<Button Type="ButtonType.Primary" Size="ButtonSize.Large" Icon="@IconType.Outline.CaretRight">@LocalizationService.GetString("Running")</Button>
|
2024-06-10 23:29:19 -05:00
|
|
|
</Popconfirm>
|
|
|
|
|
}
|
2025-01-12 21:49:30 -06:00
|
|
|
else if (State == PlayButtonState.Starting)
|
|
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
<Button Type="ButtonType.Primary" Size="ButtonSize.Large" Loading="true">@LocalizationService.GetString("Starting")</Button>
|
2025-01-12 21:49:30 -06:00
|
|
|
}
|
|
|
|
|
else if (State == PlayButtonState.Stopping)
|
|
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
<Button Type="ButtonType.Primary" Size="ButtonSize.Large" Loading="true">@LocalizationService.GetString("Stopping")</Button>
|
2025-01-12 21:49:30 -06:00
|
|
|
}
|
2024-06-10 23:29:19 -05:00
|
|
|
else
|
|
|
|
|
{
|
2024-12-31 18:21:41 -06:00
|
|
|
<Space Direction="SpaceDirection.Horizontal">
|
2024-06-10 23:29:19 -05:00
|
|
|
<SpaceItem>
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
<Button Type="ButtonType.Primary" Size="ButtonSize.Large" Icon="@IconType.Outline.CaretRight" OnClick="() => Run()">@LocalizationService.GetString("Play")</Button>
|
2024-06-10 23:29:19 -05:00
|
|
|
</SpaceItem>
|
|
|
|
|
|
|
|
|
|
<SpaceItem>
|
|
|
|
|
<Dropdown>
|
|
|
|
|
<Overlay>
|
|
|
|
|
<Menu>
|
2024-08-01 17:21:44 -05:00
|
|
|
<LibraryItemContextMenu Model="LibraryItem" MenuExtra="MenuExtra" />
|
2024-06-10 23:29:19 -05:00
|
|
|
</Menu>
|
|
|
|
|
</Overlay>
|
|
|
|
|
|
|
|
|
|
<ChildContent>
|
2024-12-31 18:21:41 -06:00
|
|
|
<Button Type="@ButtonType.Default" Size="ButtonSize.Large" Icon="@IconType.Outline.Ellipsis" />
|
2024-06-10 23:29:19 -05:00
|
|
|
</ChildContent>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
</SpaceItem>
|
|
|
|
|
</Space>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@code {
|
2025-12-01 22:46:38 +11:00
|
|
|
[Parameter] public required Guid LibraryItemId { get; set; }
|
|
|
|
|
[Parameter] public required Models.ListItem LibraryItem { get; set; }
|
|
|
|
|
[Parameter] public required RenderFragment MenuExtra { get; set; }
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2025-12-01 22:46:38 +11:00
|
|
|
Timer? StateTimer;
|
2025-01-12 21:49:30 -06:00
|
|
|
PlayButtonState State = PlayButtonState.Idle;
|
|
|
|
|
|
|
|
|
|
public enum PlayButtonState
|
|
|
|
|
{
|
|
|
|
|
Idle,
|
|
|
|
|
Starting,
|
|
|
|
|
Running,
|
|
|
|
|
Stopping
|
|
|
|
|
}
|
2024-07-15 19:47:32 -05:00
|
|
|
|
2024-07-11 18:32:09 -05:00
|
|
|
protected override async Task OnInitializedAsync()
|
|
|
|
|
{
|
2024-08-26 20:18:54 -05:00
|
|
|
StateTimer = new Timer(state => { InvokeAsync(UpdateState); }, null, 0, 250);
|
2026-03-08 14:27:56 -05:00
|
|
|
|
|
|
|
|
InstallService.OnQueueChanged += HandleQueueChanged;
|
|
|
|
|
InstallService.OnInstallComplete += HandleInstallComplete;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task HandleQueueChanged()
|
|
|
|
|
{
|
|
|
|
|
if (LibraryItem == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var queueItem = InstallService.Queue.FirstOrDefault(qi => qi.Id == LibraryItem.Key);
|
|
|
|
|
|
|
|
|
|
if (queueItem != null && (queueItem.Status == SDK.Enums.InstallStatus.Canceled ||
|
|
|
|
|
queueItem.Status == SDK.Enums.InstallStatus.Failed))
|
|
|
|
|
{
|
|
|
|
|
LibraryItem = await LibraryService.GetItemAsync(LibraryItem.Key);
|
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task HandleInstallComplete(Data.Models.Game game)
|
|
|
|
|
{
|
|
|
|
|
if (LibraryItem?.Key == game.Id)
|
|
|
|
|
{
|
|
|
|
|
LibraryItem = await LibraryService.GetItemAsync(LibraryItem.Key);
|
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
|
}
|
2024-07-11 18:32:09 -05:00
|
|
|
}
|
|
|
|
|
|
2024-06-10 23:29:19 -05:00
|
|
|
protected override async Task OnParametersSetAsync()
|
|
|
|
|
{
|
2024-08-01 17:21:44 -05:00
|
|
|
if (LibraryItem == null && LibraryItemId != Guid.Empty)
|
2024-11-09 17:15:04 -06:00
|
|
|
LibraryItem = await LibraryService.GetItemAsync(LibraryItemId);
|
2024-06-10 23:29:19 -05:00
|
|
|
}
|
|
|
|
|
|
2024-08-26 20:18:54 -05:00
|
|
|
async Task UpdateState()
|
2024-07-11 18:32:09 -05:00
|
|
|
{
|
2026-03-15 17:07:07 -05:00
|
|
|
if (State != PlayButtonState.Starting && GameClient.IsRunning(LibraryItem.Key))
|
2024-08-26 20:18:54 -05:00
|
|
|
{
|
2025-01-12 21:49:30 -06:00
|
|
|
await ChangeState(PlayButtonState.Running);
|
2024-08-26 20:18:54 -05:00
|
|
|
}
|
2025-11-29 18:24:27 -06:00
|
|
|
else if (State == PlayButtonState.Running && !GameClient.IsRunning(LibraryItem.Key))
|
2024-07-11 18:32:09 -05:00
|
|
|
{
|
2025-01-12 21:49:30 -06:00
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-07-11 18:32:09 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-12 21:49:30 -06:00
|
|
|
async Task ChangeState(PlayButtonState state)
|
|
|
|
|
{
|
|
|
|
|
State = state;
|
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-10 23:29:19 -05:00
|
|
|
async Task Run()
|
|
|
|
|
{
|
2025-12-01 22:46:38 +11:00
|
|
|
var game = (Game)LibraryItem.DataItem;
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2025-01-12 21:49:30 -06:00
|
|
|
await ChangeState(PlayButtonState.Starting);
|
|
|
|
|
|
2026-03-08 14:39:15 -05:00
|
|
|
var actions = await GameClient.GetActionsAsync(game.InstallDirectory, game.Id);
|
|
|
|
|
|
2024-08-01 17:27:35 -05:00
|
|
|
if (actions == null || actions.Count() == 0)
|
|
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
MessageService.Error(LocalizationService.GetString("NoActionsFound"));
|
2025-01-12 21:49:30 -06:00
|
|
|
|
|
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-08-01 17:27:35 -05:00
|
|
|
return;
|
2025-12-01 22:46:38 +11:00
|
|
|
}
|
2024-08-01 17:27:35 -05:00
|
|
|
|
2025-11-29 18:24:27 -06:00
|
|
|
var primaryActions = actions.Where(a => a.IsPrimaryAction && LibraryService.IsInstalled(game.Id));
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2024-08-01 17:27:35 -05:00
|
|
|
if (primaryActions.Count() == 0)
|
|
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
MessageService.Error(LocalizationService.GetString("NoPrimaryActionFound"));
|
2025-01-12 21:49:30 -06:00
|
|
|
|
|
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-08-01 17:27:35 -05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-10 23:29:19 -05:00
|
|
|
if (primaryActions.Count() == 1)
|
|
|
|
|
{
|
2024-09-05 00:48:04 -05:00
|
|
|
var task = GameService.Run(game, primaryActions.First());
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2026-03-15 17:07:07 -05:00
|
|
|
while (!GameClient.IsRunning(game.Id) && !task.IsCompleted)
|
|
|
|
|
await Task.Delay(100);
|
|
|
|
|
|
|
|
|
|
if (GameClient.IsRunning(game.Id))
|
|
|
|
|
await ChangeState(PlayButtonState.Running);
|
|
|
|
|
else
|
|
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-06-10 23:29:19 -05:00
|
|
|
|
|
|
|
|
await task;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var modalOptions = new ModalOptions()
|
|
|
|
|
{
|
Add localization support to launcher
Adds localization across the launcher and includes English, German, Spanish, French, Italian, Japanese, Korean, Dutch, Portuguese, Ukranian, and Chinese. These localizations were generated by Claude 3.5 and need to be reviewed by a human for accuracy.
2025-08-18 21:29:38 -05:00
|
|
|
Title = LocalizationService.GetString("PlayGame", game.Title),
|
2024-06-10 23:29:19 -05:00
|
|
|
Maximizable = false,
|
|
|
|
|
DefaultMaximized = false,
|
|
|
|
|
Closable = true,
|
2025-01-27 21:07:38 -06:00
|
|
|
MaskClosable = true,
|
2024-06-10 23:29:19 -05:00
|
|
|
Footer = null,
|
|
|
|
|
Centered = true,
|
2024-09-05 00:48:04 -05:00
|
|
|
WrapClassName = "game-actions-dialog",
|
|
|
|
|
AfterClose = async () =>
|
|
|
|
|
{
|
2025-11-29 18:24:27 -06:00
|
|
|
LobbyClient.ReleaseSteam();
|
2025-01-27 21:07:38 -06:00
|
|
|
|
|
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-09-05 00:48:04 -05:00
|
|
|
}
|
2024-06-10 23:29:19 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var model = new ActionSelectorDialogOptions
|
|
|
|
|
{
|
|
|
|
|
Actions = actions.Where(a => a.IsPrimaryAction),
|
2024-08-01 17:21:44 -05:00
|
|
|
Game = game
|
2024-06-10 23:29:19 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var modalRef = ModalService.CreateModal<ActionSelectorDialog, ActionSelectorDialogOptions, Process>(modalOptions, model);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task Stop()
|
|
|
|
|
{
|
2025-01-12 21:49:30 -06:00
|
|
|
await ChangeState(PlayButtonState.Stopping);
|
|
|
|
|
|
2025-11-29 18:24:27 -06:00
|
|
|
await GameClient.Stop(LibraryItem.Key);
|
2024-06-10 23:29:19 -05:00
|
|
|
|
2025-01-12 21:49:30 -06:00
|
|
|
await ChangeState(PlayButtonState.Idle);
|
2024-06-10 23:29:19 -05:00
|
|
|
}
|
|
|
|
|
|
2024-07-15 19:47:32 -05:00
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2025-12-01 22:46:38 +11:00
|
|
|
StateTimer?.Dispose();
|
2026-03-08 14:27:56 -05:00
|
|
|
InstallService.OnQueueChanged -= HandleQueueChanged;
|
|
|
|
|
InstallService.OnInstallComplete -= HandleInstallComplete;
|
2024-07-15 19:47:32 -05:00
|
|
|
}
|
2024-06-10 23:29:19 -05:00
|
|
|
}
|