feature: view related illusts
This commit is contained in:
@@ -14,8 +14,9 @@ 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 abstract class IllustRankingDataCollectionPage : IllustScrollableCollectionPage<IllustRankingData> { }
|
||||
public abstract class IllustRecommendsCollectionPage : IllustScrollableCollectionPage<IllustRecommendsData> { }
|
||||
|
||||
public interface IIllustCollectionPage
|
||||
{
|
||||
@@ -499,6 +500,68 @@ namespace Pixiview.Illust
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class IllustScrollableCollectionPage<T> : IllustCollectionPage<T>
|
||||
{
|
||||
protected const int SCROLL_OFFSET = 33;
|
||||
protected static readonly object sync = new object();
|
||||
|
||||
private double lastScrollY = double.MinValue;
|
||||
private double offset;
|
||||
|
||||
protected bool ScrollingDown(double y)
|
||||
{
|
||||
return y > lastScrollY;
|
||||
}
|
||||
protected void SetOffset(double off)
|
||||
{
|
||||
offset = off;
|
||||
}
|
||||
|
||||
protected abstract bool CheckRefresh();
|
||||
|
||||
protected override void DoIllustsLoaded(IllustCollection collection)
|
||||
{
|
||||
var now = IllustCollection;
|
||||
if (now == null)
|
||||
{
|
||||
IllustCollection = collection;
|
||||
Illusts = collection;
|
||||
}
|
||||
else
|
||||
{
|
||||
now = new IllustCollection(now.Concat(collection));
|
||||
IllustCollection = now;
|
||||
Illusts = now;
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnScrolled(double y)
|
||||
{
|
||||
lastScrollY = y;
|
||||
|
||||
if (y > 0 && offset > 0 && y - topOffset > offset)
|
||||
{
|
||||
bool refresh = false;
|
||||
lock (sync)
|
||||
{
|
||||
if (IsLoading)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (CheckRefresh())
|
||||
{
|
||||
refresh = true;
|
||||
}
|
||||
}
|
||||
if (refresh)
|
||||
{
|
||||
App.DebugPrint("start to load next page");
|
||||
StartLoad(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ScrollDirection
|
||||
{
|
||||
Stop,
|
||||
|
@@ -37,6 +37,10 @@ namespace Pixiview.Illust
|
||||
|
||||
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data)
|
||||
{
|
||||
if (data.body == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return data.body.page.follow.Select(i =>
|
||||
data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == i.ToString())?.ConvertToItem());
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@
|
||||
HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
|
||||
<u:FlowLayout ItemsSource="{Binding Illusts}" MaxHeightChanged="FlowLayout_MaxHeightChanged"
|
||||
HorizontalOptions="Fill" Column="{Binding Columns}"
|
||||
Margin="16, 16, 16, 16" RowSpacing="16" ColumnSpacing="16"
|
||||
Margin="16" RowSpacing="16" ColumnSpacing="16"
|
||||
ItemTemplate="{StaticResource cardView}"/>
|
||||
</ScrollView>
|
||||
<u:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
|
||||
|
@@ -13,7 +13,6 @@ namespace Pixiview.Illust
|
||||
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 SegmentDateProperty = BindableProperty.Create(
|
||||
nameof(SegmentDate), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentDatePropertyChanged);
|
||||
@@ -77,11 +76,9 @@ namespace Pixiview.Illust
|
||||
}
|
||||
public Command<string> ToolbarCommand { get; private set; }
|
||||
|
||||
private double lastScrollY = double.MinValue;
|
||||
private bool previousEnabled;
|
||||
private bool dateEnabled;
|
||||
private bool nextEnabled;
|
||||
private double offset;
|
||||
|
||||
private bool isFilterVisible;
|
||||
private string lastQueryKey;
|
||||
@@ -111,8 +108,6 @@ namespace Pixiview.Illust
|
||||
currentPage = 1;
|
||||
datePicker.MinimumDate = new DateTime(2007, 9, 13);
|
||||
MaximumDate = DateTime.Now;
|
||||
|
||||
App.DebugPrint("page loaded.");
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
@@ -128,30 +123,6 @@ namespace Pixiview.Illust
|
||||
}
|
||||
}
|
||||
|
||||
private void FlowLayout_MaxHeightChanged(object sender, HeightEventArgs e)
|
||||
{
|
||||
if (e.ContentHeight > 0)
|
||||
{
|
||||
offset = e.ContentHeight - scrollView.Bounds.Height - 33;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoIllustsLoaded(IllustCollection collection)
|
||||
{
|
||||
var now = IllustCollection;
|
||||
if (now == null)
|
||||
{
|
||||
IllustCollection = collection;
|
||||
Illusts = collection;
|
||||
}
|
||||
else
|
||||
{
|
||||
now = new IllustCollection(now.Concat(collection));
|
||||
IllustCollection = now;
|
||||
Illusts = now;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRankingData data)
|
||||
{
|
||||
return data.contents.Select(i => i.ConvertToItem());
|
||||
@@ -162,10 +133,6 @@ namespace Pixiview.Illust
|
||||
var data = Stores.LoadIllustRankingData(lastQueryKey, queryDate, currentPage, force);
|
||||
if (data != null)
|
||||
{
|
||||
//if (data.contents.Length * data.page < data.rank_total)
|
||||
//{
|
||||
// nextPage = currentPage + 1;
|
||||
//}
|
||||
if (int.TryParse(data.next, out int next))
|
||||
{
|
||||
nextPage = next;
|
||||
@@ -330,10 +297,29 @@ namespace Pixiview.Illust
|
||||
ToggleFilterPanel(!isFilterVisible);
|
||||
}
|
||||
|
||||
private void FlowLayout_MaxHeightChanged(object sender, HeightEventArgs e)
|
||||
{
|
||||
if (e.ContentHeight > 0)
|
||||
{
|
||||
SetOffset(e.ContentHeight - scrollView.Bounds.Height - SCROLL_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CheckRefresh()
|
||||
{
|
||||
if (nextPage == currentPage + 1)
|
||||
{
|
||||
currentPage = nextPage;
|
||||
App.DebugPrint($"loading page {nextPage}");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
|
||||
{
|
||||
var y = e.ScrollY;
|
||||
if (y > lastScrollY)
|
||||
if (ScrollingDown(y))
|
||||
{
|
||||
// down
|
||||
if (isFilterVisible)
|
||||
@@ -341,31 +327,7 @@ namespace Pixiview.Illust
|
||||
ToggleFilterPanel(false);
|
||||
}
|
||||
}
|
||||
lastScrollY = y;
|
||||
|
||||
if (y > 0 && offset > 0 && y - topOffset > offset)
|
||||
{
|
||||
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)
|
||||
{
|
||||
App.DebugPrint($"start to load page {nextPage}");
|
||||
StartLoad(true);
|
||||
}
|
||||
}
|
||||
OnScrolled(y);
|
||||
}
|
||||
|
||||
private void Filter_Clicked(object sender, EventArgs e)
|
||||
|
@@ -183,6 +183,10 @@ namespace Pixiview.Illust
|
||||
|
||||
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data)
|
||||
{
|
||||
if (data.body == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return data.body.page.recommend.Select(id =>
|
||||
data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem());
|
||||
}
|
||||
|
26
Pixiview/Illust/RelatedIllustsPage.xaml
Normal file
26
Pixiview/Illust/RelatedIllustsPage.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<i:IllustRecommendsCollectionPage 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.RelatedIllustsPage"
|
||||
Title="{r:Text RelatedIllusts}"
|
||||
BackgroundColor="{DynamicResource WindowColor}">
|
||||
<Grid>
|
||||
<ScrollView x:Name="scrollView" Scrolled="ScrollView_Scrolled"
|
||||
HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
|
||||
<u:FlowLayout ItemsSource="{Binding Illusts}" MaxHeightChanged="FlowLayout_MaxHeightChanged"
|
||||
HorizontalOptions="Fill" Column="{Binding Columns}"
|
||||
Margin="16" RowSpacing="16" ColumnSpacing="16"
|
||||
ItemTemplate="{StaticResource cardView}"/>
|
||||
</ScrollView>
|
||||
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
|
||||
IsVisible="{Binding IsLoading}"
|
||||
HorizontalOptions="Center" VerticalOptions="Center"
|
||||
BackgroundColor="{DynamicResource MaskColor}">
|
||||
<ActivityIndicator IsRunning="True" IsVisible="True"
|
||||
Color="{DynamicResource WindowColor}"/>
|
||||
</Frame>
|
||||
</Grid>
|
||||
</i:IllustRecommendsCollectionPage>
|
92
Pixiview/Illust/RelatedIllustsPage.xaml.cs
Normal file
92
Pixiview/Illust/RelatedIllustsPage.xaml.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Pixiview.UI;
|
||||
using Pixiview.Utils;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Pixiview.Illust
|
||||
{
|
||||
public partial class RelatedIllustsPage : IllustRecommendsCollectionPage
|
||||
{
|
||||
private readonly IllustItem illustItem;
|
||||
private int startIndex;
|
||||
private int nextIndex;
|
||||
private string[] illustIds;
|
||||
|
||||
public RelatedIllustsPage(IllustItem item)
|
||||
{
|
||||
illustItem = item;
|
||||
|
||||
Resources.Add("cardView", GetCardViewTemplate());
|
||||
InitializeComponent();
|
||||
|
||||
startIndex = -1;
|
||||
nextIndex = 0;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRecommendsData data)
|
||||
{
|
||||
if (data.body == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return data.body.illusts.Select(i => i.ConvertToItem());
|
||||
}
|
||||
|
||||
protected override IllustRecommendsData DoLoadIllustData(bool force)
|
||||
{
|
||||
IllustRecommendsData data;
|
||||
if (startIndex < 0)
|
||||
{
|
||||
// init
|
||||
data = Stores.LoadIllustRecommendsInitData(illustItem.Id, force);
|
||||
if (data == null || data.body == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
illustIds = data.body.nextIds;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (illustIds == null || startIndex >= illustIds.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var ids = illustIds.Skip(startIndex).Take(18).ToArray();
|
||||
nextIndex = startIndex + ids.Length;
|
||||
if (ids.Length == 0 || nextIndex >= illustIds.Length)
|
||||
{
|
||||
// done
|
||||
App.DebugPrint($"download completed: {startIndex}");
|
||||
return null;
|
||||
}
|
||||
data = Stores.LoadIllustRecommendsListData(illustItem.Id, ids);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void FlowLayout_MaxHeightChanged(object sender, HeightEventArgs e)
|
||||
{
|
||||
if (e.ContentHeight > 0)
|
||||
{
|
||||
SetOffset(e.ContentHeight - scrollView.Bounds.Height - SCROLL_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CheckRefresh()
|
||||
{
|
||||
if (nextIndex > startIndex)
|
||||
{
|
||||
startIndex = nextIndex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
|
||||
{
|
||||
var y = e.ScrollY;
|
||||
OnScrolled(y);
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,6 +30,10 @@ namespace Pixiview.Illust
|
||||
|
||||
protected override IEnumerable<IllustItem> DoGetIllustList(IllustUserData data)
|
||||
{
|
||||
if (data.body == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return data.body.works.Select(i => i.Value?.ConvertToItem());
|
||||
}
|
||||
|
||||
|
@@ -509,9 +509,11 @@ namespace Pixiview.Illust
|
||||
{
|
||||
extras.Add(share);
|
||||
}
|
||||
var saveOriginal = ResourceHelper.SaveOriginal;
|
||||
var userDetail = ResourceHelper.UserDetail;
|
||||
extras.Add(userDetail);
|
||||
var related = ResourceHelper.RelatedIllusts;
|
||||
extras.Add(related);
|
||||
var saveOriginal = ResourceHelper.SaveOriginal;
|
||||
|
||||
var illustItem = IllustItem;
|
||||
var result = await DisplayActionSheet(
|
||||
@@ -536,6 +538,11 @@ namespace Pixiview.Illust
|
||||
var page = new UserIllustPage(illustItem);
|
||||
await Navigation.PushAsync(page);
|
||||
}
|
||||
else if (result == related)
|
||||
{
|
||||
var page = new RelatedIllustsPage(illustItem);
|
||||
await Navigation.PushAsync(page);
|
||||
}
|
||||
}
|
||||
|
||||
private async void SaveOriginalImage(IllustDetailItem item)
|
||||
|
Reference in New Issue
Block a user