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

253 lines
10 KiB
Text
Raw Permalink Normal View History

@page "/"
2024-06-01 22:47:56 -05:00
@page "/{id:guid}"
@using LANCommander.Client.Enums
2024-05-23 23:41:38 -05:00
@using LANCommander.Client.Models
2024-05-25 22:21:04 -05:00
@using System.Diagnostics
2024-05-29 02:02:40 -05:00
@using LANCommander.SDK.Helpers
@inject SDK.Client Client
@inject NavigationManager NavigationManager
2024-05-23 23:41:38 -05:00
@inject LibraryService LibraryService
@inject DownloadService DownloadService
2024-05-25 22:21:04 -05:00
@inject GameService GameService
@inject ModalService ModalService
@inject ImportService ImportService
2024-06-07 23:49:11 -05:00
<Layout>
<Content Class="library">
<div class="library-list">
<Collapse>
@foreach (var collection in LibraryItems.Where(i => i != null && i.DataItem is Data.Models.Collection))
2024-06-01 22:47:56 -05:00
{
2024-06-07 23:49:11 -05:00
<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}")' Class="@GetItemClasses(context)">
2024-06-07 23:49:11 -05:00
<div class="library-list-icon">
<MediaImage Id="@context.IconId" />
</div>
<span>@context.Name</span>
</ListItem>
</AntList>
</Panel>
2024-06-01 22:47:56 -05:00
}
2024-06-07 23:49:11 -05:00
</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>
2024-06-08 16:03:41 -05:00
<GridRow Gutter="32" Class="game-info" Wrap="false">
<GridCol Flex="@("auto")">
<div class="game-action-bar">
<Space Direction="@DirectionVHType.Horizontal" Size="@("large")">
<SpaceItem>
2024-06-10 23:29:19 -05:00
@if (SelectedItem.State == LibraryItemState.Installed)
2024-06-08 18:37:52 -05:00
{
2024-06-10 23:29:19 -05:00
<PlayButton GameId="@SelectedItem.Key" />
2024-06-08 18:37:52 -05:00
}
else if (SelectedItem.State == LibraryItemState.NotInstalled)
2024-06-08 16:03:41 -05:00
{
2024-06-11 00:26:17 -05:00
<Button Type="@ButtonType.Primary" Size="@ButtonSize.Large" Icon="@IconType.Outline.Download" OnClick="() => Install(SelectedItem)">Install</Button>
2024-06-08 16:03:41 -05:00
}
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>
}
</SpaceItem>
<SpaceItem>
<Statistic Title="Play Time" Value="@GetPlayTime(SelectedGame)" />
</SpaceItem>
<SpaceItem>
<Statistic Title="Last Played" Value="@GetLastPlayed(SelectedGame)" />
</SpaceItem>
</Space>
</div>
<div class="game-metadata">
<div class="game-metadata-description">@SelectedGame.Description</div>
<div class="game-metadata-released-on">
<h3>Released On</h3>
<span>@SelectedGame.ReleasedOn.Value.ToString("MMMM d, yyyy")</span>
</div>
<div class="game-metadata-developers">
<h3>Developers</h3>
<span>@(String.Join(", ", SelectedGame.Developers.Select(c => c.Name)))</span>
</div>
<div class="game-metadata-publishers">
<h3>Publishers</h3>
<span>@(String.Join(", ", SelectedGame.Publishers.Select(c => c.Name)))</span>
</div>
<div class="game-metadata-genres">
<h3>Genres</h3>
<span>@(String.Join(", ", SelectedGame.Genres.Select(g => g.Name)))</span>
</div>
<div class="game-metadata-tags">
<h3>Tags</h3>
<span>@(String.Join(", ", SelectedGame.Tags.Select(t => t.Name)))</span>
</div>
</div>
</GridCol>
<GridCol Flex="@("256px")" Class="game-cover">
@if (SelectedGame.Media.Any(m => m.Type == Data.Enums.MediaType.Cover))
{
<MediaImage Id="@(SelectedGame.Media.First(m => m.Type == Data.Enums.MediaType.Cover).Id)" />
}
</GridCol>
</GridRow>
2024-06-07 23:49:11 -05:00
}
</div>
</Content>
</Layout>
2024-06-07 23:49:11 -05:00
<div class="logo">
<img src="assets/logo-cut.svg" />
</div>
2024-06-07 23:49:11 -05:00
<LANCommander.Client.UI.Components.Footer />
@code {
2024-06-01 22:47:56 -05:00
[Parameter] public Guid Id { get; set; }
2024-06-11 00:26:17 -05:00
2024-06-01 22:47:56 -05:00
LibraryItem SelectedItem { get; set; }
2024-05-23 23:41:38 -05:00
2024-06-01 22:47:56 -05:00
Data.Models.Game SelectedGame { get; set; }
IEnumerable<SDK.Models.Action> SelectedGameActions { get; set; }
2024-06-01 22:47:56 -05:00
IEnumerable<LibraryItem> LibraryItems { get; set; } = new List<LibraryItem>();
protected override async Task OnInitializedAsync()
2024-05-29 02:02:40 -05:00
{
LibraryService.OnLibraryChanged += LoadData;
DownloadService.OnQueueChanged += OnQueueChanged;
2024-06-14 14:35:45 -07:00
ImportService.OnImportComplete += LoadData;
2024-05-29 02:02:40 -05:00
LoadData();
}
2024-06-01 22:47:56 -05:00
protected override async Task OnParametersSetAsync()
{
if (Id != Guid.Empty)
await OnLibraryItemSelected(LibraryItems.SelectMany(i => i.Children).FirstOrDefault(i => i.Key == Id));
await InvokeAsync(StateHasChanged);
}
2024-05-29 02:02:40 -05:00
async void LoadData()
{
2024-05-23 23:41:38 -05:00
LibraryItems = await LibraryService.GetLibraryItemsAsync();
2024-05-29 02:02:40 -05:00
2024-06-01 22:47:56 -05:00
if (Id != Guid.Empty)
await OnLibraryItemSelected(LibraryItems.SelectMany(i => i.Children).FirstOrDefault(i => i.Key == Id));
2024-05-29 02:02:40 -05:00
await InvokeAsync(StateHasChanged);
2024-05-23 23:41:38 -05:00
}
string GetItemClasses(LibraryItem item)
{
HashSet<string> classes = new HashSet<string>();
if (item.State == LibraryItemState.Installed)
classes.Add("installed");
if (SelectedGame != null && SelectedGame.Id == item.Key)
classes.Add("selected");
return String.Join(" ", classes);
}
2024-05-23 23:41:38 -05:00
async Task OnLibraryItemSelected(LibraryItem item)
{
if (item.DataItem is Data.Models.Game)
{
2024-06-01 22:47:56 -05:00
SelectedItem = item;
SelectedGame = item.DataItem as Data.Models.Game;
2024-05-29 02:02:40 -05:00
2024-06-01 22:47:56 -05:00
if (SelectedItem.State == LibraryItemState.Installed)
SelectedGameActions = (await GameService.GetActionsAsync(SelectedGame)).Where(a => !a.IsPrimaryAction);
}
}
async Task Install(LibraryItem item)
{
2024-05-29 02:02:40 -05:00
await LibraryService.Install(item);
}
2024-05-25 22:21:04 -05:00
async Task OnQueueChanged()
{
2024-06-10 23:29:19 -05:00
var queueItem = DownloadService.Queue.FirstOrDefault(i => SelectedItem != null && 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);
}
}
string GetPlayTime(Data.Models.Game game)
{
var totalTime = new TimeSpan(game.PlaySessions
.Where(ps => ps.End != null && ps.Start != null)
.Select(ps => ps.End.Value.Subtract(ps.Start.Value))
.Sum(ts => ts.Ticks));
2024-06-08 00:04:12 -05:00
if (totalTime.TotalMinutes < 1)
return "None";
else if (totalTime.TotalHours < 1)
return totalTime.TotalMinutes.ToString("0") + " minutes";
else
return totalTime.TotalHours.ToString("0.##") + " hours";
}
string GetLastPlayed(Data.Models.Game game)
{
var lastSession = game.PlaySessions.Where(ps => ps.End != null && ps.Start != null).OrderByDescending(ps => ps.End).FirstOrDefault();
2024-06-07 23:58:38 -05:00
if (lastSession == null)
return "Never";
2024-06-07 23:58:38 -05:00
else
return lastSession.End.Value.ToRelativeDate();
}
}