* Pixiview/Utils/Stores.cs:

* Pixiview/Pixiview.projitems:
* Pixiview/Utils/IllustData.cs:
* Pixiview/Utils/HttpUtility.cs:
* Pixiview/Utils/IllustLegacy.cs:
* Pixiview/Illust/ViewIllustPage.xaml:
* Pixiview/Illust/ViewIllustPage.xaml.cs: feature: view animate

* Pixiview/Illust/FavoritesPage.xaml.cs: lazy load favorites page

* Pixiview/UI/CardView.cs:
* Pixiview/UI/AdaptedPage.cs:
* Pixiview/Utils/Converters.cs:
* Pixiview/UI/StyleDefinition.cs:
* Pixiview/UI/Theme/ThemeBase.cs:
* Pixiview/Illust/RankingPage.xaml:
* Pixiview/Illust/RankingPage.xaml.cs:
* Pixiview/Resources/Languages/zh-CN.xml:
* Pixiview/Illust/IllustCollectionPage.cs:
* Pixiview.iOS/Renderers/SegmentedControlRenderer.cs: feature: filter
  ranking

* Pixiview.iOS/Info.plist:
* Pixiview.iOS/Pixiview.iOS.csproj:
* Pixiview.iOS.OpenExtension/Info.plist:
* Pixiview.Android/Pixiview.Android.csproj:
* Pixiview.Android/Properties/AndroidManifest.xml: version update
This commit is contained in:
2020-05-13 01:18:45 +08:00
parent 4561bc2674
commit ba46ba02c4
23 changed files with 1301 additions and 244 deletions

View File

@@ -5,6 +5,7 @@ using System.Windows.Input;
using Pixiview.Resources;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Pixiview.Illust
{
@@ -25,7 +26,11 @@ namespace Pixiview.Illust
protected override void OnAppearing()
{
//base.OnAppearing();
Reload();
Device.StartTimer(TimeSpan.FromMilliseconds(200), () =>
{
Reload();
return false;
});
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustItem[] data, ICommand command)

View File

@@ -15,6 +15,7 @@ namespace Pixiview.Illust
{
public abstract class FavoriteIllustCollectionPage : IllustCollectionPage<IllustItem[]> { }
public abstract class IllustDataCollectionPage : IllustCollectionPage<IllustData> { }
public abstract class IllustRankingDataCollectionPage : IllustCollectionPage<IllustRankingData> { }
public abstract class IllustUserDataCollectionPage : IllustCollectionPage<IllustUserData> { }
public interface IIllustCollectionPage
@@ -132,20 +133,38 @@ namespace Pixiview.Illust
{
base.OnSizeAllocated(width, height);
int columns;
var oldMargin = PanelTopMargin;
Thickness newMargin;
if (StyleDefinition.IsFullscreenDevice)
{
newMargin = width > height ?
AppShell.HalfNavigationBarOffset :
AppShell.NavigationBarOffset;
}
else if (isPhone)
{
newMargin = width > height ?
StyleDefinition.TopOffset16 :
StyleDefinition.TopOffset32;
}
else
{
// TODO ipad
newMargin = StyleDefinition.TopOffset32;
}
if (width > height)
{
PanelTopMargin = StyleDefinition.IsFullscreenDevice ?
AppShell.HalfNavigationBarOffset :
StyleDefinition.TopOffset16;
columns = isPhone ? 4 : 6;
}
else
{
PanelTopMargin = StyleDefinition.IsFullscreenDevice ?
AppShell.NavigationBarOffset :
StyleDefinition.TopOffset32;
columns = isPhone ? 2 : 4;
}
if (oldMargin != newMargin)
{
PanelTopMargin = newMargin;
OnPanelTopMarginChanged(oldMargin, newMargin);
}
if (Columns != columns)
{
Columns = columns;
@@ -162,6 +181,11 @@ namespace Pixiview.Illust
var page = new ViewIllustPage(illust, IsFavoriteVisible);
Navigation.PushAsync(page);
}
protected virtual void DoIllustsLoaded(IllustCollection collection)
{
IllustCollection = collection;
Illusts = collection;
}
protected void StartLoad(bool force = false)
{
@@ -227,16 +251,33 @@ namespace Pixiview.Illust
.Binding(IsVisibleProperty, nameof(IllustItem.IsPageVisible))
.DynamicResource(Label.FontFamilyProperty, ThemeBase.IconSolidFontFamily);
// label: is anime
var anime = new RoundLabel
{
Text = StyleDefinition.IconPlay,
BackgroundColor = StyleDefinition.ColorDeepShadow,
Margin = new Thickness(0, 0, 6, 6),
Padding = new Thickness(12, 9, 0, 0),
WidthRequest = 36,
HeightRequest = 36,
CornerRadius = 18,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.End,
FontSize = StyleDefinition.FontSizeTitle,
TextColor = Color.White
}
.Binding(IsVisibleProperty, nameof(IllustItem.IsAnimeVisible))
.DynamicResource(Label.FontFamilyProperty, ThemeBase.IconSolidFontFamily);
// label: title
var title = new Label
{
Padding = new Thickness(8, 2),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Center,
LineBreakMode = LineBreakMode.TailTruncation,
FontSize = StyleDefinition.FontSizeSmall
}
.Binding(Label.TextProperty, nameof(IllustItem.Title))
.DynamicResource(Label.TextColorProperty, ThemeBase.TextColor);
}.DynamicResource(Label.TextColorProperty, ThemeBase.TextColor);
// label: favorite
var favorite = new Label
@@ -266,24 +307,34 @@ namespace Pixiview.Illust
Content = new Grid
{
HorizontalOptions = LayoutOptions.Fill,
RowSpacing = 0,
RowDefinitions =
{
new RowDefinition().Binding(RowDefinition.HeightProperty, nameof(IllustItem.ImageHeight)),
new RowDefinition { Height = GridLength.Auto }
new RowDefinition { Height = 30 }
},
Children =
{
image,
r18,
pages,
title,
anime,
// stacklayout: user
new StackLayout
// stacklayout: title
new Grid
{
Orientation = StackOrientation.Horizontal,
ColumnDefinitions =
{
new ColumnDefinition(),
new ColumnDefinition { Width = 20 }
},
VerticalOptions = LayoutOptions.Center,
Padding = new Thickness(0, 0, 8, 0),
Children = { title, favorite }
Children =
{
title.Binding(Label.TextProperty, nameof(IllustItem.Title)),
favorite.GridColumn(1)
}
}
.GridRow(1)
}
@@ -302,23 +353,31 @@ namespace Pixiview.Illust
Content = new Grid
{
HorizontalOptions = LayoutOptions.Fill,
RowSpacing = 0,
RowDefinitions =
{
new RowDefinition().Binding(RowDefinition.HeightProperty, nameof(IllustItem.ImageHeight)),
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto }
new RowDefinition { Height = 30 },
new RowDefinition { Height = 40 }
},
Children =
{
image,
r18,
pages,
title.GridRow(1),
anime,
title.Binding(Label.TextProperty, nameof(IllustItem.RankTitle)).GridRow(1),
// stacklayout: user
new StackLayout
new Grid
{
Orientation = StackOrientation.Horizontal,
ColumnDefinitions =
{
new ColumnDefinition { Width = 30 },
new ColumnDefinition(),
new ColumnDefinition { Width = 20 }
},
Padding = new Thickness(8, 0, 8, 8),
Children =
{
@@ -340,10 +399,11 @@ namespace Pixiview.Illust
FontSize = StyleDefinition.FontSizeMicro
}
.Binding(Label.TextProperty, nameof(IllustItem.UserName))
.DynamicResource(Label.TextColorProperty, ThemeBase.SubTextColor),
.DynamicResource(Label.TextColorProperty, ThemeBase.SubTextColor)
.GridColumn(1),
// label: favorite
favorite
favorite.GridColumn(2)
}
}
.GridRow(2)
@@ -367,7 +427,9 @@ namespace Pixiview.Illust
}
if (force && IsFavoriteVisible)
{
LastUpdated = DateTime.Now;
var now = DateTime.Now;
LastUpdated = now;
lastUpdated = now;
}
var data = DoGetIllustList(illustData, commandIllustImageTapped).Where(i => i != null);
@@ -385,8 +447,7 @@ namespace Pixiview.Illust
item.IsFavorite = favorites.Any(i => i.Id == item.Id);
}
}
IllustCollection = collection;
Illusts = collection;
DoIllustsLoaded(collection);
IsLoading = false;
DoLoadImages(collection);
@@ -474,11 +535,20 @@ namespace Pixiview.Illust
public List<IllustItem> Illusts { get; set; }
}
public enum IllustType
{
Illust = 0,
Manga = 1,
Anime = 2
}
[JsonObject(MemberSerialization.OptIn)]
public class IllustItem : BindableObject
{
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
nameof(Title), typeof(string), typeof(IllustItem));
public static readonly BindableProperty RankTitleProperty = BindableProperty.Create(
nameof(RankTitle), typeof(string), typeof(IllustItem));
public static readonly BindableProperty ImageProperty = BindableProperty.Create(
nameof(Image), typeof(ImageSource), typeof(IllustItem));
public static readonly BindableProperty ProfileImageProperty = BindableProperty.Create(
@@ -487,6 +557,8 @@ namespace Pixiview.Illust
nameof(ImageHeight), typeof(GridLength), typeof(IllustItem), GridLength.Auto);
public static readonly BindableProperty IsFavoriteProperty = BindableProperty.Create(
nameof(IsFavorite), typeof(bool), typeof(IllustItem));
public static readonly BindableProperty IsPlayingProperty = BindableProperty.Create(
nameof(IsPlaying), typeof(bool), typeof(IllustItem));
[JsonProperty]
public string Title
@@ -494,6 +566,11 @@ namespace Pixiview.Illust
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public string RankTitle
{
get => (string)GetValue(RankTitleProperty);
set => SetValue(RankTitleProperty, value);
}
public ImageSource Image
{
get => (ImageSource)GetValue(ImageProperty);
@@ -514,6 +591,11 @@ namespace Pixiview.Illust
get => (bool)GetValue(IsFavoriteProperty);
set => SetValue(IsFavoriteProperty, value);
}
public bool IsPlaying
{
get => (bool)GetValue(IsPlayingProperty);
set => SetValue(IsPlayingProperty, value);
}
public ICommand IllustTapped { get; set; }
[JsonProperty]
@@ -540,8 +622,19 @@ namespace Pixiview.Illust
get => ImageHeight.IsAuto ? -1 : ImageHeight.Value;
set => ImageHeight = value > 0 ? value : GridLength.Auto;
}
[JsonProperty]
public int YesRank { get; set; }
[JsonProperty]
public int RatingCount { get; set; }
[JsonProperty]
public int ViewCount { get; set; }
[JsonProperty]
public long UploadTimestamp { get; set; }
[JsonProperty]
public IllustType IllustType { get; set; }
public string PageCountText => $"{StyleDefinition.IconLayer} {PageCount}";
public bool IsPageVisible => PageCount > 1;
public bool IsAnimeVisible => IllustType == IllustType.Anime;
}
}

View File

@@ -1,31 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<i:IllustDataCollectionPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:i="clr-namespace:Pixiview.Illust"
xmlns:u="clr-namespace:Pixiview.UI"
xmlns:r="clr-namespace:Pixiview.Resources"
x:Class="Pixiview.Illust.RankingPage"
BackgroundColor="{DynamicResource WindowColor}"
Shell.NavBarHasShadow="False">
<i:IllustRankingDataCollectionPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:i="clr-namespace:Pixiview.Illust"
xmlns:u="clr-namespace:Pixiview.UI"
xmlns:r="clr-namespace:Pixiview.Resources"
x:Class="Pixiview.Illust.RankingPage"
BackgroundColor="{DynamicResource WindowColor}">
<Shell.TitleView>
<Grid VerticalOptions="Fill" HorizontalOptions="Fill" ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Column="1" Text="{Binding Title}"
VerticalTextAlignment="Center" FontAttributes="Bold">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
</Label>
<Label Grid.Column="2" Text="{Binding PanelState}"
FontFamily="{DynamicResource IconSolidFontFamily}"
FontSize="Small"
VerticalTextAlignment="Center"/>
</Grid>
</Shell.TitleView>
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" Clicked="Refresh_Clicked"
IconImageSource="{DynamicResource FontIconRefresh}"/>
</ContentPage.ToolbarItems>
<Grid>
<ScrollView HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
<ScrollView x:Name="scrollView" Scrolled="ScrollView_Scrolled"
HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
<u:FlowLayout ItemsSource="{Binding Illusts}"
HorizontalOptions="Fill" Column="{Binding Columns}"
Margin="16, 62, 16, 16" RowSpacing="16" ColumnSpacing="16"
Margin="16, 16, 16, 16" RowSpacing="16" ColumnSpacing="16"
ItemTemplate="{StaticResource cardView}"/>
</ScrollView>
<u:BlurryPanel VerticalOptions="Start" HeightRequest="50" Margin="{Binding PanelTopMargin}"/>
<!--<u:BlurryPanel VerticalOptions="Start" HeightRequest="50" Margin="{Binding PanelTopMargin}"/>
<SearchBar x:Name="searchBar" Placeholder="{r:Text Search}" HeightRequest="50"
VerticalOptions="Start"
Margin="{Binding PageTopMargin}"
CancelButtonColor="{DynamicResource TintColor}"
Text="{Binding Keywords, Mode=TwoWay}"
SearchButtonPressed="SearchBar_SearchButtonPressed"
Unfocused="SearchBar_Unfocused"/>
Unfocused="SearchBar_Unfocused"/>-->
<u:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
Margin="{Binding PanelTopMargin}"
HeightRequest="{Binding Height, Source={x:Reference gridFilter}}"/>
<Grid x:Name="gridFilter" VerticalOptions="Start" Opacity="0"
Margin="{Binding PageTopMargin}" Padding="10">
<Grid RowSpacing="0" HorizontalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<u:SegmentedControl Margin="6, 6, 6, 3" VerticalOptions="Center"
SelectedSegmentIndex="{Binding SegmentDate, Mode=TwoWay}">
<u:SegmentedControl.Children>
<u:SegmentedControlOption Text="{r:Text Daily}"/>
<u:SegmentedControlOption Text="{r:Text Weekly}"/>
<u:SegmentedControlOption Text="{r:Text Monthly}"/>
<u:SegmentedControlOption Text="{r:Text Male}"/>
</u:SegmentedControl.Children>
</u:SegmentedControl>
<u:SegmentedControl Grid.Row="1" HorizontalOptions="Start"
Margin="6, 3, 6, 6" VerticalOptions="Center"
SelectedSegmentIndex="{Binding SegmentType, Mode=TwoWay}">
<u:SegmentedControl.Children>
<u:SegmentedControlOption Text="{r:Text General}"/>
<u:SegmentedControlOption Text="{r:Text R18}"/>
</u:SegmentedControl.Children>
</u:SegmentedControl>
<Button Grid.Row="1" HorizontalOptions="End" VerticalOptions="Center"
Text="{DynamicResource IconCircleCheck}"
FontFamily="{DynamicResource IconSolidFontFamily}"
TextColor="{DynamicResource TintColor}"
FontSize="20" Margin="0, 0, 6, 0"
Clicked="Filter_Clicked"/>
</Grid>
</Grid>
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
IsVisible="{Binding IsLoading}"
HorizontalOptions="Center" VerticalOptions="Center"
@@ -34,4 +89,4 @@
Color="{DynamicResource WindowColor}"/>
</Frame>
</Grid>
</i:IllustDataCollectionPage>
</i:IllustRankingDataCollectionPage>

View File

@@ -1,45 +1,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Pixiview.Resources;
using Pixiview.UI;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Pixiview.Illust
{
public partial class RankingPage : IllustDataCollectionPage
public partial class RankingPage : IllustRankingDataCollectionPage
{
private static readonly string[] segmentDates = { "daily", "weekly", "monthly", "male" };
private static readonly object sync = new object();
public static readonly BindableProperty KeywordsProperty = BindableProperty.Create(
nameof(Keywords), typeof(string), typeof(RankingPage));
public static readonly BindableProperty PanelStateProperty = BindableProperty.Create(
nameof(PanelState), typeof(string), typeof(RankingPage), StyleDefinition.IconCaretDown);
public static readonly BindableProperty SegmentDateProperty = BindableProperty.Create(
nameof(SegmentDate), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentDatePropertyChanged);
public static readonly BindableProperty SegmentTypeProperty = BindableProperty.Create(
nameof(SegmentType), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentTypePropertyChanged);
private static void OnSegmentDatePropertyChanged(BindableObject obj, object old, object @new)
{
var page = (RankingPage)obj;
var index = (int)@new;
if (index == 2)
{
// monthly
var typeIndex = page.SegmentType;
if (typeIndex == 1)
{
// r-18
page.SegmentType = 0;
}
}
}
private static void OnSegmentTypePropertyChanged(BindableObject obj, object old, object @new)
{
var page = (RankingPage)obj;
var index = (int)@new;
if (index == 1)
{
// r-18
var dateIndex = page.SegmentDate;
if (dateIndex == 2)
{
// monthly
page.SegmentDate = 0;
}
}
}
public string Keywords
{
get => (string)GetValue(KeywordsProperty);
set => SetValue(KeywordsProperty, value);
}
public string PanelState
{
get => (string)GetValue(PanelStateProperty);
set => SetValue(PanelStateProperty, value);
}
public int SegmentDate
{
get => (int)GetValue(SegmentDateProperty);
set => SetValue(SegmentDateProperty, value);
}
public int SegmentType
{
get => (int)GetValue(SegmentTypeProperty);
set => SetValue(SegmentTypeProperty, value);
}
private bool isFilterVisible;
private double topOffset;
private string lastQueryKey;
private string queryDate;
private int currentPage;
private int nextPage;
private string QueryKey => segmentDates[SegmentDate] + (SegmentType == 1 ? "_r18" : string.Empty);
public RankingPage()
{
Resources.Add("cardView", GetCardViewTemplate());
InitializeComponent();
gridFilter.TranslationY = -100;
panelFilter.TranslationY = -100;
#if __IOS__
searchBar.BackgroundColor = Color.Transparent;
#elif __ANDROID__
searchBar.SetDynamicResource(SearchBar.TextColorProperty, UI.Theme.ThemeBase.TextColor);
searchBar.SetDynamicResource(SearchBar.PlaceholderColorProperty, UI.Theme.ThemeBase.SubTextColor);
searchBar.SetDynamicResource(BackgroundColorProperty, UI.Theme.ThemeBase.WindowColor);
#endif
//#if __IOS__
// searchBar.BackgroundColor = Color.Transparent;
//#elif __ANDROID__
// searchBar.SetDynamicResource(SearchBar.TextColorProperty, UI.Theme.ThemeBase.TextColor);
// searchBar.SetDynamicResource(SearchBar.PlaceholderColorProperty, UI.Theme.ThemeBase.SubTextColor);
// searchBar.SetDynamicResource(BackgroundColorProperty, UI.Theme.ThemeBase.WindowColor);
//#endif
lastQueryKey = QueryKey;
queryDate = null; // $"{now.Year}{now.Month:00}{now.Day:00}";
currentPage = 1;
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
if (StyleDefinition.IsFullscreenDevice)
{
topOffset = width > height ?
AppShell.NavigationBarOffset.Top :
AppShell.TotalBarOffset.Top;
}
else if (isPhone)
{
topOffset = width > height ?
StyleDefinition.TopOffset32.Top :
AppShell.TotalBarOffset.Top;
}
else
{
// TODO: ipad
topOffset = AppShell.TotalBarOffset.Top;
}
}
protected override bool IsLazyload => true;
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data, ICommand command)
protected override void DoIllustsLoaded(IllustCollection collection)
{
return data.body.page.ranking.items.Select(i =>
var now = IllustCollection;
if (now == null)
{
var item = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == i.id)?.ConvertToItem();
IllustCollection = collection;
Illusts = collection;
}
else
{
now = new IllustCollection(now.Concat(collection));
IllustCollection = now;
Illusts = now;
}
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRankingData data, ICommand command)
{
return data.contents.Select(i =>
{
var item = i.ConvertToItem();
if (item != null)
{
item.IllustTapped = command;
@@ -48,27 +159,67 @@ namespace Pixiview.Illust
});
}
protected override IllustData DoLoadIllustData(bool force)
protected override IllustRankingData DoLoadIllustData(bool force)
{
var data = Stores.LoadIllustData(force);
var data = Stores.LoadIllustRankingData(lastQueryKey, queryDate, currentPage, force);
if (data != null)
{
var date = data.body.page.ranking.date;
//if (data.contents.Length * data.page < data.rank_total)
//{
// nextPage = currentPage + 1;
//}
if (int.TryParse(data.next, out int next))
{
nextPage = next;
}
var date = data.date;
if (date.Length == 8)
{
queryDate = date;
date = date.Substring(0, 4) + "-" + date.Substring(4, 2) + "-" + date.Substring(6, 2);
}
date = ResourceHelper.GetResource(data.mode, date);
MainThread.BeginInvokeOnMainThread(() => Title = date);
}
return data;
}
private async void ToggleFilterPanel(bool flag)
{
ViewExtensions.CancelAnimations(gridFilter);
ViewExtensions.CancelAnimations(panelFilter);
if (flag)
{
isFilterVisible = true;
PanelState = StyleDefinition.IconCaretUp;
await Task.WhenAll(
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
gridFilter.FadeTo(1, easing: Easing.CubicOut),
panelFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
panelFilter.FadeTo(1, easing: Easing.CubicOut)
);
}
else
{
isFilterVisible = false;
PanelState = StyleDefinition.IconCaretDown;
await Task.WhenAll(
gridFilter.TranslateTo(0, -100, easing: Easing.CubicOut),
gridFilter.FadeTo(0, easing: Easing.CubicOut),
panelFilter.TranslateTo(0, -100, easing: Easing.CubicOut),
panelFilter.FadeTo(0, easing: Easing.CubicOut)
);
}
}
private void Refresh_Clicked(object sender, EventArgs e)
{
if (IsLoading)
{
return;
}
currentPage = 1;
IllustCollection = null;
StartLoad(true);
}
@@ -100,5 +251,65 @@ namespace Pixiview.Illust
SearchBar_SearchButtonPressed(sender, e);
}
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
ToggleFilterPanel(!isFilterVisible);
}
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
var bottomOffset = scrollView.ContentSize.Height - (scrollView.LayoutAreaOverride.Height * 2);
if (e.ScrollY > 0 && e.ScrollY + topOffset > bottomOffset)
{
bool refresh = false;
lock (sync)
{
if (IsLoading)
{
return;
}
App.DebugPrint("bottom arrived.");
if (nextPage == currentPage + 1)
{
currentPage = nextPage;
refresh = true;
App.DebugPrint($"loading page {nextPage}");
}
}
if (refresh)
{
StartLoad(true);
}
}
}
private void Filter_Clicked(object sender, EventArgs e)
{
var query = QueryKey;
ToggleFilterPanel(false);
bool refresh = false;
lock (sync)
{
if (IsLoading)
{
return;
}
if (lastQueryKey != query)
{
// query changed.
currentPage = 1;
lastQueryKey = query;
IllustCollection = null;
refresh = true;
App.DebugPrint($"query changed: {query}");
}
}
if (refresh)
{
StartLoad(true);
}
}
}
}

View File

@@ -31,6 +31,9 @@
<Image.Effects>
<util:LongPressEffect/>
</Image.Effects>
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Image_Tapped"/>
</Image.GestureRecognizers>
</Image>
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
IsVisible="{Binding Loading}"

View File

@@ -60,6 +60,8 @@ namespace Pixiview.Illust
private readonly ICommand longPressed;
private readonly ImageSource fontIconLove;
private readonly ImageSource fontIconNotLove;
private IllustUgoiraData ugoiraData;
private Ugoira ugoira;
public ViewIllustPage(IllustItem illust, bool save)
{
@@ -98,6 +100,12 @@ namespace Pixiview.Illust
{
base.OnDisappearing();
if (ugoira != null)
{
ugoira.TogglePlay(false);
IllustItem.IsPlaying = false;
}
if (saveFavorites)
{
Stores.SaveFavoritesIllusts();
@@ -127,6 +135,7 @@ namespace Pixiview.Illust
{
items[i] = new IllustDetailItem
{
Id = illust.Id,
LongPressed = longPressed
};
if (i == 0)
@@ -159,6 +168,7 @@ namespace Pixiview.Illust
{
tmp[i] = new IllustDetailItem
{
Id = illustItem.Id,
LongPressed = longPressed
};
}
@@ -197,6 +207,11 @@ namespace Pixiview.Illust
{
DoLoadImage(1);
}
else if (illustItem.IllustType == IllustType.Anime)
{
// anime
ugoiraData = Stores.LoadIllustUgoiraData(illustItem.Id);
}
}
private void DoLoadImage(int index, bool force = false)
@@ -268,6 +283,40 @@ namespace Pixiview.Illust
}
}
private void Image_Tapped(object sender, EventArgs e)
{
if (ugoiraData == null)
{
return;
}
var illustItem = IllustItem;
if (ugoira != null)
{
var playing = !ugoira.IsPlaying;
ugoira.TogglePlay(playing);
illustItem.IsPlaying = playing;
}
else if (((Image)sender).BindingContext is IllustDetailItem item)
{
if (illustItem.IsPlaying ||
illustItem.IllustType != IllustType.Anime)
{
return;
}
ugoira = new Ugoira(ugoiraData, item);
ugoira.FrameChanged += OnUgoiraFrameChanged;
illustItem.IsPlaying = true;
ugoira.TogglePlay(true);
}
}
private void OnUgoiraFrameChanged(object sender, UgoiraEventArgs e)
{
e.DetailItem.Image = e.Image;
}
private async void Illust_LongPressed(IllustDetailItem item)
{
List<string> extras = new List<string>();
@@ -380,6 +429,7 @@ namespace Pixiview.Illust
get => (bool)GetValue(DownloadingProperty);
set => SetValue(DownloadingProperty, value);
}
public string Id { get; set; }
public ICommand LongPressed { get; set; }
public string PreviewUrl { get; set; }
public string OriginalUrl { get; set; }