mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +00:00
Adding ability to undo move and delete actions
This commit is contained in:
parent
20dd9b87cf
commit
1ae905bd7a
172
src/helpers.js
172
src/helpers.js
@ -2305,7 +2305,7 @@ window.new_context_menu_item = function(dirname, append_to_element){
|
|||||||
* @param {string} dest_path - The destination path to move the items to
|
* @param {string} dest_path - The destination path to move the items to
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
window.move_items = async function(el_items, dest_path){
|
window.move_items = async function(el_items, dest_path, is_undo = false){
|
||||||
let move_op_id = operation_id++;
|
let move_op_id = operation_id++;
|
||||||
operation_cancelled[move_op_id] = false;
|
operation_cancelled[move_op_id] = false;
|
||||||
|
|
||||||
@ -2339,6 +2339,9 @@ window.move_items = async function(el_items, dest_path){
|
|||||||
progwin = await UIWindowMoveProgress({operation_id: move_op_id});
|
progwin = await UIWindowMoveProgress({operation_id: move_op_id});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
|
// storing moved items for undo ability
|
||||||
|
const moved_items = []
|
||||||
|
|
||||||
// Go through each item and try to move it
|
// Go through each item and try to move it
|
||||||
for(let i=0; i<el_items.length; i++){
|
for(let i=0; i<el_items.length; i++){
|
||||||
// get current item
|
// get current item
|
||||||
@ -2578,7 +2581,7 @@ window.move_items = async function(el_items, dest_path){
|
|||||||
fsentry.name = metadata?.original_name || fsentry.name;
|
fsentry.name = metadata?.original_name || fsentry.name;
|
||||||
|
|
||||||
// create new item on matching containers
|
// create new item on matching containers
|
||||||
UIItem({
|
const options = {
|
||||||
appendTo: $(`.item-container[data-path="${html_encode(dest_path)}" i]`),
|
appendTo: $(`.item-container[data-path="${html_encode(dest_path)}" i]`),
|
||||||
immutable: fsentry.immutable,
|
immutable: fsentry.immutable,
|
||||||
associated_app_name: fsentry.associated_app?.name,
|
associated_app_name: fsentry.associated_app?.name,
|
||||||
@ -2598,7 +2601,9 @@ window.move_items = async function(el_items, dest_path){
|
|||||||
has_website: $(el_item).attr('data-has_website') === '1',
|
has_website: $(el_item).attr('data-has_website') === '1',
|
||||||
metadata: fsentry.metadata ?? '',
|
metadata: fsentry.metadata ?? '',
|
||||||
suggested_apps: fsentry.suggested_apps,
|
suggested_apps: fsentry.suggested_apps,
|
||||||
});
|
}
|
||||||
|
UIItem(options);
|
||||||
|
moved_items.push({'options': options, 'original_path': $(el_item).attr('data-path')});
|
||||||
|
|
||||||
// this operation may have created some missing directories,
|
// this operation may have created some missing directories,
|
||||||
// see if any of the directories in the path of this file is new AND
|
// see if any of the directories in the path of this file is new AND
|
||||||
@ -2692,6 +2697,19 @@ window.move_items = async function(el_items, dest_path){
|
|||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// DONE! close progress window with delay to allow user to see 100% progress
|
// DONE! close progress window with delay to allow user to see 100% progress
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
// Add action to actions_history for undo ability
|
||||||
|
if(!is_undo && dest_path !== trash_path){
|
||||||
|
actions_history.push({
|
||||||
|
operation: 'move',
|
||||||
|
data: moved_items,
|
||||||
|
});
|
||||||
|
}else if(!is_undo && dest_path === trash_path){
|
||||||
|
actions_history.push({
|
||||||
|
operation: 'delete',
|
||||||
|
data: moved_items,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(progwin){
|
if(progwin){
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
$(progwin).close();
|
||||||
@ -3506,6 +3524,12 @@ window.undo_last_action = async()=>{
|
|||||||
} else if(last_action.operation === 'copy') {
|
} else if(last_action.operation === 'copy') {
|
||||||
const files = last_action.data;
|
const files = last_action.data;
|
||||||
undo_copy(files);
|
undo_copy(files);
|
||||||
|
} else if(last_action.operation === 'move') {
|
||||||
|
const items = last_action.data;
|
||||||
|
undo_move(items);
|
||||||
|
} else if(last_action.operation === 'delete') {
|
||||||
|
const items = last_action.data;
|
||||||
|
undo_delete(items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3525,3 +3549,145 @@ window.undo_copy = async(files)=>{
|
|||||||
await window.delete_item_with_path(file);
|
await window.delete_item_with_path(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.undo_move = async(items)=>{
|
||||||
|
for (const item of items) {
|
||||||
|
const el = await get_html_from_options(item.options);
|
||||||
|
console.log(item.original_path)
|
||||||
|
move_items([el], path.dirname(item.original_path), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.undo_delete = async(items)=>{
|
||||||
|
for (const item of items) {
|
||||||
|
const el = await get_html_from_options(item.options);
|
||||||
|
let metadata = $(el).attr('data-metadata') === '' ? {} : JSON.parse($(el).attr('data-metadata'))
|
||||||
|
move_items([el], path.dirname(metadata.original_path), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.get_html_element_from_options = async function(options){
|
||||||
|
const item_id = global_element_id++;
|
||||||
|
|
||||||
|
options.disabled = options.disabled ?? false;
|
||||||
|
options.visible = options.visible ?? 'visible'; // one of 'visible', 'revealed', 'hidden'
|
||||||
|
options.is_dir = options.is_dir ?? false;
|
||||||
|
options.is_selected = options.is_selected ?? false;
|
||||||
|
options.is_shared = options.is_shared ?? false;
|
||||||
|
options.is_shortcut = options.is_shortcut ?? 0;
|
||||||
|
options.is_trash = options.is_trash ?? false;
|
||||||
|
options.metadata = options.metadata ?? '';
|
||||||
|
options.multiselectable = options.multiselectable ?? true;
|
||||||
|
options.shortcut_to = options.shortcut_to ?? '';
|
||||||
|
options.shortcut_to_path = options.shortcut_to_path ?? '';
|
||||||
|
options.immutable = (options.immutable === false || options.immutable === 0 || options.immutable === undefined ? 0 : 1);
|
||||||
|
options.sort_container_after_append = (options.sort_container_after_append !== undefined ? options.sort_container_after_append : false);
|
||||||
|
const is_shared_with_me = (options.path !== '/'+window.user.username && !options.path.startsWith('/'+window.user.username+'/'));
|
||||||
|
|
||||||
|
let website_url = determine_website_url(options.path);
|
||||||
|
|
||||||
|
// do a quick check to see if the target parent has any file type restrictions
|
||||||
|
const appendto_allowed_file_types = $(options.appendTo).attr('data-allowed_file_types')
|
||||||
|
if(!window.check_fsentry_against_allowed_file_types_string({is_dir: options.is_dir, name:options.name, type:options.type}, appendto_allowed_file_types))
|
||||||
|
options.disabled = true;
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// HTML for Item
|
||||||
|
// --------------------------------------------------------
|
||||||
|
let h = '';
|
||||||
|
h += `<div id="item-${item_id}"
|
||||||
|
class="item${options.is_selected ? ' item-selected':''} ${options.disabled ? 'item-disabled':''} item-${options.visible}"
|
||||||
|
data-id="${item_id}"
|
||||||
|
data-name="${html_encode(options.name)}"
|
||||||
|
data-metadata="${html_encode(options.metadata)}"
|
||||||
|
data-uid="${options.uid}"
|
||||||
|
data-is_dir="${options.is_dir ? 1 : 0}"
|
||||||
|
data-is_trash="${options.is_trash ? 1 : 0}"
|
||||||
|
data-has_website="${options.has_website ? 1 : 0 }"
|
||||||
|
data-website_url = "${website_url ? html_encode(website_url) : ''}"
|
||||||
|
data-immutable="${options.immutable}"
|
||||||
|
data-is_shortcut = "${options.is_shortcut}"
|
||||||
|
data-shortcut_to = "${html_encode(options.shortcut_to)}"
|
||||||
|
data-shortcut_to_path = "${html_encode(options.shortcut_to_path)}"
|
||||||
|
data-sortable = "${options.sortable ?? 'true'}"
|
||||||
|
data-sort_by = "${html_encode(options.sort_by) ?? 'name'}"
|
||||||
|
data-size = "${options.size ?? ''}"
|
||||||
|
data-type = "${html_encode(options.type) ?? ''}"
|
||||||
|
data-modified = "${options.modified ?? ''}"
|
||||||
|
data-associated_app_name = "${html_encode(options.associated_app_name) ?? ''}"
|
||||||
|
data-path="${html_encode(options.path)}">`;
|
||||||
|
|
||||||
|
// spinner
|
||||||
|
h += `<div class="item-spinner">`;
|
||||||
|
h += `</div>`;
|
||||||
|
// modified
|
||||||
|
h += `<div class="item-attr item-attr--modified">`;
|
||||||
|
h += `<span>${options.modified === 0 ? '-' : timeago.format(options.modified*1000)}</span>`;
|
||||||
|
h += `</div>`;
|
||||||
|
// size
|
||||||
|
h += `<div class="item-attr item-attr--size">`;
|
||||||
|
h += `<span>${options.size ? byte_format(options.size) : '-'}</span>`;
|
||||||
|
h += `</div>`;
|
||||||
|
// type
|
||||||
|
h += `<div class="item-attr item-attr--type">`;
|
||||||
|
if(options.is_dir)
|
||||||
|
h += `<span>Folder</span>`;
|
||||||
|
else
|
||||||
|
h += `<span>${options.type ? html_encode(options.type) : '-'}</span>`;
|
||||||
|
h += `</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
// icon
|
||||||
|
h += `<div class="item-icon">`;
|
||||||
|
h += `<img src="${html_encode(options.icon.image)}" class="item-icon-${options.icon.type}" data-item-id="${item_id}">`;
|
||||||
|
h += `</div>`;
|
||||||
|
// badges
|
||||||
|
h += `<div class="item-badges">`;
|
||||||
|
// website badge
|
||||||
|
h += `<img class="item-badge item-has-website-badge long-hover"
|
||||||
|
style="${options.has_website ? 'display:block;' : ''}"
|
||||||
|
src="${html_encode(window.icons['world.svg'])}"
|
||||||
|
data-item-id="${item_id}"
|
||||||
|
>`;
|
||||||
|
// link badge
|
||||||
|
h += `<img class="item-badge item-has-website-url-badge"
|
||||||
|
style="${website_url ? 'display:block;' : ''}"
|
||||||
|
src="${html_encode(window.icons['link.svg'])}"
|
||||||
|
data-item-id="${item_id}"
|
||||||
|
>`;
|
||||||
|
|
||||||
|
// shared badge
|
||||||
|
h += `<img class="item-badge item-badge-has-permission"
|
||||||
|
style="display: ${ is_shared_with_me ? 'block' : 'none'};
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 2px;" src="${html_encode(window.icons['shared.svg'])}"
|
||||||
|
data-item-id="${item_id}"
|
||||||
|
title="A user has shared this item with you.">`;
|
||||||
|
// owner-shared badge
|
||||||
|
h += `<img class="item-badge item-is-shared"
|
||||||
|
style="background-color: #ffffff; padding: 2px; ${!is_shared_with_me && options.is_shared ? 'display:block;' : ''}"
|
||||||
|
src="${html_encode(window.icons['owner-shared.svg'])}"
|
||||||
|
data-item-id="${item_id}"
|
||||||
|
data-item-uid="${options.uid}"
|
||||||
|
data-item-path="${html_encode(options.path)}"
|
||||||
|
title="You have shared this item with at least one other user."
|
||||||
|
>`;
|
||||||
|
// shortcut badge
|
||||||
|
h += `<img class="item-badge item-shortcut"
|
||||||
|
style="background-color: #ffffff; padding: 2px; ${options.is_shortcut !== 0 ? 'display:block;' : ''}"
|
||||||
|
src="${html_encode(window.icons['shortcut.svg'])}"
|
||||||
|
data-item-id="${item_id}"
|
||||||
|
title="Shortcut"
|
||||||
|
>`;
|
||||||
|
|
||||||
|
h += `</div>`;
|
||||||
|
|
||||||
|
// name
|
||||||
|
h += `<span class="item-name" data-item-id="${item_id}" title="${html_encode(options.name)}">${html_encode(truncate_filename(options.name, TRUNCATE_LENGTH)).replaceAll(' ', ' ')}</span>`
|
||||||
|
// name editor
|
||||||
|
h += `<textarea class="item-name-editor hide-scrollbar" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" data-gramm_editor="false">${html_encode(options.name)}</textarea>`
|
||||||
|
h += `</div>`;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user