diff --git a/navigator/components/FileUpload.js b/navigator/components/FileUpload.js index 891eb21..20be803 100644 --- a/navigator/components/FileUpload.js +++ b/navigator/components/FileUpload.js @@ -92,7 +92,7 @@ export class FileUpload { async upload() { if (await this.check_if_exists()) { - if (!window.confirm(this.filename + ": File exists. Replace?")) + if (!await this.nav_window_ref.modal_prompt.confirm(this.filename + ": File exists. Replace?")) return; } this.make_html_element(); @@ -100,7 +100,7 @@ export class FileUpload { this.proc.fail((e, data) => { this.reader.onload = () => {} this.done(); - window.alert(data); + this.nav_window_ref.modal_prompt.alert(data); }) this.proc.done((data) => { this.nav_window_ref.refresh(); diff --git a/navigator/components/NavContextMenu.js b/navigator/components/NavContextMenu.js index f91c2f2..2753b5b 100644 --- a/navigator/components/NavContextMenu.js +++ b/navigator/components/NavContextMenu.js @@ -75,13 +75,13 @@ export class NavContextMenu { if (new_name === null) return; if (new_name.includes("/")) { - window.alert("File name can't contain `/`."); + this.nav_window_ref.modal_prompt.alert("File name can't contain `/`."); return; } try { await this.target.mv(new_name); } catch(e) { - window.alert(e); + this.nav_window_ref.modal_prompt.alert(e); return; } this.nav_window_ref.refresh(); @@ -117,7 +117,7 @@ export class NavContextMenu { result = await this.zip_for_download(); } catch(e) { this.nav_window_ref.stop_load(); - window.alert(e.message); + this.nav_window_ref.modal_prompt.alert(e.message); return; } this.nav_window_ref.stop_load(); diff --git a/navigator/components/NavDir.js b/navigator/components/NavDir.js index 42c4bd8..0d15ebc 100644 --- a/navigator/components/NavDir.js +++ b/navigator/components/NavDir.js @@ -102,9 +102,9 @@ export class NavDir extends NavEntry { proc.done((data) => { resolve(); }); - proc.fail((e, data) => { + proc.fail(async (e, data) => { if (/^rmdir: failed to remove .*: Directory not empty\n?$/.test(data)) { - if (window.confirm("WARNING: '" + this.path_str() + "' is not empty. Delete recursively? This can NOT be undone.")) { + if (await this.nav_window_ref.modal_prompt.confirm("WARNING: '" + this.path_str() + "' is not empty.", "Delete recursively? This can NOT be undone.")) { this.rm_recursive(resolve, reject); } } else { diff --git a/navigator/components/NavDragDrop.js b/navigator/components/NavDragDrop.js index 85b0686..6712808 100644 --- a/navigator/components/NavDragDrop.js +++ b/navigator/components/NavDragDrop.js @@ -32,12 +32,25 @@ export class NavDragDrop { for (let item of e.dataTransfer.items) { if (item.kind === 'file') { var file = item.getAsFile(); - if (file.type === "") { - window.alert(file.name + ": Cannot upload folders."); + if (file.type === "" && file.size !== 0) { + this.nav_window_ref.modal_prompt.alert(file.name + ": Cannot upload folders."); continue; } - var uploader = new FileUpload(file, this.nav_window_ref); - uploader.upload(); + if (file.size === 0) { + var proc = cockpit.spawn( + ["/usr/share/cockpit/navigator/scripts/touch.py", this.nav_window_ref.pwd().path_str() + "/" + file.name], + {superuser: "try", err: "out"} + ); + proc.done(() => { + this.nav_window_ref.refresh(); + }); + proc.fail((e, data) => { + this.nav_window_ref.modal_prompt.alert(data); + }); + } else { + var uploader = new FileUpload(file, this.nav_window_ref); + uploader.upload(); + } } } } else { diff --git a/navigator/components/NavFile.js b/navigator/components/NavFile.js index a8ef137..9556ec5 100644 --- a/navigator/components/NavFile.js +++ b/navigator/components/NavFile.js @@ -74,7 +74,7 @@ export class NavFile extends NavEntry { this.show_edit_file_contents(); } else { console.log("Unknown mimetype: " + type); - if (window.confirm("Can't open " + this.filename() + " for editing. Download?")) { + if (await this.nav_window_ref.modal_prompt.confirm("Can't open " + this.filename() + " for editing.", "Download it instead?")) { var download = new NavDownloader(this); download.download(); } @@ -89,7 +89,7 @@ export class NavFile extends NavEntry { contents = await cockpit.file(this.path_str(), {superuser: "try"}).read(); } catch (e) { this.nav_window_ref.enable_buttons(); - window.alert(e.message); + this.nav_window_ref.modal_prompt.alert(e.message); return; } var text_area = document.getElementById("nav-edit-contents-textarea"); @@ -110,7 +110,7 @@ export class NavFile extends NavEntry { else await cockpit.script("echo -n > $1", [this.path_str()], {superuser: "try"}); } catch (e) { - window.alert(e.message); + this.nav_window_ref.modal_prompt.alert(e.message); } this.nav_window_ref.refresh(); this.hide_edit_file_contents(); @@ -175,7 +175,7 @@ export class NavFileLink extends NavFile{ this.show_edit_file_contents(); } else { console.log("Unknown mimetype: " + type); - window.alert("Can't open " + this.filename() + " for editing."); + this.nav_window_ref.modal_prompt.alert("Can't open " + this.filename() + " for editing."); } } @@ -189,7 +189,7 @@ export class NavFileLink extends NavFile{ contents = await cockpit.file(target_path, {superuser: "try"}).read(); } catch(e) { this.nav_window_ref.enable_buttons(); - window.alert(e.message); + this.nav_window_ref.modal_prompt.alert(e.message); return; } var text_area = document.getElementById("nav-edit-contents-textarea"); @@ -208,7 +208,7 @@ export class NavFileLink extends NavFile{ try { await cockpit.file(target_path, {superuser: "try"}).replace(new_contents); } catch (e) { - window.alert(e.message); + this.nav_window_ref.modal_prompt.alert(e.message); } this.nav_window_ref.refresh(); this.hide_edit_file_contents(); diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index 9992291..97bdd42 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -3,6 +3,7 @@ import {NavDir} from "./NavDir.js"; import {NavContextMenu} from "./NavContextMenu.js"; import {NavDragDrop} from "./NavDragDrop.js"; import {SortFunctions} from "./SortFunctions.js"; +import {ModalPrompt} from "./ModalPrompt.js"; import {format_bytes} from "../functions.js"; export class NavWindow { @@ -27,6 +28,8 @@ export class NavWindow { this.uploader = new NavDragDrop(this.window, this); this.sort_function = new SortFunctions(); + + this.modal_prompt = new ModalPrompt(); } /** @@ -74,7 +77,7 @@ export class NavWindow { var files = await this.pwd().get_children(this); } catch(e) { this.up(); - window.alert(e); + this.modal_prompt.alert(e); return; } while (this.entries.length) { @@ -227,7 +230,7 @@ export class NavWindow { this.selected_entry().show_properties(); } - show_edit_selected() { + async show_edit_selected() { var dangerous_dirs = [ "/", "/usr", @@ -261,18 +264,20 @@ export class NavWindow { } else { dangerous_selected_str = dangerous_selected[0]; } - if (!window.confirm( + if (!await this.modal_prompt.confirm( "Warning: editing " + dangerous_selected_str + - " can be dangerous. Are you sure?" + " can be dangerous.", + "Are you sure?" )) { return; } } else if (this.selected_entries.size > 1) { - if (!window.confirm( - "Warning: are you sure you want to edit permissions for " + + if (!await this.modal_prompt.confirm( + "Warning: editing permissions for " + this.selected_entries.size + - " files?" + " files.", + "Are you sure?" )) { return; } @@ -351,14 +356,14 @@ export class NavWindow { try { await entry.chown(new_owner, new_group); } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } } if (this.changed_mode && (new_perms & 0o777) !== (entry.stat["mode"] & 0o777)) { try { await entry.chmod(new_perms); } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } } } @@ -369,18 +374,18 @@ export class NavWindow { async delete_selected() { var prompt = ""; if (this.selected_entries.size > 1) { - prompt = "Deleting " + this.selected_entries.size + " files. This cannot be undone. Are you sure?"; + prompt = "Deleting " + this.selected_entries.size + " files."; } else { - prompt = "Deleting `" + this.selected_entry().path_str() + "` cannot be undone. Are you sure?"; + prompt = "Deleting `" + this.selected_entry().path_str() + "`."; } - if (!window.confirm(prompt)) { + if (!await this.modal_prompt.confirm(prompt, "This cannot be undone. Are you sure?")) { return; } for (let target of this.selected_entries) { try { await target.rm(); } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } } this.refresh(); @@ -391,7 +396,7 @@ export class NavWindow { if (new_dir_name === null) return; if (new_dir_name.includes("/")) { - window.alert("Directory name can't contain `/`."); + this.modal_prompt.alert("Directory name can't contain `/`."); return; } var promise = new Promise((resolve, reject) => { @@ -409,7 +414,7 @@ export class NavWindow { try { await promise; } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } this.refresh(); } @@ -419,7 +424,7 @@ export class NavWindow { if (new_file_name === null) return; if (new_file_name.includes("/")) { - window.alert("File name can't contain `/`."); + this.modal_prompt.alert("File name can't contain `/`."); return; } var promise = new Promise((resolve, reject) => { @@ -437,7 +442,7 @@ export class NavWindow { try { await promise; } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } this.refresh(); } @@ -450,7 +455,7 @@ export class NavWindow { if (link_name === null) return; if (link_name.includes("/")) { - window.alert("Link name can't contain `/`."); + this.modal_prompt.alert("Link name can't contain `/`."); return; } var link_path = this.pwd().path_str() + "/" + link_name; @@ -469,7 +474,7 @@ export class NavWindow { try { await promise; } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } this.refresh(); } @@ -511,13 +516,13 @@ export class NavWindow { cmd, {superuser: "try", err: "ignore"} ); - proc.stream((data) => { + proc.stream(async (data) => { var payload = JSON.parse(data); if (payload["wants-response"]) { - var user_response = window.confirm(payload["message"]); + var user_response = await this.modal_prompt.confirm(payload["message"]); proc.input(JSON.stringify(user_response) + "\n", true); } else { - window.alert(payload["message"]); + await this.modal_prompt.alert(payload["message"]); } }); proc.done((data) => { @@ -530,7 +535,7 @@ export class NavWindow { try { await promise; } catch(e) { - window.alert(e); + this.modal_prompt.alert(e); } this.stop_load(); this.refresh();