2024-11-25 22:29:56 -06:00
|
|
|
@using AntDesign.TableModels;
|
2023-02-04 12:18:10 -06:00
|
|
|
@using LANCommander.PCGamingWiki
|
2024-05-07 01:47:00 -05:00
|
|
|
@using LANCommander.SDK.Enums
|
2023-02-04 12:18:10 -06:00
|
|
|
@inject IGDBService IGDBService
|
2023-08-09 15:28:05 -05:00
|
|
|
@inject NavigationManager NavigationManager
|
2024-02-11 18:30:33 -06:00
|
|
|
@inject IMessageService MessageService
|
2024-07-07 16:33:46 -05:00
|
|
|
@inject ILogger<GameMetadataLookup> Logger
|
2023-03-02 18:50:24 -06:00
|
|
|
|
|
|
|
|
@{
|
|
|
|
|
RenderFragment Footer =
|
|
|
|
|
@<Template>
|
2024-12-31 18:21:41 -06:00
|
|
|
<Button OnClick="SelectGame" Disabled="@(Loading || (SelectedResults != null && SelectedResults.Count() == 0) || Results.Count() == 0)" Type="ButtonType.Primary">Select</Button>
|
2023-03-20 21:00:19 -05:00
|
|
|
<Button OnClick="() => ModalVisible = false">Cancel</Button>
|
2023-03-02 18:50:24 -06:00
|
|
|
</Template>;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 00:40:44 -06:00
|
|
|
<Modal Visible="ModalVisible" Title="Game Metadata Lookup" Footer="@Footer" Class="game-metadata-lookup-modal" OnCancel="Close">
|
2023-03-02 18:50:24 -06:00
|
|
|
<Table
|
|
|
|
|
@ref="ResultsTable"
|
|
|
|
|
TItem="Game"
|
|
|
|
|
DataSource="Results"
|
|
|
|
|
HidePagination="true"
|
2023-03-20 21:00:19 -05:00
|
|
|
Loading="Loading"
|
2023-03-02 18:50:24 -06:00
|
|
|
OnRowClick="OnRowClicked"
|
|
|
|
|
@bind-SelectedRows="SelectedResults"
|
2023-09-04 12:52:45 -05:00
|
|
|
Responsive>
|
2023-03-02 18:50:24 -06:00
|
|
|
|
2024-12-31 18:21:41 -06:00
|
|
|
<Selection Key="@context.IGDBId.ToString()" Type="SelectionType.Radio" />
|
2023-03-02 18:50:24 -06:00
|
|
|
<PropertyColumn Property="g => g.Title" Title="Title" />
|
|
|
|
|
<PropertyColumn Property="g => g.ReleasedOn" Format="MM/dd/yyyy" Title="Released" />
|
|
|
|
|
<PropertyColumn Property="g => g.Developers">
|
|
|
|
|
@String.Join(", ", context.Developers?.Select(d => d.Name))
|
|
|
|
|
</PropertyColumn>
|
|
|
|
|
</Table>
|
2023-12-05 00:40:44 -06:00
|
|
|
|
|
|
|
|
@if (MoreResults && IGDBService.Authenticated)
|
|
|
|
|
{
|
2024-12-31 18:21:41 -06:00
|
|
|
<Button Type="ButtonType.Primary" OnClick="ShowMore" Block>Show More</Button>
|
2023-12-05 00:40:44 -06:00
|
|
|
}
|
2023-03-02 18:50:24 -06:00
|
|
|
</Modal>
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-08-09 15:28:05 -05:00
|
|
|
@if (IGDBService.Authenticated)
|
|
|
|
|
{
|
2025-01-20 20:00:15 -06:00
|
|
|
<Flex Gap="FlexGap.Small">
|
2025-02-23 09:18:06 -06:00
|
|
|
<Input @bind-Value="Value" BindOnInput="true" OnkeyDown="SearchFieldOnKeyDown" OnChange="ValueChanged" AutoFocus="AutoFocus" />
|
2025-01-20 20:00:15 -06:00
|
|
|
|
|
|
|
|
<Button OnClick="() => SearchForGame(Value)" Type="ButtonType.Primary" Disabled="@(String.IsNullOrWhiteSpace(Value))">@ButtonText</Button>
|
|
|
|
|
</Flex>
|
2023-08-09 15:28:05 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2025-01-20 20:00:15 -06:00
|
|
|
<Flex Gap="FlexGap.Small">
|
|
|
|
|
<Input @bind-Value="Value" BindOnInput="true" OnChange="ValueChanged" />
|
|
|
|
|
|
|
|
|
|
<Popconfirm OnConfirm="() => NavigateToSettings()" Title="Invalid IGDB credentials. Setup now?">
|
|
|
|
|
<Button Type="ButtonType.Primary">@ButtonText</Button>
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
</Flex>
|
2023-08-09 15:28:05 -05:00
|
|
|
}
|
|
|
|
|
|
2023-02-04 12:18:10 -06:00
|
|
|
@code {
|
2023-03-02 18:50:24 -06:00
|
|
|
[Parameter] public EventCallback<GameLookupResult> OnResultSelected { get; set; }
|
2023-08-09 15:28:05 -05:00
|
|
|
[Parameter] public string ButtonText { get; set; }
|
2025-02-23 09:18:06 -06:00
|
|
|
[Parameter] public bool AutoFocus { get; set; }
|
2024-03-12 00:46:44 -05:00
|
|
|
[Parameter] public string Value { get; set; }
|
|
|
|
|
[Parameter] public EventCallback<string> ValueChanged { get; set; }
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-03-02 18:50:24 -06:00
|
|
|
ITable? ResultsTable;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-12-05 00:40:44 -06:00
|
|
|
List<Game> Results { get; set; } = new List<Game>();
|
2023-03-02 18:50:24 -06:00
|
|
|
IEnumerable<Game> SelectedResults { get; set; }
|
|
|
|
|
PCGamingWikiClient PCGamingWikiClient { get; set; }
|
|
|
|
|
bool ModalVisible { get; set; } = false;
|
2023-03-20 21:00:19 -05:00
|
|
|
bool Loading = true;
|
2023-12-05 00:40:44 -06:00
|
|
|
bool MoreResults = false;
|
|
|
|
|
int Offset = 0;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2024-11-22 02:04:04 -06:00
|
|
|
protected override void OnInitialized()
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
|
|
|
|
PCGamingWikiClient = new PCGamingWikiClient();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-02 18:50:24 -06:00
|
|
|
private void OnRowClicked(RowData<Game> row)
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2023-03-02 18:50:24 -06:00
|
|
|
ResultsTable.SetSelection(new string[] { row.Data.IGDBId.ToString() });
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|
|
|
|
|
|
2024-03-12 00:46:44 -05:00
|
|
|
private async Task SearchFieldOnKeyDown(KeyboardEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if ((e.Code == "Enter" || e.Code == "NumpadEnter") && !String.IsNullOrWhiteSpace(Value))
|
|
|
|
|
await SearchForGame(Value);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-12 00:50:19 -05:00
|
|
|
private async Task SearchForGame(string title, bool newSearch = true)
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2024-02-11 18:30:33 -06:00
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Loading = true;
|
|
|
|
|
ModalVisible = true;
|
2023-03-02 18:50:24 -06:00
|
|
|
|
2024-03-12 00:50:19 -05:00
|
|
|
if (newSearch)
|
|
|
|
|
{
|
|
|
|
|
Results = new List<Game>();
|
|
|
|
|
Offset = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
int limit = 10;
|
2023-12-05 00:40:44 -06:00
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
string[] fields = new string[]
|
|
|
|
|
{
|
2023-12-05 00:40:44 -06:00
|
|
|
"involved_companies.developer",
|
|
|
|
|
"involved_companies.publisher",
|
|
|
|
|
"involved_companies.company.name"
|
2024-02-11 18:30:33 -06:00
|
|
|
};
|
2023-12-05 00:40:44 -06:00
|
|
|
|
2024-11-12 18:32:46 -06:00
|
|
|
var results = await IGDBService.SearchAsync(title, limit, Offset, fields);
|
2023-12-05 00:40:44 -06:00
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
MoreResults = results.Count() == limit;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
Loading = false;
|
2023-03-20 21:00:19 -05:00
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
if (results == null)
|
|
|
|
|
Results = new List<Game>();
|
|
|
|
|
else
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2024-02-11 18:30:33 -06:00
|
|
|
Results.AddRange(results.Select(r =>
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2024-02-11 18:30:33 -06:00
|
|
|
var result = new Game()
|
|
|
|
|
{
|
|
|
|
|
IGDBId = r.Id.GetValueOrDefault(),
|
|
|
|
|
Title = r.Name,
|
|
|
|
|
ReleasedOn = r.FirstReleaseDate.GetValueOrDefault().UtcDateTime,
|
|
|
|
|
Developers = new List<Company>(),
|
|
|
|
|
Publishers = new List<Company>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (r.InvolvedCompanies != null && r.InvolvedCompanies.Values != null)
|
2024-01-08 18:19:48 -06:00
|
|
|
{
|
2024-02-11 18:30:33 -06:00
|
|
|
result.Developers = r.InvolvedCompanies.Values.Where(c => c.Developer.HasValue && c.Developer.GetValueOrDefault() && c.Company != null && c.Company.Value != null).Select(c => new Company()
|
|
|
|
|
{
|
|
|
|
|
Name = c.Company.Value.Name
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
result.Publishers = r.InvolvedCompanies.Values.Where(c => c.Publisher.HasValue && c.Publisher.GetValueOrDefault() && c.Company != null && c.Company.Value != null).Select(c => new Company()
|
|
|
|
|
{
|
|
|
|
|
Name = c.Company.Value.Name
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageService.Error("An unknown error occurred when retrieving IGDB metadata");
|
2024-07-07 16:33:46 -05:00
|
|
|
Logger.LogError(ex, "An unknown error occurred when retrieving IGDB metadata");
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2024-02-11 18:30:33 -06:00
|
|
|
Loading = false;
|
|
|
|
|
ModalVisible = false;
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-02 18:50:24 -06:00
|
|
|
private async Task SelectGame()
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2023-03-20 21:00:19 -05:00
|
|
|
Loading = true;
|
|
|
|
|
|
2023-03-02 18:50:24 -06:00
|
|
|
var result = new GameLookupResult();
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-12-05 00:40:44 -06:00
|
|
|
string[] fields = new string[]
|
|
|
|
|
{
|
|
|
|
|
"genres.*",
|
|
|
|
|
"game_modes.*",
|
|
|
|
|
"multiplayer_modes.*",
|
|
|
|
|
"release_dates.*",
|
|
|
|
|
"platforms.*",
|
|
|
|
|
"keywords.*",
|
|
|
|
|
"involved_companies.developer",
|
|
|
|
|
"involved_companies.publisher",
|
|
|
|
|
"involved_companies.company.name",
|
2024-03-29 17:19:42 -05:00
|
|
|
"cover.*",
|
|
|
|
|
"game_engines.*"
|
2023-12-05 00:40:44 -06:00
|
|
|
};
|
|
|
|
|
|
2024-11-12 18:32:46 -06:00
|
|
|
result.IGDBMetadata = await IGDBService.GetAsync(SelectedResults.First().IGDBId.GetValueOrDefault(), fields);
|
2023-03-02 18:50:24 -06:00
|
|
|
result.MultiplayerModes = await GetMultiplayerModes(result.IGDBMetadata.Name);
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-03-02 18:50:24 -06:00
|
|
|
await OnResultSelected.InvokeAsync(result);
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2023-12-05 00:40:44 -06:00
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Close()
|
|
|
|
|
{
|
|
|
|
|
Results = new List<Game>();
|
|
|
|
|
MoreResults = false;
|
|
|
|
|
Offset = 0;
|
2023-03-02 18:50:24 -06:00
|
|
|
ModalVisible = false;
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|
|
|
|
|
|
2023-12-05 00:40:44 -06:00
|
|
|
private async Task ShowMore()
|
|
|
|
|
{
|
|
|
|
|
MoreResults = false;
|
|
|
|
|
Offset += Results.Count;
|
|
|
|
|
|
2024-03-12 00:50:19 -05:00
|
|
|
await SearchForGame(Value, false);
|
2023-12-05 00:40:44 -06:00
|
|
|
}
|
|
|
|
|
|
2023-02-04 12:18:10 -06:00
|
|
|
private async Task<ICollection<MultiplayerMode>> GetMultiplayerModes(string gameTitle)
|
|
|
|
|
{
|
|
|
|
|
var multiplayerModes = new List<MultiplayerMode>();
|
|
|
|
|
|
2024-10-01 17:54:12 -05:00
|
|
|
try
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2025-04-22 18:06:28 +02:00
|
|
|
var multiplayerInfo = await PCGamingWikiClient.GetMultiplayerPlayerInfo(gameTitle);
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-04-22 18:06:28 +02:00
|
|
|
if (multiplayerInfo != null)
|
2024-10-01 17:54:12 -05:00
|
|
|
{
|
2025-04-22 18:06:28 +02:00
|
|
|
foreach (var info in multiplayerInfo)
|
2023-02-04 12:18:10 -06:00
|
|
|
{
|
2024-10-01 17:54:12 -05:00
|
|
|
MultiplayerType type;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-04-22 18:06:28 +02:00
|
|
|
switch (info.MultiplayerType.ToLower())
|
2024-10-01 17:54:12 -05:00
|
|
|
{
|
2025-04-22 18:06:28 +02:00
|
|
|
case "local":
|
|
|
|
|
case "local play":
|
2024-10-01 17:54:12 -05:00
|
|
|
type = MultiplayerType.Local;
|
|
|
|
|
break;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-04-22 18:06:28 +02:00
|
|
|
case "lan":
|
|
|
|
|
case "lan play":
|
2024-10-01 17:54:12 -05:00
|
|
|
type = MultiplayerType.LAN;
|
|
|
|
|
break;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-04-22 18:06:28 +02:00
|
|
|
case "online":
|
|
|
|
|
case "online play":
|
2024-10-01 17:54:12 -05:00
|
|
|
type = MultiplayerType.Online;
|
|
|
|
|
break;
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2024-10-01 17:54:12 -05:00
|
|
|
default:
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
multiplayerModes.Add(new MultiplayerMode()
|
|
|
|
|
{
|
|
|
|
|
Type = type,
|
2025-04-22 18:06:28 +02:00
|
|
|
MaxPlayers = info.PlayerCount,
|
|
|
|
|
MinPlayers = 2,
|
|
|
|
|
Description = info.Notes,
|
2024-10-01 17:54:12 -05:00
|
|
|
});
|
|
|
|
|
}
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|
|
|
|
|
}
|
2024-10-01 17:54:12 -05:00
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Logger?.LogError(ex, "Could not retrieve multiplayer modes from PCGamingWiki");
|
|
|
|
|
}
|
2023-02-04 12:18:10 -06:00
|
|
|
|
|
|
|
|
return multiplayerModes;
|
|
|
|
|
}
|
2023-08-09 15:28:05 -05:00
|
|
|
|
|
|
|
|
private void NavigateToSettings()
|
|
|
|
|
{
|
|
|
|
|
NavigationManager.NavigateTo("/Settings/General", true);
|
|
|
|
|
}
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|