165 lines
4.6 KiB
Rust
165 lines
4.6 KiB
Rust
mod state;
|
|
|
|
use log::LevelFilter;
|
|
use state::{AppState, FrontendState};
|
|
use std::{path::PathBuf, str::FromStr};
|
|
use tauri_plugin_log::{Target, TargetKind};
|
|
|
|
#[tauri::command]
|
|
fn get_state(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::debug!("get_state invoked");
|
|
app_state.snapshot()
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn tick(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::trace!("tick invoked");
|
|
app_state.tick()
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn create_alarm(
|
|
time: String,
|
|
label: Option<String>,
|
|
app_state: tauri::State<AppState>,
|
|
) -> FrontendState {
|
|
let has_label = label
|
|
.as_ref()
|
|
.map(|value| !value.trim().is_empty())
|
|
.unwrap_or(false);
|
|
log::info!(
|
|
"create_alarm invoked (time={time}, has_label={has_label})",
|
|
time = time,
|
|
has_label = has_label
|
|
);
|
|
app_state.create_alarm(time, label)
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn toggle_alarm(id: String, app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::info!("toggle_alarm invoked (id={id})", id = id);
|
|
app_state.toggle_alarm(id)
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn delete_alarm(id: String, app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::info!("delete_alarm invoked (id={id})", id = id);
|
|
app_state.delete_alarm(id)
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn toggle_timer(
|
|
input: Option<String>,
|
|
force_parse: bool,
|
|
app_state: tauri::State<AppState>,
|
|
) -> FrontendState {
|
|
let has_input = input
|
|
.as_ref()
|
|
.map(|value| !value.trim().is_empty())
|
|
.unwrap_or(false);
|
|
log::info!(
|
|
"toggle_timer invoked (force_parse={force_parse}, has_input={has_input})",
|
|
force_parse = force_parse,
|
|
has_input = has_input
|
|
);
|
|
app_state.toggle_timer(input, force_parse)
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn reset_timer(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::debug!("reset_timer invoked");
|
|
app_state.reset_timer()
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn toggle_stopwatch(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::info!("toggle_stopwatch invoked");
|
|
app_state.toggle_stopwatch()
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn add_lap(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::debug!("add_lap invoked");
|
|
app_state.add_lap()
|
|
}
|
|
|
|
#[tauri::command]
|
|
fn reset_stopwatch(app_state: tauri::State<AppState>) -> FrontendState {
|
|
log::debug!("reset_stopwatch invoked");
|
|
app_state.reset_stopwatch()
|
|
}
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
let context = tauri::generate_context!();
|
|
let storage_path = resolve_storage_path(context.config());
|
|
let storage_display = storage_path.display().to_string();
|
|
let app_state = AppState::new(storage_path);
|
|
let log_level = resolve_log_level();
|
|
let log_plugin = tauri_plugin_log::Builder::new()
|
|
.targets([
|
|
Target::new(TargetKind::Stdout),
|
|
Target::new(TargetKind::Webview),
|
|
Target::new(TargetKind::LogDir { file_name: None }),
|
|
])
|
|
.level(log_level)
|
|
.build();
|
|
|
|
tauri::Builder::default()
|
|
.manage(app_state)
|
|
.plugin(log_plugin)
|
|
.plugin(tauri_plugin_opener::init())
|
|
.invoke_handler(tauri::generate_handler![
|
|
get_state,
|
|
tick,
|
|
create_alarm,
|
|
toggle_alarm,
|
|
delete_alarm,
|
|
toggle_timer,
|
|
reset_timer,
|
|
toggle_stopwatch,
|
|
add_lap,
|
|
reset_stopwatch
|
|
])
|
|
.setup(move |_| {
|
|
log::info!("Tauclock backend ready; storage_path={}", storage_display);
|
|
log::debug!("Backend log level set to {:?}", log_level);
|
|
Ok(())
|
|
})
|
|
.run(context)
|
|
.expect("error while running tauri application");
|
|
}
|
|
|
|
fn resolve_log_level() -> LevelFilter {
|
|
let env_value = std::env::var("TAUCLOCK_LOG_LEVEL")
|
|
.or_else(|_| std::env::var("TAUCLOCK_LOG"))
|
|
.ok();
|
|
if let Some(raw) = env_value {
|
|
if let Ok(level) = LevelFilter::from_str(raw.trim()) {
|
|
return level;
|
|
} else {
|
|
eprintln!(
|
|
"[tauclock] Invalid TAUCLOCK_LOG_LEVEL '{}', falling back to default",
|
|
raw
|
|
);
|
|
}
|
|
}
|
|
if cfg!(debug_assertions) {
|
|
LevelFilter::Debug
|
|
} else {
|
|
LevelFilter::Info
|
|
}
|
|
}
|
|
|
|
fn resolve_storage_path(config: &tauri::Config) -> PathBuf {
|
|
let mut dir = dirs::data_dir()
|
|
.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
|
|
let identifier = if config.identifier.is_empty() {
|
|
"tauclock".to_string()
|
|
} else {
|
|
config.identifier.clone()
|
|
};
|
|
dir.push(identifier);
|
|
dir.join("alarms.json")
|
|
}
|