Represented user details better, refresh on log in
This commit is contained in:
parent
5fb95c8305
commit
4fa8440e1f
10 changed files with 256 additions and 67 deletions
|
@ -1,9 +1,12 @@
|
|||
namespace Neighbourhood.omg.lol {
|
||||
public partial class App : Application {
|
||||
public App() {
|
||||
public App(NavigatorService navigatorService) {
|
||||
InitializeComponent();
|
||||
|
||||
MainPage = new AppShell();
|
||||
NavigatorService = navigatorService;
|
||||
}
|
||||
|
||||
internal NavigatorService NavigatorService { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
@inherits LayoutComponentBase
|
||||
@inject NavigatorService NavigatorService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject State State
|
||||
<link rel="stylesheet" href="vendor/fluent-emoji/animated.css" />
|
||||
<NavMenu />
|
||||
<main class="responsive max">
|
||||
@Body
|
||||
</main>
|
||||
|
||||
@code {
|
||||
protected override void OnInitialized() {
|
||||
base.OnInitialized();
|
||||
NavigatorService.NavigationManager = NavigationManager;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,46 @@
|
|||
@inject CustomAuthenticationStateProvider AuthStateProvider;
|
||||
@inject State State;
|
||||
<nav class="left drawer l">
|
||||
<header>
|
||||
<nav>
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<img class="circle medium" src="https://profiles.cache.lol/@FirstAddress/picture" alt="@FirstAddress" />
|
||||
<div>Hey, @Name.</div>
|
||||
|
||||
<button class="transparent circle large">
|
||||
<img class="responsive" src="https://profiles.cache.lol/@State.SelectedAddressName/picture" alt="@State.SelectedAddressName">
|
||||
<menu class="no-wrap">
|
||||
@foreach (AddressResponseData address in State.AddressList ?? new List<AddressResponseData>()) {
|
||||
<a class="row @(address == State.SelectedAddress ? "active" : "")" @onclick="() => changeAddress(address)">
|
||||
<img class="tiny circle" src="https://profiles.cache.lol/@address.Address/picture" alt="@address.Address" />
|
||||
<span class="address"><i class="fa-solid fa-fw fa-at tiny"></i>@address.Address</span>
|
||||
</a>
|
||||
}
|
||||
<a class="row" @onclick='() => AuthStateProvider.Logout()'>
|
||||
<i class="fa-solid fa-door-open"></i>
|
||||
<span>Logout</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
<div>
|
||||
Hey, @State.Name. <br />
|
||||
<span class="address"><i class="fa-solid fa-fw fa-at tiny"></i>@State.SelectedAddressName</span>
|
||||
</div>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<img src="https://cdn.cache.lol/img/prami.svg" class="medium">
|
||||
<button class="transparent circle large">
|
||||
<img class="responsive" src="https://cdn.cache.lol/img/prami.svg">
|
||||
<menu class="no-wrap">
|
||||
<a class="row" href="/login">
|
||||
<i class="fa-solid fa-door-closed"></i>
|
||||
<span>Login</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
<div>
|
||||
Hey there. <br/>
|
||||
Hey there. <br />
|
||||
<a href="/login">Login?</a>
|
||||
</div>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
|
||||
</nav>
|
||||
</header>
|
||||
<NavLink class="row nav-link" href="" Match="NavLinkMatch.All">
|
||||
|
@ -27,51 +51,114 @@
|
|||
<i><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><path fill="#4dabf7" d="M250 450c-38.388 0-76.775-14.646-106.066-43.934l-100-100c-58.579-58.58-58.579-153.553 0-212.132C100.534 37.336 191.105 35.421 250 88.191c58.898-52.768 149.47-50.853 206.066 5.743 58.58 58.58 58.58 153.553 0 212.132l-100 100C326.778 435.354 288.39 450 250 450" /><path fill="#228be6" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" stroke="#461036" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /><path fill="#1971c2" d="M438.68 212.011c0-32.564-26.399-58.962-58.963-58.962s-58.962 26.398-58.962 58.962 26.398 58.963 58.962 58.963 58.962-26.399 58.962-58.963m-259.433 0c0-32.564-26.398-58.962-58.962-58.962S61.32 179.447 61.32 212.011s26.398 58.963 58.963 58.963 58.962-26.399 58.962-58.963" /><path fill="#4dabf7" stroke="#1864ab" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /></svg></i>
|
||||
<div>Statuslog</div>
|
||||
</NavLink>
|
||||
<div class="row max"></div>
|
||||
<footer>
|
||||
<AuthorizeView>
|
||||
<Authorized><a class="button small" @onclick='() => AuthStateProvider.Logout()'>Logout</a></Authorized>
|
||||
<NotAuthorized><a class="button small" href="/login">Login</a></NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</footer>
|
||||
</nav>
|
||||
|
||||
<nav class="left m">
|
||||
<header>
|
||||
<img src="https://cdn.cache.lol/img/prami.svg" class="circle">
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<button class="transparent circle">
|
||||
<img class="responsive" src="https://profiles.cache.lol/@State.SelectedAddressName/picture" alt="@State.SelectedAddressName">
|
||||
<menu class="no-wrap">
|
||||
<a class="row">
|
||||
<img class="tiny" data-emoji="👋">
|
||||
<span>Hey, @State.Name.</span>
|
||||
</a>
|
||||
@foreach (AddressResponseData address in State.AddressList ?? new List<AddressResponseData>()) {
|
||||
<a class="row @(address == State.SelectedAddress ? "active" : "")" @onclick="() => changeAddress(address)">
|
||||
<img class="tiny circle" src="https://profiles.cache.lol/@address.Address/picture" alt="@address.Address">
|
||||
<span class="address"><i class="fa-solid fa-fw fa-at tiny"></i>@address.Address</span>
|
||||
</a>
|
||||
}
|
||||
<a class="row" @onclick='() => AuthStateProvider.Logout()'>
|
||||
<i class="fa-solid fa-door-open"></i>
|
||||
<span>Logout</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<button class="transparent circle">
|
||||
<img class="responsive" src="https://cdn.cache.lol/img/prami.svg">
|
||||
<menu class="no-wrap">
|
||||
<a class="row">
|
||||
<i class="medium" data-emoji="👋"></i>
|
||||
<span>Hey there.</span>
|
||||
</a>
|
||||
<a class="row" href="/login">
|
||||
<i class="fa-solid fa-door-closed"></i>
|
||||
<span>Login</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</header>
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<i class="fa-solid fa-fw fa-home"></i>
|
||||
<div>Home</div>
|
||||
<small>Home</small>
|
||||
</NavLink>
|
||||
<NavLink class="nav-link" href="/statuslog/latest">
|
||||
<i><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><path fill="#4dabf7" d="M250 450c-38.388 0-76.775-14.646-106.066-43.934l-100-100c-58.579-58.58-58.579-153.553 0-212.132C100.534 37.336 191.105 35.421 250 88.191c58.898-52.768 149.47-50.853 206.066 5.743 58.58 58.58 58.58 153.553 0 212.132l-100 100C326.778 435.354 288.39 450 250 450" /><path fill="#228be6" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" stroke="#461036" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /><path fill="#1971c2" d="M438.68 212.011c0-32.564-26.399-58.962-58.963-58.962s-58.962 26.398-58.962 58.962 26.398 58.963 58.962 58.963 58.962-26.399 58.962-58.963m-259.433 0c0-32.564-26.398-58.962-58.962-58.962S61.32 179.447 61.32 212.011s26.398 58.963 58.963 58.963 58.962-26.399 58.962-58.963" /><path fill="#4dabf7" stroke="#1864ab" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /></svg></i>
|
||||
<div>Statuslog</div>
|
||||
<small>Statuslog</small>
|
||||
</NavLink>
|
||||
</nav>
|
||||
|
||||
<nav class="bottom s">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<i class="fa-solid fa-fw fa-home"></i>
|
||||
<div>Home</div>
|
||||
<small>Home</small>
|
||||
</NavLink>
|
||||
<NavLink class="nav-link" href="/statuslog/latest">
|
||||
<i><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><path fill="#4dabf7" d="M250 450c-38.388 0-76.775-14.646-106.066-43.934l-100-100c-58.579-58.58-58.579-153.553 0-212.132C100.534 37.336 191.105 35.421 250 88.191c58.898-52.768 149.47-50.853 206.066 5.743 58.58 58.58 58.58 153.553 0 212.132l-100 100C326.778 435.354 288.39 450 250 450" /><path fill="#228be6" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M220.52 176.634a11.792 11.792 0 1 1-23.586 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0" /><path fill="#1864ab" stroke="#1864ab" stroke-miterlimit="10" stroke-width="11.32074" d="M303.066 176.634a11.792 11.792 0 1 1-23.585 0 11.792 11.792 0 0 1 23.585 0Z" /><path fill="#228be6" stroke="#461036" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /><path fill="#1971c2" d="M438.68 212.011c0-32.564-26.399-58.962-58.963-58.962s-58.962 26.398-58.962 58.962 26.398 58.963 58.962 58.963 58.962-26.399 58.962-58.963m-259.433 0c0-32.564-26.398-58.962-58.962-58.962S61.32 179.447 61.32 212.011s26.398 58.963 58.963 58.963 58.962-26.399 58.962-58.963" /><path fill="#4dabf7" stroke="#1864ab" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="18.8679" d="M208.75 223.817c18.875 30.802 63.626 30.802 82.501 0" /></svg></i>
|
||||
<div>Statuslog</div>
|
||||
<small>Statuslog</small>
|
||||
</NavLink>
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<NavLink>
|
||||
<button class="transparent circle small">
|
||||
<img class="responsive" src="https://profiles.cache.lol/@State.SelectedAddressName/picture" alt="@State.SelectedAddressName">
|
||||
<menu>
|
||||
<a class="row">
|
||||
<img class="tiny" data-emoji="👋">
|
||||
<span>Hey, @State.Name.</span>
|
||||
</a>
|
||||
@foreach (AddressResponseData address in State.AddressList ?? new List<AddressResponseData>()) {
|
||||
<a class="row @(address == State.SelectedAddress ? "active" : "")" @onclick="() => changeAddress(address)">
|
||||
<img class="tiny circle" src="https://profiles.cache.lol/@address.Address/picture" alt="@address.Address">
|
||||
<span class="address"><i class="fa-solid fa-fw fa-at tiny"></i>@address.Address</span>
|
||||
</a>
|
||||
}
|
||||
<a class="row" @onclick='() => AuthStateProvider.Logout()'>
|
||||
<i class="fa-solid fa-door-open"></i>
|
||||
<span>Logout</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
<small class="address"><i class="fa-solid fa-fw fa-at tiny"></i>@State.SelectedAddressName</small>
|
||||
</NavLink>
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<button class="transparent circle">
|
||||
<img class="responsive" src="https://cdn.cache.lol/img/prami.svg">
|
||||
<menu>
|
||||
<a class="row">
|
||||
<i class="medium" data-emoji="👋"></i>
|
||||
<span>Hey there.</span>
|
||||
</a>
|
||||
<a class="row" href="/login">
|
||||
<i class="fa-solid fa-door-closed"></i>
|
||||
<span>Login</span>
|
||||
</a>
|
||||
</menu>
|
||||
</button>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</nav>
|
||||
|
||||
@code {
|
||||
private string? Name = null;
|
||||
private List<string> Addresses = new List<string>();
|
||||
private string FirstAddress { get => this.Addresses.FirstOrDefault() ?? string.Empty; }
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
var state = await AuthStateProvider.GetAuthenticationStateAsync();
|
||||
var identity = state.User.Identity;
|
||||
|
||||
Name = identity?.Name ?? string.Empty;
|
||||
Addresses = state.User.FindFirst("addresses")?.Value?.Split(',')?.ToList() ?? new List<string>();
|
||||
public void changeAddress(AddressResponseData address) {
|
||||
State.SelectedAddress = address;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Neighbourhood.omg.lol.Models;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Neighbourhood.omg.lol {
|
||||
public class CustomAuthenticationStateProvider : AuthenticationStateProvider {
|
||||
public CustomAuthenticationStateProvider() {
|
||||
private State State;
|
||||
public CustomAuthenticationStateProvider(State _state) {
|
||||
this.State = _state;
|
||||
}
|
||||
|
||||
public async Task Login(string token) {
|
||||
|
@ -14,7 +18,8 @@ namespace Neighbourhood.omg.lol {
|
|||
|
||||
public async Task Logout() {
|
||||
SecureStorage.Remove("accounttoken");
|
||||
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
|
||||
Preferences.Default.Clear();
|
||||
NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
|
||||
}
|
||||
|
||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync() {
|
||||
|
@ -22,39 +27,12 @@ namespace Neighbourhood.omg.lol {
|
|||
try {
|
||||
var token = await SecureStorage.GetAsync("accounttoken");
|
||||
if (token != null) {
|
||||
var name = await SecureStorage.GetAsync("accountname");
|
||||
var email = await SecureStorage.GetAsync("accountemail");
|
||||
var addresses = await SecureStorage.GetAsync("accountaddresses");
|
||||
await State.PopulateAccountDetails(token);
|
||||
|
||||
RestService api = new RestService(token);
|
||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(email)) {
|
||||
AccountResponseData? accountInfo = await api.AccountInfo();
|
||||
if (accountInfo != null) {
|
||||
name = accountInfo.Name;
|
||||
email = accountInfo.Email;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(email)) {
|
||||
if (string.IsNullOrEmpty(addresses)) {
|
||||
AddressResponseList? addressList = await api.Addresses();
|
||||
List<string> addressStrings = new List<string>();
|
||||
if (addressList != null) foreach (var address in addressList) {
|
||||
if (!address.Expiration.Expired && !string.IsNullOrEmpty(address.Address)) {
|
||||
addressStrings.Add(address.Address);
|
||||
}
|
||||
}
|
||||
addresses = string.Join(',', addressStrings);
|
||||
}
|
||||
if(!string.IsNullOrEmpty(addresses)) {
|
||||
await SecureStorage.SetAsync("accountname", name);
|
||||
await SecureStorage.SetAsync("accountemail", email);
|
||||
await SecureStorage.SetAsync("accountaddresses", addresses);
|
||||
}
|
||||
|
||||
var claims = new[] {
|
||||
new Claim(ClaimTypes.Name, name),
|
||||
new Claim(ClaimTypes.Email, email),
|
||||
new Claim("addresses", addresses)
|
||||
if(State.AccountInfo != null) {
|
||||
List<Claim> claims = new List<Claim> {
|
||||
new Claim(ClaimTypes.Name, State.AccountInfo.Name),
|
||||
new Claim(ClaimTypes.Email, State.AccountInfo.Email)
|
||||
};
|
||||
identity = new ClaimsIdentity(claims, "Server authentication");
|
||||
}
|
||||
|
|
|
@ -8,10 +8,12 @@ namespace Neighbourhood.omg.lol;
|
|||
public partial class LoginWebViewPage : ContentPage
|
||||
{
|
||||
private AuthenticationStateProvider AuthStateProvider { get; set; }
|
||||
private NavigatorService NavigatorService { get; set; }
|
||||
|
||||
public LoginWebViewPage(AuthenticationStateProvider authStateProvider)
|
||||
public LoginWebViewPage(AuthenticationStateProvider authStateProvider, NavigatorService navigatorService)
|
||||
{
|
||||
this.AuthStateProvider = authStateProvider;
|
||||
this.NavigatorService = navigatorService;
|
||||
InitializeComponent();
|
||||
this.loginwebview.Source = "https://home.omg.lol/oauth/authorize?client_id=ea14dafd3e92cbcf93750c35cd81a031&scope=everything&redirect_uri=https://neatnik.net/adam/bucket/omgloloauth/&response_type=code";
|
||||
|
||||
|
@ -29,6 +31,7 @@ public partial class LoginWebViewPage : ContentPage
|
|||
if (!string.IsNullOrEmpty(token)) {
|
||||
Debug.WriteLine($"Fuck yeah, a token! {token}");
|
||||
await ((CustomAuthenticationStateProvider)this.AuthStateProvider).Login(token);
|
||||
NavigatorService.NavigationManager.NavigateTo(NavigatorService.NavigationManager.Uri, forceLoad: true);
|
||||
await Shell.Current.GoToAsync("..");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
using Microsoft.AspNetCore.Components.WebView;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.WebView;
|
||||
using Microsoft.AspNetCore.Components.WebView.Maui;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Neighbourhood.omg.lol {
|
||||
public partial class MainPage : ContentPage {
|
||||
|
||||
public MainPage() {
|
||||
InitializeComponent();
|
||||
}
|
||||
|
@ -13,5 +16,10 @@ namespace Neighbourhood.omg.lol {
|
|||
Shell.Current.GoToAsync(nameof(LoginWebViewPage));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAppearing() {
|
||||
base.OnAppearing();
|
||||
Debug.WriteLine("And now you're back. From outer space.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Neighbourhood.omg.lol.Models;
|
||||
|
||||
namespace Neighbourhood.omg.lol {
|
||||
public static class MauiProgram {
|
||||
|
@ -14,6 +15,9 @@ namespace Neighbourhood.omg.lol {
|
|||
builder.Services.AddMauiBlazorWebView();
|
||||
builder.Services.AddTransient<LoginWebViewPage>();
|
||||
|
||||
builder.Services.AddSingleton<State>();
|
||||
builder.Services.AddSingleton<NavigatorService>();
|
||||
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddScoped<CustomAuthenticationStateProvider>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<CustomAuthenticationStateProvider>());
|
||||
|
|
49
Models/State.cs
Normal file
49
Models/State.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Neighbourhood.omg.lol.Models {
|
||||
public class State {
|
||||
public AccountResponseData? AccountInfo { get; set; }
|
||||
public AddressResponseList? AddressList { get; set; }
|
||||
|
||||
public string? Name { get => AccountInfo?.Name; }
|
||||
public string? Email { get => AccountInfo?.Email; }
|
||||
public IEnumerable<string>? AddressNames { get => AddressList?.Select(a => a.Address); }
|
||||
public AddressResponseData? SelectedAddress { get; set; }
|
||||
public string? SelectedAddressName { get => SelectedAddress?.Address; }
|
||||
|
||||
public async Task PopulateAccountDetails(string token) {
|
||||
RestService api = new RestService(token);
|
||||
|
||||
string accountJson = Preferences.Default.Get("accountdetails", string.Empty);
|
||||
string addressJson = Preferences.Default.Get("accountaddresses", string.Empty);
|
||||
string selectedAddressJson = Preferences.Default.Get("selectedaddress", string.Empty);
|
||||
|
||||
if (!string.IsNullOrEmpty(accountJson)) AccountInfo = JsonSerializer.Deserialize<AccountResponseData>(accountJson);
|
||||
if (!string.IsNullOrEmpty(addressJson)) AddressList = JsonSerializer.Deserialize<AddressResponseList>(addressJson);
|
||||
if (!string.IsNullOrEmpty(selectedAddressJson)) SelectedAddress = JsonSerializer.Deserialize<AddressResponseData>(selectedAddressJson);
|
||||
|
||||
// if we haven't got account info, attempt to retrieve it.
|
||||
if (AccountInfo == null) {
|
||||
AccountInfo = await api.AccountInfo();
|
||||
if (AccountInfo != null) {
|
||||
Preferences.Default.Set("accountdetails", JsonSerializer.Serialize(AccountInfo));
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have the list of addresses, attempt to retrieve that.
|
||||
if (AddressList == null) {
|
||||
AddressList = await api.Addresses();
|
||||
if (AddressList != null) {
|
||||
Preferences.Default.Set("accountaddresses", JsonSerializer.Serialize(AddressList));
|
||||
SelectedAddress = AddressList.FirstOrDefault();
|
||||
Preferences.Default.Set("selectedaddress", JsonSerializer.Serialize(SelectedAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
NavigatorService.cs
Normal file
12
NavigatorService.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Neighbourhood.omg.lol {
|
||||
public class NavigatorService {
|
||||
internal NavigationManager NavigationManager { get; set; }
|
||||
}
|
||||
}
|
|
@ -32,8 +32,10 @@ p, li {
|
|||
line-height: 160%;
|
||||
}
|
||||
|
||||
.author {
|
||||
.author, .address {
|
||||
font-family: 'VC Honey Deck', var(--font);
|
||||
}
|
||||
.author {
|
||||
color: inherit;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
@ -102,3 +104,36 @@ main {
|
|||
flex:1 1 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
nav header {
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
:is(button,.button).tiny {
|
||||
block-size: 1.5rem;
|
||||
/*max-inline-size: 1.5rem;*/
|
||||
font-size: .875rem;
|
||||
border-radius: .75rem;
|
||||
}
|
||||
|
||||
nav.bottom.s:not(.drawer) > a:not(.button,.chip) {
|
||||
inline-size: unset;
|
||||
}
|
||||
|
||||
nav.bottom.s:not(.drawer) :is(button,.button) > menu {
|
||||
position: fixed;
|
||||
margin-top:auto;
|
||||
margin-bottom: 5rem;
|
||||
margin-left:auto;
|
||||
margin-right:0;
|
||||
inline-size: auto;
|
||||
min-inline-size: 12rem;
|
||||
z-index: 100;
|
||||
transform: none !important;
|
||||
inset: auto 0 0 auto;
|
||||
}
|
||||
|
||||
i[class*=fa-at] {
|
||||
vertical-align:unset;
|
||||
font-size: .75em;
|
||||
}
|
Loading…
Reference in a new issue