Updated search logic. More UI updates.
All checks were successful
ci / build-test (push) Successful in 2m17s
ci / publish-image (push) Has been skipped

This commit is contained in:
2025-11-17 21:05:55 -05:00
parent 9ef1972472
commit 2418bd0a8f
13 changed files with 430 additions and 108 deletions

View File

@@ -2,8 +2,8 @@
<div>
<label>@IndexInfo</label>
</div>
<MudPagination ShowFirstButton="true" ShowLastButton="true" Count="@((int)Math.Ceiling((decimal)TotalItems / (decimal)PageSize))" Selected="@PageNumber" SelectedChanged="OnSelectedChanged" />
<div>
<MudPagination class="pager" ShowFirstButton="true" ShowLastButton="true" Count="@((int)Math.Ceiling((decimal)TotalItems / (decimal)PageSize))" Selected="@PageNumber" SelectedChanged="OnSelectedChanged" />
<div class="page-sizes">
<MudSelect T="int" Value="PageSize" ValueChanged="OnPageSizeChanged" Dense="true" Variant="Variant.Outlined" Margin="Margin.Dense">
@foreach (int value in PageSizes)
{

View File

@@ -7,18 +7,20 @@
<JImage OverlayClass="j-voice-work-image-overlay" ImageClass="j-voice-work-image" Source="@ImageUrlProvider.GetImageUrl(Product, "main")"></JImage>
</div>
<div class="j-voice-work-content">
<div class="j-product-title">@Product.ProductName</div>
<div class="j-product-title">
<a href="@Product.ProductUrl" target="_blank">@Product.ProductName</a>
</div>
<div class="j-product-contributors">
<span class="j-circle">
<MudChip T="string"
Href="https://github.com/MudBlazor/MudBlazor"
Href=@($"https://www.dlsite.com/maniax/circle/profile/=/maker_id/{Product.MakerId}.html")
Target="_blank"
Variant="Variant.Filled"
Icon="@Icons.Material.Outlined.Circle">@Product.Maker</MudChip>
@foreach (var creator in Product.Creators)
{
<MudChip T="string"
Href="https://github.com/MudBlazor/MudBlazor"
Href=@($"https://www.dlsite.com/maniax/fsr/=/keyword_creater/{creator.Name}")
Target="_blank"
Variant="Variant.Filled"
Icon="@Icons.Material.Filled.Person">@creator.Name</MudChip>
@@ -36,7 +38,7 @@
<div class="j-voice-work-info">
<div class="j-release-date-container">
<span class="j-icon j-icon-calendar"></span>
<span>@GetSomething(Product)</span>
<span>@GetReleaseDateText(Product)</span>
</div>
<div class="j-wishlist-container">
<span class="j-icon j-icon-star j-icon-color-yellow"></span>
@@ -49,6 +51,14 @@
<span>@((Product.Downloads ?? 0).ToString("n0"))</span>
</div>
}
@* <div class="j-icon-2 j-icon-2-flag-@GetFlagClassSuffix(Product)"></div> *@
<div class="j-spacer"></div>
@if (Product.HasTrial || Product.HasChobit)
{
<div class="j-trial-container">
<div class="j-icon j-icon-headphones"></div>
</div>
}
</div>
</div>
@@ -56,7 +66,7 @@
[Parameter]
public required VoiceWorkSearchResult Product { get; set; }
private string GetSomething(VoiceWorkSearchResult voiceWork)
private string GetReleaseDateText(VoiceWorkSearchResult voiceWork)
{
if (voiceWork.SalesDate.HasValue)
{
@@ -82,4 +92,19 @@
return "Unknown";
}
private string GetFlagClassSuffix(VoiceWorkSearchResult voiceWork)
{
switch (voiceWork.SubtitleLanguage)
{
case 1:
return "us";
case 2:
return "cn";
case 3:
return "kr";
default:
return "jp";
}
}
}

View File

@@ -18,67 +18,6 @@
</MudTabPanel>
</MudTabs>
<style>
.j-product-items-container {
display: flex;
flex-direction: column;
gap: 2rem;
}
.j-voice-work-card {
display: flex;
gap: 1rem;
background-image: linear-gradient(0deg, rgb(30, 53, 69), rgb(39, 59, 73));
border-color: rgb(63, 78, 88);
background-image: linear-gradient(0deg, rgb(30, 53, 69), rgb(57, 79, 94));
}
.j-voice-work-image-container {
width: 240px;
width: 300px;
}
.j-voice-work-card > .j-voice-work-image-container {
flex-shrink: 0;
}
.j-voice-work-image {
border-radius: 20px;
}
.j-voice-work-content {
display: flex;
flex-direction: column;
gap: .5rem;
}
.j-voice-work-card > .j-voice-work-content {
flex-grow: 1;
}
.j-product-title {
font-size: 1.25rem;
font-weight: 600;
font-family: "Poppins", "M+ 1p";
color: #d2dce6;
text-shadow: 1px 1px 2px black;
}
.j-product-description {
/* color: #7C8099; */
font-size: 1rem;
font-family: "Poppins", "M+ 1p";
}
.j-voice-work-info {
width: 240px;
}
.j-voice-work-card > .j-voice-work-info {
flex-shrink: 0;
}
</style>
@code {
VoiceWorkSearchResult[]? availableVoiceWorks;
VoiceWorkSearchResult[]? upcomingVoiceWorks;

View File

@@ -14,6 +14,39 @@
<div class="search-filter-control-span-4">
<MudTextField T="string" Value="Keywords" ValueChanged="OnKeywordsChanged" Immediate="true" DebounceInterval="500" Label="Filter" Variant="Variant.Text" Adornment="@Adornment.Start" AdornmentIcon="@Icons.Material.Outlined.Search" />
</div>
<div class="search-filter-control-span-1">
<MudSelect T="string" Value="SelectedSaleStatus" ValueChanged="OnSaleStatusChanged" Label="Sale Status" Variant="Variant.Text">
<MudSelectItem Value="@SaleStatus.Available.ToString()">Available</MudSelectItem>
<MudSelectItem Value="@SaleStatus.Upcoming.ToString()">Upcoming</MudSelectItem>
<MudSelectItem Value="@String.Empty">All</MudSelectItem>
</MudSelect>
</div>
<div class="search-filter-control-span-1">
<MudSelect T="string" Value="SelectedCircleStatus" ValueChanged="OnCircleStatusChanged" Label="Circle Status" Variant="Variant.Text">
<MudSelectItem Value="@CircleStatus.NotBlacklisted.ToString()">Not Blacklisted</MudSelectItem>
<MudSelectItem Value="@CircleStatus.Favorited.ToString()">Favorite</MudSelectItem>
<MudSelectItem Value="@CircleStatus.Blacklisted.ToString()">Blacklisted</MudSelectItem>
<MudSelectItem Value="@String.Empty">All</MudSelectItem>
</MudSelect>
</div>
<div class="search-filter-control-span-1">
<MudSelect T="string" Value="SelectedTagStatus" ValueChanged="OnTagStatusChanged" Label="Tag Status" Dense="true" Variant="Variant.Outlined" Margin="Margin.Dense" Adornment="@Adornment.Start" AdornmentIcon="@Icons.Material.Outlined.Search">
<MudSelectItem Value="@TagStatus.NotBlacklisted.ToString()">Not Blacklisted</MudSelectItem>
<MudSelectItem Value="@TagStatus.FavoriteExcludeBlacklist.ToString()">Favorite (Exclude Blacklisted)</MudSelectItem>
<MudSelectItem Value="@TagStatus.FavoriteIncludeBlacklist.ToString()">Favorite (Include Blacklisted)</MudSelectItem>
<MudSelectItem Value="@TagStatus.Blacklisted.ToString()">Blacklisted</MudSelectItem>
<MudSelectItem Value="@String.Empty">All</MudSelectItem>
</MudSelect>
</div>
<div class="search-filter-control-span-1">
<MudSelect T="string" Value="SelectedCreatorStatus" ValueChanged="OnCreatorStatusChanged" Label="Creator Status" Dense="true" Variant="Variant.Outlined" Margin="Margin.Dense" Adornment="@Adornment.Start" AdornmentIcon="@Icons.Material.Outlined.Search">
<MudSelectItem Value="@CreatorStatus.NotBlacklisted.ToString()">Not Blacklisted</MudSelectItem>
<MudSelectItem Value="@CreatorStatus.FavoriteExcludeBlacklist.ToString()">Favorite (Exclude Blacklisted)</MudSelectItem>
<MudSelectItem Value="@CreatorStatus.FavoriteIncludeBlacklist.ToString()">Favorite (Include Blacklisted)</MudSelectItem>
<MudSelectItem Value="@CreatorStatus.Blacklisted.ToString()">Blacklisted</MudSelectItem>
<MudSelectItem Value="@String.Empty">All</MudSelectItem>
</MudSelect>
</div>
</div>
<JProductCollection Products="searchResults?.Items"></JProductCollection>
@@ -25,6 +58,10 @@
@code {
public string? Keywords { get; set; }
public string? SelectedSaleStatus { get; set; } = string.Empty;
public string? SelectedCircleStatus { get; set; } = string.Empty;
public string? SelectedTagStatus { get; set; } = string.Empty;
public string? SelectedCreatorStatus { get; set; } = string.Empty;
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 100;
@@ -48,11 +85,15 @@
Criteria = new()
{
Keywords = Keywords,
SupportedLanguages = [Domain.Enums.Language.English]
SaleStatus = string.IsNullOrWhiteSpace(SelectedSaleStatus) == false ? Enum.Parse<SaleStatus>(SelectedSaleStatus) : null,
CircleStatus = string.IsNullOrWhiteSpace(SelectedCircleStatus) == false ? Enum.Parse<CircleStatus>(SelectedCircleStatus) : null,
TagStatus = string.IsNullOrWhiteSpace(SelectedTagStatus) == false ? Enum.Parse<TagStatus>(SelectedTagStatus) : null,
CreatorStatus = string.IsNullOrWhiteSpace(SelectedCreatorStatus) == false ? Enum.Parse<CreatorStatus>(SelectedCreatorStatus) : null,
//SupportedLanguages = [Domain.Enums.Language.English]
},
SortOptions =
[
new(VoiceWorkSortField.ReleaseDate, Application.Common.Search.SortDirection.Descending)
new(GetSortField(), Application.Common.Search.SortDirection.Descending)
],
PageNumber = PageNumber,
PageSize = PageSize
@@ -70,6 +111,30 @@
await UpdateDataAsync(true);
}
public async Task OnSaleStatusChanged(string? saleStatus)
{
SelectedSaleStatus = saleStatus;
await UpdateDataAsync(true);
}
public async Task OnCircleStatusChanged(string? circleStatus)
{
SelectedCircleStatus = circleStatus;
await UpdateDataAsync(true);
}
public async Task OnTagStatusChanged(string? tagStatus)
{
SelectedTagStatus = tagStatus;
await UpdateDataAsync(true);
}
public async Task OnCreatorStatusChanged(string? creatorStatus)
{
SelectedCreatorStatus = creatorStatus;
await UpdateDataAsync(true);
}
public async Task OnPageNumberChanged(int newPageNumber)
{
PageNumber = newPageNumber;
@@ -81,4 +146,19 @@
PageSize = newPageSize;
await UpdateDataAsync(true);
}
private VoiceWorkSortField GetSortField()
{
SaleStatus? saleStatus = string.IsNullOrWhiteSpace(SelectedSaleStatus) == false ? Enum.Parse<SaleStatus>(SelectedSaleStatus) : null;
switch (saleStatus)
{
case SaleStatus.Available:
return VoiceWorkSortField.ReleaseDate;
case SaleStatus.Upcoming:
return VoiceWorkSortField.ExpectedReleaseDate;
default:
return VoiceWorkSortField.AnyReleaseDate;
}
}
}

View File

@@ -200,6 +200,20 @@ code {
z-index: 1;
}
.pagination .pager {
padding: 0;
justify-content: center;
}
.pagination > .page-sizes {
justify-content: flex-end;
display: inline-flex;
}
.pagination > .page-sizes > * {
max-width: 6rem;
}
/* Circle */
.j-circle-image-container {
height: 300px;
@@ -330,8 +344,12 @@ code {
width: 100%;
}
/* Product */
/* Spacer */
.j-spacer {
flex-grow: 1;
}
/* Product */
.j-product-items-container {
display: flex;
flex-direction: column;
@@ -344,6 +362,9 @@ code {
background-image: linear-gradient(0deg, rgb(30, 53, 69), rgb(39, 59, 73));
border-color: rgb(63, 78, 88);
background-image: linear-gradient(0deg, rgb(30, 53, 69), rgb(57, 79, 94));
border-top-color: rgb(83, 99, 109);
border-left-color: rgb(72, 88, 99);
border-right-color: rgb(72, 88, 99);
}
.j-voice-work-image-container {
@@ -381,6 +402,15 @@ code {
text-shadow: 1px 1px 2px black;
}
.j-product-title > a,
.j-product-title > a:hover {
color: var(--product-title-text-color);
}
.j-product-title > a:hover {
text-decoration: underline;
}
.j-product-contributors {
font-size: 1rem;
font-family: "Poppins", "M+ 1p";
@@ -437,6 +467,19 @@ code {
gap: .5rem;
font-size: 1rem;
font-weight: 500;
color: #afe07d;
}
.j-trial-container {
border: 1px solid rgb(30, 53, 69);
padding: .5rem;
border-radius: 100%;
border-color: var(--product-title-text-color);
}
.j-trial-container > .j-icon {
width: 16px;
height: 16px;
}
/* Tags */
@@ -461,7 +504,9 @@ code {
/* Icons */
.j-icon {
mask-size: auto;
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
align-self: center;
background: rgb(180,200, 214);
height: 16px;
@@ -474,6 +519,7 @@ code {
.j-icon-color-green {
background: #388E3C;
background: #afe07d;
}
.j-icon-calendar {
@@ -490,4 +536,32 @@ code {
.j-icon-bag-fill {
mask-image: url("../svg/bag-fill.svg");
}
.j-icon-headphones {
mask-image: url("../svg/headphones.svg");
}
.j-icon-2 {
background-repeat: no-repeat;
background-position: center;
background-size: contain;
width: 32px;
height: 32px;
}
.j-icon-2-flag-jp {
background-image: url("../svg/flag-jp.svg");
}
.j-icon-2-flag-us {
background-image: url("../svg/flag-us.svg");
}
.j-icon-2-flag-cn {
background-image: url("../svg/flag-cn.svg");
}
.j-icon-2-flag-kr {
background-image: url("../svg/flag-kr.svg");
}