diff --git a/Pixiview/Illust/FavoritesPage.xaml.cs b/Pixiview/Illust/FavoritesPage.xaml.cs index ae82d34..ab47677 100644 --- a/Pixiview/Illust/FavoritesPage.xaml.cs +++ b/Pixiview/Illust/FavoritesPage.xaml.cs @@ -146,8 +146,8 @@ namespace Pixiview.Illust { ToggleFilterPanel(false); await ScrollToTopAsync(scrollView); - startIndex = 0; lastUpdated = default; + startIndex = 0; StartLoad(); } @@ -187,11 +187,11 @@ namespace Pixiview.Illust public void Reload(bool force = false) { - lastUpdated = default; if (force) { flag = true; } + lastUpdated = default; startIndex = -1; StartLoad(force); } @@ -225,7 +225,6 @@ namespace Pixiview.Illust flag = false; lastUpdated = default; startIndex = -1; - nextIndex = 0; MainThread.BeginInvokeOnMainThread(() => StartLoad(true)); } }); @@ -336,6 +335,7 @@ namespace Pixiview.Illust { flag = false; lastUpdated = default; + startIndex = -1; StartLoad(); }); }); diff --git a/Pixiview/Illust/ViewIllustPage.xaml.cs b/Pixiview/Illust/ViewIllustPage.xaml.cs index 93c048f..90c43e8 100644 --- a/Pixiview/Illust/ViewIllustPage.xaml.cs +++ b/Pixiview/Illust/ViewIllustPage.xaml.cs @@ -14,9 +14,16 @@ namespace Pixiview.Illust [QueryProperty("IllustId", "id")] public partial class ViewIllustPage : AdaptedPage { + #region - Properties - public static readonly BindableProperty FavoriteIconProperty = BindableProperty.Create( nameof(FavoriteIcon), typeof(ImageSource), typeof(ViewIllustPage)); + public ImageSource FavoriteIcon + { + get => (ImageSource)GetValue(FavoriteIconProperty); + set => SetValue(FavoriteIconProperty, value); + } + public static readonly BindableProperty IllustsProperty = BindableProperty.Create( nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage)); public static readonly BindableProperty IsPageVisibleProperty = BindableProperty.Create( @@ -27,43 +34,6 @@ namespace Pixiview.Illust nameof(CurrentPage), typeof(int), typeof(ViewIllustPage), propertyChanged: OnCurrentPagePropertyChanged); public static readonly BindableProperty IsScrollAnimatedProperty = BindableProperty.Create( nameof(IsScrollAnimated), typeof(bool), typeof(ViewIllustPage), true); - public static readonly BindableProperty AnimeStatusProperty = BindableProperty.Create( - nameof(AnimeStatus), typeof(string), typeof(ViewIllustPage), StyleDefinition.IconPlay); - public static readonly BindableProperty IsAnimateSliderVisibleProperty = BindableProperty.Create( - nameof(IsAnimateSliderVisible), typeof(bool), typeof(ViewIllustPage)); - public static readonly BindableProperty IsAnimateSliderEnabledProperty = BindableProperty.Create( - nameof(IsAnimateSliderEnabled), typeof(bool), typeof(ViewIllustPage)); - public static readonly BindableProperty CurrentAnimeFrameProperty = BindableProperty.Create( - nameof(CurrentAnimeFrame), typeof(double), typeof(ViewIllustPage), propertyChanged: OnCurrentAnimeFramePropertyChanged); - public static readonly BindableProperty MaximumFrameProperty = BindableProperty.Create( - nameof(MaximumFrame), typeof(double), typeof(ViewIllustPage), 1.0); - public static readonly BindableProperty ProgressVisibleProperty = BindableProperty.Create( - nameof(ProgressVisible), typeof(bool), typeof(ViewIllustPage)); - - private static void OnCurrentPagePropertyChanged(BindableObject obj, object old, object @new) - { - var page = (ViewIllustPage)obj; - var index = (int)@new; - var items = page.Illusts; - var length = items.Length; - page.PagePositionText = $"{index + 1}/{length}"; - } - - private static void OnCurrentAnimeFramePropertyChanged(BindableObject obj, object old, object @new) - { - var page = (ViewIllustPage)obj; - if (page.ugoira != null && page.IsAnimateSliderEnabled) - { - var frame = (double)@new; - page.ugoira.ToggleFrame((int)frame); - } - } - - public ImageSource FavoriteIcon - { - get => (ImageSource)GetValue(FavoriteIconProperty); - set => SetValue(FavoriteIconProperty, value); - } public IllustDetailItem[] Illusts { @@ -85,16 +55,47 @@ namespace Pixiview.Illust get => (int)GetValue(CurrentPageProperty); set => SetValue(CurrentPageProperty, value); } - public string AnimeStatus - { - get => (string)GetValue(AnimeStatusProperty); - set => SetValue(AnimeStatusProperty, value); - } public bool IsScrollAnimated { get => (bool)GetValue(IsScrollAnimatedProperty); set => SetValue(IsScrollAnimatedProperty, value); } + + private static void OnCurrentPagePropertyChanged(BindableObject obj, object old, object @new) + { + var page = (ViewIllustPage)obj; + var index = (int)@new; + var items = page.Illusts; + var length = items.Length; + page.PagePositionText = $"{index + 1}/{length}"; + } + + public static readonly BindableProperty AnimeStatusProperty = BindableProperty.Create( + nameof(AnimeStatus), typeof(string), typeof(ViewIllustPage), StyleDefinition.IconPlay); + public static readonly BindableProperty IsAnimateSliderVisibleProperty = BindableProperty.Create( + nameof(IsAnimateSliderVisible), typeof(bool), typeof(ViewIllustPage)); + public static readonly BindableProperty IsAnimateSliderEnabledProperty = BindableProperty.Create( + nameof(IsAnimateSliderEnabled), typeof(bool), typeof(ViewIllustPage)); + public static readonly BindableProperty CurrentAnimeFrameProperty = BindableProperty.Create( + nameof(CurrentAnimeFrame), typeof(double), typeof(ViewIllustPage), propertyChanged: OnCurrentAnimeFramePropertyChanged); + public static readonly BindableProperty MaximumFrameProperty = BindableProperty.Create( + nameof(MaximumFrame), typeof(double), typeof(ViewIllustPage), 1.0); + + private static void OnCurrentAnimeFramePropertyChanged(BindableObject obj, object old, object @new) + { + var page = (ViewIllustPage)obj; + if (page.ugoira != null && page.IsAnimateSliderEnabled) + { + var frame = (double)@new; + page.ugoira.ToggleFrame((int)frame); + } + } + + public string AnimeStatus + { + get => (string)GetValue(AnimeStatusProperty); + set => SetValue(AnimeStatusProperty, value); + } public bool IsAnimateSliderVisible { get => (bool)GetValue(IsAnimateSliderVisibleProperty); @@ -115,16 +116,22 @@ namespace Pixiview.Illust get => (double)GetValue(MaximumFrameProperty); set => SetValue(MaximumFrameProperty, value); } + + public static readonly BindableProperty ProgressVisibleProperty = BindableProperty.Create( + nameof(ProgressVisible), typeof(bool), typeof(ViewIllustPage)); + public bool ProgressVisible { get => (bool)GetValue(ProgressVisibleProperty); set => SetValue(ProgressVisibleProperty, value); } + #endregion public IllustItem IllustItem { get; private set; } private readonly ImageSource fontIconLove; private readonly ImageSource fontIconNotLove; + private readonly ImageSource fontIconCircleLove; private bool favoriteChanged; private IllustUgoiraData ugoiraData; private Ugoira ugoira; @@ -138,27 +145,23 @@ namespace Pixiview.Illust public ViewIllustPage(IllustItem illust) { IllustItem = illust; - Title = illust.Title; - BindingContext = this; fontIconLove = (ImageSource)Application.Current.Resources[ThemeBase.FontIconLove]; fontIconNotLove = (ImageSource)Application.Current.Resources[ThemeBase.FontIconNotLove]; - FavoriteIcon = Stores.Favorites.Any(i => i.Id == illust.Id) - ? fontIconLove - : fontIconNotLove; + fontIconCircleLove = (ImageSource)Application.Current.Resources[ThemeBase.FontIconCircleLove]; if (illust != null) { pageCount = illust.PageCount; - ProgressVisible = IsPageVisible = pageCount > 1; + RefreshInformation(illust, pageCount); } Resources.Add("carouselView", GetCarouseTemplate()); + BindingContext = this; InitializeComponent(); if (illust != null) { - IsAnimateSliderVisible = illust.IsAnimeVisible; LoadIllust(illust); } } @@ -306,10 +309,6 @@ namespace Pixiview.Illust } var items = new IllustDetailItem[illust.PageCount]; - if (items.Length > 1) - { - PagePositionText = $"1/{items.Length}"; - } #if __IOS__ var topMargin = PageTopMargin; @@ -351,6 +350,7 @@ namespace Pixiview.Illust return; } var items = Illusts; + var reload = false; if (pages.body.Length > items.Length) { App.DebugPrint($"local page count ({items.Length}) is not equals the remote one ({pages.body.Length})"); @@ -371,6 +371,7 @@ namespace Pixiview.Illust }; } Illusts = items = tmp; + reload = true; } for (var i = 0; i < items.Length; i++) @@ -383,10 +384,15 @@ namespace Pixiview.Illust if (i == 0 && illustItem.ImageUrl == null) { // maybe open from a link - DoForcePreload(false); + reload = true; } } + if (reload) + { + DoForcePreload(false); + } + if (task != null) { task.Dispose(); @@ -503,7 +509,8 @@ namespace Pixiview.Illust var favorites = Stores.Favorites; var illust = IllustItem; var index = favorites.FindIndex(i => i.Id == illust.Id); - bool add = index < 0; + var bookmarkId = illust.BookmarkId; + bool add = index < 0 && bookmarkId == null; if (add) { illust.IsFavorite = true; @@ -513,14 +520,20 @@ namespace Pixiview.Illust } else { - var item = favorites[index]; - if (illust.BookmarkId == null && item.BookmarkId != null) + if (index >= 0) { - illust.BookmarkId = item.BookmarkId; + var item = favorites[index]; + if (bookmarkId == null && item.BookmarkId != null) + { + bookmarkId = item.BookmarkId; + illust.BookmarkId = bookmarkId; + } + favorites.RemoveAt(index); } illust.IsFavorite = false; - favorites.RemoveAt(index); - FavoriteIcon = fontIconNotLove; + FavoriteIcon = bookmarkId == null ? + fontIconNotLove : + fontIconCircleLove; } favoriteChanged = true; @@ -528,7 +541,7 @@ namespace Pixiview.Illust { return; } - if (!add && string.IsNullOrEmpty(illust.BookmarkId)) + if (!add && string.IsNullOrEmpty(bookmarkId)) { return; } @@ -550,12 +563,18 @@ namespace Pixiview.Illust var id = await Task.Run(() => Stores.AddBookmark(illust.Id)); if (id != null) { - illust.BookmarkId = id; + bookmarkId = id; + illust.BookmarkId = bookmarkId; + FavoriteIcon = fontIconCircleLove; } } else { - _ = Task.Run(() => Stores.DeleteBookmark(illust.BookmarkId)); + var result = await Task.Run(() => Stores.DeleteBookmark(bookmarkId)); + if (result) + { + FavoriteIcon = fontIconNotLove; + } } // immediately save after changing remote @@ -600,6 +619,23 @@ namespace Pixiview.Illust CurrentAnimeFrame = e.FrameIndex; } + private void RefreshInformation(IllustItem item, int count) + { + Title = item.Title; + FavoriteIcon = item.BookmarkId != null ? + fontIconCircleLove : + Stores.Favorites.Any(i => i.Id == item.Id) ? + fontIconLove : + fontIconNotLove; + IsAnimateSliderVisible = item.IsAnimeVisible; + if (count > 1) + { + IsPageVisible = true; + ProgressVisible = true; + PagePositionText = $"1/{count}"; + } + } + private void DoForcePreload(bool force) { isPreloading = true; @@ -609,18 +645,10 @@ namespace Pixiview.Illust if (preload != null && preload.illust.TryGetValue(illustItem.Id, out var illust)) { illust.CopyToItem(illustItem); + pageCount = illustItem.PageCount; MainThread.BeginInvokeOnMainThread(() => { - var count = illustItem.PageCount; - pageCount = count; - Title = illustItem.Title; - IsAnimateSliderVisible = illustItem.IsAnimeVisible; - if (count > 1) - { - IsPageVisible = true; - ProgressVisible = true; - PagePositionText = $"1/{count}"; - } + RefreshInformation(illustItem, pageCount); }); if (preload.user.TryGetValue(illust.userId, out var user)) { diff --git a/Pixiview/UI/Theme/ThemeBase.cs b/Pixiview/UI/Theme/ThemeBase.cs index f1004fc..716553d 100644 --- a/Pixiview/UI/Theme/ThemeBase.cs +++ b/Pixiview/UI/Theme/ThemeBase.cs @@ -10,6 +10,7 @@ namespace Pixiview.UI.Theme public const string FontIconRefresh = nameof(FontIconRefresh); public const string FontIconLove = nameof(FontIconLove); public const string FontIconNotLove = nameof(FontIconNotLove); + public const string FontIconCircleLove = nameof(FontIconCircleLove); public const string FontIconOption = nameof(FontIconOption); public const string FontIconFavorite = nameof(FontIconFavorite); public const string FontIconShare = nameof(FontIconShare); @@ -53,6 +54,7 @@ namespace Pixiview.UI.Theme var solidFontFamily = StyleDefinition.IconSolidFontFamily; Add(FontIconLove, GetSolidIcon(StyleDefinition.IconLove, solidFontFamily, StyleDefinition.ColorRedBackground)); + Add(FontIconCircleLove, GetSolidIcon(StyleDefinition.IconCircleLove, solidFontFamily, StyleDefinition.ColorRedBackground)); Add(FontIconUser, GetSolidIcon(StyleDefinition.IconUser, solidFontFamily)); Add(FontIconSparkles, GetSolidIcon(StyleDefinition.IconSparkles, solidFontFamily)); Add(FontIconOrder, GetSolidIcon(StyleDefinition.IconOrder, solidFontFamily));