Utilized more BitBlazor components. Added enhancements to voice work search.

This commit is contained in:
2025-11-27 22:13:33 -05:00
parent 403c436a34
commit b2ef08c995
4 changed files with 223 additions and 100 deletions

View File

@@ -6,6 +6,11 @@
@using JSMR.UI.Blazor.Filters @using JSMR.UI.Blazor.Filters
@using JSMR.UI.Blazor.Services @using JSMR.UI.Blazor.Services
<div class="search-toolbar">
<BitMenuButton TItem="BitMenuButtonItem" Text="Presets" Items="presets" Variant="BitVariant.Outline" OnClick="test" />
<BitToggleButton @bind-IsChecked="showAdvancedFilters" Text="@(showAdvancedFilters ? "Advanced" : "Basic")" Variant="BitVariant.Outline" />
</div>
<div class="search-filter-control-container"> <div class="search-filter-control-container">
<div class="search-filter-control-span-2"> <div class="search-filter-control-span-2">
<BitTextField Prefix="Keywords" <BitTextField Prefix="Keywords"
@@ -69,94 +74,97 @@
Value="@Value.CreatorStatus" Value="@Value.CreatorStatus"
ValueChanged="@(value => Update(Value with { CreatorStatus = value }))" /> ValueChanged="@(value => Update(Value with { CreatorStatus = value }))" />
</div> </div>
<!-- Row 3 --> @if (showAdvancedFilters)
<div class="search-filter-control-span-2"> {
<BitDropdown Prefix="Tags" <!-- Row 3 -->
Items="tags" <div class="search-filter-control-span-2">
MultiSelect <BitDropdown Prefix="Tags"
Virtualize Items="tags"
ShowSearchBox MultiSelect
AutoFocusSearchBox Virtualize
Chips ShowSearchBox
Placeholder="Select..." AutoFocusSearchBox
TItem="BitDropdownItem<int>" Chips
TValue="int" Placeholder="Select..."
Values="@Value.TagIds" TItem="BitDropdownItem<int>"
ValuesChanged="@(values => Update(Value with { TagIds = [.. values] }))" /> TValue="int"
</div> Values="@Value.TagIds"
<div class="search-filter-control-span-1"> ValuesChanged="@(values => Update(Value with { TagIds = [.. values] }))" />
<BitCheckbox Label="Include All Tags" </div>
Value="@Value.IncludeAllTags" <div class="search-filter-control-span-1">
ValueChanged="@(value => Update(Value with { IncludeAllTags = value }))" /> <BitCheckbox Label="Include All Tags"
</div> Value="@Value.IncludeAllTags"
<div class="search-filter-control-span-1"></div> ValueChanged="@(value => Update(Value with { IncludeAllTags = value }))" />
<!-- Row 4 --> </div>
<div class="search-filter-control-span-2"> <div class="search-filter-control-span-1"></div>
<BitDropdown Prefix="Creators" <!-- Row 4 -->
Items="creators" <div class="search-filter-control-span-2">
MultiSelect <BitDropdown Prefix="Creators"
Virtualize Items="creators"
ShowSearchBox MultiSelect
AutoFocusSearchBox Virtualize
Chips ShowSearchBox
Placeholder="Select..." AutoFocusSearchBox
TItem="BitDropdownItem<int>" Chips
TValue="int" Placeholder="Select..."
Values="@Value.CreatorIds" TItem="BitDropdownItem<int>"
ValuesChanged="@(values => Update(Value with { CreatorIds = [.. values] }))" /> TValue="int"
</div> Values="@Value.CreatorIds"
<div class="search-filter-control-span-1"> ValuesChanged="@(values => Update(Value with { CreatorIds = [.. values] }))" />
<BitCheckbox Label="Include All Creators" </div>
Value="@Value.IncludeAllCreators" <div class="search-filter-control-span-1">
ValueChanged="@(value => Update(Value with { IncludeAllCreators = value }))" /> <BitCheckbox Label="Include All Creators"
</div> Value="@Value.IncludeAllCreators"
<div class="search-filter-control-span-1"></div> ValueChanged="@(value => Update(Value with { IncludeAllCreators = value }))" />
<!-- Row 5 --> </div>
<div class="search-filter-control-span-1"> <div class="search-filter-control-span-1"></div>
<BitCheckbox Label="Show Only Favorite Works" <!-- Row 5 -->
Value="@Value.ShowFavorite" <div class="search-filter-control-span-1">
ValueChanged="@(value => Update(Value with { ShowFavorite = value }))" /> <BitCheckbox Label="Show Only Favorite Works"
</div> Value="@Value.ShowFavorite"
<div class="search-filter-control-span-1"> ValueChanged="@(value => Update(Value with { ShowFavorite = value }))" />
<BitCheckbox Label="Show Only Invalid Works" </div>
Value="@Value.ShowInvalid" <div class="search-filter-control-span-1">
ValueChanged="@(value => Update(Value with { ShowInvalid = value }))" /> <BitCheckbox Label="Show Only Invalid Works"
</div> Value="@Value.ShowInvalid"
<div class="search-filter-control-span-2"></div> ValueChanged="@(value => Update(Value with { ShowInvalid = value }))" />
<div class="search-filter-control-span-1"> </div>
<BitDropdown Label="Age Ratings" <div class="search-filter-control-span-2"></div>
MultiSelect <div class="search-filter-control-span-1">
Items="ageRatings" <BitDropdown Label="Age Ratings"
Placeholder="Select..." MultiSelect
TItem="BitDropdownItem<AgeRating>" Items="ageRatings"
TValue="AgeRating" Placeholder="Select..."
Values="@Value.AgeRatings" TItem="BitDropdownItem<AgeRating>"
ValuesChanged="@(values => Update(Value with { AgeRatings = [.. values] }))" /> TValue="AgeRating"
</div> Values="@Value.AgeRatings"
<div class="search-filter-control-span-1"> ValuesChanged="@(values => Update(Value with { AgeRatings = [.. values] }))" />
<BitDatePicker Label="Release Date Start" </div>
ShowClearButton="true" <div class="search-filter-control-span-1">
Value="@ToDto(Value.ReleaseDateStart)" <BitDatePicker Label="Release Date Start"
ValueChanged="@(value => Update(Value with { ReleaseDateStart = FromDto(value) }))" /> ShowClearButton="true"
</div> Value="@ToDto(Value.ReleaseDateStart)"
<div class="search-filter-control-span-1"> ValueChanged="@(value => Update(Value with { ReleaseDateStart = FromDto(value) }))" />
<BitDatePicker Label="Release Date End" </div>
ShowClearButton="true" <div class="search-filter-control-span-1">
Value="@ToDto(Value.ReleaseDateEnd)" <BitDatePicker Label="Release Date End"
ValueChanged="@(value => Update(Value with { ReleaseDateEnd = FromDto(value) }))" /> ShowClearButton="true"
</div> Value="@ToDto(Value.ReleaseDateEnd)"
<div class="search-filter-control-span-2"> ValueChanged="@(value => Update(Value with { ReleaseDateEnd = FromDto(value) }))" />
<BitDropdown Prefix="Sort" </div>
Items="sortOptions" <div class="search-filter-control-span-2">
Placeholder="Select..." <BitDropdown Prefix="Sort"
TItem="BitDropdownItem<VoiceWorkSort>" Items="sortOptions"
TValue="VoiceWorkSort" Placeholder="Select..."
Value="@Value.Sort" TItem="BitDropdownItem<VoiceWorkSort>"
ValueChanged="@(value => Update(Value with { Sort = value }))" /> TValue="VoiceWorkSort"
</div> Value="@Value.Sort"
@* <div class="search-filter-control-span-1"> ValueChanged="@(value => Update(Value with { Sort = value }))" />
</div>
@* <div class="search-filter-control-span-1">
<BitSlider Label="Downloads" Min="0" Max="100000" Value="MinDownloads" ValueChanged="OnMinDownloadsChanged" /> <BitSlider Label="Downloads" Min="0" Max="100000" Value="MinDownloads" ValueChanged="OnMinDownloadsChanged" />
</div> *@ </div> *@
}
</div> </div>
@code { @code {
@@ -169,6 +177,8 @@
[Parameter] [Parameter]
public EventCallback<VoiceWorkFilterState> ValueChanged { get; set; } public EventCallback<VoiceWorkFilterState> ValueChanged { get; set; }
private bool showAdvancedFilters { get; set; }
List<BitDropdownItem<Locale>> locales = []; List<BitDropdownItem<Locale>> locales = [];
List<BitDropdownItem<SaleStatus?>> saleStatuses = []; List<BitDropdownItem<SaleStatus?>> saleStatuses = [];
List<BitDropdownItem<CircleStatus?>> circleStatuses = []; List<BitDropdownItem<CircleStatus?>> circleStatuses = [];
@@ -180,6 +190,16 @@
List<BitDropdownItem<int>> tags = []; List<BitDropdownItem<int>> tags = [];
List<BitDropdownItem<int>> creators = []; List<BitDropdownItem<int>> creators = [];
private List<BitMenuButtonItem> presets =
[
new() { Text = "Default", Key = "Default" },
new() { Text = "Released English", Key = "Released-English" },
new() { Text = "Popular Upcoming", Key = "Favorite-Upcoming" },
new() { Text = "Popular This Week", Key = "Popular-ThisWeek" },
new() { Text = "Popular This Month", Key = "Popular-ThisMonth" },
new() { Text = "Popular This Year", Key = "Popular-ThisYear" },
];
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
locales = Lookups.GetLocales(); locales = Lookups.GetLocales();
@@ -205,4 +225,89 @@
// Map DateTimeOffset? -> DateOnly? // Map DateTimeOffset? -> DateOnly?
private static DateOnly? FromDto(DateTimeOffset? dto) => private static DateOnly? FromDto(DateTimeOffset? dto) =>
dto is null ? null : DateOnly.FromDateTime(dto.Value.Date); dto is null ? null : DateOnly.FromDateTime(dto.Value.Date);
private async Task test(BitMenuButtonItem? item)
{
if (item is null)
return;
if (item.Key == "Default")
{
Value = new()
{
SaleStatus = SaleStatus.Available,
CircleStatus = CircleStatus.NotBlacklisted,
TagStatus = TagStatus.NotBlacklisted,
CreatorStatus = CreatorStatus.NotBlacklisted,
SupportedLanguages = [Language.Japanese, Language.English],
Locale = Locale.English
};
_ = Update(Value);
}
else if (item.Key == "Released-English")
{
Value = new()
{
SaleStatus = SaleStatus.Available,
SupportedLanguages = [Language.English],
Locale = Locale.English,
Sort = VoiceWorkSort.ReleaseDateNewToOld
};
_ = Update(Value);
}
else if (item.Key == "Favorite-Upcoming")
{
Value = new()
{
SaleStatus = SaleStatus.Upcoming,
CircleStatus = CircleStatus.Favorited,
SupportedLanguages = [Language.Japanese, Language.English],
Locale = Locale.English,
Sort = VoiceWorkSort.MostFavorited
};
_ = Update(Value);
}
else if (item.Key == "Popular-ThisWeek")
{
Value = new()
{
SaleStatus = SaleStatus.Available,
SupportedLanguages = [Language.Japanese, Language.English],
Locale = Locale.English,
Sort = VoiceWorkSort.BestSelling,
ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-8))
};
_ = Update(Value);
}
else if (item.Key == "Popular-ThisMonth")
{
Value = new()
{
SaleStatus = SaleStatus.Available,
SupportedLanguages = [Language.Japanese, Language.English],
Locale = Locale.English,
Sort = VoiceWorkSort.BestSelling,
ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-29))
};
_ = Update(Value);
}
else if (item.Key == "Popular-ThisYear")
{
Value = new()
{
SaleStatus = SaleStatus.Available,
SupportedLanguages = [Language.Japanese, Language.English],
Locale = Locale.English,
Sort = VoiceWorkSort.BestSelling,
ReleaseDateStart = DateOnly.FromDateTime(DateTime.Now.AddDays(-366))
};
_ = Update(Value);
}
}
} }

View File

@@ -6,17 +6,17 @@
<PageTitle>Home</PageTitle> <PageTitle>Home</PageTitle>
<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6"> <BitPivot Size="BitSize.Medium">
<MudTabPanel Text="Available" Icon="@Icons.Material.Filled.Home"> <BitPivotItem HeaderText="@($"Available ({availableVoiceWorks?.Length ?? 0})")">
<JProductCollection Products="availableVoiceWorks"></JProductCollection> <JProductCollection Products="availableVoiceWorks"></JProductCollection>
</MudTabPanel> </BitPivotItem>
<MudTabPanel Text="Upcoming" Icon="@Icons.Material.Filled.ArrowUpward"> <BitPivotItem HeaderText="@($"Upcoming ({upcomingVoiceWorks?.Length ?? 0})")">
<JProductCollection Products="upcomingVoiceWorks"></JProductCollection> <JProductCollection Products="upcomingVoiceWorks"></JProductCollection>
</MudTabPanel> </BitPivotItem>
<MudTabPanel Text="Announcements" Icon="@Icons.Material.Filled.Home"> <BitPivotItem HeaderText="@($"Announcements ({announcedVoiceWorks?.Length ?? 0})")">
<JProductCollection Products="announcedVoiceWorks"></JProductCollection> <JProductCollection Products="announcedVoiceWorks"></JProductCollection>
</MudTabPanel> </BitPivotItem>
</MudTabs> </BitPivot>
@code { @code {
VoiceWorkSearchResult[]? availableVoiceWorks; VoiceWorkSearchResult[]? availableVoiceWorks;
@@ -29,9 +29,6 @@
_ = LoadUpcomingVoiceWorksAsync(); _ = LoadUpcomingVoiceWorksAsync();
_ = LoadAnnouncedVoiceWorksAsync(); _ = LoadAnnouncedVoiceWorksAsync();
// availableVoiceWorks = await GetAvailableVoiceWorksAsync();
// upcomingVoiceWorks = await GetUpcomingVoiceWorksAsync();
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -55,7 +52,7 @@
var result = await Client.SearchAsync(request); var result = await Client.SearchAsync(request);
availableVoiceWorks = result.Results.Items; availableVoiceWorks = result?.Results.Items;
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
@@ -80,7 +77,7 @@
var result = await Client.SearchAsync(request); var result = await Client.SearchAsync(request);
upcomingVoiceWorks = result.Results.Items; upcomingVoiceWorks = result?.Results.Items;
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
@@ -104,7 +101,7 @@
var result = await Client.SearchAsync(request); var result = await Client.SearchAsync(request);
announcedVoiceWorks = result.Results.Items; announcedVoiceWorks = result?.Results.Items;
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }

View File

@@ -116,6 +116,12 @@ code {
/* Custom */ /* Custom */
/* Search Filters */ /* Search Filters */
.search-toolbar {
display: flex;
justify-content: flex-end;
gap: 1em;
}
.search-filter-control-container { .search-filter-control-container {
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;

View File

@@ -1,3 +1,12 @@
.bit-tfl {
width: 100%;
}
.bit-tfl-inp {
font-family: var(--font-family);
}
.bit-tfl-inp, .bit-tfl-inp,
.bit-drp-wrp, .bit-drp-wrp,
.bit-dtp-wrp { .bit-dtp-wrp {
@@ -65,4 +74,10 @@
.bit-drp-pre, .bit-drp-suf { .bit-drp-pre, .bit-drp-suf {
background: rgb(57, 79, 94); background: rgb(57, 79, 94);
}
.bit-pvt-cct {
font-weight: inherit;
font-size: inherit;
color: inherit;
} }