summaryrefslogtreecommitdiff
path: root/Pages/Component/LoadableContent.razor
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2026-06-04 13:59:07 +1000
committerJake Mannens <jake@asger.xyz>2026-06-11 01:41:01 +1000
commitf1a5597380a80395b743b2022c18251babb0e9d5 (patch)
tree16333fd076b37d146e309984289ac2c9016d870e /Pages/Component/LoadableContent.razor
parent3263576943a491bcad3aff6c18c166fb1c874619 (diff)
Added Razor components for loadable remote content
Diffstat (limited to 'Pages/Component/LoadableContent.razor')
-rw-r--r--Pages/Component/LoadableContent.razor59
1 files changed, 59 insertions, 0 deletions
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());
+ }
+ }
+}