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), 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 ToolbarCommand { get => (Command)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(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) }); }); } } }