Form for extractor html

This commit is contained in:
poslop
2024-06-07 04:08:59 -05:00
parent a05d64a9c6
commit e7bf93d4d1
10 changed files with 181 additions and 77 deletions

View File

@@ -22,7 +22,4 @@ members = ["src-tauri"]
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3" version = "0.3"
features = [ features = ["Window", "console", "HtmlSelectElement"]
"Window",
"console"
]

View File

@@ -11,3 +11,7 @@ export async function write_config_js(config) {
export async function load_config_js() { export async function load_config_js() {
return await invoke("load_config"); return await invoke("load_config");
} }
export async function load_champions_js() {
return await invoke("load_champions");
}

View File

@@ -17,6 +17,7 @@ serde_json = "1"
toml = "0.5" toml = "0.5"
tokio = "1.38.0" tokio = "1.38.0"
serde-wasm-bindgen = "0.4" serde-wasm-bindgen = "0.4"
walkdir = "2"
[features] [features]
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!! # This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!

View File

@@ -0,0 +1,68 @@
use std::process::Command;
use std::env;
use std::fs;
use std::process::ExitStatus;
use serde::de::value::Error;
use serde::Deserialize;
use serde::Serialize;
use walkdir::WalkDir;
use std::ffi::OsString;
use std::path::PathBuf;
use crate::config_settings;
#[derive(Serialize, Deserialize)]
pub struct Champion {
name: String,
location: String,
}
#[tauri::command]
pub async fn load_champions() -> Vec<Champion> {
let config = config_settings::load_config().await;
let champions: Vec<Champion> = WalkDir::new(&config.wad_dir)
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| {
let path = entry.path();
let file_name = path.file_name().and_then(|name| name.to_str())?;
let extension = path.extension().and_then(|ext| ext.to_str())?;
if extension == "client" &&
file_name.ends_with(".wad.client") &&
file_name.split('.').count() == 3
{
let name = file_name.split('.').next().unwrap_or("").to_string();
let location = path.to_str().unwrap_or("").to_string();
Some(Champion {
name,
location,
})
} else {
None
}
})
.collect();
champions
}
#[tauri::command]
pub async fn extract_wad(champion: Champion) {
let config = config_settings::load_config().await;
let current_dir = env::current_dir().expect("Failed to get current directory");
let extraction_path = current_dir.join("champions").join(champion.name);
let bat_path = PathBuf::from(config.cslol_dir).join("cslol-tools\\wad-extract.exe");
if !extraction_path.exists() {
fs::create_dir_all(&extraction_path).expect("Failed to create extraction folder");
}
let _status = Command::new(&bat_path)
.arg(&champion.location)
.arg(&extraction_path)
.status().unwrap();
}

View File

@@ -2,7 +2,10 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
mod config_settings; mod config_settings;
mod extractor;
use config_settings::*; use config_settings::*;
use extractor::*;
#[tauri::command] #[tauri::command]
fn greet(name: &str) -> String { fn greet(name: &str) -> String {
@@ -11,7 +14,7 @@ fn greet(name: &str) -> String {
fn main() { fn main() {
tauri::Builder::default() tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet, init_config, load_config, write_config]) .invoke_handler(tauri::generate_handler![greet, init_config, load_config, write_config, extract_wad, load_champions])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }

View File

@@ -15,6 +15,8 @@ pub enum Route {
#[at("/")] #[at("/")]
Home, Home,
#[at("/extract")] #[at("/extract")]
ExtractRoot,
#[at("/extract/*")]
Extract, Extract,
#[at("/settings")] #[at("/settings")]
Settings, Settings,
@@ -38,12 +40,20 @@ pub fn app() -> Html {
} }
} }
fn switch(routes: Route) -> Html { fn switch(route: Route) -> Html {
match routes { match route {
Route::Home => html! { <Home/> }, Route::Home => html! { <Home/> },
Route::Extract => html! { <Extract/> }, Route::ExtractRoot | Route::Extract => html! { <Switch<ExtractRoute> render={switch_extract}/> },
Route::Settings => html! { <Settings/> }, Route::Settings => html! { <Settings/> },
Route::NotFound => html! { <h1>{"404 Page Not Found"}</h1> }, Route::NotFound => html! { <NotFound/> },
} }
} }
#[function_component(NotFound)]
pub fn not_found() -> Html {
html! {
<h2 class={"content"}>
{"Not Found"}
</h2>
}
}

View File

@@ -1,56 +1,19 @@
use std::process::Command; use serde::{Deserialize, Serialize};
use std::env; use serde_wasm_bindgen::*;
use std::fs; use wasm_bindgen::prelude::*;
use walkdir::WalkDir;
use std::ffi::OsString;
use std::path::PathBuf;
use crate::config_settings; #[derive(Serialize, Deserialize, Clone)]
pub struct Champion {
pub fn extract_wad() { pub name: String,
let config = config_settings::load_config(); pub location: String,
let wad_files: Vec<OsString> = WalkDir::new(config.wad_dir) }
.into_iter()
.filter_map(|entry| entry.ok()) #[wasm_bindgen(module = "/public/glue.js")]
.filter(|entry| { extern "C" {
let path = entry.path(); #[wasm_bindgen(js_name = load_champions_js, catch)]
let file_name = path.file_name().and_then(|name| name.to_str()).unwrap_or(""); pub async fn load_champions_js() -> Result<JsValue, JsValue>;
let extension = path.extension().and_then(|ext| ext.to_str()).unwrap_or(""); }
extension == "client" &&
file_name.ends_with(".wad.client") && pub async fn load_champions() -> Result<Vec<Champion>, Error> {
file_name.split('.').count() == 3 from_value(load_champions_js().await.unwrap())
})
.map(|entry| entry.path().to_owned().into_os_string())
.collect();
if wad_files.is_empty() {
eprintln!("No valid .wad.client files found in the directory");
return;
}
let current_dir = env::current_dir().expect("Failed to get current directory");
let extraction_path = current_dir.join("wads");
let bat_path = PathBuf::from(config.cslol_dir).join("cslol-tools\\wad-extract.exe");
if !extraction_path.exists() {
fs::create_dir_all(&extraction_path).expect("Failed to create extraction folder");
}
for (i, wad_file) in wad_files.iter().enumerate() {
let status = Command::new(&bat_path)
.arg(&wad_file)
.arg(&extraction_path)
.status()
.expect("Failed to execute command");
if status.success() {
println!("Successfully executed wad-extract.bat for {:?}", wad_file);
} else {
eprintln!("wad-extract.bat returned a non-zero status for {:?}", wad_file);
}
if i >= 3 {
break;
}
}
} }

View File

@@ -1,6 +1,6 @@
mod app; mod app;
mod views; mod views;
// mod extractor; mod extractor;
mod config_settings; mod config_settings;
use app::App; use app::App;
@@ -11,6 +11,6 @@ fn main() {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
yew::Renderer::<App>::new().render(); yew::Renderer::<App>::new().render();
spawn_local(async move { spawn_local(async move {
init_config().await; let _ = init_config().await;
}) })
} }

View File

@@ -1,18 +1,76 @@
use yew::prelude::*; use wasm_bindgen::convert::IntoWasmAbi;
use yew::{prelude::*, suspense::use_future};
use yew_router::prelude::*;
use web_sys::{console, HtmlSelectElement};
use crate::{app::Route, extractor::load_champions};
#[derive(Clone, Routable, PartialEq)]
pub enum ExtractRoute {
#[at("/extract")]
Extract,
#[at("/extract/skinselect")]
SkinSelect,
#[not_found]
#[at("/404")]
NotFound,
}
pub fn switch_extract(route: ExtractRoute) -> Html {
match route {
ExtractRoute::Extract => html! { <Extract/> },
ExtractRoute::SkinSelect => html! { <SkinSelect/> },
ExtractRoute::NotFound => html!{ <Redirect<Route> to={Route::NotFound}/> },
}
}
#[function_component(Extract)] #[function_component(Extract)]
pub fn extract() -> Html { pub fn extract() -> HtmlResult {
let champions_future = use_future(|| async {load_champions().await})?;
let champions = champions_future.as_ref().unwrap().clone();
let champion_selected_handle = use_state(|| champions[0].name.clone());
let champion_selected = (*champion_selected_handle).clone();
let on_submit = {
let champion_selected_handle = champion_selected_handle.clone();
Callback::from(move |event: SubmitEvent| {
let champion_selected_event = event.target_unchecked_into::<web_sys::HtmlSelectElement>();
web_sys::console::log_1(&(*champion_selected_handle).clone().into());
champion_selected_handle.set(champion_selected_event.value());
})
};
Ok(
html! { html! {
<div class="content"> <div class="content">
<h2>{"Extract"}</h2> <h2>{"Extract"}</h2>
<p>{"Exctract shit"}</p> <p>{"Exctract shit"}</p>
<form action="/extract-wads" method="post">
<div class="option"> <div class="option">
<button type="submit">{"Extract WADs"}</button> <form id="champion" onsubmit={on_submit}>
</div> <select id="champion">
{ for champions.iter().enumerate().map(|(index, champion)| html! {
<option value={champion.name.clone()} selected={champion.name == champion_selected}>{&champion.name}</option>
}) }
</select>
<br/>
<button type="submit">{"Select"} </button>
</form> </form>
</div>
</div> </div>
} }
)
}
#[function_component(SkinSelect)]
pub fn skinselect() -> Html {
html! {
}
} }

View File

@@ -7,7 +7,7 @@ pub fn nav() -> Html {
html! { html! {
<div class="nav"> <div class="nav">
<Link<Route> to={Route::Home}>{"Home"}</Link<Route>> <Link<Route> to={Route::Home}>{"Home"}</Link<Route>>
<Link<Route> to={Route::Extract}>{"Extract"}</Link<Route>> <Link<Route> to={Route::ExtractRoot}>{"Extract"}</Link<Route>>
<Link<Route> to={Route::Settings}>{"Settings"}</Link<Route>> <Link<Route> to={Route::Settings}>{"Settings"}</Link<Route>>
</div> </div>
} }