Add High Scores page
This commit is contained in:
parent
9144dacf8d
commit
57b0390322
@ -26,4 +26,17 @@ public class FavoriteSongsController : BaseController<FavoriteSongsController>
|
||||
await userDatumService.UpdateFavoriteSong(request.Baid, request.SongId, request.IsFavorite);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpGet("{baid}")]
|
||||
public async Task<IActionResult> GetFavoriteSongs(uint baid)
|
||||
{
|
||||
var user = await userDatumService.GetFirstUserDatumOrNull(baid);
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Ok(user.FavoriteSongsArray);
|
||||
}
|
||||
}
|
@ -104,7 +104,8 @@
|
||||
FullWidth="true"
|
||||
AnchorOrigin="Origin.BottomCenter"
|
||||
TransformOrigin="Origin.TopCenter">
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/Songs")">@Localizer["high scores"]</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/HighScores")">@Localizer["High Scores"]</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/Songs")">@Localizer["Song List"]</MudMenuItem>
|
||||
<MudMenuItem Href="@($"Users/{user.Baid}/DaniDojo")">@Localizer["dani dojo"]</MudMenuItem>
|
||||
</MudMenu>
|
||||
</MudStack>
|
||||
|
136
TaikoWebUI/Pages/HighScores.razor
Normal file
136
TaikoWebUI/Pages/HighScores.razor
Normal file
@ -0,0 +1,136 @@
|
||||
@inject IGameDataService GameDataService
|
||||
@inject HttpClient Client
|
||||
@inject LoginService LoginService
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject NavigationManager NavigationManager
|
||||
@using TaikoWebUI.Utilities;
|
||||
|
||||
@page "/Users/{baid:int}/HighScores"
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="p-0 mb-2"></MudBreadcrumbs>
|
||||
<MudText Typo="Typo.h4">@Localizer["High Scores"]</MudText>
|
||||
<MudText Typo="Typo.caption">User ID: @Baid</MudText>
|
||||
|
||||
<MudGrid Class="my-8">
|
||||
@if (response is null)
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center">
|
||||
@Localizer["No data."]
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (LoginService.LoginRequired && (!LoginService.IsLoggedIn || (LoginService.GetLoggedInUser().Baid != Baid && !LoginService.IsAdmin)))
|
||||
{
|
||||
if (!LoginService.IsLoggedIn)
|
||||
{
|
||||
NavigationManager.NavigateTo("/Login");
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudTabs Elevation="0" Border="true" Rounded="true" ApplyEffectsToContainer="true" Outlined="true" Class="mb-10">
|
||||
@foreach (var difficulty in Enum.GetValues<Difficulty>())
|
||||
{
|
||||
@if (difficulty is not Difficulty.None)
|
||||
{
|
||||
<MudTabPanel Text="@ScoreUtils.GetDifficultyTitle(difficulty)"
|
||||
Icon="@ScoreUtils.GetDifficultyIconSvg(difficulty)">
|
||||
@if (songBestDataMap.TryGetValue(difficulty, out var value))
|
||||
{
|
||||
<MudDataGrid Items="@value"
|
||||
ColumnResizeMode="ResizeMode.None" RowsPerPage="25" Elevation="0">
|
||||
<Columns>
|
||||
<TemplateColumn T="SongBestData" Title=@Localizer["Song"] StickyLeft="true">
|
||||
<CellTemplate>
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
||||
<div style="width:300px">
|
||||
<a href="@($"/Users/{Baid}/Songs/{context.Item.SongId}")">
|
||||
<MudText Typo="Typo.body2" Style="font-weight:bold">@context.Item.MusicName</MudText>
|
||||
<MudText Typo="Typo.caption">@context.Item.MusicArtist</MudText>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<MudToggleIconButton Toggled="@context.Item.IsFavorite"
|
||||
ToggledChanged="@(async () => await OnFavoriteToggled(context.Item))"
|
||||
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>
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<TemplateColumn T="SongBestData" Title=@Localizer["Level"] Sortable="false">
|
||||
<CellTemplate>
|
||||
<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;">@GameDataService.GetMusicStarLevel(@context.Item.SongId, difficulty)</MudText>
|
||||
</MudStack>
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<TemplateColumn T="SongBestData" Title=@Localizer["Genre"]
|
||||
Sortable="false" Filterable="true">
|
||||
<CellTemplate>
|
||||
<MudChip Style="@ScoreUtils.GetGenreStyle(context.Item.Genre)"
|
||||
Size="Size.Small">
|
||||
@ScoreUtils.GetGenreTitle(context.Item.Genre)
|
||||
</MudChip>
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<PropertyColumn Property="data => data.BestScore" Title=@Localizer["Best Score"] />
|
||||
<TemplateColumn T="SongBestData" Title=@Localizer["Best Crown"]>
|
||||
<CellTemplate>
|
||||
<img src="@($"/images/crown_{context.Item.BestCrown}.png")" alt="@(ScoreUtils.GetCrownText(context.Item.BestCrown))" title="@(ScoreUtils.GetCrownText(context.Item.BestCrown))" style="@IconStyle" />
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<TemplateColumn T="SongBestData" Title=@Localizer["Best Rank"] Sortable="false">
|
||||
<CellTemplate>
|
||||
@if (context.Item.BestScoreRank is not ScoreRank.None)
|
||||
{
|
||||
<img src="@($"/images/rank_{context.Item.BestScoreRank}.png")" alt="@(ScoreUtils.GetRankText(context.Item.BestScoreRank))" title="@(ScoreUtils.GetRankText(context.Item.BestScoreRank))" style="@IconStyle" />
|
||||
}
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<PropertyColumn Property="data => data.GoodCount" Title=@Localizer["Good"] Sortable="false" />
|
||||
<PropertyColumn Property="data => data.OkCount" Title=@Localizer["OK"] Sortable="false" />
|
||||
<PropertyColumn Property="data => data.MissCount" Title=@Localizer["Bad"] Sortable="false" />
|
||||
<PropertyColumn Property="data => data.DrumrollCount" Title=@Localizer["Drumroll"] Sortable="false" />
|
||||
<PropertyColumn Property="data => data.ComboCount" Title=@Localizer["MAX Combo"] Sortable="false" />
|
||||
<PropertyColumn Property="data => data.LastPlayTime" Title=@Localizer["Last Played"] Hideable="true" />
|
||||
<PropertyColumn Property="data => data.PlayCount" Title=@Localizer["Total Plays"] Hideable="true" />
|
||||
<PropertyColumn Property="data => data.ClearCount" Title=@Localizer["Total Clears"] Hideable="true" />
|
||||
<PropertyColumn Property="data => data.FullComboCount" Title=@Localizer["Total Full Combos"] Hideable="true" />
|
||||
<PropertyColumn Property="data => data.PerfectCount" Title=@Localizer["Total Donderful Combos"] Hideable="true" />
|
||||
</Columns>
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="SongBestData" />
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudGrid>
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center" Class="my-16">
|
||||
No data for selected difficulty.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
</MudTabPanel>
|
||||
}
|
||||
}
|
||||
</MudTabs>
|
||||
</MudItem>
|
||||
}
|
||||
}
|
||||
</MudGrid>
|
81
TaikoWebUI/Pages/HighScores.razor.cs
Normal file
81
TaikoWebUI/Pages/HighScores.razor.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using static MudBlazor.Colors;
|
||||
using System;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace TaikoWebUI.Pages;
|
||||
|
||||
public partial class HighScores
|
||||
{
|
||||
[Parameter]
|
||||
public int Baid { get; set; }
|
||||
|
||||
private const string IconStyle = "width:25px; height:25px;";
|
||||
|
||||
private SongBestResponse? response;
|
||||
private UserSetting? userSetting;
|
||||
|
||||
private Dictionary<Difficulty, List<SongBestData>> songBestDataMap = new();
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
response = await Client.GetFromJsonAsync<SongBestResponse>($"api/PlayData/{Baid}");
|
||||
response.ThrowIfNull();
|
||||
|
||||
userSetting = await Client.GetFromJsonAsync<UserSetting>($"api/UserSettings/{Baid}");
|
||||
|
||||
var language = await JSRuntime.InvokeAsync<string>("blazorCulture.get");
|
||||
|
||||
response.SongBestData.ForEach(data =>
|
||||
{
|
||||
var songId = data.SongId;
|
||||
data.Genre = GameDataService.GetMusicGenreBySongId(songId);
|
||||
data.MusicName = GameDataService.GetMusicNameBySongId(songId, string.IsNullOrEmpty(language) ? "ja" : language);
|
||||
data.MusicArtist = GameDataService.GetMusicArtistBySongId(songId, string.IsNullOrEmpty(language) ? "ja" : language);
|
||||
});
|
||||
|
||||
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(data1.SongId)
|
||||
.CompareTo(GameDataService.GetMusicIndexBySongId(data2.SongId)));
|
||||
}
|
||||
|
||||
if (LoginService.IsLoggedIn && !LoginService.IsAdmin)
|
||||
{
|
||||
breadcrumbs.Add(new BreadcrumbItem("Dashboard", href: "/"));
|
||||
}
|
||||
else
|
||||
{
|
||||
breadcrumbs.Add(new BreadcrumbItem("Users", href: "/Users"));
|
||||
};
|
||||
breadcrumbs.Add(new BreadcrumbItem($"{userSetting?.MyDonName}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("High Scores", href: $"/Users/{Baid}/HighScores", disabled: false));
|
||||
}
|
||||
|
||||
private async Task OnFavoriteToggled(SongBestData data)
|
||||
{
|
||||
var request = new SetFavoriteRequest
|
||||
{
|
||||
Baid = (uint)Baid,
|
||||
IsFavorite = !data.IsFavorite,
|
||||
SongId = data.SongId
|
||||
};
|
||||
var result = await Client.PostAsJsonAsync("api/FavoriteSongs", request);
|
||||
if (result.IsSuccessStatusCode)
|
||||
{
|
||||
data.IsFavorite = !data.IsFavorite;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsAiDataPresent(SongBestData data)
|
||||
{
|
||||
var aiData = data.AiSectionBestData;
|
||||
|
||||
return aiData.Count > 0;
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@
|
||||
else
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudTable Items="musicMap" Elevation="0" Outlined="true" Filter="@FilterSongs" Striped="true">
|
||||
<MudTable Items="musicMap" Elevation="0" Outlined="true" Filter="@FilterSongs">
|
||||
<ToolBarContent>
|
||||
<MudGrid Spacing="2">
|
||||
<MudItem xs="12" md="8">
|
||||
@ -54,7 +54,7 @@
|
||||
var genreValue = (SongGenre)genre;
|
||||
<MudSelectItem Value="@genreValue.ToString()" Label="@Localizer[$"Key_{genreValue}"]">
|
||||
@ScoreUtils.GetGenreTitle(genreValue)
|
||||
</MudSelectItem>
|
||||
</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudItem>
|
||||
@ -69,14 +69,27 @@
|
||||
</HeaderContent>
|
||||
<RowTemplate>
|
||||
<MudTd>
|
||||
<a href="@($"/Users/{Baid}/Songs/{context.SongId}")">
|
||||
<MudText Typo="Typo.body2">
|
||||
@GameDataService.GetMusicNameBySongId(context.SongId, CurrentLanguage)
|
||||
</MudText>
|
||||
<MudText Typo="Typo.caption">
|
||||
@GameDataService.GetMusicArtistBySongId(context.SongId, CurrentLanguage)
|
||||
</MudText>
|
||||
</a>
|
||||
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
||||
<div>
|
||||
<a href="@($"/Users/{Baid}/Songs/{context.SongId}")">
|
||||
<MudText Typo="Typo.body2">
|
||||
@GameDataService.GetMusicNameBySongId(context.SongId, CurrentLanguage)
|
||||
</MudText>
|
||||
<MudText Typo="Typo.caption">
|
||||
@GameDataService.GetMusicArtistBySongId(context.SongId, CurrentLanguage)
|
||||
</MudText>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<MudToggleIconButton
|
||||
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>
|
||||
</RowTemplate>
|
||||
<PagerContent>
|
||||
|
@ -3,7 +3,6 @@
|
||||
public class MusicDetail
|
||||
{
|
||||
public uint SongId { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public string SongName { get; set; } = string.Empty;
|
||||
@ -17,14 +16,11 @@ public class MusicDetail
|
||||
public string ArtistNameKO { get; set; } = string.Empty;
|
||||
|
||||
public SongGenre Genre { get; set; }
|
||||
|
||||
public int StarEasy { get; set; }
|
||||
|
||||
public int StarNormal { get; set; }
|
||||
|
||||
public int StarHard { get; set; }
|
||||
|
||||
public int StarOni { get; set; }
|
||||
|
||||
public int StarUra { get; set; }
|
||||
|
||||
public bool IsFavorite { get; set; } = false;
|
||||
}
|
6
TaikoWebUI/Shared/Models/SongListEntry.cs
Normal file
6
TaikoWebUI/Shared/Models/SongListEntry.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace TaikoWebUI.Shared.Models
|
||||
{
|
||||
public class SongListEntry
|
||||
{
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
<MudNavLink Href="@($"Users/{currentUser.Baid}/Profile")" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Person">@Localizer["Profile"]</MudNavLink>
|
||||
<MudNavGroup Title="Play Data" Expanded="true" Icon="@Icons.Material.Filled.EmojiEvents">
|
||||
<MudNavLink Href="@($"Users/{currentUser.Baid}/Songs")" Match="NavLinkMatch.All">@Localizer["Key_01"]</MudNavLink>
|
||||
<MudNavLink Href="@($"Users/{currentUser.Baid}/HighScores")" Match="NavLinkMatch.All">@Localizer["High Scores"]</MudNavLink>
|
||||
<MudNavLink Href="@($"Users/{currentUser.Baid}/DaniDojo")" Match="NavLinkMatch.All">@Localizer["Key_03"]</MudNavLink>
|
||||
</MudNavGroup>
|
||||
<MudNavGroup Title="Settings" Expanded="_settingsOpen" Icon="@Icons.Material.Filled.Settings">
|
||||
|
Loading…
x
Reference in New Issue
Block a user