1
0
mirror of synced 2025-01-19 00:04:05 +01:00

Updated highscore page styling, fixed empty entries

Songs entries can be broken when updating the datatables (if songs are removed). The frontend now filters those empty songs out.
This commit is contained in:
Farewell_ 2024-10-29 14:33:03 +01:00
parent 9cdfb0406b
commit 505b867e1a
16 changed files with 1297 additions and 1297 deletions

View File

@ -29,6 +29,8 @@ public class SongBestData
public DateTime LastPlayTime { get; set; }
public DateTime PlayTime { get; set; }
public bool IsFavorite { get; set; }
public uint GoodCount { get; set; }

View File

@ -21,30 +21,23 @@ public class SongBestDatumService : ISongBestDatumService
public async Task<List<SongBestData>> GetAllSongBestAsModel(uint baid)
{
var songbestDbData = await context.SongBestData.Where(datum => datum.Baid == baid)
.ToListAsync();
var songbestDbData = await context.SongBestData.Where(datum => datum.Baid == baid).ToListAsync();
var result = songbestDbData.Select(datum => datum.CopyPropertiesToNew<SongBestData>()).ToList();
var aiSectionBest = await context.AiScoreData.Where(datum => datum.Baid == baid)
.Include(datum => datum.AiSectionScoreData)
.ToListAsync();
var aiSectionBest = await context.AiScoreData.Where(datum => datum.Baid == baid).Include(datum => datum.AiSectionScoreData).ToListAsync();
var playLogs = await context.SongPlayData.Where(datum => datum.Baid == baid).ToListAsync();
foreach (var bestData in result)
{
var songPlayDatums = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty &&
datum.SongId == bestData.SongId).ToArray();
songPlayDatums.Throw($"Play log for song id {bestData.SongId} is null! " +
"Something is wrong with db!")
.IfEmpty();
var lastPlayLog = songPlayDatums
.MaxBy(datum => datum.PlayTime);
bestData.LastPlayTime = lastPlayLog!.PlayTime;
var songPlayDatums = playLogs.Where(datum => datum.Difficulty == bestData.Difficulty && datum.SongId == bestData.SongId).ToArray();
songPlayDatums.Throw($"Play log for song id {bestData.SongId} is null! " + "Something is wrong with db!").IfEmpty();
var bestLog = songPlayDatums
.MaxBy(datum => datum.Score);
bestData.LastPlayTime = songPlayDatums.MaxBy(datum => datum.PlayTime)!.PlayTime;
var bestLog = songPlayDatums.MaxBy(datum => datum.Score);
bestLog.CopyOnlyPropertiesTo(bestData,
nameof(SongPlayDatum.PlayTime),
nameof(SongPlayDatum.GoodCount),
nameof(SongPlayDatum.OkCount),
nameof(SongPlayDatum.MissCount),

View File

@ -19,17 +19,17 @@
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongHistoryData" SortBy="x => x.Difficulty">
<MudTableSortLabel T="SongHistoryData" SortBy="x => (int)x.Difficulty * 1000000 + x.Score">
@Localizer["Difficulty"]
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongHistoryData" SortBy="x => x.Crown">
<MudTableSortLabel T="SongHistoryData" SortBy="x => (int)x.Crown * 1000000 + x.Score">
@Localizer["Crown"]
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongHistoryData" SortBy="x => x.ScoreRank">
<MudTableSortLabel T="SongHistoryData" SortBy="x => (int)x.ScoreRank * 1000000 + x.Score">
@Localizer["Rank"]
</MudTableSortLabel>
</MudTh>

View File

@ -200,7 +200,7 @@
["user"] = user
};
var dialog = await DialogService.ShowAsync<UserDeleteConfirmDialog>(Localizer["Delete User"], parameters, options);
var dialog = await DialogService.ShowAsync<UserDeleteConfirmDialog>((string)Localizer["Delete User"], parameters, options);
var result = await dialog.Result;
if (result.Canceled) return;
@ -210,7 +210,7 @@
await AuthService.Logout();
}
NavigationManager.NavigateTo("/Users");
NavigationManager.NavigateTo("/Users", true);
}
private async Task GenerateInviteCode(uint baid)

File diff suppressed because it is too large Load Diff

View File

@ -163,13 +163,13 @@
<value>Genre</value>
</data>
<data name="Best Score" xml:space="preserve">
<value>Meilleur score</value>
<value>Score</value>
</data>
<data name="Best Crown" xml:space="preserve">
<value>Meilleure couronne</value>
<value>Couronne</value>
</data>
<data name="Best Rank" xml:space="preserve">
<value>Meilleur rank</value>
<value>Rank</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
@ -184,25 +184,25 @@
<value>Drumroll</value>
</data>
<data name="MAX Combo" xml:space="preserve">
<value>Combo MAX</value>
<value>Combo</value>
</data>
<data name="AI Battle Data" xml:space="preserve">
<value>Données du mode IA Battle</value>
</data>
<data name="Last Played" xml:space="preserve">
<value>Joué la dernière fois</value>
<data name="Played" xml:space="preserve">
<value>Date</value>
</data>
<data name="Total Credits Played" xml:space="preserve">
<value>Nombre total de parties</value>
<value>Parties</value>
</data>
<data name="Total Clears" xml:space="preserve">
<value>Total Clears</value>
<value>Clears</value>
</data>
<data name="Total Full Combos" xml:space="preserve">
<value>Nombre total de Full Combos</value>
<value>Full Combos</value>
</data>
<data name="Total Donderful Combos" xml:space="preserve">
<value>Nombre total de Combos Donderful</value>
<value>Combos Donderful</value>
</data>
<data name="Song List" xml:space="preserve">
<value>Musiques</value>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,13 +5,12 @@
<TitleContent>
<MudText Typo="Typo.h6">
<MudIcon Icon="@Icons.Material.Filled.DeleteForever" Class="mr-3 mb-n1" />
(MarkupString)
(string)@Localizer["Delete User"]
@((MarkupString)(string)@Localizer["Delete User"])
</MudText>
</TitleContent>
<DialogContent>
<MudText>
@Localizer["Delete User Confirm"]
@((MarkupString)(string)Localizer["Delete User Confirm"])
</MudText>
</DialogContent>
<DialogActions>

View File

@ -9,7 +9,7 @@
@page "/Users/{baid:int}/HighScores"
<MudGrid Class="my-8">
<MudGrid Class="my-8" Style="margin-bottom: 0px !important;">
@if (response is null)
{
<MudContainer Style="display:flex;margin:50px 0;align-items:center;justify-content:center;">
@ -25,7 +25,7 @@
else
{
<MudItem xs="12">
<MudTabs Elevation="0" Border="true" Rounded="true" ApplyEffectsToContainer="true" Outlined="true" Class="mb-10" ActivePanelIndexChanged="@(async (index) => await OnTabChanged(index))" ActivePanelIndex="@selectedDifficultyTab">
<MudTabs Elevation="0" Border="true" Rounded="true" ApplyEffectsToContainer="true" Outlined="true" ActivePanelIndexChanged="@(async (index) => await OnTabChanged(index))" ActivePanelIndex="@selectedDifficultyTab">
@foreach (var difficulty in Enum.GetValues<Difficulty>())
{
@if (difficulty is not Difficulty.None)
@ -35,18 +35,20 @@
@if (songBestDataMap.TryGetValue(difficulty, out var value))
{
// Rows per page 25
<MudTable Items="@value" Elevation="0" Striped="true" RowsPerPage="25" Breakpoint=Breakpoint.None>
<MudTable Items="@value" Elevation="0" Striped="false" Outlined="true" RowsPerPage="25" Breakpoint=Breakpoint.None >
<HeaderContent>
<MudTh>
<MudText Typo="Typo.body2" Style="font-weight:bold">@Localizer["Song Name"]</MudText>
<MudTableSortLabel T="SongBestData" SortBy="x => GameDataService.GetMusicNameBySongId(musicDetailDictionary, x.SongId, CultureInfo.CurrentCulture.ToString())">
<MudText>@Localizer["Song Name"]</MudText>
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => GameDataService.GetMusicStarLevel(musicDetailDictionary, x.SongId, difficulty)">
<MudTableSortLabel T="SongBestData" SortBy="x => GameDataService.GetMusicStarLevel(musicDetailDictionary, x.SongId, difficulty) * 1000000 + x.BestScore">
<MudText>@Localizer["Level"]</MudText>
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => x.Genre">
<MudTableSortLabel T="SongBestData" SortBy="x => (int)x.Genre * 1000000 + x.BestScore">
<MudText>@Localizer["Genre"]</MudText>
</MudTableSortLabel>
</MudTh>
@ -56,12 +58,12 @@
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => x.BestCrown">
<MudTableSortLabel T="SongBestData" SortBy="x => (int)x.BestCrown * 1000000 + x.BestScore">
<MudText>@Localizer["Best Crown"]</MudText>
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => x.BestScoreRank">
<MudTableSortLabel T="SongBestData" SortBy="x => (int)x.BestScoreRank * 1000000 + x.BestScore">
<MudText>@Localizer["Best Rank"]</MudText>
</MudTableSortLabel>
</MudTh>
@ -91,11 +93,11 @@
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => x.LastPlayTime">
<MudText>@Localizer["Last Played"]</MudText>
<MudTableSortLabel T="SongBestData" InitialDirection="SortDirection.Descending" SortBy="x => x.PlayTime">
<MudText>@Localizer["Played"]</MudText>
</MudTableSortLabel>
</MudTh>
<MudTh>
@* <MudTh>
<MudTableSortLabel T="SongBestData" SortBy="x => x.PlayCount">
<MudText>@Localizer["Total Credits Played"]</MudText>
</MudTableSortLabel>
@ -114,18 +116,18 @@
<MudTableSortLabel T="SongBestData" SortBy="x => x.PerfectCount">
<MudText>@Localizer["Total Donderful Combos"]</MudText>
</MudTableSortLabel>
</MudTh>
</MudTh> *@
</HeaderContent>
<RowTemplate>
<MudTd>
<MudTd Style="text-align: initial !important;">
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
<div style="width:300px">
<div style="width:400px">
<a href="@($"/Users/{Baid}/Songs/{context.SongId}")">
<MudText Typo="Typo.body2" Style="font-weight:bold">@context.MusicName</MudText>
<MudText Typo="Typo.caption">@context.MusicArtist</MudText>
</a>
</div>
<div>
@* <div>
<MudToggleIconButton Toggled="@context.IsFavorite"
ToggledChanged="@(async () => await OnFavoriteToggled(context))"
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
@ -133,7 +135,7 @@
Size="Size.Small"
ToggledSize="Size.Small"
Title="Add to favorites" ToggledTitle="Remove from favorites" />
</div>
</div> *@
</MudStack>
</MudTd>
<MudTd>
@ -176,9 +178,9 @@
<MudText>@context.ComboCount</MudText>
</MudTd>
<MudTd>
<MudText>@context.LastPlayTime</MudText>
<MudText>@context.PlayTime</MudText>
</MudTd>
<MudTd>
@* <MudTd>
<MudText>@context.PlayCount</MudText>
</MudTd>
<MudTd>
@ -189,7 +191,7 @@
</MudTd>
<MudTd>
<MudText>@context.PerfectCount</MudText>
</MudTd>
</MudTd> *@
</RowTemplate>
<PagerContent>
<MudTablePager RowsPerPageString=@Localizer["Rows Per Page:"] />
@ -200,7 +202,7 @@
{
<MudGrid>
<MudItem xs="12">
<MudText Align="Align.Center" Class="my-16">
<MudText Align="Align.Center" Class="my-8">
@Localizer["No Data"]
</MudText>
</MudItem>

View File

@ -36,9 +36,16 @@ public partial class HighScores
data.MusicArtist = GameDataService.GetMusicArtistBySongId(musicDetailDictionary, songId, string.IsNullOrEmpty(songNameLanguage) ? "ja" : songNameLanguage);
});
//We get rid of entries with empty song names
//This can happen if the database has been used with a different version of the songlist (Omnimix/Version update)
response.SongBestData = response.SongBestData.FindAll(x => x.MusicName != "");
songBestDataMap = response.SongBestData.GroupBy(data => data.Difficulty)
.ToDictionary(data => data.Key,
data => data.ToList());
foreach (var songBestDataList in songBestDataMap.Values)
{
songBestDataList.Sort((data1, data2) => GameDataService.GetMusicIndexBySongId(musicDetailDictionary, data1.SongId)

View File

@ -33,11 +33,11 @@
else
{
<MudItem xs="12">
<MudTable Class="mud-table-outlined" Items="@songHistoryDataMap.Values.ToList()" Elevation="0" Filter=@FilterSongs Virtualize="true" RowsPerPage="25" Bordered="false" Dense="true" Breakpoint=Breakpoint.None>
<MudTable Class="mud-table-outlined" Items="@songHistoryDataMap.Values.ToList()" Elevation="0" Filter=@FilterSongs Virtualize="true" RowsPerPage="25" Striped="false" Hover="false" Bordered="false" Dense="true" Breakpoint=Breakpoint.None>
<ToolBarContent>
<MudGrid Spacing="2" Justify="Justify.SpaceBetween">
<MudItem xs="12" md="4">
<MudText Typo="Typo.caption">@Localizer["Total Credits Played"]: @songHistoryDataMap.Values.Count</MudText>
<MudItem xs="12" md="4" Style="align-content: center;">
<MudText Typo="Typo.body2">@Localizer["Total Credits Played"]: @songHistoryDataMap.Values.Count</MudText>
</MudItem>
<MudItem xs="12" md="8">
<MudTextField @bind-Value="Search"
@ -48,12 +48,12 @@
Margin="Margin.Dense"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
IconSize="Size.Medium"/>
IconSize="Size.Medium" />
</MudItem>
</MudGrid>
</ToolBarContent>
<HeaderContent>
<MudTh>
<MudTh Style="text-align: initial !important;">
<MudTableSortLabel InitialDirection="SortDirection.Descending" T="List<SongHistoryData>" SortBy="x => x[0].PlayTime">
@Localizer["Play Time"]
</MudTableSortLabel>
@ -94,7 +94,7 @@
</MudTd>
@* Song title *@
<MudTd DataLabel="Song">
<MudTd DataLabel="Song" Style="text-align: initial !important;">
<MudStack Row="true" Spacing="1" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween">
<div>
<a href="@($"/Users/{Baid}/Songs/{songHistoryData.SongId}")">
@ -102,20 +102,11 @@
<MudText Typo="Typo.caption">@songHistoryData.MusicArtist</MudText>
</a>
</div>
@* <div>
<MudToggleIconButton Toggled="@songHistoryData.IsFavorite"
ToggledChanged="@(async () => await OnFavoriteToggled(songHistoryData))"
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
ToggledIcon="@Icons.Material.Filled.Favorite" ToggledColor="@Color.Secondary"
Size="Size.Small"
ToggledSize="Size.Small"
Title="Add to favorites" ToggledTitle="Remove from favorites" />
</div> *@
</MudStack>
</MudTd>
@* Genre display *@
<MudTd DataLabel="Genre" Style="text-align:left">
<MudTd DataLabel="Genre">
<MudChip Style=@GetGenreStyle(songHistoryData.Genre) Size="Size.Small">@GetGenreTitle(songHistoryData.Genre)</MudChip>
</MudTd>
@ -124,7 +115,7 @@
<MudTd Style="text-align:center">
@if (songHistoryData.ScoreRank is not ScoreRank.None)
{
<img src="@($"/images/rank_{songHistoryData.ScoreRank}.webp")" alt="@(GetRankText(songHistoryData.ScoreRank))" title="@(GetRankText(songHistoryData.ScoreRank))" style=@IconStyle />
<img src="@($"/images/rank_{songHistoryData.ScoreRank}.webp")" alt="@(GetRankText(songHistoryData.ScoreRank))" title="@(GetRankText(songHistoryData.ScoreRank))" style=@IconStyle />
}
</MudTd>
<MudTd>@(songHistoryData.GoodCount)</MudTd>

View File

@ -51,6 +51,10 @@ public partial class PlayHistory
data.ShowDetails = false;
});
//We get rid of entries with empty song names
//This can happen if the database has been used with a different version of the songlist (Omnimix/Version update)
response.SongHistoryData = response.SongHistoryData.FindAll(x => x.MusicName != "");
songHistoryDataMap = response.SongHistoryData.GroupBy(data => data.PlayTime).ToDictionary(data => data.Key,data => data.ToList());
foreach (var songHistoryDataList in songHistoryDataMap.Values)
{

View File

@ -26,7 +26,7 @@
else
{
<MudItem xs="12">
<MudTable Items="musicDetailDictionary.Values" Elevation="0" Outlined="true" Filter="@FilterSongs" Breakpoint=Breakpoint.None>
<MudTable Items="musicDetailDictionary.Values" Elevation="0" RowsPerPage="25" Outlined="true" Filter="@FilterSongs" Breakpoint=Breakpoint.None>
<ToolBarContent>
<MudGrid Spacing="2">
<MudItem xs="12" md="8">
@ -68,42 +68,42 @@
{
@if (difficulty is not Difficulty.None)
{
<MudTh>
<MudTableSortLabel T="MusicDetail" SortBy="context => GameDataService.GetMusicStarLevel(musicDetailDictionary, context.SongId, difficulty)">
<img src="@ScoreUtils.GetDifficultyIcon(difficulty)" alt="@ScoreUtils.GetDifficultyTitle(difficulty)" style="@Constants.ICON_STYLE" />
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel T="MusicDetail" SortBy="context => GameDataService.GetMusicStarLevel(musicDetailDictionary, context.SongId, difficulty)">
<img src="@ScoreUtils.GetDifficultyIcon(difficulty)" alt="@ScoreUtils.GetDifficultyTitle(difficulty)" style="@Constants.ICON_STYLE" />
</MudTableSortLabel>
</MudTh>
}
}
</HeaderContent>
<RowTemplate>
<MudTd Style="width:400px">
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
<div>
<a href="@($"/Users/{Baid}/Songs/{context.SongId}")">
<MudText Typo="Typo.body2" Style="font-weight:bold">
@GameDataService.GetMusicNameBySongId(musicDetailDictionary, context.SongId, SongNameLanguage)
</MudText>
<MudText Typo="Typo.caption">
@GameDataService.GetMusicArtistBySongId(musicDetailDictionary, context.SongId, SongNameLanguage)
</MudText>
</a>
</div>
<div>
<MudToggleIconButton Toggled="@context.IsFavorite"
ToggledChanged="@(async () => await OnFavoriteToggled(context))"
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
ToggledIcon="@Icons.Material.Filled.Favorite" ToggledColor="@Color.Secondary"
Size="Size.Small"
ToggledSize="Size.Small"
Title="Add to favorites" ToggledTitle="Remove from favorites" />
</div>
<MudTd Style="width:400px; text-align: initial !important;">
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
<div>
<a href="@($"/Users/{Baid}/Songs/{context.SongId}")">
<MudText Typo="Typo.body2" Style="font-weight:bold">
@GameDataService.GetMusicNameBySongId(musicDetailDictionary, context.SongId, SongNameLanguage)
</MudText>
<MudText Typo="Typo.caption">
@GameDataService.GetMusicArtistBySongId(musicDetailDictionary, context.SongId, SongNameLanguage)
</MudText>
</a>
</div>
<div>
<MudToggleIconButton Toggled="@context.IsFavorite"
ToggledChanged="@(async () => await OnFavoriteToggled(context))"
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
ToggledIcon="@Icons.Material.Filled.Favorite" ToggledColor="@Color.Secondary"
Size="Size.Small"
ToggledSize="Size.Small"
Title="Add to favorites" ToggledTitle="Remove from favorites" />
</div>
</MudStack>
</MudTd>
<MudTd>
<MudChip Style="@ScoreUtils.GetGenreStyle(context.Genre)" Size="Size.Small">
@ScoreUtils.GetGenreTitle(context.Genre)
</MudChip>
<MudChip Style="@ScoreUtils.GetGenreStyle(context.Genre)" Size="Size.Small">
@ScoreUtils.GetGenreTitle(context.Genre)
</MudChip>
</MudTd>
@foreach (var difficulty in Enum.GetValues<Difficulty>())
{
@ -112,18 +112,18 @@
var starLevel = GameDataService.GetMusicStarLevel(musicDetailDictionary, context.SongId, difficulty);
<MudTd>
@if (starLevel > 0)
{
{
<MudStack Row="true" Spacing="1" AlignItems="AlignItems.Center">
<MudIcon Icon="@Icons.Material.Filled.Star" Size="Size.Small" />
<MudText Typo="Typo.caption" Style="line-height:1;margin-top:2px;margin-right:2px;">@starLevel</MudText>
</MudStack>
}
else
{
<MudText Typo="Typo.body2" Style="font-weight:bold">
-
</MudText>
}
}
else
{
<MudText Typo="Typo.body2" Style="font-weight:bold">
-
</MudText>
}
</MudTd>
}
}

View File

@ -337,3 +337,9 @@ tr.is-current-user p {
justify-content: space-between;
height: 100%;
}
.mud-table-cell {
padding-top: 8px !important;
padding-bottom: 8px !important;
text-align: center;
}