From 05d82eb12eb26cc5cfefb61accca33d4dd9ec6bc Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 12:17:11 -0300 Subject: [PATCH 1/9] implement more intuitive file renaming --- navigator/components/NavContextMenu.js | 47 ++++---------- navigator/components/NavEntry.js | 90 +++++++++++++++++++++++++- navigator/components/NavFile.js | 5 +- navigator/components/NavWindow.js | 6 +- 4 files changed, 109 insertions(+), 39 deletions(-) diff --git a/navigator/components/NavContextMenu.js b/navigator/components/NavContextMenu.js index a34bdf9..1333cf0 100644 --- a/navigator/components/NavContextMenu.js +++ b/navigator/components/NavContextMenu.js @@ -53,7 +53,7 @@ export class NavContextMenu { var name_list = func[0].split("_"); name_list.forEach((word, index) => {name_list[index] = word.charAt(0).toUpperCase() + word.slice(1)}); elem.innerHTML = func[1] + name_list.join(" "); - elem.addEventListener("click", (e) => {this[func[0]].bind(this).apply()}); + elem.addEventListener("click", (e) => {this[func[0]].bind(this, e).apply()}); elem.classList.add("nav-context-menu-item") elem.id = "nav-context-menu-" + func[0]; this.dom_element.appendChild(elem); @@ -61,58 +61,37 @@ export class NavContextMenu { } } - new_dir() { + new_dir(e) { this.nav_window_ref.mkdir(); } - new_file() { + new_file(e) { this.nav_window_ref.touch(); } - new_link() { + 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(); this.nav_window_ref.ln(default_target); } - cut() { + cut(e) { this.nav_window_ref.cut(); } - copy() { + copy(e) { this.nav_window_ref.copy(); } - paste() { + paste(e) { this.nav_window_ref.paste(); } - async rename() { + async rename(e) { this.hide(); - let response = await this.nav_window_ref.modal_prompt.prompt("Renaming " + this.target.filename(), - { - new_name: { - label: "New Name: ", - type: "text", - default: this.target.filename() - } - } - ); - if (response === null) - return; - var new_name = response.new_name; - if (new_name.includes("/")) { - this.nav_window_ref.modal_prompt.alert("File name can't contain `/`."); - return; - } - try { - await this.target.mv(new_name); - } catch(e) { - this.nav_window_ref.modal_prompt.alert(e); - return; - } - this.nav_window_ref.refresh(); + this.target.show_edit(this.target.dom_element.nav_item_title); + e.stopPropagation(); } zip_for_download() { @@ -134,7 +113,7 @@ export class NavContextMenu { }); } - async download() { + async download(e) { var download_target = ""; if (this.nav_window_ref.selected_entries.size === 1 && !(this.nav_window_ref.selected_entry() instanceof NavDir)) { download_target = this.nav_window_ref.selected_entry(); @@ -155,11 +134,11 @@ export class NavContextMenu { download.download(); } - delete() { + delete(e) { this.nav_window_ref.delete_selected(); } - properties() { + properties(e) { this.nav_window_ref.show_edit_selected(); } diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index 45eef0e..6ccff18 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -42,6 +42,19 @@ export class NavEntry { 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"); + title_edit.type = "text"; + title_edit.style.display = "none"; + title_edit.style.padding = title_edit.style.margin = "0"; + title_edit.style.flexBasis = "0"; + title_edit.style.flexGrow = "2"; + title_edit.classList.add("nav-item-title"); + title_edit.oninput = (e) => { + let elem = e.target; + elem.style.width = elem.value.length + "ch"; + } + title_edit.addEventListener("click", (e) => {e.stopPropagation();}); + this.dom_element.appendChild(title_edit); this.stat = stat; if (stat && stat["inaccessible"]) { this.dom_element.style.cursor = "not-allowed"; @@ -80,9 +93,18 @@ export class NavEntry { handleEvent(e) { switch (e.type) { case "click": + if (this.nav_window_ref.selected_entries.size === 1 && this.nav_window_ref.selected_entries.has(this)) { + switch (e.target) { + case this.dom_element.nav_item_title: + this.show_edit(e.target); + e.stopPropagation(); + break; + default: + break; + } + } this.nav_window_ref.set_selected(this, e.shiftKey, e.ctrlKey); this.context_menu_ref.hide(); - e.stopPropagation(); break; case "contextmenu": this.context_menu_ref.show(e, this); @@ -227,6 +249,72 @@ export class NavEntry { }); } + /** + * + * @param {string} new_path + */ + async rename(new_name) { + if (new_name === this.filename()) + return; + if (new_name.includes("/")) { + this.nav_window_ref.modal_prompt.alert("File name can't contain `/`."); + return; + } else if (new_name === "..") { + this.nav_window_ref.modal_prompt.alert( + "File name can't be `..`.", + "If you want to move the file, right click > cut then right click > paste." + ); + return; + } + try { + await this.mv(new_name); + } catch(e) { + this.nav_window_ref.modal_prompt.alert(e); + return; + } + this.nav_window_ref.refresh(); + } + + /** + * + * @param {HTMLDivElement} element + * @returns + */ + show_edit(element) { + if (!element.editor) + return; + element.hide_func = () => {this.hide_edit(element)}; + element.editor.onchange = element.hide_func; + window.addEventListener("click", element.hide_func); + switch (element) { + case this.dom_element.nav_item_title: + element.editor.value = this.filename(); + break; + default: + element.editor.value = element.innerText; + break; + } + element.editor.style.width = element.editor.value.length + "ch"; + element.editor.style.display = "inline-block"; + element.style.display = "none"; + element.editor.focus(); + } + + hide_edit(element) { + if (!element.editor) + return; + switch (element) { + case this.dom_element.nav_item_title: + this.rename(element.editor.value); + break; + default: + break; + } + element.editor.style.display = "none"; + element.style.display = "inline-block"; + window.removeEventListener("click", element.hide_func); + } + /** * * @param {string} extra_properties diff --git a/navigator/components/NavFile.js b/navigator/components/NavFile.js index 199d6db..e06fd30 100644 --- a/navigator/components/NavFile.js +++ b/navigator/components/NavFile.js @@ -43,9 +43,10 @@ export class NavFile extends NavEntry { handleEvent(e) { switch(e.type){ case "click": - if (this.double_click) + if (this.double_click) { this.open(); - else { // single click + return; + } else { // single click this.double_click = true; if(this.timeout) clearTimeout(this.timeout) diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index b7e3955..c97afdb 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -58,8 +58,10 @@ export class NavWindow { handleEvent(e) { switch (e.type) { case "click": - this.clear_selected(); - this.show_selected_properties(); + if (e.target === this.window) { + this.clear_selected(); + this.show_selected_properties(); + } break; case "contextmenu": this.context_menu.show(e, this.pwd()); From ef6cb9ecbe08fdc010f295411dc4e78a7c066785 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 12:19:45 -0300 Subject: [PATCH 2/9] keep margin the same --- navigator/components/NavEntry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index 6ccff18..ef20944 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -45,7 +45,7 @@ export class NavEntry { let title_edit = this.dom_element.nav_item_title.editor = document.createElement("input"); title_edit.type = "text"; title_edit.style.display = "none"; - title_edit.style.padding = title_edit.style.margin = "0"; + title_edit.style.padding = "0"; title_edit.style.flexBasis = "0"; title_edit.style.flexGrow = "2"; title_edit.classList.add("nav-item-title"); From 514729894f7e6baedcb68e655cac7c9d67b4d169 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 12:22:01 -0300 Subject: [PATCH 3/9] disable keydown listeners while editing filename --- navigator/components/NavEntry.js | 1 + 1 file changed, 1 insertion(+) diff --git a/navigator/components/NavEntry.js b/navigator/components/NavEntry.js index ef20944..bd3fd03 100644 --- a/navigator/components/NavEntry.js +++ b/navigator/components/NavEntry.js @@ -53,6 +53,7 @@ export class NavEntry { let elem = e.target; elem.style.width = elem.value.length + "ch"; } + title_edit.addEventListener("keydown", (e) => {e.stopPropagation();}); title_edit.addEventListener("click", (e) => {e.stopPropagation();}); this.dom_element.appendChild(title_edit); this.stat = stat; From 649f6ec371173f22ffeb5308083dc57488945152 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 13:22:42 -0300 Subject: [PATCH 4/9] add info popup --- navigator/components/ModalPrompt.js | 2 +- navigator/navigator.html | 4 ++++ navigator/navigator.js | 12 ++++++++++++ navigator/version.js | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 navigator/version.js diff --git a/navigator/components/ModalPrompt.js b/navigator/components/ModalPrompt.js index 5f940d1..9c48988 100644 --- a/navigator/components/ModalPrompt.js +++ b/navigator/components/ModalPrompt.js @@ -96,7 +96,7 @@ export class ModalPrompt { */ set_body(message) { this.body.innerHTML = ""; - this.body.innerText = message; + this.body.innerHTML = message; } /** diff --git a/navigator/navigator.html b/navigator/navigator.html index 4d7a51d..9010aad 100644 --- a/navigator/navigator.html +++ b/navigator/navigator.html @@ -194,6 +194,10 @@ +
+ diff --git a/navigator/navigator.js b/navigator/navigator.js index 42e35dd..c6af453 100644 --- a/navigator/navigator.js +++ b/navigator/navigator.js @@ -17,7 +17,9 @@ along with Cockpit Navigator. If not, see . */ +import {ModalPrompt} from "./components/ModalPrompt.js"; import {NavWindow} from "./components/NavWindow.js"; +import {NAVIGATOR_VERSION} from "./version.js"; /** * @@ -139,6 +141,16 @@ function set_up_buttons() { e.target.selectionStart = e.target.selectionEnd = start + 1; } }); + document.getElementById("nav-info-btn").addEventListener("click", () => { + new ModalPrompt().alert( + `Cockpit Navigator v${NAVIGATOR_VERSION}`, + `

` + + `Created by 45Drives for Houston UI (Cockpit).
` + + `Issue Tracker
` + + `Feedback
` + + `

` + ); + }); } async function main() { diff --git a/navigator/version.js b/navigator/version.js new file mode 100644 index 0000000..efcce94 --- /dev/null +++ b/navigator/version.js @@ -0,0 +1 @@ +export let NAVIGATOR_VERSION = "0.5.3"; \ No newline at end of file From d367d69c6758d854a0021cfb694442484016f377 Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 13:32:24 -0300 Subject: [PATCH 5/9] implement automatic version string on packaging --- makefile | 6 ++++++ navigator/navigator.js | 2 +- navigator/version.js | 2 +- packaging/el7/main.spec | 4 ++-- packaging/el8/main.spec | 4 ++-- packaging/focal/rules | 2 ++ 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index cea61d6..c37978e 100644 --- a/makefile +++ b/makefile @@ -27,6 +27,9 @@ ifeq ($(DIST),$(EL7_DIST)) sed -i "s/pf-c-button/btn/g;s/pf-m-primary/btn-primary/g;s/pf-m-secondary/btn-default/g;s/pf-m-danger/btn-danger/g" $(DESTDIR)/usr/share/cockpit/navigator/navigator.html sed -i "s/pf-c-button/btn/g;s/pf-m-primary/btn-primary/g;s/pf-m-secondary/btn-default/g;s/pf-m-danger/btn-danger/g" $(DESTDIR)/usr/share/cockpit/navigator/components/ModalPrompt.js endif +ifneq ($(NAV_VERS),) + echo "export let NAVIGATOR_VERSION = \"$(NAV_VERS)\";" > $(DESTDIR)/usr/share/cockpit/navigator/version.js +endif uninstall: rm -rf $(DESTDIR)/usr/share/cockpit/navigator @@ -35,6 +38,9 @@ install-local: mkdir -p $(HOME)/.local/share/cockpit cp -rpf navigator $(HOME)/.local/share/cockpit find $(HOME)/.local/share/cockpit/navigator -name '*.js' -exec sed -i "s#\"/usr/share/\(cockpit/navigator/scripts/.*\)\"#\"$(HOME)/.local/share/\1\"#g" {} \; +ifneq ($(NAV_VERS),) + echo "export let NAVIGATOR_VERSION = \"$(NAV_VERS)\";" > $(HOME)/.local/share/cockpit/navigator/version.js +endif uninstall-local: rm -rf $(HOME)/.local/share/cockpit/navigator diff --git a/navigator/navigator.js b/navigator/navigator.js index c6af453..f920452 100644 --- a/navigator/navigator.js +++ b/navigator/navigator.js @@ -143,7 +143,7 @@ function set_up_buttons() { }); document.getElementById("nav-info-btn").addEventListener("click", () => { new ModalPrompt().alert( - `Cockpit Navigator v${NAVIGATOR_VERSION}`, + `Cockpit Navigator ${NAVIGATOR_VERSION}`, `

` + `Created by 45Drives for Houston UI (Cockpit).
` + `Issue Tracker
` + diff --git a/navigator/version.js b/navigator/version.js index efcce94..c30769d 100644 --- a/navigator/version.js +++ b/navigator/version.js @@ -1 +1 @@ -export let NAVIGATOR_VERSION = "0.5.3"; \ No newline at end of file +export let NAVIGATOR_VERSION = "built from source"; \ No newline at end of file diff --git a/packaging/el7/main.spec b/packaging/el7/main.spec index 82e65a8..2c25b14 100644 --- a/packaging/el7/main.spec +++ b/packaging/el7/main.spec @@ -23,7 +23,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root # empty %install -make DESTDIR=%{buildroot} DIST=%{dist} install +make DESTDIR=%{buildroot} DIST=%{dist} NAV_VERS="%{version}-%{release}" install %clean rm -rf %{buildroot} @@ -41,7 +41,7 @@ rm -rf %{buildroot} * Thu Jul 15 2021 Josh Boudreau 0.5.0-1 - Implement custom modal style popups to replace browser dialogs. * Wed Jul 07 2021 Josh Boudreau 0.4.6-3 -- Add relase for el7 +- Add release for el7 * Wed Jun 30 2021 Josh Boudreau 0.4.6-2 - First build with auto packaging * Fri Jun 18 2021 Josh Boudreau 0.4.6-1 diff --git a/packaging/el8/main.spec b/packaging/el8/main.spec index 82e65a8..2c25b14 100644 --- a/packaging/el8/main.spec +++ b/packaging/el8/main.spec @@ -23,7 +23,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root # empty %install -make DESTDIR=%{buildroot} DIST=%{dist} install +make DESTDIR=%{buildroot} DIST=%{dist} NAV_VERS="%{version}-%{release}" install %clean rm -rf %{buildroot} @@ -41,7 +41,7 @@ rm -rf %{buildroot} * Thu Jul 15 2021 Josh Boudreau 0.5.0-1 - Implement custom modal style popups to replace browser dialogs. * Wed Jul 07 2021 Josh Boudreau 0.4.6-3 -- Add relase for el7 +- Add release for el7 * Wed Jun 30 2021 Josh Boudreau 0.4.6-2 - First build with auto packaging * Fri Jun 18 2021 Josh Boudreau 0.4.6-1 diff --git a/packaging/focal/rules b/packaging/focal/rules index e73eae0..e310c6b 100755 --- a/packaging/focal/rules +++ b/packaging/focal/rules @@ -13,6 +13,8 @@ # package maintainers to append LDFLAGS #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed +export NAV_VERS := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ':') + %: dh $@ From 7e78ec95931abdf1a7a25fcddb1dfd446b9e8e0b Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Mon, 19 Jul 2021 13:50:05 -0300 Subject: [PATCH 6/9] fix pluralization in dir and file count --- navigator/components/NavWindow.js | 4 ++-- navigator/navigator.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/navigator/components/NavWindow.js b/navigator/components/NavWindow.js index c97afdb..5967f54 100644 --- a/navigator/components/NavWindow.js +++ b/navigator/components/NavWindow.js @@ -131,8 +131,8 @@ export class NavWindow { document.getElementById("pwd").value = this.pwd().path_str(); this.set_selected(this.pwd(), false, false); this.show_selected_properties(); - document.getElementById("nav-num-dirs").innerText = num_dirs.toString(); - document.getElementById("nav-num-files").innerText = num_files.toString(); + document.getElementById("nav-num-dirs").innerText = `${num_dirs} Director${(num_dirs === 1)? "y" : "ies"}`; + document.getElementById("nav-num-files").innerText = `${num_files} File${(num_files === 1)? "" : "s"}`; document.getElementById("nav-num-bytes").innerText = format_bytes(bytes_sum); this.stop_load(); this.set_nav_button_state(); diff --git a/navigator/navigator.html b/navigator/navigator.html index 9010aad..72df661 100644 --- a/navigator/navigator.html +++ b/navigator/navigator.html @@ -162,7 +162,7 @@