From f1a5597380a80395b743b2022c18251babb0e9d5 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Thu, 4 Jun 2026 13:59:07 +1000 Subject: Added Razor components for loadable remote content --- Pages/Component/LoadableContent.razor | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Pages/Component/LoadableContent.razor (limited to 'Pages/Component/LoadableContent.razor') 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 + + + @ChildContent + + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public required Func> 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()); + } + } +} -- cgit v1.3