mirror of
https://github.com/R0m1k3/TodoFlow.git
synced 2026-10-11 17:28:17 +02:00
feat: initial commit for TodoFlow - Conteneurised API and Glassmorphic Desktop Widget
This commit is contained in:
commit
a996f0694b
23 files changed
+1897
No files matched your search
@@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "todoflow"
|
||||
version = "1.0.0"
|
||||
description = "Sleek Windows TodoFlow desktop widget"
|
||||
authors = ["Michael"]
|
||||
edition = "2021"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "1.5" }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "1.6", features = ["api-all", "system-tray"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
# winreg permet de gérer le démarrage automatique dans le registre Windows de façon native
|
||||
winreg = "0.50"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
strip = true
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
Binary file not shown.
|
After Width: | Height: | Size: 92 B |
@@ -0,0 +1,128 @@
|
||||
#![cfg_attr(
|
||||
all(not(debug_assertions), target_os = "windows"),
|
||||
windows_subsystem = "windows"
|
||||
)]
|
||||
|
||||
use std::env;
|
||||
use tauri::{
|
||||
AppHandle, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu,
|
||||
SystemTrayMenuItem, WindowEvent,
|
||||
};
|
||||
use winreg::enums::*;
|
||||
use winreg::RegKey;
|
||||
|
||||
// --- COMMANDES TAURI POUR LE FRONTEND ---
|
||||
|
||||
#[tauri::command]
|
||||
fn toggle_always_on_top(window: tauri::Window, enabled: bool) -> Result<(), String> {
|
||||
// Cette fonction permet à l'utilisateur de configurer dynamiquement si le widget
|
||||
// reste au-dessus de toutes les autres fenêtres.
|
||||
window
|
||||
.set_always_on_top(enabled)
|
||||
.map_err(|e| format!("Impossible d'ajuster le premier plan : {}", e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn set_autostart(enabled: bool) -> Result<(), String> {
|
||||
// Permet d'activer ou de désactiver le lancement automatique au démarrage de Windows.
|
||||
// On écrit directement dans le registre Windows (HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)
|
||||
// ce qui évite d'avoir à gérer un installateur complexe ou des plugins externes lourds.
|
||||
let hkcu = RegKey::predefined(HKEY_CURRENT_USER);
|
||||
let run_key = hkcu
|
||||
.open_subkey_with_flags(
|
||||
r"Software\Microsoft\Windows\CurrentVersion\Run",
|
||||
KEY_WRITE | KEY_READ,
|
||||
)
|
||||
.map_err(|e| format!("Échec de l'ouverture du registre : {}", e))?;
|
||||
|
||||
if enabled {
|
||||
let current_exe = env::current_exe()
|
||||
.map_err(|e| format!("Impossible d'obtenir le chemin de l'exécutable : {}", e))?;
|
||||
let exe_path = current_exe.to_str().ok_or("Chemin invalide")?;
|
||||
// Entourer le chemin de guillemets au cas où il contiendrait des espaces
|
||||
let quoted_path = format!("\"{}\"", exe_path);
|
||||
run_key
|
||||
.set_value("TodoFlow", "ed_path)
|
||||
.map_err(|e| format!("Échec de l'écriture dans le registre : {}", e))?;
|
||||
} else {
|
||||
// Suppression discrète de la clé, en ignorant si elle n'existe pas déjà
|
||||
let _ = run_key.delete_value("TodoFlow");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_autostart() -> Result<bool, String> {
|
||||
// Lit le registre Windows pour vérifier si l'application est configurée pour démarrer automatiquement.
|
||||
let hkcu = RegKey::predefined(HKEY_CURRENT_USER);
|
||||
let run_key = hkcu
|
||||
.open_subkey_with_flags(
|
||||
r"Software\Microsoft\Windows\CurrentVersion\Run",
|
||||
KEY_READ,
|
||||
)
|
||||
.map_err(|e| format!("Échec de la lecture du registre : {}", e))?;
|
||||
|
||||
let val: Result<String, _> = run_key.get_value("TodoFlow");
|
||||
Ok(val.is_ok())
|
||||
}
|
||||
|
||||
// --- CONTEXTE ET INITIALISATION ---
|
||||
|
||||
fn main() {
|
||||
// Configuration du menu de la barre d'état (System Tray)
|
||||
// Permet au widget d'être discret et accessible même s'il est masqué du bureau
|
||||
let tray_menu = SystemTrayMenu::new()
|
||||
.add_item(CustomMenuItem::new("toggle".to_string(), "Afficher / Masquer"))
|
||||
.add_native_item(SystemTrayMenuItem::Separator)
|
||||
.add_item(CustomMenuItem::new("quit".to_string(), "Quitter"));
|
||||
|
||||
let system_tray = SystemTray::new().with_menu(tray_menu);
|
||||
|
||||
tauri::Builder::default()
|
||||
.system_tray(system_tray)
|
||||
.on_system_tray_event(|app, event| match event {
|
||||
SystemTrayEvent::LeftClick { .. } => {
|
||||
// Un simple clic gauche sur l'icône de la barre des tâches bascule la visibilité
|
||||
let window = app.get_window("main").unwrap();
|
||||
if window.is_visible().unwrap() {
|
||||
window.hide().unwrap();
|
||||
} else {
|
||||
window.show().unwrap();
|
||||
window.focus().unwrap();
|
||||
}
|
||||
}
|
||||
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
||||
"quit" => {
|
||||
std::process::exit(0);
|
||||
}
|
||||
"toggle" => {
|
||||
let window = app.get_window("main").unwrap();
|
||||
if window.is_visible().unwrap() {
|
||||
window.hide().unwrap();
|
||||
} else {
|
||||
window.show().unwrap();
|
||||
window.focus().unwrap();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
})
|
||||
.on_window_event(|event| match event.event() {
|
||||
WindowEvent::CloseRequested { api, .. } => {
|
||||
// Au lieu de fermer et détruire l'application, on la masque dans le system tray.
|
||||
// Cela garantit que l'application reste active pour les synchronisations et l'IA.
|
||||
event.window().hide().unwrap();
|
||||
api.prevent_close();
|
||||
}
|
||||
_ => {}
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
toggle_always_on_top,
|
||||
set_autostart,
|
||||
get_autostart
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("Erreur lors de l'exécution de l'application Tauri");
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"build": {
|
||||
"distDir": "../src",
|
||||
"devPath": "../src",
|
||||
"beforeDevCommand": "",
|
||||
"beforeBuildCommand": ""
|
||||
},
|
||||
"package": {
|
||||
"productName": "TodoFlow",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": true
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"category": "Utility",
|
||||
"copyright": "",
|
||||
"deb": {
|
||||
"depends": []
|
||||
},
|
||||
"externalBin": [],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"identifier": "com.todoflow.widget",
|
||||
"longDescription": "",
|
||||
"macOS": {
|
||||
"entitlements": null,
|
||||
"exceptionDomain": "",
|
||||
"frameworks": [],
|
||||
"providerBundleIdentifier": null,
|
||||
"signingIdentity": null
|
||||
},
|
||||
"resources": [],
|
||||
"shortDescription": "Sleek Windows Todo list desktop widget",
|
||||
"targets": "all",
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"csp": null
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"height": 520,
|
||||
"resizable": false,
|
||||
"title": "TodoFlow",
|
||||
"width": 340,
|
||||
"decorations": false,
|
||||
"transparent": true,
|
||||
"alwaysOnTop": false,
|
||||
"skipTaskbar": true,
|
||||
"center": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user