@page "/Learn" @using System.Text; @using LearningChineseSimplified.ExtensionMethods; @inject NavigationManager navigator @inject Blazored.LocalStorage.ILocalStorageService localStorage @inject HttpClient httpClient @inject ISnackbar Snackbar <style> .LargeCharecter{ width: 0; height: 0; display: flex; justify-content: center; align-items: center; font-size: 125px; } .PinyinButtons{ width: 125px; font-size: 20px; } </style> <MudContainer Class="justify-center d-flex ma-0" Style="height: 100%;"> <MudStack Class="d-flex"> <MudStack Row=true Class="pt-2 d-flex justify-center"> <MudButton Color="Color.Default" OnClick="RemoveCCharFromSelection" Variant="Variant.Outlined">Skip</MudButton> </MudStack> <MudContainer> <MudPaper Class="pa-16 ma-2 rounded-xl mud-dark" Elevation="1"> <MudContainer Style="width: 100px; height: 100px" Class="pa-8 ma-4 d-flex justify-center align-center"> @if (!Answers.Any(x => x == null)) { <p class="LargeCharecter">@GetDisplayChar()</p> } </MudContainer> </MudPaper> </MudContainer> <MudContainer Class="pa-8 pt-10 justify-center align-center d-flex" Style="max-width:300px"> <MudGrid Spacing="10" Class="align-center justify-center d-flex"> @if (!Answers.Any(x=>x == null)) { @for (int i = 0; i < Answers.Length; i++) { int buttonIndex = i; <MudButton Class="PinyinButtons ma-3" Variant="Variant.Outlined" @onclick="() => SelectButton(buttonIndex)" Color="@(Answers[buttonIndex].isSelected ? Color.Primary : Color.Default)"> <MudText> @Answers[buttonIndex].cchar.pinyin.ToTitleCase() </MudText> </MudButton> } } </MudGrid> </MudContainer> <MudSpacer/> <MudContainer Class="pb-8 justify-center align-center d-flex"> @if (!Answers.Any(x => x == null)) { <MudButton Disabled="@(!(Answers.Any(x=>x.isSelected)))" OnClick="Submit" Class="px-8 py-3" Variant="Variant.Filled" Size="Size.Large" Color="Color.Success" Style="font-size: 20px;"> Submit</MudButton> } </MudContainer> </MudStack> </MudContainer> <MudOverlay @bind-Visible="ShowOverlay" DarkBackground="true" AutoClose="true" /> @code { public bool ShowOverlay = false; public Answer[] Answers = new Answer[4]; public void SelectButton(int selectedIndex) { for (int i = 0; i < Answers.Length; i++) { Answers[i].isSelected = (i == selectedIndex); } } private CChar[]? _charecters; public CChar[]? Charecters { get { if (_charecters == null) throw new Exception("Loaded dataset empty?"); return _charecters; } set { _charecters = value; } } public List<CChar>? DontSkipTheseCChar; private async Task<string> GetFileContentsAsync(string filePath) { var fileResponse = await httpClient.GetByteArrayAsync(filePath); return Encoding.UTF8.GetString(fileResponse); } protected override async Task OnInitializedAsync() { int selectedChunk = await localStorage.GetItemAsync<int>("SelectedChunk"); //Charecters = await httpClient.GetFromJsonAsync<CChar[]>("Data/NormalizedDataset.json"); Charecters = await httpClient.GetFromJsonAsync<CChar[]>($"Data/Normalized_chunk_{selectedChunk.ToString("000")}.json"); DontSkipTheseCChar = Charecters.ToList(); GenerateQuestion(); } void GenerateQuestion() { if (DontSkipTheseCChar.Count < 3) throw new Exception("Finished this chunk of CChars"); int correctIndex = Random.Shared.Next(0, Answers.Length); for (int i = 0; i < Answers.Length; i++) { bool isCorrect = i == correctIndex; Answers[i] = new Answer(DontSkipTheseCChar[Random.Shared.Next(0, DontSkipTheseCChar.Count)], isCorrect); } } async void Submit() { bool isCorrect = Answers.Any(x => x.isCorrect && x.isSelected); CChar correctCChar = GetCorrectCChar(); if (isCorrect) { Snackbar.Add($"<b>Definition:</b> {correctCChar.definition}", Severity.Success, config => { config.VisibleStateDuration = 1000; }); } else { Snackbar.Add( @<div> <h3>Incorrect!</h3> <ul> <li>Correct answer: @correctCChar.pinyin.ToTitleCase()</li> <li>Meaning: @correctCChar.definition</li> </ul> </div> , Severity.Error); } GenerateQuestion(); } public class Answer { public Answer() { } public Answer(CChar cchar, bool isCorrect) { this.cchar = cchar; this.isCorrect = isCorrect; } public CChar cchar { get; set; } public bool isCorrect { get; set; } = false; public bool isSelected { get; set; } = false; } public char GetDisplayChar() { char? cc = GetCorrectCChar().charcter; if (cc == null) return ' '; else return (char)cc; } public CChar GetCorrectCChar() { CChar cchar = Answers.FirstOrDefault(x => x.isCorrect)?.cchar; return cchar; } public void RemoveCCharFromSelection() { CChar correctChar = GetCorrectCChar(); DontSkipTheseCChar.Remove(correctChar); Console.WriteLine("Remaining CChars: " + DontSkipTheseCChar); GenerateQuestion(); } }