Neighbourhood.omg.lol/Models/State.cs

199 lines
8.6 KiB
C#

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
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 List<Status>? Statuses { get; set; }
public List<Pic>? Pics { get; set; }
public List<NowData>? NowGarden { get; set; }
public List<Status>? CachedAddressStatuses { get; set; }
public List<Pic>? CachedAddressPics { get; set; }
public MarkupString? CachedAddressBio { get; set; }
private string? _cachedAddress;
public string? CachedAddress {
get => _cachedAddress;
set {
if (_cachedAddress != value) {
_cachedAddress = value;
CachedAddressStatuses = new List<Status>();
CachedAddressPics = new List<Pic>();
CachedAddressBio = null;
}
}
}
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));
}
}
}
public async Task RemoveAccountDetails() {
Preferences.Default.Clear();
AccountInfo = null;
AddressList = null;
SelectedAddress = null;
}
public async Task<MarkupString?> GetBio(string address, bool forceRefresh = false) {
CachedAddress = address;
if (forceRefresh || CachedAddressBio == null) {
RestService api = new RestService();
CachedAddressBio = await api.StatuslogBio(address);
}
return CachedAddressBio;
}
public async Task<List<Status>?> GetStatuses(bool forceRefresh = false) {
RestService api = new RestService();
if (forceRefresh || this.Statuses == null || this.Statuses.Count == 0) {
this.Statuses = await api.StatuslogLatest();
}
return this.Statuses;
}
public async ValueTask<ItemsProviderResult<Status>> VirtualStatuses(ItemsProviderRequest request) {
// TODO: request.cancellationToken
var statuses = (await this.GetStatuses()) ?? new List<Status>();
var numStatuses = Math.Min(request.Count, statuses.Count - request.StartIndex);
return new ItemsProviderResult<Status>(statuses.Skip(request.StartIndex).Take(numStatuses), statuses.Count);
}
public async ValueTask<ItemsProviderResult<Status>> VirtualStatuses(ItemsProviderRequest request, string address) {
// TODO: request.cancellationToken
RestService api = new RestService();
CachedAddressStatuses = (await api.Statuslog(address)) ?? new List<Status>();
var numStatuses = Math.Min(request.Count, CachedAddressStatuses.Count - request.StartIndex);
return new ItemsProviderResult<Status>(CachedAddressStatuses.Skip(request.StartIndex).Take(numStatuses), CachedAddressStatuses.Count);
}
public Func<ItemsProviderRequest, ValueTask<ItemsProviderResult<Status>>> VirtualStatusesFunc(string? address = null) {
if (address == null) return VirtualStatuses;
else {
CachedAddress = address;
return async (ItemsProviderRequest request) => await VirtualStatuses(request, CachedAddress);
}
}
public async Task<List<NowData>?> GetNowGarden(bool forceRefresh = false) {
RestService api = new RestService();
if (forceRefresh || this.NowGarden == null || this.NowGarden.Count == 0) {
this.NowGarden = await api.NowGarden();
}
return this.NowGarden;
}
public async ValueTask<ItemsProviderResult<NowData>> VirtualNowGarden(ItemsProviderRequest request) {
// TODO: request.cancellationToken
var garden = (await this.GetNowGarden()) ?? new List<NowData>();
var numSeedlings = Math.Min(request.Count, garden.Count - request.StartIndex);
return new ItemsProviderResult<NowData>(garden.Skip(request.StartIndex).Take(numSeedlings), garden.Count);
}
public Func<ItemsProviderRequest, ValueTask<ItemsProviderResult<NowData>>> VirtualNowGardenFunc() {
return VirtualNowGarden;
}
public async Task<List<Pic>?> GetPics(bool forceRefresh = false) {
if(forceRefresh || this.Pics == null || this.Pics.Count == 0) {
RestService api = new RestService();
this.Pics = await api.SomePics();
}
return this.Pics;
}
public async ValueTask<ItemsProviderResult<Pic>> VirtualPics(ItemsProviderRequest request) {
// TODO: request.cancellationToken
var pics = (await this.GetPics()) ?? new List<Pic>();
var numPics = Math.Min(request.Count, pics.Count - request.StartIndex);
return new ItemsProviderResult<Pic>(pics.Skip(request.StartIndex).Take(numPics), pics.Count);
}
public async ValueTask<ItemsProviderResult<Pic>> VirtualPics(ItemsProviderRequest request, string address) {
// TODO: request.cancellationToken
RestService api = new RestService();
CachedAddressPics = (await api.SomePics(address)) ?? new List<Pic>();
var numPics = Math.Min(request.Count, CachedAddressPics.Count - request.StartIndex);
return new ItemsProviderResult<Pic>(CachedAddressPics.Skip(request.StartIndex).Take(numPics), CachedAddressPics.Count);
}
public Func<ItemsProviderRequest, ValueTask<ItemsProviderResult<Pic>>> VirtualPicsFunc(string? address = null) {
if (address == null) return VirtualPics;
else {
CachedAddress = address;
return async (ItemsProviderRequest request) => await VirtualPics(request, CachedAddress);
}
}
public async Task<long> FileSize(FileResult file) {
using var fileStream = await file.OpenReadAsync();
return fileStream.Length;
}
public async Task<string> Base64FromFile(FileResult file) {
using var memoryStream = new MemoryStream();
using var fileStream = await file.OpenReadAsync();
await fileStream.CopyToAsync(memoryStream);
byte[] bytes = memoryStream.ToArray();
return Convert.ToBase64String(bytes);
}
public async Task RefreshStatuses() => await GetStatuses(forceRefresh: true);
public async Task RefreshPics() => await GetPics(forceRefresh: true);
public async Task RefreshNow() => await GetNowGarden(forceRefresh: true);
public static string RelativeTimeFromUnix(long unix) {
DateTimeOffset createdTime = DateTimeOffset.UnixEpoch.AddSeconds(unix);
TimeSpan offset = DateTimeOffset.UtcNow - createdTime;
var offsetString = string.Empty;
if (offset.TotalDays >= 1) offsetString = $"{Math.Floor(offset.TotalDays)} days ago";
else if (offset.TotalHours >= 1) offsetString = $"{Math.Floor(offset.TotalHours)} hours, {offset.Minutes} minutes ago";
else if (offset.TotalMinutes >= 1) offsetString = $"{Math.Floor(offset.TotalMinutes)} minutes ago";
else offsetString = $"{Math.Floor(offset.TotalSeconds)} seconds ago";
return offsetString;
}
}
}