feature: user illusts page
This commit is contained in:
		| @@ -14,9 +14,9 @@ namespace Pixiview.Illust | |||||||
| { | { | ||||||
|     public abstract class FavoriteIllustCollectionPage : IllustCollectionPage<IllustItem[]> { } |     public abstract class FavoriteIllustCollectionPage : IllustCollectionPage<IllustItem[]> { } | ||||||
|     public abstract class IllustDataCollectionPage : IllustCollectionPage<IllustData> { } |     public abstract class IllustDataCollectionPage : IllustCollectionPage<IllustData> { } | ||||||
|     public abstract class IllustUserDataCollectionPage : IllustCollectionPage<IllustUserData> { } |  | ||||||
|     public abstract class IllustRankingDataCollectionPage : IllustScrollableCollectionPage<IllustRankingData> { } |     public abstract class IllustRankingDataCollectionPage : IllustScrollableCollectionPage<IllustRankingData> { } | ||||||
|     public abstract class IllustRecommendsCollectionPage : IllustScrollableCollectionPage<IllustRecommendsData> { } |     public abstract class IllustRecommendsCollectionPage : IllustScrollableCollectionPage<IllustRecommendsData> { } | ||||||
|  |     public abstract class IllustUserDataCollectionPage : IllustScrollableCollectionPage<IllustUserData> { } | ||||||
|  |  | ||||||
|     public interface IIllustCollectionPage |     public interface IIllustCollectionPage | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -61,7 +61,6 @@ namespace Pixiview.Illust | |||||||
|                 if (ids.Length == 0 || nextIndex >= illustIds.Length) |                 if (ids.Length == 0 || nextIndex >= illustIds.Length) | ||||||
|                 { |                 { | ||||||
|                     // done |                     // done | ||||||
|  |  | ||||||
|                     App.DebugPrint($"download completed: {startIndex}"); |                     App.DebugPrint($"download completed: {startIndex}"); | ||||||
|                     startIndex = nextIndex; |                     startIndex = nextIndex; | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -6,9 +6,10 @@ | |||||||
|                                 x:Class="Pixiview.Illust.UserIllustPage" |                                 x:Class="Pixiview.Illust.UserIllustPage" | ||||||
|                                 BackgroundColor="{DynamicResource WindowColor}"> |                                 BackgroundColor="{DynamicResource WindowColor}"> | ||||||
|     <Shell.TitleView> |     <Shell.TitleView> | ||||||
|         <StackLayout Orientation="Horizontal" Padding="0, 2, 0, 4"> |         <StackLayout Orientation="Horizontal"> | ||||||
|             <u:CircleImage Aspect="AspectFill" Source="{Binding UserIcon}" |             <u:CircleImage Aspect="AspectFill" Source="{Binding UserIcon}" | ||||||
|                            WidthRequest="{x:OnPlatform Android=40}"> |                            VerticalOptions="Center" | ||||||
|  |                            WidthRequest="34" HeightRequest="34" > | ||||||
|                 <u:CircleImage.Margin> |                 <u:CircleImage.Margin> | ||||||
|                     <OnPlatform x:TypeArguments="Thickness" Android="0, 5, 0, 5"/> |                     <OnPlatform x:TypeArguments="Thickness" Android="0, 5, 0, 5"/> | ||||||
|                 </u:CircleImage.Margin> |                 </u:CircleImage.Margin> | ||||||
| @@ -23,8 +24,9 @@ | |||||||
|                      IconImageSource="{DynamicResource FontIconRefresh}"/> |                      IconImageSource="{DynamicResource FontIconRefresh}"/> | ||||||
|     </ContentPage.ToolbarItems> |     </ContentPage.ToolbarItems> | ||||||
|     <Grid> |     <Grid> | ||||||
|         <ScrollView HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never"> |         <ScrollView x:Name="scrollView" Scrolled="ScrollView_Scrolled" | ||||||
|             <u:FlowLayout ItemsSource="{Binding Illusts}" |                     HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never"> | ||||||
|  |             <u:FlowLayout ItemsSource="{Binding Illusts}" MaxHeightChanged="FlowLayout_MaxHeightChanged" | ||||||
|                           HorizontalOptions="Fill" Column="{Binding Columns}" |                           HorizontalOptions="Fill" Column="{Binding Columns}" | ||||||
|                           Margin="16" RowSpacing="16" ColumnSpacing="16" |                           Margin="16" RowSpacing="16" ColumnSpacing="16" | ||||||
|                           ItemTemplate="{StaticResource cardView}"/> |                           ItemTemplate="{StaticResource cardView}"/> | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Linq; | using System.Linq; | ||||||
|  | using Pixiview.UI; | ||||||
| using Pixiview.Utils; | using Pixiview.Utils; | ||||||
| using Xamarin.Forms; | using Xamarin.Forms; | ||||||
|  |  | ||||||
| @@ -8,6 +9,8 @@ namespace Pixiview.Illust | |||||||
| { | { | ||||||
|     public partial class UserIllustPage : IllustUserDataCollectionPage |     public partial class UserIllustPage : IllustUserDataCollectionPage | ||||||
|     { |     { | ||||||
|  |         private const int STEP = 48; | ||||||
|  |  | ||||||
|         public static readonly BindableProperty UserIconProperty = BindableProperty.Create( |         public static readonly BindableProperty UserIconProperty = BindableProperty.Create( | ||||||
|             nameof(UserIcon), typeof(ImageSource), typeof(UserIllustPage)); |             nameof(UserIcon), typeof(ImageSource), typeof(UserIllustPage)); | ||||||
|  |  | ||||||
| @@ -19,6 +22,10 @@ namespace Pixiview.Illust | |||||||
|  |  | ||||||
|         public IIllustUser UserItem { get; } |         public IIllustUser UserItem { get; } | ||||||
|  |  | ||||||
|  |         private int startIndex; | ||||||
|  |         private int nextIndex; | ||||||
|  |         private string[] illustIds; | ||||||
|  |  | ||||||
|         public UserIllustPage(IIllustUser item) |         public UserIllustPage(IIllustUser item) | ||||||
|         { |         { | ||||||
|             UserItem = item; |             UserItem = item; | ||||||
| @@ -26,6 +33,9 @@ namespace Pixiview.Illust | |||||||
|  |  | ||||||
|             Resources.Add("cardView", GetCardViewTemplate(true)); |             Resources.Add("cardView", GetCardViewTemplate(true)); | ||||||
|             InitializeComponent(); |             InitializeComponent(); | ||||||
|  |  | ||||||
|  |             startIndex = -1; | ||||||
|  |             nextIndex = 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         protected override IEnumerable<IllustItem> DoGetIllustList(IllustUserData data) |         protected override IEnumerable<IllustItem> DoGetIllustList(IllustUserData data) | ||||||
| @@ -39,7 +49,56 @@ namespace Pixiview.Illust | |||||||
|  |  | ||||||
|         protected override IllustUserData DoLoadIllustData(bool force) |         protected override IllustUserData DoLoadIllustData(bool force) | ||||||
|         { |         { | ||||||
|             return Stores.LoadIllustUserData(UserItem.UserId, force); |             var userId = UserItem.UserId; | ||||||
|  |             if (startIndex < 0) | ||||||
|  |             { | ||||||
|  |                 var init = Stores.LoadIllustUserInitData(userId); | ||||||
|  |                 if (init == null || init.body == null) | ||||||
|  |                 { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 illustIds = init.body.illusts.Keys.OrderByDescending(i => i).ToArray(); | ||||||
|  |                 startIndex = 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (illustIds == null || startIndex >= illustIds.Length) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             var ids = illustIds.Skip(startIndex).Take(STEP).ToArray(); | ||||||
|  |             var data = Stores.LoadIllustUserData(userId, ids, startIndex == 0); | ||||||
|  |             nextIndex = startIndex + STEP; | ||||||
|  |             if (ids.Length == 0 || nextIndex >= illustIds.Length) | ||||||
|  |             { | ||||||
|  |                 // done | ||||||
|  |                 App.DebugPrint($"download completed: {startIndex}"); | ||||||
|  |                 startIndex = nextIndex; | ||||||
|  |             } | ||||||
|  |             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); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void Refresh_Clicked(object sender, EventArgs e) |         private void Refresh_Clicked(object sender, EventArgs e) | ||||||
| @@ -48,6 +107,16 @@ namespace Pixiview.Illust | |||||||
|             { |             { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  |             // release | ||||||
|  |             var collection = IllustCollection; | ||||||
|  |             if (collection != null) | ||||||
|  |             { | ||||||
|  |                 collection.Running = false; | ||||||
|  |                 IllustCollection = null; | ||||||
|  |             } | ||||||
|  |             startIndex = -1; | ||||||
|  |             nextIndex = 0; | ||||||
|  |             illustIds = null; | ||||||
|             StartLoad(true); |             StartLoad(true); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -341,29 +341,33 @@ namespace Pixiview.Utils | |||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static IllustUserData LoadIllustUserData(string userId, bool force = false) |         public static IllustUserListData LoadIllustUserInitData(string userId) | ||||||
|         { |         { | ||||||
|             var list = HttpUtility.LoadObject<IllustUserListData>( |             var list = HttpUtility.LoadObject<IllustUserListData>( | ||||||
|                 null, |                 null, | ||||||
|                 string.Format(Configs.UrlIllustUserAll, userId), |                 string.Format(Configs.UrlIllustUserAll, userId), | ||||||
|                 string.Format(Configs.RefererIllustUser, userId), |                 string.Format(Configs.RefererIllustUser, userId)); | ||||||
|                 force: force); |  | ||||||
|             if (list == null || list.error) |             if (list == null || list.error) | ||||||
|             { |             { | ||||||
|                 App.DebugPrint($"error when load user data: {list?.message}, force({force})"); |                 App.DebugPrint($"error when load user data: {list?.message}"); | ||||||
|  |             } | ||||||
|  |             return list; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|             // TODO |         public static IllustUserData LoadIllustUserData(string userId, string[] ids, bool firstPage) | ||||||
|             var ids = string.Join("", list.body.illusts.Keys.Take(20).Select(id => $"ids%5B%5D={id}&")); |         { | ||||||
|  |             if (ids == null || ids.Length == 0) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             var ps = string.Concat(ids.Select(i => $"ids%5B%5D={i}&")); | ||||||
|             var result = HttpUtility.LoadObject<IllustUserData>( |             var result = HttpUtility.LoadObject<IllustUserData>( | ||||||
|                 null, |                 null, | ||||||
|                 string.Format(Configs.UrlIllustUserArtworks, userId, ids, 1), |                 string.Format(Configs.UrlIllustUserArtworks, userId, ps, firstPage ? 1 : 0), | ||||||
|                 string.Format(Configs.RefererIllustUser, userId), |                 string.Format(Configs.RefererIllustUser, userId)); | ||||||
|                 force: force); |  | ||||||
|             if (result == null || result.error) |             if (result == null || result.error) | ||||||
|             { |             { | ||||||
|                 App.DebugPrint($"error when load user illust data: {result?.message}, force({force})"); |                 App.DebugPrint($"error when load user illust data: {result?.message}"); | ||||||
|             } |             } | ||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
| @@ -449,7 +453,7 @@ namespace Pixiview.Utils | |||||||
|         public const string Referer = "https://www.pixiv.net/"; |         public const string Referer = "https://www.pixiv.net/"; | ||||||
|         public const string RefererIllust = "https://www.pixiv.net/artworks/{0}"; |         public const string RefererIllust = "https://www.pixiv.net/artworks/{0}"; | ||||||
|         public const string RefererIllustRanking = "https://www.pixiv.net/ranking.php?{0}"; |         public const string RefererIllustRanking = "https://www.pixiv.net/ranking.php?{0}"; | ||||||
|         public const string RefererIllustUser = "https://www.pixiv.net/users/{0}/artworks"; |         public const string RefererIllustUser = "https://www.pixiv.net/users/{0}/illustrations"; | ||||||
|  |  | ||||||
|         public static WebProxy Proxy; |         public static WebProxy Proxy; | ||||||
|         private static string Prefix => Proxy == null ? |         private static string Prefix => Proxy == null ? | ||||||
| @@ -496,18 +500,29 @@ namespace Pixiview.Utils | |||||||
|             "first_visit_datetime_pc=2019-10-29+22%3A05%3A30; " + |             "first_visit_datetime_pc=2019-10-29+22%3A05%3A30; " + | ||||||
|             "yuid_b=NgcXQWQ"; |             "yuid_b=NgcXQWQ"; | ||||||
| #endif | #endif | ||||||
|  |         private const string URL_PREVIEW = "https://i.pximg.net/c/360x360_70"; | ||||||
|  |  | ||||||
|         public static string GetThumbnailUrl(string url) |         public static string GetThumbnailUrl(string url) | ||||||
|         { |         { | ||||||
|             url = url.Replace("/custom-thumb/", "/img-master/"); |             if (url == null) | ||||||
|  |             { | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |             url = url.ToLower().Replace("/custom-thumb/", "/img-master/"); | ||||||
|             var index = url.LastIndexOf("_square1200.jpg"); |             var index = url.LastIndexOf("_square1200.jpg"); | ||||||
|             if (index < 0) |             if (index < 0) | ||||||
|             { |             { | ||||||
|                 index = url.LastIndexOf("_custom1200.jpg"); |                 index = url.LastIndexOf("_custom1200.jpg"); | ||||||
|             } |             } | ||||||
|             if (index >= 0) |             if (index > 0) | ||||||
|             { |             { | ||||||
|                 return url.Substring(0, index) + "_master1200.jpg"; |                 url = url.Substring(0, index) + "_master1200.jpg"; | ||||||
|  |  | ||||||
|  |                 var start = url.IndexOf("/img-master/"); | ||||||
|  |                 if (start > 0) | ||||||
|  |                 { | ||||||
|  |                     url = URL_PREVIEW + url.Substring(start); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|             return url; |             return url; | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user