LANCommander/LANCommander.Client/UI/Library/Index.razor

249 lines
9.3 KiB
Text

@page "/"
@page "/{id:guid}"
@using LANCommander.Client.Enums
@using LANCommander.Client.Models
@using System.Diagnostics
@using LANCommander.SDK.Helpers
@inject SDK.Client Client
@inject NavigationManager NavigationManager
@inject LibraryService LibraryService
@inject DownloadService DownloadService
@inject GameService GameService
@inject ModalService ModalService
@inject ImportService ImportService
<div class="library">
<div class="library-list">
<Collapse>
@foreach (var collection in LibraryItems.Where(i => i != null && i.DataItem is Data.Models.Collection))
{
<Panel Header="@collection.Name" Key="@collection.Key.ToString()">
<AntList DataSource="@collection.Children" TItem="LibraryItem" Class="ant-list-clickable" Size="small">
<ListItem OnClick='() => NavigationManager.NavigateTo($"/{context.Key}")'>
<div class="library-list-icon">
<MediaImage Id="@context.IconId" />
</div>
<span>@context.Name</span>
</ListItem>
</AntList>
</Panel>
}
</Collapse>
</div>
<div class="game-details">
@if (SelectedGame != null)
{
<div class="game-hero">
<h1>@SelectedGame.Title</h1>
@if (SelectedGame.Media.Any(m => m.Type == Data.Enums.MediaType.Background))
{
<MediaImage Id="@(SelectedGame.Media.First(m => m.Type == Data.Enums.MediaType.Background).Id)" Class="game-details-background" />
}
</div>
<div class="game-infobar">
@if (SelectedItem.State == LibraryItemState.NotInstalled)
{
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.Download" OnClick="() => Install(SelectedItem)">Install</Button>
}
else if (SelectedItem.State == LibraryItemState.Installed)
{
<Space Direction="@DirectionVHType.Horizontal">
<SpaceItem>
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.CaretRight" OnClick="() => Run(SelectedGame)">Play</Button>
</SpaceItem>
<SpaceItem>
<Dropdown>
<Overlay>
<Menu>
@if (SelectedGameActions.Count() > 0)
{
@foreach (var action in SelectedGameActions)
{
<MenuItem OnClick="() => LibraryService.Run(SelectedGame, action)">
@action.Name
</MenuItem>
}
<MenuDivider />
}
<MenuItem OnClick="() => Uninstall(SelectedItem)">
Uninstall
</MenuItem>
</Menu>
</Overlay>
<ChildContent>
<Button Type="@ButtonType.Default" Size="@ButtonSize.Large" Icon="@IconType.Outline.Ellipsis" />
</ChildContent>
</Dropdown>
</SpaceItem>
</Space>
}
else if (SelectedItem.State == LibraryItemState.Queued)
{
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.Bars" Disabled="true">Queued</Button>
}
else if (SelectedItem.State == LibraryItemState.UpdateAvailable)
{
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.Download">Update</Button>
}
else if (SelectedItem.State == LibraryItemState.Installing)
{
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.Loading" Disabled="true">Installing</Button>
}
</div>
}
</div>
</div>
@code {
[Parameter] public Guid Id { get; set; }
LibraryItem SelectedItem { get; set; }
Data.Models.Game SelectedGame { get; set; }
IEnumerable<SDK.Models.Action> SelectedGameActions { get; set; }
IEnumerable<LibraryItem> LibraryItems { get; set; } = new List<LibraryItem>();
protected override async Task OnInitializedAsync()
{
LibraryService.OnLibraryChanged += LoadData;
DownloadService.OnQueueChanged += OnQueueChanged;
LoadData();
}
protected override async Task OnParametersSetAsync()
{
if (Id != Guid.Empty)
await OnLibraryItemSelected(LibraryItems.SelectMany(i => i.Children).FirstOrDefault(i => i.Key == Id));
await InvokeAsync(StateHasChanged);
}
async void LoadData()
{
LibraryItems = await LibraryService.GetLibraryItemsAsync();
if (Id != Guid.Empty)
await OnLibraryItemSelected(LibraryItems.SelectMany(i => i.Children).FirstOrDefault(i => i.Key == Id));
await InvokeAsync(StateHasChanged);
}
async Task OnLibraryItemSelected(LibraryItem item)
{
if (item.DataItem is Data.Models.Game)
{
SelectedItem = item;
SelectedGame = item.DataItem as Data.Models.Game;
if (SelectedItem.State == LibraryItemState.Installed)
SelectedGameActions = (await GameService.GetActionsAsync(SelectedGame)).Where(a => !a.IsPrimaryAction);
}
}
async Task Install(LibraryItem item)
{
await LibraryService.Install(item);
}
async Task Uninstall(LibraryItem item)
{
var game = item.DataItem as Data.Models.Game;
var manifest = ManifestHelper.Read(game.InstallDirectory, game.Id);
var message = $"Would you like to uninstall {game.Title}?";
if (manifest.SavePaths != null && manifest.SavePaths.Any())
message += " Your save files have been uploaded to the server.";
else
message += " Your save files may be unrecoverable if they are contained within the game's install directory.";
var confirmed = await ModalService.ConfirmAsync(new ConfirmOptions
{
OkText = "Uninstall",
CancelText = "Cancel",
Title = "Uninstall",
Content = message,
OkType = "danger",
Icon = @<Icon Type="@IconType.Outline.Delete" />
});
if (confirmed)
await LibraryService.Uninstall(item);
}
async Task Run(Data.Models.Game game)
{
var actions = await GameService.GetActionsAsync(game);
var primaryActions = actions.Where(a => a.IsPrimaryAction);
if (primaryActions.Count() == 1)
LibraryService.Run(game, primaryActions.First());
else
{
var modalOptions = new ModalOptions()
{
Title = game.Title,
Maximizable = false,
DefaultMaximized = false,
Closable = true,
Footer = null,
Centered = true,
WrapClassName = "game-actions-dialog"
};
var model = new ActionSelectorDialogOptions
{
Actions = actions.Where(a => a.IsPrimaryAction),
Game = game
};
var modalRef = ModalService.CreateModal<ActionSelectorDialog, ActionSelectorDialogOptions, Process>(modalOptions, model);
}
}
async Task OnQueueChanged()
{
var queueItem = DownloadService.Queue.FirstOrDefault(i => i.Id == SelectedItem.Key);
if (queueItem != null)
{
SelectedItem = await LibraryService.GetLibraryItemAsync(SelectedItem);
switch (queueItem.Status)
{
case DownloadStatus.Downloading:
case DownloadStatus.InstallingRedistributables:
case DownloadStatus.InstallingMods:
case DownloadStatus.InstallingExpansions:
case DownloadStatus.RunningScripts:
case DownloadStatus.DownloadingSaves:
SelectedItem.State = LibraryItemState.Installing;
break;
case DownloadStatus.Idle:
SelectedItem.State = LibraryItemState.Queued;
break;
case DownloadStatus.Failed:
case DownloadStatus.Canceled:
SelectedItem.State = LibraryItemState.NotInstalled;
break;
case DownloadStatus.Complete:
SelectedItem.State = LibraryItemState.Installed;
break;
}
await OnLibraryItemSelected(SelectedItem);
await InvokeAsync(StateHasChanged);
}
}
}