diff --git a/data/styles/SearchPage.scss b/data/styles/SearchPage.scss index de58382d1..4e80864a2 100644 --- a/data/styles/SearchPage.scss +++ b/data/styles/SearchPage.scss @@ -1,10 +1,23 @@ navigation-view-page.search { gridview { border-spacing: 1em 2em; + + child { + border-radius: 1em; + padding-bottom: 0.5em; + } } -} -search-list-item { - border-spacing: 1em 0; - margin: 0.5em 1em; + search-list-item { + border-spacing: 1em 0; + margin: 0.5em 1em; + + image { + margin: 0 -4px; + } + } + + screenshot { + margin-top: calc(1em - 3px); + } } diff --git a/src/Views/SearchView.vala b/src/Views/SearchView.vala index eedee1132..06e063706 100644 --- a/src/Views/SearchView.vala +++ b/src/Views/SearchView.vala @@ -77,8 +77,14 @@ public class AppCenter.SearchView : Adw.NavigationPage { single_click_activate = true }; - scrolled = new Gtk.ScrolledWindow () { + var scrollable_clamp = new Adw.ClampScrollable () { child = grid_view, + maximum_size = 800, + tightening_threshold = 800 + }; + + scrolled = new Gtk.ScrolledWindow () { + child = scrollable_clamp, hscrollbar_policy = NEVER }; diff --git a/src/Widgets/Screenshot.vala b/src/Widgets/Screenshot.vala index 7da18d851..285da71a0 100644 --- a/src/Widgets/Screenshot.vala +++ b/src/Widgets/Screenshot.vala @@ -33,13 +33,17 @@ public class AppCenter.Screenshot : Granite.Bin { var box = new Gtk.Box (VERTICAL, 0) { halign = CENTER }; - box.append (label); box.append (picture); child = box; add_css_class (Granite.CssClass.CARD); bind_property ("caption", label, "label"); + notify["caption"].connect (() => { + if (caption != "" && label.parent == null) { + box.prepend (label); + } + }); } public void set_branding (AppCenterCore.Package package) { diff --git a/src/Widgets/SearchListItem.vala b/src/Widgets/SearchListItem.vala index fd84bb902..90514a644 100644 --- a/src/Widgets/SearchListItem.vala +++ b/src/Widgets/SearchListItem.vala @@ -4,6 +4,8 @@ */ public class AppCenter.SearchListItem : Gtk.Grid { + private const int SCREENSHOT_HEIGHT = 180; + public AppCenterCore.Package package { set { app_icon.package = value; @@ -14,15 +16,26 @@ public class AppCenter.SearchListItem : Gtk.Grid { remove (action_stack); } - action_stack = new ActionStack (value); + action_stack = new ActionStack (value) { + halign = END + }; attach (action_stack, 2, 0, 1, 2); + + load_screenshot (value); } } + private static AppCenterCore.ScreenshotCache? screenshot_cache; + private AppCenter.ActionStack action_stack; private AppCenter.AppIcon app_icon; private Gtk.Label name_label; private Gtk.Label summary_label; + private AppCenter.Screenshot screenshot_picture; + + static construct { + screenshot_cache = new AppCenterCore.ScreenshotCache (); + } class construct { set_css_name ("search-list-item"); @@ -33,7 +46,6 @@ public class AppCenter.SearchListItem : Gtk.Grid { name_label = new Gtk.Label (null) { ellipsize = END, - max_width_chars = 30, valign = END, xalign = 0 }; @@ -43,8 +55,6 @@ public class AppCenter.SearchListItem : Gtk.Grid { ellipsize = END, hexpand = true, lines = 2, - width_chars = 20, - max_width_chars = 35, valign = START, wrap = true, xalign = 0 @@ -52,8 +62,47 @@ public class AppCenter.SearchListItem : Gtk.Grid { summary_label.add_css_class (Granite.CssClass.DIM); summary_label.add_css_class (Granite.CssClass.SMALL); + screenshot_picture = new AppCenter.Screenshot () { + height_request = SCREENSHOT_HEIGHT + }; + attach (app_icon, 0, 0, 1, 2); attach (name_label, 1, 0); attach (summary_label, 1, 1); + attach (screenshot_picture, 0, 2, 3); + } + + private void load_screenshot (AppCenterCore.Package package) { + screenshot_picture.visible = false; + + screenshot_picture.set_branding (package); + + string? screenshot_url = null; + + var screenshots = package.get_screenshots (); + foreach (unowned var screenshot in screenshots) { + screenshot_url = screenshot.get_image (-1, SCREENSHOT_HEIGHT, scale_factor).get_url (); + screenshot_picture.tooltip_text = screenshot.get_caption (); + + if (screenshot.get_kind () == DEFAULT && screenshot_url != null) { + break; + } + } + + if (screenshot_url == null) { + return; + } + + screenshot_cache.fetch.begin (screenshot_url, (obj, res) => { + string? screenshot_path = null; + var fetched = screenshot_cache.fetch.end (res, out screenshot_path); + + if (!fetched || screenshot_path == null) { + return; + } + + screenshot_picture.path = screenshot_path; + screenshot_picture.visible = true; + }); } }