diff options
Diffstat (limited to 'Pages')
| -rw-r--r-- | Pages/Component/ErrorState.razor | 23 | ||||
| -rw-r--r-- | Pages/Component/LoadableContent.razor | 59 | ||||
| -rw-r--r-- | Pages/Component/LoadedState.razor | 23 | ||||
| -rw-r--r-- | Pages/Component/LoadingState.razor | 23 |
4 files changed, 128 insertions, 0 deletions
diff --git a/Pages/Component/ErrorState.razor b/Pages/Component/ErrorState.razor new file mode 100644 index 0000000..92baac6 --- /dev/null +++ b/Pages/Component/ErrorState.razor @@ -0,0 +1,23 @@ +@implements IDisposable +@typeparam T + +@if(Parent.ComponentState == ComponentState.Error) { + @ChildContent +} + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [CascadingParameter] + public LoadableContent<T> Parent { get; set; } + + protected override void OnInitialized() => + Parent.OnStateChanged += OnStateChanged; + + public void OnStateChanged(object? sender, EventArgs e) => + InvokeAsync(StateHasChanged); + + public void Dispose() => + Parent.OnStateChanged -= OnStateChanged; +} diff --git a/Pages/Component/LoadableContent.razor b/Pages/Component/LoadableContent.razor new file mode 100644 index 0000000..570317f --- /dev/null +++ b/Pages/Component/LoadableContent.razor @@ -0,0 +1,59 @@ +@attribute [CascadingTypeParameter(nameof(T))] +@typeparam T + +<CascadingValue Value=this> + @ChildContent +</CascadingValue> + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public required Func<Task<T>> DataSource { private get; set; } + + public T Data { get; private set; } + + public ComponentState ComponentState { get; private set; } = ComponentState.Loading; + + public event EventHandler? OnStateChanged; + + private bool reloadRequested = false; + private Task? loadTask = null; + private object loadLock = new(); + + protected override void OnInitialized() => Load(); + + public void Load() { + lock(loadLock) { + reloadRequested = true; + if(loadTask is null || loadTask.IsCompleted) { + //loadTask = Task.Run(LoadInternalAsync); + loadTask = LoadInternalAsync(); + } + } + } + + private async Task LoadInternalAsync() { + while(true) { + lock(loadLock) { + if(!reloadRequested) + break; + reloadRequested = false; + } + + //ComponentState = ComponentState.Loading; + //await InvokeAsync(() => OnStateChanged?.Invoke(this, EventArgs.Empty)); + //await InvokeAsync(() => StateHasChanged()); + try { + Data = await DataSource.Invoke(); + ComponentState = ComponentState.Loaded; + } catch { + ComponentState = ComponentState.Error; + } + + await InvokeAsync(() => OnStateChanged?.Invoke(this, EventArgs.Empty)); + await InvokeAsync(() => StateHasChanged()); + } + } +} diff --git a/Pages/Component/LoadedState.razor b/Pages/Component/LoadedState.razor new file mode 100644 index 0000000..fce18d8 --- /dev/null +++ b/Pages/Component/LoadedState.razor @@ -0,0 +1,23 @@ +@implements IDisposable +@typeparam T + +@if(Parent.ComponentState == ComponentState.Loaded) { + @ChildContent +} + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [CascadingParameter] + public LoadableContent<T> Parent { get; set; } + + protected override void OnInitialized() => + Parent.OnStateChanged += OnStateChanged; + + public void OnStateChanged(object? sender, EventArgs e) => + InvokeAsync(StateHasChanged); + + public void Dispose() => + Parent.OnStateChanged -= OnStateChanged; +} diff --git a/Pages/Component/LoadingState.razor b/Pages/Component/LoadingState.razor new file mode 100644 index 0000000..0a7cffc --- /dev/null +++ b/Pages/Component/LoadingState.razor @@ -0,0 +1,23 @@ +@implements IDisposable +@typeparam T + +@if(Parent.ComponentState == ComponentState.Loading) { + @ChildContent +} + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [CascadingParameter] + public LoadableContent<T> Parent { get; set; } + + protected override void OnInitialized() => + Parent.OnStateChanged += OnStateChanged; + + public void OnStateChanged(object? sender, EventArgs e) => + InvokeAsync(StateHasChanged); + + public void Dispose() => + Parent.OnStateChanged -= OnStateChanged; +} |
