diff --git a/Pixiview/Illust/RecommendsPage.xaml b/Pixiview/Illust/RecommendsPage.xaml
index f11fa82..ecf6382 100644
--- a/Pixiview/Illust/RecommendsPage.xaml
+++ b/Pixiview/Illust/RecommendsPage.xaml
@@ -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"
diff --git a/Pixiview/Illust/RecommendsPage.xaml.cs b/Pixiview/Illust/RecommendsPage.xaml.cs
index f87c1a5..71abb67 100644
--- a/Pixiview/Illust/RecommendsPage.xaml.cs
+++ b/Pixiview/Illust/RecommendsPage.xaml.cs
@@ -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; }
+    }
 }