|
1 | 1 | <template> |
2 | 2 | <div> |
3 | | - <div class="row" :class="{ clickable: canEdit(file) }" v-on:contextmenu="showContextMenu"> |
| 3 | + <div class="row" :class="{ clickable: canEdit(file), 'active-selection': contextMenuVisible }" v-on:contextmenu="showContextMenu"> |
4 | 4 | <div class="flex-none icon"> |
5 | 5 | <file-text-icon v-if="!file.symlink"/> |
6 | 6 | <link2-icon v-else/> |
|
10 | 10 | <div class="flex-1 text-right text-grey-dark">{{formatDate(file.modified)}}</div> |
11 | 11 | <div class="flex-none w-1/6"></div> |
12 | 12 | </div> |
13 | | - <div class="context-menu" v-show="contextMenuVisible" ref="contextMenu"> |
14 | | - <div> |
15 | | - <div class="context-row"> |
16 | | - <div class="icon"><edit3-icon/></div> |
17 | | - <div class="action"><span>Rename</span></div> |
18 | | - </div> |
19 | | - <div class="context-row"> |
20 | | - <div class="icon"><corner-up-left-icon class="h-4"/></div> |
21 | | - <div class="action"><span class="text-left">Move</span></div> |
22 | | - </div> |
23 | | - <div class="context-row"> |
24 | | - <div class="icon"><copy-icon class="h-4"/></div> |
25 | | - <div class="action">Copy</div> |
26 | | - </div> |
27 | | - </div> |
28 | | - <div> |
29 | | - <div class="context-row"> |
30 | | - <div class="icon"><file-plus-icon class="h-4"/></div> |
31 | | - <div class="action">New File</div> |
32 | | - </div> |
33 | | - <div class="context-row"> |
34 | | - <div class="icon"><folder-plus-icon class="h-4"/></div> |
35 | | - <div class="action">New Folder</div> |
36 | | - </div> |
37 | | - </div> |
38 | | - <div> |
39 | | - <div class="context-row"> |
40 | | - <div class="icon"><download-icon class="h-4"/></div> |
41 | | - <div class="action">Download</div> |
42 | | - </div> |
43 | | - <div class="context-row danger"> |
44 | | - <div class="icon"><delete-icon class="h-4"/></div> |
45 | | - <div class="action">Delete</div> |
46 | | - </div> |
47 | | - </div> |
48 | | - </div> |
| 13 | + <file-manager-context-menu class="context-menu" v-show="contextMenuVisible" ref="contextMenu"/> |
49 | 14 | </div> |
50 | 15 | </template> |
51 | 16 |
|
52 | 17 | <script> |
53 | | - import { CopyIcon, CornerUpLeftIcon, DeleteIcon, DownloadIcon, Edit3Icon, FileTextIcon, FilePlusIcon, FolderPlusIcon, Link2Icon } from 'vue-feather-icons'; |
54 | 18 | import * as Helpers from './../../../helpers/index'; |
| 19 | + import { FileTextIcon, Link2Icon } from 'vue-feather-icons'; |
| 20 | + import isObject from 'lodash/isObject'; |
| 21 | + import FileManagerContextMenu from './FileManagerContextMenu'; |
55 | 22 |
|
56 | 23 | export default { |
57 | 24 | name: 'file-manager-file-row', |
58 | 25 | components: { |
59 | | - CopyIcon, CornerUpLeftIcon, DeleteIcon, DownloadIcon, |
60 | | - Edit3Icon, FileTextIcon, FilePlusIcon, FolderPlusIcon, |
61 | | - Link2Icon, |
| 26 | + FileManagerContextMenu, |
| 27 | + FileTextIcon, Link2Icon |
62 | 28 | }, |
63 | 29 | props: { |
64 | 30 | file: {type: Object, required: true}, |
|
67 | 33 |
|
68 | 34 | data: function () { |
69 | 35 | return { |
70 | | - listener: null, |
71 | 36 | contextMenuVisible: false, |
72 | 37 | }; |
73 | 38 | }, |
74 | 39 |
|
75 | 40 | mounted: function () { |
76 | | - // Handle a click anywhere in the document and hide the context menu if that click is not |
77 | | - // a right click and isn't occurring somewhere in the currently visible context menu. |
78 | | - this.listener = document.addEventListener('click', (e) => { |
79 | | - if (e.button !== 2 |
80 | | - && this.contextMenuVisible |
81 | | - && e.target !== this.$refs.contextMenu |
82 | | - && !this.$refs.contextMenu.contains(e.target) |
83 | | - ) { |
84 | | - this.contextMenuVisible = false; |
85 | | - } |
86 | | - }); |
| 41 | + document.addEventListener('click', this._clickListener); |
87 | 42 |
|
88 | 43 | // If the parent component emits the collapse menu event check if the unique ID of the component |
89 | 44 | // is this one. If not, collapse the menu (we right clicked into another element). |
|
95 | 50 | }, |
96 | 51 |
|
97 | 52 | beforeDestroy: function () { |
98 | | - document.removeEventListener('click', this.listener); |
| 53 | + document.removeEventListener('click', this._clickListener, false); |
99 | 54 | }, |
100 | 55 |
|
101 | 56 | methods: { |
102 | 57 | /** |
103 | 58 | * Handle a right-click action on a file manager row. |
104 | 59 | * |
105 | | - * @param {Event} e |
| 60 | + * @param {MouseEvent} e |
106 | 61 | */ |
107 | 62 | showContextMenu: function (e) { |
108 | 63 | e.preventDefault(); |
109 | 64 | this.$parent.$emit('collapse-menus', this._uid); |
110 | | - this.contextMenuVisible = !this.contextMenuVisible; |
| 65 | +
|
| 66 | + this.contextMenuVisible = true; |
| 67 | +
|
| 68 | + const menuWidth = this.$refs.contextMenu.$el.offsetWidth; |
| 69 | + const positionElement = e.clientX - Math.round(menuWidth / 2); |
| 70 | + |
| 71 | + this.$refs.contextMenu.$el.style = `left: ${positionElement}; top: ${e.clientY}`; |
111 | 72 | }, |
112 | 73 |
|
113 | 74 | /** |
|
120 | 81 | return this.editable.indexOf(file.mime) >= 0; |
121 | 82 | }, |
122 | 83 |
|
| 84 | + /** |
| 85 | + * Handle a click anywhere in the document and hide the context menu if that click is not |
| 86 | + * a right click and isn't occurring somewhere in the currently visible context menu. |
| 87 | + * |
| 88 | + * @param {MouseEvent} e |
| 89 | + * @private |
| 90 | + */ |
| 91 | + _clickListener: function (e) { |
| 92 | + if (e.button !== 2 && this.contextMenuVisible) { |
| 93 | + if (e.target !== this.$refs.contextMenu.$el && !this.$refs.contextMenu.$el.contains(e.target)) { |
| 94 | + this.contextMenuVisible = false; |
| 95 | + } |
| 96 | + } |
| 97 | + }, |
| 98 | +
|
123 | 99 | readableSize: Helpers.readableSize, |
124 | 100 | formatDate: Helpers.formatDate, |
125 | 101 | } |
|
0 commit comments