From 91d76bfeb52dd6ab91604f778440bbe55fb0e729 Mon Sep 17 00:00:00 2001
From: asesidaa <1061472754@qq.com>
Date: Fri, 9 Sep 2022 20:31:45 +0800
Subject: [PATCH] Add play result sample page and update related parts
---
.../Models/Requests/SetFavoriteRequest.cs | 8 ++
SharedProject/SharedProject.csproj | 4 -
TaikoLocalServer.sln.DotSettings | 2 +
.../Api/FavoriteSongsController.cs | 9 +-
.../Controllers/Game/MyDonEntryController.cs | 2 +-
TaikoLocalServer/Services/UserDatumService.cs | 9 +-
TaikoWebUI/.gitignore | 2 +
TaikoWebUI/Pages/Card.razor | 4 +-
TaikoWebUI/Pages/PlayResults.razor | 82 +++++++++++++++++++
TaikoWebUI/Program.cs | 11 ++-
TaikoWebUI/Services/GameDataService.cs | 52 ++++++++++++
TaikoWebUI/Services/IGameDataService.cs | 10 +++
TaikoWebUI/Shared/Models/MusicInfo.cs | 9 ++
TaikoWebUI/Shared/Models/MusicInfoEntry.cs | 15 ++++
TaikoWebUI/Shared/Models/WordList.cs | 9 ++
TaikoWebUI/Shared/Models/WordListEntry.cs | 21 +++++
TaikoWebUI/TaikoWebUI.csproj | 9 ++
TaikoWebUI/wwwroot/appsettings.json | 3 +-
18 files changed, 245 insertions(+), 16 deletions(-)
create mode 100644 SharedProject/Models/Requests/SetFavoriteRequest.cs
create mode 100644 TaikoLocalServer.sln.DotSettings
create mode 100644 TaikoWebUI/.gitignore
create mode 100644 TaikoWebUI/Pages/PlayResults.razor
create mode 100644 TaikoWebUI/Services/GameDataService.cs
create mode 100644 TaikoWebUI/Services/IGameDataService.cs
create mode 100644 TaikoWebUI/Shared/Models/MusicInfo.cs
create mode 100644 TaikoWebUI/Shared/Models/MusicInfoEntry.cs
create mode 100644 TaikoWebUI/Shared/Models/WordList.cs
create mode 100644 TaikoWebUI/Shared/Models/WordListEntry.cs
diff --git a/SharedProject/Models/Requests/SetFavoriteRequest.cs b/SharedProject/Models/Requests/SetFavoriteRequest.cs
new file mode 100644
index 0000000..a9d6441
--- /dev/null
+++ b/SharedProject/Models/Requests/SetFavoriteRequest.cs
@@ -0,0 +1,8 @@
+namespace SharedProject.Models.Requests;
+
+public class SetFavoriteRequest
+{
+ public uint Baid { get; set; }
+ public uint SongId { get; set; }
+ public bool IsFavorite { get; set; }
+}
\ No newline at end of file
diff --git a/SharedProject/SharedProject.csproj b/SharedProject/SharedProject.csproj
index e3c7c83..f6af8be 100644
--- a/SharedProject/SharedProject.csproj
+++ b/SharedProject/SharedProject.csproj
@@ -6,10 +6,6 @@
enable
-
-
-
-
diff --git a/TaikoLocalServer.sln.DotSettings b/TaikoLocalServer.sln.DotSettings
new file mode 100644
index 0000000..4153d9b
--- /dev/null
+++ b/TaikoLocalServer.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/TaikoLocalServer/Controllers/Api/FavoriteSongsController.cs b/TaikoLocalServer/Controllers/Api/FavoriteSongsController.cs
index 7dbda2c..5ecded6 100644
--- a/TaikoLocalServer/Controllers/Api/FavoriteSongsController.cs
+++ b/TaikoLocalServer/Controllers/Api/FavoriteSongsController.cs
@@ -1,4 +1,5 @@
-using TaikoLocalServer.Services.Interfaces;
+using SharedProject.Models.Requests;
+using TaikoLocalServer.Services.Interfaces;
namespace TaikoLocalServer.Controllers.Api;
@@ -14,16 +15,16 @@ public class FavoriteSongsController : BaseController
}
[HttpPost]
- public async Task UpdateFavoriteSong(uint baid, uint songId, bool isFavorite)
+ public async Task UpdateFavoriteSong(SetFavoriteRequest request)
{
- var user = await userDatumService.GetFirstUserDatumOrNull(baid);
+ var user = await userDatumService.GetFirstUserDatumOrNull(request.Baid);
if (user is null)
{
return NotFound();
}
- await userDatumService.UpdateFavoriteSong(baid, songId, isFavorite);
+ await userDatumService.UpdateFavoriteSong(request.Baid, request.SongId, request.IsFavorite);
return NoContent();
}
}
\ No newline at end of file
diff --git a/TaikoLocalServer/Controllers/Game/MyDonEntryController.cs b/TaikoLocalServer/Controllers/Game/MyDonEntryController.cs
index b11f3a7..e4ac874 100644
--- a/TaikoLocalServer/Controllers/Game/MyDonEntryController.cs
+++ b/TaikoLocalServer/Controllers/Game/MyDonEntryController.cs
@@ -40,7 +40,7 @@ public class MyDonEntryController : BaseController
ColorFace = 0,
ColorBody = 1,
ColorLimb = 3,
- FavoriteSongsArray = "{}"
+ FavoriteSongsArray = "[]"
};
await userDatumService.InsertUserDatum(newUser);
diff --git a/TaikoLocalServer/Services/UserDatumService.cs b/TaikoLocalServer/Services/UserDatumService.cs
index 39225ed..8b3d5ca 100644
--- a/TaikoLocalServer/Services/UserDatumService.cs
+++ b/TaikoLocalServer/Services/UserDatumService.cs
@@ -102,9 +102,14 @@ public class UserDatumService : IUserDatumService
{
favoriteSet.Remove(songId);
}
-
- await JsonSerializer.SerializeAsync(stringStream, favoriteSet);
+ using var newFavoriteSongStream = new MemoryStream();
+ await JsonSerializer.SerializeAsync(newFavoriteSongStream, favoriteSet);
+ newFavoriteSongStream.Position = 0;
+ using var reader = new StreamReader(newFavoriteSongStream);
+
+ userDatum.FavoriteSongsArray = await reader.ReadToEndAsync();
+ logger.LogInformation("Favorite songs are: {Favorite}", userDatum.FavoriteSongsArray);
context.Update(userDatum);
await context.SaveChangesAsync();
}
diff --git a/TaikoWebUI/.gitignore b/TaikoWebUI/.gitignore
new file mode 100644
index 0000000..5a7f5b5
--- /dev/null
+++ b/TaikoWebUI/.gitignore
@@ -0,0 +1,2 @@
+wwwroot/data/musicinfo
+wwwroot/data/wordlist
\ No newline at end of file
diff --git a/TaikoWebUI/Pages/Card.razor b/TaikoWebUI/Pages/Card.razor
index 09d1755..e04e583 100644
--- a/TaikoWebUI/Pages/Card.razor
+++ b/TaikoWebUI/Pages/Card.razor
@@ -1,4 +1,4 @@
-@page "/Card/{baid}"
+@page "/Card/{baid:int}"
@using SharedProject.Enums
@using SharedProject.Models
@inject HttpClient Client
@@ -121,7 +121,7 @@
@code {
[Parameter]
- public string? Baid { get; set; }
+ public int Baid { get; set; }
private UserSetting? response;
diff --git a/TaikoWebUI/Pages/PlayResults.razor b/TaikoWebUI/Pages/PlayResults.razor
new file mode 100644
index 0000000..8a76e13
--- /dev/null
+++ b/TaikoWebUI/Pages/PlayResults.razor
@@ -0,0 +1,82 @@
+@using TaikoWebUI.Services
+@using SharedProject.Models.Responses
+@using SharedProject.Models
+@using SharedProject.Models.Requests
+@inject IGameDataService GameDataService
+@inject HttpClient Client
+
+@page "/PlayResults/{baid:int}"
+PlayResults for baid : @Baid
+
+@if (response is null)
+{
+ No data
+}
+else
+{
+
+
+ @* Notice here we have to use cell template for custom conversion *@
+ @* Field is retrieved using reflection, so it is a string with name equals field name*@
+
+
+ @GameDataService.GetMusicNameBySongId(context.Item.SongId)
+
+
+
+
+ @GameDataService.GetMusicArtistBySongId(context.Item.SongId)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+@code {
+
+ [Parameter]
+ public int Baid { get; set; }
+
+ private SongBestResponse? response;
+
+ protected override async Task OnInitializedAsync()
+ {
+ await base.OnInitializedAsync();
+ response = await Client.GetFromJsonAsync($"api/PlayData/{Baid}");
+ }
+
+ 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;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Program.cs b/TaikoWebUI/Program.cs
index 8e3eca2..bdb486b 100644
--- a/TaikoWebUI/Program.cs
+++ b/TaikoWebUI/Program.cs
@@ -2,15 +2,22 @@ using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using TaikoWebUI;
using MudBlazor.Services;
+using TaikoWebUI.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#app");
builder.RootComponents.Add("head::after");
-builder.Services.AddScoped(sp => new HttpClient
+builder.Services.AddSingleton(sp => new HttpClient
{
BaseAddress = new Uri(builder.Configuration.GetValue("BaseUrl"))
});
builder.Services.AddMudServices();
+builder.Services.AddSingleton();
-await builder.Build().RunAsync();
\ No newline at end of file
+var host = builder.Build();
+
+var gameDataService = host.Services.GetRequiredService();
+await gameDataService.InitializeAsync(builder.Configuration.GetValue("DataBaseUrl"));
+
+await host.RunAsync();
\ No newline at end of file
diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs
new file mode 100644
index 0000000..73cc79c
--- /dev/null
+++ b/TaikoWebUI/Services/GameDataService.cs
@@ -0,0 +1,52 @@
+using System.Collections.Immutable;
+using System.Net.Http.Json;
+using TaikoWebUI.Shared.Models;
+using Throw;
+
+namespace TaikoWebUI.Services;
+
+public class GameDataService : IGameDataService
+{
+ private readonly HttpClient client;
+
+ private readonly Dictionary musicNameMap = new();
+
+ private readonly Dictionary musicArtistMap = new();
+
+ public GameDataService(HttpClient client)
+ {
+ this.client = client;
+ }
+
+ public async Task InitializeAsync(string dataBaseUrl)
+ {
+ var musicInfo = await client.GetFromJsonAsync($"{dataBaseUrl}/data/musicinfo");
+ var wordList = await client.GetFromJsonAsync($"{dataBaseUrl}/data/wordlist");
+
+ musicInfo.ThrowIfNull();
+ wordList.ThrowIfNull();
+
+ var dict = wordList.WordListEntries.ToImmutableDictionary(entry => entry.Key);
+ foreach (var music in musicInfo.Items)
+ {
+ var songNameKey = $"song_{music.Id}";
+ var songArtistKey = $"song_sub_{music.Id}";
+
+ 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);
+ }
+ }
+
+ public string GetMusicNameBySongId(uint songId)
+ {
+ return musicNameMap.GetValueOrDefault(songId, string.Empty);
+ }
+
+ public string GetMusicArtistBySongId(uint songId)
+ {
+ return musicArtistMap.GetValueOrDefault(songId, string.Empty);
+ }
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs
new file mode 100644
index 0000000..d5a1410
--- /dev/null
+++ b/TaikoWebUI/Services/IGameDataService.cs
@@ -0,0 +1,10 @@
+namespace TaikoWebUI.Services;
+
+public interface IGameDataService
+{
+ public Task InitializeAsync(string dataBaseUrl);
+
+ public string GetMusicNameBySongId(uint songId);
+
+ public string GetMusicArtistBySongId(uint songId);
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Shared/Models/MusicInfo.cs b/TaikoWebUI/Shared/Models/MusicInfo.cs
new file mode 100644
index 0000000..3cedc11
--- /dev/null
+++ b/TaikoWebUI/Shared/Models/MusicInfo.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace TaikoWebUI.Shared.Models;
+
+public class MusicInfo
+{
+ [JsonPropertyName("items")]
+ public List Items { get; set; } = new();
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Shared/Models/MusicInfoEntry.cs b/TaikoWebUI/Shared/Models/MusicInfoEntry.cs
new file mode 100644
index 0000000..0eda2de
--- /dev/null
+++ b/TaikoWebUI/Shared/Models/MusicInfoEntry.cs
@@ -0,0 +1,15 @@
+using System.Text.Json.Serialization;
+
+namespace TaikoWebUI.Shared.Models;
+
+public class MusicInfoEntry
+{
+ [JsonPropertyName("id")]
+ public string Id { get; set; } = string.Empty;
+
+ [JsonPropertyName("uniqueId")]
+ public uint SongId { get; set; }
+
+ [JsonPropertyName("genreNo")]
+ public uint Genre { get; set; }
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Shared/Models/WordList.cs b/TaikoWebUI/Shared/Models/WordList.cs
new file mode 100644
index 0000000..ce837a9
--- /dev/null
+++ b/TaikoWebUI/Shared/Models/WordList.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace TaikoWebUI.Shared.Models;
+
+public class WordList
+{
+ [JsonPropertyName("items")]
+ public List WordListEntries { get; set; } = new();
+}
\ No newline at end of file
diff --git a/TaikoWebUI/Shared/Models/WordListEntry.cs b/TaikoWebUI/Shared/Models/WordListEntry.cs
new file mode 100644
index 0000000..3fe7324
--- /dev/null
+++ b/TaikoWebUI/Shared/Models/WordListEntry.cs
@@ -0,0 +1,21 @@
+using System.Text.Json.Serialization;
+
+namespace TaikoWebUI.Shared.Models;
+
+public class WordListEntry
+{
+ [JsonPropertyName("key")]
+ public string Key { get; set; } = string.Empty;
+
+ [JsonPropertyName("japaneseText")]
+ public string JapaneseText { get; set; } = string.Empty;
+
+ [JsonPropertyName("englishUsText")]
+ public string EnglishUsText { get; set; } = string.Empty;
+
+ [JsonPropertyName("chineseTText")]
+ public string ChineseTText { get; set; } = string.Empty;
+
+ [JsonPropertyName("koreanText")]
+ public string KoreanText { get; set; } = string.Empty;
+}
\ No newline at end of file
diff --git a/TaikoWebUI/TaikoWebUI.csproj b/TaikoWebUI/TaikoWebUI.csproj
index 68108c1..408f607 100644
--- a/TaikoWebUI/TaikoWebUI.csproj
+++ b/TaikoWebUI/TaikoWebUI.csproj
@@ -16,5 +16,14 @@
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
\ No newline at end of file
diff --git a/TaikoWebUI/wwwroot/appsettings.json b/TaikoWebUI/wwwroot/appsettings.json
index e575e49..44139dc 100644
--- a/TaikoWebUI/wwwroot/appsettings.json
+++ b/TaikoWebUI/wwwroot/appsettings.json
@@ -1,3 +1,4 @@
{
- "BaseUrl": "http://localhost:5000"
+ "BaseUrl": "http://localhost:5000",
+ "DataBaseUrl": "https://localhost:44398"
}
\ No newline at end of file