Add BasicComponent, BasicLayout and AppState

This commit is contained in:
Ivan Yaremenchuk 2022-08-26 13:13:40 -05:00
parent c131eccf65
commit 89c5536610
13 changed files with 192 additions and 80 deletions

View File

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Components;
using NftFaucetRadzen.Models;
using NftFaucetRadzen.Options;
namespace NftFaucetRadzen.Components;
public abstract class BasicComponent : ComponentBase
{
[Inject]
protected NavigationManager UriHelper { get; set; }
[Inject]
protected ScopedAppState AppState { get; set; }
[Inject]
protected RefreshMediator RefreshMediator { get; set; }
[Inject]
protected Settings Settings { get; set; }
protected override void OnInitialized()
{
RefreshMediator.StateChanged += async () => await InvokeAsync(StateHasChangedSafe);
}
protected void StateHasChangedSafe()
{
try
{
InvokeAsync(StateHasChanged);
}
catch (Exception)
{
// ignored
}
}
}

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Components;
using NftFaucetRadzen.Models;
namespace NftFaucetRadzen.Components;
public abstract class BasicLayout : LayoutComponentBase
{
[Inject]
protected NavigationManager UriHelper { get; set; }
[Inject]
protected ScopedAppState AppState { get; set; }
[Inject]
protected RefreshMediator RefreshMediator { get; set; }
protected override void OnInitialized()
{
RefreshMediator.StateChanged += async () => await InvokeAsync(StateHasChangedSafe);
}
protected void StateHasChangedSafe()
{
try
{
InvokeAsync(StateHasChanged);
}
catch (Exception)
{
// ignored
}
}
}

View File

@ -1,4 +1,5 @@
@using NftFaucetRadzen.Models @using NftFaucetRadzen.Models
@inherits BasicComponent
<RadzenDataList WrapItems="true" Data="@Data" TItem="CardListItem" > <RadzenDataList WrapItems="true" Data="@Data" TItem="CardListItem" >
<Template Context="cardListItem"> <Template Context="cardListItem">

View File

@ -3,7 +3,7 @@ using NftFaucetRadzen.Models;
namespace NftFaucetRadzen.Components; namespace NftFaucetRadzen.Components;
public partial class CardList public partial class CardList : BasicComponent
{ {
[Parameter] public CardListItem[] Data { get; set; } [Parameter] public CardListItem[] Data { get; set; }
[Parameter] public CardListItem[] SelectedItems { get; set; } [Parameter] public CardListItem[] SelectedItems { get; set; }
@ -34,6 +34,6 @@ public partial class CardList
} }
SelectedItems = selectedItems.ToArray(); SelectedItems = selectedItems.ToArray();
await SelectedItemsChanged.InvokeAsync(SelectedItems); await SelectedItemsChanged.InvokeAsync(SelectedItems);
StateHasChanged(); RefreshMediator.NotifyStateHasChangedSafe();
} }
} }

View File

@ -0,0 +1,19 @@
namespace NftFaucetRadzen.Models;
public class RefreshMediator
{
public delegate void StateChangedDelegate();
public event StateChangedDelegate StateChanged;
public void NotifyStateHasChangedSafe()
{
try
{
StateChanged?.Invoke();
}
catch (Exception)
{
// ignored
}
}
}

View File

@ -0,0 +1,11 @@
namespace NftFaucetRadzen.Models;
public class ScopedAppState
{
public StateStorage Storage { get; private set; } = new();
public void Reset()
{
Storage = new StateStorage();
}
}

View File

@ -0,0 +1,6 @@
namespace NftFaucetRadzen.Models;
public class StateStorage
{
public CardListItem[] SelectedNetworks { get; set; }
}

View File

@ -1,4 +1,5 @@
@page "/network" @page "/network"
@inherits BasicComponent
<PageTitle>Network</PageTitle> <PageTitle>Network</PageTitle>
<RadzenContent Container="main"> <RadzenContent Container="main">
@ -6,30 +7,29 @@
<RadzenTabs RenderMode="TabRenderMode.Client"> <RadzenTabs RenderMode="TabRenderMode.Client">
<Tabs> <Tabs>
<RadzenTabsItem Text="Ethereum"> <RadzenTabsItem Text="Ethereum">
<CardList Data="@EthereumNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@EthereumNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Polygon"> <RadzenTabsItem Text="Polygon">
<CardList Data="@PolygonNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@PolygonNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Bsc"> <RadzenTabsItem Text="Bsc">
<CardList Data="@BscNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@BscNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Optimism"> <RadzenTabsItem Text="Optimism">
<CardList Data="@OptimismNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@OptimismNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Moonbase"> <RadzenTabsItem Text="Moonbase">
<CardList Data="@MoonbaseNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@MoonbaseNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Arbitrum"> <RadzenTabsItem Text="Arbitrum">
<CardList Data="@ArbitrumNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@ArbitrumNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Avalanche"> <RadzenTabsItem Text="Avalanche">
<CardList Data="@AvalancheNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@AvalancheNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
<RadzenTabsItem Text="Solana"> <RadzenTabsItem Text="Solana">
<CardList Data="@SolanaNetworks" @bind-SelectedItems="@SelectedNetworks" /> <CardList Data="@SolanaNetworks" @bind-SelectedItems="@AppState.Storage.SelectedNetworks" />
</RadzenTabsItem> </RadzenTabsItem>
</Tabs> </Tabs>
</RadzenTabs> </RadzenTabs>
</RadzenContent> </RadzenContent>

View File

@ -1,75 +1,66 @@
using Microsoft.JSInterop; using Microsoft.JSInterop;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using NftFaucetRadzen.Components;
using NftFaucetRadzen.Models; using NftFaucetRadzen.Models;
using NftFaucetRadzen.Models.Enums; using NftFaucetRadzen.Models.Enums;
using NftFaucetRadzen.Options;
using Radzen; using Radzen;
namespace NftFaucetRadzen.Pages namespace NftFaucetRadzen.Pages;
public partial class Network : BasicComponent
{ {
public partial class Network [Inject]
protected IJSRuntime JSRuntime { get; set; }
[Inject]
protected DialogService DialogService { get; set; }
[Inject]
protected TooltipService TooltipService { get; set; }
[Inject]
protected ContextMenuService ContextMenuService { get; set; }
[Inject]
protected NotificationService NotificationService { get; set; }
protected override void OnInitialized()
{ {
[Inject] EthereumNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Ethereum).Select(MapCardListItem).ToArray();
protected IJSRuntime JSRuntime { get; set; } PolygonNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Polygon).Select(MapCardListItem).ToArray();
BscNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Bsc).Select(MapCardListItem).ToArray();
[Inject] OptimismNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Optimism).Select(MapCardListItem).ToArray();
protected NavigationManager NavigationManager { get; set; } MoonbaseNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Moonbase).Select(MapCardListItem).ToArray();
ArbitrumNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Arbitrum).Select(MapCardListItem).ToArray();
[Inject] AvalancheNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Avalanche).Select(MapCardListItem).ToArray();
protected DialogService DialogService { get; set; } SolanaNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Solana).Select(MapCardListItem).ToArray();
[Inject]
protected TooltipService TooltipService { get; set; }
[Inject]
protected ContextMenuService ContextMenuService { get; set; }
[Inject]
protected NotificationService NotificationService { get; set; }
[Inject]
protected Settings Settings { get; set; }
protected override void OnInitialized()
{
EthereumNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Ethereum).Select(MapCardListItem).ToArray();
PolygonNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Polygon).Select(MapCardListItem).ToArray();
BscNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Bsc).Select(MapCardListItem).ToArray();
OptimismNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Optimism).Select(MapCardListItem).ToArray();
MoonbaseNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Moonbase).Select(MapCardListItem).ToArray();
ArbitrumNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Arbitrum).Select(MapCardListItem).ToArray();
AvalancheNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Avalanche).Select(MapCardListItem).ToArray();
SolanaNetworks = Settings.Networks.Where(x => x.Type == NetworkType.Solana).Select(MapCardListItem).ToArray();
}
protected CardListItem[] EthereumNetworks { get; private set; }
protected CardListItem[] PolygonNetworks { get; private set; }
protected CardListItem[] BscNetworks { get; private set; }
protected CardListItem[] OptimismNetworks { get; private set; }
protected CardListItem[] MoonbaseNetworks { get; private set; }
protected CardListItem[] ArbitrumNetworks { get; private set; }
protected CardListItem[] AvalancheNetworks { get; private set; }
protected CardListItem[] SolanaNetworks { get; private set; }
public CardListItem[] SelectedNetworks { get; set; }
private static CardListItem MapCardListItem(NetworkModel model)
=> new CardListItem
{
ImageName = model.ImageName,
Header = model.Name,
IsDisabled = !model.IsSupported,
Properties = new[]
{
new CardListItemProperty { Name = "ChainID", Value = model.ChainId?.ToString() },
new CardListItemProperty { Name = "Currency", Value = model.Currency },
},
Badges = new[]
{
!model.IsSupported ? new CardListItemBadge { Style = BadgeStyle.Light, Text = "Not Supported" } : null,
!model.IsTestnet ? new CardListItemBadge { Style = BadgeStyle.Danger, Text = "Mainnet" } : null,
model.IsDeprecated ? new CardListItemBadge { Style = BadgeStyle.Warning, Text = "Deprecated" } : null,
}.Where(x => x != null).ToArray(),
};
} }
protected CardListItem[] EthereumNetworks { get; private set; }
protected CardListItem[] PolygonNetworks { get; private set; }
protected CardListItem[] BscNetworks { get; private set; }
protected CardListItem[] OptimismNetworks { get; private set; }
protected CardListItem[] MoonbaseNetworks { get; private set; }
protected CardListItem[] ArbitrumNetworks { get; private set; }
protected CardListItem[] AvalancheNetworks { get; private set; }
protected CardListItem[] SolanaNetworks { get; private set; }
private static CardListItem MapCardListItem(NetworkModel model)
=> new CardListItem
{
ImageName = model.ImageName,
Header = model.Name,
IsDisabled = !model.IsSupported,
Properties = new[]
{
new CardListItemProperty { Name = "ChainID", Value = model.ChainId?.ToString() },
new CardListItemProperty { Name = "Currency", Value = model.Currency },
},
Badges = new[]
{
!model.IsSupported ? new CardListItemBadge { Style = BadgeStyle.Light, Text = "Not Supported" } : null,
!model.IsTestnet ? new CardListItemBadge { Style = BadgeStyle.Danger, Text = "Mainnet" } : null,
model.IsDeprecated ? new CardListItemBadge { Style = BadgeStyle.Warning, Text = "Deprecated" } : null,
}.Where(x => x != null).ToArray(),
};
} }

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using NftFaucetRadzen; using NftFaucetRadzen;
using NftFaucetRadzen.Models;
using NftFaucetRadzen.Options; using NftFaucetRadzen.Options;
using Radzen; using Radzen;
@ -14,7 +15,8 @@ builder.Configuration.Bind(settings);
builder.Services.AddSingleton(settings); builder.Services.AddSingleton(settings);
builder.Services.AddScoped(sp => new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)}); builder.Services.AddScoped(sp => new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)});
builder.Services.AddScoped<ScopedAppState>();
builder.Services.AddScoped<RefreshMediator>();
builder.Services.AddScoped<DialogService>(); builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>(); builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>(); builder.Services.AddScoped<TooltipService>();

View File

@ -1,4 +1,4 @@
@inherits LayoutComponentBase @inherits BasicLayout
<div class="page"> <div class="page">
<div class="sidebar"> <div class="sidebar">

View File

@ -1,4 +1,6 @@
<div class="top-row ps-3 navbar navbar-dark"> @inherits BasicComponent
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" href="">NftFaucetRadzen</a> <a class="navbar-brand" href="">NftFaucetRadzen</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
@ -11,7 +13,7 @@
<nav class="flex-column"> <nav class="flex-column">
<div class="nav-item px-3"> <div class="nav-item px-3">
<NavLink class="nav-link" href="network"> <NavLink class="nav-link" href="network">
<span class="oi oi-wifi" aria-hidden="true"></span> Network <span class="oi oi-wifi" aria-hidden="true"></span> @("Network" + (SelectedNetworkName != null ? $" ({SelectedNetworkName})" : string.Empty))
</NavLink> </NavLink>
</div> </div>
<div class="nav-item px-3"> <div class="nav-item px-3">

View File

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Components;
using NftFaucetRadzen.Components;
using NftFaucetRadzen.Models;
namespace NftFaucetRadzen.Shared;
public partial class NavMenu : BasicComponent
{
protected string SelectedNetworkName => AppState.Storage.SelectedNetworks?.FirstOrDefault()?.Header;
}