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 {
|
Box contents {
|
||||||
orientation: vertical;
|
orientation: vertical;
|
||||||
|
margin-start: 12;
|
||||||
|
margin-end: 12;
|
||||||
|
margin-top: 12;
|
||||||
|
margin-bottom: 12;
|
||||||
|
|
||||||
Label heading {
|
Label heading {
|
||||||
styles ["heading"]
|
styles ["heading"]
|
||||||
}
|
}
|
||||||
|
|
||||||
Label body {
|
Label body {
|
||||||
|
vexpand: true;
|
||||||
styles ["body"]
|
styles ["body"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box footer {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,24 +37,29 @@ template $GamesAndMods: Adw.Bin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Adw.Clamp {
|
content: Box {
|
||||||
orientation: vertical;
|
orientation: vertical;
|
||||||
|
|
||||||
Label title {
|
Label title {
|
||||||
label: "Mods";
|
label: "List of Mods";
|
||||||
styles ["title-1"]
|
styles ["title-1"]
|
||||||
}
|
}
|
||||||
|
|
||||||
Adw.Carousel {
|
Label {
|
||||||
|
halign: start;
|
||||||
|
margin-bottom: 12;
|
||||||
|
label: "Latest mods";
|
||||||
|
styles ["title-2"]
|
||||||
}
|
}
|
||||||
Adw.CarouselIndicatorDots {}
|
|
||||||
|
|
||||||
ScrolledWindow {
|
ScrolledWindow {
|
||||||
vexpand: true;
|
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)]
|
#[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 name: String,
|
||||||
//pub modId: i32,
|
//pub modId: i32,
|
||||||
//pub gameSlug: String,
|
//pub gameSlug: String,
|
||||||
|
@ -212,6 +227,7 @@ pub struct Mod {
|
||||||
//pub gamePopularityRank: i32,
|
//pub gamePopularityRank: i32,
|
||||||
//pub isAvailable: bool,
|
//pub isAvailable: bool,
|
||||||
//pub thumbsUpCount: i32,
|
//pub thumbsUpCount: i32,
|
||||||
|
pub categories: Vec<Category>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -260,7 +276,7 @@ struct LatestEarlyAccessFileIndex {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct GetModsResponse {
|
struct GetModsResponse {
|
||||||
data: Vec<Mod>,
|
data: Vec<GameMod>,
|
||||||
pagination: Pagination,
|
pagination: Pagination,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +288,7 @@ struct Pagination {
|
||||||
totalCount: i32,
|
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 client = get_curse_forge_client().unwrap();
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
|
use gtk::prelude::BoxExt;
|
||||||
use gtk::CompositeTemplate;
|
use gtk::CompositeTemplate;
|
||||||
use gtk::{gio, glib};
|
use gtk::{gio, glib};
|
||||||
|
|
||||||
use crate::api::loaders::ImageLoader;
|
use crate::api::loaders::ImageLoader;
|
||||||
|
use crate::api::GameMod;
|
||||||
use crate::dispatch::Worker;
|
use crate::dispatch::Worker;
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
|
@ -20,6 +22,9 @@ mod imp {
|
||||||
|
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub image: TemplateChild<gtk::Image>,
|
pub image: TemplateChild<gtk::Image>,
|
||||||
|
|
||||||
|
#[template_child]
|
||||||
|
pub footer: TemplateChild<gtk::Box>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
@ -53,21 +58,47 @@ impl Card {
|
||||||
glib::Object::builder().build()
|
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();
|
let widget = self.imp();
|
||||||
|
|
||||||
widget.heading.set_text(heading);
|
widget.heading.set_text(heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_body(&self, body: &str) {
|
||||||
|
let widget = self.imp();
|
||||||
widget.body.set_text(body);
|
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 {
|
worker.send_local_task(async move {
|
||||||
let loader = ImageLoader::new();
|
let loader = ImageLoader::new();
|
||||||
let pixbuf = loader.from_url(url).await;
|
let pixbuf = loader.from_url(url).await;
|
||||||
image.set_from_pixbuf(pixbuf.as_ref());
|
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>,
|
pub games_list: TemplateChild<gtk::ListBox>,
|
||||||
|
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub mods_list: TemplateChild<gtk::ListBox>,
|
pub mods_list: TemplateChild<gtk::FlowBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[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()
|
.iter()
|
||||||
.for_each(|mod_| {
|
.for_each(|item| {
|
||||||
let card = Card::new();
|
let card = Card::new_for_game_mod(worker.clone(), item);
|
||||||
card.bind(worker.clone(), &mod_.name, &mod_.summary, &mod_.logo.url);
|
|
||||||
|
|
||||||
obj.imp().mods_list.append(&card);
|
obj.imp().mods_list.append(&card);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue