LearnCChar1.0/CCharLearn/Pages/Index.razor
2023-08-27 06:22:01 +02:00

251 lines
No EOL
9.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">
<MudStack Class="pt-4 " Spacing="0">
<MudContainer Class="pa-4">
<MudText Typo="Typo.h6" Class="fw-bold">Modifiers:</MudText>
<MudCheckBox Class="mr-6" @bind-Checked="@IgnoreTone" Label="Ignore pinyin tones" Color="Color.Primary"></MudCheckBox>
<MudCheckBox Class="mr-6" @bind-Checked="@UseChangingFonts" Label="Changing fonts" Color="Color.Primary"></MudCheckBox>
</MudContainer>
</MudStack>
</MudContainer>
<MudContainer Class="pt-4 justify-center d-flex">
@if (Charecters != null)
{
<MudPaper Class="overflow-scroll rounded-lg" Style="height: 40vh;" Elevation="1">
<MudDataGrid Style="" SortMode="SortMode.None" Height="500" 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 ignoreTone;
public bool IgnoreTone
{
get { return ignoreTone; }
set
{
ignoreTone = value;
SetIgnoreTone();
}
}
private bool useChangingFonts;
public bool UseChangingFonts
{
get { return useChangingFonts; }
set
{
useChangingFonts = value;
SetChangingFonts();
}
}
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 SetIgnoreTone()
{
await localStorage.SetItemAsync("IgnoreTone", ignoreTone);
}
async void SetChangingFonts()
{
await localStorage.SetItemAsync("ChangingFonts", UseChangingFonts);
}
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("IgnoreTone"))
{
ignoreTone = await localStorage.GetItemAsync<bool>("IgnoreTone");
}
if (await localStorage.ContainKeyAsync("ChangingFonts"))
{
UseChangingFonts = await localStorage.GetItemAsync<bool>("ChangingFonts");
}
}
}