Added voice work image fallback. Added tag/creator/circle chip components. Updated voice work search response to include favorite/blacklisted flags for tags/creators/circles.
This commit is contained in:
@@ -27,18 +27,31 @@ public record VoiceWorkSearchResult
|
||||
public byte Status { get; init; }
|
||||
public byte SubtitleLanguage { get; init; }
|
||||
public bool? IsValid { get; init; }
|
||||
public required VoiceWorkCircleItem Circle { get; set; }
|
||||
public VoiceWorkTagItem[] Tags { get; set; } = [];
|
||||
public VoiceWorkCreatorItem[] Creators { get; set; } = [];
|
||||
}
|
||||
|
||||
public class VoiceWorkCircleItem
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
public required string MakerId { get; init; }
|
||||
public bool IsFavorite { get; init; }
|
||||
public bool IsBlacklisted { get; init; }
|
||||
}
|
||||
|
||||
public class VoiceWorkTagItem
|
||||
{
|
||||
public int TagId { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public bool IsFavorite { get; set; }
|
||||
public bool IsBlacklisted { get; set; }
|
||||
}
|
||||
|
||||
public class VoiceWorkCreatorItem
|
||||
{
|
||||
public int CreatorId { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public bool IsFavorite { get; set; }
|
||||
public bool IsBlacklisted { get; set; }
|
||||
}
|
||||
@@ -376,6 +376,13 @@ public class VoiceWorkSearchProvider(AppDbContext context, IVoiceWorkFullTextSea
|
||||
HasImage = voiceWork.HasImage,
|
||||
Maker = circle.Name,
|
||||
MakerId = circle.MakerId,
|
||||
Circle = new()
|
||||
{
|
||||
Name = circle.Name,
|
||||
MakerId = circle.MakerId,
|
||||
IsFavorite = circle.Favorite,
|
||||
IsBlacklisted = circle.Blacklisted
|
||||
},
|
||||
ExpectedDate = voiceWork.ExpectedDate,
|
||||
SalesDate = voiceWork.SalesDate,
|
||||
PlannedReleaseDate = voiceWork.PlannedReleaseDate,
|
||||
@@ -413,6 +420,13 @@ public class VoiceWorkSearchProvider(AppDbContext context, IVoiceWorkFullTextSea
|
||||
HasImage = voiceWork.HasImage,
|
||||
Maker = circle.Name,
|
||||
MakerId = circle.MakerId,
|
||||
Circle = new()
|
||||
{
|
||||
Name = circle.Name,
|
||||
MakerId = circle.MakerId,
|
||||
IsFavorite = circle.Favorite,
|
||||
IsBlacklisted = circle.Blacklisted
|
||||
},
|
||||
ExpectedDate = voiceWork.ExpectedDate,
|
||||
SalesDate = voiceWork.SalesDate,
|
||||
PlannedReleaseDate = voiceWork.PlannedReleaseDate,
|
||||
@@ -457,14 +471,14 @@ public class VoiceWorkSearchProvider(AppDbContext context, IVoiceWorkFullTextSea
|
||||
from englishTag in et.DefaultIfEmpty()
|
||||
where voiceWorkIds.Contains(voiceWorkTag.VoiceWorkId)
|
||||
orderby voiceWorkTag.VoiceWorkId, voiceWorkTag.Position
|
||||
select new { voiceWorkTag.VoiceWorkId, voiceWorkTag.TagId, tag.Name, EnglishName = englishTag.Name }
|
||||
select new { voiceWorkTag.VoiceWorkId, voiceWorkTag.TagId, tag.Name, EnglishName = englishTag.Name, IsFavorite = tag.Favorite, IsBlacklisted = tag.Blacklisted }
|
||||
).ToListAsync(cancellationToken);
|
||||
|
||||
return tagRows
|
||||
.GroupBy(r => r.VoiceWorkId)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => g.Select(r => new VoiceWorkTagItem { TagId = r.TagId, Name = r.EnglishName ?? r.Name }).ToArray()
|
||||
g => g.Select(r => new VoiceWorkTagItem { TagId = r.TagId, Name = r.EnglishName ?? r.Name, IsFavorite = r.IsFavorite, IsBlacklisted = r.IsBlacklisted }).ToArray()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -475,14 +489,14 @@ public class VoiceWorkSearchProvider(AppDbContext context, IVoiceWorkFullTextSea
|
||||
join creator in context.Creators.AsNoTracking() on voiceWorkCreator.CreatorId equals creator.CreatorId
|
||||
where voiceWorkIds.Contains(voiceWorkCreator.VoiceWorkId)
|
||||
orderby voiceWorkCreator.VoiceWorkId, voiceWorkCreator.Position
|
||||
select new { voiceWorkCreator.VoiceWorkId, creator.CreatorId, creator.Name }
|
||||
select new { voiceWorkCreator.VoiceWorkId, creator.CreatorId, creator.Name, creator.Favorite, creator.Blacklisted }
|
||||
).ToListAsync(cancellationToken);
|
||||
|
||||
return creatorRows
|
||||
.GroupBy(r => r.VoiceWorkId)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => g.Select(r => new VoiceWorkCreatorItem { CreatorId = r.CreatorId, Name = r.Name }).ToArray()
|
||||
g => g.Select(r => new VoiceWorkCreatorItem { CreatorId = r.CreatorId, Name = r.Name, IsFavorite = r.Favorite, IsBlacklisted = r.Blacklisted }).ToArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,26 @@
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
|
||||
<div class="j-chip">
|
||||
@if (string.IsNullOrWhiteSpace(Url))
|
||||
{
|
||||
<div class="@GetClasses()" @onclick="@OnClickAsync">
|
||||
@if (Graphic != null)
|
||||
{
|
||||
<Icon Graphic="@Graphic.Value" Color="@Color"></Icon>
|
||||
<Icon Graphic="@Graphic.Value" Varient="@(IconVarient ?? Enums.IconVarient.None)" Color="@Color"></Icon>
|
||||
}
|
||||
<span>@ChildContent</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="@GetClasses()" href="@Url" target="@Target">
|
||||
@if (Graphic != null)
|
||||
{
|
||||
<Icon Graphic="@Graphic.Value" Varient="@(IconVarient ?? Enums.IconVarient.None)" Color="@Color"></Icon>
|
||||
}
|
||||
<span>@ChildContent</span>
|
||||
</a>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
@@ -15,6 +29,72 @@
|
||||
[Parameter]
|
||||
public Graphic? Graphic { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public IconVarient? IconVarient { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public ColorVarient Color { get; set; } = ColorVarient.Primary;
|
||||
|
||||
[Parameter]
|
||||
public ElementVarient Varient { get; set; } = ElementVarient.None;
|
||||
|
||||
[Parameter]
|
||||
public ToneVarient Tone { get; set; } = ToneVarient.None;
|
||||
|
||||
[Parameter]
|
||||
public string? Url { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string? Target { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback Click { get; set; }
|
||||
|
||||
private string GetClasses()
|
||||
{
|
||||
string color = Color.ToString().ToLower();
|
||||
|
||||
List<string> classNames =
|
||||
[
|
||||
$"j-chip",
|
||||
$"color-{color}"
|
||||
];
|
||||
|
||||
switch (Varient)
|
||||
{
|
||||
case ElementVarient.Filled:
|
||||
classNames.Add($"varient-filled");
|
||||
//classNames.Add($"background-color-{color}");
|
||||
break;
|
||||
case ElementVarient.Outlined:
|
||||
classNames.Add($"varient-outlined");
|
||||
//classNames.Add($"border-color-{color}");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Tone)
|
||||
{
|
||||
case ToneVarient.Solid:
|
||||
classNames.Add($"tone-solid");
|
||||
break;
|
||||
case ToneVarient.Tint:
|
||||
classNames.Add($"tone-tint");
|
||||
break;
|
||||
}
|
||||
|
||||
if (Click.HasDelegate || string.IsNullOrWhiteSpace(Url) == false)
|
||||
{
|
||||
classNames.Add("is-clickable");
|
||||
}
|
||||
|
||||
return string.Join(" ", classNames);
|
||||
}
|
||||
|
||||
private async Task OnClickAsync()
|
||||
{
|
||||
if (Click.HasDelegate)
|
||||
{
|
||||
await Click.InvokeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
43
JSMR.UI.Blazor/Components/Chips/CircleChip.razor
Normal file
43
JSMR.UI.Blazor/Components/Chips/CircleChip.razor
Normal file
@@ -0,0 +1,43 @@
|
||||
@using JSMR.Application.Tags.Queries.Search.Contracts
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
@using Microsoft.AspNetCore.WebUtilities
|
||||
|
||||
<Chip Graphic="Graphic.Circle" Color="@GetColor()" Varient="ElementVarient.Outlined" Tone="@GetTone()" Url="@GetUrl()" Target="_blank">@Circle.Name</Chip>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public required VoiceWorkCircleItem Circle { get; set; }
|
||||
|
||||
private string GetUrl()
|
||||
{
|
||||
return $"https://www.dlsite.com/maniax/circle/profile/=/maker_id/{Circle.MakerId}.html";
|
||||
}
|
||||
|
||||
private ColorVarient GetColor()
|
||||
{
|
||||
if (Circle.IsFavorite)
|
||||
{
|
||||
return ColorVarient.Mint;
|
||||
}
|
||||
|
||||
if (Circle.IsBlacklisted)
|
||||
{
|
||||
return ColorVarient.Pink;
|
||||
}
|
||||
|
||||
return ColorVarient.Secondary;
|
||||
}
|
||||
|
||||
private ToneVarient GetTone()
|
||||
{
|
||||
if (Circle.IsFavorite || Circle.IsBlacklisted)
|
||||
{
|
||||
return ToneVarient.Tint;
|
||||
}
|
||||
|
||||
return ToneVarient.None;
|
||||
}
|
||||
}
|
||||
43
JSMR.UI.Blazor/Components/Chips/CreatorChip.razor
Normal file
43
JSMR.UI.Blazor/Components/Chips/CreatorChip.razor
Normal file
@@ -0,0 +1,43 @@
|
||||
@using JSMR.Application.Tags.Queries.Search.Contracts
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
@using Microsoft.AspNetCore.WebUtilities
|
||||
|
||||
<Chip Graphic="Graphic.Person" IconVarient="IconVarient.Fill" Color="@GetColor()" Varient="ElementVarient.Outlined" Tone="@GetTone()" Url="@GetUrl()" Target="_blank">@Creator.Name</Chip>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public required VoiceWorkCreatorItem Creator { get; set; }
|
||||
|
||||
private string GetUrl()
|
||||
{
|
||||
return $"https://www.dlsite.com/maniax/fsr/=/keyword_creater/{Creator.Name}";
|
||||
}
|
||||
|
||||
private ColorVarient GetColor()
|
||||
{
|
||||
if (Creator.IsFavorite)
|
||||
{
|
||||
return ColorVarient.Mint;
|
||||
}
|
||||
|
||||
if (Creator.IsBlacklisted)
|
||||
{
|
||||
return ColorVarient.Pink;
|
||||
}
|
||||
|
||||
return ColorVarient.Secondary;
|
||||
}
|
||||
|
||||
private ToneVarient GetTone()
|
||||
{
|
||||
if (Creator.IsFavorite || Creator.IsBlacklisted)
|
||||
{
|
||||
return ToneVarient.Tint;
|
||||
}
|
||||
|
||||
return ToneVarient.None;
|
||||
}
|
||||
}
|
||||
54
JSMR.UI.Blazor/Components/Chips/TagChip.razor
Normal file
54
JSMR.UI.Blazor/Components/Chips/TagChip.razor
Normal file
@@ -0,0 +1,54 @@
|
||||
@using JSMR.Application.Tags.Queries.Search.Contracts
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
@using Microsoft.AspNetCore.WebUtilities
|
||||
|
||||
<Chip Graphic="Graphic.Tag" Color="@GetColor()" Varient="ElementVarient.Outlined" Tone="@GetTone()" Click="@OnClick">@Tag.Name</Chip>
|
||||
|
||||
@code {
|
||||
[Inject]
|
||||
protected NavigationManager NavigationManager { get; set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
public required VoiceWorkTagItem Tag { get; set; }
|
||||
|
||||
private ColorVarient GetColor()
|
||||
{
|
||||
if (Tag.IsFavorite)
|
||||
{
|
||||
return ColorVarient.Mint;
|
||||
}
|
||||
|
||||
if (Tag.IsBlacklisted)
|
||||
{
|
||||
return ColorVarient.Pink;
|
||||
}
|
||||
|
||||
return ColorVarient.Secondary;
|
||||
}
|
||||
|
||||
private ToneVarient GetTone()
|
||||
{
|
||||
if (Tag.IsFavorite || Tag.IsBlacklisted)
|
||||
{
|
||||
return ToneVarient.Tint;
|
||||
}
|
||||
|
||||
return ToneVarient.None;
|
||||
}
|
||||
|
||||
private void OnClick()
|
||||
{
|
||||
VoiceWorkFilterState state = new()
|
||||
{
|
||||
TagIds = [Tag.TagId]
|
||||
};
|
||||
|
||||
string basePath = new Uri(NavigationManager.Uri).GetLeftPart(UriPartial.Authority);
|
||||
string uri = QueryHelpers.AddQueryString($"{basePath}/voiceworks", state.ToQuery());
|
||||
|
||||
NavigationManager.NavigateTo(uri);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="@ContainerClassees">
|
||||
<div class="@OverlayClasses"></div>
|
||||
<img class="@ImageClasses" loading="@LoadingAttribute" src="@Source" @onload="OnImageLoaded">
|
||||
<img class="@ImageClasses" loading="@LoadingAttribute" src="@currentSource" @onload="OnImageLoaded" @onerror="OnImageError">
|
||||
</div>
|
||||
|
||||
@code {
|
||||
@@ -8,7 +8,7 @@
|
||||
public required string Source { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string FallbackSource { get; set; } = "images/home/no_img_main.gif";
|
||||
public string FallbackSource { get; set; } = "images/web/home/not_found_img_main.png"; // "images/web/home/no_img_main.gif";
|
||||
|
||||
[Parameter]
|
||||
public bool LazyLoading { get; set; } = true;
|
||||
@@ -22,6 +22,10 @@
|
||||
[Parameter]
|
||||
public string? ImageClass { get; set; }
|
||||
|
||||
private string? currentSource;
|
||||
private bool hasSourceErrored = false;
|
||||
private bool hasFallbackSourceErrored = false;
|
||||
|
||||
private bool _isLoaded;
|
||||
private string? _lastSource;
|
||||
|
||||
@@ -33,6 +37,10 @@
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
currentSource = Source;
|
||||
hasSourceErrored = false;
|
||||
hasFallbackSourceErrored = false;
|
||||
|
||||
if (!string.Equals(_lastSource, Source, StringComparison.Ordinal))
|
||||
{
|
||||
_lastSource = Source;
|
||||
@@ -103,4 +111,20 @@
|
||||
{
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
private void OnImageError()
|
||||
{
|
||||
if (!hasSourceErrored && !string.IsNullOrEmpty(FallbackSource))
|
||||
{
|
||||
hasSourceErrored = true;
|
||||
currentSource = FallbackSource;
|
||||
StateHasChanged();
|
||||
}
|
||||
else if (!hasFallbackSourceErrored)
|
||||
{
|
||||
hasFallbackSourceErrored = true;
|
||||
currentSource = "images/web/home/not_found_img_main.png";
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.Domain.Enums
|
||||
@using JSMR.UI.Blazor.Components.Chips
|
||||
@using JSMR.UI.Blazor.Enums
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
@@ -8,7 +9,7 @@
|
||||
|
||||
<div class=@GetCardClasses(Product)>
|
||||
<div class="j-voice-work-image-container">
|
||||
<JImage OverlayClass="j-voice-work-image-overlay" ImageClass="j-voice-work-image" Source="@ImageUrlProvider.GetImageUrl(Product, "main")"></JImage>
|
||||
<JImage OverlayClass="j-voice-work-image-overlay" ImageClass="j-voice-work-image" Source="@ImageUrlProvider.GetImageUrl(Product, "main")" FallbackSource="@ImageUrlProvider.GetImageUrl(Product, "main", "webp")"></JImage>
|
||||
</div>
|
||||
<div class="j-voice-work-content">
|
||||
<div class="j-product-title">
|
||||
@@ -21,6 +22,7 @@
|
||||
Target="_blank"
|
||||
Variant="MudBlazor.Variant.Filled"
|
||||
Icon="@Icons.Material.Outlined.Circle">@Product.Maker</MudChip>
|
||||
@* <CircleChip Circle="@Product.Circle"></CircleChip> *@
|
||||
@foreach (var creator in Product.Creators)
|
||||
{
|
||||
<MudChip T="string"
|
||||
@@ -28,6 +30,7 @@
|
||||
Target="_blank"
|
||||
Variant="MudBlazor.Variant.Filled"
|
||||
Icon="@Icons.Material.Filled.Person">@creator.Name</MudChip>
|
||||
@* <CreatorChip Creator="@creator"></CreatorChip> *@
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
@@ -39,6 +42,12 @@
|
||||
<ProductTag Tag="tag"></ProductTag>
|
||||
}
|
||||
</div>
|
||||
<div class="j-tags">
|
||||
@foreach (var tag in Product.Tags)
|
||||
{
|
||||
@* <TagChip Tag="tag"></TagChip> *@
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="j-voice-work-info">
|
||||
<div class="j-release-date-container">
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.Application.Tags.Queries.Search.Contracts
|
||||
@using JSMR.Application.VoiceWorks.Queries.Search
|
||||
@using JSMR.UI.Blazor.Filters
|
||||
@using JSMR.UI.Blazor.Services
|
||||
@using Microsoft.AspNetCore.WebUtilities
|
||||
|
||||
<a class="j-tag" @onclick="@OnClick">@Tag.Name</a>
|
||||
<a class="@Classes" @onclick="@OnClick"><Icon Graphic="Enums.Graphic.Tag" Color="Enums.ColorVarient.Primary"></Icon>@Tag.Name</a>
|
||||
@* <MudChip T="string" Icon="@Icons.Material.Outlined.Tag" @onclick="@OnClick" Variant="@MudBlazor.Variant.Filled" Color="@MudBlazor.Color.Surface">@Tag.Name</MudChip> *@
|
||||
|
||||
@code {
|
||||
@@ -12,6 +14,25 @@
|
||||
[Parameter]
|
||||
public required VoiceWorkTagItem Tag { get; set; }
|
||||
|
||||
private string Classes => GetClasses();
|
||||
|
||||
private string GetClasses()
|
||||
{
|
||||
List<string> classNames = ["j-tag", "j-tag-2"];
|
||||
|
||||
if (Tag.IsFavorite)
|
||||
{
|
||||
classNames.Add("j-tag-favorite");
|
||||
}
|
||||
|
||||
if (Tag.IsBlacklisted)
|
||||
{
|
||||
classNames.Add("j-tag-blacklisted");
|
||||
}
|
||||
|
||||
return string.Join(" ", classNames);
|
||||
}
|
||||
|
||||
private void OnClick()
|
||||
{
|
||||
VoiceWorkFilterState state = new()
|
||||
|
||||
@@ -16,6 +16,7 @@ public enum ColorVarient
|
||||
Black,
|
||||
Yellow,
|
||||
Green,
|
||||
Mint,
|
||||
Teal,
|
||||
Blue,
|
||||
Orange,
|
||||
@@ -35,6 +36,7 @@ public static class CssUtil
|
||||
ColorVarient.SurfaceContainerOutlineLow => "surface-container-outline-low",
|
||||
ColorVarient.Yellow => "text-yellow",
|
||||
ColorVarient.Green => "text-green",
|
||||
ColorVarient.Mint => "text-mint",
|
||||
ColorVarient.Teal => "text-teal",
|
||||
ColorVarient.Blue => "text-blue",
|
||||
ColorVarient.Orange => "text-orange",
|
||||
@@ -50,6 +52,7 @@ public static class CssUtil
|
||||
ColorVarient.SurfaceContainerLow => "surface-container-low",
|
||||
ColorVarient.Yellow => "text-yellow",
|
||||
ColorVarient.Green => "text-green",
|
||||
ColorVarient.Mint => "text-mint",
|
||||
ColorVarient.Teal => "text-teal",
|
||||
ColorVarient.Blue => "text-blue",
|
||||
ColorVarient.Orange => "text-orange",
|
||||
|
||||
8
JSMR.UI.Blazor/Enums/ElementVarient.cs
Normal file
8
JSMR.UI.Blazor/Enums/ElementVarient.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace JSMR.UI.Blazor.Enums;
|
||||
|
||||
public enum ElementVarient
|
||||
{
|
||||
None = 0,
|
||||
Filled = 1,
|
||||
Outlined = 2
|
||||
}
|
||||
7
JSMR.UI.Blazor/Enums/ImageExtension.cs
Normal file
7
JSMR.UI.Blazor/Enums/ImageExtension.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace JSMR.UI.Blazor.Enums;
|
||||
|
||||
public enum ImageExtension
|
||||
{
|
||||
Jpeg,
|
||||
WebP
|
||||
}
|
||||
8
JSMR.UI.Blazor/Enums/ToneVarient.cs
Normal file
8
JSMR.UI.Blazor/Enums/ToneVarient.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace JSMR.UI.Blazor.Enums;
|
||||
|
||||
public enum ToneVarient
|
||||
{
|
||||
None = 0,
|
||||
Tint = 1,
|
||||
Solid = 2
|
||||
}
|
||||
@@ -1,15 +1,21 @@
|
||||
using JSMR.Application.VoiceWorks.Queries.Search;
|
||||
using JSMR.UI.Blazor.Enums;
|
||||
|
||||
namespace JSMR.UI.Blazor.Services;
|
||||
|
||||
public static class ImageUrlProvider
|
||||
{
|
||||
public static string GetImageUrl(VoiceWorkSearchResult voiceWork, string size)
|
||||
public static string GetImageUrl(VoiceWorkSearchResult voiceWork, string size, string extension = "jpg")
|
||||
{
|
||||
return GetImageURL(voiceWork.OriginalProductId ?? voiceWork.ProductId, voiceWork.HasImage, voiceWork.SalesDate, size);
|
||||
return GetImageURL(voiceWork.OriginalProductId ?? voiceWork.ProductId, voiceWork.HasImage, voiceWork.SalesDate, size, extension);
|
||||
}
|
||||
|
||||
public static string GetImageURL(string? productId, bool hasImage, DateTime? salesDate, string size)
|
||||
public static string GetImageUrl(VoiceWorkSearchResult voiceWork, ImageSize imageSize, ImageExtension imageExtension)
|
||||
{
|
||||
return GetImageUrl(voiceWork.OriginalProductId ?? voiceWork.ProductId, voiceWork.HasImage, voiceWork.SalesDate.HasValue, imageSize, imageExtension);
|
||||
}
|
||||
|
||||
public static string GetImageURL(string? productId, bool hasImage, DateTime? salesDate, string size, string extension = "jpg")
|
||||
{
|
||||
string folder = "modpub";
|
||||
string imageSize = "main";
|
||||
@@ -46,7 +52,7 @@ public static class ImageUrlProvider
|
||||
return noImageUrl;
|
||||
}
|
||||
|
||||
var imageUrlTemplate = "//img.dlsite.jp/[folder]/images2/[imageType1]/[imageWorkType]/[fullRoundedProductId]/[productId][imageType2]_img_[imageSize].jpg";
|
||||
var imageUrlTemplate = $"//img.dlsite.jp/[folder]/images2/[imageType1]/[imageWorkType]/[fullRoundedProductId]/[productId][imageType2]_img_[imageSize].{extension}";
|
||||
|
||||
string productIdWithoutPrefixString = productId.Substring(2);
|
||||
int productIdWithoutPrefix = Convert.ToInt32(productId.Substring(2));
|
||||
@@ -78,4 +84,43 @@ public static class ImageUrlProvider
|
||||
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public static string GetImageUrl(string? productId, bool hasImage, bool isOnSale, ImageSize size, ImageExtension extension)
|
||||
{
|
||||
string imageWorkType = productId != null ? productId.StartsWith("RJ") ? "doujin" : "professional" : "doujin";
|
||||
(string imageSize, string folder) = GetImageSizeAndFolder(size, hasImage);
|
||||
|
||||
if (hasImage == false || productId == null)
|
||||
{
|
||||
return $"/images/web/home/no_img_{imageSize}.gif";
|
||||
}
|
||||
|
||||
string productIdWithoutPrefixString = productId.Substring(2);
|
||||
int productIdWithoutPrefix = Convert.ToInt32(productId.Substring(2));
|
||||
|
||||
string productIdPrefix = productId[..2];
|
||||
|
||||
int roundedProductId = (int)Math.Round(Math.Ceiling((double)productIdWithoutPrefix / 1000) * 1000);
|
||||
|
||||
int productIdWithPrefixStringLength = productIdWithoutPrefixString.Length;
|
||||
int zeroPadLength = productIdWithPrefixStringLength - roundedProductId.ToString().Length;
|
||||
|
||||
var fullRoundedProductId = productIdPrefix.PadRight(productIdPrefix.Length + zeroPadLength, '0') + roundedProductId;
|
||||
|
||||
string imageType1 = isOnSale ? "work" : "ana";
|
||||
string imageType2 = isOnSale ? "" : "_ana";
|
||||
|
||||
return $"//img.dlsite.jp/{folder}/images2/{imageType1}/{imageWorkType}/{fullRoundedProductId}/{productId}{imageType2}_img_{imageSize}.{extension}";
|
||||
}
|
||||
|
||||
private static (string, string) GetImageSizeAndFolder(ImageSize imageSize, bool hasImage)
|
||||
{
|
||||
return imageSize switch
|
||||
{
|
||||
ImageSize.Thumb100 => ("sam", "modpub"),
|
||||
ImageSize.Square240 => (hasImage ? "main_240x240" : "main", "resize"),
|
||||
ImageSize.Square300 => (hasImage ? "main_300x300" : "main", "resize"),
|
||||
_ => ("main", "modpub"),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -608,15 +608,90 @@ code {
|
||||
font-weight: 500;*/
|
||||
}
|
||||
|
||||
/* Chips */
|
||||
.j-chip {
|
||||
.j-tag-2 {
|
||||
padding: .4rem .8rem;
|
||||
font-size: .8rem;
|
||||
border-color: var(--tag-text-color);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
background-color: transparent;
|
||||
border-radius: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .5rem;
|
||||
gap: .3rem;
|
||||
}
|
||||
|
||||
.j-tag-favorite {
|
||||
border: 1px solid rgb(167, 243, 208);
|
||||
color: rgb(167, 243, 208);
|
||||
background-color: rgba(67, 243, 208, .1);
|
||||
}
|
||||
|
||||
.j-tag-favorite > .j-icon-tag {
|
||||
background-color: #a7f3d0;
|
||||
}
|
||||
|
||||
.j-tag-blacklisted {
|
||||
border: 1px solid rgb(254, 205, 211);
|
||||
color: rgb(254, 205, 211);
|
||||
background-color: rgba(254, 205, 211, .1);
|
||||
color: #ea9ab2;
|
||||
border: 1px solid #ea9ab2;
|
||||
background-color: #ea9ab222;
|
||||
color: rgb(243, 167, 167);
|
||||
border: 1px solid rgb(243, 167, 167);
|
||||
background-color: rgba(243, 167, 167, .1);
|
||||
}
|
||||
|
||||
/* Chips */
|
||||
.j-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .4rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
font-size: .8rem;
|
||||
font-weight: 400;
|
||||
--chip-rgb: var(--secondary-rgb, 148 163 184);
|
||||
--chip-tint-alpha: 0.12;
|
||||
}
|
||||
|
||||
.j-chip.is-clickable {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.j-chip.varient-filled {
|
||||
padding: .4rem .8rem;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.j-chip.varient-outlined {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
padding: .4rem .8rem;
|
||||
border-radius: 1rem;
|
||||
border-color: rgb(var(--chip-rgb));
|
||||
color: rgb(var(--chip-rgb));
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.j-chip.tone-tint {
|
||||
background: rgb(var(--chip-rgb) / var(--chip-tint-alpha));
|
||||
}
|
||||
|
||||
.j-chip.color-mint {
|
||||
--chip-rgb: var(--rgb-mint);
|
||||
}
|
||||
|
||||
.j-chip.color-green {
|
||||
--chip-rgb: var(--rgb-green);
|
||||
}
|
||||
|
||||
.j-chip.color-teal {
|
||||
--chip-rgb: var(--rgb-teal);
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.j-icon {
|
||||
mask-repeat: no-repeat;
|
||||
@@ -705,6 +780,10 @@ code {
|
||||
mask-image: url("../svg/person.svg");
|
||||
}
|
||||
|
||||
.j-icon-person-fill {
|
||||
mask-image: url("../svg/person-fill.svg");
|
||||
}
|
||||
|
||||
.j-icon-sort {
|
||||
mask-image: url("../svg/sort.svg");
|
||||
}
|
||||
@@ -741,6 +820,39 @@ code {
|
||||
background-image: url("../svg/flag-kr.svg");
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
.color-black {
|
||||
color: var(--color-black);
|
||||
}
|
||||
|
||||
.color-yellow {
|
||||
color: var(--color-yellow);
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
.color-mint {
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
.color-teal {
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
.color-blue {
|
||||
color: var(--color-blue);
|
||||
}
|
||||
|
||||
.color-orange {
|
||||
color: var(--color-orange);
|
||||
}
|
||||
|
||||
.color-pink {
|
||||
color: var(--color-pink);
|
||||
}
|
||||
|
||||
/* Border Colors */
|
||||
.border-color-black {
|
||||
border-color: var(--color-black);
|
||||
@@ -754,6 +866,11 @@ code {
|
||||
border-color: var(--color-green);
|
||||
}
|
||||
|
||||
.border-color-mint {
|
||||
border-color: var(--color-mint);
|
||||
}
|
||||
|
||||
|
||||
.border-color-teal {
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
@@ -799,6 +916,10 @@ code {
|
||||
background-color: var(--color-green);
|
||||
}
|
||||
|
||||
.background-color-mint {
|
||||
background-color: var(--color-mint);
|
||||
}
|
||||
|
||||
.background-color-teal {
|
||||
background-color: var(--color-teal);
|
||||
}
|
||||
|
||||
@@ -39,12 +39,17 @@
|
||||
--input-background-color: rgb(0,20,34);
|
||||
--input-focus-border-color: #64b5f6;
|
||||
--input-focus-box-shadow: 0 0 0 1px #93cbf9;
|
||||
/* RGB Tokens */
|
||||
--rgb-mint: 167 243 208;
|
||||
--rgb-green: 175 224 125;
|
||||
--rgb-teal: 110 236 255;
|
||||
/* Colors */
|
||||
--color-primary: rgb(180,200, 214);
|
||||
--color-secondary: rgb(200,220,234);
|
||||
--color-black: #272727;
|
||||
--color-yellow: #ffe073;
|
||||
--color-green: #afe07d;
|
||||
--color-mint: #a7f3d0;
|
||||
--color-teal: #6eecff;
|
||||
--color-blue: #73c4ff;
|
||||
--color-orange: #ffa773;
|
||||
|
||||
BIN
JSMR.UI.Blazor/wwwroot/images/web/home/not_found_img_main.png
Normal file
BIN
JSMR.UI.Blazor/wwwroot/images/web/home/not_found_img_main.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Reference in New Issue
Block a user