125 lines
3.8 KiB
Rust
125 lines
3.8 KiB
Rust
use config::Config;
|
|
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
use enigo::{
|
|
Direction::{Press, Release},
|
|
Enigo, Key, Keyboard,
|
|
};
|
|
use rdev::{listen, Event, EventType};
|
|
use std::sync::Mutex;
|
|
use std::thread;
|
|
use tauri::{ipc::Channel, Manager, State};
|
|
|
|
mod config;
|
|
|
|
struct AppState {
|
|
config: Config,
|
|
}
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.plugin(tauri_plugin_fs::init())
|
|
.plugin(tauri_plugin_opener::init())
|
|
.invoke_handler(tauri::generate_handler![
|
|
get_config_path,
|
|
update_config,
|
|
get_default,
|
|
get_theme,
|
|
get_bind,
|
|
start_listener,
|
|
paste_text
|
|
])
|
|
.setup(|app| {
|
|
let config = config::Config::load_or_create(get_config_path()).unwrap();
|
|
|
|
let theme = &config.theme;
|
|
|
|
// Validate and set the theme
|
|
let themes = vec!["grey", "night", "day", "catppuccin_mocha"];
|
|
if themes.contains(&theme.as_str()) {
|
|
println!("Setting theme to: {}", theme);
|
|
app.manage(Mutex::new(AppState { config: config }));
|
|
} else {
|
|
println!(
|
|
"{}",
|
|
format!("Theme {} is invalid! Valid themes are: {:?}", theme, themes)
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
})
|
|
.run(tauri::generate_context!())
|
|
.expect("error while running tauri application");
|
|
}
|
|
|
|
// Commands
|
|
// Config commands
|
|
// gross but i tried returning a struct and everything froze up
|
|
#[tauri::command]
|
|
fn get_config_path() -> std::path::PathBuf {
|
|
let config_dir = dirs::config_dir().expect("Config directory not found");
|
|
config_dir.join("copybot")
|
|
}
|
|
// update the app state with new config
|
|
#[tauri::command]
|
|
fn update_config(state: State<'_, Mutex<AppState>>) {
|
|
let mut state = state.lock().unwrap();
|
|
state.config = config::Config::load_or_create(get_config_path()).unwrap();
|
|
}
|
|
#[tauri::command]
|
|
fn get_default(state: State<'_, Mutex<AppState>>) -> Result<bool, bool> {
|
|
let default = state.lock().unwrap().config.default;
|
|
Ok(default)
|
|
}
|
|
#[tauri::command]
|
|
fn get_theme(state: State<'_, Mutex<AppState>>) -> Result<String, String> {
|
|
let theme = state.lock().unwrap().config.theme.clone();
|
|
Ok(theme)
|
|
}
|
|
#[tauri::command]
|
|
fn get_bind(state: State<'_, Mutex<AppState>>) -> Result<String, String> {
|
|
let bind = state.lock().unwrap().config.bind.clone();
|
|
Ok(bind)
|
|
}
|
|
|
|
// Input events
|
|
|
|
#[tauri::command]
|
|
fn start_listener(bind: String, channel: Channel<Event>) {
|
|
thread::spawn(move || {
|
|
println!("Started listening for bind: {:?}", bind);
|
|
listen(move |event| match event.event_type {
|
|
EventType::KeyPress(key) | EventType::KeyRelease(key) => {
|
|
if bind == serde_json::to_string(&key).unwrap().replace("\"", "") {
|
|
channel.send(event).unwrap()
|
|
};
|
|
}
|
|
|
|
_ => (),
|
|
})
|
|
});
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn paste_text(state: State<'_, Mutex<AppState>>, text: String) {
|
|
println!("{}", text);
|
|
let mut enigo = Enigo::new(&enigo::Settings::default()).unwrap();
|
|
|
|
if state.lock().unwrap().config.shift_enter_newline {
|
|
for c in text.chars() {
|
|
if c == '\n' {
|
|
// Press Shift+Enter combination
|
|
enigo.key(Key::Shift, Press).unwrap();
|
|
enigo.key(Key::Return, Press).unwrap();
|
|
enigo.key(Key::Return, Release).unwrap();
|
|
enigo.key(Key::Shift, Release).unwrap();
|
|
} else {
|
|
// Type regular characters normally
|
|
enigo.text(&c.to_string()).unwrap();
|
|
}
|
|
}
|
|
} else {
|
|
enigo.text(text.as_str()).unwrap();
|
|
}
|
|
}
|