feature: favorites type filter
This commit is contained in:
@ -7,6 +7,32 @@
|
|||||||
x:Class="Pixiview.Illust.FavoritesPage"
|
x:Class="Pixiview.Illust.FavoritesPage"
|
||||||
BackgroundColor="{DynamicResource WindowColor}"
|
BackgroundColor="{DynamicResource WindowColor}"
|
||||||
Title="{r:Text Favorites}">
|
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>
|
<ContentPage.ToolbarItems>
|
||||||
<ToolbarItem Order="Primary" Clicked="Refresh_Clicked"
|
<ToolbarItem Order="Primary" Clicked="Refresh_Clicked"
|
||||||
IconImageSource="{DynamicResource FontIconCloudDownload}"/>
|
IconImageSource="{DynamicResource FontIconCloudDownload}"/>
|
||||||
@ -30,5 +56,25 @@
|
|||||||
IsVisible="{Binding IsBottomLoading}"/>
|
IsVisible="{Binding IsBottomLoading}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</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>
|
</Grid>
|
||||||
</i:FavoriteIllustCollectionPage>
|
</i:FavoriteIllustCollectionPage>
|
||||||
|
@ -14,6 +14,22 @@ namespace Pixiview.Illust
|
|||||||
{
|
{
|
||||||
private const int STEP = 20;
|
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 startIndex;
|
||||||
private int nextIndex;
|
private int nextIndex;
|
||||||
private bool flag = false;
|
private bool flag = false;
|
||||||
@ -22,6 +38,8 @@ namespace Pixiview.Illust
|
|||||||
{
|
{
|
||||||
Resources.Add("cardView", GetCardViewTemplate());
|
Resources.Add("cardView", GetCardViewTemplate());
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
gridFilter.TranslationY = -60;
|
||||||
|
panelFilter.TranslationY = -60;
|
||||||
|
|
||||||
startIndex = -1;
|
startIndex = -1;
|
||||||
nextIndex = 0;
|
nextIndex = 0;
|
||||||
@ -35,7 +53,6 @@ namespace Pixiview.Illust
|
|||||||
if (lastUpdated != LastUpdated)
|
if (lastUpdated != LastUpdated)
|
||||||
{
|
{
|
||||||
startIndex = -1;
|
startIndex = -1;
|
||||||
nextIndex = 0;
|
|
||||||
StartLoad();
|
StartLoad();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -45,7 +62,6 @@ namespace Pixiview.Illust
|
|||||||
{
|
{
|
||||||
lastUpdated = default;
|
lastUpdated = default;
|
||||||
startIndex = -1;
|
startIndex = -1;
|
||||||
nextIndex = 0;
|
|
||||||
StartLoad();
|
StartLoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +74,7 @@ namespace Pixiview.Illust
|
|||||||
|
|
||||||
protected override IllustItem[] DoLoadIllustData(bool force)
|
protected override IllustItem[] DoLoadIllustData(bool force)
|
||||||
{
|
{
|
||||||
FavoriteList favs;
|
IEnumerable<IllustItem> favs;
|
||||||
if (startIndex < 0)
|
if (startIndex < 0)
|
||||||
{
|
{
|
||||||
var favorites = Stores.GetFavoriteObject(flag);
|
var favorites = Stores.GetFavoriteObject(flag);
|
||||||
@ -67,14 +83,22 @@ namespace Pixiview.Illust
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
favs = favorites.Illusts;
|
favs = favorites.Illusts.Reload();
|
||||||
favs.Reload();
|
|
||||||
startIndex = 0;
|
startIndex = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
favs = Stores.Favorites;
|
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();
|
var illusts = favs.Skip(startIndex).Take(STEP).ToArray();
|
||||||
nextIndex = startIndex + STEP;
|
nextIndex = startIndex + STEP;
|
||||||
if (illusts.Length == 0 || nextIndex >= Stores.Favorites.Count)
|
if (illusts.Length == 0 || nextIndex >= Stores.Favorites.Count)
|
||||||
@ -85,6 +109,53 @@ namespace Pixiview.Illust
|
|||||||
return illusts;
|
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)
|
private void FlowLayout_MaxHeightChanged(object sender, HeightEventArgs e)
|
||||||
{
|
{
|
||||||
SetOffset(e.ContentHeight - scrollView.Bounds.Height - SCROLL_OFFSET);
|
SetOffset(e.ContentHeight - scrollView.Bounds.Height - SCROLL_OFFSET);
|
||||||
@ -103,6 +174,14 @@ namespace Pixiview.Illust
|
|||||||
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
|
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
|
||||||
{
|
{
|
||||||
var y = e.ScrollY;
|
var y = e.ScrollY;
|
||||||
|
if (IsScrollingDown(y))
|
||||||
|
{
|
||||||
|
// down
|
||||||
|
if (isFilterVisible)
|
||||||
|
{
|
||||||
|
ToggleFilterPanel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
OnScrolled(y);
|
OnScrolled(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +193,6 @@ namespace Pixiview.Illust
|
|||||||
flag = true;
|
flag = true;
|
||||||
}
|
}
|
||||||
startIndex = -1;
|
startIndex = -1;
|
||||||
nextIndex = 0;
|
|
||||||
StartLoad(force);
|
StartLoad(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,6 +630,7 @@ namespace Pixiview.Illust
|
|||||||
public abstract class IllustScrollableCollectionPage<T> : IllustCollectionPage<T>
|
public abstract class IllustScrollableCollectionPage<T> : IllustCollectionPage<T>
|
||||||
{
|
{
|
||||||
protected const int SCROLL_OFFSET = 33;
|
protected const int SCROLL_OFFSET = 33;
|
||||||
|
protected ScrollDirection scrollDirection = ScrollDirection.Stop;
|
||||||
|
|
||||||
private double lastScrollY = double.MinValue;
|
private double lastScrollY = double.MinValue;
|
||||||
private double lastRefreshY = double.MinValue;
|
private double lastRefreshY = double.MinValue;
|
||||||
@ -637,7 +638,22 @@ namespace Pixiview.Illust
|
|||||||
|
|
||||||
protected bool IsScrollingDown(double y)
|
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)
|
protected void SetOffset(double off)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,6 @@ namespace Pixiview.Illust
|
|||||||
private bool previousEnabled;
|
private bool previousEnabled;
|
||||||
private bool dateEnabled;
|
private bool dateEnabled;
|
||||||
private bool nextEnabled;
|
private bool nextEnabled;
|
||||||
private ScrollDirection scrollDirection = ScrollDirection.Stop;
|
|
||||||
|
|
||||||
private bool isFilterVisible;
|
private bool isFilterVisible;
|
||||||
private string lastQueryKey;
|
private string lastQueryKey;
|
||||||
@ -332,23 +331,12 @@ namespace Pixiview.Illust
|
|||||||
var y = e.ScrollY;
|
var y = e.ScrollY;
|
||||||
if (IsScrollingDown(y))
|
if (IsScrollingDown(y))
|
||||||
{
|
{
|
||||||
if (scrollDirection != ScrollDirection.Down)
|
|
||||||
{
|
|
||||||
scrollDirection = ScrollDirection.Down;
|
|
||||||
}
|
|
||||||
// down
|
// down
|
||||||
if (isFilterVisible)
|
if (isFilterVisible)
|
||||||
{
|
{
|
||||||
ToggleFilterPanel(false);
|
ToggleFilterPanel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (scrollDirection != ScrollDirection.Up)
|
|
||||||
{
|
|
||||||
scrollDirection = ScrollDirection.Up;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OnScrolled(y);
|
OnScrolled(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,4 +59,7 @@
|
|||||||
<FailedResponse>无法获取返回结果。</FailedResponse>
|
<FailedResponse>无法获取返回结果。</FailedResponse>
|
||||||
<ConfirmSyncFavorite>要同步收藏吗?</ConfirmSyncFavorite>
|
<ConfirmSyncFavorite>要同步收藏吗?</ConfirmSyncFavorite>
|
||||||
<ConfirmLogin>当前身份为游客,是否跳转到登录页面?</ConfirmLogin>
|
<ConfirmLogin>当前身份为游客,是否跳转到登录页面?</ConfirmLogin>
|
||||||
|
<All>所有</All>
|
||||||
|
<Animation>动画</Animation>
|
||||||
|
<Online>在线</Online>
|
||||||
</root>
|
</root>
|
@ -675,9 +675,10 @@ namespace Pixiview.Utils
|
|||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reload()
|
public FavoriteList Reload()
|
||||||
{
|
{
|
||||||
Changed = false;
|
Changed = false;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user