/** * Copyright (C) 2024 Puter Technologies Inc. * * This file is part of Puter. * * Puter is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ import UIWindow from './UIWindow.js' import Placeholder from '../util/Placeholder.js'; import Button from './Components/Button.js'; /** * General purpose progress dialog. * @param operation_id If provided, is saved in the data-operation-id attribute, for later lookup. * @param show_progress Enable a progress bar, and display `(foo%)` after the status message * @param on_cancel A callback run when the Cancel button is clicked. Without it, no Cancel button will appear. * @returns {Promise<{set_progress: *, set_status: *, close: *, show_error: *, element: Element}>} Object for managing the progress dialog * @constructor * TODO: Debouncing logic (show only after a delay, then hide only after a delay) */ async function UIWindowProgress({ operation_id = null, show_progress = false, on_cancel = null, } = {}){ const placeholder_cancel_btn = Placeholder(); const placeholder_ok_btn = Placeholder(); let h = ''; h += `
`; h += `
`; h += `
`; // spinner h += `circle anim`; // Progress report h += `
${i18n('preparing')}`; if (show_progress) { h += ` (0%)`; } h += `
`; h +=`
`; if (show_progress) { h += `
`; h += `
`; h += `
`; } if (on_cancel) { h += `
`; h += placeholder_cancel_btn.html; h += `
`; } h += `
`; h += ``; h += `
`; const el_window = await UIWindow({ uid: null, is_dir: false, body_content: h, has_head: false, selectable_body: false, draggable_body: true, allow_context_menu: false, is_resizable: false, is_droppable: false, init_center: true, allow_native_ctxmenu: false, allow_user_select: false, window_class: 'window-progress', width: 450, dominant: true, window_css:{ height: 'initial', }, body_css: { padding: '22px', width: 'initial', 'background-color': `hsla( var(--primary-hue), var(--primary-saturation), var(--primary-lightness), var(--primary-alpha))`, 'backdrop-filter': 'blur(3px)', } }); if (on_cancel) { const cancel_btn = new Button({ label: i18n('cancel'), style: 'small', on_click: () => { $(el_window).close(); on_cancel(); }, }); cancel_btn.attach(placeholder_cancel_btn); } const ok_btn = new Button({ label: i18n('ok'), style: 'small', on_click: () => { $(el_window).close(); }, }); ok_btn.attach(placeholder_ok_btn); return { element: el_window, set_status: (text) => { el_window.querySelector('.progress-msg').innerHTML = text; }, set_progress: (percent) => { el_window.querySelector('.progress-bar').style.width = `${percent}%`; el_window.querySelector('.progress-percent').innerText = `${percent}%`; }, close: () => { $(el_window).close(); }, show_error: (title, message) => { el_window.querySelector('.progress-running').style.display = 'none'; el_window.querySelector('.progress-error').style.display = 'block'; el_window.querySelector('.progress-error-title').innerText = title; el_window.querySelector('.progress-error-message').innerText = message; }, }; } export default UIWindowProgress;