feature: favorites type filter

This commit is contained in:
Tsanie Lily 2020-05-20 01:17:11 +08:00
parent d1ea0243b8
commit 34a8d5f434
6 changed files with 152 additions and 20 deletions

View File

@ -7,6 +7,32 @@
x:Class="Pixiview.Illust.FavoritesPage"
BackgroundColor="{DynamicResource WindowColor}"
Title="{r:Text Favorites}">
<Shell.TitleView>
<Grid VerticalOptions="Fill" ColumnSpacing="6"
HorizontalOptions="{x:OnPlatform Android=Start, iOS=Fill}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{OnPlatform Android=Auto}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="1" Orientation="Horizontal" Spacing="6">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</StackLayout.GestureRecognizers>
<Label Text="{Binding Title}"
TextColor="{DynamicResource TextColor}"
FontSize="{OnPlatform Android=18}"
LineBreakMode="HeadTruncation"
VerticalTextAlignment="Center" FontAttributes="Bold"/>
<Label x:Name="labelCaret"
Text="{DynamicResource IconCaretDown}"
TextColor="{DynamicResource TextColor}"
FontFamily="{DynamicResource IconSolidFontFamily}"
FontSize="Small"
VerticalTextAlignment="Center"/>
</StackLayout>
</Grid>
</Shell.TitleView>
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" Clicked="Refresh_Clicked"
IconImageSource="{DynamicResource FontIconCloudDownload}"/>
@ -30,5 +56,25 @@
IsVisible="{Binding IsBottomLoading}"/>
</StackLayout>
</ScrollView>
<u:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
Margin="{Binding PanelTopMargin}"
BackgroundColor="{DynamicResource WindowColor}"
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">
<u:SegmentedControl Margin="6, 6, 6, 3" VerticalOptions="Center"
SelectedSegmentIndex="{Binding SegmentType, Mode=TwoWay}"
SelectedTextColor="{DynamicResource TextColor}"
TintColor="{DynamicResource CardBackgroundColor}">
<u:SegmentedControl.Children>
<u:SegmentedControlOption Text="{r:Text All}"/>
<u:SegmentedControlOption Text="{r:Text Animation}"/>
<u:SegmentedControlOption Text="{r:Text Online}"/>
</u:SegmentedControl.Children>
</u:SegmentedControl>
</Grid>
</Grid>
</Grid>
</i:FavoriteIllustCollectionPage>

View File

@ -14,6 +14,22 @@ namespace Pixiview.Illust
{
private const int STEP = 20;
public static readonly BindableProperty SegmentTypeProperty = BindableProperty.Create(
nameof(SegmentType), typeof(int), typeof(FavoritesPage), propertyChanged: OnSegmentTypePropertyChanged);
private static void OnSegmentTypePropertyChanged(BindableObject obj, object old, object @new)
{
var page = (FavoritesPage)obj;
MainThread.BeginInvokeOnMainThread(page.ChangeFilter);
}
public int SegmentType
{
get => (int)GetValue(SegmentTypeProperty);
set => SetValue(SegmentTypeProperty, value);
}
private bool isFilterVisible;
private int startIndex;
private int nextIndex;
private bool flag = false;
@ -22,6 +38,8 @@ namespace Pixiview.Illust
{
Resources.Add("cardView", GetCardViewTemplate());
InitializeComponent();
gridFilter.TranslationY = -60;
panelFilter.TranslationY = -60;
startIndex = -1;
nextIndex = 0;
@ -35,7 +53,6 @@ namespace Pixiview.Illust
if (lastUpdated != LastUpdated)
{
startIndex = -1;
nextIndex = 0;
StartLoad();
}
else
@ -45,7 +62,6 @@ namespace Pixiview.Illust
{
lastUpdated = default;
startIndex = -1;
nextIndex = 0;
StartLoad();
}
}
@ -58,7 +74,7 @@ namespace Pixiview.Illust
protected override IllustItem[] DoLoadIllustData(bool force)
{
FavoriteList favs;
IEnumerable<IllustItem> favs;
if (startIndex < 0)
{
var favorites = Stores.GetFavoriteObject(flag);
@ -67,14 +83,22 @@ namespace Pixiview.Illust
{
return null;
}
favs = favorites.Illusts;
favs.Reload();
favs = favorites.Illusts.Reload();
startIndex = 0;
}
else
{
favs = Stores.Favorites;
}
switch (SegmentType)
{
case 1: // animation
favs = favs.Where(f => f.IllustType == IllustType.Anime);
break;
case 2: // online
favs = favs.Where(f => f.BookmarkId != null);
break;
}
var illusts = favs.Skip(startIndex).Take(STEP).ToArray();
nextIndex = startIndex + STEP;
if (illusts.Length == 0 || nextIndex >= Stores.Favorites.Count)
@ -85,6 +109,53 @@ namespace Pixiview.Illust
return illusts;
}
private async void ToggleFilterPanel(bool flag)
{
ViewExtensions.CancelAnimations(gridFilter);
ViewExtensions.CancelAnimations(panelFilter);
if (flag)
{
isFilterVisible = true;
if (scrollDirection == ScrollDirection.Down)
{
// stop the scrolling
await scrollView.ScrollToAsync(scrollView.ScrollX, scrollView.ScrollY, false);
}
await Task.WhenAll(
labelCaret.RotateTo(180, easing: Easing.CubicOut),
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;
await Task.WhenAll(
labelCaret.RotateTo(0, easing: Easing.CubicIn),
gridFilter.TranslateTo(0, -60, easing: Easing.CubicIn),
gridFilter.FadeTo(0, easing: Easing.CubicIn),
panelFilter.TranslateTo(0, -60, easing: Easing.CubicIn),
panelFilter.FadeTo(0, easing: Easing.CubicIn)
);
}
}
private async void ChangeFilter()
{
ToggleFilterPanel(false);
await ScrollToTopAsync(scrollView);
startIndex = 0;
lastUpdated = default;
StartLoad();
}
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
ToggleFilterPanel(!isFilterVisible);
}
private void FlowLayout_MaxHeightChanged(object sender, HeightEventArgs e)
{
SetOffset(e.ContentHeight - scrollView.Bounds.Height - SCROLL_OFFSET);
@ -103,6 +174,14 @@ namespace Pixiview.Illust
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
var y = e.ScrollY;
if (IsScrollingDown(y))
{
// down
if (isFilterVisible)
{
ToggleFilterPanel(false);
}
}
OnScrolled(y);
}
@ -114,7 +193,6 @@ namespace Pixiview.Illust
flag = true;
}
startIndex = -1;
nextIndex = 0;
StartLoad(force);
}

View File

@ -630,6 +630,7 @@ namespace Pixiview.Illust
public abstract class IllustScrollableCollectionPage<T> : IllustCollectionPage<T>
{
protected const int SCROLL_OFFSET = 33;
protected ScrollDirection scrollDirection = ScrollDirection.Stop;
private double lastScrollY = double.MinValue;
private double lastRefreshY = double.MinValue;
@ -637,7 +638,22 @@ namespace Pixiview.Illust
protected bool IsScrollingDown(double y)
{
return y > lastScrollY;
if (y > lastScrollY)
{
if (scrollDirection != ScrollDirection.Down)
{
scrollDirection = ScrollDirection.Down;
}
return true;
}
else
{
if (scrollDirection != ScrollDirection.Up)
{
scrollDirection = ScrollDirection.Up;
}
return false;
}
}
protected void SetOffset(double off)
{

View File

@ -86,7 +86,6 @@ namespace Pixiview.Illust
private bool previousEnabled;
private bool dateEnabled;
private bool nextEnabled;
private ScrollDirection scrollDirection = ScrollDirection.Stop;
private bool isFilterVisible;
private string lastQueryKey;
@ -332,23 +331,12 @@ namespace Pixiview.Illust
var y = e.ScrollY;
if (IsScrollingDown(y))
{
if (scrollDirection != ScrollDirection.Down)
{
scrollDirection = ScrollDirection.Down;
}
// down
if (isFilterVisible)
{
ToggleFilterPanel(false);
}
}
else
{
if (scrollDirection != ScrollDirection.Up)
{
scrollDirection = ScrollDirection.Up;
}
}
OnScrolled(y);
}

View File

@ -59,4 +59,7 @@
<FailedResponse>无法获取返回结果。</FailedResponse>
<ConfirmSyncFavorite>要同步收藏吗?</ConfirmSyncFavorite>
<ConfirmLogin>当前身份为游客,是否跳转到登录页面?</ConfirmLogin>
<All>所有</All>
<Animation>动画</Animation>
<Online>在线</Online>
</root>

View File

@ -675,9 +675,10 @@ namespace Pixiview.Utils
Changed = true;
}
public void Reload()
public FavoriteList Reload()
{
Changed = false;
return this;
}
}