From ce2124451742402eb06662e4a5740719220ef710 Mon Sep 17 00:00:00 2001 From: Gordon Pedersen Date: Mon, 24 Jun 2024 14:52:45 +1000 Subject: [PATCH] Making refresh behaviour more solid --- Components/EditPicDialog.razor | 2 ++ Components/EditStatusDialog.razor | 2 ++ Components/ExternalPageComponent.razor | 4 ++-- Components/NewPicDialog.razor | 1 + Components/NewStatusDialog.razor | 3 ++- Components/Pages/Directory.razor | 8 +++++--- Components/Pages/Ephemeral.razor | 6 ++++-- Components/Pages/Now.razor | 6 ++++-- Components/Pages/Person.razor | 12 ++++++++++++ Components/PicList.razor | 6 ++++-- Components/RefreshButton.razor | 2 +- Components/StatusList.razor | 8 +++++--- Models/State.cs | 27 +++++++++++++++++++++++++- 13 files changed, 70 insertions(+), 17 deletions(-) diff --git a/Components/EditPicDialog.razor b/Components/EditPicDialog.razor index c19ad36..87ce719 100644 --- a/Components/EditPicDialog.razor +++ b/Components/EditPicDialog.razor @@ -72,6 +72,7 @@ if (!string.IsNullOrEmpty(Pic?.Id)) { await api.DeletePic(State.SelectedAddressName, Pic.Id); await State.RefreshPics(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); } @@ -92,6 +93,7 @@ if(!string.IsNullOrEmpty(Pic?.Id)) { await api.PostPicDescription(State.SelectedAddressName, Pic.Id, Description); await State.RefreshPics(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); } diff --git a/Components/EditStatusDialog.razor b/Components/EditStatusDialog.razor index c8518e1..55be210 100644 --- a/Components/EditStatusDialog.razor +++ b/Components/EditStatusDialog.razor @@ -91,6 +91,7 @@ if (!string.IsNullOrEmpty(Status?.Id)) { await api.DeleteStatus(State.SelectedAddressName, Status.Id); await State.RefreshStatuses(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); } @@ -112,6 +113,7 @@ if (!string.IsNullOrEmpty(Status?.Id)) { await api.PatchStatus(State.SelectedAddressName, Status.Id, Content, Emoji); await State.RefreshStatuses(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); } diff --git a/Components/ExternalPageComponent.razor b/Components/ExternalPageComponent.razor index 2450e14..950a3b1 100644 --- a/Components/ExternalPageComponent.razor +++ b/Components/ExternalPageComponent.razor @@ -19,13 +19,13 @@ } public async Task Reload() { - if (Html == null){ + // if (Html == null){ Html = await api.GetHtml(Url); string? HtmlString = Html?.ToString(); HtmlString = HtmlString?.Replace("", ""); HtmlString = HtmlString?.Replace("", ""); Html = (MarkupString)HtmlString; - } + // } await InvokeAsync(StateHasChanged); } } diff --git a/Components/NewPicDialog.razor b/Components/NewPicDialog.razor index a179122..b9fca93 100644 --- a/Components/NewPicDialog.razor +++ b/Components/NewPicDialog.razor @@ -78,6 +78,7 @@ if(!string.IsNullOrEmpty(Description) && response != null && !string.IsNullOrEmpty(response.Id)) { await api.PostPicDescription(State.SelectedAddressName, response.Id, Description); await State.RefreshPics(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); } diff --git a/Components/NewStatusDialog.razor b/Components/NewStatusDialog.razor index e44415e..d7d3ee7 100644 --- a/Components/NewStatusDialog.razor +++ b/Components/NewStatusDialog.razor @@ -81,8 +81,9 @@ var result = await api.StatusPost(State!.SelectedAddressName!, post); if(result != null){ await State.RefreshStatuses(); + State.SendRefresh(); await InvokeAsync(StateHasChanged); - navigationManager.NavigateTo("/statuslog/latest"); + // navigationManager.NavigateTo("/statuslog/latest"); } this.Active = false; diff --git a/Components/Pages/Directory.razor b/Components/Pages/Directory.razor index ea69c72..a936d35 100644 --- a/Components/Pages/Directory.razor +++ b/Components/Pages/Directory.razor @@ -65,9 +65,11 @@ else { private async void StateChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { - addresses = await State.GetDirectory(true); - GroupAddresses(); - State.IsRefreshing = false; + using (State.GetRefreshToken()) { + addresses = await State.GetDirectory(true); + GroupAddresses(); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Components/Pages/Ephemeral.razor b/Components/Pages/Ephemeral.razor index e75d990..1255c8f 100644 --- a/Components/Pages/Ephemeral.razor +++ b/Components/Pages/Ephemeral.razor @@ -36,8 +36,10 @@ private async void StateChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { - messages = await State.GetEphemeralMessages(true); - State.IsRefreshing = false; + using (State.GetRefreshToken()) { + messages = await State.GetEphemeralMessages(true); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Components/Pages/Now.razor b/Components/Pages/Now.razor index f8f9feb..16342b8 100644 --- a/Components/Pages/Now.razor +++ b/Components/Pages/Now.razor @@ -43,8 +43,10 @@ private async void StateChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { - garden = await State.GetNowGarden(true); - State.IsRefreshing = false; + using (State.GetRefreshToken()){ + garden = await State.GetNowGarden(true); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Components/Pages/Person.razor b/Components/Pages/Person.razor index a00c482..802a8e8 100644 --- a/Components/Pages/Person.razor +++ b/Components/Pages/Person.razor @@ -129,6 +129,18 @@ if (fragment.EndsWith("now")) await ReloadNow(); else if (fragment.EndsWith("profile")) await ReloadProfile(); bio = await State.GetBio(Address); + State.PropertyChanged += StateChanged; + } + + private async void StateChanged(object? sender, PropertyChangedEventArgs e) { + if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { + using (State.GetRefreshToken()){ + await ReloadNow(); + await ReloadProfile(); + bio = await State.GetBio(Address); + await InvokeAsync(StateHasChanged); + } + } } private async Task ReloadNow() { diff --git a/Components/PicList.razor b/Components/PicList.razor index f3caa5f..cf77205 100644 --- a/Components/PicList.razor +++ b/Components/PicList.razor @@ -34,8 +34,10 @@ private async void StateChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { - pics = await PicsFunc(true); - State.IsRefreshing = false; + using (State.GetRefreshToken()){ + pics = await PicsFunc(true); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Components/RefreshButton.razor b/Components/RefreshButton.razor index c46c7e3..368767e 100644 --- a/Components/RefreshButton.razor +++ b/Components/RefreshButton.razor @@ -1,6 +1,6 @@ @inject State State - diff --git a/Components/StatusList.razor b/Components/StatusList.razor index 97c285f..4a00190 100644 --- a/Components/StatusList.razor +++ b/Components/StatusList.razor @@ -19,7 +19,7 @@ public bool Editable { get; set; } = false; public EditStatusDialog? Dialog { get; set; } - + private List? statuses; protected override async Task OnInitializedAsync() { @@ -33,8 +33,10 @@ private async void StateChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) { - statuses = await StatusFunc(true); - State.IsRefreshing = false; + using (State.GetRefreshToken()) { + statuses = await StatusFunc(true); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Models/State.cs b/Models/State.cs index ac9f02c..49fc9e4 100644 --- a/Models/State.cs +++ b/Models/State.cs @@ -70,12 +70,37 @@ namespace Neighbourhood.omg.lol.Models { private bool _isRefreshing; public bool IsRefreshing { get => _isRefreshing; - set { + private set { _isRefreshing = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRefreshing))); } } + public void SendRefresh() => IsRefreshing = true; + + private static int _refresherCount = 0; + private static Mutex mutex = new Mutex(); + + public class RefreshToken : IDisposable { + public event EventHandler? Disposed; + public void Dispose() => Disposed?.Invoke(this, EventArgs.Empty); + } + public RefreshToken GetRefreshToken() { + mutex.WaitOne(); + _refresherCount++; + mutex.ReleaseMutex(); + RefreshToken token = new RefreshToken(); + token.Disposed += RefreshToken_Disposed; + return token; + } + + private void RefreshToken_Disposed(object? sender, EventArgs e) { + mutex.WaitOne(); + _refresherCount--; + if (_refresherCount == 0) IsRefreshing = false; + mutex.ReleaseMutex(); + } + private bool _canRefresh; public bool CanRefresh { get => _canRefresh;