diff --git a/LANCommander/Components/ImagePicker.razor b/LANCommander/Components/ImagePicker.razor index fc8c390..f2d0ebf 100644 --- a/LANCommander/Components/ImagePicker.razor +++ b/LANCommander/Components/ImagePicker.razor @@ -2,7 +2,7 @@
@foreach (var image in Images) { -
+
diff --git a/LANCommander/Components/MediaGrabberDialog.razor b/LANCommander/Components/MediaGrabberDialog.razor index b5dea49..b70c6b9 100644 --- a/LANCommander/Components/MediaGrabberDialog.razor +++ b/LANCommander/Components/MediaGrabberDialog.razor @@ -3,28 +3,49 @@ @using LANCommander.Models; @inject IMediaGrabberService MediaGrabberService - + + + + + + + + + - +@foreach (var group in Results) +{ +
+

@group.First().Group

+ + +
+} @code { [Parameter] public string Search { get; set; } [Parameter] public MediaType Type { get; set; } - + MediaGrabberResult Media { get; set; } double Size { get; set; } = 200; - IEnumerable Results = new List(); + IEnumerable> Results = new List>(); Dictionary Images { get; set; } = new Dictionary(); - 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) diff --git a/LANCommander/Models/MediaGrabberResult.cs b/LANCommander/Models/MediaGrabberResult.cs index e524011..34c3d56 100644 --- a/LANCommander/Models/MediaGrabberResult.cs +++ b/LANCommander/Models/MediaGrabberResult.cs @@ -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; } } } diff --git a/LANCommander/Pages/Games/Components/MediaEditor.razor b/LANCommander/Pages/Games/Components/MediaEditor.razor index b153768..31c0fb9 100644 --- a/LANCommander/Pages/Games/Components/MediaEditor.razor +++ b/LANCommander/Pages/Games/Components/MediaEditor.razor @@ -9,7 +9,7 @@ @if (MediaService.FileExists(context)) { - + } @@ -53,7 +53,8 @@ Values.Add(new Media() { - GameId = GameId + GameId = GameId, + Type = Enum.GetValues().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(); diff --git a/LANCommander/Services/MediaGrabbers/SteamGridDBMediaGrabber.cs b/LANCommander/Services/MediaGrabbers/SteamGridDBMediaGrabber.cs index ed0c747..1b81d73 100644 --- a/LANCommander/Services/MediaGrabbers/SteamGridDBMediaGrabber.cs +++ b/LANCommander/Services/MediaGrabbers/SteamGridDBMediaGrabber.cs @@ -18,63 +18,68 @@ namespace LANCommander.Services.MediaGrabbers public async Task> SearchAsync(MediaType type, string keywords) { var games = await SteamGridDb.SearchForGamesAsync(keywords); + var results = new List(); - 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(); + return results; } - private async Task> GetIconsAsync(int gameId) + private async Task> 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> GetCoversAsync(int gameId) + private async Task> 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> GetBackgroundsAsync(int gameId) + private async Task> 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 }); } } diff --git a/LANCommander/Services/MediaService.cs b/LANCommander/Services/MediaService.cs index 4a5342e..f0aada4 100644 --- a/LANCommander/Services/MediaService.cs +++ b/LANCommander/Services/MediaService.cs @@ -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 DownloadMediaAsync(string sourceUrl) { var fileId = Guid.NewGuid(); + var path = Path.Combine(Settings.Media.StoragePath, fileId.ToString()); using (var http = new HttpClient()) diff --git a/LANCommander/wwwroot/css/site.css b/LANCommander/wwwroot/css/site.css index 4dfd38b..5e64036 100644 --- a/LANCommander/wwwroot/css/site.css +++ b/LANCommander/wwwroot/css/site.css @@ -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;