Add song genre
Add tabs for play result Reformat game data manager
This commit is contained in:
parent
f5bb98d5da
commit
62d0e6b4d7
13
SharedProject/Enums/SongGenre.cs
Normal file
13
SharedProject/Enums/SongGenre.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace SharedProject.Enums;
|
||||
|
||||
public enum SongGenre
|
||||
{
|
||||
Pop = 0,
|
||||
Anime = 1,
|
||||
Kids = 2,
|
||||
Vocaloid = 3,
|
||||
GameMusic = 4,
|
||||
NamcoOriginal = 5,
|
||||
Variety = 7,
|
||||
Classical = 8
|
||||
}
|
@ -1,2 +1,4 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=musicinfo/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=musicinfo/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Namco/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vocaloid/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
@ -3,6 +3,7 @@
|
||||
@using SharedProject.Models
|
||||
@using SharedProject.Models.Requests
|
||||
@using SharedProject.Enums
|
||||
@using Throw
|
||||
@inject IGameDataService GameDataService
|
||||
@inject HttpClient Client
|
||||
|
||||
@ -14,65 +15,72 @@
|
||||
<MudText Typo="Typo.caption">Card: @Baid</MudText>
|
||||
|
||||
<MudGrid Class="my-8">
|
||||
@if (response is null)
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center">
|
||||
No data.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudDataGrid Items="@response.SongBestData">
|
||||
<Columns>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.SongId)" Title="Song">
|
||||
<CellTemplate>
|
||||
<MudText Typo="Typo.body2" Style="font-weight:bold">@GameDataService.GetMusicNameBySongId(context.Item.SongId)</MudText>
|
||||
<MudText Typo="Typo.caption">@GameDataService.GetMusicArtistBySongId(context.Item.SongId)</MudText>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.Difficulty)" Title="Difficulty">
|
||||
<CellTemplate>
|
||||
<MudTooltip Text="@(context.Item.Difficulty.ToString())" Arrow="true" Placement="Placement.Top">
|
||||
<img src="@($"/images/{context.Item.Difficulty}.png")" alt="@(context.Item.Difficulty)" style="@ICON_STYLE" />
|
||||
</MudTooltip>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestScore)" Title="Best Score"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestCrown)" Title="Best Crown">
|
||||
<CellTemplate>
|
||||
<MudTooltip Text="@(GetCrownText(context.Item.BestCrown))" Arrow="true" Placement="Placement.Top">
|
||||
<img src="@($"/images/crown_{context.Item.BestCrown}.png")" alt="@(context.Item.BestCrown)" style="@ICON_STYLE" />
|
||||
</MudTooltip>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestScoreRank)" Title="Best Rank" />
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestRate)" Title="Best Rate"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.GoodCount)" Title="Good"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.OkCount)" Title="Ok"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.MissCount)" Title="Miss"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.ComboCount)" Title="Max Combo"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.DrumrollCount)" Title="Drum Rolls"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.HitCount)" Title="Hit"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.IsFavorite)" Title="Favorite">
|
||||
<CellTemplate>
|
||||
<MudToggleIconButton Toggled="@context.Item.IsFavorite"
|
||||
ToggledChanged="@(async () => await OnFavoriteToggled(context.Item))"
|
||||
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
|
||||
Title="Add to favorites"
|
||||
ToggledIcon="@Icons.Material.Filled.Favorite" ToggledColor="@Color.Secondary"
|
||||
ToggledTitle="Remove from favorites"/>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
</Columns>
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="SongBestData"/>
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
</MudItem>
|
||||
}
|
||||
@if (response is null)
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudText Align="Align.Center">
|
||||
No data.
|
||||
</MudText>
|
||||
</MudItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudItem xs="12">
|
||||
<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6">
|
||||
@foreach (var genre in Enum.GetValues<SongGenre>())
|
||||
{
|
||||
<MudTabPanel Text="@genre.ToString()">
|
||||
<MudDataGrid Items="@response.SongBestData.Where(data => GameDataService.GetMusicGenreBySongId(data.SongId) == genre)">
|
||||
<Columns>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.SongId)" Title="Song">
|
||||
<CellTemplate>
|
||||
<MudText Typo="Typo.body2" Style="font-weight:bold">@GameDataService.GetMusicNameBySongId(context.Item.SongId)</MudText>
|
||||
<MudText Typo="Typo.caption">@GameDataService.GetMusicArtistBySongId(context.Item.SongId)</MudText>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.Difficulty)" Title="Difficulty">
|
||||
<CellTemplate>
|
||||
<MudTooltip Text="@(context.Item.Difficulty.ToString())" Arrow="true" Placement="Placement.Top">
|
||||
<img src="@($"/images/{context.Item.Difficulty}.png")" alt="@(context.Item.Difficulty)" style="@ICON_STYLE"/>
|
||||
</MudTooltip>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestScore)" Title="Best Score"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestCrown)" Title="Best Crown">
|
||||
<CellTemplate>
|
||||
<MudTooltip Text="@(GetCrownText(context.Item.BestCrown))" Arrow="true" Placement="Placement.Top">
|
||||
<img src="@($"/images/crown_{context.Item.BestCrown}.png")" alt="@(context.Item.BestCrown)" style="@ICON_STYLE"/>
|
||||
</MudTooltip>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestScoreRank)" Title="Best Rank"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.BestRate)" Title="Best Rate"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.GoodCount)" Title="Good"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.OkCount)" Title="Ok"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.MissCount)" Title="Miss"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.ComboCount)" Title="Max Combo"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.DrumrollCount)" Title="Drum Rolls"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.HitCount)" Title="Hit"/>
|
||||
<Column T="SongBestData" Field="@nameof(SongBestData.IsFavorite)" Title="Favorite">
|
||||
<CellTemplate>
|
||||
<MudToggleIconButton Toggled="@context.Item.IsFavorite"
|
||||
ToggledChanged="@(async () => await OnFavoriteToggled(context.Item))"
|
||||
Icon="@Icons.Material.Filled.FavoriteBorder" Color="@Color.Secondary"
|
||||
Title="Add to favorites"
|
||||
ToggledIcon="@Icons.Material.Filled.Favorite" ToggledColor="@Color.Secondary"
|
||||
ToggledTitle="Remove from favorites"/>
|
||||
</CellTemplate>
|
||||
</Column>
|
||||
</Columns>
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="SongBestData"/>
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
</MudTabPanel>
|
||||
}
|
||||
</MudTabs>
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
||||
|
||||
|
||||
@ -82,7 +90,7 @@ else
|
||||
public int Baid { get; set; }
|
||||
|
||||
private SongBestResponse? response;
|
||||
|
||||
|
||||
private const string ICON_STYLE = "width:25px; height:25px;";
|
||||
|
||||
private readonly List<BreadcrumbItem> breadcrumbs = new()
|
||||
@ -94,7 +102,13 @@ else
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
response = await Client.GetFromJsonAsync<SongBestResponse>($"api/PlayData/{Baid}");
|
||||
|
||||
response.ThrowIfNull();
|
||||
response.SongBestData.Sort((data1, data2) =>
|
||||
{
|
||||
return GameDataService.GetMusicIndexBySongId(data1.SongId)
|
||||
.CompareTo(GameDataService.GetMusicIndexBySongId(data2.SongId));
|
||||
});
|
||||
|
||||
breadcrumbs.Add(new BreadcrumbItem($"Card: {Baid}", href: null, disabled: true));
|
||||
breadcrumbs.Add(new BreadcrumbItem("Play Data", href: $"/Cards/{Baid}/PlayResults", disabled: false));
|
||||
}
|
||||
@ -123,7 +137,7 @@ else
|
||||
CrownType.Gold => "Full Combo",
|
||||
CrownType.Dondaful => "Donderful Combo",
|
||||
_ => ""
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Net.Http.Json;
|
||||
using SharedProject.Enums;
|
||||
using TaikoWebUI.Shared.Models;
|
||||
using Throw;
|
||||
|
||||
@ -9,9 +10,7 @@ public class GameDataService : IGameDataService
|
||||
{
|
||||
private readonly HttpClient client;
|
||||
|
||||
private readonly Dictionary<uint, string> musicNameMap = new();
|
||||
|
||||
private readonly Dictionary<uint, string> musicArtistMap = new();
|
||||
private readonly Dictionary<uint, MusicDetail> musicMap = new();
|
||||
|
||||
public GameDataService(HttpClient client)
|
||||
{
|
||||
@ -22,10 +21,13 @@ public class GameDataService : IGameDataService
|
||||
{
|
||||
var musicInfo = await client.GetFromJsonAsync<MusicInfo>($"{dataBaseUrl}/data/musicinfo.json");
|
||||
var wordList = await client.GetFromJsonAsync<WordList>($"{dataBaseUrl}/data/wordlist.json");
|
||||
var musicOrder = await client.GetFromJsonAsync<MusicOrder>($"{dataBaseUrl}/data/music_order.json");
|
||||
|
||||
musicInfo.ThrowIfNull();
|
||||
wordList.ThrowIfNull();
|
||||
musicOrder.ThrowIfNull();
|
||||
|
||||
// To prevent duplicate entries in wordlist
|
||||
var dict = wordList.WordListEntries.GroupBy(entry => entry.Key)
|
||||
.ToImmutableDictionary(group => group.Key, group => group.First());
|
||||
foreach (var music in musicInfo.Items)
|
||||
@ -35,19 +37,47 @@ public class GameDataService : IGameDataService
|
||||
|
||||
var musicName = dict.GetValueOrDefault(songNameKey, new WordListEntry());
|
||||
var musicArtist = dict.GetValueOrDefault(songArtistKey, new WordListEntry());
|
||||
|
||||
musicNameMap.TryAdd(music.SongId, musicName.JapaneseText);
|
||||
musicArtistMap.TryAdd(music.SongId, musicArtist.JapaneseText);
|
||||
|
||||
var musicSongId = music.SongId;
|
||||
var musicDetail = new MusicDetail
|
||||
{
|
||||
SongId = musicSongId,
|
||||
SongName = musicName.JapaneseText,
|
||||
ArtistName = musicArtist.JapaneseText,
|
||||
Genre = music.Genre
|
||||
};
|
||||
|
||||
musicMap.TryAdd(musicSongId, musicDetail);
|
||||
}
|
||||
|
||||
for (var index = 0; index < musicOrder.Order.Count; index++)
|
||||
{
|
||||
var musicOrderEntry = musicOrder.Order[index];
|
||||
var songId = musicOrderEntry.SongId;
|
||||
if (musicMap.ContainsKey(songId))
|
||||
{
|
||||
musicMap[songId].Index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetMusicNameBySongId(uint songId)
|
||||
{
|
||||
return musicNameMap.GetValueOrDefault(songId, string.Empty);
|
||||
return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.SongName : string.Empty;
|
||||
}
|
||||
|
||||
public string GetMusicArtistBySongId(uint songId)
|
||||
{
|
||||
return musicArtistMap.GetValueOrDefault(songId, string.Empty);
|
||||
return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.ArtistName : string.Empty;
|
||||
}
|
||||
public SongGenre GetMusicGenreBySongId(uint songId)
|
||||
{
|
||||
return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.Genre : SongGenre.Variety;
|
||||
}
|
||||
|
||||
public int GetMusicIndexBySongId(uint songId)
|
||||
{
|
||||
return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.Index : int.MaxValue;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
namespace TaikoWebUI.Services;
|
||||
using SharedProject.Enums;
|
||||
using TaikoWebUI.Shared.Models;
|
||||
|
||||
namespace TaikoWebUI.Services;
|
||||
|
||||
public interface IGameDataService
|
||||
{
|
||||
@ -7,4 +10,8 @@ public interface IGameDataService
|
||||
public string GetMusicNameBySongId(uint songId);
|
||||
|
||||
public string GetMusicArtistBySongId(uint songId);
|
||||
|
||||
public SongGenre GetMusicGenreBySongId(uint songId);
|
||||
|
||||
public int GetMusicIndexBySongId(uint songId);
|
||||
}
|
16
TaikoWebUI/Shared/Models/MusicDetail.cs
Normal file
16
TaikoWebUI/Shared/Models/MusicDetail.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using SharedProject.Enums;
|
||||
|
||||
namespace TaikoWebUI.Shared.Models;
|
||||
|
||||
public class MusicDetail
|
||||
{
|
||||
public uint SongId { get; set; }
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public string SongName { get; set; } = string.Empty;
|
||||
|
||||
public string ArtistName { get; set; } = string.Empty;
|
||||
|
||||
public SongGenre Genre { get; set; }
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SharedProject.Enums;
|
||||
|
||||
namespace TaikoWebUI.Shared.Models;
|
||||
|
||||
@ -11,5 +12,5 @@ public class MusicInfoEntry
|
||||
public uint SongId { get; set; }
|
||||
|
||||
[JsonPropertyName("genreNo")]
|
||||
public uint Genre { get; set; }
|
||||
public SongGenre Genre { get; set; }
|
||||
}
|
9
TaikoWebUI/Shared/Models/MusicOrder.cs
Normal file
9
TaikoWebUI/Shared/Models/MusicOrder.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace TaikoWebUI.Shared.Models;
|
||||
|
||||
public class MusicOrder
|
||||
{
|
||||
[JsonPropertyName("items")]
|
||||
public List<MusicOrderEntry> Order { get; set; } = new();
|
||||
}
|
10
TaikoWebUI/Shared/Models/MusicOrderEntry.cs
Normal file
10
TaikoWebUI/Shared/Models/MusicOrderEntry.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SharedProject.Enums;
|
||||
|
||||
namespace TaikoWebUI.Shared.Models;
|
||||
|
||||
public class MusicOrderEntry
|
||||
{
|
||||
[JsonPropertyName("uniqueId")]
|
||||
public uint SongId { get; set; }
|
||||
}
|
@ -28,5 +28,9 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\data" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user