@page "/Learn" @using System.Text; @using LearningChineseSimplified.ExtensionMethods; @inject NavigationManager navigator @inject Blazored.LocalStorage.ILocalStorageService localStorage @inject HttpClient httpClient @inject ISnackbar Snackbar Avoid Meaning Pinyin @if (!Answers.Any(x => x == null)) {

@GetDisplayChar()

}
@if (!Answers.Any(x=>x == null)) { @for (int i = 0; i < Answers.Length; i++) { int buttonIndex = i; @Answers[buttonIndex].cchar.pinyin.ToTitleCase() } } @if (!Answers.Any(x => x == null)) { Submit }
@code { public bool ShowOverlay = false; bool isSavedLocally = 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? DontSkipTheseCChar; private async Task GetFileContentsAsync(string filePath) { var fileResponse = await httpClient.GetByteArrayAsync(filePath); return Encoding.UTF8.GetString(fileResponse); } protected override async Task OnInitializedAsync() { Program.UpdateUiEvent += OnUiUpdate; isSavedLocally = await localStorage.ContainKeyAsync("Normalized_chunk_001.json"); int selectedChunk = await localStorage.GetItemAsync("SelectedChunk"); if (!isSavedLocally) Charecters = await httpClient.GetFromJsonAsync($"Data/Normalized_chunk_{selectedChunk.ToString("000")}.json"); else { string json = await localStorage.GetItemAsync($"Normalized_chunk_{selectedChunk.ToString("000")}.json"); Charecters = JsonConvert.DeserializeObject(json); } DontSkipTheseCChar = Charecters.ToList(); Program.CCharsLeft = DontSkipTheseCChar.Count; Program.InvokeUiUpdate(); GenerateQuestion(); } void OnUiUpdate() => StateHasChanged(); void GenerateQuestion() { if (DontSkipTheseCChar.Count < 5) { FinishAndKickBackToLearn(); return; } int correctIndex = Random.Shared.Next(0, Answers.Length); for (int i = 0; i < Answers.Length; i++) { bool isCorrect = i == correctIndex; CChar randomCChar; repickRandomCChar: randomCChar = DontSkipTheseCChar[Random.Shared.Next(0, DontSkipTheseCChar.Count)]; if (Answers.Any(x =>x != null && x.cchar == randomCChar)) goto repickRandomCChar; Answers[i] = new Answer(randomCChar, isCorrect); } } void FinishAndKickBackToLearn() { Snackbar.Add("Congrats, you have compleated this chunk!", Severity.Success, config => { config.RequireInteraction = true; config.CloseAfterNavigation = false; }); Program.UpdateUiEvent -= OnUiUpdate; Program.CCharsLeft = 0; navigator.NavigateTo(""); } async void Submit() { bool isCorrect = Answers.Any(x => x.isCorrect && x.isSelected); CChar correctCChar = GetCorrectCChar(); if (isCorrect) { Snackbar.Add($"Definition: {correctCChar.definition}", Severity.Success, config => { config.VisibleStateDuration = 1000; }); } else { Snackbar.Add( @

Incorrect!

  • CChar: @correctCChar.charcter
  • Correct answer: @correctCChar.pinyin.ToTitleCase()
  • Meaning: @correctCChar.definition
, 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); Program.CCharsLeft = DontSkipTheseCChar.Count; Program.InvokeUiUpdate(); GenerateQuestion(); } public void ShowMeaning() { Snackbar.Add($"Definition: {GetCorrectCChar().definition}", Severity.Info); } public void ShowPinyin() { Snackbar.Add($"Pinyin: {GetCorrectCChar().pinyin.ToTitleCase()}", Severity.Info); } }