LearnCChar1.0/CCharLearn/Pages/Index.razor

223 lines
No EOL
8.1 KiB
Text

@page "/"
@inject NavigationManager navigator
@inject HttpClient httpClient
@inject Blazored.LocalStorage.ILocalStorageService localStorage
@inject SpeechSynthesis SpeechSynthesis
<PageTitle>Index</PageTitle>
<MudContainer Class="align-center justify-center d-flex">
<MudContainer Style="width: 400px">
<MudSelect Class="pt-12" @bind-Value=selectedChunk TextChanged="SelectedChunk" select T=int Label="Chunk" Variant="Variant.Filled" AnchorOrigin="Origin.BottomCenter">
@for (int i = 0; i < numOfChunks; i++)
{
<MudSelectItem T="int" Value="@i" />
}
</MudSelect>
<MudContainer Class="justify-center d-flex pt-4" Style="width:300px">
<MudButton Variant="Variant.Filled" OnClick=StartLearning Color="Color.Primary">@((!continueDataExists) ? "Start learning!" : "Start new!")</MudButton>
<MudStack Spacing="0" Class="pa-0 pl-2 ma-0">
@if (continueDataExists)
{
<MudButton Class="pb-0 px-0" Variant="Variant.Filled" Color="Color.Success" OnClick="ContinueLearning" Disabled="@(!continueDataExists)">
<MudStack Class="mud-width-full" Spacing="1">
<MudContainer Class="px-2">
<MudStack Class="justify-center d-flex" Row=true Spacing="1">
<MudText>@($"Continue: {continueCharectersLeft}")</MudText>
<MudIconButton Class="pa-0 ma-0" OnClick="DeleteContinueData" Variant=Variant.Filled Color="Color.Error" Icon="@Icons.Material.Filled.Close"></MudIconButton>
</MudStack>
</MudContainer>
<MudProgressLinear Class="pa-0 ma-0" Color="Color.Warning" Size="Size.Small" Value="@(((float)continueCharectersLeft/(float)chunkSize))" />
</MudStack>
</MudButton>
}
</MudStack>
</MudContainer>
<MudContainer Class="justify-center d-flex">
<MudCheckBox Class="mr-6" @bind-Checked="@IsEasyMode" Label="Easy mode" Color="Color.Primary"></MudCheckBox>
</MudContainer>
<MudContainer Class="pt-16 justify-center d-flex">
@if (Charecters != null)
{
<MudPaper Class="overflow-scroll rounded-0" Style="height: 50vh;" Elevation="1">
<MudDataGrid FixedHeader=true Items="@Charecters" Breakpoint="Breakpoint.None">
<Columns>
<PropertyColumn Property="x => x.charcter" Title="CChar" />
<PropertyColumn Property="x => x.pinyin" Title="Pinyin" />
</Columns>
</MudDataGrid>
</MudPaper>
}
</MudContainer>
<MudContainer Class="justify-center d-flex pt-4">
<MudButton Class="mt-1 mb-7" Variant="Variant.Filled" Color="Color.Secondary" Disabled="@(isLoading || isSavedLocally)" OnClick="LoadAllChunksIntoLocalStorage">
@if (!isSavedLocally)
{
@if (isLoading)
{
<MudText>@($"{savedChunks}/{numOfChunks}")</MudText>
<MudProgressCircular Class="pl-8 ms-n1 mr-2" Size="Size.Small" Indeterminate="true" />
}
else
{
<MudText>Load chunks to local storage</MudText>
<MudIcon Icon="@Icons.Material.Rounded.Send" Class="mr-1" />
}
}
else
{
<MudText>Chunks are saved locally</MudText>
}
</MudButton>
</MudContainer>
<MudContainer Class="justify-center d-flex pt-4">
<MudButton OnClick="async ()=>{await localStorage.ClearAsync(); navigator.NavigateTo(string.Empty, true);}" Variant="Variant.Outlined" Color="Color.Tertiary">Delete local storage</MudButton>
</MudContainer>
</MudContainer>
</MudContainer>
@code{
int numOfChunks = 197; //Exclusive index 0
int selectedChunk = 0;
int savedChunks = 0;
const int chunkSize = 50;
bool isLoading = false;
bool isSavedLocally = false;
bool continueDataExists = false;
int continueCharectersLeft = -1;
private bool isEasyMode;
public bool IsEasyMode
{
get { return isEasyMode; }
set
{
isEasyMode = value;
SetEasyMode();
}
}
protected async override Task OnInitializedAsync()
{
if (await localStorage.ContainKeyAsync("Normalized_chunk_001.json"))
isSavedLocally = true;
continueDataExists = await localStorage.ContainKeyAsync("ContinueData");
SelectedChunk();
StateHasChanged();
}
async void StartLearning()
{
await localStorage.SetItemAsync("SelectedChunk", selectedChunk);
await localStorage.SetItemAsync("ContinueLearning", false);
navigator.NavigateTo("/Learn");
}
async void ContinueLearning()
{
await localStorage.SetItemAsync("ContinueLearning", true);
navigator.NavigateTo("/Learn");
}
async void DeleteContinueData()
{
string[] continueDataKeys = { "ContinueLearning", "ContinueData", "ContinueCharectersLeft" };
await localStorage.RemoveItemsAsync(continueDataKeys);
continueDataExists = false;
StateHasChanged();
}
CChar[]? Charecters;
async void SelectedChunk()
{
if (await localStorage.ContainKeyAsync("Normalized_chunk_001.json"))
isSavedLocally = true;
if (!isSavedLocally)
Charecters = await httpClient.GetFromJsonAsync<CChar[]>($"Data/Normalized_chunk_{selectedChunk.ToString("000")}.json");
else
{
string json = await localStorage.GetItemAsync<string>($"Normalized_chunk_{selectedChunk.ToString("000")}.json");
Charecters = JsonConvert.DeserializeObject<CChar[]>(json);
}
StateHasChanged();
}
async void SetEasyMode()
{
await localStorage.SetItemAsync("EasyMode", isEasyMode);
}
async Task LoadAllChunksIntoLocalStorage()
{
isLoading = true;
string[] jsonChunks = new string[numOfChunks];
Parallel.For(0, numOfChunks, async (i)=>
{
await Task.Delay(10*i);
try
{
jsonChunks[i] = await httpClient.GetStringAsync($"Data/Normalized_chunk_{i.ToString("000")}.json");
}
catch (Exception)
{
await Task.Delay(100);
jsonChunks[i] = await httpClient.GetStringAsync($"Data/Normalized_chunk_{i.ToString("000")}.json");
}
if (string.IsNullOrEmpty(jsonChunks[i])) throw new Exception("Couldn't load chunk: " + i);
try
{
await localStorage.SetItemAsync($"Normalized_chunk_{i.ToString("000")}.json", jsonChunks[i]);
}
catch (Exception)
{
await Task.Delay(100);
await localStorage.SetItemAsync($"Normalized_chunk_{i.ToString("000")}.json", jsonChunks[i]);
}
if (!await localStorage.ContainKeyAsync($"Normalized_chunk_{i.ToString("000")}.json")) throw new Exception("Couldn't save chunk: " + i);
});
while (jsonChunks.Any(x => x == null))
{
await Task.Delay(1);
savedChunks = jsonChunks.Count(x=>x != null);
StateHasChanged();
}
isLoading = false;
isSavedLocally = true;
StateHasChanged();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
}
if (continueDataExists)
{
continueCharectersLeft = await localStorage.GetItemAsync<int>("ContinueCharectersLeft");
}
if (await localStorage.ContainKeyAsync("EasyMode"))
{
isEasyMode = await localStorage.GetItemAsync<bool>("EasyMode");
}
}
}