Allow media grabber dialog to show results from multiple groups. Show media type in media grabber dialog. Allow modification of search for media grabber dialog.
parent
499b0c910a
commit
d51eab151a
|
@ -2,7 +2,7 @@
|
|||
<div class="image-picker-images">
|
||||
@foreach (var image in Images)
|
||||
{
|
||||
<div class="image-picker-image" style="width: @(Size)px; height: @(Size)px">
|
||||
<div class="image-picker-image" style="width: @(Size)px; max-height: @(Size)px">
|
||||
<input type="radio" id="image-picker-image-@image.Key" checked="@(Value == image.Key)" name="SelectedResult" @onchange="@(() => SelectionChanged(image.Key))" />
|
||||
<label for="image-picker-image-@image.Key"></label>
|
||||
<img src="@image.Value" />
|
||||
|
|
|
@ -3,9 +3,24 @@
|
|||
@using LANCommander.Models;
|
||||
@inject IMediaGrabberService MediaGrabberService
|
||||
|
||||
<Slider TValue="double" @bind-Value="Size" DefaultValue="200" Min="50" Max="400" />
|
||||
<GridRow Justify="space-between">
|
||||
<GridCol Span="6">
|
||||
<Search @bind-Value="Search" OnSearch="(x) => GetResults(Type, x)" DefaultValue="@Search" />
|
||||
</GridCol>
|
||||
<GridCol Span="12"></GridCol>
|
||||
<GridCol Span="6">
|
||||
<Slider TValue="double" @bind-Value="Size" DefaultValue="200" Min="50" Max="400" />
|
||||
</GridCol>
|
||||
</GridRow>
|
||||
|
||||
<ImagePicker Size="Size" Images="Images" ValueChanged="OnImageSelected" />
|
||||
@foreach (var group in Results)
|
||||
{
|
||||
<div class="media-grabber-group">
|
||||
<h2>@group.First().Group</h2>
|
||||
|
||||
<ImagePicker Size="Size" Images="@group.ToDictionary(r => r.Id, r => r.ThumbnailUrl)" ValueChanged="OnImageSelected" />
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public string Search { get; set; }
|
||||
|
@ -15,16 +30,22 @@
|
|||
|
||||
double Size { get; set; } = 200;
|
||||
|
||||
IEnumerable<MediaGrabberResult> Results = new List<MediaGrabberResult>();
|
||||
IEnumerable<IEnumerable<MediaGrabberResult>> Results = new List<List<MediaGrabberResult>>();
|
||||
Dictionary<string, string> Images { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
protected override async Task OnFirstAfterRenderAsync()
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
Results = await MediaGrabberService.SearchAsync(Options.Type, Options.Search);
|
||||
Type = Options.Type;
|
||||
Search = Options.Search;
|
||||
|
||||
Images = Results.ToDictionary(r => r.Id, r => r.ThumbnailUrl);
|
||||
await GetResults(Type, Search);
|
||||
}
|
||||
|
||||
private async Task GetResults(MediaType type, string search)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
Results = (await MediaGrabberService.SearchAsync(type, search)).GroupBy(r => r.Group);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -32,7 +53,7 @@
|
|||
|
||||
private void OnImageSelected(string key)
|
||||
{
|
||||
Media = Results.FirstOrDefault(r => r.Id == key);
|
||||
Media = Results.SelectMany(g => g).FirstOrDefault(r => r.Id == key);
|
||||
}
|
||||
|
||||
public override async Task OnFeedbackOkAsync(ModalClosingEventArgs args)
|
||||
|
|
|
@ -8,5 +8,6 @@ namespace LANCommander.Models
|
|||
public MediaType Type { get; set; }
|
||||
public string SourceUrl { get; set; }
|
||||
public string ThumbnailUrl { get; set; }
|
||||
public string Group { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<PropertyColumn Property="p => p.Id" Title="Preview" Width="100px" Align="ColumnAlign.Center">
|
||||
@if (MediaService.FileExists(context))
|
||||
{
|
||||
<Image Width="100px" Src="@($"/api/Media/{context.Id}/Download")" />
|
||||
<Image Width="100px" Src="@($"/api/Media/{context.Id}/Download?fileId={context.FileId}")" />
|
||||
}
|
||||
</PropertyColumn>
|
||||
<PropertyColumn Property="p => p.Type">
|
||||
|
@ -53,7 +53,8 @@
|
|||
|
||||
Values.Add(new Media()
|
||||
{
|
||||
GameId = GameId
|
||||
GameId = GameId,
|
||||
Type = Enum.GetValues<MediaType>().ToList().FirstOrDefault(t => !Values.Any(v => v.Type == t))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,7 @@
|
|||
{
|
||||
var modalOptions = new ModalOptions()
|
||||
{
|
||||
Title = "Search Media",
|
||||
Title = $"Download {media.Type}",
|
||||
Maximizable = false,
|
||||
DefaultMaximized = true,
|
||||
Closable = true,
|
||||
|
@ -81,9 +82,19 @@
|
|||
modalRef.Config.ConfirmLoading = true;
|
||||
|
||||
media.SourceUrl = result.SourceUrl;
|
||||
media.FileId = await MediaService.DownloadMediaAsync(result.SourceUrl);
|
||||
|
||||
await MediaService.Add(media);
|
||||
if (media.Id == Guid.Empty)
|
||||
{
|
||||
media.FileId = await MediaService.DownloadMediaAsync(result.SourceUrl);
|
||||
|
||||
await MediaService.Add(media);
|
||||
}
|
||||
else
|
||||
{
|
||||
MediaService.DeleteLocalMediaFile(media.FileId);
|
||||
media.FileId = await MediaService.DownloadMediaAsync(result.SourceUrl);
|
||||
await MediaService.Update(media);
|
||||
}
|
||||
|
||||
Values = MediaService.Get(m => m.GameId == media.GameId).ToList();
|
||||
|
||||
|
|
|
@ -18,63 +18,68 @@ namespace LANCommander.Services.MediaGrabbers
|
|||
public async Task<IEnumerable<MediaGrabberResult>> SearchAsync(MediaType type, string keywords)
|
||||
{
|
||||
var games = await SteamGridDb.SearchForGamesAsync(keywords);
|
||||
var results = new List<MediaGrabberResult>();
|
||||
|
||||
if (games.Length > 0)
|
||||
foreach (var game in games)
|
||||
{
|
||||
var game = games.FirstOrDefault();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MediaType.Icon:
|
||||
return await GetIconsAsync(game.Id);
|
||||
results.AddRange(await GetIconsAsync(game));
|
||||
break;
|
||||
|
||||
case MediaType.Cover:
|
||||
return await GetCoversAsync(game.Id);
|
||||
results.AddRange(await GetCoversAsync(game));
|
||||
break;
|
||||
|
||||
case MediaType.Background:
|
||||
return await GetBackgroundsAsync(game.Id);
|
||||
results.AddRange(await GetBackgroundsAsync(game));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new List<MediaGrabberResult>();
|
||||
return results;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetIconsAsync(int gameId)
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetIconsAsync(SteamGridDbGame game)
|
||||
{
|
||||
var icons = await SteamGridDb.GetIconsByGameIdAsync(gameId);
|
||||
var icons = await SteamGridDb.GetIconsByGameIdAsync(game.Id);
|
||||
|
||||
return icons.Select(i => new MediaGrabberResult()
|
||||
{
|
||||
Id = i.Id.ToString(),
|
||||
Type = MediaType.Icon,
|
||||
SourceUrl = i.FullImageUrl,
|
||||
ThumbnailUrl = i.ThumbnailImageUrl
|
||||
ThumbnailUrl = i.ThumbnailImageUrl,
|
||||
Group = game.Name
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetCoversAsync(int gameId)
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetCoversAsync(SteamGridDbGame game)
|
||||
{
|
||||
var covers = await SteamGridDb.GetGridsByGameIdAsync(gameId);
|
||||
var covers = await SteamGridDb.GetGridsByGameIdAsync(game.Id);
|
||||
|
||||
return covers.Select(c => new MediaGrabberResult()
|
||||
{
|
||||
Id = c.Id.ToString(),
|
||||
Type = MediaType.Cover,
|
||||
SourceUrl = c.FullImageUrl,
|
||||
ThumbnailUrl = c.ThumbnailImageUrl
|
||||
ThumbnailUrl = c.ThumbnailImageUrl,
|
||||
Group = game.Name
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetBackgroundsAsync(int gameId)
|
||||
private async Task<IEnumerable<MediaGrabberResult>> GetBackgroundsAsync(SteamGridDbGame game)
|
||||
{
|
||||
var backgrounds = await SteamGridDb.GetHeroesByGameIdAsync(gameId);
|
||||
var backgrounds = await SteamGridDb.GetHeroesByGameIdAsync(game.Id);
|
||||
|
||||
return backgrounds.Select(b => new MediaGrabberResult()
|
||||
{
|
||||
Id = b.Id.ToString(),
|
||||
Type = MediaType.Background,
|
||||
SourceUrl = b.FullImageUrl,
|
||||
ThumbnailUrl = b.ThumbnailImageUrl
|
||||
ThumbnailUrl = b.ThumbnailImageUrl,
|
||||
Group = game.Name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,18 @@ namespace LANCommander.Services
|
|||
return Path.Combine(Settings.Media.StoragePath, entity.FileId.ToString());
|
||||
}
|
||||
|
||||
public void DeleteLocalMediaFile(Guid fileId)
|
||||
{
|
||||
var path = Path.Combine(Settings.Media.StoragePath, fileId.ToString());
|
||||
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
public async Task<Guid> DownloadMediaAsync(string sourceUrl)
|
||||
{
|
||||
var fileId = Guid.NewGuid();
|
||||
|
||||
var path = Path.Combine(Settings.Media.StoragePath, fileId.ToString());
|
||||
|
||||
using (var http = new HttpClient())
|
||||
|
|
|
@ -176,13 +176,11 @@
|
|||
.image-picker-images {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.image-picker-image {
|
||||
position: relative;
|
||||
aspect-ratio: 1/1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -218,6 +216,19 @@
|
|||
max-height: 100px;
|
||||
}
|
||||
|
||||
.media-grabber-group {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.media-grabber-group + .media-grabber-group {
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
[data-theme="Dark"] .media-grabber-group + .media-grabber-group {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.mobile-menu {
|
||||
display: none;
|
||||
|
|
Loading…
Reference in New Issue