fix: cannot tap into recommended illust

This commit is contained in:
Tsanie Lily 2020-05-14 11:21:00 +08:00
parent d8f9f3da99
commit ef70d7108a
2 changed files with 280 additions and 51 deletions

View File

@ -13,25 +13,17 @@
</ContentPage.ToolbarItems>
<Grid>
<ScrollView HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
<u:FlowLayout ItemsSource="{Binding Illusts}"
HorizontalOptions="Fill" Column="{Binding Columns}"
Margin="16" RowSpacing="16" ColumnSpacing="16"
ItemTemplate="{StaticResource cardView}"/>
<StackLayout>
<u:FlowLayout ItemsSource="{Binding Users}"
HorizontalOptions="Fill" Column="{Binding UserColumns}"
Margin="16" RowSpacing="16"
ItemTemplate="{StaticResource userCardView}"/>
<u:FlowLayout ItemsSource="{Binding Illusts}"
HorizontalOptions="Fill" Column="{Binding Columns}"
Margin="16" RowSpacing="16" ColumnSpacing="16"
ItemTemplate="{StaticResource cardView}"/>
</StackLayout>
</ScrollView>
<!--<Grid Margin="0, -40, 0, 0" VerticalOptions="Start" HeightRequest="40">
<u:SegmentedControl VerticalOptions="Center" HorizontalOptions="Center"
HeightRequest="30"
BackgroundColor="{DynamicResource WindowColor}"
TintColor="{DynamicResource SubTextColor}"
SelectedTextColor="{DynamicResource TextColor}"
SelectedSegmentIndex="{Binding SegmentIndex, Mode=TwoWay}">
<u:SegmentedControl.Children>
<u:SegmentedControlOption Text="{r:Text Recommends}"/>
<u:SegmentedControlOption Text="{r:Text ByUser}"/>
</u:SegmentedControl.Children>
</u:SegmentedControl>
</Grid>-->
<Frame HasShadow="False" Margin="0" Padding="20" CornerRadius="8"
IsVisible="{Binding IsLoading}"
HorizontalOptions="Center" VerticalOptions="Center"

View File

@ -2,7 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Pixiview.UI;
using Pixiview.UI.Theme;
using Pixiview.Utils;
using Xamarin.Forms;
@ -10,64 +11,274 @@ namespace Pixiview.Illust
{
public partial class RecommendsPage : IllustDataCollectionPage
{
public static readonly BindableProperty SegmentIndexProperty = BindableProperty.Create(
nameof(SegmentIndex), typeof(int), typeof(RecommendsPage), propertyChanged: OnSegmentIndexPropertyChanged);
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);
private static void OnSegmentIndexPropertyChanged(BindableObject obj, object oldValue, object newValue)
public List<IllustUserItem> Users
{
var page = (RecommendsPage)obj;
Task.Run(() => page.DoLoadIllusts());
get => (List<IllustUserItem>)GetValue(UsersProperty);
set => SetValue(UsersProperty, value);
}
public int UserColumns
{
get => (int)GetValue(UserColumnsProperty);
set => SetValue(UserColumnsProperty, value);
}
public int SegmentIndex
{
get => (int)GetValue(SegmentIndexProperty);
set => SetValue(SegmentIndexProperty, value);
}
private readonly Command<IllustUserItem> commandUserTapped;
public RecommendsPage()
{
Resources.Add("cardView", GetCardViewTemplate());
Resources.Add("userCardView", GetUserCardViewTemplate());
InitializeComponent();
commandUserTapped = new Command<IllustUserItem>(OnIllustUserItemTapped);
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data, ICommand command)
private void OnIllustUserItemTapped(IllustUserItem item)
{
if (SegmentIndex == 1)
Start(async () =>
{
// by user
return data.body.page.recommendUser.SelectMany(i => i.illustIds)
.Select(id =>
{
var item = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem();
if (item != null)
{
item.IllustTapped = command;
}
return item;
});
var page = new UserIllustPage(item);
await Navigation.PushAsync(page);
});
}
private Image GetUserCardViewImage(int column, CornerMask masks, string source, string parameter)
{
Image image;
if (masks == CornerMask.None)
{
image = new Image();
}
else
{
// recommends
return data.body.page.recommend.Select(id =>
image = new RoundImage
{
var item = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem();
if (item != null)
{
item.IllustTapped = command;
}
return item;
});
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,
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;
App.DebugPrint($"change user columns to {columns}");
}
}
protected override void DoIllustsLoaded(IllustCollection collection)
{
IllustCollection = collection;
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data)
{
return data.body.page.recommend.Select(id =>
data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem());
}
protected override IllustData DoLoadIllustData(bool force)
{
var illustData = Stores.LoadIllustData(force);
Task.Run(() => DoLoadUserRecommendsData(illustData));
return illustData;
}
private void DoLoadUserRecommendsData(IllustData data)
{
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 == id)?.ConvertToItem(defaultImage);
}
if (length > 1)
{
var id = u.illustIds[1];
item2 = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem(defaultImage);
}
if (length > 2)
{
var id = u.illustIds[2];
item3 = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem(defaultImage);
}
}
return new IllustUserItem
{
UserId = usrId,
UserName = usr.name,
ProfileUrl = usr.image,
Image1Item = item1,
Image2Item = item2,
Image3Item = item3
};
});
var list = new List<IllustUserItem>(users);
Users = list;
Illusts = IllustCollection;
DoLoadUserRecommendsImages(list);
}
private void DoLoadUserRecommendsImages(List<IllustUserItem> users)
{
foreach (var user in users)
{
if (user.ProfileUrl != null)
{
var userImage = Stores.LoadUserProfileImage(user.ProfileUrl);
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);
}
if (image != null)
{
illust.Image = image;
}
}
}
private void Refresh_Clicked(object sender, EventArgs e)
{
if (IsLoading)
@ -77,4 +288,30 @@ namespace Pixiview.Illust
StartLoad(true);
}
}
public class IllustUserItem : BindableObject, IIllustUser
{
//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; }
}
}