* 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:
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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}"
|
||||
|
@@ -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; }
|
||||
|
Reference in New Issue
Block a user