diff --git a/GC-local-server-rewrite/backports/JsonDataAttribute.cs b/GC-local-server-rewrite/backports/JsonDataAttribute.cs
new file mode 100644
index 0000000..f14696f
--- /dev/null
+++ b/GC-local-server-rewrite/backports/JsonDataAttribute.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Threading.Tasks;
+
+namespace EmbedIO.WebApi
+{
+ ///
+ /// Specifies that a parameter of a controller method will receive
+ /// an object obtained by deserializing the request body as JSON.
+ /// The received object will be
+ /// only if the deserialized object is null .
+ /// If the request body is not valid JSON,
+ /// or if it cannot be deserialized to the type of the parameter,
+ /// a 400 Bad Request response will be sent to the client.
+ /// This class cannot be inherited.
+ ///
+ ///
+ ///
+ [AttributeUsage(AttributeTargets.Parameter)]
+ public class JsonDataAttribute : Attribute, IRequestDataAttribute
+ {
+ ///
+ public async Task GetRequestDataAsync(WebApiController controller, Type type, string parameterName)
+ {
+ string body;
+
+ using (var reader = controller.HttpContext.OpenRequestText())
+ {
+ body = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
+
+ try
+ {
+ return Swan.Formatters.Json.Deserialize(body, type);
+ }
+ catch (FormatException)
+ {
+ throw HttpException.BadRequest($"Expected request body to be deserializable to {type.FullName}.");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/GC-local-server-rewrite/common/Configs.cs b/GC-local-server-rewrite/common/Configs.cs
index b2bb00f..66f30a8 100644
--- a/GC-local-server-rewrite/common/Configs.cs
+++ b/GC-local-server-rewrite/common/Configs.cs
@@ -122,6 +122,16 @@ public static class Configs
public const string RANK_STATUS_XPATH = $"{ROOT_XPATH}/ranking_status";
+ public const int CONFIG_PCOL1 = 0;
+ public const int CONFIG_PCOL2 = 0;
+ public const int CONFIG_PCOL3 = 0;
+
+ public const int FAVORITE_PCOL1 = 10;
+
+ public const int COUNT_PCOL1 = 20;
+
+ public const int SCORE_PCOL1 = 21;
+
public static readonly List DOMAINS = new()
{
"localhost",
diff --git a/GC-local-server-rewrite/controllers/ApiController.cs b/GC-local-server-rewrite/controllers/ApiController.cs
index 8f0295b..2a13769 100644
--- a/GC-local-server-rewrite/controllers/ApiController.cs
+++ b/GC-local-server-rewrite/controllers/ApiController.cs
@@ -1,5 +1,4 @@
-using ChoETL;
-using EmbedIO;
+using EmbedIO;
using EmbedIO.Routing;
using EmbedIO.WebApi;
using GCLocalServerRewrite.common;
@@ -39,6 +38,54 @@ public class ApiController : WebApiController
return result;
}
+ [Route(HttpVerbs.Post, "/UserDetail/SetMusicFavorite")]
+ // ReSharper disable once UnusedMember.Global
+ public bool SetFavorite([JsonData] MusicFavoriteData data)
+ {
+ var existing = cardSqLiteConnection.Table()
+ .Where(detail => detail.CardId == data.CardId
+ && detail.Pcol1 == Configs.FAVORITE_PCOL1
+ && detail.Pcol2 == data.MusicId);
+
+ if (!existing.Any())
+ {
+ $"Trying to update non existing song's favorite! Card id {data.CardId}, music id {data.MusicId}".Warn();
+ return false;
+ }
+
+ var cardDetail = existing.First();
+ cardDetail.Fcol1 = data.IsFavorite ? 1 : 0;
+ var result = cardSqLiteConnection.Update(cardDetail);
+
+ return result == 1;
+ }
+
+ [Route(HttpVerbs.Post, "/UserDetail/SetPlayOption")]
+ // ReSharper disable once UnusedMember.Global
+ public bool SetPlayOption([JsonData] PlayOption data)
+ {
+ var existing = cardSqLiteConnection.Table()
+ .Where(detail => detail.CardId == data.CardId
+ && detail.Pcol1 == Configs.CONFIG_PCOL1
+ && detail.Pcol2 == Configs.CONFIG_PCOL2
+ && detail.Pcol3 == Configs.CONFIG_PCOL3);
+
+ if (!existing.Any())
+ {
+ $"Trying to update non existing card's config! Card id {data.CardId}".Warn();
+
+ return false;
+ }
+
+ var cardDetail = existing.First();
+ cardDetail.ScoreUi1 = (long)data.FastSlowIndicator;
+ cardDetail.ScoreUi2 = (long)data.FeverTrance;
+
+ var result = cardSqLiteConnection.Update(cardDetail);
+
+ return result == 1;
+ }
+
[Route(HttpVerbs.Get, "/UserDetail/{cardId}")]
// ReSharper disable once UnusedMember.Global
public UserDetail? GetUserDetail(long cardId)
@@ -47,6 +94,7 @@ public class ApiController : WebApiController
if (!cardResult.Any())
{
+ $"Getting detail for non exisisting card! Card id is {cardId}".Warn();
return null;
}
@@ -229,6 +277,7 @@ public class ApiController : WebApiController
{
Artist = musicData.Artist ?? string.Empty,
Title = musicData.Title ?? string.Empty,
+ MusicId = musicId,
SongPlaySubDataList = new SongPlayDetailData[4]
};
diff --git a/MudAdmin/Pages/FavoriteDialog.razor b/MudAdmin/Pages/FavoriteDialog.razor
new file mode 100644
index 0000000..639da68
--- /dev/null
+++ b/MudAdmin/Pages/FavoriteDialog.razor
@@ -0,0 +1,57 @@
+@using SharedProject.models
+@inject HttpClient Client
+@inject ILogger Logger
+
+
+
+ @if (!Data.IsFavorite)
+ {
+
+
+ Add to favorite?
+
+ }
+ else
+ {
+
+
+ Remove from favorite?
+
+ }
+
+
+
+
+
+
+ Cancel
+ Confirm
+
+
+@code {
+ [CascadingParameter]
+ MudDialogInstance MudDialog { get; set; } = null!;
+
+ [Parameter]
+ public SongPlayData Data { get; set; } = null!;
+
+ [Parameter]
+ public long CardId { get; set; }
+
+ async void Submit()
+ {
+ var postData = new MusicFavoriteData
+ {
+ CardId = CardId,
+ IsFavorite = !Data.IsFavorite,
+ MusicId = Data.MusicId
+ };
+ Logger.LogInformation("Data is {cardId}, {musicId}", CardId, Data.MusicId);
+ var response = await Client.PostAsJsonAsync("api/UserDetail/SetMusicFavorite", postData);
+ var result = await response.Content.ReadFromJsonAsync();
+ Logger.LogInformation("Favorite result is {result}", result);
+ MudDialog.Close(DialogResult.Ok(result));
+ }
+
+ void Cancel() => MudDialog.Cancel();
+}
\ No newline at end of file
diff --git a/MudAdmin/Pages/FetchData.razor b/MudAdmin/Pages/FetchData.razor
deleted file mode 100644
index 0db80ca..0000000
--- a/MudAdmin/Pages/FetchData.razor
+++ /dev/null
@@ -1,61 +0,0 @@
-@page "/fetchdata"
-@inject HttpClient Http
-
-Weather forecast
-
-Weather forecast
-This component demonstrates fetching data from the server.
-@if (forecasts == null)
-{
-
-}
-else
-{
-
-
-
- Date
-
-
- Temp. (C)
-
-
- Temp. (F)
-
-
- Summary
-
-
-
- @context.Date
- @context.TemperatureC
- @context.TemperatureF
- @context.Summary
-
-
-
-
-
-}
-
-
-@code {
- private WeatherForecast[]? forecasts;
-
- protected override async Task OnInitializedAsync()
- {
- forecasts = await Http.GetFromJsonAsync("sample-data/weather.json");
- }
-
- public class WeatherForecast
- {
- public DateTime Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public string? Summary { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
- }
-
-}
\ No newline at end of file
diff --git a/MudAdmin/Pages/User.razor b/MudAdmin/Pages/User.razor
index 6c32fa4..a109dd5 100644
--- a/MudAdmin/Pages/User.razor
+++ b/MudAdmin/Pages/User.razor
@@ -1,14 +1,17 @@
@page "/user/{CardId:long}"
@using SharedProject.models
-@using MudAdmin.Utils
@using SharedProject.enums
@inject HttpClient Client
+@inject IDialogService DialogService
+@inject ILogger Logger
User
-
+
@if (userDetail == null)
{
-
+
+
+
}
else
{
@@ -57,12 +60,12 @@ else
-
+
Played Songs
-
+
@@ -70,22 +73,17 @@ else
-
+
-
-
-
-
- @CalculateTotalPlayCount(context.Item)
-
-
-
+
@if (context.ShowDetails)
@@ -99,7 +97,7 @@ else
-
+
Difficulty
Clear State
@@ -132,6 +130,7 @@ else
}
+
@code {
@@ -177,7 +176,13 @@ else
private async Task SaveOptions()
{
isSavingOptions = true;
- await Task.Delay(2000);
+ var postData = new PlayOption
+ {
+ CardId = CardId,
+ FastSlowIndicator = fastSlowIndicator,
+ FeverTrance = feverTranceShow
+ };
+ var result = await Client.PostAsJsonAsync("api/UserDetail/SetPlayOption", postData);
isSavingOptions = false;
}
@@ -195,14 +200,29 @@ else
return grade;
}
- private void OnFavoriteToggled(SongPlayData data)
+ private async Task OnFavoriteToggled(SongPlayData data)
{
- data.IsFavorite = !data.IsFavorite;
- }
+ var options = new DialogOptions
+ {
+ CloseOnEscapeKey = false,
+ DisableBackdropClick = true,
+ FullWidth = true
+ };
+ var parameters = new DialogParameters();
+ parameters.Add("Data", data);
+ parameters.Add("CardId", CardId);
+ var dialog = DialogService.Show("Favorite", parameters, options);
+ var result = await dialog.Result;
- private static int CalculateTotalPlayCount(SongPlayData data)
- {
- return data.SongPlaySubDataList
- .Sum(detailData => detailData.PlayCount);
+ if (result.Cancelled)
+ {
+ return;
+ }
+
+ if ((bool)result.Data)
+ {
+ Logger.LogInformation("Changed!");
+ data.IsFavorite = !data.IsFavorite;
+ }
}
}
\ No newline at end of file
diff --git a/MudAdmin/Pages/Users.razor b/MudAdmin/Pages/Users.razor
index 08d7257..a486c2b 100644
--- a/MudAdmin/Pages/Users.razor
+++ b/MudAdmin/Pages/Users.razor
@@ -5,31 +5,64 @@
Users
-
- @foreach (var user in users)
+
+ @if (users is null)
{
-
-
-
-
- @user.PlayerName
-
-
-
- Card ID
- @user.CardId
-
-
- Test
-
-
-
+
+ @for (var i = 0; i < 5; i++)
+ {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
}
-
+ else if (!(users.Count == 0))
+ {
+
+ @foreach (var user in users)
+ {
+
+
+
+
+ @user.PlayerName
+
+
+
+ Card ID
+ @user.CardId
+
+
+ Check detail
+
+
+
+ }
+
+ }
+ else
+ {
+ No Data
+ }
+
@code {
- private List users = new();
-
+ private List? users;
+
protected override async Task OnInitializedAsync()
{
@@ -41,4 +74,5 @@
{
NavigationManager.NavigateTo($"user/{user.CardId}");
}
+
}
\ No newline at end of file
diff --git a/MudAdmin/Program.cs b/MudAdmin/Program.cs
index 441cf5a..11f979d 100644
--- a/MudAdmin/Program.cs
+++ b/MudAdmin/Program.cs
@@ -1,3 +1,4 @@
+using System.Text.Json;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using MudAdmin;
diff --git a/MudAdmin/Shared/NavMenu.razor b/MudAdmin/Shared/NavMenu.razor
index b3c37b3..9b23ec3 100644
--- a/MudAdmin/Shared/NavMenu.razor
+++ b/MudAdmin/Shared/NavMenu.razor
@@ -1,6 +1,5 @@
Home
Counter
- Fetch data
Users
\ No newline at end of file
diff --git a/SharedProject/enums/ClearState.cs b/SharedProject/enums/ClearState.cs
index 7530662..a9376ce 100644
--- a/SharedProject/enums/ClearState.cs
+++ b/SharedProject/enums/ClearState.cs
@@ -2,6 +2,7 @@
public enum ClearState
{
+ NotPlayed = 0,
Failed,
Clear,
NoMiss,
diff --git a/SharedProject/models/MusicFavoriteData.cs b/SharedProject/models/MusicFavoriteData.cs
new file mode 100644
index 0000000..2054155
--- /dev/null
+++ b/SharedProject/models/MusicFavoriteData.cs
@@ -0,0 +1,15 @@
+using System.Text.Json.Serialization;
+
+namespace SharedProject.models;
+
+public class MusicFavoriteData
+{
+ [JsonPropertyName(nameof(CardId))]
+ public long CardId { get; set; }
+
+ [JsonPropertyName(nameof(MusicId))]
+ public int MusicId { get; set; }
+
+ [JsonPropertyName(nameof(IsFavorite))]
+ public bool IsFavorite { get; set; }
+}
\ No newline at end of file
diff --git a/SharedProject/models/PlayOption.cs b/SharedProject/models/PlayOption.cs
index 1c3bf5a..0795e68 100644
--- a/SharedProject/models/PlayOption.cs
+++ b/SharedProject/models/PlayOption.cs
@@ -1,12 +1,16 @@
-using SharedProject.enums;
+using System.Text.Json.Serialization;
+using SharedProject.enums;
namespace SharedProject.models;
public class PlayOption
{
+ [JsonPropertyName(nameof(CardId))]
public long CardId { get; set; }
+ [JsonPropertyName(nameof(FastSlowIndicator))]
public PlayOptions.FastSlowIndicator FastSlowIndicator { get; set; }
+ [JsonPropertyName(nameof(FeverTrance))]
public PlayOptions.FeverTranceShow FeverTrance { get; set; }
}
\ No newline at end of file
diff --git a/SharedProject/models/SongPlayData.cs b/SharedProject/models/SongPlayData.cs
index 4f56ae9..41744a1 100644
--- a/SharedProject/models/SongPlayData.cs
+++ b/SharedProject/models/SongPlayData.cs
@@ -1,14 +1,27 @@
-namespace SharedProject.models;
+using System.Text.Json.Serialization;
+
+namespace SharedProject.models;
public class SongPlayData
{
public string Title { get; set; } = string.Empty;
public string Artist { get; set; } = string.Empty;
+
+ public int MusicId { get; set; }
public SongPlayDetailData[] SongPlaySubDataList { get; set; } = new SongPlayDetailData[4];
public bool IsFavorite { get; set; }
public bool ShowDetails { get; set; }
+
+ [JsonIgnore]
+ public int TotalPlayCount
+ {
+ get
+ {
+ return SongPlaySubDataList.Sum(data => data.PlayCount);
+ }
+ }
}
\ No newline at end of file