370 lines
13 KiB
C#
370 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Gallery.UI;
|
|
using Gallery.UI.Theme;
|
|
using Gallery.Utils;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Gallery.Illust
|
|
{
|
|
public partial class RecommendsPage : IllustDataCollectionPage
|
|
{
|
|
public static readonly BindableProperty UsersProperty = BindableProperty.Create(
|
|
nameof(Users), typeof(List<IllustUserItem>), typeof(RecommendsPage));
|
|
public static readonly BindableProperty UserColumnsProperty = BindableProperty.Create(
|
|
nameof(UserColumns), typeof(int), typeof(RecommendsPage), 1);
|
|
public static readonly BindableProperty UserRecommendsVisibleProperty = BindableProperty.Create(
|
|
nameof(UserRecommendsVisible), typeof(bool), typeof(RecommendsPage));
|
|
|
|
public List<IllustUserItem> Users
|
|
{
|
|
get => (List<IllustUserItem>)GetValue(UsersProperty);
|
|
set => SetValue(UsersProperty, value);
|
|
}
|
|
public int UserColumns
|
|
{
|
|
get => (int)GetValue(UserColumnsProperty);
|
|
set => SetValue(UserColumnsProperty, value);
|
|
}
|
|
public bool UserRecommendsVisible
|
|
{
|
|
get => (bool)GetValue(UserRecommendsVisibleProperty);
|
|
set => SetValue(UserRecommendsVisibleProperty, value);
|
|
}
|
|
|
|
private IllustData illustData;
|
|
|
|
public RecommendsPage()
|
|
{
|
|
Resources.Add("cardView", GetCardViewTemplate());
|
|
Resources.Add("userCardView", GetUserCardViewTemplate());
|
|
InitializeComponent();
|
|
}
|
|
|
|
protected override bool NeedCookie => true;
|
|
protected override ActivityIndicator LoadingIndicator => activityLoading;
|
|
|
|
public override void OnUnload()
|
|
{
|
|
base.OnUnload();
|
|
Users = null;
|
|
}
|
|
|
|
private Image GetUserCardViewImage(int column, CornerMask masks, string source, string parameter)
|
|
{
|
|
Image image;
|
|
if (masks == CornerMask.None)
|
|
{
|
|
image = new Image();
|
|
}
|
|
else
|
|
{
|
|
image = new RoundImage
|
|
{
|
|
CornerRadius = 10,
|
|
CornerMasks = masks
|
|
};
|
|
}
|
|
image.HorizontalOptions = LayoutOptions.Fill;
|
|
image.Aspect = Aspect.AspectFill;
|
|
image.GestureRecognizers.Add(new TapGestureRecognizer
|
|
{
|
|
Command = commandIllustImageTapped
|
|
}
|
|
.Binding(TapGestureRecognizer.CommandParameterProperty, parameter));
|
|
image.SetBinding(Image.SourceProperty, source);
|
|
if (column > 0)
|
|
{
|
|
Grid.SetColumn(image, column);
|
|
}
|
|
Grid.SetRow(image, 1);
|
|
return image;
|
|
}
|
|
|
|
private DataTemplate GetUserCardViewTemplate()
|
|
{
|
|
return new DataTemplate(() =>
|
|
{
|
|
return new Grid
|
|
{
|
|
RowSpacing = 0,
|
|
ColumnSpacing = 0,
|
|
RowDefinitions =
|
|
{
|
|
new RowDefinition { Height = 40 },
|
|
new RowDefinition { Height = 120 }
|
|
},
|
|
ColumnDefinitions =
|
|
{
|
|
new ColumnDefinition(),
|
|
new ColumnDefinition(),
|
|
new ColumnDefinition()
|
|
},
|
|
Children =
|
|
{
|
|
// stacklayout: user
|
|
new Grid
|
|
{
|
|
ColumnDefinitions =
|
|
{
|
|
new ColumnDefinition { Width = 30 },
|
|
new ColumnDefinition()
|
|
},
|
|
Padding = new Thickness(8, 0, 8, 8),
|
|
Children =
|
|
{
|
|
// user icon
|
|
new CircleImage
|
|
{
|
|
WidthRequest = 30,
|
|
HeightRequest = 30,
|
|
Aspect = Aspect.AspectFill
|
|
}
|
|
.Binding(Image.SourceProperty, nameof(IllustUserItem.ProfileImage)),
|
|
|
|
// user name
|
|
new Label
|
|
{
|
|
HorizontalOptions = LayoutOptions.FillAndExpand,
|
|
VerticalOptions = LayoutOptions.Center,
|
|
LineBreakMode = LineBreakMode.TailTruncation,
|
|
FontSize = StyleDefinition.FontSizeSmall
|
|
}
|
|
.Binding(Label.TextProperty, nameof(IllustUserItem.UserName))
|
|
.DynamicResource(Label.TextColorProperty, ThemeBase.SubTextColor)
|
|
.GridColumn(1),
|
|
},
|
|
GestureRecognizers =
|
|
{
|
|
new TapGestureRecognizer
|
|
{
|
|
Command = commandUserTapped
|
|
}
|
|
.Binding(TapGestureRecognizer.CommandParameterProperty, ".")
|
|
}
|
|
}
|
|
.GridColumnSpan(3),
|
|
|
|
GetUserCardViewImage(0, CornerMask.Left,
|
|
$"{nameof(IllustUserItem.Image1Item)}.{nameof(IllustItem.Image)}",
|
|
nameof(IllustUserItem.Image1Item)),
|
|
|
|
GetUserCardViewImage(1, CornerMask.None,
|
|
$"{nameof(IllustUserItem.Image2Item)}.{nameof(IllustItem.Image)}",
|
|
nameof(IllustUserItem.Image2Item)),
|
|
|
|
GetUserCardViewImage(2, CornerMask.Right,
|
|
$"{nameof(IllustUserItem.Image3Item)}.{nameof(IllustItem.Image)}",
|
|
nameof(IllustUserItem.Image3Item))
|
|
}
|
|
};
|
|
});
|
|
}
|
|
|
|
protected override void OnSizeAllocated(double width, double height)
|
|
{
|
|
base.OnSizeAllocated(width, height);
|
|
int columns;
|
|
if (width > height)
|
|
{
|
|
columns = isPhone ? 2 : 3;
|
|
}
|
|
else
|
|
{
|
|
columns = isPhone ? 1 : 2;
|
|
}
|
|
if (UserColumns != columns)
|
|
{
|
|
UserColumns = columns;
|
|
#if DEBUG
|
|
App.DebugPrint($"change user columns to {columns}");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
protected override void DoIllustsLoaded(IllustCollection collection, bool bottom)
|
|
{
|
|
//IsLoading = false;
|
|
if (illustData != null)
|
|
{
|
|
IllustCollection = collection;
|
|
Task.Run(() => DoLoadUserRecommendsData(illustData));
|
|
}
|
|
else
|
|
{
|
|
base.DoIllustsLoaded(collection, bottom);
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data, out int tag)
|
|
{
|
|
tag = 0;
|
|
if (data.body == null)
|
|
{
|
|
return null;
|
|
}
|
|
return data.body.page.recommend.ids.Select(id =>
|
|
data.body.thumbnails.illust.FirstOrDefault(l => (l.illustId ?? l.id) == id)?.ConvertToItem());
|
|
}
|
|
|
|
protected override IllustData DoLoadIllustData(bool force)
|
|
{
|
|
illustData = Stores.LoadIllustData(force);
|
|
return illustData;
|
|
}
|
|
|
|
private void DoLoadUserRecommendsData(IllustData data)
|
|
{
|
|
var r18 = Configs.IsOnR18;
|
|
var defaultImage = StyleDefinition.DownloadBackground;
|
|
var users = data.body.page.recommendUser.Select(u =>
|
|
{
|
|
var usrId = u.id.ToString();
|
|
var usr = data.body.users.FirstOrDefault(r => r.userId == usrId);
|
|
if (usr == null)
|
|
{
|
|
return null;
|
|
}
|
|
IllustItem item1 = null, item2 = null, item3 = null;
|
|
if (u.illustIds != null)
|
|
{
|
|
var length = u.illustIds.Length;
|
|
if (length > 0)
|
|
{
|
|
var id = u.illustIds[0];
|
|
item1 = data.body.thumbnails.illust.FirstOrDefault(l => (l.illustId ?? l.id) == id)?.ConvertToItem(defaultImage);
|
|
}
|
|
if (length > 1)
|
|
{
|
|
var id = u.illustIds[1];
|
|
item2 = data.body.thumbnails.illust.FirstOrDefault(l => (l.illustId ?? l.id) == id)?.ConvertToItem(defaultImage);
|
|
}
|
|
if (length > 2)
|
|
{
|
|
var id = u.illustIds[2];
|
|
item3 = data.body.thumbnails.illust.FirstOrDefault(l => (l.illustId ?? l.id) == id)?.ConvertToItem(defaultImage);
|
|
}
|
|
}
|
|
if (!r18)
|
|
{
|
|
if (item1?.IsRestrict == true ||
|
|
item2?.IsRestrict == true ||
|
|
item3?.IsRestrict == true)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
return new IllustUserItem
|
|
{
|
|
UserId = usrId,
|
|
UserName = usr.name,
|
|
ProfileUrl = usr.image,
|
|
Image1Item = item1,
|
|
Image2Item = item2,
|
|
Image3Item = item3
|
|
};
|
|
}).Where(u => u != null);
|
|
|
|
var list = new List<IllustUserItem>(users);
|
|
activityLoading.Animate("margin", top =>
|
|
{
|
|
activityLoading.Margin = new Thickness(0, top, 0, 0);
|
|
},
|
|
16, -40, easing: Easing.CubicIn, finished: (v, r) =>
|
|
{
|
|
IsLoading = false;
|
|
UserRecommendsVisible = list.Count > 0;
|
|
#if __IOS__
|
|
Device.StartTimer(TimeSpan.FromMilliseconds(48), () =>
|
|
#else
|
|
Device.StartTimer(TimeSpan.FromMilliseconds(150), () =>
|
|
#endif
|
|
{
|
|
Users = list;
|
|
Illusts = IllustCollection;
|
|
return false;
|
|
});
|
|
});
|
|
|
|
DoLoadUserRecommendsImages(list);
|
|
}
|
|
|
|
private void DoLoadUserRecommendsImages(List<IllustUserItem> users)
|
|
{
|
|
foreach (var user in users)
|
|
{
|
|
if (user.ProfileUrl != null)
|
|
{
|
|
var userImage = Stores.LoadUserProfileImage(user.ProfileUrl, true);
|
|
if (userImage != null)
|
|
{
|
|
user.ProfileImage = userImage;
|
|
}
|
|
}
|
|
Task.WaitAll(
|
|
Task.Run(() => DoLoadUserRecommendsImage(user.Image1Item)),
|
|
Task.Run(() => DoLoadUserRecommendsImage(user.Image2Item)),
|
|
Task.Run(() => DoLoadUserRecommendsImage(user.Image3Item)));
|
|
}
|
|
}
|
|
|
|
private void DoLoadUserRecommendsImage(IllustItem illust)
|
|
{
|
|
if (illust.ImageUrl != null)
|
|
{
|
|
var url = Configs.GetThumbnailUrl(illust.ImageUrl);
|
|
var image = Stores.LoadPreviewImage(url, false);
|
|
if (image == null)
|
|
{
|
|
image = Stores.LoadThumbnailImage(url, true);
|
|
}
|
|
if (image != null)
|
|
{
|
|
illust.Image = image;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void Refresh_Clicked(object sender, EventArgs e)
|
|
{
|
|
if (IsLoading)
|
|
{
|
|
return;
|
|
}
|
|
await ScrollToTopAsync(scrollView);
|
|
StartLoad(true);
|
|
}
|
|
}
|
|
|
|
public class IllustUserItem : BindableObject, IIllustItem
|
|
{
|
|
//public static readonly BindableProperty Image1Property = BindableProperty.Create(
|
|
// nameof(Image1), typeof(ImageSource), typeof(IllustUserItem));
|
|
public static readonly BindableProperty ProfileImageProperty = BindableProperty.Create(
|
|
nameof(ProfileImage), typeof(ImageSource), typeof(IllustUserItem));
|
|
|
|
//public ImageSource Image1
|
|
//{
|
|
// get => (ImageSource)GetValue(Image1Property);
|
|
// set => SetValue(Image1Property, value);
|
|
//}
|
|
public ImageSource ProfileImage
|
|
{
|
|
get => (ImageSource)GetValue(ProfileImageProperty);
|
|
set => SetValue(ProfileImageProperty, value);
|
|
}
|
|
|
|
public string UserId { get; set; }
|
|
public string UserName { get; set; }
|
|
public IllustItem Image1Item { get; set; }
|
|
public IllustItem Image2Item { get; set; }
|
|
public IllustItem Image3Item { get; set; }
|
|
public string ProfileUrl { get; set; }
|
|
|
|
public bool IsFavorite { get; }
|
|
public string BookmarkId { get; }
|
|
}
|
|
}
|