From e1b630ae14b39b876a2e3a8d5241c06413b8da96 Mon Sep 17 00:00:00 2001 From: Omar Hussein Date: Mon, 1 Jul 2024 02:48:05 -0400 Subject: [PATCH 1/3] fix:migrate context menu to vue3 --- frontend/src/components/ContextMenu.vue | 54 +++++++ frontend/src/components/files/ListingItem.vue | 21 +++ frontend/src/css/context-menu.css | 16 ++ frontend/src/css/styles.css | 3 +- frontend/src/views/files/FileListing.vue | 138 +++++++++++++----- 5 files changed, 195 insertions(+), 37 deletions(-) create mode 100644 frontend/src/components/ContextMenu.vue create mode 100644 frontend/src/css/context-menu.css diff --git a/frontend/src/components/ContextMenu.vue b/frontend/src/components/ContextMenu.vue new file mode 100644 index 00000000..b709df08 --- /dev/null +++ b/frontend/src/components/ContextMenu.vue @@ -0,0 +1,54 @@ + + + diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 75326f4c..362c940c 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -8,6 +8,7 @@ @dragover="dragOver" @drop="drop" @click="itemClick" + @contextmenu="contextMenu" :data-dir="isDir" :data-type="type" :aria-label="name" @@ -220,6 +221,26 @@ const itemClick = (event: Event | KeyboardEvent) => { else click(event); }; +const contextMenu = (event: MouseEvent) => { + const to = setTimeout(() => { + touches.value = 0; + }, 300); + + touches.value++; + if (touches.value > 1) return; + + event.preventDefault(); + if ( + fileStore.selected.length < 2 || + event.ctrlKey || + fileStore.selected.indexOf(props.index) === -1 + ) { + touches.value--; + clearTimeout(to); + click(event); + } +}; + const click = (event: Event | KeyboardEvent) => { if (!singleClick.value && fileStore.selectedCount !== 0) event.preventDefault(); diff --git a/frontend/src/css/context-menu.css b/frontend/src/css/context-menu.css new file mode 100644 index 00000000..825643f6 --- /dev/null +++ b/frontend/src/css/context-menu.css @@ -0,0 +1,16 @@ +.context-menu { + position: fixed; + background: var(--surfacePrimary); + min-width: 180px; + border: 1px solid var(--borderSecondary); + box-shadow: 0 2px 4px var(--borderPrimary); + z-index: 1000; +} + +.context-menu .action { + display: block; + width: 100%; + border-radius: 0; + display: flex; + align-items: center; +} \ No newline at end of file diff --git a/frontend/src/css/styles.css b/frontend/src/css/styles.css index 19b94b95..024b4886 100644 --- a/frontend/src/css/styles.css +++ b/frontend/src/css/styles.css @@ -17,6 +17,7 @@ @import "./mobile.css"; @import "./epubReader.css"; @import "./mdPreview.css"; +@import "./context-menu.css"; /* For testing only :focus { @@ -456,4 +457,4 @@ html[dir="rtl"] .card-content .small + input { html[dir="rtl"] .card.floating .card-content .file-list { direction: ltr; text-align: left; -} +} \ No newline at end of file diff --git a/frontend/src/views/files/FileListing.vue b/frontend/src/views/files/FileListing.vue index 8fa48f72..3cda761c 100644 --- a/frontend/src/views/files/FileListing.vue +++ b/frontend/src/views/files/FileListing.vue @@ -205,41 +205,92 @@ -

- {{ t("files.folders") }} -

-
- - -
+ +

+ {{ t("files.folders") }} +

+
+ + +
-

{{ t("files.files") }}

-
- + {{ t("files.files") }} + +
+ + +
+ -
-
+ + + + + + + + +
(280); const dragCounter = ref(0); const width = ref(window.innerWidth); const itemWeight = ref(0); +const isContextMenuVisible = ref(false); +const contextMenuPos = ref<{ x: number; y: number }>({ x: 0, y: 0 }); const $showError = inject("$showError")!; @@ -444,7 +498,7 @@ watch(req, () => { onMounted(() => { // Check the columns size for the first time. - colunmsResize(); + columnsResize(); // How much every listing item affects the window height setItemWeight(); @@ -638,7 +692,7 @@ const paste = (event: Event) => { action(overwrite, rename); }; -const colunmsResize = () => { +const columnsResize = () => { // Update the columns size based on the window width. const items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]); if (items_ === null) return; @@ -841,7 +895,7 @@ const toggleMultipleSelection = () => { }; const windowsResize = throttle(() => { - colunmsResize(); + columnsResize(); width.value = window.innerWidth; // Listing element is not displayed @@ -951,4 +1005,16 @@ const fillWindow = (fit = false) => { // Set the number of displayed items showLimit.value = showQuantity > totalItems ? totalItems : showQuantity; }; + +const showContextMenu = (event: MouseEvent) => { + isContextMenuVisible.value = true; + contextMenuPos.value = { + x: event.clientX, + y: event.clientY, + }; +}; + +const hideContextMenu = () => { + isContextMenuVisible.value = false; +}; From 3f21a64b4f3a6ed6bacebdddece0d015be004604 Mon Sep 17 00:00:00 2001 From: Omar Hussein Date: Mon, 1 Jul 2024 02:50:51 -0400 Subject: [PATCH 2/3] fix: move prompt not displaying move messege --- frontend/src/components/prompts/Move.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/prompts/Move.vue b/frontend/src/components/prompts/Move.vue index 6591d09d..0cb0d599 100644 --- a/frontend/src/components/prompts/Move.vue +++ b/frontend/src/components/prompts/Move.vue @@ -5,6 +5,7 @@
+

{{ $t("prompts.moveMessage") }}

Date: Thu, 27 Feb 2025 00:41:33 -0500 Subject: [PATCH 3/3] fix: update menu to match requirements --- frontend/src/components/ContextMenu.vue | 9 +- frontend/src/components/files/ListingItem.vue | 11 +- frontend/src/css/context-menu.css | 5 +- frontend/src/views/files/FileListing.vue | 179 +++++++++--------- 4 files changed, 97 insertions(+), 107 deletions(-) diff --git a/frontend/src/components/ContextMenu.vue b/frontend/src/components/ContextMenu.vue index b709df08..14663fd9 100644 --- a/frontend/src/components/ContextMenu.vue +++ b/frontend/src/components/ContextMenu.vue @@ -4,7 +4,7 @@ ref="contextMenu" v-show="show" :style="{ - top: `${top}px`, + top: `${props.pos.y}px`, left: `${left}px`, }" > @@ -19,13 +19,6 @@ const emit = defineEmits(["hide"]); const props = defineProps<{ show: boolean; pos: { x: number; y: number } }>(); const contextMenu = ref(null); -const top = computed(() => { - return Math.min( - props.pos.y, - window.innerHeight - (contextMenu.value?.clientHeight ?? 0) - ); -}); - const left = computed(() => { return Math.min( props.pos.x, diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 362c940c..932bc4b1 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -222,21 +222,12 @@ const itemClick = (event: Event | KeyboardEvent) => { }; const contextMenu = (event: MouseEvent) => { - const to = setTimeout(() => { - touches.value = 0; - }, 300); - - touches.value++; - if (touches.value > 1) return; - event.preventDefault(); if ( - fileStore.selected.length < 2 || + fileStore.selected.length === 0 || event.ctrlKey || fileStore.selected.indexOf(props.index) === -1 ) { - touches.value--; - clearTimeout(to); click(event); } }; diff --git a/frontend/src/css/context-menu.css b/frontend/src/css/context-menu.css index 825643f6..cd791364 100644 --- a/frontend/src/css/context-menu.css +++ b/frontend/src/css/context-menu.css @@ -1,10 +1,11 @@ .context-menu { - position: fixed; + position: absolute; background: var(--surfacePrimary); min-width: 180px; + max-width: 220px; border: 1px solid var(--borderSecondary); box-shadow: 0 2px 4px var(--borderPrimary); - z-index: 1000; + z-index: 999; } .context-menu .action { diff --git a/frontend/src/views/files/FileListing.vue b/frontend/src/views/files/FileListing.vue index 3cda761c..e5e929e3 100644 --- a/frontend/src/views/files/FileListing.vue +++ b/frontend/src/views/files/FileListing.vue @@ -205,92 +205,96 @@
- -

- {{ t("files.folders") }} -

-
- - -
- -

- {{ t("files.files") }} -

-
- - -
- + {{ t("files.folders") }} + +
+ - - - - - - - - - + +
+ +

+ {{ t("files.files") }} +

+
+ + +
+ + + + + + + + + { }; const showContextMenu = (event: MouseEvent) => { + event.preventDefault(); isContextMenuVisible.value = true; contextMenuPos.value = { - x: event.clientX, - y: event.clientY, + x: event.clientX + 8, + y: event.clientY + Math.floor(window.scrollY), }; };