v1.0.0 — release avec auto-update Gitea

Ajout du systeme de mise a jour automatique :
- UpdateManager (main) : verifie les tags Gitea, telecharge et applique les MAJ
- UpdateBanner (renderer) : banniere UI avec progression et retry
- IPC channels : check-for-updates, apply-update, update-available, update-progress, update-error
- Desactivation asar pour permettre le remplacement des sources
- version.json comme source de verite pour la version locale

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sorlinv
2026-02-25 15:58:02 +01:00
parent b556cce88c
commit f31f5aa605
16 changed files with 766 additions and 54 deletions

View File

@@ -0,0 +1,132 @@
const UpdateBanner = {
obj_banner: null,
str_pending_tag: null,
init: () => {
UpdateBanner._create_dom();
UpdateBanner._bind_events();
},
_create_dom: () => {
let obj_banner = document.createElement("div");
obj_banner.id = "update_banner";
obj_banner.className = "update-banner d-none";
obj_banner.innerHTML =
'<div class="d-flex align-items-center justify-content-between px-3 py-2">' +
'<span class="update-banner-text">' +
'<i class="mdi mdi-download-circle-outline me-1"></i>' +
'<span id="update_banner_message">Mise a jour disponible</span>' +
'</span>' +
'<div class="d-flex align-items-center gap-2">' +
'<button id="btn_update_install" class="btn btn-sm btn-light">' +
'<i class="mdi mdi-download me-1"></i>Installer' +
'</button>' +
'<button id="btn_update_close" class="btn btn-sm btn-outline-light border-0">' +
'<i class="mdi mdi-close"></i>' +
'</button>' +
'</div>' +
'</div>';
let obj_nav = document.querySelector("nav.navbar");
obj_nav.parentNode.insertBefore(obj_banner, obj_nav.nextSibling);
UpdateBanner.obj_banner = obj_banner;
},
_bind_events: () => {
let obj_btn_install = document.getElementById("btn_update_install");
obj_btn_install.addEventListener("click", () => {
UpdateBanner._on_install_click();
});
let obj_btn_close = document.getElementById("btn_update_close");
obj_btn_close.addEventListener("click", () => {
UpdateBanner._hide();
});
window.api.on_update_available((obj_data) => {
UpdateBanner.str_pending_tag = obj_data.str_tag_name;
UpdateBanner._show("Version " + obj_data.str_version + " disponible");
});
window.api.on_update_progress((obj_data) => {
UpdateBanner._show_progress(obj_data.str_step, obj_data.nb_percent);
});
window.api.on_update_error((obj_data) => {
UpdateBanner.str_pending_tag = obj_data.str_tag_name || UpdateBanner.str_pending_tag;
UpdateBanner._show_error(obj_data.str_message);
});
},
_show: (str_message) => {
let obj_message = document.getElementById("update_banner_message");
obj_message.textContent = str_message;
let obj_btn_install = document.getElementById("btn_update_install");
obj_btn_install.innerHTML = '<i class="mdi mdi-download me-1"></i>Installer';
obj_btn_install.disabled = false;
obj_btn_install.className = "btn btn-sm btn-light";
let obj_btn_close = document.getElementById("btn_update_close");
obj_btn_close.classList.remove("d-none");
UpdateBanner.obj_banner.classList.remove("d-none", "update-banner-error");
document.body.classList.add("has-update-banner");
},
_hide: () => {
UpdateBanner.obj_banner.classList.add("d-none");
document.body.classList.remove("has-update-banner");
},
_on_install_click: () => {
if (!UpdateBanner.str_pending_tag) {
return;
}
let obj_btn_install = document.getElementById("btn_update_install");
obj_btn_install.disabled = true;
obj_btn_install.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>0%';
let obj_btn_close = document.getElementById("btn_update_close");
obj_btn_close.classList.add("d-none");
window.api.apply_update(UpdateBanner.str_pending_tag)
.catch(() => {});
},
_show_progress: (str_step, nb_percent) => {
let obj_btn_install = document.getElementById("btn_update_install");
let obj_message = document.getElementById("update_banner_message");
let str_label = "Mise a jour";
if (str_step === "downloading") {
str_label = "Telechargement";
} else if (str_step === "extracting") {
str_label = "Extraction";
} else if (str_step === "installing") {
str_label = "Installation";
} else if (str_step === "restarting") {
str_label = "Redemarrage";
}
obj_message.textContent = str_label + "...";
obj_btn_install.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>' + nb_percent + "%";
obj_btn_install.disabled = true;
},
_show_error: (str_message) => {
let obj_message = document.getElementById("update_banner_message");
obj_message.textContent = "Erreur : " + str_message;
UpdateBanner.obj_banner.classList.add("update-banner-error");
let obj_btn_install = document.getElementById("btn_update_install");
obj_btn_install.innerHTML = '<i class="mdi mdi-refresh me-1"></i>Reessayer';
obj_btn_install.disabled = false;
obj_btn_install.className = "btn btn-sm btn-outline-light";
let obj_btn_close = document.getElementById("btn_update_close");
obj_btn_close.classList.remove("d-none");
},
};