feat: card design improvements
This commit is contained in:
parent
6240c59e24
commit
2f09f3b093
5 changed files with 82 additions and 25 deletions
|
@ -11,13 +11,20 @@ template $Card: Box {
|
|||
|
||||
Box contents {
|
||||
orientation: vertical;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-top: 12;
|
||||
margin-bottom: 12;
|
||||
|
||||
Label heading {
|
||||
styles ["heading"]
|
||||
}
|
||||
|
||||
Label body {
|
||||
vexpand: true;
|
||||
styles ["body"]
|
||||
}
|
||||
|
||||
Box footer {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,24 +37,29 @@ template $GamesAndMods: Adw.Bin {
|
|||
}
|
||||
}
|
||||
|
||||
content: Adw.Clamp {
|
||||
content: Box {
|
||||
orientation: vertical;
|
||||
|
||||
Label title {
|
||||
label: "Mods";
|
||||
label: "List of Mods";
|
||||
styles ["title-1"]
|
||||
}
|
||||
|
||||
Adw.Carousel {
|
||||
Label {
|
||||
halign: start;
|
||||
margin-bottom: 12;
|
||||
label: "Latest mods";
|
||||
styles ["title-2"]
|
||||
}
|
||||
Adw.CarouselIndicatorDots {}
|
||||
|
||||
ScrolledWindow {
|
||||
vexpand: true;
|
||||
ListBox mods_list {
|
||||
hexpand: true;
|
||||
FlowBox mods_list {
|
||||
row-spacing: 12;
|
||||
column-spacing: 12;
|
||||
homogeneous: true;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -193,7 +193,22 @@ pub struct Logo {
|
|||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Mod {
|
||||
pub struct Category {
|
||||
pub id: i32,
|
||||
// game_id: i32,
|
||||
pub name: String,
|
||||
pub slug: String,
|
||||
// url: String,
|
||||
// pub icon_url: String,
|
||||
// date_modified: DateTime<Utc>,
|
||||
// is_class: bool,
|
||||
// class_id: i32,
|
||||
// parent_category_id: i32,
|
||||
// display_index: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct GameMod {
|
||||
pub name: String,
|
||||
//pub modId: i32,
|
||||
//pub gameSlug: String,
|
||||
|
@ -212,6 +227,7 @@ pub struct Mod {
|
|||
//pub gamePopularityRank: i32,
|
||||
//pub isAvailable: bool,
|
||||
//pub thumbsUpCount: i32,
|
||||
pub categories: Vec<Category>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -260,7 +276,7 @@ struct LatestEarlyAccessFileIndex {
|
|||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct GetModsResponse {
|
||||
data: Vec<Mod>,
|
||||
data: Vec<GameMod>,
|
||||
pagination: Pagination,
|
||||
}
|
||||
|
||||
|
@ -272,7 +288,7 @@ struct Pagination {
|
|||
totalCount: i32,
|
||||
}
|
||||
|
||||
pub fn get_mods(game_id: &i32) -> Vec<Mod> {
|
||||
pub fn get_mods(game_id: &i32) -> Vec<GameMod> {
|
||||
let client = get_curse_forge_client().unwrap();
|
||||
|
||||
let response = client
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use adw::subclass::prelude::*;
|
||||
use gtk::prelude::BoxExt;
|
||||
use gtk::CompositeTemplate;
|
||||
use gtk::{gio, glib};
|
||||
|
||||
use crate::api::loaders::ImageLoader;
|
||||
use crate::api::GameMod;
|
||||
use crate::dispatch::Worker;
|
||||
|
||||
mod imp {
|
||||
|
@ -20,6 +22,9 @@ mod imp {
|
|||
|
||||
#[template_child]
|
||||
pub image: TemplateChild<gtk::Image>,
|
||||
|
||||
#[template_child]
|
||||
pub footer: TemplateChild<gtk::Box>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -53,21 +58,47 @@ impl Card {
|
|||
glib::Object::builder().build()
|
||||
}
|
||||
|
||||
pub fn bind(&self, worker: Worker, heading: &str, body: &str, image_url: &str) {
|
||||
fn set_heading(&self, heading: &str) {
|
||||
let widget = self.imp();
|
||||
|
||||
widget.heading.set_text(heading);
|
||||
}
|
||||
|
||||
fn set_body(&self, body: &str) {
|
||||
let widget = self.imp();
|
||||
widget.body.set_text(body);
|
||||
}
|
||||
|
||||
println!("image_url: {}", image_url);
|
||||
fn set_image_from_url(&self, worker: Worker, url: String) {
|
||||
let card = self.imp();
|
||||
let image = card.image.clone();
|
||||
|
||||
let url = image_url.to_string();
|
||||
|
||||
let image = widget.image.clone();
|
||||
worker.send_local_task(async move {
|
||||
let loader = ImageLoader::new();
|
||||
let pixbuf = loader.from_url(url).await;
|
||||
image.set_from_pixbuf(pixbuf.as_ref());
|
||||
});
|
||||
}
|
||||
|
||||
pub fn new_for_game_mod(worker: Worker, game_mod: &GameMod) -> Self {
|
||||
let card = Self::new();
|
||||
let widget = card.imp();
|
||||
|
||||
card.set_image_from_url(worker, game_mod.logo.url.to_string());
|
||||
card.set_heading(&game_mod.name);
|
||||
card.set_body(&game_mod.summary);
|
||||
|
||||
let categories = gtk::Box::new(gtk::Orientation::Horizontal, 0);
|
||||
categories.append(>k::Label::new(Some("Categories: ")));
|
||||
|
||||
for category in &game_mod.categories {
|
||||
let button = gtk::Button::builder()
|
||||
.label(&category.name)
|
||||
.css_classes(["pill", "flat"])
|
||||
.build();
|
||||
categories.append(&button);
|
||||
}
|
||||
widget.footer.append(&categories);
|
||||
|
||||
card
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ mod imp {
|
|||
pub games_list: TemplateChild<gtk::ListBox>,
|
||||
|
||||
#[template_child]
|
||||
pub mods_list: TemplateChild<gtk::ListBox>,
|
||||
pub mods_list: TemplateChild<gtk::FlowBox>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -102,12 +102,10 @@ mod imp {
|
|||
}
|
||||
}));
|
||||
|
||||
let mods = get_mods(&get_game_id(Game::TheSims4("".to_string())))
|
||||
get_mods(&get_game_id(Game::TheSims4("".to_string())))
|
||||
.iter()
|
||||
.for_each(|mod_| {
|
||||
let card = Card::new();
|
||||
card.bind(worker.clone(), &mod_.name, &mod_.summary, &mod_.logo.url);
|
||||
|
||||
.for_each(|item| {
|
||||
let card = Card::new_for_game_mod(worker.clone(), item);
|
||||
obj.imp().mods_list.append(&card);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue