From d6e27fa75c33f37a66c5a69130b63e3049a32ac1 Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Wed, 14 Sep 2022 20:14:21 +0800 Subject: [PATCH 01/20] Add costume setting to user settings and page prototype --- SharedProject/Models/UserSetting.cs | 31 ++++++++++- TaikoLocalServer.sln.DotSettings | 2 + TaikoLocalServer/Common/Utils/JsonHelper.cs | 52 +++++++++++++++++++ TaikoLocalServer/Common/Utils/PathHelper.cs | 9 +++- TaikoLocalServer/Context/TaikoDbContext.cs | 2 +- .../Controllers/Api/UserSettingsController.cs | 35 ++++++++++++- .../Controllers/Game/BaidController.cs | 33 ++---------- .../Game/InitialDataCheckController.cs | 9 +--- TaikoLocalServer/Entities/UserDatum.cs | 10 ++-- TaikoLocalServer/Program.cs | 2 +- .../Services/Interfaces/IUserDatumService.cs | 2 + TaikoLocalServer/TaikoLocalServer.csproj | 4 +- .../wwwroot/{ => data}/dan_data.json | 0 TaikoWebUI/Pages/Profile.razor | 25 +++++++++ 14 files changed, 165 insertions(+), 51 deletions(-) create mode 100644 TaikoLocalServer/Common/Utils/JsonHelper.cs rename TaikoLocalServer/wwwroot/{ => data}/dan_data.json (100%) diff --git a/SharedProject/Models/UserSetting.cs b/SharedProject/Models/UserSetting.cs index 6020490..50808a4 100644 --- a/SharedProject/Models/UserSetting.cs +++ b/SharedProject/Models/UserSetting.cs @@ -20,9 +20,36 @@ public class UserSetting public int NotesPosition { get; set; } - public string MyDonName { get; set; } = String.Empty; + public string MyDonName { get; set; } = string.Empty; - public string Title { get; set; } = String.Empty; + public string Title { get; set; } = string.Empty; public uint TitlePlateId { get; set; } + + public uint Kigurumi { get; set; } + + public uint Head { get; set; } + + public uint Body { get; set; } + + public uint Face { get; set; } + + public uint Puchi { get; set; } + + public List UnlockedKigurumi { get; set; } = new(); + + public List UnlockedHead { get; set; } = new(); + + public List UnlockedBody { get; set; } = new(); + + public List UnlockedFace { get; set; } = new(); + + public List UnlockedPuchi { get; set; } = new(); + + public uint FaceColor { get; set; } + + public uint BodyColor { get; set; } + + public uint LimbColor { get; set; } + } \ No newline at end of file diff --git a/TaikoLocalServer.sln.DotSettings b/TaikoLocalServer.sln.DotSettings index eea663e..abd12a3 100644 --- a/TaikoLocalServer.sln.DotSettings +++ b/TaikoLocalServer.sln.DotSettings @@ -1,4 +1,6 @@  + True True True + True True \ No newline at end of file diff --git a/TaikoLocalServer/Common/Utils/JsonHelper.cs b/TaikoLocalServer/Common/Utils/JsonHelper.cs new file mode 100644 index 0000000..d409045 --- /dev/null +++ b/TaikoLocalServer/Common/Utils/JsonHelper.cs @@ -0,0 +1,52 @@ +using System.Text.Json; + +namespace TaikoLocalServer.Common.Utils; + +public static class JsonHelper +{ + public static List GetCostumeDataFromUserData(UserDatum userData, ILogger logger) + { + var costumeData = new List { 0, 0, 0, 0, 0 }; + try + { + costumeData = JsonSerializer.Deserialize>(userData.CostumeData); + } + catch (JsonException e) + { + logger.LogError(e, "Parsing costume json data failed"); + } + + if (costumeData != null && costumeData.Count >= 5) + { + return costumeData; + } + + logger.LogWarning("Costume data is null or count less than 5!"); + costumeData = new List { 0, 0, 0, 0, 0 }; + + return costumeData; + } + + public static List> GetCostumeUnlockDataFromUserData(UserDatum userData, ILogger logger) + { + var costumeUnlockData = new List> { new(), new(), new(), new(), new() }; + try + { + costumeUnlockData = JsonSerializer.Deserialize>>(userData.CostumeFlgArray); + } + catch (JsonException e) + { + logger.LogError(e, "Parsing costume json data failed"); + } + + if (costumeUnlockData != null && costumeUnlockData.Count >= 5) + { + return costumeUnlockData; + } + + logger.LogWarning("Costume unlock data is null or count less than 5!"); + costumeUnlockData = new List> { new(), new(), new(), new(), new() }; + + return costumeUnlockData; + } +} \ No newline at end of file diff --git a/TaikoLocalServer/Common/Utils/PathHelper.cs b/TaikoLocalServer/Common/Utils/PathHelper.cs index 152d29f..9073fdc 100644 --- a/TaikoLocalServer/Common/Utils/PathHelper.cs +++ b/TaikoLocalServer/Common/Utils/PathHelper.cs @@ -2,7 +2,7 @@ public static class PathHelper { - public static string GetDataPath() + public static string GetRootPath() { var path = Environment.ProcessPath; if (path is null) @@ -14,6 +14,11 @@ public static class PathHelper { throw new ApplicationException(); } - return Path.Combine(parentPath.ToString(), "wwwroot", "data"); + return Path.Combine(parentPath.ToString(), "wwwroot"); + } + + public static string GetDataPath() + { + return Path.Combine(GetRootPath(), "data"); } } \ No newline at end of file diff --git a/TaikoLocalServer/Context/TaikoDbContext.cs b/TaikoLocalServer/Context/TaikoDbContext.cs index f6c80cb..69d41ae 100644 --- a/TaikoLocalServer/Context/TaikoDbContext.cs +++ b/TaikoLocalServer/Context/TaikoDbContext.cs @@ -22,7 +22,7 @@ { return; } - var path = Path.Combine(PathHelper.GetDataPath(), Constants.DEFAULT_DB_NAME); + var path = Path.Combine(PathHelper.GetRootPath(), Constants.DEFAULT_DB_NAME); optionsBuilder.UseSqlite($"Data Source={path}"); } diff --git a/TaikoLocalServer/Controllers/Api/UserSettingsController.cs b/TaikoLocalServer/Controllers/Api/UserSettingsController.cs index 43ac82b..40feec2 100644 --- a/TaikoLocalServer/Controllers/Api/UserSettingsController.cs +++ b/TaikoLocalServer/Controllers/Api/UserSettingsController.cs @@ -1,9 +1,11 @@ using System.Buffers.Binary; +using System.Text.Json; using SharedProject.Models; using SharedProject.Models.Responses; using SharedProject.Utils; using TaikoLocalServer.Services; using TaikoLocalServer.Services.Interfaces; +using Throw; namespace TaikoLocalServer.Controllers.Api; @@ -28,6 +30,10 @@ public class UserSettingsController : BaseController return NotFound(); } + var costumeData = JsonHelper.GetCostumeDataFromUserData(user, Logger); + + var costumeUnlockData = JsonHelper.GetCostumeUnlockDataFromUserData(user, Logger); + var response = new UserSetting { AchievementDisplayDifficulty = user.AchievementDisplayDifficulty, @@ -40,7 +46,20 @@ public class UserSettingsController : BaseController ToneId = user.SelectedToneId, MyDonName = user.MyDonName, Title = user.Title, - TitlePlateId = user.TitlePlateId + TitlePlateId = user.TitlePlateId, + Kigurumi = costumeData[0], + Head = costumeData[1], + Body = costumeData[2], + Face = costumeData[3], + Puchi = costumeData[4], + UnlockedKigurumi = costumeUnlockData[0], + UnlockedHead = costumeUnlockData[1], + UnlockedBody = costumeUnlockData[2], + UnlockedFace = costumeUnlockData[3], + UnlockedPuchi = costumeUnlockData[4], + BodyColor = user.ColorBody, + FaceColor = user.ColorFace, + LimbColor = user.ColorLimb }; return Ok(response); } @@ -55,6 +74,15 @@ public class UserSettingsController : BaseController return NotFound(); } + var costumes = new List + { + userSetting.Kigurumi, + userSetting.Head, + userSetting.Body, + userSetting.Face, + userSetting.Puchi, + }; + user.IsSkipOn = userSetting.IsSkipOn; user.IsVoiceOn = userSetting.IsVoiceOn; user.DisplayAchievement = userSetting.IsDisplayAchievement; @@ -66,6 +94,11 @@ public class UserSettingsController : BaseController user.MyDonName = userSetting.MyDonName; user.Title = userSetting.Title; user.TitlePlateId = userSetting.TitlePlateId; + user.ColorBody = userSetting.BodyColor; + user.ColorFace = userSetting.FaceColor; + user.ColorLimb = userSetting.LimbColor; + user.CostumeData = JsonSerializer.Serialize(costumes); + await userDatumService.UpdateUserDatum(user); diff --git a/TaikoLocalServer/Controllers/Game/BaidController.cs b/TaikoLocalServer/Controllers/Game/BaidController.cs index 3ffd832..32b98bd 100644 --- a/TaikoLocalServer/Controllers/Game/BaidController.cs +++ b/TaikoLocalServer/Controllers/Game/BaidController.cs @@ -1,6 +1,4 @@ -using System.Text.Json; -using TaikoLocalServer.Services.Interfaces; -using Throw; +using TaikoLocalServer.Services.Interfaces; namespace TaikoLocalServer.Controllers.Game; @@ -79,34 +77,9 @@ public class BaidController : BaseController var scoreRankCount = CalculateScoreRankCount(songCountData); - var costumeData = new List{ 0, 0, 0, 0, 0 }; - try - { - costumeData = JsonSerializer.Deserialize>(userData.CostumeData); - } - catch (JsonException e) - { - Logger.LogError(e, "Parsing costume json data failed"); - } - if (costumeData == null || costumeData.Count < 5) - { - Logger.LogWarning("Costume data is null or count less than 5!"); - costumeData = new List { 0, 0, 0, 0, 0 }; - } + var costumeData = JsonHelper.GetCostumeDataFromUserData(userData, Logger); - var costumeArrays = Array.Empty(); - try - { - costumeArrays = JsonSerializer.Deserialize(userData.CostumeFlgArray); - } - catch (JsonException e) - { - Logger.LogError(e, "Parsing costume flg json data failed"); - } - - // The only way to get a null is provide string "null" as input, - // which means database content need to be fixed, so better throw - costumeArrays.ThrowIfNull("Costume flg should never be null!"); + var costumeArrays = JsonHelper.GetCostumeUnlockDataFromUserData(userData, Logger); var costumeFlagArrays = Constants.CostumeFlagArraySizes .Select((size, index) => FlagCalculator.GetBitArrayFromIds(costumeArrays[index], size, Logger)) diff --git a/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs b/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs index 1693e5c..3e1a129 100644 --- a/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs +++ b/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs @@ -14,13 +14,8 @@ public class InitialDataCheckController : BaseController(); for (var danId = Constants.MIN_DAN_ID; danId <= Constants.MAX_DAN_ID; danId++) diff --git a/TaikoLocalServer/Entities/UserDatum.cs b/TaikoLocalServer/Entities/UserDatum.cs index 89be015..cfd98b6 100644 --- a/TaikoLocalServer/Entities/UserDatum.cs +++ b/TaikoLocalServer/Entities/UserDatum.cs @@ -6,10 +6,10 @@ public string MyDonName { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; public uint TitlePlateId { get; set; } - public string FavoriteSongsArray { get; set; } = string.Empty; - public string ToneFlgArray { get; set; } = string.Empty; - public string TitleFlgArray { get; set; } = string.Empty; - public string CostumeFlgArray { get; set; } = string.Empty; + public string FavoriteSongsArray { get; set; } = "[]"; + public string ToneFlgArray { get; set; } = "[]"; + public string TitleFlgArray { get; set; } = "[]"; + public string CostumeFlgArray { get; set; } = "[]"; public short OptionSetting { get; set; } public int NotesPosition { get; set; } public bool IsVoiceOn { get; set; } @@ -20,7 +20,7 @@ public uint ColorBody { get; set; } public uint ColorFace { get; set; } public uint ColorLimb { get; set; } - public string CostumeData { get; set; } = string.Empty; + public string CostumeData { get; set; } = "[[],[],[],[],[]]"; public bool DisplayDan { get; set; } public bool DisplayAchievement { get; set; } public Difficulty AchievementDisplayDifficulty { get; set; } diff --git a/TaikoLocalServer/Program.cs b/TaikoLocalServer/Program.cs index a0cb9bc..e12a919 100644 --- a/TaikoLocalServer/Program.cs +++ b/TaikoLocalServer/Program.cs @@ -28,7 +28,7 @@ builder.Services.AddDbContext(option => { dbName = Constants.DEFAULT_DB_NAME; } - var path = Path.Combine(PathHelper.GetDataPath(), dbName); + var path = Path.Combine(PathHelper.GetRootPath(), dbName); option.UseSqlite($"Data Source={path}"); }); builder.Services.AddHttpLogging(options => diff --git a/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs b/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs index c78d592..25d811c 100644 --- a/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs +++ b/TaikoLocalServer/Services/Interfaces/IUserDatumService.cs @@ -17,4 +17,6 @@ public interface IUserDatumService public Task> GetFavoriteSongIds(uint baid); public Task UpdateFavoriteSong(uint baid, uint songId, bool isFavorite); + + } \ No newline at end of file diff --git a/TaikoLocalServer/TaikoLocalServer.csproj b/TaikoLocalServer/TaikoLocalServer.csproj index fd477fb..a2bcdb8 100644 --- a/TaikoLocalServer/TaikoLocalServer.csproj +++ b/TaikoLocalServer/TaikoLocalServer.csproj @@ -35,10 +35,10 @@ - + PreserveNewest - + PreserveNewest diff --git a/TaikoLocalServer/wwwroot/dan_data.json b/TaikoLocalServer/wwwroot/data/dan_data.json similarity index 100% rename from TaikoLocalServer/wwwroot/dan_data.json rename to TaikoLocalServer/wwwroot/data/dan_data.json diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index a70d29e..f898932 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -90,6 +90,31 @@ + + + + Costume Options + + + + + + + + + + + + + + + + + + + + + From 4457fe439ff8b4677252fbac6684164329960bb7 Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Wed, 14 Sep 2022 21:15:14 +0800 Subject: [PATCH 02/20] Update merge --- .../Controllers/Game/InitialDataCheckController.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs b/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs index b3f8278..2352c79 100644 --- a/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs +++ b/TaikoLocalServer/Controllers/Game/InitialDataCheckController.cs @@ -20,10 +20,8 @@ public class InitialDataCheckController : BaseController(); for (var danId = Constants.MIN_DAN_ID; danId <= Constants.MAX_DAN_ID; danId++) From fb3ceac51c5e7f09c6fd21d999973bad2cf0fbb1 Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 10:26:06 -0400 Subject: [PATCH 03/20] Add costume constants --- TaikoWebUI/Pages/Profile.razor.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index b646c36..68359d6 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -9,6 +9,28 @@ public partial class Profile private bool isSavingOptions; + private const int COSTUME_HEAD_MAX = 138; + private const int COSTUME_FACE_MAX = 57; + private const int COSTUME_BODY_MAX = 154; + private const int COSTUME_KIGURUMI_MAX = 152; + private const int COSTUME_PUCHI_MAX = 127; + private const int COSTUME_COLOR_MAX = 62; + + private readonly string[] costumeColors = + { + "F84828", "68C0C0", "DC1500", "F8F0E0", "009687", "00BF87", + "00FF9A", "66FFC2", "FFFFFF", "690000", "FF0000", "FF6666", + "FFB3B3", "00BCC2", "00F7FF", "66FAFF", "B3FDFF", "B3FDFF", + "E4E4E4", "993800", "FF5E00", "FF9E78", "FFCFB3", "005199", + "0088FF", "66B8FF", "B3DBFF", "B9B9B9", "B37700", "FFAA00", + "FFCC66", "FFE2B3", "000C80", "0019FF", "6675FF", "B3BAFF", + "858585", "B39B00", "FFDD00", "FFFF71", "2B0080", "5500FF", + "9966FF", "CCB3FF", "505050", "38A100", "78C900", "B3FF00", + "DCFF8A", "610080", "C400FF", "DC66FF", "EDB3FF", "232323", + "006600", "00B800", "00FF00", "8AFF9E", "990059", "FF0095", + "FF66BF", "FFB3DF", "000000" + }; + private readonly string[] speedStrings = { "1.0", "1.1", "1.2", "1.3", "1.4", From 0888581d27a266809852b51a11fa6d865c77c95e Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 14:17:46 -0400 Subject: [PATCH 04/20] Add color pickers --- SharedProject/Models/CostumeData.cs | 16 ++ TaikoWebUI/Pages/Profile.razor | 253 +++++++++++++++--------- TaikoWebUI/Pages/Profile.razor.cs | 35 ++-- TaikoWebUI/Services/GameDataService.cs | 17 +- TaikoWebUI/Services/IGameDataService.cs | 2 + TaikoWebUI/wwwroot/style.overrides.css | 11 ++ 6 files changed, 219 insertions(+), 115 deletions(-) create mode 100644 SharedProject/Models/CostumeData.cs diff --git a/SharedProject/Models/CostumeData.cs b/SharedProject/Models/CostumeData.cs new file mode 100644 index 0000000..f09ce43 --- /dev/null +++ b/SharedProject/Models/CostumeData.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace SharedProject.Models; + +public class CostumeData +{ + public uint Head { get; set; } + + public uint Body { get; set; } + + public uint Face { get; set; } + + public uint Kigurumi { get; set; } + + public uint Puchi { get; set; } +} \ No newline at end of file diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index f898932..2348264 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -8,116 +8,180 @@ @if (response is not null) { - + - - -

Profile Options

+ + + + +

Profile Options

- + - - - - - - - @for (uint i = 0; i < 8; i++) + + + + + + + @for (uint i = 0; i < 8; i++) + { + var index = i; + @titlePlateStrings[index] + } + + + + + + @foreach (var item in Enum.GetValues()) { - var index = i; - @titlePlateStrings[index] + } - - - - @foreach (var item in Enum.GetValues()) - { - - } - + + +
+
- - -
-
+ + +

Costume Options

+ + + + + @for (uint i = 0; i < GameDataService.COSTUME_HEAD_MAX; i++) + { + var index = i; + @index + } + - - -

Song Options

- - - - - - - - - - - - - @for (uint i = 0; i < 15; i++) - { - var index = i; - @speedStrings[index] - } - + + @for (uint i = 0; i < GameDataService.COSTUME_BODY_MAX; i++) + { + var index = i; + @index + } + - - @foreach (var item in Enum.GetValues()) - { - - } - + + @for (uint i = 0; i < GameDataService.COSTUME_FACE_MAX; i++) + { + var index = i; + @index + } + - - @for (uint i = 0; i < 19; i++) - { - var index = i; - @toneStrings[index] - } - + + @for (uint i = 0; i < GameDataService.COSTUME_KIGURUMI_MAX; i++) + { + var index = i; + @index + } + - - Notes Position - - - - -
-
+ + @for (uint i = 0; i < GameDataService.COSTUME_PUCHI_MAX; i++) + { + var index = i; + @index + } + +
- - - Costume Options - - - - - - - - - - - - - - - - - - - + + + @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+ + @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+ + @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+
+
+
+
+
+ + +

Song Options

+ + + + + + + + + + + + + @for (uint i = 0; i < 15; i++) + { + var index = i; + @speedStrings[index] + } + + + + @foreach (var item in Enum.GetValues()) + { + + } + + + + @for (uint i = 0; i < 19; i++) + { + var index = i; + @toneStrings[index] + } + + + + Notes Position + + + + +
+
+
- - + + + +
} \ No newline at end of file diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index 68359d6..c65ac9f 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -1,4 +1,6 @@ -namespace TaikoWebUI.Pages; +using MudBlazor.Utilities; + +namespace TaikoWebUI.Pages; public partial class Profile { @@ -9,26 +11,19 @@ public partial class Profile private bool isSavingOptions; - private const int COSTUME_HEAD_MAX = 138; - private const int COSTUME_FACE_MAX = 57; - private const int COSTUME_BODY_MAX = 154; - private const int COSTUME_KIGURUMI_MAX = 152; - private const int COSTUME_PUCHI_MAX = 127; - private const int COSTUME_COLOR_MAX = 62; - - private readonly string[] costumeColors = + public string[] costumeColors = { - "F84828", "68C0C0", "DC1500", "F8F0E0", "009687", "00BF87", - "00FF9A", "66FFC2", "FFFFFF", "690000", "FF0000", "FF6666", - "FFB3B3", "00BCC2", "00F7FF", "66FAFF", "B3FDFF", "B3FDFF", - "E4E4E4", "993800", "FF5E00", "FF9E78", "FFCFB3", "005199", - "0088FF", "66B8FF", "B3DBFF", "B9B9B9", "B37700", "FFAA00", - "FFCC66", "FFE2B3", "000C80", "0019FF", "6675FF", "B3BAFF", - "858585", "B39B00", "FFDD00", "FFFF71", "2B0080", "5500FF", - "9966FF", "CCB3FF", "505050", "38A100", "78C900", "B3FF00", - "DCFF8A", "610080", "C400FF", "DC66FF", "EDB3FF", "232323", - "006600", "00B800", "00FF00", "8AFF9E", "990059", "FF0095", - "FF66BF", "FFB3DF", "000000" + "#F84828", "#68C0C0", "#DC1500", "#F8F0E0", "#009687", "#00BF87", + "#00FF9A", "#66FFC2", "#FFFFFF", "#690000", "#FF0000", "#FF6666", + "#FFB3B3", "#00BCC2", "#00F7FF", "#66FAFF", "#B3FDFF", "#E4E4E4", + "#993800", "#FF5E00", "#FF9E78", "#FFCFB3", "#005199", "#0088FF", + "#66B8FF", "#B3DBFF", "#B9B9B9", "#B37700", "#FFAA00", "#FFCC66", + "#FFE2B3", "#000C80", "#0019FF", "#6675FF", "#B3BAFF", "#858585", + "#B39B00", "#FFDD00", "#FFFF71", "#2B0080", "#5500FF", "#9966FF", + "#CCB3FF", "#505050", "#38A100", "#78C900", "#B3FF00", "#DCFF8A", + "#610080", "#C400FF", "#DC66FF", "#EDB3FF", "#232323", "#006600", + "#00B800", "#00FF00", "#8AFF9E", "#990059", "#FF0095", "#FF66BF", + "#FFB3DF", "#000000" }; private readonly string[] speedStrings = diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index 4fd7c2f..871a991 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using MudBlazor.Utilities; using Swan.Mapping; using TaikoWebUI.Shared.Models; @@ -12,6 +13,15 @@ public class GameDataService : IGameDataService private ImmutableDictionary danMap = null!; + private ImmutableDictionary costumeMap = null!; + + public const uint COSTUME_HEAD_MAX = 138; + public const uint COSTUME_FACE_MAX = 57; + public const uint COSTUME_BODY_MAX = 154; + public const uint COSTUME_KIGURUMI_MAX = 152; + public const uint COSTUME_PUCHI_MAX = 127; + public const uint COSTUME_COLOR_MAX = 62; + public GameDataService(HttpClient client) { this.client = client; @@ -38,7 +48,7 @@ public class GameDataService : IGameDataService { 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()); @@ -84,6 +94,11 @@ public class GameDataService : IGameDataService return danMap.GetValueOrDefault(danId, new DanData()); } + public string GetCostumeTitleById(uint costumeId, string type) + { + return ""; + } + public int GetMusicStarLevel(uint songId, Difficulty difficulty) { var success = musicMap.TryGetValue(songId, out var musicDetail); diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs index fbad860..a80c7bd 100644 --- a/TaikoWebUI/Services/IGameDataService.cs +++ b/TaikoWebUI/Services/IGameDataService.cs @@ -8,6 +8,8 @@ public interface IGameDataService public string GetMusicArtistBySongId(uint songId); + public string GetCostumeTitleById(uint costumeId, string type); + public SongGenre GetMusicGenreBySongId(uint songId); public int GetMusicIndexBySongId(uint songId); diff --git a/TaikoWebUI/wwwroot/style.overrides.css b/TaikoWebUI/wwwroot/style.overrides.css index 61dab8d..bbae00c 100644 --- a/TaikoWebUI/wwwroot/style.overrides.css +++ b/TaikoWebUI/wwwroot/style.overrides.css @@ -18,4 +18,15 @@ .mud-progress-linear.bar-pass-red .mud-typography { font-weight: bold; color: #333; +} + +.color-box { + width: 16px; + height: 16px; + border-radius: 9999px; + display: inline-block; + margin-right: 10px; + border: 1px solid black; + position: relative; + top: 2px; } \ No newline at end of file From d75b1a4d9f6a328e12525084bb0ce09f415264e1 Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 15:36:12 -0400 Subject: [PATCH 05/20] Costume select complete --- SharedProject/Models/CostumeData.cs | 16 ------- TaikoWebUI/Pages/Profile.razor | 17 +++++--- TaikoWebUI/Services/GameDataService.cs | 58 ++++++++++++++++++++++--- TaikoWebUI/Services/IGameDataService.cs | 2 - 4 files changed, 62 insertions(+), 31 deletions(-) delete mode 100644 SharedProject/Models/CostumeData.cs diff --git a/SharedProject/Models/CostumeData.cs b/SharedProject/Models/CostumeData.cs deleted file mode 100644 index f09ce43..0000000 --- a/SharedProject/Models/CostumeData.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace SharedProject.Models; - -public class CostumeData -{ - public uint Head { get; set; } - - public uint Body { get; set; } - - public uint Face { get; set; } - - public uint Kigurumi { get; set; } - - public uint Puchi { get; set; } -} \ No newline at end of file diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 2348264..8e3ba5e 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -11,7 +11,7 @@ - +

Profile Options

@@ -56,7 +56,8 @@ @for (uint i = 0; i < GameDataService.COSTUME_HEAD_MAX; i++) { var index = i; - @index + var costumeTitle = GameDataService.headMap[index]; + @index - @costumeTitle } @@ -64,7 +65,8 @@ @for (uint i = 0; i < GameDataService.COSTUME_BODY_MAX; i++) { var index = i; - @index + var costumeTitle = GameDataService.bodyMap[index]; + @index - @costumeTitle } @@ -72,7 +74,8 @@ @for (uint i = 0; i < GameDataService.COSTUME_FACE_MAX; i++) { var index = i; - @index + var costumeTitle = GameDataService.faceMap[index]; + @index - @costumeTitle } @@ -80,7 +83,8 @@ @for (uint i = 0; i < GameDataService.COSTUME_KIGURUMI_MAX; i++) { var index = i; - @index + var costumeTitle = GameDataService.kigurumiMap[index]; + @index - @costumeTitle } @@ -88,7 +92,8 @@ @for (uint i = 0; i < GameDataService.COSTUME_PUCHI_MAX; i++) { var index = i; - @index + var costumeTitle = GameDataService.puchiMap[index]; + @index - @costumeTitle }
diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index 871a991..b1d2f77 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -13,14 +13,18 @@ public class GameDataService : IGameDataService private ImmutableDictionary danMap = null!; - private ImmutableDictionary costumeMap = null!; - public const uint COSTUME_HEAD_MAX = 138; public const uint COSTUME_FACE_MAX = 57; public const uint COSTUME_BODY_MAX = 154; public const uint COSTUME_KIGURUMI_MAX = 152; public const uint COSTUME_PUCHI_MAX = 127; public const uint COSTUME_COLOR_MAX = 62; + + public static string[] headMap = new string[COSTUME_HEAD_MAX]; + public static string[] faceMap = new string[COSTUME_FACE_MAX]; + public static string[] bodyMap = new string[COSTUME_BODY_MAX]; + public static string[] kigurumiMap = new string[COSTUME_KIGURUMI_MAX]; + public static string[] puchiMap = new string[COSTUME_PUCHI_MAX]; public GameDataService(HttpClient client) { @@ -69,6 +73,51 @@ public class GameDataService : IGameDataService musicMap[songId].Index = index; } } + + for (var i = 0; i < COSTUME_HEAD_MAX; i++) + { + var index = i; + var key = $"costume_head_{index}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + headMap[index] = costumeWordlistItem.JapaneseText; + } + + for (var i = 0; i < COSTUME_FACE_MAX; i++) + { + var index = i; + var key = $"costume_face_{index}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + faceMap[index] = costumeWordlistItem.JapaneseText; + } + + for (var i = 0; i < COSTUME_BODY_MAX; i++) + { + var index = i; + var key = $"costume_body_{index}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + bodyMap[index] = costumeWordlistItem.JapaneseText; + } + + for (var i = 0; i < COSTUME_KIGURUMI_MAX; i++) + { + var index = i; + var key = $"costume_kigurumi_{index}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + kigurumiMap[index] = costumeWordlistItem.JapaneseText; + } + + for (var i = 0; i < COSTUME_PUCHI_MAX; i++) + { + var index = i; + var key = $"costume_puchi_{index}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + puchiMap[index] = costumeWordlistItem.JapaneseText; + } } public string GetMusicNameBySongId(uint songId) @@ -94,11 +143,6 @@ public class GameDataService : IGameDataService return danMap.GetValueOrDefault(danId, new DanData()); } - public string GetCostumeTitleById(uint costumeId, string type) - { - return ""; - } - public int GetMusicStarLevel(uint songId, Difficulty difficulty) { var success = musicMap.TryGetValue(songId, out var musicDetail); diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs index a80c7bd..fbad860 100644 --- a/TaikoWebUI/Services/IGameDataService.cs +++ b/TaikoWebUI/Services/IGameDataService.cs @@ -8,8 +8,6 @@ public interface IGameDataService public string GetMusicArtistBySongId(uint songId); - public string GetCostumeTitleById(uint costumeId, string type); - public SongGenre GetMusicGenreBySongId(uint songId); public int GetMusicIndexBySongId(uint songId); From 0e3a54eeefde092cd5e2976f64adf59a1489439d Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 16:13:06 -0400 Subject: [PATCH 06/20] Add missing color, fix max values --- TaikoWebUI/Pages/Profile.razor.cs | 10 +++++----- TaikoWebUI/Services/GameDataService.cs | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index c65ac9f..dc5c5bb 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -19,11 +19,11 @@ public partial class Profile "#993800", "#FF5E00", "#FF9E78", "#FFCFB3", "#005199", "#0088FF", "#66B8FF", "#B3DBFF", "#B9B9B9", "#B37700", "#FFAA00", "#FFCC66", "#FFE2B3", "#000C80", "#0019FF", "#6675FF", "#B3BAFF", "#858585", - "#B39B00", "#FFDD00", "#FFFF71", "#2B0080", "#5500FF", "#9966FF", - "#CCB3FF", "#505050", "#38A100", "#78C900", "#B3FF00", "#DCFF8A", - "#610080", "#C400FF", "#DC66FF", "#EDB3FF", "#232323", "#006600", - "#00B800", "#00FF00", "#8AFF9E", "#990059", "#FF0095", "#FF66BF", - "#FFB3DF", "#000000" + "#B39B00", "#FFDD00", "#FFFF00", "#FFFF71", "#2B0080", "#5500FF", + "#9966FF", "#CCB3FF", "#505050", "#38A100", "#78C900", "#B3FF00", + "#DCFF8A", "#610080", "#C400FF", "#DC66FF", "#EDB3FF", "#232323", + "#006600", "#00B800", "#00FF00", "#8AFF9E", "#990059", "#FF0095", + "#FF66BF", "#FFB3DF", "#000000" }; private readonly string[] speedStrings = diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index b1d2f77..f421683 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -13,12 +13,12 @@ public class GameDataService : IGameDataService private ImmutableDictionary danMap = null!; - public const uint COSTUME_HEAD_MAX = 138; - public const uint COSTUME_FACE_MAX = 57; - public const uint COSTUME_BODY_MAX = 154; - public const uint COSTUME_KIGURUMI_MAX = 152; - public const uint COSTUME_PUCHI_MAX = 127; - public const uint COSTUME_COLOR_MAX = 62; + public const uint COSTUME_HEAD_MAX = 140; + public const uint COSTUME_FACE_MAX = 59; + public const uint COSTUME_BODY_MAX = 156; + public const uint COSTUME_KIGURUMI_MAX = 154; + public const uint COSTUME_PUCHI_MAX = 129; + public const uint COSTUME_COLOR_MAX = 63; public static string[] headMap = new string[COSTUME_HEAD_MAX]; public static string[] faceMap = new string[COSTUME_FACE_MAX]; From 128f2834fe7425db8f7875130e666bb2653cec33 Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 17:20:55 -0400 Subject: [PATCH 07/20] Add autocomplete for player title --- TaikoWebUI/Pages/Profile.razor | 2 +- TaikoWebUI/Pages/Profile.razor.cs | 12 ++++++++++ TaikoWebUI/Services/GameDataService.cs | 33 ++++++++++++++++++++------ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 8e3ba5e..7991626 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -20,7 +20,7 @@ - + diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index dc5c5bb..9c37a68 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -1,4 +1,5 @@ using MudBlazor.Utilities; +using static MudBlazor.Colors; namespace TaikoWebUI.Pages; @@ -72,4 +73,15 @@ public partial class Profile isSavingOptions = false; } + private async Task> SearchForTitle(string value) + { + var titles = GameDataService.titleMap; + + if (string.IsNullOrWhiteSpace(value)) + { + return titles.Values; + } + + return titles.Values.Where(x => x.Contains(value, StringComparison.OrdinalIgnoreCase)); + } } \ No newline at end of file diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index f421683..fcf9380 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -13,19 +13,22 @@ public class GameDataService : IGameDataService private ImmutableDictionary danMap = null!; - public const uint COSTUME_HEAD_MAX = 140; - public const uint COSTUME_FACE_MAX = 59; - public const uint COSTUME_BODY_MAX = 156; - public const uint COSTUME_KIGURUMI_MAX = 154; - public const uint COSTUME_PUCHI_MAX = 129; - public const uint COSTUME_COLOR_MAX = 63; - + public const int COSTUME_HEAD_MAX = 140; + public const int COSTUME_FACE_MAX = 59; + public const int COSTUME_BODY_MAX = 156; + public const int COSTUME_KIGURUMI_MAX = 154; + public const int COSTUME_PUCHI_MAX = 129; + public const int COSTUME_COLOR_MAX = 63; + public const int PLAYER_TITLE_MAX = 749; + public static string[] headMap = new string[COSTUME_HEAD_MAX]; public static string[] faceMap = new string[COSTUME_FACE_MAX]; public static string[] bodyMap = new string[COSTUME_BODY_MAX]; public static string[] kigurumiMap = new string[COSTUME_KIGURUMI_MAX]; public static string[] puchiMap = new string[COSTUME_PUCHI_MAX]; + public static Dictionary titleMap = new(); + public GameDataService(HttpClient client) { this.client = client; @@ -118,6 +121,22 @@ public class GameDataService : IGameDataService var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); puchiMap[index] = costumeWordlistItem.JapaneseText; } + + for (var i = 1; i < PLAYER_TITLE_MAX; i++) + { + var index = i; + var key = $"syougou_{index}"; + + var titleWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + + // prevent duplicate values with different keys + if (titleMap.ContainsValue(titleWordlistItem.JapaneseText)) + { + continue; + } + + titleMap.TryAdd(index, titleWordlistItem.JapaneseText); + } } public string GetMusicNameBySongId(uint songId) From c5ec3819fb01f560efdac9d0a1758897b9cd149c Mon Sep 17 00:00:00 2001 From: shiibe Date: Wed, 14 Sep 2022 18:22:20 -0400 Subject: [PATCH 08/20] Fix maximums --- TaikoWebUI/Services/GameDataService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index fcf9380..c30d6bf 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -14,12 +14,12 @@ public class GameDataService : IGameDataService private ImmutableDictionary danMap = null!; public const int COSTUME_HEAD_MAX = 140; - public const int COSTUME_FACE_MAX = 59; + public const int COSTUME_FACE_MAX = 58; public const int COSTUME_BODY_MAX = 156; public const int COSTUME_KIGURUMI_MAX = 154; public const int COSTUME_PUCHI_MAX = 129; public const int COSTUME_COLOR_MAX = 63; - public const int PLAYER_TITLE_MAX = 749; + public const int PLAYER_TITLE_MAX = 750; public static string[] headMap = new string[COSTUME_HEAD_MAX]; public static string[] faceMap = new string[COSTUME_FACE_MAX]; From df13336615d794bdbd325b1fe29e7c655b2934e3 Mon Sep 17 00:00:00 2001 From: TLH Date: Thu, 15 Sep 2022 13:08:19 +0900 Subject: [PATCH 09/20] Switch title field between dropdown and textbox --- TaikoWebUI/Pages/Profile.razor | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 7991626..04f3ac5 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -20,7 +20,15 @@ - + @if (EnterTextDirectly) + { + + } + else + { + + } + Enter Text Directly @@ -206,4 +214,8 @@ + + @code { + private bool EnterTextDirectly; + } } \ No newline at end of file From 17f89fde889564408ffda935856793c9ed87a800 Mon Sep 17 00:00:00 2001 From: shiibe Date: Thu, 15 Sep 2022 01:00:28 -0400 Subject: [PATCH 10/20] Clean up --- TaikoWebUI/Pages/Profile.razor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 04f3ac5..a77e060 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -22,13 +22,13 @@ @if (EnterTextDirectly) { - + } else { - + } - Enter Text Directly + Enter Text Directly From f8ef701b8655a4a2099eea9c0edceceab28576d0 Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Thu, 15 Sep 2022 13:18:50 +0800 Subject: [PATCH 11/20] Refactor costume related functions --- TaikoWebUI/GlobalUsings.cs | 1 + TaikoWebUI/Pages/Profile.razor | 380 ++++++++++++------------ TaikoWebUI/Pages/Profile.razor.cs | 25 +- TaikoWebUI/Services/GameDataService.cs | 197 +++++++----- TaikoWebUI/Services/IGameDataService.cs | 12 +- TaikoWebUI/Shared/Constants.cs | 12 + 6 files changed, 346 insertions(+), 281 deletions(-) create mode 100644 TaikoWebUI/Shared/Constants.cs diff --git a/TaikoWebUI/GlobalUsings.cs b/TaikoWebUI/GlobalUsings.cs index c9a23b1..f644645 100644 --- a/TaikoWebUI/GlobalUsings.cs +++ b/TaikoWebUI/GlobalUsings.cs @@ -6,6 +6,7 @@ global using Microsoft.AspNetCore.Components.Web; global using MudBlazor; global using TaikoWebUI; global using TaikoWebUI.Services; +global using TaikoWebUI.Shared; global using SharedProject.Models; global using SharedProject.Models.Requests; global using SharedProject.Models.Responses; diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index a77e060..8e93555 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -1,5 +1,6 @@ @page "/Cards/{baid:int}/Profile" @inject HttpClient Client +@inject IGameDataService GameDataService @@ -9,213 +10,212 @@ @if (response is not null) { - - - - - -

Profile Options

+ + + + + +

Profile Options

- + - - - @if (EnterTextDirectly) + + + @if (enterTextDirectly) + { + + } + else + { + + } + Enter Text Directly + + + + @for (uint i = 0; i < 8; i++) { - + var index = i; + @TitlePlateStrings[index] } - else - { - - } - Enter Text Directly - - - - @for (uint i = 0; i < 8; i++) + + + + + + @foreach (var item in Enum.GetValues()) + { + + } + + + + +
+
+ + + +

Costume Options

+ + + + + @for (var i = 0; i < Constants.COSTUME_HEAD_MAX; i++) { - var index = i; - @titlePlateStrings[index] + var index = (uint)i; + var costumeTitle = GameDataService.GetHeadTitle(index); + @index - @costumeTitle } - - - - @foreach (var item in Enum.GetValues()) - { - - } - + + @for (var i = 0; i < Constants.COSTUME_BODY_MAX; i++) + { + var index = (uint)i; + var costumeTitle = GameDataService.GetBodyTitle(index); + @index - @costumeTitle + } + - - -
-
+ + @for (var i = 0; i < Constants.COSTUME_FACE_MAX; i++) + { + var index = (uint)i; + var costumeTitle = GameDataService.GetFaceTitle(index); + @index - @costumeTitle + } + - - -

Costume Options

- - - - - @for (uint i = 0; i < GameDataService.COSTUME_HEAD_MAX; i++) - { - var index = i; - var costumeTitle = GameDataService.headMap[index]; - @index - @costumeTitle - } - + + @for (var i = 0; i < Constants.COSTUME_KIGURUMI_MAX; i++) + { + var index = (uint)i; + var costumeTitle = GameDataService.GetKigurumiTitle(index); + @index - @costumeTitle + } + - - @for (uint i = 0; i < GameDataService.COSTUME_BODY_MAX; i++) - { - var index = i; - var costumeTitle = GameDataService.bodyMap[index]; - @index - @costumeTitle - } - + + @for (var i = 0; i < Constants.COSTUME_PUCHI_MAX; i++) + { + var index = (uint)i; + var costumeTitle = GameDataService.GetPuchiTitle(index); + @index - @costumeTitle + } + + - - @for (uint i = 0; i < GameDataService.COSTUME_FACE_MAX; i++) - { - var index = i; - var costumeTitle = GameDataService.faceMap[index]; - @index - @costumeTitle - } - + + + @for (uint i = 0; i < Constants.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+ + @for (uint i = 0; i < Constants.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+ + @for (uint i = 0; i < Constants.COSTUME_COLOR_MAX; i++) + { + var index = i; + +
+ @index +
+ } +
+
+
+
+
+
- - @for (uint i = 0; i < GameDataService.COSTUME_KIGURUMI_MAX; i++) - { - var index = i; - var costumeTitle = GameDataService.kigurumiMap[index]; - @index - @costumeTitle - } - + + +

Song Options

+ + + + + + + + + + + + + @for (uint i = 0; i < 15; i++) + { + var index = i; + @SpeedStrings[index] + } + - - @for (uint i = 0; i < GameDataService.COSTUME_PUCHI_MAX; i++) - { - var index = i; - var costumeTitle = GameDataService.puchiMap[index]; - @index - @costumeTitle - } - - + + @foreach (var item in Enum.GetValues()) + { + + } + - - - @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) - { - var index = i; - -
- @index -
- } -
- - @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) - { - var index = i; - -
- @index -
- } -
- - @for (uint i = 0; i < GameDataService.COSTUME_COLOR_MAX; i++) - { - var index = i; - -
- @index -
- } -
-
-
-
-
-
+ + @for (uint i = 0; i < 19; i++) + { + var index = i; + @ToneStrings[index] + } + - - -

Song Options

- - - - - - - - - - - - - @for (uint i = 0; i < 15; i++) - { - var index = i; - @speedStrings[index] - } - + + Notes Position + + + + +
+
+
+
+
- - @foreach (var item in Enum.GetValues()) - { - - } - + + + + @if (isSavingOptions) + { + + Saving... + } + else + { + + Save + } + + - - @for (uint i = 0; i < 19; i++) - { - var index = i; - @toneStrings[index] - } - - - - Notes Position - -
-
-
-
- - - -
- - - - - @if (isSavingOptions) - { - - Saving... - } - else - { - - Save - } - - - - + - - @code { - private bool EnterTextDirectly; - } } \ No newline at end of file diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index 9c37a68..f3e1fda 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -11,8 +11,10 @@ public partial class Profile private UserSetting? response; private bool isSavingOptions; + + private bool enterTextDirectly; - public string[] costumeColors = + private static readonly string[] CostumeColors = { "#F84828", "#68C0C0", "#DC1500", "#F8F0E0", "#009687", "#00BF87", "#00FF9A", "#66FFC2", "#FFFFFF", "#690000", "#FF0000", "#FF6666", @@ -27,16 +29,16 @@ public partial class Profile "#FF66BF", "#FFB3DF", "#000000" }; - private readonly string[] speedStrings = + private static readonly string[] SpeedStrings = { "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2.0", "2.5", "3.0", "3.5", "4.0" }; - private readonly string[] notePositionStrings = { "-5", "-4", "-3", "-2", "-1", "0", "+1", "+2", "+3", "+4", "+5" }; + private static readonly string[] NotePositionStrings = { "-5", "-4", "-3", "-2", "-1", "0", "+1", "+2", "+3", "+4", "+5" }; - private readonly string[] toneStrings = + private static readonly string[] ToneStrings = { "Taiko", "Festival", "Dogs & Cats", "Deluxe", "Drumset", "Tambourine", "Don Wada", "Clapping", @@ -45,13 +47,13 @@ public partial class Profile "Synth Drum", "Shuriken", "Bubble Pop", "Electric Guitar" }; - private readonly string[] titlePlateStrings = + private static readonly string[] TitlePlateStrings = { "Wood", "Rainbow", "Gold", "Purple", "AI 1", "AI 2", "AI 3", "AI 4" }; - private List breadcrumbs = new() + private readonly List breadcrumbs = new() { new BreadcrumbItem("Cards", href: "/Cards"), }; @@ -73,15 +75,12 @@ public partial class Profile isSavingOptions = false; } +#pragma warning disable CS1998 private async Task> SearchForTitle(string value) +#pragma warning restore CS1998 { - var titles = GameDataService.titleMap; + var titles = GameDataService.GetTitles(); - if (string.IsNullOrWhiteSpace(value)) - { - return titles.Values; - } - - return titles.Values.Where(x => x.Contains(value, StringComparison.OrdinalIgnoreCase)); + return string.IsNullOrWhiteSpace(value) ? titles : titles.Where(x => x.Contains(value, StringComparison.OrdinalIgnoreCase)); } } \ No newline at end of file diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index c30d6bf..c1a3527 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -11,23 +11,15 @@ public class GameDataService : IGameDataService private readonly Dictionary musicMap = new(); - private ImmutableDictionary danMap = null!; + private ImmutableDictionary danMap = ImmutableDictionary.Empty; + + private ImmutableHashSet titles = ImmutableHashSet.Empty; - public const int COSTUME_HEAD_MAX = 140; - public const int COSTUME_FACE_MAX = 58; - public const int COSTUME_BODY_MAX = 156; - public const int COSTUME_KIGURUMI_MAX = 154; - public const int COSTUME_PUCHI_MAX = 129; - public const int COSTUME_COLOR_MAX = 63; - public const int PLAYER_TITLE_MAX = 750; - - public static string[] headMap = new string[COSTUME_HEAD_MAX]; - public static string[] faceMap = new string[COSTUME_FACE_MAX]; - public static string[] bodyMap = new string[COSTUME_BODY_MAX]; - public static string[] kigurumiMap = new string[COSTUME_KIGURUMI_MAX]; - public static string[] puchiMap = new string[COSTUME_PUCHI_MAX]; - - public static Dictionary titleMap = new(); + private readonly string[] headTitles = new string[Constants.COSTUME_HEAD_MAX]; + private readonly string[] faceTitles = new string[Constants.COSTUME_FACE_MAX]; + private readonly string[] bodyTitles = new string[Constants.COSTUME_BODY_MAX]; + private readonly string[] kigurumiMTitles = new string[Constants.COSTUME_KIGURUMI_MAX]; + private readonly string[] puchiTitles = new string[Constants.COSTUME_PUCHI_MAX]; public GameDataService(HttpClient client) { @@ -51,6 +43,88 @@ public class GameDataService : IGameDataService // To prevent duplicate entries in wordlist var dict = wordList.WordListEntries.GroupBy(entry => entry.Key) .ToImmutableDictionary(group => group.Key, group => group.First()); + await Task.Run(()=>InitializeMusicMap(musicInfo, dict, musicOrder)); + + await Task.Run(() => InitializeHeadTitles(dict)); + await Task.Run(() => InitializeFaceTitles(dict)); + await Task.Run(() => InitializeBodyTitles(dict)); + await Task.Run(() => InitializePuchiTitles(dict)); + await Task.Run(() => InitializeKigurumiTitles(dict)); + await Task.Run(() => InitializeTitles(dict)); + } + + private void InitializeTitles(ImmutableDictionary dict) + { + var set = ImmutableHashSet.CreateBuilder(); + for (var i = 1; i < Constants.PLAYER_TITLE_MAX; i++) + { + var key = $"syougou_{i}"; + + var titleWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + + set.Add(titleWordlistItem.JapaneseText); + } + + titles = set.ToImmutable(); + } + + private void InitializePuchiTitles(ImmutableDictionary dict) + { + for (var i = 0; i < Constants.COSTUME_PUCHI_MAX; i++) + { + var key = $"costume_puchi_{i}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + puchiTitles[i] = costumeWordlistItem.JapaneseText; + } + } + + private void InitializeKigurumiTitles(ImmutableDictionary dict) + { + for (var i = 0; i < Constants.COSTUME_KIGURUMI_MAX; i++) + { + var key = $"costume_kigurumi_{i}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + kigurumiMTitles[i] = costumeWordlistItem.JapaneseText; + } + } + + private void InitializeBodyTitles(ImmutableDictionary dict) + { + for (var i = 0; i < Constants.COSTUME_BODY_MAX; i++) + { + var key = $"costume_body_{i}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + bodyTitles[i] = costumeWordlistItem.JapaneseText; + } + } + + private void InitializeFaceTitles(ImmutableDictionary dict) + { + for (var i = 0; i < Constants.COSTUME_FACE_MAX; i++) + { + var key = $"costume_face_{i}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + faceTitles[i] = costumeWordlistItem.JapaneseText; + } + } + + private void InitializeHeadTitles(ImmutableDictionary dict) + { + for (var i = 0; i < Constants.COSTUME_HEAD_MAX; i++) + { + var key = $"costume_head_{i}"; + + var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); + headTitles[i] = costumeWordlistItem.JapaneseText; + } + } + + private void InitializeMusicMap(MusicInfo musicInfo, ImmutableDictionary dict, MusicOrder musicOrder) + { foreach (var music in musicInfo.Items) { var songNameKey = $"song_{music.Id}"; @@ -76,67 +150,6 @@ public class GameDataService : IGameDataService musicMap[songId].Index = index; } } - - for (var i = 0; i < COSTUME_HEAD_MAX; i++) - { - var index = i; - var key = $"costume_head_{index}"; - - var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - headMap[index] = costumeWordlistItem.JapaneseText; - } - - for (var i = 0; i < COSTUME_FACE_MAX; i++) - { - var index = i; - var key = $"costume_face_{index}"; - - var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - faceMap[index] = costumeWordlistItem.JapaneseText; - } - - for (var i = 0; i < COSTUME_BODY_MAX; i++) - { - var index = i; - var key = $"costume_body_{index}"; - - var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - bodyMap[index] = costumeWordlistItem.JapaneseText; - } - - for (var i = 0; i < COSTUME_KIGURUMI_MAX; i++) - { - var index = i; - var key = $"costume_kigurumi_{index}"; - - var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - kigurumiMap[index] = costumeWordlistItem.JapaneseText; - } - - for (var i = 0; i < COSTUME_PUCHI_MAX; i++) - { - var index = i; - var key = $"costume_puchi_{index}"; - - var costumeWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - puchiMap[index] = costumeWordlistItem.JapaneseText; - } - - for (var i = 1; i < PLAYER_TITLE_MAX; i++) - { - var index = i; - var key = $"syougou_{index}"; - - var titleWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - - // prevent duplicate values with different keys - if (titleMap.ContainsValue(titleWordlistItem.JapaneseText)) - { - continue; - } - - titleMap.TryAdd(index, titleWordlistItem.JapaneseText); - } } public string GetMusicNameBySongId(uint songId) @@ -176,4 +189,34 @@ public class GameDataService : IGameDataService _ => throw new ArgumentOutOfRangeException(nameof(difficulty), difficulty, null) }; } + + public string GetHeadTitle(uint index) + { + return index < headTitles.Length ? headTitles[index] : string.Empty; + } + + public string GetKigurumiTitle(uint index) + { + return index < kigurumiMTitles.Length ? kigurumiMTitles[index] : string.Empty; + } + + public string GetBodyTitle(uint index) + { + return index < bodyTitles.Length ? bodyTitles[index] : string.Empty; + } + + public string GetFaceTitle(uint index) + { + return index < faceTitles.Length ? faceTitles[index] : string.Empty; + } + + public string GetPuchiTitle(uint index) + { + return index < puchiTitles.Length ? puchiTitles[index] : string.Empty; + } + + public IEnumerable GetTitles() + { + return titles.ToArray(); + } } \ No newline at end of file diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs index fbad860..95eb397 100644 --- a/TaikoWebUI/Services/IGameDataService.cs +++ b/TaikoWebUI/Services/IGameDataService.cs @@ -1,4 +1,6 @@ -namespace TaikoWebUI.Services; +using System.Collections.Immutable; + +namespace TaikoWebUI.Services; public interface IGameDataService { @@ -15,4 +17,12 @@ public interface IGameDataService public DanData GetDanDataById(uint danId); public int GetMusicStarLevel(uint songId, Difficulty difficulty); + + public string GetHeadTitle(uint index); + public string GetKigurumiTitle(uint index); + public string GetBodyTitle(uint index); + public string GetFaceTitle(uint index); + public string GetPuchiTitle(uint index); + + public IEnumerable GetTitles(); } \ No newline at end of file diff --git a/TaikoWebUI/Shared/Constants.cs b/TaikoWebUI/Shared/Constants.cs new file mode 100644 index 0000000..47eb065 --- /dev/null +++ b/TaikoWebUI/Shared/Constants.cs @@ -0,0 +1,12 @@ +namespace TaikoWebUI.Shared; + +public static class Constants +{ + public const int COSTUME_HEAD_MAX = 140; + public const int COSTUME_FACE_MAX = 58; + public const int COSTUME_BODY_MAX = 156; + public const int COSTUME_KIGURUMI_MAX = 154; + public const int COSTUME_PUCHI_MAX = 129; + public const int COSTUME_COLOR_MAX = 63; + public const int PLAYER_TITLE_MAX = 750; +} \ No newline at end of file From e6eb83af2ce25d9928489921255bca3ac22bf07d Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Thu, 15 Sep 2022 15:27:27 +0800 Subject: [PATCH 12/20] Clean up --- TaikoWebUI/Pages/Profile.razor | 14 +- TaikoWebUI/Pages/Profile.razor.cs | 10 +- TaikoWebUI/Services/GameDataService.cs | 162 ++++++++++++------------ TaikoWebUI/Services/IGameDataService.cs | 4 +- TaikoWebUI/TaikoWebUI.csproj | 1 + 5 files changed, 89 insertions(+), 102 deletions(-) diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 8e93555..8ec99a5 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -21,18 +21,8 @@ - @if (enterTextDirectly) - { - - } - else - { - - } - Enter Text Directly + + diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index f3e1fda..05998a9 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -1,7 +1,4 @@ -using MudBlazor.Utilities; -using static MudBlazor.Colors; - -namespace TaikoWebUI.Pages; +namespace TaikoWebUI.Pages; public partial class Profile { @@ -74,11 +71,10 @@ public partial class Profile await Client.PostAsJsonAsync($"api/UserSettings/{Baid}", response); isSavingOptions = false; } - -#pragma warning disable CS1998 + private async Task> SearchForTitle(string value) -#pragma warning restore CS1998 { + await Task.Delay(1); var titles = GameDataService.GetTitles(); return string.IsNullOrWhiteSpace(value) ? titles : titles.Where(x => x.Contains(value, StringComparison.OrdinalIgnoreCase)); diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index c1a3527..eb9278b 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using MudBlazor.Utilities; using Swan.Mapping; using TaikoWebUI.Shared.Models; @@ -7,20 +6,20 @@ namespace TaikoWebUI.Services; public class GameDataService : IGameDataService { + private readonly string[] bodyTitles = new string[Constants.COSTUME_BODY_MAX]; private readonly HttpClient client; - - private readonly Dictionary musicMap = new(); - - private ImmutableDictionary danMap = ImmutableDictionary.Empty; - - private ImmutableHashSet titles = ImmutableHashSet.Empty; + private readonly string[] faceTitles = new string[Constants.COSTUME_FACE_MAX]; private readonly string[] headTitles = new string[Constants.COSTUME_HEAD_MAX]; - private readonly string[] faceTitles = new string[Constants.COSTUME_FACE_MAX]; - private readonly string[] bodyTitles = new string[Constants.COSTUME_BODY_MAX]; private readonly string[] kigurumiMTitles = new string[Constants.COSTUME_KIGURUMI_MAX]; + + private readonly Dictionary musicMap = new(); private readonly string[] puchiTitles = new string[Constants.COSTUME_PUCHI_MAX]; + private ImmutableDictionary danMap = ImmutableDictionary.Empty; + + private ImmutableHashSet titles = ImmutableHashSet.Empty; + public GameDataService(HttpClient client) { this.client = client; @@ -39,11 +38,11 @@ public class GameDataService : IGameDataService danData.ThrowIfNull(); danMap = danData.ToImmutableDictionary(data => data.DanId); - + // To prevent duplicate entries in wordlist var dict = wordList.WordListEntries.GroupBy(entry => entry.Key) .ToImmutableDictionary(group => group.Key, group => group.First()); - await Task.Run(()=>InitializeMusicMap(musicInfo, dict, musicOrder)); + await Task.Run(() => InitializeMusicMap(musicInfo, dict, musicOrder)); await Task.Run(() => InitializeHeadTitles(dict)); await Task.Run(() => InitializeFaceTitles(dict)); @@ -53,6 +52,76 @@ public class GameDataService : IGameDataService await Task.Run(() => InitializeTitles(dict)); } + public string GetMusicNameBySongId(uint songId) + { + return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.SongName : string.Empty; + } + + public string GetMusicArtistBySongId(uint songId) + { + 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; + } + + public DanData GetDanDataById(uint danId) + { + return danMap.GetValueOrDefault(danId, new DanData()); + } + + public int GetMusicStarLevel(uint songId, Difficulty difficulty) + { + var success = musicMap.TryGetValue(songId, out var musicDetail); + return difficulty switch + { + Difficulty.None => throw new ArgumentException("Difficulty cannot be none"), + Difficulty.Easy => success ? musicDetail!.StarEasy : 0, + Difficulty.Normal => success ? musicDetail!.StarNormal : 0, + Difficulty.Hard => success ? musicDetail!.StarHard : 0, + Difficulty.Oni => success ? musicDetail!.StarOni : 0, + Difficulty.UraOni => success ? musicDetail!.StarUra : 0, + _ => throw new ArgumentOutOfRangeException(nameof(difficulty), difficulty, null) + }; + } + + public string GetHeadTitle(uint index) + { + return index < headTitles.Length ? headTitles[index] : string.Empty; + } + + public string GetKigurumiTitle(uint index) + { + return index < kigurumiMTitles.Length ? kigurumiMTitles[index] : string.Empty; + } + + public string GetBodyTitle(uint index) + { + return index < bodyTitles.Length ? bodyTitles[index] : string.Empty; + } + + public string GetFaceTitle(uint index) + { + return index < faceTitles.Length ? faceTitles[index] : string.Empty; + } + + public string GetPuchiTitle(uint index) + { + return index < puchiTitles.Length ? puchiTitles[index] : string.Empty; + } + + public IEnumerable GetTitles() + { + return titles.ToArray(); + } + private void InitializeTitles(ImmutableDictionary dict) { var set = ImmutableHashSet.CreateBuilder(); @@ -123,7 +192,8 @@ public class GameDataService : IGameDataService } } - private void InitializeMusicMap(MusicInfo musicInfo, ImmutableDictionary dict, MusicOrder musicOrder) + private void InitializeMusicMap(MusicInfo musicInfo, ImmutableDictionary dict, + MusicOrder musicOrder) { foreach (var music in musicInfo.Items) { @@ -151,72 +221,4 @@ public class GameDataService : IGameDataService } } } - - public string GetMusicNameBySongId(uint songId) - { - return musicMap.TryGetValue(songId, out var musicDetail) ? musicDetail.SongName : string.Empty; - } - - public string GetMusicArtistBySongId(uint songId) - { - 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; - } - public DanData GetDanDataById(uint danId) - { - return danMap.GetValueOrDefault(danId, new DanData()); - } - - public int GetMusicStarLevel(uint songId, Difficulty difficulty) - { - var success = musicMap.TryGetValue(songId, out var musicDetail); - return difficulty switch - { - Difficulty.None => throw new ArgumentException("Difficulty cannot be none"), - Difficulty.Easy => success ? musicDetail!.StarEasy : 0, - Difficulty.Normal => success ? musicDetail!.StarNormal : 0, - Difficulty.Hard => success ? musicDetail!.StarHard : 0, - Difficulty.Oni => success ? musicDetail!.StarOni : 0, - Difficulty.UraOni => success ? musicDetail!.StarUra : 0, - _ => throw new ArgumentOutOfRangeException(nameof(difficulty), difficulty, null) - }; - } - - public string GetHeadTitle(uint index) - { - return index < headTitles.Length ? headTitles[index] : string.Empty; - } - - public string GetKigurumiTitle(uint index) - { - return index < kigurumiMTitles.Length ? kigurumiMTitles[index] : string.Empty; - } - - public string GetBodyTitle(uint index) - { - return index < bodyTitles.Length ? bodyTitles[index] : string.Empty; - } - - public string GetFaceTitle(uint index) - { - return index < faceTitles.Length ? faceTitles[index] : string.Empty; - } - - public string GetPuchiTitle(uint index) - { - return index < puchiTitles.Length ? puchiTitles[index] : string.Empty; - } - - public IEnumerable GetTitles() - { - return titles.ToArray(); - } } \ No newline at end of file diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs index 95eb397..b21d2bc 100644 --- a/TaikoWebUI/Services/IGameDataService.cs +++ b/TaikoWebUI/Services/IGameDataService.cs @@ -1,6 +1,4 @@ -using System.Collections.Immutable; - -namespace TaikoWebUI.Services; +namespace TaikoWebUI.Services; public interface IGameDataService { diff --git a/TaikoWebUI/TaikoWebUI.csproj b/TaikoWebUI/TaikoWebUI.csproj index 02bf122..d6221e1 100644 --- a/TaikoWebUI/TaikoWebUI.csproj +++ b/TaikoWebUI/TaikoWebUI.csproj @@ -7,6 +7,7 @@ + From a5f3cef90ec34117f8ad239857570d4412df9412 Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Thu, 15 Sep 2022 17:47:46 +0800 Subject: [PATCH 13/20] Change to table for built in titles --- .../Pages/Dialogs/ChooseTitleDialog.razor | 104 ++++++++++++++++++ TaikoWebUI/Pages/Profile.razor | 5 +- TaikoWebUI/Pages/Profile.razor.cs | 31 ++++-- TaikoWebUI/Services/GameDataService.cs | 13 ++- TaikoWebUI/Services/IGameDataService.cs | 7 +- TaikoWebUI/Shared/Models/Title.cs | 23 ++++ 6 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor create mode 100644 TaikoWebUI/Shared/Models/Title.cs diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor new file mode 100644 index 0000000..4459b91 --- /dev/null +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -0,0 +1,104 @@ +@using TaikoWebUI.Shared.Models +@using System.Collections.Immutable +@inject IGameDataService GameDataService + + + + @* + + Built in titles + + + + + + + + + + + + + *@ + + + Built in titles + + + + + + + + Id + + + + + Name + + + + + @context.TitleId + @context.TitleName + + + + + + Selected Title: @selectedTitle?.TitleName + + + Cancel + Ok + + + +@code { + + [CascadingParameter] + MudDialogInstance MudDialog { get; set; } = null!; + + [Parameter] + public UserSetting UserSetting { get; set; } = new(); + + private IEnumerable titles = new List<Title>(); + + private Title? selectedTitle; + + private string searchString = string.Empty; + + protected override void OnInitialized() + { + base.OnInitialized(); + var titleSet = GameDataService.GetTitles(); + titles = titleSet.ToImmutableList().Sort((title, title1) => title.TitleId.CompareTo(title1.TitleId)); + titleSet.TryGetValue(new Title + { + TitleName = UserSetting.Title + }, out selectedTitle); + } + + private bool Filter(Title title) + { + return string.IsNullOrEmpty(searchString) || + title.TitleName.Contains(searchString, StringComparison.InvariantCultureIgnoreCase); + } + + private void Submit() + { + if (selectedTitle is not null) + { + UserSetting.Title = selectedTitle.TitleName; + } + MudDialog.Close(DialogResult.Ok(true)); + } + + private void Cancel() => MudDialog.Cancel(); + +} \ No newline at end of file diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 8ec99a5..28b628b 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -1,6 +1,7 @@ @page "/Cards/{baid:int}/Profile" @inject HttpClient Client @inject IGameDataService GameDataService +@inject IDialogService DialogService <MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs> @@ -22,7 +23,9 @@ <MudGrid> <MudItem xs="12" md="8"> <MudTextField @bind-Value="@response.Title" Label="Title"/> - <MudButton></MudButton> + <MudButton Color="Color.Primary" OnClick="@((e)=>OpenChooseTitleDialog())"> + Choose a built in title + </MudButton> </MudItem> <MudItem xs="12" md="4"> <MudSelect @bind-Value="@response.TitlePlateId" Label="Title Plate"> diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index 05998a9..23d395e 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -1,4 +1,6 @@ -namespace TaikoWebUI.Pages; +using TaikoWebUI.Pages.Dialogs; + +namespace TaikoWebUI.Pages; public partial class Profile { @@ -8,8 +10,6 @@ public partial class Profile private UserSetting? response; private bool isSavingOptions; - - private bool enterTextDirectly; private static readonly string[] CostumeColors = { @@ -71,12 +71,25 @@ public partial class Profile await Client.PostAsJsonAsync($"api/UserSettings/{Baid}", response); isSavingOptions = false; } - - private async Task<IEnumerable<string>> SearchForTitle(string value) - { - await Task.Delay(1); - var titles = GameDataService.GetTitles(); - return string.IsNullOrWhiteSpace(value) ? titles : titles.Where(x => x.Contains(value, StringComparison.OrdinalIgnoreCase)); + private async Task OpenChooseTitleDialog() + { + var options = new DialogOptions + { + // CloseButton = false, + CloseOnEscapeKey = false, + DisableBackdropClick = true, + FullScreen = true + }; + var parameters = new DialogParameters + { + ["UserSetting"] = response + }; + var dialog = DialogService.Show<ChooseTitleDialog>("Choose a built in dialog", parameters, options); + var result = await dialog.Result; + if (!result.Cancelled) + { + StateHasChanged(); + } } } \ No newline at end of file diff --git a/TaikoWebUI/Services/GameDataService.cs b/TaikoWebUI/Services/GameDataService.cs index eb9278b..768832c 100644 --- a/TaikoWebUI/Services/GameDataService.cs +++ b/TaikoWebUI/Services/GameDataService.cs @@ -18,7 +18,7 @@ public class GameDataService : IGameDataService private ImmutableDictionary<uint, DanData> danMap = ImmutableDictionary<uint, DanData>.Empty; - private ImmutableHashSet<string> titles = ImmutableHashSet<string>.Empty; + private ImmutableHashSet<Title> titles = ImmutableHashSet<Title>.Empty; public GameDataService(HttpClient client) { @@ -117,21 +117,24 @@ public class GameDataService : IGameDataService return index < puchiTitles.Length ? puchiTitles[index] : string.Empty; } - public IEnumerable<string> GetTitles() + public ImmutableHashSet<Title> GetTitles() { - return titles.ToArray(); + return titles; } private void InitializeTitles(ImmutableDictionary<string, WordListEntry> dict) { - var set = ImmutableHashSet.CreateBuilder<string>(); + var set = ImmutableHashSet.CreateBuilder<Title>(); for (var i = 1; i < Constants.PLAYER_TITLE_MAX; i++) { var key = $"syougou_{i}"; var titleWordlistItem = dict.GetValueOrDefault(key, new WordListEntry()); - set.Add(titleWordlistItem.JapaneseText); + set.Add(new Title{ + TitleName = titleWordlistItem.JapaneseText, + TitleId = i + }); } titles = set.ToImmutable(); diff --git a/TaikoWebUI/Services/IGameDataService.cs b/TaikoWebUI/Services/IGameDataService.cs index b21d2bc..b5a7310 100644 --- a/TaikoWebUI/Services/IGameDataService.cs +++ b/TaikoWebUI/Services/IGameDataService.cs @@ -1,4 +1,7 @@ -namespace TaikoWebUI.Services; +using System.Collections.Immutable; +using TaikoWebUI.Shared.Models; + +namespace TaikoWebUI.Services; public interface IGameDataService { @@ -22,5 +25,5 @@ public interface IGameDataService public string GetFaceTitle(uint index); public string GetPuchiTitle(uint index); - public IEnumerable<string> GetTitles(); + public ImmutableHashSet<Title> GetTitles(); } \ No newline at end of file diff --git a/TaikoWebUI/Shared/Models/Title.cs b/TaikoWebUI/Shared/Models/Title.cs new file mode 100644 index 0000000..d6f68be --- /dev/null +++ b/TaikoWebUI/Shared/Models/Title.cs @@ -0,0 +1,23 @@ +namespace TaikoWebUI.Shared.Models; + +public class Title +{ + public int TitleId { get; set; } + + public string TitleName { get; init; } = string.Empty; + + public override bool Equals(object? obj) + { + if (obj is Title title) + { + return title.TitleName.Equals(TitleName); + } + + return false; + } + + public override int GetHashCode() + { + return TitleName.GetHashCode(); + } +} \ No newline at end of file From f290deca3f8241577795b7945fc4394285d00620 Mon Sep 17 00:00:00 2001 From: TLH <hmgrtlh@gmail.com> Date: Thu, 15 Sep 2022 20:05:36 +0900 Subject: [PATCH 14/20] Tweaking the table --- TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor | 13 ++++++++++--- TaikoWebUI/Pages/Profile.razor.cs | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index 4459b91..fc269c3 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -24,6 +24,13 @@ </PagerContent> </MudDataGrid>*@ <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle"> + <ColGroup> + <col style="width: 150px;" /> + <col /> + <col /> + <col /> + <col style="width: 150px;" /> + </ColGroup> <ToolBarContent> <MudText Typo="Typo.h6">Built in titles</MudText> <MudSpacer/> @@ -44,14 +51,14 @@ </MudTh> </HeaderContent> <RowTemplate> - <MudTd DataLabel="Id">@context.TitleId</MudTd> - <MudTd DataLabel="Name">@context.TitleName</MudTd> + <MudTd DataLabel="Id" Class="cursor-pointer">@context.TitleId</MudTd> + <MudTd DataLabel="Name" Class="cursor-pointer">@context.TitleName</MudTd> </RowTemplate> <PagerContent> <MudTablePager PageSizeOptions="new []{10}"/> </PagerContent> </MudTable> - <MudText>Selected Title: @selectedTitle?.TitleName</MudText> + <MudText Class="pt-4">Selected Title: @selectedTitle?.TitleName</MudText> </DialogContent> <DialogActions> <MudButton OnClick="Cancel">Cancel</MudButton> diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index 23d395e..51ae8e2 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -76,10 +76,11 @@ public partial class Profile { var options = new DialogOptions { - // CloseButton = false, + //CloseButton = false, CloseOnEscapeKey = false, DisableBackdropClick = true, - FullScreen = true + MaxWidth = MaxWidth.Medium, + FullWidth = true }; var parameters = new DialogParameters { From e93bf5bb4406eb54054c306117fba15691f04a97 Mon Sep 17 00:00:00 2001 From: shiibe <beckchop9@gmail.com> Date: Thu, 15 Sep 2022 09:49:38 -0400 Subject: [PATCH 15/20] Fix button spacing --- TaikoWebUI/Pages/Profile.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index 28b628b..ddccfac 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -23,7 +23,7 @@ <MudGrid> <MudItem xs="12" md="8"> <MudTextField @bind-Value="@response.Title" Label="Title"/> - <MudButton Color="Color.Primary" OnClick="@((e)=>OpenChooseTitleDialog())"> + <MudButton Color="Color.Primary" Class="mt-1" Size="Size.Small" OnClick="@((e)=>OpenChooseTitleDialog())"> Choose a built in title </MudButton> </MudItem> From 30e681ba020aac57260f96deb135d1849cabcf2c Mon Sep 17 00:00:00 2001 From: shiibe <beckchop9@gmail.com> Date: Thu, 15 Sep 2022 11:43:27 -0400 Subject: [PATCH 16/20] Add vh sizing to title table This should allow the entire dialog to be visible when browser is at least ~540px in height. --- TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor | 4 +--- TaikoWebUI/Pages/Profile.razor.cs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index fc269c3..abcff1a 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -23,7 +23,7 @@ <MudDataGridPager T="Title"/> </PagerContent> </MudDataGrid>*@ - <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle"> + <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle" Height="40vh"> <ColGroup> <col style="width: 150px;" /> <col /> @@ -32,8 +32,6 @@ <col style="width: 150px;" /> </ColGroup> <ToolBarContent> - <MudText Typo="Typo.h6">Built in titles</MudText> - <MudSpacer/> <MudTextField @bind-Value="searchString" Placeholder="Search" Adornment="Adornment.Start" Immediate="true" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"> </MudTextField> diff --git a/TaikoWebUI/Pages/Profile.razor.cs b/TaikoWebUI/Pages/Profile.razor.cs index 51ae8e2..31c2d78 100644 --- a/TaikoWebUI/Pages/Profile.razor.cs +++ b/TaikoWebUI/Pages/Profile.razor.cs @@ -86,7 +86,7 @@ public partial class Profile { ["UserSetting"] = response }; - var dialog = DialogService.Show<ChooseTitleDialog>("Choose a built in dialog", parameters, options); + var dialog = DialogService.Show<ChooseTitleDialog>("Player Titles", parameters, options); var result = await dialog.Result; if (!result.Cancelled) { From 6d46eeb6241511665ea694115ddb560629113a50 Mon Sep 17 00:00:00 2001 From: shiibe <beckchop9@gmail.com> Date: Thu, 15 Sep 2022 11:57:39 -0400 Subject: [PATCH 17/20] Small style fixes --- TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index abcff1a..ae076ac 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -23,13 +23,10 @@ <MudDataGridPager T="Title"/> </PagerContent> </MudDataGrid>*@ - <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle" Height="40vh"> + <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle" Height="40vh" Hover="true"> <ColGroup> - <col style="width: 150px;" /> + <col style="width: 50px;" /> <col /> - <col /> - <col /> - <col style="width: 150px;" /> </ColGroup> <ToolBarContent> <MudTextField @bind-Value="searchString" Placeholder="Search" Adornment="Adornment.Start" Immediate="true" @@ -39,7 +36,7 @@ <HeaderContent> <MudTh> <MudTableSortLabel SortBy="@(new Func<Title, object>(x => x.TitleId))"> - Id + ID </MudTableSortLabel> </MudTh> <MudTh> @@ -56,7 +53,7 @@ <MudTablePager PageSizeOptions="new []{10}"/> </PagerContent> </MudTable> - <MudText Class="pt-4">Selected Title: @selectedTitle?.TitleName</MudText> + <MudText Class="mt-4 d-block" Typo="Typo.caption"><b>Selected Title:</b> @selectedTitle?.TitleName</MudText> </DialogContent> <DialogActions> <MudButton OnClick="Cancel">Cancel</MudButton> From 2914d376b3613ff929ace4c937936cd5d3f1fc24 Mon Sep 17 00:00:00 2001 From: shiibe <beckchop9@gmail.com> Date: Thu, 15 Sep 2022 11:59:40 -0400 Subject: [PATCH 18/20] Re-enable rows per page options --- TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index ae076ac..62a9f35 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -50,7 +50,7 @@ <MudTd DataLabel="Name" Class="cursor-pointer">@context.TitleName</MudTd> </RowTemplate> <PagerContent> - <MudTablePager PageSizeOptions="new []{10}"/> + <MudTablePager /> </PagerContent> </MudTable> <MudText Class="mt-4 d-block" Typo="Typo.caption"><b>Selected Title:</b> @selectedTitle?.TitleName</MudText> From 44ba2e72293c23541c8dd1b45bb81cab5384659e Mon Sep 17 00:00:00 2001 From: shiibe <beckchop9@gmail.com> Date: Thu, 15 Sep 2022 11:59:40 -0400 Subject: [PATCH 19/20] Re-enable rows per page options --- TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor | 6 +++--- TaikoWebUI/Pages/Profile.razor | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index ae076ac..dffb797 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -41,16 +41,16 @@ </MudTh> <MudTh> <MudTableSortLabel SortBy="@(new Func<Title, object>(x => x.TitleName))"> - Name + Title </MudTableSortLabel> </MudTh> </HeaderContent> <RowTemplate> <MudTd DataLabel="Id" Class="cursor-pointer">@context.TitleId</MudTd> - <MudTd DataLabel="Name" Class="cursor-pointer">@context.TitleName</MudTd> + <MudTd DataLabel="Title" Class="cursor-pointer">@context.TitleName</MudTd> </RowTemplate> <PagerContent> - <MudTablePager PageSizeOptions="new []{10}"/> + <MudTablePager /> </PagerContent> </MudTable> <MudText Class="mt-4 d-block" Typo="Typo.caption"><b>Selected Title:</b> @selectedTitle?.TitleName</MudText> diff --git a/TaikoWebUI/Pages/Profile.razor b/TaikoWebUI/Pages/Profile.razor index ddccfac..1373290 100644 --- a/TaikoWebUI/Pages/Profile.razor +++ b/TaikoWebUI/Pages/Profile.razor @@ -24,7 +24,7 @@ <MudItem xs="12" md="8"> <MudTextField @bind-Value="@response.Title" Label="Title"/> <MudButton Color="Color.Primary" Class="mt-1" Size="Size.Small" OnClick="@((e)=>OpenChooseTitleDialog())"> - Choose a built in title + Select a Title </MudButton> </MudItem> <MudItem xs="12" md="4"> From eea0b6f32fd3111b75f54ded01f616551d5f5a00 Mon Sep 17 00:00:00 2001 From: asesidaa <1061472754@qq.com> Date: Fri, 16 Sep 2022 00:06:26 +0800 Subject: [PATCH 20/20] Clean up, don't show selected when using custom title --- .../Pages/Dialogs/ChooseTitleDialog.razor | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor index 62a9f35..6e54b02 100644 --- a/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor +++ b/TaikoWebUI/Pages/Dialogs/ChooseTitleDialog.razor @@ -4,25 +4,6 @@ <MudDialog> <DialogContent> - @*<MudDataGrid T="Title" Items="@GameDataService.GetTitles()" - @bind-SelectedItem="@selectedTitle" Filterable="false" - QuickFilter="@Filter"> - <ToolBarContent> - <MudText Typo="Typo.h6">Built in titles</MudText> - <MudSpacer/> - <MudTextField @bind-Value="searchString" Placeholder="Search" Adornment="Adornment.Start" Immediate="true" - AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"> - </MudTextField> - </ToolBarContent> - <Columns> - <SelectColumn T="Title" ShowInFooter="false" ShowInHeader="false"/> - <Column T="Title" Field="@nameof(Title.TitleId)" Title="Id"/> - <Column T="Title" Field="@nameof(Title.TitleName)" Title="Name"/> - </Columns> - <PagerContent> - <MudDataGridPager T="Title"/> - </PagerContent> - </MudDataGrid>*@ <MudTable Items="@titles" Filter="@Filter" @bind-SelectedItem="@selectedTitle" Height="40vh" Hover="true"> <ColGroup> <col style="width: 50px;" /> @@ -50,7 +31,7 @@ <MudTd DataLabel="Name" Class="cursor-pointer">@context.TitleName</MudTd> </RowTemplate> <PagerContent> - <MudTablePager /> + <MudTablePager/> </PagerContent> </MudTable> <MudText Class="mt-4 d-block" Typo="Typo.caption"><b>Selected Title:</b> @selectedTitle?.TitleName</MudText> @@ -80,10 +61,17 @@ base.OnInitialized(); var titleSet = GameDataService.GetTitles(); titles = titleSet.ToImmutableList().Sort((title, title1) => title.TitleId.CompareTo(title1.TitleId)); - titleSet.TryGetValue(new Title + var currentTitle = new Title { TitleName = UserSetting.Title - }, out selectedTitle); + }; + if (titleSet.Contains(currentTitle)) + { + titleSet.TryGetValue(new Title + { + TitleName = UserSetting.Title + }, out selectedTitle); + } } private bool Filter(Title title)