157 lines
4.2 KiB
C#
157 lines
4.2 KiB
C#
using Blahblah.FlowerApp.Controls;
|
|
using Blahblah.FlowerApp.Data;
|
|
using Blahblah.FlowerApp.Data.Model;
|
|
using Microsoft.Extensions.Logging;
|
|
using static Blahblah.FlowerApp.PropertyExtension;
|
|
|
|
namespace Blahblah.FlowerApp;
|
|
|
|
public partial class HomePage : AppContentPage
|
|
{
|
|
static readonly BindableProperty FlowersProperty = CreateProperty<FlowerClientItem[], HomePage>(nameof(Flowers));
|
|
static readonly BindableProperty IsRefreshingProperty = CreateProperty<bool, HomePage>(nameof(IsRefreshing));
|
|
|
|
public FlowerClientItem[] Flowers
|
|
{
|
|
get => GetValue<FlowerClientItem[]>(FlowersProperty);
|
|
set => SetValue(FlowersProperty, value);
|
|
}
|
|
public bool IsRefreshing
|
|
{
|
|
get => GetValue<bool>(IsRefreshingProperty);
|
|
set => SetValue(IsRefreshingProperty, value);
|
|
}
|
|
|
|
readonly FlowerDatabase database;
|
|
readonly ILogger logger;
|
|
|
|
bool loaded = false;
|
|
double pageWidth;
|
|
|
|
const int margin = 12;
|
|
const int cols = 2;
|
|
double[] ys = null!;
|
|
int yIndex;
|
|
int itemWidth;
|
|
int emptyHeight;
|
|
|
|
public HomePage(FlowerDatabase database, ILogger<HomePage> logger)
|
|
{
|
|
this.database = database;
|
|
this.logger = logger;
|
|
|
|
InitializeComponent();
|
|
}
|
|
|
|
protected override void OnSizeAllocated(double width, double height)
|
|
{
|
|
base.OnSizeAllocated(width, height);
|
|
|
|
pageWidth = width - margin * 2;
|
|
if (!loaded)
|
|
{
|
|
loaded = true;
|
|
IsRefreshing = true;
|
|
}
|
|
else if (Flowers?.Length > 0)
|
|
{
|
|
DoInitSize();
|
|
foreach (var item in Flowers)
|
|
{
|
|
DoResizeItem(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DoInitSize()
|
|
{
|
|
ys = new double[cols];
|
|
yIndex = 0;
|
|
itemWidth = (int)(pageWidth / cols) - margin * (cols - 1) / 2;
|
|
emptyHeight = (int)(itemWidth * AppResources.EmptySize.Height / AppResources.EmptySize.Width);
|
|
}
|
|
|
|
private void DoResizeItem(FlowerClientItem item)
|
|
{
|
|
int height;
|
|
if (item.Width > 0 && item.Height > 0)
|
|
{
|
|
height = itemWidth * item.Height.Value / item.Width.Value;
|
|
}
|
|
else
|
|
{
|
|
height = emptyHeight;
|
|
}
|
|
height += 36;
|
|
double yMin = double.MaxValue;
|
|
for (var i = 0; i < cols; i++)
|
|
{
|
|
if (ys[i] < yMin)
|
|
{
|
|
yMin = ys[i];
|
|
yIndex = i;
|
|
}
|
|
}
|
|
ys[yIndex] += height + margin;
|
|
item.Bounds = new Rect(
|
|
yIndex,
|
|
yMin,
|
|
itemWidth,
|
|
height);
|
|
}
|
|
|
|
private async void DoRefreshSquare()
|
|
{
|
|
try
|
|
{
|
|
var result = await FetchAsync<FlowerResult>("api/flower/latest?photo=true");
|
|
if (result?.Count > 0)
|
|
{
|
|
DoInitSize();
|
|
var flowers = result.Flowers.Select(f =>
|
|
{
|
|
var item = new FlowerClientItem(f);
|
|
if (f.Photos?.Length > 0 && f.Photos[0] is PhotoItem cover)
|
|
{
|
|
item.Cover = new UriImageSource { Uri = new Uri($"{Constants.BaseUrl}/{cover.Url}") };
|
|
}
|
|
else
|
|
{
|
|
item.Cover = "empty_flower.jpg";
|
|
}
|
|
DoResizeItem(item);
|
|
return item;
|
|
});
|
|
logger.LogInformation("got {count} flowers.", result.Count);
|
|
|
|
Flowers = flowers.ToArray();
|
|
}
|
|
else
|
|
{
|
|
Flowers = Array.Empty<FlowerClientItem>();
|
|
logger.LogInformation("no flowers.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await AlertError(L("failedGetFlowers", "Failed to get flowers, please try again."));
|
|
logger.LogError("error occurs in HomePage, {exception}", ex);
|
|
}
|
|
finally
|
|
{
|
|
IsRefreshing = false;
|
|
}
|
|
}
|
|
|
|
private void RefreshView_Refreshing(object sender, EventArgs e)
|
|
{
|
|
Task.Run(DoRefreshSquare);
|
|
}
|
|
}
|
|
|
|
public record FlowerResult
|
|
{
|
|
public FlowerItem[] Flowers { get; init; } = null!;
|
|
|
|
public int Count { get; init; }
|
|
} |