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

@@ -9,6 +9,7 @@ const App = {
RenderQueue.init();
PreviewPanel.init();
ProgressBar.init();
UpdateBanner.init();
App._bind_events();
App._bind_render_events();
@@ -54,8 +55,14 @@ const App = {
let obj_radio_subfolder = document.getElementById("radio_output_subfolder");
let obj_radio_prefix = document.getElementById("radio_output_prefix");
let obj_radio_both = document.getElementById("radio_output_both");
let obj_input_frame_prefix = document.getElementById("input_frame_prefix");
let obj_input_frame_padding = document.getElementById("input_frame_padding");
obj_radio_subfolder.addEventListener("change", () => { App._update_output_example(); });
obj_radio_prefix.addEventListener("change", () => { App._update_output_example(); });
obj_radio_both.addEventListener("change", () => { App._update_output_example(); });
obj_input_frame_prefix.addEventListener("input", () => { App._update_output_example(); });
obj_input_frame_padding.addEventListener("input", () => { App._update_output_example(); });
},
_bind_render_events: () => {
@@ -73,11 +80,16 @@ const App = {
_update_output_example: () => {
let str_mode = document.querySelector('input[name="output_mode"]:checked').value;
let str_prefix = document.getElementById("input_frame_prefix").value || "";
let nb_padding = parseInt(document.getElementById("input_frame_padding").value, 10) || 5;
let str_padded = String(1).padStart(nb_padding, "0");
let obj_label = document.getElementById("label_output_example");
if (str_mode === "subfolder") {
obj_label.innerHTML = 'Ex: /sortie/<strong>Camera.001</strong>/frame_00001.png';
obj_label.innerHTML = 'Ex: /sortie/<strong>Camera.001</strong>/' + str_prefix + str_padded + '.png';
} else if (str_mode === "prefix") {
obj_label.innerHTML = 'Ex: /sortie/<strong>Camera.001</strong>_' + str_prefix + str_padded + '.png';
} else {
obj_label.innerHTML = 'Ex: /sortie/<strong>Camera.001</strong>_frame_00001.png';
obj_label.innerHTML = 'Ex: /sortie/<strong>Camera.001</strong>/<strong>Camera.001</strong>_' + str_prefix + str_padded + '.png';
}
},
@@ -101,16 +113,16 @@ const App = {
return window.api.get_cameras(str_path);
})
.then((list_cameras) => {
.then((obj_result) => {
obj_btn_blend.disabled = false;
if (!list_cameras) {
if (!obj_result) {
return;
}
CameraList.set_cameras(list_cameras);
CameraList.set_cameras(obj_result.list_cameras, obj_result.obj_scene);
CameraConfig.clear();
ConsoleLog.add(list_cameras.length + " camera(s) trouvee(s).");
ConsoleLog.add(obj_result.list_cameras.length + " camera(s) trouvee(s).");
App._update_start_button();
})
.catch((obj_err) => {
@@ -158,11 +170,15 @@ const App = {
let str_overwrite_mode = document.querySelector('input[name="overwrite_mode"]:checked').value;
let list_cameras = CameraList.list_cameras;
let str_frame_prefix = document.getElementById("input_frame_prefix").value || "";
let nb_frame_padding = parseInt(document.getElementById("input_frame_padding").value, 10) || 5;
let obj_config = {
str_blend_file: App.str_blend_path,
str_render_mode: str_mode,
str_output_mode: str_output_mode,
str_overwrite_mode: str_overwrite_mode,
str_frame_prefix: str_frame_prefix,
nb_frame_padding: nb_frame_padding,
str_output_path: App.str_output_path,
list_cameras: list_cameras,
};
@@ -205,11 +221,15 @@ const App = {
let str_mode = document.querySelector('input[name="render_mode"]:checked').value;
let str_output_mode = document.querySelector('input[name="output_mode"]:checked').value;
let str_overwrite_mode = document.querySelector('input[name="overwrite_mode"]:checked').value;
let str_frame_prefix = document.getElementById("input_frame_prefix").value || "";
let nb_frame_padding = parseInt(document.getElementById("input_frame_padding").value, 10) || 5;
let obj_config = {
str_blend_file: App.str_blend_path,
str_render_mode: str_mode,
str_output_mode: str_output_mode,
str_overwrite_mode: str_overwrite_mode,
str_frame_prefix: str_frame_prefix,
nb_frame_padding: nb_frame_padding,
str_output_path: App.str_output_path,
list_cameras: CameraList.list_cameras,
};
@@ -245,6 +265,8 @@ const App = {
if (obj_config.str_output_mode === "prefix") {
document.getElementById("radio_output_prefix").checked = true;
} else if (obj_config.str_output_mode === "both") {
document.getElementById("radio_output_both").checked = true;
} else {
document.getElementById("radio_output_subfolder").checked = true;
}
@@ -255,6 +277,13 @@ const App = {
document.getElementById("radio_overwrite").checked = true;
}
if (obj_config.str_frame_prefix !== undefined) {
document.getElementById("input_frame_prefix").value = obj_config.str_frame_prefix;
}
if (obj_config.nb_frame_padding !== undefined) {
document.getElementById("input_frame_padding").value = obj_config.nb_frame_padding;
}
App._update_output_example();
if (obj_config.list_cameras && obj_config.list_cameras.length > 0) {