mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-04 08:30:39 +00:00
refactor: IPC/showSaveFilePicker
This commit is contained in:
+153
-142
@@ -1216,6 +1216,152 @@ const ipc_listener = async (event, handled) => {
|
||||
$el_parent_disable_mask.show();
|
||||
$el_parent_disable_mask.css('z-index', parseInt($el_parent_window.css('z-index')) + 1);
|
||||
$(target_iframe).blur();
|
||||
|
||||
const handle_same_name_exists = async ({
|
||||
action, parent_uuid,
|
||||
}) => {
|
||||
try {
|
||||
await action({ overwrite: false });
|
||||
} catch ( err ) {
|
||||
if ( err.code !== 'item_with_same_name_exists' ) {
|
||||
await UIAlert({
|
||||
message: err.message ?? "Upload failed.",
|
||||
parent_uuid,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
const alert_resp = await UIAlert({
|
||||
message: `<strong>${html_encode(err.entry_name)}</strong> already exists.`,
|
||||
buttons:[
|
||||
{
|
||||
label: i18n('replace'),
|
||||
value: 'replace',
|
||||
type: 'primary',
|
||||
},
|
||||
{
|
||||
label: i18n('cancel'),
|
||||
value: 'cancel',
|
||||
},
|
||||
],
|
||||
parent_uuid,
|
||||
});
|
||||
if ( alert_resp === 'replace' ) {
|
||||
await action({ overwrite: true });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const handle_url_save = async ({ target_path }) => {
|
||||
// download progress tracker
|
||||
let dl_op_id = window.operation_id++;
|
||||
|
||||
// upload progress tracker defaults
|
||||
window.progress_tracker[dl_op_id] = [];
|
||||
window.progress_tracker[dl_op_id][0] = {};
|
||||
window.progress_tracker[dl_op_id][0].total = 0;
|
||||
window.progress_tracker[dl_op_id][0].ajax_uploaded = 0;
|
||||
window.progress_tracker[dl_op_id][0].cloud_uploaded = 0;
|
||||
|
||||
let item_with_same_name_already_exists = true;
|
||||
while(item_with_same_name_already_exists){
|
||||
await download({
|
||||
url: event.data.url,
|
||||
name: path.basename(target_path),
|
||||
dest_path: path.dirname(target_path),
|
||||
auth_token: window.auth_token,
|
||||
api_origin: window.api_origin,
|
||||
dedupe_name: false,
|
||||
overwrite: false,
|
||||
operation_id: dl_op_id,
|
||||
item_upload_id: 0,
|
||||
success: function(res){
|
||||
},
|
||||
error: function(err){
|
||||
UIAlert(err && err.message ? err.message : "Download failed.");
|
||||
}
|
||||
});
|
||||
item_with_same_name_already_exists = false;
|
||||
}
|
||||
};
|
||||
|
||||
const write_file_tell_caller_and_update_views = async ({
|
||||
target_path, el_filedialog_window,
|
||||
file_to_upload, overwrite,
|
||||
}) => {
|
||||
const res = await puter.fs.write(
|
||||
target_path,
|
||||
file_to_upload,
|
||||
{
|
||||
dedupeName: false,
|
||||
overwrite: overwrite
|
||||
}
|
||||
);
|
||||
|
||||
let file_signature = await puter.fs.sign(app_uuid, {uid: res.uid, action: 'write'});
|
||||
file_signature = file_signature.items;
|
||||
|
||||
target_iframe.contentWindow.postMessage({
|
||||
msg: "fileSaved",
|
||||
original_msg_id: msg_id,
|
||||
filename: res.name,
|
||||
saved_file: {
|
||||
name: file_signature.fsentry_name,
|
||||
readURL: file_signature.read_url,
|
||||
writeURL: file_signature.write_url,
|
||||
metadataURL: file_signature.metadata_url,
|
||||
type: file_signature.type,
|
||||
uid: file_signature.uid,
|
||||
path: privacy_aware_path(res.path)
|
||||
},
|
||||
}, '*');
|
||||
|
||||
$(target_iframe).get(0).focus({preventScroll:true});
|
||||
// Update matching items on open windows
|
||||
// todo don't blanket-update, mostly files with thumbnails really need to be updated
|
||||
// first remove overwritten items
|
||||
$(`.item[data-uid="${res.uid}"]`).removeItems();
|
||||
// now add new items
|
||||
UIItem({
|
||||
appendTo: $(`.item-container[data-path="${html_encode(path.dirname(target_path))}" i]`),
|
||||
immutable: res.immutable || res.writable === false,
|
||||
associated_app_name: res.associated_app?.name,
|
||||
path: target_path,
|
||||
icon: await item_icon(res),
|
||||
name: path.basename(target_path),
|
||||
uid: res.uid,
|
||||
size: res.size,
|
||||
modified: res.modified,
|
||||
type: res.type,
|
||||
is_dir: false,
|
||||
is_shared: res.is_shared,
|
||||
suggested_apps: res.suggested_apps,
|
||||
});
|
||||
// sort each window
|
||||
$(`.item-container[data-path="${html_encode(path.dirname(target_path))}" i]`).each(function(){
|
||||
window.sort_items(this, $(this).attr('data-sort_by'), $(this).attr('data-sort_order'))
|
||||
});
|
||||
$(el_filedialog_window).close();
|
||||
window.show_save_account_notice_if_needed();
|
||||
}
|
||||
|
||||
const handle_data_save = async ({ target_path, el_filedialog_window }) => {
|
||||
let file_to_upload = new File([event.data.content], path.basename(target_path));
|
||||
const written = await handle_same_name_exists({
|
||||
action: async ({ overwrite }) => {
|
||||
console.log('action with overwrite flag:', overwrite);
|
||||
await write_file_tell_caller_and_update_views({
|
||||
target_path, el_filedialog_window,
|
||||
file_to_upload, overwrite,
|
||||
});
|
||||
},
|
||||
parent_uuid: $(el_filedialog_window).attr('data-element_uuid'),
|
||||
});
|
||||
|
||||
if ( written ) return true;
|
||||
$(el_filedialog_window).find('.window-disable-mask, .busy-indicator').hide();
|
||||
};
|
||||
|
||||
await UIWindow({
|
||||
path: '/' + window.user.username + '/Desktop',
|
||||
@@ -1234,150 +1380,15 @@ const ipc_listener = async (event, handled) => {
|
||||
onSaveFileDialogSave: async function(target_path, el_filedialog_window){
|
||||
$(el_filedialog_window).find('.window-disable-mask, .busy-indicator').show();
|
||||
let busy_init_ts = Date.now();
|
||||
let done;
|
||||
|
||||
// -------------------------------------
|
||||
// URL
|
||||
// -------------------------------------
|
||||
if(event.data.url){
|
||||
// download progress tracker
|
||||
let dl_op_id = window.operation_id++;
|
||||
|
||||
// upload progress tracker defaults
|
||||
window.progress_tracker[dl_op_id] = [];
|
||||
window.progress_tracker[dl_op_id][0] = {};
|
||||
window.progress_tracker[dl_op_id][0].total = 0;
|
||||
window.progress_tracker[dl_op_id][0].ajax_uploaded = 0;
|
||||
window.progress_tracker[dl_op_id][0].cloud_uploaded = 0;
|
||||
|
||||
let item_with_same_name_already_exists = true;
|
||||
while(item_with_same_name_already_exists){
|
||||
await download({
|
||||
url: event.data.url,
|
||||
name: path.basename(target_path),
|
||||
dest_path: path.dirname(target_path),
|
||||
auth_token: window.auth_token,
|
||||
api_origin: window.api_origin,
|
||||
dedupe_name: false,
|
||||
overwrite: false,
|
||||
operation_id: dl_op_id,
|
||||
item_upload_id: 0,
|
||||
success: function(res){
|
||||
},
|
||||
error: function(err){
|
||||
UIAlert(err && err.message ? err.message : "Download failed.");
|
||||
}
|
||||
});
|
||||
item_with_same_name_already_exists = false;
|
||||
}
|
||||
}
|
||||
// -------------------------------------
|
||||
// File
|
||||
// -------------------------------------
|
||||
else{
|
||||
let overwrite = false;
|
||||
let file_to_upload = new File([event.data.content], path.basename(target_path));
|
||||
let item_with_same_name_already_exists = true;
|
||||
while(item_with_same_name_already_exists){
|
||||
// overwrite?
|
||||
if(overwrite)
|
||||
item_with_same_name_already_exists = false;
|
||||
// upload
|
||||
try{
|
||||
const res = await puter.fs.write(
|
||||
target_path,
|
||||
file_to_upload,
|
||||
{
|
||||
dedupeName: false,
|
||||
overwrite: overwrite
|
||||
}
|
||||
);
|
||||
|
||||
let file_signature = await puter.fs.sign(app_uuid, {uid: res.uid, action: 'write'});
|
||||
file_signature = file_signature.items;
|
||||
|
||||
item_with_same_name_already_exists = false;
|
||||
target_iframe.contentWindow.postMessage({
|
||||
msg: "fileSaved",
|
||||
original_msg_id: msg_id,
|
||||
filename: res.name,
|
||||
saved_file: {
|
||||
name: file_signature.fsentry_name,
|
||||
readURL: file_signature.read_url,
|
||||
writeURL: file_signature.write_url,
|
||||
metadataURL: file_signature.metadata_url,
|
||||
type: file_signature.type,
|
||||
uid: file_signature.uid,
|
||||
path: privacy_aware_path(res.path)
|
||||
},
|
||||
}, '*');
|
||||
|
||||
$(target_iframe).get(0).focus({preventScroll:true});
|
||||
// Update matching items on open windows
|
||||
// todo don't blanket-update, mostly files with thumbnails really need to be updated
|
||||
// first remove overwritten items
|
||||
$(`.item[data-uid="${res.uid}"]`).removeItems();
|
||||
// now add new items
|
||||
UIItem({
|
||||
appendTo: $(`.item-container[data-path="${html_encode(path.dirname(target_path))}" i]`),
|
||||
immutable: res.immutable || res.writable === false,
|
||||
associated_app_name: res.associated_app?.name,
|
||||
path: target_path,
|
||||
icon: await item_icon(res),
|
||||
name: path.basename(target_path),
|
||||
uid: res.uid,
|
||||
size: res.size,
|
||||
modified: res.modified,
|
||||
type: res.type,
|
||||
is_dir: false,
|
||||
is_shared: res.is_shared,
|
||||
suggested_apps: res.suggested_apps,
|
||||
});
|
||||
// sort each window
|
||||
$(`.item-container[data-path="${html_encode(path.dirname(target_path))}" i]`).each(function(){
|
||||
window.sort_items(this, $(this).attr('data-sort_by'), $(this).attr('data-sort_order'))
|
||||
});
|
||||
$(el_filedialog_window).close();
|
||||
window.show_save_account_notice_if_needed();
|
||||
}
|
||||
catch(err){
|
||||
// item with same name exists
|
||||
if(err.code === 'item_with_same_name_exists'){
|
||||
const alert_resp = await UIAlert({
|
||||
message: `<strong>${html_encode(err.entry_name)}</strong> already exists.`,
|
||||
buttons:[
|
||||
{
|
||||
label: i18n('replace'),
|
||||
value: 'replace',
|
||||
type: 'primary',
|
||||
},
|
||||
{
|
||||
label: i18n('cancel'),
|
||||
value: 'cancel',
|
||||
},
|
||||
],
|
||||
parent_uuid: $(el_filedialog_window).attr('data-element_uuid'),
|
||||
})
|
||||
if(alert_resp === 'replace'){
|
||||
overwrite = true;
|
||||
}else if(alert_resp === 'cancel'){
|
||||
// enable parent window
|
||||
$(el_filedialog_window).find('.window-disable-mask, .busy-indicator').hide();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// show error
|
||||
await UIAlert({
|
||||
message: err.message ?? "Upload failed.",
|
||||
parent_uuid: $(el_filedialog_window).attr('data-element_uuid'),
|
||||
});
|
||||
// enable parent window
|
||||
$(el_filedialog_window).find('.window-disable-mask, .busy-indicator').hide();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event.data.url){
|
||||
done = await handle_url_save({ target_path });
|
||||
} else {
|
||||
done = await handle_data_save({ target_path, el_filedialog_window });
|
||||
}
|
||||
|
||||
if ( ! done ) return;
|
||||
|
||||
// done
|
||||
let busy_duration = (Date.now() - busy_init_ts);
|
||||
|
||||
Reference in New Issue
Block a user