/**
* 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 UIAlert from './UIAlert.js';
import UIContextMenu from './UIContextMenu.js';
import path from '../lib/path.js';
import UITaskbarItem from './UITaskbarItem.js';
import UIWindowLogin from './UIWindowLogin.js';
import UIWindowPublishWebsite from './UIWindowPublishWebsite.js';
import UIWindowItemProperties from './UIWindowItemProperties.js';
import new_context_menu_item from '../helpers/new_context_menu_item.js';
import refresh_item_container from '../helpers/refresh_item_container.js';
import UIWindowSaveAccount from './UIWindowSaveAccount.js';
import UIWindowEmailConfirmationRequired from './UIWindowEmailConfirmationRequired.js';
import launch_app from "../helpers/launch_app.js"
import UIWindowShare from './UIWindowShare.js';
import item_icon from '../helpers/item_icon.js';
const el_body = document.getElementsByTagName('body')[0];
async function UIWindow(options) {
const win_id = window.global_element_id++;
window.last_window_zindex++;
// options.dominant places the window in center close to top.
options.dominant = options.dominant ?? false;
// in case of file dialogs, the window is automatically dominant
if(options.is_openFileDialog || options.is_saveFileDialog || options.is_directoryPicker)
options.dominant = true;
// we don't want to increment window_counter for dominant windows
if(!options.dominant)
window.window_counter++;
// add this window's id to the window_stack
window.window_stack.push(win_id);
// =====================================
// set options defaults
// =====================================
// indicates if sidebar is hidden, only applies to directory windows
let sidebar_hidden = false;
const default_window_top = ('calc(15% + ' + ((window.window_counter-1) % 10 * 20) + 'px)');
// list of file types that are allowed, other types will be disabled but still shown
options.allowed_file_types = options.allowed_file_types ?? '';
options.app = options.app ?? '';
options.allow_context_menu = options.allow_context_menu ?? true;
options.allow_native_ctxmenu = options.allow_native_ctxmenu ?? false;
options.allow_user_select = options.allow_user_select ?? false;
options.backdrop = options.backdrop ?? false;
options.body_css = options.body_css ?? {};
options.border_radius = options.border_radius ?? undefined;
options.draggable_body = options.draggable_body ?? false;
options.element_uuid = options.element_uuid ?? window.uuidv4();
options.center = options.center ?? false;
options.close_on_backdrop_click = options.close_on_backdrop_click ?? true;
options.disable_parent_window = options.disable_parent_window ?? false;
options.has_head = options.has_head ?? true;
options.height = options.height ?? 380;
options.icon = options.icon ?? null;
options.iframe_msg_uid = options.iframe_msg_uid ?? null;
options.is_droppable = options.is_droppable ?? true;
options.is_draggable = options.is_draggable ?? true;
options.is_dir = options.is_dir ?? false;
options.is_minimized = options.is_minimized ?? false;
options.is_maximized = options.is_maximized ?? false;
options.is_openFileDialog = options.is_openFileDialog ?? false;
options.is_resizable = options.is_resizable ?? true;
// if this is a fullpage window, it won't be resizable
if(options.is_fullpage)
options.is_resizable = false;
// in the embedded/fullpage mode every window is on top since there is no taskbar to switch between windows
// if user has specifically asked for this window to NOT stay on top, honor it.
if((window.is_embedded || window.is_fullpage_mode) && !options.parent_uuid && options.stay_on_top !== false)
options.stay_on_top = true;
// Keep the window on top of all previously opened windows
options.stay_on_top = options.stay_on_top ?? false;
options.is_saveFileDialog = options.is_saveFileDialog ?? false;
options.show_minimize_button = options.show_minimize_button ?? true;
options.on_close = options.on_close ?? undefined;
options.parent_uuid = options.parent_uuid ?? null;
options.selectable_body = (options.selectable_body === undefined || options.selectable_body === true) ? true : false;
options.show_in_taskbar = options.show_in_taskbar ?? true;
options.show_maximize_button = options.show_maximize_button ?? true;
options.single_instance = options.single_instance ?? false;
options.sort_by = options.sort_by ?? 'name';
options.sort_order = options.sort_order ?? 'asc';
options.title = options.title ?? null;
options.top = options.top ?? default_window_top;
options.type = options.type ?? null;
options.update_window_url = options.update_window_url ?? false;
options.layout = options.layout ?? 'icons';
options.width = options.width ?? 680;
options.window_css = options.window_css ?? {};
options.window_class = (options.window_class !== undefined ? ' ' + options.window_class : '');
options.is_visible = options.is_visible ?? true;
// if only one instance is allowed, bring focus to the window that is already open
if(options.single_instance && options.app !== ''){
let $already_open_window = $(`.window[data-app="${html_encode(options.app)}"]`);
if($already_open_window.length){
$(`.window[data-app="${html_encode(options.app)}"]`).focusWindow();
return;
}
}
// left
if(!options.dominant && !options.center){
options.left = options.left ?? ((window.innerWidth/2 - options.width/2) +(window.window_counter-1) % 10 * 30) + 'px';
}else if(!options.dominant && options.center){
options.left = options.left ?? ((window.innerWidth/2 - options.width/2)) + 'px';
}
else if(options.dominant){
options.left = (window.innerWidth/2 - options.width/2) + 'px';
}
else
options.left = options.left ?? ((window.innerWidth/2 - options.width/2) + 'px');
// top
if(!options.dominant && !options.center){
options.top = options.top ?? ((window.innerHeight/2 - options.height/2) +(window.window_counter-1) % 10 * 30) + 'px';
}else if(!options.dominant && options.center){
options.top = options.top ?? ((window.innerHeight/2 - options.height/2)) + 'px';
}
else if(options.dominant){
options.top = (window.innerHeight * 0.15);
}
else if(isMobile.phone)
options.top = 100;
if(isMobile.phone){
options.left = 0;
options.top = window.toolbar_height + 'px';
options.width = '100%';
options.height = 'calc(100% - ' + window.toolbar_height + 'px)';
}else{
options.width += 'px'
options.height += 'px'
}
// =====================================
// cover page
// =====================================
if(options.cover_page){
options.left = 0;
options.top = 0;
options.width = '100%';
options.height = '100%';
}
// --------------------------------------------------------
// HTML for Window
// --------------------------------------------------------
let h = '';
// Window
let zindex = options.stay_on_top ? (99999999 + window.last_window_zindex + 1 + ' !important') : window.last_window_zindex;
let user_set_url_params = [];
if (options.params !== undefined) {
for (let key in options.params) {
user_set_url_params.push(key + "=" + options.params[key]);
}
if(user_set_url_params.length > 0)
user_set_url_params = '?'+ user_set_url_params.join('&');
}
h += `
`;
// window mask
h += `
`;
//busy indicator
h += `
BUSY
`;
h += `
`;
// Head
if(options.has_head){
h += `
`;
// draggable handle which also contains icon and title
h+=`
`;
// icon
if(options.icon)
h += ``;
// title
h += ``;
h += `
`;
// Minimize button, only if window is resizable and not embedded
if(options.is_resizable && options.show_minimize_button && !window.is_embedded)
h += ``;
// Maximize button
if(options.is_resizable && options.show_maximize_button)
h += ``;
// Close button
h += ``;
h += `
`;
}
// Sidebar
if(options.is_dir && !isMobile.phone){
h += `