mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
feat: customize the order of Explorer sidebar items
This commit is contained in:
parent
121043d312
commit
ff30de1d69
@ -563,6 +563,11 @@ async function UIDesktop(options){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// load window sidebar items from KV
|
||||||
|
puter.kv.get("sidebar_items").then(async (val) => {
|
||||||
|
window.sidebar_items = val;
|
||||||
|
})
|
||||||
|
|
||||||
// Get menubar style
|
// Get menubar style
|
||||||
puter.kv.get('menubar_style').then(async (val) => {
|
puter.kv.get('menubar_style').then(async (val) => {
|
||||||
let value = val;
|
let value = val;
|
||||||
|
@ -265,12 +265,35 @@ async function UIWindow(options) {
|
|||||||
>`;
|
>`;
|
||||||
// favorites
|
// favorites
|
||||||
h += `<h2 class="window-sidebar-title disable-user-select">${i18n('favorites')}</h2>`;
|
h += `<h2 class="window-sidebar-title disable-user-select">${i18n('favorites')}</h2>`;
|
||||||
|
// default items if sidebar_items is not set
|
||||||
|
if(!window.sidebar_items){
|
||||||
h += `<div draggable="false" title="${i18n('home')}" class="window-sidebar-item disable-user-select ${options.path === window.home_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.home_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-home.svg'])}">${i18n('home')}</div>`;
|
h += `<div draggable="false" title="${i18n('home')}" class="window-sidebar-item disable-user-select ${options.path === window.home_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.home_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-home.svg'])}">${i18n('home')}</div>`;
|
||||||
h += `<div draggable="false" title="${i18n('documents')}" class="window-sidebar-item disable-user-select ${options.path === window.docs_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.docs_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-documents.svg'])}">${i18n('documents')}</div>`;
|
h += `<div draggable="false" title="${i18n('documents')}" class="window-sidebar-item disable-user-select ${options.path === window.docs_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.docs_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-documents.svg'])}">${i18n('documents')}</div>`;
|
||||||
h += `<div draggable="false" title="${i18n('public')}" class="window-sidebar-item disable-user-select ${options.path === window.public_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.public_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-public.svg'])}">${i18n('public')}</div>`;
|
h += `<div draggable="false" title="${i18n('public')}" class="window-sidebar-item disable-user-select ${options.path === window.public_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.public_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-public.svg'])}">${i18n('public')}</div>`;
|
||||||
h += `<div draggable="false" title="${i18n('pictures')}" class="window-sidebar-item disable-user-select ${options.path === window.pictures_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.pictures_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-pictures.svg'])}">${i18n('pictures')}</div>`;
|
h += `<div draggable="false" title="${i18n('pictures')}" class="window-sidebar-item disable-user-select ${options.path === window.pictures_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.pictures_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-pictures.svg'])}">${i18n('pictures')}</div>`;
|
||||||
h += `<div draggable="false" title="${i18n('desktop')}" class="window-sidebar-item disable-user-select ${options.path === window.desktop_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.desktop_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-desktop.svg'])}">${i18n('desktop')}</div>`;
|
h += `<div draggable="false" title="${i18n('desktop')}" class="window-sidebar-item disable-user-select ${options.path === window.desktop_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.desktop_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-desktop.svg'])}">${i18n('desktop')}</div>`;
|
||||||
h += `<div draggable="false" title="${i18n('videos')}" class="window-sidebar-item disable-user-select ${options.path === window.videos_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.videos_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-videos.svg'])}">${i18n('videos')}</div>`;
|
h += `<div draggable="false" title="${i18n('videos')}" class="window-sidebar-item disable-user-select ${options.path === window.videos_path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(window.videos_path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(window.icons['sidebar-folder-videos.svg'])}">${i18n('videos')}</div>`;
|
||||||
|
}else{
|
||||||
|
let items = JSON.parse(window.sidebar_items);
|
||||||
|
for(let item of items){
|
||||||
|
let icon;
|
||||||
|
if(item.path === window.home_path)
|
||||||
|
icon = window.icons['sidebar-folder-home.svg'];
|
||||||
|
else if(item.path === window.docs_path)
|
||||||
|
icon = window.icons['sidebar-folder-documents.svg'];
|
||||||
|
else if(item.path === window.public_path)
|
||||||
|
icon = window.icons['sidebar-folder-public.svg'];
|
||||||
|
else if(item.path === window.pictures_path)
|
||||||
|
icon = window.icons['sidebar-folder-pictures.svg'];
|
||||||
|
else if(item.path === window.desktop_path)
|
||||||
|
icon = window.icons['sidebar-folder-desktop.svg'];
|
||||||
|
else if(item.path === window.videos_path)
|
||||||
|
icon = window.icons['sidebar-folder-videos.svg'];
|
||||||
|
else
|
||||||
|
icon = window.icons['sidebar-folder.svg'];
|
||||||
|
h += `<div title="${html_encode(item.label)}" class="window-sidebar-item disable-user-select ${options.path === item.path ? 'window-sidebar-item-active' : ''}" data-path="${html_encode(item.path)}"><img draggable="false" class="window-sidebar-item-icon" src="${html_encode(icon)}">${html_encode(item.name)}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
h += `</div>`;
|
h += `</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,6 +457,7 @@ async function UIWindow(options) {
|
|||||||
// Append
|
// Append
|
||||||
$(el_body).append(h);
|
$(el_body).append(h);
|
||||||
|
|
||||||
|
|
||||||
// disable_parent_window
|
// disable_parent_window
|
||||||
if(options.disable_parent_window && options.parent_uuid !== null){
|
if(options.disable_parent_window && options.parent_uuid !== null){
|
||||||
const $el_parent_window = $(`.window[data-element_uuid="${options.parent_uuid}"]`);
|
const $el_parent_window = $(`.window[data-element_uuid="${options.parent_uuid}"]`);
|
||||||
@ -2369,6 +2393,70 @@ async function UIWindow(options) {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Sidebar sortable
|
||||||
|
//--------------------------------------------------
|
||||||
|
if(options.is_dir && !isMobile.phone){
|
||||||
|
loadSavedSidebarOrder(el_window);
|
||||||
|
const $sidebar = $(el_window).find('.window-sidebar');
|
||||||
|
|
||||||
|
$sidebar.sortable({
|
||||||
|
items: '.window-sidebar-item:not(.window-sidebar-title)', // More specific selector
|
||||||
|
connectWith: '.window-sidebar',
|
||||||
|
cursor: 'move',
|
||||||
|
axis: 'y',
|
||||||
|
distance: 5,
|
||||||
|
containment: 'parent',
|
||||||
|
placeholder: 'window-sidebar-item-placeholder',
|
||||||
|
tolerance: 'pointer',
|
||||||
|
helper: 'clone',
|
||||||
|
opacity: 0.8,
|
||||||
|
|
||||||
|
start: function(event, ui) {
|
||||||
|
// Add dragging class
|
||||||
|
ui.item.addClass('window-sidebar-item-dragging');
|
||||||
|
|
||||||
|
// Create placeholder styling
|
||||||
|
ui.placeholder.css({
|
||||||
|
'height': ui.item.height(),
|
||||||
|
'visibility': 'visible',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
sort: function(event, ui) {
|
||||||
|
// Ensure the helper follows the cursor properly
|
||||||
|
ui.helper.css('pointer-events', 'none');
|
||||||
|
},
|
||||||
|
|
||||||
|
stop: function(event, ui) {
|
||||||
|
// Remove dragging class
|
||||||
|
ui.item.removeClass('window-sidebar-item-dragging');
|
||||||
|
|
||||||
|
// Get the new order
|
||||||
|
const newOrder = $sidebar.find('.window-sidebar-item').map(function() {
|
||||||
|
return {
|
||||||
|
path: $(this).attr('data-path'),
|
||||||
|
name: $(this).text().trim()
|
||||||
|
};
|
||||||
|
}).get();
|
||||||
|
|
||||||
|
// Save the new order
|
||||||
|
saveSidebarOrder(newOrder);
|
||||||
|
}
|
||||||
|
}).disableSelection(); // Prevent text selection while dragging
|
||||||
|
|
||||||
|
// Make the sortable operation more responsive
|
||||||
|
$sidebar.on('mousedown', '.window-sidebar-item', function(e) {
|
||||||
|
if (!$(this).hasClass('window-sidebar-title')) {
|
||||||
|
$(this).addClass('grabbing');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$sidebar.on('mouseup mouseleave', '.window-sidebar-item', function() {
|
||||||
|
$(this).removeClass('grabbing');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//set styles
|
//set styles
|
||||||
$(el_window_body).css(options.body_css);
|
$(el_window_body).css(options.body_css);
|
||||||
|
|
||||||
@ -3575,4 +3663,50 @@ document.addEventListener('scroll', function (event) {
|
|||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
// Function to save sidebar order to user preferences
|
||||||
|
async function saveSidebarOrder(order) {
|
||||||
|
try {
|
||||||
|
await puter.kv.set({
|
||||||
|
key: "sidebar_items",
|
||||||
|
value: JSON.stringify(order)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save to window object for quick access
|
||||||
|
window.sidebar_items = JSON.stringify(order);
|
||||||
|
} catch(err) {
|
||||||
|
console.error('Error saving sidebar order:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to load and apply saved sidebar order
|
||||||
|
async function loadSavedSidebarOrder(el_window) {
|
||||||
|
setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
// Load saved sidebar order
|
||||||
|
let savedOrder = window.sidebar_items
|
||||||
|
|
||||||
|
// If not found in window object, try to get from KV
|
||||||
|
if(!savedOrder){
|
||||||
|
savedOrder = await puter.kv.get("sidebar_items");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If found, apply the order
|
||||||
|
if (savedOrder && savedOrder !== 'null' && savedOrder !== 'undefined') {
|
||||||
|
const order = JSON.parse(savedOrder);
|
||||||
|
const $sidebar = $(el_window).find('.window-sidebar');
|
||||||
|
|
||||||
|
// Reorder items according to saved order
|
||||||
|
order.forEach(item => {
|
||||||
|
const $item = $sidebar.find(`.window-sidebar-item[data-path="${item.path}"]`);
|
||||||
|
if ($item.length) {
|
||||||
|
$item.appendTo($sidebar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.error('Error loading sidebar order:', err);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
export default UIWindow;
|
export default UIWindow;
|
||||||
|
@ -1242,7 +1242,7 @@ span.header-sort-icon img {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-sidebar-item {
|
.window-sidebar-item, .window-sidebar-item.grabbing {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
@ -1262,6 +1262,34 @@ span.header-sort-icon img {
|
|||||||
background-color: #fefeff;
|
background-color: #fefeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window-sidebar-item.grabbing, .window-sidebar-item.ui-sortable-helper{
|
||||||
|
background-color: none !important;
|
||||||
|
height: 23px !important;
|
||||||
|
/* width: 100% !important; */
|
||||||
|
}
|
||||||
|
.window-sidebar-item-placeholder{
|
||||||
|
height: 27px !important;
|
||||||
|
}
|
||||||
|
.window-sidebar-item {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.window-sidebar-item:not(.window-sidebar-title):hover {
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.window-sidebar-item.grabbing {
|
||||||
|
cursor: grabbing !important;
|
||||||
|
}
|
||||||
|
.window-sidebar-item-dragging {
|
||||||
|
background-color: #f5f5f5 !important;
|
||||||
|
opacity: 0.8;
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
.ui-sortable-helper {
|
||||||
|
background: white !important;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.window-sidebar-item-icon {
|
.window-sidebar-item-icon {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
|
8
src/gui/src/icons/sidebar-folder.svg
Normal file
8
src/gui/src/icons/sidebar-folder.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" version="1">
|
||||||
|
<rect style="opacity:0.2" width="40" height="26" x="4" y="17" rx="2" ry="2"/>
|
||||||
|
<path style="fill:#e19d00" d="M 4,34 C 4,35.108 4.892,36 6,36 H 42 C 43.108,36 44,35.108 44,34 V 12 C 44,10.892 43.108,10 42,10 H 24 C 21,10 20,6 17,6 H 6 C 4.892,6 4,6.892 4,8"/>
|
||||||
|
<rect style="opacity:0.2" width="40" height="26" x="4" y="15" rx="2" ry="2"/>
|
||||||
|
<rect style="fill:#e4e4e4" width="36" height="16" x="6" y="13" rx="2" ry="2"/>
|
||||||
|
<rect style="fill:#f9bd30" width="40" height="26" x="4" y="16" rx="2" ry="2"/>
|
||||||
|
<path style="opacity:0.1;fill:#ffffff" d="M 6,6 C 4.892,6 4,6.892 4,8 V 9 C 4,7.892 4.892,7 6,7 H 17 C 20,7 21,11 24,11 H 42 C 43.108,11 44,11.892 44,13 V 12 C 44,10.892 43.108,10 42,10 H 24 C 21,10 20,6 17,6 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 797 B |
Loading…
Reference in New Issue
Block a user