4 Commits
Author SHA1 Message Date
LogiFlowandClaude a635aa29a4 Correction de la restauration du widget + release automatique v1.1.0 (#2)
- Monte la version à 1.1.0 (tauri.conf.json, Cargo.toml, package.json)
  pour générer un nouvel installeur via la CI.
- Met releaseDraft à false dans le workflow : les releases étaient
  créées en brouillon, donc invisibles et jamais marquées 'Latest' sur
  la page GitHub. Elles sont désormais publiées et présentées comme la
  dernière version.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-31 10:28:14 +02:00
LogiFlow fcac504693 Merge pull request #1 from R0m1k3/claude/amazing-ramanujan-56hE0
Corrige la restauration du widget masqué sans icône de barre des tâches
2026-05-31 04:16:22 +02:00
Claude 27d3fb7d50 Corrige la restauration du widget masqué sans icône de barre des tâches
Le bouton Réduire appelait minimize() alors que la fenêtre utilise
skipTaskbar:true : sans entrée dans la barre des tâches, la fenêtre
minimisée devenait irrécupérable. Le bouton masque désormais vers le
system tray.

La logique de bascule du tray gère maintenant correctement l'état
minimisé (is_minimized) et restaure la fenêtre via unminimize/show/
set_focus, faisant de l'icône de la barre d'état un point de
restauration fiable dans tous les cas.
2026-05-31 01:27:33 +00:00
Michael d9c1720523 preserve API key across container updates 2026-05-28 08:10:41 +02:00
8 changed files with 95 additions and 21 deletions

No files matched your search

+7 -2
View File
@@ -61,7 +61,12 @@ jobs:
with:
tagName: ${{ github.ref_name }}
releaseName: 'TodoFlow ${{ github.ref_name }}'
releaseBody: 'Release generated automatically by GitHub Actions.'
releaseDraft: true
releaseBody: |
Installeur Windows de TodoFlow ${{ github.ref_name }}.
Téléchargez le fichier `.exe` (NSIS) ou `.msi` ci-dessous pour installer l'application.
# Publier directement la release (et non en brouillon) afin qu'elle soit visible
# publiquement et marquée automatiquement comme "Latest" sur la page GitHub.
releaseDraft: false
prerelease: false
projectPath: './widget'
+2 -1
View File
@@ -30,11 +30,12 @@ ENV PYTHONUNBUFFERED=1
RUN mkdir -p /app/data
# Création d'un utilisateur système non-privilégié pour des raisons de sécurité
RUN useradd -u 8888 appuser && chown -R appuser:appuser /app
RUN chmod +x /app/entrypoint.sh && useradd -u 8888 appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
# Lancement d'Uvicorn
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
+51
View File
@@ -0,0 +1,51 @@
#!/bin/sh
set -eu
DEFAULT_API_KEYS_RAW="widget-token-secure-789,ai-agent-token-secure-101"
PERSISTED_ENV_FILE="${PERSISTED_ENV_FILE:-/app/data/.env}"
APP_ENV_FILE="${APP_ENV_FILE:-/app/.env}"
read_env_value() {
file="$1"
name="$2"
if [ ! -f "$file" ]; then
return 0
fi
sed -n "s/^[[:space:]]*${name}[[:space:]]*=[[:space:]]*//p" "$file" \
| tail -n 1 \
| sed 's/^"//; s/"$//; s/^'\''//; s/'\''$//'
}
write_env_value() {
file="$1"
name="$2"
value="$3"
mkdir -p "$(dirname "$file")"
if [ -f "$file" ] && grep -q "^[[:space:]]*${name}[[:space:]]*=" "$file"; then
escaped_value=$(printf '%s' "$value" | sed 's/[\/&]/\\&/g')
sed -i "s/^[[:space:]]*${name}[[:space:]]*=.*/${name}=${escaped_value}/" "$file"
else
printf '%s=%s\n' "$name" "$value" >> "$file"
fi
}
persisted_api_keys="$(read_env_value "$PERSISTED_ENV_FILE" "API_KEYS_RAW" || true)"
app_env_api_keys="$(read_env_value "$APP_ENV_FILE" "API_KEYS_RAW" || true)"
current_api_keys="${API_KEYS_RAW:-}"
if [ -n "$persisted_api_keys" ] && { [ -z "$current_api_keys" ] || [ "$current_api_keys" = "$DEFAULT_API_KEYS_RAW" ]; }; then
export API_KEYS_RAW="$persisted_api_keys"
elif [ -n "$app_env_api_keys" ] && { [ -z "$current_api_keys" ] || [ "$current_api_keys" = "$DEFAULT_API_KEYS_RAW" ]; }; then
export API_KEYS_RAW="$app_env_api_keys"
if [ "$app_env_api_keys" != "$DEFAULT_API_KEYS_RAW" ]; then
write_env_value "$PERSISTED_ENV_FILE" "API_KEYS_RAW" "$app_env_api_keys"
fi
elif [ -n "$current_api_keys" ] && [ "$current_api_keys" != "$DEFAULT_API_KEYS_RAW" ]; then
write_env_value "$PERSISTED_ENV_FILE" "API_KEYS_RAW" "$current_api_keys"
fi
exec "$@"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "todoflow-widget",
"version": "1.0.0",
"version": "1.1.0",
"private": true,
"scripts": {
"tauri": "tauri"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "todoflow"
version = "1.0.0"
version = "1.1.0"
description = "Sleek Windows TodoFlow desktop widget"
authors = ["Michael"]
edition = "2021"
+28 -14
View File
@@ -67,6 +67,32 @@ fn get_autostart() -> Result<bool, String> {
Ok(val.is_ok())
}
// --- GESTION DE LA VISIBILITÉ DE LA FENÊTRE ---
fn toggle_window_visibility(app: &AppHandle) {
// Bascule l'affichage du widget depuis l'icône de la barre d'état.
// Comme la fenêtre est configurée avec skipTaskbar:true, l'icône du tray est le
// seul point de restauration : il doit donc fonctionner dans tous les états.
let window = match app.get_window("main") {
Some(w) => w,
None => return,
};
// Une fenêtre réduite est toujours rapportée comme "visible" par Tauri. On la
// considère donc comme masquée afin de la restaurer correctement (et non la re-masquer).
let is_minimized = window.is_minimized().unwrap_or(false);
let is_visible = window.is_visible().unwrap_or(false);
if is_visible && !is_minimized {
let _ = window.hide();
} else {
// Restauration robuste : dé-minimiser, ré-afficher, puis ramener au premier plan.
let _ = window.unminimize();
let _ = window.show();
let _ = window.set_focus();
}
}
// --- CONTEXTE ET INITIALISATION ---
fn main() {
@@ -84,26 +110,14 @@ fn main() {
.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.set_focus().unwrap();
}
toggle_window_visibility(app);
}
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.set_focus().unwrap();
}
toggle_window_visibility(app);
}
_ => {}
},
+1 -1
View File
@@ -8,7 +8,7 @@
},
"package": {
"productName": "TodoFlow",
"version": "1.0.0"
"version": "1.1.0"
},
"tauri": {
"allowlist": {
+4 -1
View File
@@ -88,7 +88,10 @@ document.addEventListener("DOMContentLoaded", async () => {
// Événements Tauri pour le contrôle de la fenêtre de bureau
if (appWindow) {
btnMinimize.addEventListener("click", () => appWindow.minimize());
// La fenêtre utilise skipTaskbar:true : elle n'apparaît jamais dans la barre des tâches.
// Un minimize() classique la rendrait donc irrécupérable. On masque plutôt vers le
// system tray, d'où elle peut toujours être restaurée via l'icône de la barre d'état.
btnMinimize.addEventListener("click", () => appWindow.hide());
btnClose.addEventListener("click", () => appWindow.hide()); // Masquer vers le tray au clic sur 'Fermer'
// Récupération de l'état réel du démarrage automatique depuis le registre Windows