Skip to content

Commit

Permalink
feat(settings): add custom config folder selector
Browse files Browse the repository at this point in the history
chore: update config type to be more specific
0.5.0
  • Loading branch information
RyKilleen committed Mar 20, 2022
1 parent 8a360b5 commit d7a2735
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 132 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "brancato",
"version": "0.4.1",
"version": "0.5.0",
"private": true,
"dependencies": {
"@algolia/autocomplete-js": "^1.5.3",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "brancato"
version = "0.4.1"
version = "0.5.0"
description = "A tool for stage-managing your life"
authors = ["Ryan Killeen"]
license = ""
Expand Down
81 changes: 81 additions & 0 deletions src-tauri/src/app_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use directories::ProjectDirs;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;

const USER_CONFIG_FILE_NAME: &str = "config.json";
const APP_CONFIG_FILE_NAME: &str = "app-config.json";
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct AppConfig {
#[serde(default = "default_user_config_path")]
pub user_config_path: PathBuf,
}

impl Default for AppConfig {
fn default() -> Self {
let default_path = default_user_config_path();
AppConfig {
user_config_path: default_path,
}
}
}

fn default_dir() -> PathBuf {
ProjectDirs::from("", "", "Brancato")
.unwrap()
.config_dir()
.to_owned()
}

fn default_user_config_path() -> PathBuf {
default_dir().join(USER_CONFIG_FILE_NAME)
}

fn default_app_config_path() -> PathBuf {
default_dir().join(APP_CONFIG_FILE_NAME)
}

fn create_app_config(config: Option<AppConfig>) -> AppConfig {
let default = match config {
Some(c) => c,
None => AppConfig::default(),
};
let data = serde_json::to_string(&default).expect("Unable to parse struct");
let path = default_dir().join(APP_CONFIG_FILE_NAME);
let prefix = path.parent().unwrap();
fs::create_dir_all(prefix).unwrap();
fs::write(path, data).expect("Unable to write file");

return default;
}

pub fn get_or_create_app_config() -> AppConfig {
let read_path = default_app_config_path();
let config_file = fs::read_to_string(&read_path);
let config: AppConfig = match config_file {
Ok(file) => serde_json::from_str(&file).unwrap(),
Err(_) => create_app_config(None),
};
return config;
}

pub fn set_custom_user_config_path(
new_user_config_path: PathBuf,
) -> Result<AppConfig, std::io::Error> {
let new_user_config_path = new_user_config_path.join(USER_CONFIG_FILE_NAME);

let current_config = get_or_create_app_config();

let new_config = AppConfig {
user_config_path: new_user_config_path,
..current_config
};

fs::copy(
&current_config.user_config_path,
new_config.user_config_path.clone(),
)
.and_then(|_| fs::remove_file(current_config.user_config_path))?;

Ok(create_app_config(Some(new_config.clone())))
}
53 changes: 0 additions & 53 deletions src-tauri/src/config.rs

This file was deleted.

111 changes: 77 additions & 34 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,36 @@
windows_subsystem = "windows"
)]

mod config;
mod app_config;
mod user_config;
mod windows;
mod workflows;

use std::{env, sync::Mutex};
use app_config::{set_custom_user_config_path, AppConfig};
use serde::Serialize;
use std::{env, path::PathBuf, sync::Mutex};
use tauri::{
AppHandle, CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, State, SystemTray,
SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
api::dialog::blocking::FileDialogBuilder, AppHandle, CustomMenuItem, GlobalShortcutManager,
Manager, RunEvent, State, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
};

use config::Config;
use user_config::{set_user_config, UserConfig};
use windows::focus_window;
use workflows::run_step;

#[derive(Default)]
struct AppState(Mutex<Config>);

fn _get_state(state: State<AppState>) -> Config {
let config_mutex = state.0.lock().expect("Could not lock mutex");
let config = config_mutex.clone();
config
#[derive(Default, Serialize)]
struct AppState {
user_config: UserConfig,
app_config: AppConfig,
}

fn update_config_and_state(
fn update_user_config_and_state(
app: &AppHandle,
state: State<AppState>,
new_config: Config,
user_config: State<Mutex<UserConfig>>,
new_config: UserConfig,
) -> Result<(), tauri::Error> {
let mut app_state = state.0.lock().expect("Could not lock mutex");
config::set_config(&new_config);
let mut app_state = user_config.lock().expect("Could not lock mutex");
set_user_config(&new_config);
*app_state = new_config;

app
Expand All @@ -43,24 +43,59 @@ fn update_config_and_state(
}

#[tauri::command]
fn save_workflows(
state: State<AppState>,
fn save_user_config(
state: State<Mutex<UserConfig>>,
app: AppHandle,
config: Config,
config: UserConfig,
) -> Result<(), tauri::Error> {
update_config_and_state(&app, state, config).ok();
update_user_config_and_state(&app, state, config).ok();

Ok(())
}

#[tauri::command]
fn get_state(state: State<AppState>) -> Config {
_get_state(state)
fn get_state(
user_config_state: State<Mutex<UserConfig>>,
app_config_state: State<Mutex<AppConfig>>,
) -> AppState {
let user_config = user_config_state
.lock()
.expect("Could not lock mutex")
.clone();

let app_config = app_config_state
.lock()
.expect("Couldn't lock mutex")
.clone();

let state = AppState {
user_config,
app_config,
};
return state;
}

#[tauri::command]
fn set_user_config_path(app_config_state: State<Mutex<AppConfig>>) -> Option<PathBuf> {
let folder_path = FileDialogBuilder::new().pick_folder();

match folder_path {
Some(path) => match set_custom_user_config_path(path.clone()) {
Ok(updated_config) => {
let mut state = app_config_state.lock().expect("Couldn't lock");

*state = updated_config;
Some(path)
}
Err(_) => None,
},
None => None,
}
}

#[tauri::command]
async fn run_workflow(state: State<'_, AppState>, label: String) -> Result<(), ()> {
let current_state = _get_state(state);
async fn run_workflow(state: State<'_, Mutex<UserConfig>>, label: String) -> Result<(), ()> {
let current_state = state.lock().expect("Can't unlock").clone();

let mut workflow = current_state
.workflows
Expand All @@ -85,12 +120,12 @@ async fn open_settings(app: AppHandle) -> Result<(), tauri::Error> {
#[tauri::command]
async fn set_shortcut(
app: AppHandle,
state: State<'_, AppState>,
user_config: State<'_, Mutex<UserConfig>>,
shortcut: String,
) -> Result<(), tauri::Error> {
let config = _get_state(state.clone());
let config = user_config.lock().expect("Could not lock mutex").clone();

let new_config = Config {
let new_config = UserConfig {
shortcut: shortcut.to_owned(),
..config.to_owned()
};
Expand All @@ -107,7 +142,7 @@ async fn set_shortcut(
})
.ok();

update_config_and_state(app_ref, state, new_config).ok();
update_user_config_and_state(app_ref, user_config, new_config).ok();
Ok(())
}

Expand All @@ -119,7 +154,8 @@ fn open_omnibar(app: &AppHandle) -> Result<(), tauri::Error> {
Ok(())
}
fn main() {
let user_config = config::get_config();
let app_config = app_config::get_or_create_app_config();
let user_config = user_config::get_user_config(app_config.user_config_path.clone());

let quit = CustomMenuItem::new("quit", "Quit");
let hide = CustomMenuItem::new("hide", "Hide");
Expand Down Expand Up @@ -173,13 +209,15 @@ fn main() {
},
_ => {}
})
.manage(AppState(Mutex::new(user_config)))
.manage(Mutex::new(user_config))
.manage(Mutex::new(app_config))
.invoke_handler(tauri::generate_handler![
get_state,
save_workflows,
save_user_config,
run_workflow,
open_settings,
set_shortcut
set_shortcut,
set_user_config_path
])
.build(tauri::generate_context!())
.expect("error while running tauri application");
Expand All @@ -188,7 +226,12 @@ fn main() {
// Application is ready (triggered only once)
RunEvent::Ready => {
let app_handle = app_handle.clone();
let startup_shortcut = _get_state(app_handle.state::<AppState>()).shortcut;
let startup_shortcut = app_handle
.state::<Mutex<UserConfig>>()
.lock()
.expect("Could not lock mutex")
.clone()
.shortcut;

app_handle
.global_shortcut_manager()
Expand Down
Loading

0 comments on commit d7a2735

Please sign in to comment.