Added refresh (no pull-to-refresh, yet)

This commit is contained in:
Gordon Pedersen 2024-06-18 11:44:18 +10:00
parent 996e1286cb
commit 413051ad4c
10 changed files with 124 additions and 14 deletions

View file

@ -1,6 +1,10 @@
@page "/ephemeral"
@implements IDisposable
@inject IJSRuntime JS
@inject State State
<RefreshButton></RefreshButton>
<PageHeading title="Eph.emer.al" icon="fa-light fa-comment-dots">
<Description><a href="https://eph.emer.al">Eph.emer.al</a> is a place for fleeting thoughts. Everything on this page will disappear after a while.</Description>
</PageHeading>
@ -24,7 +28,21 @@
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
if (messages == null || messages.Count == 0) messages = await State.GetEphemeralMessages();
State.PropertyChanged += StateChanged;
State.CanRefresh = true;
await InvokeAsync(StateHasChanged);
await JS.InvokeVoidAsync("removeElementById", "ephemeral-loading");
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) {
messages = await State.GetEphemeralMessages(true);
State.IsRefreshing = false;
}
}
public void Dispose() {
State.PropertyChanged -= StateChanged;
State.CanRefresh = false;
}
}

View file

@ -1,6 +1,10 @@
@page "/now"
@implements IDisposable
@inject IJSRuntime JS
@inject State State
<RefreshButton></RefreshButton>
<PageHeading title="Now.garden" icon="fa-duotone fa-seedling">
<Description>Feel free to stroll through the <a href="now.garden">now.garden</a> and take a look at what people are up to.</Description>
</PageHeading>
@ -31,7 +35,21 @@
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
if (garden == null || garden.Count == 0) garden = await State.GetNowGarden();
State.PropertyChanged += StateChanged;
State.CanRefresh = true;
await InvokeAsync(StateHasChanged);
await JS.InvokeVoidAsync("removeElementById", "now-loading");
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) {
garden = await State.GetNowGarden(true);
State.IsRefreshing = false;
}
}
public void Dispose() {
State.PropertyChanged -= StateChanged;
State.CanRefresh = false;
}
}

View file

@ -3,6 +3,8 @@
@inject IJSRuntime JS
@inject NavigationManager Nav
<RefreshButton></RefreshButton>
<div class="row center-align">
<h3 class="page-heading"><i class="fa-solid fa-fw fa-at"></i>@Address</h3>
@ -51,7 +53,7 @@
}
</article>
</div>
<StatusList @ref="StatusList" StatusFunc="@(async() => await State.GetStatuses(Address))" Editable="@Editable"></StatusList>
<StatusList @ref="StatusList" StatusFunc="@(async(refresh) => await State.GetStatuses(Address, refresh))" Editable="@Editable"></StatusList>
@if(Address == State.SelectedAddressName) {
<button class="fab circle extra large-elevate" data-ui="#post-modal">
<i class="fa-solid fa-pen-to-square"></i>
@ -61,7 +63,7 @@
</div>
<div id="pics" class="page padding">
<PicList @ref="PicList" PicsFunc="@(async() => await State.GetPics(Address))" Editable="@Editable"></PicList>
<PicList @ref="PicList" PicsFunc="@(async(refresh) => await State.GetPics(Address, refresh))" Editable="@Editable"></PicList>
@if (Address == State.SelectedAddressName) {
<button class="fab circle extra large-elevate" data-ui="#post-modal">
<i class="fa-solid fa-camera-retro"></i>
@ -84,8 +86,8 @@
get => _address;
set {
_address = value;
if(StatusList != null) StatusList.StatusFunc = async () => await State.GetStatuses(_address);
if(PicList != null) PicList.PicsFunc = async () => await State.GetPics(_address);
if (StatusList != null) StatusList.StatusFunc = async (refresh) => await State.GetStatuses(_address, refresh);
if (PicList != null) PicList.PicsFunc = async (refresh) => await State.GetPics(_address, refresh);
}
}
public string ProfileUrl {

View file

@ -1,6 +1,8 @@
@page "/pics"
@inject State State
<RefreshButton></RefreshButton>
<PageHeading title="Some.pics" icon="fa-solid fa-images">
<Description>Sit back, relax, and look at <a href="https://some.pics/">some.pics</a></Description>
</PageHeading>
@ -15,7 +17,7 @@
</AuthorizeView>
<div id="pics" class="responsive card-grid">
<PicList PicsFunc="@(async() => await State.GetPics())"></PicList>
<PicList PicsFunc="@(async(refresh) => await State.GetPics(refresh))"></PicList>
</div>
@code {

View file

@ -2,6 +2,8 @@
@page "/statuslog/latest"
@inject State State
<RefreshButton></RefreshButton>
<PageHeading title="Status.lol" icon="fa-solid fa-message-smile">
<Description>The latest posts from everyone at <a href="https://status.lol">status.lol</a></Description>
</PageHeading>
@ -16,7 +18,7 @@
</AuthorizeView>
<div id="statuses" class="responsive">
<StatusList StatusFunc="@(async() => await State.GetStatuses())"></StatusList>
<StatusList StatusFunc="@(async(refresh) => await State.GetStatuses(refresh))"></StatusList>
</div>
@code {

View file

@ -1,4 +1,5 @@
@inject IJSRuntime JS
@implements IDisposable
@inject IJSRuntime JS
@inject State State
@if (Editable) {
@ -13,7 +14,7 @@
@code {
[Parameter]
public Func<Task<List<Pic>?>> PicsFunc { get; set; }
public Func<bool, Task<List<Pic>?>> PicsFunc { get; set; }
[Parameter]
public bool Editable { get; set; } = false;
@ -24,8 +25,22 @@
// TODO: There is a noticable rendering delay between the pics loading and the page rendering
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
if (pics == null || pics.Count == 0) pics = await PicsFunc();
if (pics == null || pics.Count == 0) pics = await PicsFunc(false);
State.PropertyChanged += StateChanged;
State.CanRefresh = true;
await InvokeAsync(StateHasChanged);
await JS.InvokeVoidAsync("removeElementById", "pics-loading");
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) {
pics = await PicsFunc(true);
State.IsRefreshing = false;
}
}
public void Dispose() {
State.PropertyChanged -= StateChanged;
State.CanRefresh = false;
}
}

View file

@ -0,0 +1,18 @@
@inject State State
<button id="refreshButton" class="absolute transparent circle top right margin" @onclick="() => State.IsRefreshing = true">
<i class="fa-solid fa-arrow-rotate-right @(State.IsRefreshing ? "fa-spin" : "")"></i>
</button>
@code {
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
State.PropertyChanged += StateChanged;
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing)) {
await InvokeAsync(StateHasChanged);
}
}
}

View file

@ -1,4 +1,5 @@
@inject IJSRuntime JS
@implements IDisposable
@inject IJSRuntime JS
@inject State State
@if (Editable) {
@ -13,7 +14,7 @@
@code {
[Parameter]
public Func<Task<List<Status>?>> StatusFunc { get; set; }
public Func<bool, Task<List<Status>?>> StatusFunc { get; set; }
[Parameter]
public bool Editable { get; set; } = false;
@ -23,8 +24,22 @@
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
if (statuses == null || statuses.Count == 0) statuses = await StatusFunc();
if (statuses == null || statuses.Count == 0) statuses = await StatusFunc(false);
State.PropertyChanged += StateChanged;
State.CanRefresh = true;
await InvokeAsync(StateHasChanged);
await JS.InvokeVoidAsync("removeElementById", "statusLoading");
}
private async void StateChanged(object? sender, PropertyChangedEventArgs e) {
if (e.PropertyName == nameof(State.IsRefreshing) && State.IsRefreshing) {
statuses = await StatusFunc(true);
State.IsRefreshing = false;
}
}
public void Dispose() {
State.PropertyChanged -= StateChanged;
State.CanRefresh = false;
}
}

View file

@ -1,4 +1,5 @@
@using System.Net.Http
@using System.ComponentModel
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing

View file

@ -1,8 +1,9 @@
using Microsoft.AspNetCore.Components;
using System.ComponentModel;
using System.Text.Json;
namespace Neighbourhood.omg.lol.Models {
public class State {
public class State : INotifyPropertyChanged {
// Main data lists
public List<Status>? Statuses { get; set; }
public List<Pic>? Pics { get; set; }
@ -57,7 +58,25 @@ namespace Neighbourhood.omg.lol.Models {
}
}
// refreshing
public event PropertyChangedEventHandler? PropertyChanged;
private bool _isRefreshing;
public bool IsRefreshing {
get => _isRefreshing;
set {
_isRefreshing = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRefreshing)));
}
}
private bool _canRefresh;
public bool CanRefresh {
get => _canRefresh;
set {
_canRefresh = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CanRefresh)));
}
}
// api service
private RestService api { get; set; }