From 37b3a6c756c1aa9509ae42d204c566885b838be7 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 14:36:49 -0300 Subject: [PATCH 01/21] store entry filename in memory --- navigator/components/NavContextMenu.js | 2 +- navigator/components/NavDownloader.js | 2 +- navigator/components/NavEntry.js | 19 ++++++++++--------- navigator/components/NavFile.js | 4 ++-- navigator/components/NavWindow.js | 4 ++-- navigator/components/SortFunctions.js | 4 ++-- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/navigator/components/NavContextMenu.js b/navigator/components/NavContextMenu.js index 1333cf0..c9e9cc7 100644 --- a/navigator/components/NavContextMenu.js +++ b/navigator/components/NavContextMenu.js @@ -72,7 +72,7 @@ export class NavContextMenu { new_link(e) { var default_target = ""; if (this.nav_window_ref.selected_entries.size <= 1 && this.target !== this.nav_window_ref.pwd()) - default_target = this.target.filename(); + default_target = this.target.filename; this.nav_window_ref.ln(default_target); } diff --git a/navigator/components/NavDownloader.js b/navigator/components/NavDownloader.js index fa64df7..12b234b 100644 --- a/navigator/components/NavDownloader.js +++ b/navigator/components/NavDownloader.js @@ -26,7 +26,7 @@ export class NavDownloader { */ constructor(file) { this.path = file.path_str(); - this.filename = file.filename(); + this.filename = file.filename; this.read_size = file.stat["size"]; } diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index bd3fd03..26707c9 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -33,13 +33,14 @@ export class NavEntry { this.path = path.split("/").splice(1); else this.path = (path.length) ? path : [""]; + this.filename = this.get_filename(); this.dom_element = document.createElement("div"); this.dom_element.classList.add("nav-item"); let icon = this.dom_element.nav_item_icon = document.createElement("i"); icon.classList.add("nav-item-icon"); let title = this.dom_element.nav_item_title = document.createElement("div"); title.classList.add("nav-item-title", "no-select"); - title.innerText = this.filename(); + title.innerText = this.filename; this.dom_element.appendChild(icon); this.dom_element.appendChild(title); let title_edit = this.dom_element.nav_item_title.editor = document.createElement("input"); @@ -63,10 +64,10 @@ export class NavEntry { this.dom_element.addEventListener("click", this); this.dom_element.addEventListener("contextmenu", this); } - this.is_hidden_file = this.filename().startsWith('.'); + this.is_hidden_file = this.filename.startsWith('.'); if (this.is_hidden_file) icon.style.opacity = 0.5; - this.dom_element.title = this.filename(); + this.dom_element.title = this.filename; if (nav_window_ref && nav_window_ref.item_display === "list") { let mode = document.createElement("div"); let owner = document.createElement("div"); @@ -127,7 +128,7 @@ export class NavEntry { * * @returns {string} */ - filename() { + get_filename() { var name = this.path[this.path.length - 1]; if (!name) name = "/"; @@ -255,7 +256,7 @@ export class NavEntry { * @param {string} new_path */ async rename(new_name) { - if (new_name === this.filename()) + if (new_name === this.filename) return; if (new_name.includes("/")) { this.nav_window_ref.modal_prompt.alert("File name can't contain `/`."); @@ -289,7 +290,7 @@ export class NavEntry { window.addEventListener("click", element.hide_func); switch (element) { case this.dom_element.nav_item_title: - element.editor.value = this.filename(); + element.editor.value = this.filename; break; default: element.editor.value = element.innerText; @@ -323,8 +324,8 @@ export class NavEntry { show_properties(extra_properties = "") { var selected_name_fields = document.getElementsByClassName("nav-info-column-filename"); for (let elem of selected_name_fields) { - elem.innerHTML = this.filename(); - elem.title = this.filename(); + elem.innerHTML = this.filename; + elem.title = this.filename; } var html = ""; html += property_entry_html("Mode", this.stat["mode-str"]); @@ -339,7 +340,7 @@ export class NavEntry { } populate_edit_fields() { - document.getElementById("nav-edit-filename").innerText = this.filename(); + document.getElementById("nav-edit-filename").innerText = this.filename; var mode_bits = [ "other-exec", "other-write", "other-read", "group-exec", "group-write", "group-read", diff --git a/navigator/components/NavFile.js b/navigator/components/NavFile.js index e06fd30..4c87162 100644 --- a/navigator/components/NavFile.js +++ b/navigator/components/NavFile.js @@ -94,7 +94,7 @@ export class NavFile extends NavEntry { this.show_edit_file_contents(); } else { console.log("Unknown mimetype: " + type); - if (await this.nav_window_ref.modal_prompt.confirm("Can't open " + this.filename() + " for editing.", "Download it instead?")) { + 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(); } @@ -195,7 +195,7 @@ export class NavFileLink extends NavFile{ this.show_edit_file_contents(); } else { console.log("Unknown mimetype: " + type); - this.nav_window_ref.modal_prompt.alert("Can't open " + this.filename() + " for editing."); + this.nav_window_ref.modal_prompt.alert("Can't open " + this.filename + " for editing."); } } diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index 5967f54..d50200d 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -321,7 +321,7 @@ export class NavWindow { } var targets = []; for (let target of this.selected_entries) { - targets.push(target.filename()); + targets.push(target.filename); } var targets_str = targets.join(", "); document.getElementById("selected-files-list-header").innerText = "Applying edits to:"; @@ -834,7 +834,7 @@ export class NavWindow { search_filter(event) { var search_name = event.target.value; this.entries.forEach((entry) => { - if (entry.filename().toLowerCase().startsWith(search_name.toLowerCase())) + if (entry.filename.toLowerCase().startsWith(search_name.toLowerCase())) entry.show(); else entry.hide(); diff --git a/navigator/components/SortFunctions.js b/navigator/components/SortFunctions.js index bb7845b..e6f322d 100644 --- a/navigator/components/SortFunctions.js +++ b/navigator/components/SortFunctions.js @@ -60,11 +60,11 @@ export class SortFunctions { } name_asc(first, second) { - return first.filename().localeCompare(second.filename()); + return first.filename.localeCompare(second.filename); } name_desc(first, second) { - return second.filename().localeCompare(first.filename()); + return second.filename.localeCompare(first.filename); } owner_asc(first, second) { From f94dbdfed1d291ed475d9b5bd9bf221afc205d5f Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 14:49:08 -0300 Subject: [PATCH 02/21] add fuzzy search --- navigator/components/NavWindow.js | 7 ++++++- navigator/navigator.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index d50200d..30ca52a 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -833,8 +833,13 @@ export class NavWindow { search_filter(event) { var search_name = event.target.value; + let search_func; + if (search_name[0] === '*') + search_func = (entry) => entry.filename.toLowerCase().includes(search_name.slice(1).toLowerCase()); + else + search_func = (entry) => entry.filename.toLowerCase().startsWith(search_name.toLowerCase()); this.entries.forEach((entry) => { - if (entry.filename.toLowerCase().startsWith(search_name.toLowerCase())) + if (search_func(entry)) entry.show(); else entry.hide(); diff --git a/navigator/navigator.html b/navigator/navigator.html index 72df661..8d5d1d2 100644 --- a/navigator/navigator.html +++ b/navigator/navigator.html @@ -55,7 +55,7 @@
- +
From 5ee43047f9418a90efd32266a304d274e6ebf723 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 15:47:02 -0300 Subject: [PATCH 05/21] fix synopsys --- navigator/scripts/write-chunks.py3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/navigator/scripts/write-chunks.py3 b/navigator/scripts/write-chunks.py3 index 3ccb8df..cad06b0 100755 --- a/navigator/scripts/write-chunks.py3 +++ b/navigator/scripts/write-chunks.py3 @@ -18,7 +18,7 @@ """ """ -Synopsis: `write-chunks.py3 ` +Synopsis: `echo | write-chunks.py3` JSON objects are of form: obj = { seek: From dffe7b00cecb3fda6fd5e9203be0b4506c1a6bef Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 16:03:26 -0300 Subject: [PATCH 06/21] check if paths exist all at once --- navigator/components/NavDragDrop.js | 26 +++++++++++++++-- navigator/scripts/return-exists.py3 | 44 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100755 navigator/scripts/return-exists.py3 diff --git a/navigator/components/NavDragDrop.js b/navigator/components/NavDragDrop.js index 6d0ee19..5872a3c 100644 --- a/navigator/components/NavDragDrop.js +++ b/navigator/components/NavDragDrop.js @@ -98,10 +98,30 @@ export class NavDragDrop { * @returns {FileUpload[]} */ async handle_conflicts(uploads) { + let test_paths = []; + for (let upload of uploads) + test_paths.push(upload.path); + let proc = cockpit.spawn( + ["/usr/share/cockpit/navigator/scripts/return-exists.py3", ... test_paths], + {error: "out", superuser: "try"} + ); + let exist_result; + proc.done((data) => { + exist_result = JSON.parse(data); + }); + proc.fail((e, data) => { + this.nav_window_ref.modal_prompt.alert(e, data); + }); + try { + await proc; + } catch { + return; + } + console.log(exist_result); let keepers = []; let requests = {}; for (let upload of uploads) { - if (!await check_if_exists(upload.path)) { + if (!exist_result[upload.path]) { keepers.push(upload.filename); continue; } @@ -163,8 +183,10 @@ export class NavDragDrop { } } this.drop_area.classList.remove("drag-enter"); - if (uploads.length === 0) + if (uploads.length === 0) { + this.nav_window_ref.stop_load(); break; + } uploads = await this.handle_conflicts(uploads); this.nav_window_ref.stop_load(); uploads.forEach((upload) => {upload.upload()}); diff --git a/navigator/scripts/return-exists.py3 b/navigator/scripts/return-exists.py3 new file mode 100755 index 0000000..38ce962 --- /dev/null +++ b/navigator/scripts/return-exists.py3 @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +""" + Cockpit Navigator - A File System Browser for Cockpit. + Copyright (C) 2021 Josh Boudreau + + This file is part of Cockpit Navigator. + Cockpit Navigator is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Cockpit Navigator 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with Cockpit Navigator. If not, see . +""" + +""" +Synopsys: return-exists.py3 /full/path1 [/full/path2 ...] +replys with JSON formatted dictionary of path : boolean where true means the file exists +""" + +import os +import sys +import json + +def main(): + argv = sys.argv + argc = len(sys.argv) + if argc <= 1: + print("No arguments provided") + sys.exit(1) + response = {} + for i in range (1, argc): + path = argv[i] + response[path] = os.path.lexists(path) + print(json.dumps(response)) + sys.exit(0) + + +if __name__ == "__main__": + main() \ No newline at end of file From 11851bbfede2c72c1b175bbed4575ac7c14aaf23 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 16:42:57 -0300 Subject: [PATCH 07/21] implement upload manager to limit concurrent uploads --- navigator/components/FileUpload.js | 4 +- navigator/components/FileUploadManager.js | 47 +++++++++++++++++++++++ navigator/components/NavDragDrop.js | 6 +-- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 navigator/components/FileUploadManager.js diff --git a/navigator/components/FileUpload.js b/navigator/components/FileUpload.js index 3855a0f..b52b521 100644 --- a/navigator/components/FileUpload.js +++ b/navigator/components/FileUpload.js @@ -129,8 +129,10 @@ export class FileUpload { this.nav_window_ref.modal_prompt.alert(e, data); }) this.proc.done((data) => { - this.nav_window_ref.refresh(); + if (!this.done_hook) + this.nav_window_ref.refresh(); }) + this.proc.always(() => this?.done_hook?.()); this.reader.onerror = (evt) => { this.modal_prompt.alert("Failed to read file: " + this.filename, "Upload of directories not supported."); this.done(); diff --git a/navigator/components/FileUploadManager.js b/navigator/components/FileUploadManager.js new file mode 100644 index 0000000..3e8e46e --- /dev/null +++ b/navigator/components/FileUploadManager.js @@ -0,0 +1,47 @@ +/* + Cockpit Navigator - A File System Browser for Cockpit. + Copyright (C) 2021 Josh Boudreau + Copyright (C) 2021 Sam Silver + Copyright (C) 2021 Dawson Della Valle + + This file is part of Cockpit Navigator. + Cockpit Navigator is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Cockpit Navigator 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 General Public License for more details. + You should have received a copy of the GNU General Public License + along with Cockpit Navigator. If not, see . + */ + +import {FileUpload} from "./FileUpload.js"; +import {NavWindow} from "./NavWindow.js"; + +export class FileUploadManager { + /** + * + * @param {FileUpload[]} uploads + * @param {NavWindow} nav_window_ref + * @param {number} max_concurrent + */ + constructor(uploads, nav_window_ref, max_concurrent = 10) { + this.remaining_uploads = uploads; + this.max_concurrent = Math.min(max_concurrent, uploads.length); + let start_next = this.kickoff = () => { + let next_upload = this.remaining_uploads.pop(); + next_upload?.upload?.(); + if (!this.remaining_uploads.length) + nav_window_ref.refresh(); + } + this.remaining_uploads.forEach((upload) => {upload.done_hook = start_next}); + } + + start_uploads() { + for (let i = 0; i < this.max_concurrent; i++) { + this.kickoff(); + } + } +} \ No newline at end of file diff --git a/navigator/components/NavDragDrop.js b/navigator/components/NavDragDrop.js index 5872a3c..cdc7faa 100644 --- a/navigator/components/NavDragDrop.js +++ b/navigator/components/NavDragDrop.js @@ -20,7 +20,7 @@ import {FileUpload} from "./FileUpload.js"; import {ModalPrompt} from "./ModalPrompt.js"; import {NavWindow} from "./NavWindow.js"; -import {check_if_exists} from "../functions.js"; +import {FileUploadManager} from "./FileUploadManager.js"; export class NavDragDrop { /** @@ -117,7 +117,6 @@ export class NavDragDrop { } catch { return; } - console.log(exist_result); let keepers = []; let requests = {}; for (let upload of uploads) { @@ -189,7 +188,8 @@ export class NavDragDrop { } uploads = await this.handle_conflicts(uploads); this.nav_window_ref.stop_load(); - uploads.forEach((upload) => {upload.upload()}); + let upload_manager = new FileUploadManager(uploads, this.nav_window_ref); + upload_manager.start_uploads(); break; default: this.drop_area.classList.remove("drag-enter"); From f0fc84d80cf025d22f4bbc6c46c991475e9de391 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 17:34:54 -0300 Subject: [PATCH 08/21] have single upload manager that can be added to --- navigator/components/FileUpload.js | 2 +- navigator/components/FileUploadManager.js | 39 ++++++++++++++++------- navigator/components/NavDragDrop.js | 4 +-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/navigator/components/FileUpload.js b/navigator/components/FileUpload.js index b52b521..0309a1b 100644 --- a/navigator/components/FileUpload.js +++ b/navigator/components/FileUpload.js @@ -44,6 +44,7 @@ export class FileUpload { this.timestamp = Date.now(); this.modal_prompt = new ModalPrompt(); this.using_webkit = true; + this.make_html_element(); } make_html_element() { @@ -121,7 +122,6 @@ export class FileUpload { } async upload() { - this.make_html_element(); this.proc = cockpit.spawn(["/usr/share/cockpit/navigator/scripts/write-chunks.py3", this.path], {err: "out", superuser: "try"}); this.proc.fail((e, data) => { this.reader.onload = () => {} diff --git a/navigator/components/FileUploadManager.js b/navigator/components/FileUploadManager.js index 3e8e46e..22e6f74 100644 --- a/navigator/components/FileUploadManager.js +++ b/navigator/components/FileUploadManager.js @@ -23,25 +23,40 @@ import {NavWindow} from "./NavWindow.js"; export class FileUploadManager { /** * - * @param {FileUpload[]} uploads * @param {NavWindow} nav_window_ref * @param {number} max_concurrent */ - constructor(uploads, nav_window_ref, max_concurrent = 10) { - this.remaining_uploads = uploads; - this.max_concurrent = Math.min(max_concurrent, uploads.length); - let start_next = this.kickoff = () => { + constructor(nav_window_ref, max_concurrent = 10) { + this.nav_window_ref = nav_window_ref; + this.running = 0; + this.remaining_uploads = []; + this.max_concurrent = max_concurrent; + this.start_next = () => { let next_upload = this.remaining_uploads.pop(); - next_upload?.upload?.(); - if (!this.remaining_uploads.length) - nav_window_ref.refresh(); + if (next_upload) { + next_upload?.upload?.(); + this.running++; + } } - this.remaining_uploads.forEach((upload) => {upload.done_hook = start_next}); } - start_uploads() { - for (let i = 0; i < this.max_concurrent; i++) { - this.kickoff(); + /** + * + * @param {...FileUpload} uploads + */ + add(...uploads) { + let done_hook = () => { + this.running--; + this.start_next(); + if (!this.running) + this.nav_window_ref.refresh(); + } + for (let upload of uploads) { + upload.done_hook = done_hook; + this.remaining_uploads.unshift(upload); + } + while (this.remaining_uploads.length && this.running < this.max_concurrent) { + this.start_next(); } } } \ No newline at end of file diff --git a/navigator/components/NavDragDrop.js b/navigator/components/NavDragDrop.js index cdc7faa..5b9e73c 100644 --- a/navigator/components/NavDragDrop.js +++ b/navigator/components/NavDragDrop.js @@ -36,6 +36,7 @@ export class NavDragDrop { this.drop_area = drop_area; this.nav_window_ref = nav_window_ref; this.modal_prompt = new ModalPrompt(); + this.upload_manager = new FileUploadManager(this.nav_window_ref, 10); } /** @@ -188,8 +189,7 @@ export class NavDragDrop { } uploads = await this.handle_conflicts(uploads); this.nav_window_ref.stop_load(); - let upload_manager = new FileUploadManager(uploads, this.nav_window_ref); - upload_manager.start_uploads(); + this.upload_manager.add(... uploads); break; default: this.drop_area.classList.remove("drag-enter"); From 04bd831a9ca730b019791b2ea84a2779697f42c3 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 17:48:43 -0300 Subject: [PATCH 09/21] update xfr rates on interval, not once per chunk --- navigator/components/FileUpload.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/navigator/components/FileUpload.js b/navigator/components/FileUpload.js index 0309a1b..94c1455 100644 --- a/navigator/components/FileUpload.js +++ b/navigator/components/FileUpload.js @@ -158,6 +158,7 @@ export class FileUpload { } this.done(); } + this.update_rates_interval = setInterval(this.display_xfr_rate.bind(this), 1000); } /** @@ -193,6 +194,7 @@ export class FileUpload { done() { this.proc.input(); // close stdin this.remove_html_element(); + clearInterval(this.update_rates_interval); } update_xfr_rate() { @@ -200,12 +202,19 @@ export class FileUpload { var elapsed = (now - this.timestamp) / 1000; this.timestamp = now; var rate = this.chunk_size / elapsed; - this.rate.innerText = cockpit.format_bytes_per_sec(rate); + this.rate_avg = (this.rate_avg) + ? (0.125 * rate + (0.875 * this.rate_avg)) + : rate; // keep exponential moving average of chunk time for eta this.chunk_time = (this.chunk_time) ? (0.125 * elapsed + (0.875 * this.chunk_time)) : elapsed; var eta = (this.num_chunks - this.chunk_index) * this.chunk_time; - this.eta.innerText = format_time_remaining(eta); + this.eta_avg = eta; + } + + display_xfr_rate() { + this.rate.innerText = cockpit.format_bytes_per_sec(this.rate_avg); + this.eta.innerText = format_time_remaining(this.eta_avg); } } From 6da417a9e6fc0c7930e68ab518db573a1f98ebd0 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Tue, 20 Jul 2021 09:44:09 -0300 Subject: [PATCH 10/21] show load spinner while deleting --- navigator/components/NavWindow.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index 0de0494..51ea5b2 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -404,6 +404,7 @@ export class NavWindow { if (!await this.modal_prompt.confirm(prompt, "This cannot be undone. Are you sure?", true)) { return; } + this.start_load(); for (let target of this.selected_entries) { try { await target.rm(); @@ -411,6 +412,7 @@ export class NavWindow { this.modal_prompt.alert(e); } } + this.stop_load(); this.refresh(); } From abe58a8b1486bc6c8c2d806991130f46be3fcc84 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Tue, 20 Jul 2021 09:47:42 -0300 Subject: [PATCH 11/21] update repo instructions --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 50db70f..0251113 100644 --- a/README.md +++ b/README.md @@ -39,12 +39,12 @@ With no command line use needed, you can: ### Ubuntu 1. Import GPG Key ```sh -wget -qO - http://repo.45drives.com/key.asc | sudo apt-key add - +wget -qO - https://repo.45drives.com/key/gpg.asc | gpg --dearmor -o /usr/share/keyrings/45drives-archive-keyring.gpg ``` -2. Add 45drives.list +2. Add 45drives.sources ```sh cd /etc/apt/sources.list.d -sudo wget http://repo.45drives.com/debian/45drives.list +curl -sSL https://repo.45drives.com/lists/45drives.sources -o /etc/apt/sources.list.d/45drives.sources sudo apt update ``` 3. Install Package @@ -52,10 +52,9 @@ sudo apt update sudo apt install cockpit-navigator ``` ### EL7/EL8 -1. Add Repository +1. Add 45drives.repo ```sh -cd /etc/yum.repos.d -sudo wget http://repo.45drives.com/rhel/45drives.repo +curl -sSL https://repo.45drives.com/lists/45drives.repo -o /etc/yum.repos.d/45drives.repo sudo yum clean all ``` 2. Install Package From 09394b27e95bfcf9abccdc97e271bb4bda42954a Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Tue, 20 Jul 2021 10:40:50 -0300 Subject: [PATCH 12/21] fix upload notification style and event listener on inputs --- navigator/components/FileUpload.js | 22 ++++++++++++++-------- navigator/components/NavDragDrop.js | 2 +- navigator/components/NavEntry.js | 3 +++ navigator/components/NavWindow.js | 7 ++++++- navigator/navigator.css | 20 ++++++++++++++------ navigator/navigator.html | 18 ++++++++++-------- navigator/navigator.js | 1 + 7 files changed, 49 insertions(+), 24 deletions(-) diff --git a/navigator/components/FileUpload.js b/navigator/components/FileUpload.js index 94c1455..3ceb895 100644 --- a/navigator/components/FileUpload.js +++ b/navigator/components/FileUpload.js @@ -48,20 +48,24 @@ export class FileUpload { } make_html_element() { - var notification = document.createElement("div"); + var notification = this.dom_element = document.createElement("div"); notification.classList.add("nav-notification"); var header = document.createElement("div"); header.classList.add("nav-notification-header"); notification.appendChild(header); - header.innerText = "Uploading " + this.filename; - header.style.position = "relative"; - header.style.paddingRight = "1em"; + header.style.display = "grid"; + header.style.gridTemplateColumns = "1fr 20px"; + header.style.gap = "5px"; + + var title = document.createElement("p"); + title.innerText = "Uploading " + this.filename; + title.title = this.filename; var cancel = document.createElement("i"); cancel.classList.add("fa", "fa-times"); - cancel.style.position = "absolute" - cancel.style.right = "0"; + cancel.style.justifySelf = "center"; + cancel.style.alignSelf = "center"; cancel.style.cursor = "pointer"; cancel.onclick = () => { if (this.proc) { @@ -69,7 +73,8 @@ export class FileUpload { this.done(); } } - header.appendChild(cancel); + + header.append(title, cancel); var info = document.createElement("div"); info.classList.add("flex-row", "space-between"); @@ -122,6 +127,7 @@ export class FileUpload { } async upload() { + this.dom_element.style.display = "flex"; this.proc = cockpit.spawn(["/usr/share/cockpit/navigator/scripts/write-chunks.py3", this.path], {err: "out", superuser: "try"}); this.proc.fail((e, data) => { this.reader.onload = () => {} @@ -158,7 +164,7 @@ export class FileUpload { } this.done(); } - this.update_rates_interval = setInterval(this.display_xfr_rate.bind(this), 1000); + this.update_rates_interval = setInterval(this.display_xfr_rate.bind(this), 2000); } /** diff --git a/navigator/components/NavDragDrop.js b/navigator/components/NavDragDrop.js index 5b9e73c..2d3f751 100644 --- a/navigator/components/NavDragDrop.js +++ b/navigator/components/NavDragDrop.js @@ -36,7 +36,7 @@ export class NavDragDrop { this.drop_area = drop_area; this.nav_window_ref = nav_window_ref; this.modal_prompt = new ModalPrompt(); - this.upload_manager = new FileUploadManager(this.nav_window_ref, 10); + this.upload_manager = new FileUploadManager(this.nav_window_ref, 6); } /** diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index c9fbd6a..a3fcb51 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -86,6 +86,7 @@ export class NavEntry { this.dom_element.appendChild(group); this.dom_element.appendChild(size); } + this.visible = true; } /** @@ -158,10 +159,12 @@ export class NavEntry { } show() { + this.visible = true; this.dom_element.style.display = "flex"; } hide() { + this.visible = false; this.dom_element.style.display = "none"; } diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index 51ea5b2..7144438 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -56,6 +56,7 @@ export class NavWindow { * @param {Event} e */ handleEvent(e) { + console.log(e); switch (e.type) { case "click": if (e.target === this.window) { @@ -73,6 +74,8 @@ export class NavWindow { } else if (e.keyCode === 65 && e.ctrlKey) { this.select_all(); e.preventDefault(); + } else if (e.keyCode === 27) { + this.clear_selected(); } else if (e.keyCode === 67 && e.ctrlKey) { this.copy(); } else if (e.keyCode === 86 && e.ctrlKey) { @@ -212,6 +215,7 @@ export class NavWindow { this.selected_entries.clear(); to_be_selected = [entry]; } + to_be_selected = to_be_selected.filter((entry) => entry.visible); for (let i of to_be_selected) { this.selected_entries.add(i); } @@ -248,7 +252,7 @@ export class NavWindow { } show_selected_properties() { - this.selected_entry().show_properties(); + this.selected_entry()?.show_properties?.(); } async show_edit_selected() { @@ -645,6 +649,7 @@ export class NavWindow { default: break; } + e.stopPropagation(); } nav_bar_cd() { diff --git a/navigator/navigator.css b/navigator/navigator.css index fd861d1..5e0be1e 100644 --- a/navigator/navigator.css +++ b/navigator/navigator.css @@ -651,7 +651,7 @@ input:checked + .slider:before { .nav-notifications { position: absolute; bottom: 0; - right: 0; + right: 10px; padding: 5px; display: flex; flex-flow: column-reverse nowrap; @@ -663,7 +663,7 @@ input:checked + .slider:before { .nav-notification { margin: 5px; position: relative; - display: flex; + display: none; flex-flow: column nowrap; align-items: stretch; z-index: 10; @@ -673,15 +673,23 @@ input:checked + .slider:before { border-radius: var(--nav-border-radius); color: var(--font); } - -.nav-notification-header { +/* .nav-notification-header { position: relative; z-index: 10; font-weight: bold; -} +} */ -.nav-notification-header > progress { +/* .nav-notification-header > progress { position: relative; z-index: 10; +} */ + +.nav-notification-header > p { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } +.no-border { + border: none; +} \ No newline at end of file diff --git a/navigator/navigator.html b/navigator/navigator.html index f047a07..b678a99 100644 --- a/navigator/navigator.html +++ b/navigator/navigator.html @@ -68,14 +68,16 @@
-