better queue render
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const BlenderProcess = require("./BlenderProcess.js");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const { Notification } = require("electron");
|
||||
|
||||
const STR_STATUS_IDLE = "idle";
|
||||
const STR_STATUS_RUNNING = "running";
|
||||
@@ -15,6 +16,11 @@ class QueueManager {
|
||||
this.obj_current_process = null;
|
||||
this.nb_last_render_ms = 0;
|
||||
this.str_last_image_path = null;
|
||||
this.obj_notification_config = { is_notify_each_image: false, is_notify_all_done: true };
|
||||
}
|
||||
|
||||
set_notification_config(obj_config) {
|
||||
this.obj_notification_config = obj_config || { is_notify_each_image: false, is_notify_all_done: true };
|
||||
}
|
||||
|
||||
start(obj_config) {
|
||||
@@ -56,10 +62,39 @@ class QueueManager {
|
||||
this.obj_current_process = null;
|
||||
}
|
||||
|
||||
if (this.nb_current_index < this.list_queue.length) {
|
||||
let obj_item = this.list_queue[this.nb_current_index];
|
||||
if (obj_item.str_status === "rendering") {
|
||||
obj_item.str_status = "stopped";
|
||||
}
|
||||
}
|
||||
|
||||
this._send_log("Rendu arrete.");
|
||||
this._send_progress();
|
||||
return Promise.resolve({ is_success: true });
|
||||
}
|
||||
|
||||
check_queue(obj_config) {
|
||||
let list_queue = this._build_queue(obj_config);
|
||||
let list_existing = [];
|
||||
|
||||
for (let nb_i = 0; nb_i < list_queue.length; nb_i++) {
|
||||
let obj_item = list_queue[nb_i];
|
||||
try {
|
||||
if (fs.existsSync(obj_item.str_expected_file)) {
|
||||
let nb_size = fs.statSync(obj_item.str_expected_file).size;
|
||||
if (nb_size > 0) {
|
||||
list_existing.push({ nb_index: nb_i, str_path: obj_item.str_expected_file });
|
||||
}
|
||||
}
|
||||
} catch (obj_err) {
|
||||
// Fichier inaccessible, on ignore
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve({ list_existing: list_existing, nb_total: list_queue.length });
|
||||
}
|
||||
|
||||
_build_queue(obj_config) {
|
||||
let list_queue = [];
|
||||
let str_blend_path = obj_config.str_blend_file;
|
||||
@@ -159,11 +194,21 @@ class QueueManager {
|
||||
let nb_skip_count = 0;
|
||||
while (this.nb_current_index < this.list_queue.length && this.str_overwrite_mode === "skip") {
|
||||
let obj_check = this.list_queue[this.nb_current_index];
|
||||
if (!fs.existsSync(obj_check.str_expected_file)) {
|
||||
let is_exists = false;
|
||||
let nb_size = 0;
|
||||
try {
|
||||
is_exists = fs.existsSync(obj_check.str_expected_file);
|
||||
if (is_exists) {
|
||||
nb_size = fs.statSync(obj_check.str_expected_file).size;
|
||||
}
|
||||
} catch (obj_fs_err) {
|
||||
is_exists = false;
|
||||
}
|
||||
|
||||
if (!is_exists) {
|
||||
break;
|
||||
}
|
||||
let obj_stats = fs.statSync(obj_check.str_expected_file);
|
||||
if (obj_stats.size === 0) {
|
||||
if (nb_size === 0) {
|
||||
this._send_log("Placeholder vide detecte, re-rendu : " + obj_check.str_camera_name + " F" + obj_check.nb_frame);
|
||||
break;
|
||||
}
|
||||
@@ -181,10 +226,33 @@ class QueueManager {
|
||||
this.str_status = STR_STATUS_IDLE;
|
||||
this._send_log("Tous les rendus sont termines !");
|
||||
this._send_event("render-complete", { is_all_done: true });
|
||||
if (this.obj_notification_config.is_notify_all_done) {
|
||||
this._send_notification("Rendus termines", "Tous les rendus de la file sont termines (" + this.list_queue.length + " elements).");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let obj_item = this.list_queue[this.nb_current_index];
|
||||
|
||||
// Re-verification avant rendu : rattrape les fichiers non detectes par le batch skip
|
||||
if (this.str_overwrite_mode === "skip") {
|
||||
try {
|
||||
if (fs.existsSync(obj_item.str_expected_file)) {
|
||||
let nb_recheck_size = fs.statSync(obj_item.str_expected_file).size;
|
||||
if (nb_recheck_size > 0) {
|
||||
obj_item.str_status = "skipped";
|
||||
this._send_log("Skip : " + obj_item.str_camera_name + " F" + obj_item.nb_frame + " (existant)");
|
||||
this.nb_current_index++;
|
||||
this._send_progress();
|
||||
this._process_next();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (obj_recheck_err) {
|
||||
// Erreur fs, on continue le rendu
|
||||
}
|
||||
}
|
||||
|
||||
obj_item.str_status = "rendering";
|
||||
|
||||
if (this.str_overwrite_mode === "skip") {
|
||||
@@ -234,6 +302,10 @@ class QueueManager {
|
||||
this._send_event("preview-update", str_image);
|
||||
this._send_log("Termine : " + str_image);
|
||||
|
||||
if (this.obj_notification_config.is_notify_each_image) {
|
||||
this._send_notification("Rendu termine", obj_item.str_camera_name + " — Frame " + obj_item.nb_frame);
|
||||
}
|
||||
|
||||
this.nb_current_index++;
|
||||
this._send_progress();
|
||||
this._process_next();
|
||||
@@ -260,11 +332,12 @@ class QueueManager {
|
||||
this.nb_last_render_ms = Date.now() - nb_start;
|
||||
this.str_last_image_path = null;
|
||||
|
||||
this._send_log("ERREUR : " + obj_err.str_message);
|
||||
let str_err_msg = obj_err.str_message || obj_err.message || String(obj_err);
|
||||
this._send_log("ERREUR : " + str_err_msg);
|
||||
this._send_event("render-error", {
|
||||
str_camera: obj_item.str_camera_name,
|
||||
nb_frame: obj_item.nb_frame,
|
||||
str_error: obj_err.str_message,
|
||||
str_error: str_err_msg,
|
||||
});
|
||||
|
||||
this.nb_current_index++;
|
||||
@@ -276,9 +349,14 @@ class QueueManager {
|
||||
_send_progress() {
|
||||
let obj_item = this.list_queue[this.nb_current_index] || {};
|
||||
let list_skipped = [];
|
||||
let list_stopped = [];
|
||||
let list_skipped_paths = [];
|
||||
for (let nb_i = 0; nb_i < this.list_queue.length; nb_i++) {
|
||||
if (this.list_queue[nb_i].str_status === "skipped") {
|
||||
list_skipped.push(nb_i);
|
||||
list_skipped_paths.push({ nb_index: nb_i, str_path: this.list_queue[nb_i].str_expected_file });
|
||||
} else if (this.list_queue[nb_i].str_status === "stopped") {
|
||||
list_stopped.push(nb_i);
|
||||
}
|
||||
}
|
||||
this._send_event("render-progress", {
|
||||
@@ -290,6 +368,8 @@ class QueueManager {
|
||||
nb_last_render_ms: this.nb_last_render_ms,
|
||||
str_last_image_path: this.str_last_image_path,
|
||||
list_skipped: list_skipped,
|
||||
list_stopped: list_stopped,
|
||||
list_skipped_paths: list_skipped_paths,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -302,6 +382,13 @@ class QueueManager {
|
||||
this.obj_window.webContents.send(str_channel, obj_data);
|
||||
}
|
||||
}
|
||||
|
||||
_send_notification(str_title, str_body) {
|
||||
if (Notification.isSupported()) {
|
||||
let obj_notif = new Notification({ title: str_title, body: str_body });
|
||||
obj_notif.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = QueueManager;
|
||||
|
||||
@@ -172,6 +172,9 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex gap-2 mb-3">
|
||||
<button id="btn_check_queue" class="btn btn-outline-info" disabled title="Verifier les fichiers existants">
|
||||
<i class="mdi mdi-check-all"></i>
|
||||
</button>
|
||||
<button id="btn_start" class="btn btn-success flex-fill" disabled>
|
||||
<i class="mdi mdi-play"></i> Start
|
||||
</button>
|
||||
@@ -265,6 +268,7 @@
|
||||
<script src="scripts/ProgressBar.js"></script>
|
||||
<script src="scripts/UpdateBanner.js"></script>
|
||||
<script src="scripts/BlenderPath.js"></script>
|
||||
<script src="scripts/NotificationConfig.js"></script>
|
||||
<script src="scripts/App.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -11,6 +11,7 @@ const App = {
|
||||
ProgressBar.init();
|
||||
UpdateBanner.init();
|
||||
BlenderPath.init();
|
||||
NotificationConfig.init();
|
||||
|
||||
App._bind_events();
|
||||
App._bind_render_events();
|
||||
@@ -44,6 +45,11 @@ const App = {
|
||||
App._stop_render();
|
||||
});
|
||||
|
||||
let obj_btn_check = document.getElementById("btn_check_queue");
|
||||
obj_btn_check.addEventListener("click", () => {
|
||||
App._check_queue();
|
||||
});
|
||||
|
||||
let obj_btn_save = document.getElementById("btn_save_config");
|
||||
obj_btn_save.addEventListener("click", () => {
|
||||
App._save_config();
|
||||
@@ -218,6 +224,51 @@ const App = {
|
||||
});
|
||||
},
|
||||
|
||||
_check_queue: () => {
|
||||
let obj_btn_check = document.getElementById("btn_check_queue");
|
||||
if (obj_btn_check.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!App.str_output_path) {
|
||||
ConsoleLog.add("Veuillez selectionner un dossier de sortie.");
|
||||
return;
|
||||
}
|
||||
|
||||
let str_mode = document.querySelector('input[name="render_mode"]:checked').value;
|
||||
let str_output_mode = document.querySelector('input[name="output_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_frame_prefix: str_frame_prefix,
|
||||
nb_frame_padding: nb_frame_padding,
|
||||
str_output_path: App.str_output_path,
|
||||
list_cameras: list_cameras,
|
||||
};
|
||||
|
||||
RenderQueue.build_display(str_mode, list_cameras);
|
||||
obj_btn_check.disabled = true;
|
||||
ConsoleLog.add("Verification des fichiers existants...");
|
||||
|
||||
window.api.check_queue(obj_config)
|
||||
.then((obj_result) => {
|
||||
obj_btn_check.disabled = false;
|
||||
RenderQueue.mark_existing(obj_result.list_existing);
|
||||
let nb_existing = obj_result.list_existing.length;
|
||||
let nb_to_render = obj_result.nb_total - nb_existing;
|
||||
ConsoleLog.add("Verification terminee : " + nb_existing + " fichier(s) existant(s), " + nb_to_render + " a rendre.");
|
||||
})
|
||||
.catch((obj_err) => {
|
||||
obj_btn_check.disabled = false;
|
||||
ConsoleLog.add("Erreur verification : " + obj_err.message);
|
||||
});
|
||||
},
|
||||
|
||||
_save_config: () => {
|
||||
let str_mode = document.querySelector('input[name="render_mode"]:checked').value;
|
||||
let str_output_mode = document.querySelector('input[name="output_mode"]:checked').value;
|
||||
@@ -311,15 +362,18 @@ const App = {
|
||||
let obj_btn_start = document.getElementById("btn_start");
|
||||
let obj_btn_pause = document.getElementById("btn_pause");
|
||||
let obj_btn_stop = document.getElementById("btn_stop");
|
||||
let obj_btn_check = document.getElementById("btn_check_queue");
|
||||
|
||||
if (str_state === "running") {
|
||||
obj_btn_start.disabled = true;
|
||||
obj_btn_pause.disabled = false;
|
||||
obj_btn_stop.disabled = false;
|
||||
obj_btn_check.disabled = true;
|
||||
} else if (str_state === "paused") {
|
||||
obj_btn_start.disabled = false;
|
||||
obj_btn_pause.disabled = true;
|
||||
obj_btn_stop.disabled = false;
|
||||
obj_btn_check.disabled = true;
|
||||
} else {
|
||||
App._update_start_button();
|
||||
obj_btn_pause.disabled = true;
|
||||
@@ -329,10 +383,12 @@ const App = {
|
||||
|
||||
_update_start_button: () => {
|
||||
let obj_btn_start = document.getElementById("btn_start");
|
||||
let obj_btn_check = document.getElementById("btn_check_queue");
|
||||
let is_ready = App.str_blend_path
|
||||
&& App.str_output_path
|
||||
&& CameraList.get_enabled_cameras().length > 0;
|
||||
obj_btn_start.disabled = !is_ready;
|
||||
obj_btn_check.disabled = !is_ready;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
132
src/renderer/scripts/NotificationConfig.js
Normal file
132
src/renderer/scripts/NotificationConfig.js
Normal file
@@ -0,0 +1,132 @@
|
||||
const NotificationConfig = {
|
||||
is_notify_each_image: false,
|
||||
is_notify_all_done: true,
|
||||
obj_modal: null,
|
||||
|
||||
init: () => {
|
||||
NotificationConfig._create_badge();
|
||||
NotificationConfig._create_modal();
|
||||
NotificationConfig._bind_events();
|
||||
NotificationConfig._load_config();
|
||||
},
|
||||
|
||||
_create_badge: () => {
|
||||
let obj_nav_right = document.querySelector("nav .d-flex.gap-2");
|
||||
let obj_badge = document.createElement("button");
|
||||
obj_badge.id = "btn_notification_config";
|
||||
obj_badge.className = "btn btn-sm btn-outline-secondary";
|
||||
obj_badge.title = "Notifications";
|
||||
obj_badge.innerHTML = '<i class="mdi mdi-bell-outline"></i>';
|
||||
let obj_blender_btn = document.getElementById("btn_blender_status");
|
||||
if (obj_blender_btn) {
|
||||
obj_nav_right.insertBefore(obj_badge, obj_blender_btn.nextSibling);
|
||||
} else {
|
||||
obj_nav_right.insertBefore(obj_badge, obj_nav_right.firstChild);
|
||||
}
|
||||
|
||||
obj_badge.addEventListener("click", () => {
|
||||
NotificationConfig._open_modal();
|
||||
});
|
||||
},
|
||||
|
||||
_create_modal: () => {
|
||||
let obj_modal_el = document.createElement("div");
|
||||
obj_modal_el.id = "modal_notification_config";
|
||||
obj_modal_el.className = "modal fade";
|
||||
obj_modal_el.tabIndex = -1;
|
||||
obj_modal_el.innerHTML =
|
||||
'<div class="modal-dialog modal-dialog-centered modal-sm">' +
|
||||
'<div class="modal-content bg-dark text-light border-secondary">' +
|
||||
'<div class="modal-header border-secondary">' +
|
||||
'<h6 class="modal-title"><i class="mdi mdi-bell-outline me-2"></i>Notifications</h6>' +
|
||||
'<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>' +
|
||||
'</div>' +
|
||||
'<div class="modal-body">' +
|
||||
'<p class="text-light-emphasis mb-3" style="font-size: 0.85rem;">' +
|
||||
'Configurez les notifications systeme.' +
|
||||
'</p>' +
|
||||
'<div class="form-check mb-2">' +
|
||||
'<input class="form-check-input" type="checkbox" id="check_notify_each_image">' +
|
||||
'<label class="form-check-label" for="check_notify_each_image">' +
|
||||
'A chaque image rendue' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'<div class="form-check">' +
|
||||
'<input class="form-check-input" type="checkbox" id="check_notify_all_done" checked>' +
|
||||
'<label class="form-check-label" for="check_notify_all_done">' +
|
||||
'Quand tous les rendus sont termines' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="modal-footer border-secondary">' +
|
||||
'<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Annuler</button>' +
|
||||
'<button id="btn_save_notification" type="button" class="btn btn-sm btn-primary">' +
|
||||
'<i class="mdi mdi-check me-1"></i>Valider' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
document.body.appendChild(obj_modal_el);
|
||||
NotificationConfig.obj_modal = new bootstrap.Modal(obj_modal_el);
|
||||
},
|
||||
|
||||
_bind_events: () => {
|
||||
let obj_btn_save = document.getElementById("btn_save_notification");
|
||||
obj_btn_save.addEventListener("click", () => {
|
||||
NotificationConfig._save_config();
|
||||
});
|
||||
},
|
||||
|
||||
_open_modal: () => {
|
||||
document.getElementById("check_notify_each_image").checked = NotificationConfig.is_notify_each_image;
|
||||
document.getElementById("check_notify_all_done").checked = NotificationConfig.is_notify_all_done;
|
||||
NotificationConfig.obj_modal.show();
|
||||
},
|
||||
|
||||
_load_config: () => {
|
||||
window.api.get_notification_config()
|
||||
.then((obj_config) => {
|
||||
if (obj_config) {
|
||||
NotificationConfig.is_notify_each_image = obj_config.is_notify_each_image || false;
|
||||
NotificationConfig.is_notify_all_done = obj_config.is_notify_all_done !== undefined ? obj_config.is_notify_all_done : true;
|
||||
NotificationConfig._update_badge();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Config non trouvee, valeurs par defaut
|
||||
});
|
||||
},
|
||||
|
||||
_save_config: () => {
|
||||
NotificationConfig.is_notify_each_image = document.getElementById("check_notify_each_image").checked;
|
||||
NotificationConfig.is_notify_all_done = document.getElementById("check_notify_all_done").checked;
|
||||
|
||||
let obj_config = {
|
||||
is_notify_each_image: NotificationConfig.is_notify_each_image,
|
||||
is_notify_all_done: NotificationConfig.is_notify_all_done,
|
||||
};
|
||||
|
||||
window.api.set_notification_config(obj_config)
|
||||
.then(() => {
|
||||
NotificationConfig._update_badge();
|
||||
NotificationConfig.obj_modal.hide();
|
||||
ConsoleLog.add("Configuration notifications sauvegardee.");
|
||||
})
|
||||
.catch((obj_err) => {
|
||||
ConsoleLog.add("Erreur sauvegarde notifications : " + obj_err.message);
|
||||
});
|
||||
},
|
||||
|
||||
_update_badge: () => {
|
||||
let obj_badge = document.getElementById("btn_notification_config");
|
||||
let is_any_active = NotificationConfig.is_notify_each_image || NotificationConfig.is_notify_all_done;
|
||||
if (is_any_active) {
|
||||
obj_badge.className = "btn btn-sm btn-outline-success";
|
||||
obj_badge.title = "Notifications activees";
|
||||
} else {
|
||||
obj_badge.className = "btn btn-sm btn-outline-secondary";
|
||||
obj_badge.title = "Notifications desactivees";
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -40,7 +40,7 @@ const ProgressBar = {
|
||||
let obj_frame_label = document.getElementById("label_current_frame");
|
||||
obj_frame_label.textContent = nb_frame !== null && nb_frame !== undefined ? String(nb_frame) : "-";
|
||||
|
||||
RenderQueue.update_progress(nb_current, obj_data.nb_last_render_ms || 0, obj_data.str_last_image_path || null, obj_data.list_skipped || []);
|
||||
RenderQueue.update_progress(nb_current, obj_data.nb_last_render_ms || 0, obj_data.str_last_image_path || null, obj_data.list_skipped || [], obj_data.list_stopped || [], obj_data.list_skipped_paths || []);
|
||||
},
|
||||
|
||||
reset: () => {
|
||||
|
||||
@@ -115,7 +115,7 @@ const RenderQueue = {
|
||||
obj_container.appendChild(obj_fragment);
|
||||
},
|
||||
|
||||
update_progress: (nb_current, nb_last_render_ms, str_last_image_path, list_skipped) => {
|
||||
update_progress: (nb_current, nb_last_render_ms, str_last_image_path, list_skipped, list_stopped, list_skipped_paths) => {
|
||||
if (nb_current > RenderQueue.nb_last_current && nb_last_render_ms > 0) {
|
||||
RenderQueue.nb_total_render_ms += nb_last_render_ms;
|
||||
RenderQueue.nb_completed_renders++;
|
||||
@@ -126,8 +126,18 @@ const RenderQueue = {
|
||||
RenderQueue.list_items[nb_current - 1].str_image_path = str_last_image_path;
|
||||
}
|
||||
|
||||
if (list_skipped_paths) {
|
||||
for (let obj_sp of list_skipped_paths) {
|
||||
if (obj_sp.nb_index < RenderQueue.list_items.length) {
|
||||
RenderQueue.list_items[obj_sp.nb_index].str_image_path = obj_sp.str_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let nb_i = 0; nb_i < RenderQueue.list_items.length; nb_i++) {
|
||||
if (list_skipped && list_skipped.indexOf(nb_i) !== -1) {
|
||||
if (list_stopped && list_stopped.indexOf(nb_i) !== -1) {
|
||||
RenderQueue.list_items[nb_i].str_status = "stopped";
|
||||
} else if (list_skipped && list_skipped.indexOf(nb_i) !== -1) {
|
||||
RenderQueue.list_items[nb_i].str_status = "skipped";
|
||||
} else if (nb_i < nb_current) {
|
||||
RenderQueue.list_items[nb_i].str_status = "done";
|
||||
@@ -143,14 +153,20 @@ const RenderQueue = {
|
||||
},
|
||||
|
||||
_update_statuses: () => {
|
||||
let obj_rendering_el = null;
|
||||
|
||||
for (let obj_item of RenderQueue.list_items) {
|
||||
if (!obj_item.obj_dom_el) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_needs_click = obj_item.str_status === "done" && obj_item.str_image_path && !obj_item.is_click_bound;
|
||||
let is_needs_click = (obj_item.str_status === "done" || obj_item.str_status === "skipped")
|
||||
&& obj_item.str_image_path && !obj_item.is_click_bound;
|
||||
|
||||
if (obj_item.str_status === obj_item.str_dom_status && !is_needs_click) {
|
||||
if (obj_item.str_status === "rendering") {
|
||||
obj_rendering_el = obj_item.obj_dom_el;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -160,6 +176,7 @@ const RenderQueue = {
|
||||
if (obj_item.str_status === "rendering") {
|
||||
str_icon = "mdi-loading mdi-spin";
|
||||
str_color = "text-primary";
|
||||
obj_rendering_el = obj_item.obj_dom_el;
|
||||
} else if (obj_item.str_status === "done") {
|
||||
str_icon = "mdi-check-circle";
|
||||
str_color = "text-success";
|
||||
@@ -169,6 +186,9 @@ const RenderQueue = {
|
||||
} else if (obj_item.str_status === "skipped") {
|
||||
str_icon = "mdi-skip-next-circle";
|
||||
str_color = "text-info";
|
||||
} else if (obj_item.str_status === "stopped") {
|
||||
str_icon = "mdi-stop-circle";
|
||||
str_color = "text-warning";
|
||||
}
|
||||
|
||||
obj_item.obj_dom_icon.className = "mdi " + str_icon + " " + str_color;
|
||||
@@ -184,6 +204,20 @@ const RenderQueue = {
|
||||
|
||||
obj_item.str_dom_status = obj_item.str_status;
|
||||
}
|
||||
|
||||
if (obj_rendering_el) {
|
||||
obj_rendering_el.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
}
|
||||
},
|
||||
|
||||
mark_existing: (list_existing) => {
|
||||
for (let obj_existing of list_existing) {
|
||||
if (obj_existing.nb_index < RenderQueue.list_items.length) {
|
||||
RenderQueue.list_items[obj_existing.nb_index].str_status = "skipped";
|
||||
RenderQueue.list_items[obj_existing.nb_index].str_image_path = obj_existing.str_path;
|
||||
}
|
||||
}
|
||||
RenderQueue._update_statuses();
|
||||
},
|
||||
|
||||
_update_time_display: () => {
|
||||
|
||||
Reference in New Issue
Block a user