mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-24 23:38:40 +08:00
307 lines
12 KiB
JavaScript
307 lines
12 KiB
JavaScript
/**
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import UITaskbarItem from './UITaskbarItem.js'
|
|
import UIPopover from './UIPopover.js'
|
|
|
|
async function UITaskbar(options){
|
|
global_element_id++;
|
|
|
|
options = options ?? {};
|
|
options.content = options.content ?? '';
|
|
|
|
// get launch apps
|
|
$.ajax({
|
|
url: api_origin + "/get-launch-apps",
|
|
type: 'GET',
|
|
async: true,
|
|
contentType: "application/json",
|
|
headers: {
|
|
"Authorization": "Bearer "+auth_token
|
|
},
|
|
success: function (apps){
|
|
window.launch_apps = apps;
|
|
}
|
|
});
|
|
|
|
let h = '';
|
|
h += `<div id="ui-taskbar_${global_element_id}" class="taskbar" style="height:${window.taskbar_height}px;"><span id='clock'></span></div>`;
|
|
|
|
$('.desktop').append(h);
|
|
|
|
// init clock visibility
|
|
window.change_clock_visible();
|
|
|
|
//---------------------------------------------
|
|
// add `Start` to taskbar
|
|
//---------------------------------------------
|
|
UITaskbarItem({
|
|
icon: window.icons['start.svg'],
|
|
name: i18n('start'),
|
|
sortable: false,
|
|
keep_in_taskbar: true,
|
|
disable_context_menu: true,
|
|
onClick: async function(item){
|
|
// skip if popover already open
|
|
if($(item).hasClass('has-open-popover'))
|
|
return;
|
|
|
|
// show popover
|
|
let popover = UIPopover({
|
|
content: `<div class="launch-popover hide-scrollbar"><span class="close-launch-popover">✕</span></div>`,
|
|
snapToElement: item,
|
|
parent_element: item,
|
|
width: 500,
|
|
height: 500,
|
|
center_horizontally: true,
|
|
});
|
|
|
|
// In the rare case that launch_apps is not populated yet, get it from the server
|
|
// then populate the popover
|
|
if(!launch_apps || !launch_apps.recent || launch_apps.recent.length === 0){
|
|
// get launch apps
|
|
launch_apps = await $.ajax({
|
|
url: api_origin + "/get-launch-apps",
|
|
type: 'GET',
|
|
async: true,
|
|
contentType: "application/json",
|
|
headers: {
|
|
"Authorization": "Bearer "+auth_token
|
|
},
|
|
});
|
|
}
|
|
|
|
let apps_str = '';
|
|
|
|
apps_str += `<div style="margin-bottom: 10px; padding: 5px; position: relative;">`
|
|
apps_str += `<input style="background-image:url(${window.icons['magnifier-outline.svg']});" class="launch-search">`;
|
|
apps_str += `<img class="launch-search-clear" src="${window.icons['close.svg']}">`;
|
|
apps_str += `</div>`;
|
|
// -------------------------------------------
|
|
// Recent apps
|
|
// -------------------------------------------
|
|
if(launch_apps.recent.length > 0){
|
|
// heading
|
|
apps_str += `<h1 class="start-section-heading start-section-heading-recent">${i18n('recent')}</h1>`;
|
|
|
|
// apps
|
|
apps_str += `<div class="launch-apps-recent">`;
|
|
for (let index = 0; index < window.launch_recent_apps_count && index < launch_apps.recent.length; index++) {
|
|
const app_info = launch_apps.recent[index];
|
|
apps_str += `<div title="${html_encode(app_info.title)}" data-name="${html_encode(app_info.name)}" class="start-app-card">`;
|
|
apps_str += `<div class="start-app" data-app-name="${html_encode(app_info.name)}" data-app-uuid="${html_encode(app_info.uuid)}" data-app-icon="${html_encode(app_info.icon)}" data-app-title="${html_encode(app_info.title)}">`;
|
|
apps_str += `<img class="start-app-icon" src="${html_encode(app_info.icon ? app_info.icon : window.icons['app.svg'])}">`;
|
|
apps_str += `<span class="start-app-title">${html_encode(app_info.title)}</span>`;
|
|
apps_str += `</div>`;
|
|
apps_str += `</div>`;
|
|
}
|
|
apps_str += `</div>`;
|
|
}
|
|
// -------------------------------------------
|
|
// Reccomended apps
|
|
// -------------------------------------------
|
|
if(launch_apps.recommended.length > 0){
|
|
// heading
|
|
apps_str += `<h1 class="start-section-heading start-section-heading-recommended" style="${launch_apps.recent.length > 0 ? 'padding-top: 30px;' : ''}">Recommended</h1>`;
|
|
|
|
// apps
|
|
apps_str += `<div class="launch-apps-recommended">`;
|
|
for (let index = 0; index < launch_apps.recommended.length; index++) {
|
|
const app_info = launch_apps.recommended[index];
|
|
apps_str += `<div title="${html_encode(app_info.title)}" data-name="${html_encode(app_info.name)}" class="start-app-card">`;
|
|
apps_str += `<div class="start-app" data-app-name="${html_encode(app_info.name)}" data-app-uuid="${html_encode(app_info.uuid)}" data-app-icon="${html_encode(app_info.icon)}" data-app-title="${html_encode(app_info.title)}">`;
|
|
apps_str += `<img class="start-app-icon" src="${html_encode(app_info.icon ? app_info.icon : window.icons['app.svg'])}">`;
|
|
apps_str += `<span class="start-app-title">${html_encode(app_info.title)}</span>`;
|
|
apps_str += `</div>`;
|
|
apps_str += `</div>`;
|
|
}
|
|
apps_str += `</div>`;
|
|
}
|
|
|
|
// add apps to popover
|
|
$(popover).find('.launch-popover').append(apps_str);
|
|
|
|
// focus on search input only if not on mobile
|
|
if(!isMobile.phone)
|
|
$(popover).find('.launch-search').focus();
|
|
|
|
// make apps draggable
|
|
$(popover).find('.start-app').draggable({
|
|
appendTo: "body",
|
|
revert: "invalid",
|
|
connectToSortable: ".taskbar",
|
|
//containment: "document",
|
|
zIndex: parseInt($(popover).css('z-index')) + 1,
|
|
scroll: false,
|
|
distance: 5,
|
|
revertDuration: 100,
|
|
helper: 'clone',
|
|
cursorAt: { left: 18, top: 20 },
|
|
start: function(event, ui){
|
|
},
|
|
drag: function(event, ui){
|
|
},
|
|
stop: function(){
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
//---------------------------------------------
|
|
// add `Explorer` to the taskbar
|
|
//---------------------------------------------
|
|
UITaskbarItem({
|
|
icon: window.icons['folders.svg'],
|
|
app: 'explorer',
|
|
name: 'Explorer',
|
|
sortable: false,
|
|
keep_in_taskbar: true,
|
|
lock_keep_in_taskbar: true,
|
|
onClick: function(){
|
|
let open_window_count = parseInt($(`.taskbar-item[data-app="explorer"]`).attr('data-open-windows'));
|
|
if(open_window_count === 0){
|
|
launch_app({ name: 'explorer', path: window.home_path});
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
})
|
|
|
|
//---------------------------------------------
|
|
// Add other useful apps to the taskbar
|
|
//---------------------------------------------
|
|
if(window.user.taskbar_items && window.user.taskbar_items.length > 0){
|
|
for (let index = 0; index < window.user.taskbar_items.length; index++) {
|
|
const app_info = window.user.taskbar_items[index];
|
|
// add taskbar item for each app
|
|
UITaskbarItem({
|
|
icon: app_info.icon,
|
|
app: app_info.name,
|
|
name: app_info.title,
|
|
keep_in_taskbar: true,
|
|
onClick: function(){
|
|
let open_window_count = parseInt($(`.taskbar-item[data-app="${app_info.name}"]`).attr('data-open-windows'));
|
|
if(open_window_count === 0){
|
|
launch_app({
|
|
name: app_info.name,
|
|
})
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------
|
|
// add `Trash` to the taskbar
|
|
//---------------------------------------------
|
|
const trash = await puter.fs.stat(trash_path);
|
|
if(window.socket){
|
|
window.socket.emit('trash.is_empty', {is_empty: trash.is_empty});
|
|
}
|
|
|
|
UITaskbarItem({
|
|
icon: trash.is_empty ? window.icons['trash.svg'] : window.icons['trash-full.svg'],
|
|
app: 'trash',
|
|
name: `${i18n('trash')}`,
|
|
sortable: false,
|
|
keep_in_taskbar: true,
|
|
lock_keep_in_taskbar: true,
|
|
onClick: function(){
|
|
let open_windows = $(`.window[data-path="${html_encode(trash_path)}"]`);
|
|
if(open_windows.length === 0){
|
|
launch_app({ name: 'explorer', path: window.trash_path});
|
|
}else{
|
|
open_windows.focusWindow();
|
|
}
|
|
},
|
|
onItemsDrop: function(items){
|
|
move_items(items, trash_path);
|
|
}
|
|
})
|
|
|
|
make_taskbar_sortable();
|
|
}
|
|
|
|
window.make_taskbar_sortable = function(){
|
|
//-------------------------------------------
|
|
// Taskbar is sortable
|
|
//-------------------------------------------
|
|
$('.taskbar').sortable({
|
|
axis: "x",
|
|
items: '.taskbar-item-sortable:not(.has-open-contextmenu)',
|
|
cancel: '.has-open-contextmenu',
|
|
placeholder: "taskbar-item-sortable-placeholder",
|
|
helper : 'clone',
|
|
distance: 5,
|
|
revert: 10,
|
|
receive: function(event, ui){
|
|
if(!$(ui.item).hasClass('taskbar-item')){
|
|
// if app is already in taskbar, cancel
|
|
if($(`.taskbar-item[data-app="${$(ui.item).attr('data-app-name')}"]`).length !== 0){
|
|
$(this).sortable('cancel');
|
|
$('.taskbar .start-app').remove();
|
|
return;
|
|
}else{
|
|
}
|
|
}
|
|
},
|
|
update: function(event, ui){
|
|
if(!$(ui.item).hasClass('taskbar-item')){
|
|
// if app is already in taskbar, cancel
|
|
if($(`.taskbar-item[data-app="${$(ui.item).attr('data-app-name')}"]`).length !== 0){
|
|
$(this).sortable('cancel');
|
|
$('.taskbar .start-app').remove();
|
|
return;
|
|
}
|
|
|
|
let item = UITaskbarItem({
|
|
icon: $(ui.item).attr('data-app-icon'),
|
|
app: $(ui.item).attr('data-app-name'),
|
|
name: $(ui.item).attr('data-app-title'),
|
|
append_to_taskbar: false,
|
|
keep_in_taskbar: true,
|
|
onClick: function(){
|
|
let open_window_count = parseInt($(`.taskbar-item[data-app="${$(ui.item).attr('data-app-name')}"]`).attr('data-open-windows'));
|
|
if(open_window_count === 0){
|
|
launch_app({
|
|
name: $(ui.item).attr('data-app-name'),
|
|
})
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
let el = ($(item).detach())
|
|
$(el).insertAfter(ui.item);
|
|
// $(ui.item).insertBefore(`<h1>Hello!</h1>`);
|
|
$(el).show();
|
|
$(ui.item).removeItems();
|
|
update_taskbar();
|
|
}
|
|
// only proceed to update DB if the item sorted was a pinned item otherwise no point in updating the taskbar in DB
|
|
else if($(ui.item).attr('data-keep-in-taskbar') === 'true'){
|
|
update_taskbar();
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
export default UITaskbar; |