diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f52e0f2..3453380 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3176,6 +3176,18 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "rusty-slicer" +version = "0.0.1" +dependencies = [ + "lazy_static", + "native-dialog", + "serde", + "serde_json", + "tauri", + "tauri-build", +] + [[package]] name = "ryu" version = "1.0.17" @@ -3969,18 +3981,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "test-tauri" -version = "0.0.0" -dependencies = [ - "lazy_static", - "native-dialog", - "serde", - "serde_json", - "tauri", - "tauri-build", -] - [[package]] name = "thin-slice" version = "0.1.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 40ab743..6d0e5d3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "test-tauri" -version = "0.0.0" -description = "A Tauri App" -authors = ["you"] +name = "rusty-slicer" +version = "0.0.1" +description = "An app to slice your playlist into multiple files" +authors = ["Ayabusa"] edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index aa9f7dd..3dc6eeb 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,7 +3,7 @@ use native_dialog::FileDialog; use tauri::{Manager, PhysicalSize, Size}; -use std::{io::{Error, ErrorKind}, path::PathBuf, sync::Mutex}; +use std::{env, io::{Error, ErrorKind}, path::PathBuf, sync::Mutex}; #[macro_use] extern crate lazy_static; @@ -36,11 +36,30 @@ async fn select_folder_button(app: tauri::AppHandle) { #[tauri::command] async fn slice_button(app: tauri::AppHandle, chapter: String, fileformat: String){ + // Check the user selected a file and a folder + let mut cancel_slicing = false; + if FILE_PATH.lock().unwrap().to_owned() == "" || FILE_PATH.lock().unwrap().to_owned() == "None"{ + println!("error no file selected, slicing aborted"); + app.emit_all("backend_error", Payload { message: "file_empty".to_owned() }).unwrap(); + cancel_slicing = true; + } + if FOLDER_PATH.lock().unwrap().to_owned() == "" || FOLDER_PATH.lock().unwrap().to_owned() == "None"{ + println!("error no folder selected, slicing aborted"); + app.emit_all("backend_error", Payload { message: "folder_empty".to_owned() }).unwrap(); + cancel_slicing = true; + } + if cancel_slicing == true { return; } + // Try to format the chapters and panic if it was not able to let formated_chapters = match format_chapter(&chapter) { Ok(res) => res, - Err(error) => panic!("Problem slicing chapter: {:?}", error), + Err(_error) => { + println!("error formating chapters, slicing aborted"); + app.emit_all("backend_error", Payload { message: "formating_issue".to_owned() }).unwrap(); + return; + }, }; + let time_codes: Vec = formated_chapters.0; let title_names: Vec = formated_chapters.1; @@ -126,6 +145,7 @@ fn format_chapter(chapter: &str) -> Result<(Vec, Vec), Error>{ let lines: Vec<&str> = chapter.split("\n").collect(); let mut time_code: Vec = vec![]; let mut title_names: Vec = vec![]; + if lines.len() < 2 { return Err(Error::new(ErrorKind::Other, "Lines are empty")); } for l in lines.iter(){ if l.is_empty() { break; } @@ -133,12 +153,24 @@ fn format_chapter(chapter: &str) -> Result<(Vec, Vec), Error>{ if splited_line.len()<2 || splited_line[1] == "" { // To avoid blank title return Err(Error::new(ErrorKind::Other, "No title associated with the time code")); } + if !is_time_code_valid(&splited_line[0].to_owned()){ + return Err(Error::new(ErrorKind::Other, "one or multiple time code is invalid")); + } time_code.push(splited_line[0].to_owned()); title_names.push(splited_line[1..].join(" - ")); } Ok((time_code, title_names)) } +/// return true if the time code is valid, and false otherwise +fn is_time_code_valid(time_code: &String) -> bool{ + let allowed_char = "0123456789:"; + for c in time_code.chars(){ + if !allowed_char.contains(c) { return false; } + } + true +} + // prompt user file chooser using native_dialogue crate fn choose_file() -> String{ println!("Let's choose a file !"); @@ -188,6 +220,7 @@ fn launch_ffmpeg(app: tauri::AppHandle, args: Vec) { } fn main() { + env::set_var("WEBKIT_DISABLE_COMPOSITING_MODE", "1"); // generate the tauri app tauri::Builder::default() .invoke_handler(tauri::generate_handler![select_file_button, select_folder_button, debug_call, slice_button, about_button]) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 29da878..0d5074e 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -6,7 +6,7 @@ }, "package": { "productName": "rusty-slicer", - "version": "0.0.0" + "version": "0.0.1" }, "tauri": { "allowlist": { diff --git a/src/about.html b/src/about.html index 67d727d..8a0f0a8 100644 --- a/src/about.html +++ b/src/about.html @@ -18,7 +18,7 @@ Native Dialog crate
to open file select dialog (Really easy to use)
Lazy static crate
to create global variables more easly
Amanda Cifaldi
For the animated background template
- + Fira Sans
By Erik Spiekermann is a clean font

About Me

diff --git a/src/event_handler.js b/src/event_handler.js index 61e0529..f9555b2 100644 --- a/src/event_handler.js +++ b/src/event_handler.js @@ -2,12 +2,34 @@ const { listen } = window.__TAURI__.event // listen for file location from rust backend const unlistenfile = await listen('file_path_changed', (event) => { + document.getElementById("fileLocation").style.color = "white"; document.getElementById("fileLocation").innerHTML = event.payload.message; console.log("changing file label to : ", event.payload.message); }) // listen for folder location from rust backend const unlistenfolder = await listen('folder_path_changed', (event) => { + document.getElementById("folderLocation").style.color = "white"; document.getElementById("folderLocation").innerHTML = event.payload.message; console.log("changing folder label to : ", event.payload.message); +}) + +// listen for error from rust backend +const unlistenerror = await listen('backend_error', (event) => { + switch (event.payload.message) { + case "file_empty": + document.getElementById("fileLocation").style.color = "red"; + document.getElementById("fileLocation").innerHTML = "please select an input file" + console.log("please select an input file"); + break; + case "folder_empty": + document.getElementById("folderLocation").style.color = "red"; + document.getElementById("folderLocation").innerHTML = "please select an output folder" + console.log("please select an output folder"); + break; + case "formating_issue": + document.getElementById("errorLabel").innerHTML = "error: wrong chapter format. use 0:13 - my title" + console.log("error: wrong chapter format. use \n0:00 - first song title \n2:13 - second song title \n3:45 - third song title \n..."); + break; + } }) \ No newline at end of file diff --git a/src/fonts/FiraSans-Bold.ttf b/src/fonts/FiraSans-Bold.ttf new file mode 100644 index 0000000..e3593fb Binary files /dev/null and b/src/fonts/FiraSans-Bold.ttf differ diff --git a/src/index.html b/src/index.html index caa0da7..1d05135 100644 --- a/src/index.html +++ b/src/index.html @@ -29,6 +29,7 @@ 0:00 - my first song 3:30 - another one 13:37 - one more time - Daft punk +

diff --git a/src/main.js b/src/main.js index de17f80..2de8342 100644 --- a/src/main.js +++ b/src/main.js @@ -11,6 +11,7 @@ function select_folder_button_pressed(){ } function slice_button_pressed(){ + document.getElementById("errorLabel").innerHTML = ""; invoke("slice_button", {chapter: document.getElementById("chapterList").value, fileformat: document.getElementById("fileFormatSelect").value}) } diff --git a/src/styles.css b/src/styles.css index c4dd4eb..80b8e39 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,5 +1,10 @@ +@font-face { + font-family: FiraSans-extrabold; + src: url(fonts/FiraSans-Bold.ttf); +} + :root { - font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-family: FiraSans-extrabold, Inter, Avenir, Helvetica, Arial, sans-serif; color: #f6f6f6; background-color: #292829;