Gallery/Gallery.Share/Views/GalleryItemPage.xaml.cs
2021-08-12 17:29:57 +08:00

214 lines
6.9 KiB
C#

using System.Linq;
using System.Threading.Tasks;
using Gallery.Resources.Theme;
using Gallery.Resources.UI;
using Gallery.Services;
using Gallery.Util;
using Gallery.Util.Model;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Gallery.Views
{
[QueryProperty("GalleryId", "id")]
public partial class GalleryItemPage : AdaptedPage
{
public static readonly BindableProperty FavoriteIconProperty = BindableProperty.Create(nameof(FavoriteIcon), typeof(ImageSource), typeof(GalleryItemPage));
public static readonly BindableProperty GalleryItemProperty = BindableProperty.Create(nameof(GalleryItem), typeof(GalleryItem), typeof(GalleryItemPage));
public static readonly BindableProperty ProgressVisibleProperty = BindableProperty.Create(nameof(ProgressVisible), typeof(bool), typeof(GalleryItemPage));
public static readonly BindableProperty ToolbarCommandProperty = BindableProperty.Create(nameof(ToolbarCommand), typeof(Command<string>), typeof(GalleryItemPage));
public ImageSource FavoriteIcon
{
get => (ImageSource)GetValue(FavoriteIconProperty);
set => SetValue(FavoriteIconProperty, value);
}
public GalleryItem GalleryItem
{
get => (GalleryItem)GetValue(GalleryItemProperty);
}
public bool ProgressVisible
{
get => (bool)GetValue(ProgressVisibleProperty);
set => SetValue(ProgressVisibleProperty, value);
}
public Command<string> ToolbarCommand
{
get => (Command<string>)GetValue(ToolbarCommandProperty);
}
private readonly ImageSource fontIconLove;
private readonly ImageSource fontIconNotLove;
private bool favoriteChanged;
private bool isLoaded;
public GalleryItemPage(GalleryItem item)
{
SetValue(GalleryItemProperty, item);
SetValue(ToolbarCommandProperty, new Command<string>(HandleCommand, cmd => !IsBusy));
fontIconLove = (ImageSource)Application.Current.Resources[Theme.FontIconLove];
fontIconNotLove = (ImageSource)Application.Current.Resources[Theme.FontIconNotLove];
if (item != null)
{
InitInformation(item);
}
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
Screen.SetHomeIndicatorAutoHidden(Shell.Current, true);
if (!isLoaded)
{
isLoaded = true;
Task.Run(() => LoadImage());
}
}
protected override void OnDisappearing()
{
Screen.SetHomeIndicatorAutoHidden(Shell.Current, false);
base.OnDisappearing();
if (favoriteChanged)
{
Store.SaveFavoriteList();
}
}
private void InitInformation(GalleryItem item)
{
Title = item.TagDescription;
FavoriteIcon = Store.FavoriteList.Any(i => i.SourceEquals(item)) ?
fontIconLove :
fontIconNotLove;
}
private async void LoadImage(bool force = false)
{
IsBusy = true;
MainThread.BeginInvokeOnMainThread(async () =>
{
ToolbarCommand.ChangeCanExecute();
if (force)
{
ProgressVisible = true;
progress.Progress = 0;
await progress.FadeTo(1, easing: Easing.CubicIn);
}
});
var item = GalleryItem;
if (item.IsRawPage)
{
var source = App.GallerySources.FirstOrDefault(s => s.Route == item.Source);
if (source != null)
{
var url = await source.ResolveImageUrl(item);
if (!string.IsNullOrEmpty(url))
{
item.IsRawPage = false;
}
}
}
var image = await Store.LoadRawImage(item, true, force: force, o =>
{
var val = o.loc / (double)o.size;
if (val > progress.Progress)
{
MainThread.BeginInvokeOnMainThread(async () =>
{
if (!ProgressVisible)
{
ProgressVisible = true;
}
progress.CancelAnimations();
await progress.ProgressTo(val, 250, Easing.CubicIn);
});
}
});
if (image != null)
{
item.PreviewImage = image;
}
IsBusy = false;
MainThread.BeginInvokeOnMainThread(async () =>
{
ToolbarCommand.ChangeCanExecute();
progress.CancelAnimations();
await progress.ProgressTo(1, 250, Easing.CubicIn);
await progress.FadeTo(0, easing: Easing.CubicIn);
ProgressVisible = false;
});
}
private void HandleCommand(string cmd)
{
switch (cmd)
{
case "favorite": Favorite_Clicked(); break;
case "refresh": Refresh_Clicked(); break;
case "share": Share_Clicked(); break;
}
}
private void Favorite_Clicked()
{
if (IsBusy)
{
return;
}
Start(() =>
{
var favorites = Store.FavoriteList;
var item = GalleryItem;
var index = favorites.FindIndex(i => i.SourceEquals(item));
if (index < 0)
{
item.IsFavorite = true;
favorites.Insert(0, item);
FavoriteIcon = fontIconLove;
}
else
{
favorites.RemoveAt(index);
item.IsFavorite = false;
FavoriteIcon = fontIconNotLove;
}
favoriteChanged = true;
});
}
private void Refresh_Clicked()
{
if (IsBusy)
{
return;
}
Start(async () => await Task.Run(() => LoadImage(true)));
}
private void Share_Clicked()
{
if (IsBusy)
{
return;
}
Start(async () =>
{
var item = GalleryItem;
var path = Store.GetRawImagePath(item);
await Share.RequestAsync(new ShareFileRequest
{
Title = item.TagDescription,
File = new ShareFile(path)
});
});
}
}
}