feat: fetch games and show in dropdown
This commit is contained in:
parent
7c911282b6
commit
85bdf733be
13 changed files with 1029 additions and 104 deletions
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
|
@ -7,12 +7,15 @@
|
|||
".flatpak/**": true,
|
||||
"_build/**": true
|
||||
},
|
||||
"mesonbuild.configureOnOpen": false,
|
||||
"mesonbuild.buildFolder": "_build",
|
||||
"mesonbuild.mesonPath": "${workspaceFolder}/.flatpak/meson.sh",
|
||||
"rust-analyzer.server.path": "${workspaceFolder}/.flatpak/rust-analyzer.sh",
|
||||
"rust-analyzer.runnables.command": "${workspaceFolder}/.flatpak/cargo.sh",
|
||||
"rust-analyzer.files.excludeDirs": [
|
||||
".flatpak"
|
||||
]
|
||||
],
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml"
|
||||
],
|
||||
"mesonbuild.configureOnOpen": false,
|
||||
"mesonbuild.buildFolder": "_build",
|
||||
"mesonbuild.mesonPath": "${workspaceFolder}/.flatpak/meson.sh"
|
||||
}
|
925
Cargo.lock
generated
925
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,8 @@ edition = "2021"
|
|||
[dependencies]
|
||||
gettext-rs = { version = "0.7", features = ["gettext-system"] }
|
||||
gtk = { version = "0.7", package = "gtk4" }
|
||||
reqwest = { version = "0.11", features = ["json", "blocking"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.adw]
|
||||
package = "libadwaita"
|
||||
|
|
14
src/api/base.rs
Normal file
14
src/api/base.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
pub const API_URL: &str = "https://api.curseforge.com";
|
||||
|
||||
pub fn get_curse_forge_client() -> Result<reqwest::blocking::Client, reqwest::Error> {
|
||||
let mut api_key_header = reqwest::header::HeaderValue::from_str(crate::config::API_KEY).unwrap();
|
||||
api_key_header.set_sensitive(true);
|
||||
|
||||
let mut headers = reqwest::header::HeaderMap::new();
|
||||
headers.insert("x-api-key", api_key_header);
|
||||
|
||||
reqwest::blocking::Client::builder()
|
||||
.user_agent(format!("dev.mnts.ModManager/{}", crate::config::VERSION))
|
||||
.default_headers(headers)
|
||||
.build()
|
||||
}
|
44
src/api/games.rs
Normal file
44
src/api/games.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::api::*;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Response {
|
||||
data: Vec<Game>,
|
||||
pagination: Pagination
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Game {
|
||||
id: u32,
|
||||
name: String,
|
||||
slug: String,
|
||||
dateModified: String,
|
||||
assets: Assets,
|
||||
status: u32,
|
||||
apiStatus: u32
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Assets {
|
||||
iconUrl: Option<String>,
|
||||
tileUrl: String,
|
||||
coverUrl: Option<String>
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Pagination {
|
||||
index: u32,
|
||||
pageSize: u32,
|
||||
resultCount: u32,
|
||||
totalCount: u32
|
||||
}
|
||||
|
||||
|
||||
pub fn get_games() -> Vec<String> {
|
||||
let client = base::get_curse_forge_client().unwrap();
|
||||
let response = client.get(&format!("{}/v1/games", base::API_URL)).send().unwrap();
|
||||
let json: Response = response.json().unwrap();
|
||||
|
||||
return json.data.iter().map(|game| game.name.clone()).collect();
|
||||
}
|
5
src/api/mod.rs
Normal file
5
src/api/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod base;
|
||||
pub use base::*;
|
||||
|
||||
pub mod games;
|
||||
pub use games::*;
|
|
@ -61,8 +61,11 @@ mod imp {
|
|||
} else {
|
||||
let window = ModManagerWindow::new(&*application);
|
||||
|
||||
let welcome = &ModManagerWelcome::new().upcast::<adw::NavigationPage>();
|
||||
window.set_page(welcome);
|
||||
let welcome = ModManagerWelcome::new();
|
||||
|
||||
// TODO: Somehow we should handle this at some other point?
|
||||
welcome.setup_dropdown();
|
||||
window.set_page(&welcome.upcast::<adw::NavigationPage>());
|
||||
|
||||
window.upcast()
|
||||
};
|
||||
|
|
|
@ -2,3 +2,5 @@ pub static VERSION: &str = "0.1.0";
|
|||
pub static GETTEXT_PACKAGE: &str = "mod-manager";
|
||||
pub static LOCALEDIR: &str = "/app/share/locale";
|
||||
pub static PKGDATADIR: &str = "/app/share/mod-manager";
|
||||
|
||||
pub static API_KEY: &str = "$2a$10$AtaQ/fkWxMoVHVhO.6PMoOHQq7ERdSdpmegqJ09.2Mgj5iTQP3r.2";
|
||||
|
|
|
@ -2,3 +2,5 @@ pub static VERSION: &str = @VERSION@;
|
|||
pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@;
|
||||
pub static LOCALEDIR: &str = @LOCALEDIR@;
|
||||
pub static PKGDATADIR: &str = @PKGDATADIR@;
|
||||
|
||||
pub static API_KEY: &str = @API_KEY@;
|
||||
|
|
|
@ -19,6 +19,7 @@ mod application;
|
|||
mod config;
|
||||
mod window;
|
||||
mod pages;
|
||||
mod api;
|
||||
|
||||
use self::application::ModManagerApplication;
|
||||
use self::window::ModManagerWindow;
|
||||
|
|
|
@ -26,6 +26,7 @@ conf.set_quoted('VERSION', meson.project_version())
|
|||
conf.set_quoted('GETTEXT_PACKAGE', 'mod-manager')
|
||||
conf.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir'))
|
||||
conf.set_quoted('PKGDATADIR', pkgdatadir)
|
||||
conf.set_quoted('API_KEY', '$2a$10$AtaQ/fkWxMoVHVhO.6PMoOHQq7ERdSdpmegqJ09.2Mgj5iTQP3r.2')
|
||||
|
||||
configure_file(
|
||||
input: 'config.rs.in',
|
||||
|
|
|
@ -3,109 +3,24 @@ using Adw 1;
|
|||
|
||||
template $ModManagerWelcome : Adw.NavigationPage {
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
halign: center;
|
||||
valign: center;
|
||||
|
||||
Label {
|
||||
label: _("Welcome to Mod Manager");
|
||||
margin-bottom: 30;
|
||||
|
||||
styles [
|
||||
"title-1"
|
||||
]
|
||||
justify: center;
|
||||
styles ["title-1"]
|
||||
}
|
||||
|
||||
Box subtitle {
|
||||
orientation: vertical;
|
||||
halign: center;
|
||||
margin-bottom: 30;
|
||||
|
||||
Label {
|
||||
label: "Learn and prototype with\nGNOME technologies";
|
||||
label: _("Start with picking the game you want to manage mods for");
|
||||
margin-bottom: 30;
|
||||
justify: center;
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
homogeneous: true;
|
||||
halign: center;
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Image {
|
||||
icon-name: "update-symbolic";
|
||||
margin-end: 12;
|
||||
icon-size: normal;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Edit Style or UI to update the Preview");
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Image {
|
||||
icon-name: "media-playback-start-symbolic";
|
||||
margin-end: 12;
|
||||
icon-size: normal;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Hit");
|
||||
}
|
||||
|
||||
ShortcutsShortcut {
|
||||
accelerator: "<Control>Return";
|
||||
margin-start: 12;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("to format and run Code");
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Image {
|
||||
icon-name: "media-floppy-symbolic";
|
||||
margin-end: 12;
|
||||
icon-size: normal;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Changes are automatically saved and restored");
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Image {
|
||||
icon-name: "library-symbolic";
|
||||
margin-end: 12;
|
||||
icon-size: normal;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Browse the Library for demos and examples");
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Image {
|
||||
icon-name: "user-bookmarks-symbolic";
|
||||
margin-end: 12;
|
||||
icon-size: normal;
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Checkout the Bookmarks menu to learn and get help");
|
||||
}
|
||||
}
|
||||
DropDown games_dropdown {}
|
||||
}
|
||||
}
|
|
@ -22,12 +22,16 @@ use gtk::prelude::*;
|
|||
use adw::subclass::prelude::*;
|
||||
use gtk::{gio, glib};
|
||||
|
||||
use crate::api::*;
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
#[template(resource = "/dev/mnts/ModManager/pages/welcome.ui")]
|
||||
pub struct ModManagerWelcome {
|
||||
#[template_child]
|
||||
pub games_dropdown: TemplateChild<gtk::DropDown>
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -62,5 +66,13 @@ impl ModManagerWelcome {
|
|||
glib::Object::builder()
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn setup_dropdown(&self) {
|
||||
let games = games::get_games();
|
||||
let games_strs: Vec<&str> = games.iter().map(|s| s.as_str()).collect();
|
||||
let games_list = >k::StringList::new(&games_strs);
|
||||
|
||||
imp::ModManagerWelcome::from_obj(self).games_dropdown.set_property("model", games_list)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue