@cloudron/pankow 4.1.9 → 4.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="grid-item-wrapper"
2
+ <div ref="rowWrapper" class="grid-item-wrapper"
3
3
  :draggable="!rename"
4
4
  @mouseup="onSelect($event)"
5
5
  @drop="onDrop($event)"
@@ -22,13 +22,16 @@
22
22
  </template>
23
23
  </div>
24
24
 
25
- <div v-if="visible && !rename" class="grid-item-label" :title="item.name + (item.target ? ` ${item.target}` : '')">
25
+ <!-- this is just a placeholder label to allow the native browser search to work -->
26
+ <div v-if="!visible">
27
+ {{ item.name }}
28
+ </div>
29
+ <div v-else-if="visible && !rename" class="grid-item-label" :title="item.name + (item.target ? ` → ${item.target}` : '')">
26
30
  <a v-if="item.href" class="open-action" @dblclick.stop @click="onOpen($event)" :href="item.href">{{ item.name }}</a>
27
31
  <span v-else>{{ item.name }}</span>
28
32
  </div>
29
- <div v-if="visible && rename" class="grid-item-label grid-item-rename">
33
+ <div v-else-if="visible && rename" ref="renameCell" class="grid-item-label grid-item-rename">
30
34
  <TextInput
31
- ref="renameInput"
32
35
  v-model="newName"
33
36
  :disabled="renameBusy"
34
37
  @blur="onRenameEnd"
@@ -42,167 +45,189 @@
42
45
  </div>
43
46
  </template>
44
47
 
45
- <script>
48
+ <script setup>
49
+
50
+ import { ref, onMounted } from 'vue';
46
51
 
47
52
  import Icon from './Icon.vue';
48
53
  import TextInput from './TextInput.vue';
49
54
 
50
- export default {
51
- name: 'DirectoryViewGridItem',
52
- emits: [ 'activated', 'action-menu' ],
53
- components: {
54
- Icon,
55
- TextInput
55
+ const props = defineProps({
56
+ item: Object,
57
+ showStar: {
58
+ type: Boolean,
59
+ default: false,
56
60
  },
57
- props: {
58
- item: Object,
59
- showStar: {
60
- type: Boolean,
61
- default: false
62
- },
63
- shareIndicatorProperty: {
64
- type: String,
65
- default: '',
66
- },
67
- fallbackIcon: String,
68
- renameHandler: {
69
- type: Function,
70
- default() {
71
- console.warn('Missing renameHandler for DirectoryViewGridItem');
72
- }
73
- },
74
- starHandler: {
75
- type: Function,
76
- default() {
77
- console.warn('Missing starHandler for DirectoryViewGridItem');
78
- }
79
- },
80
- selectHandler: {
81
- type: Function,
82
- default() {
83
- console.warn('Missing selectHandler for DirectoryViewGridItem');
84
- }
85
- },
86
- dropHandler: {
87
- type: Function,
88
- default() {
89
- console.warn('Missing dropHandler for DirectoryViewGridItem');
90
- }
91
- },
92
- canDropHandler: {
93
- type: Function,
94
- default() {
95
- console.warn('Missing canDropHandler for DirectoryViewGridItem');
96
- }
97
- }
98
- },
99
- data() {
100
- return {
101
- visible: false,
102
- rename: false,
103
- renameBusy: false,
104
- newName: '',
105
- dropTargetActive: false,
106
- previewRetries: 0
107
- };
61
+ shareIndicatorProperty: {
62
+ type: String,
63
+ default: '',
108
64
  },
109
- methods: {
110
- highlight() {
111
- this.$el.classList.add('pankow-directory-view-highlight-animation');
112
- setTimeout(() => { this.$el.classList.remove('pankow-directory-view-highlight-animation'); }, 4000);
65
+ fallbackIcon: String,
66
+ renameHandler: {
67
+ type: Function,
68
+ default() {
69
+ console.warn('Missing renameHandler for DirectoryViewGridItem');
113
70
  },
114
- onToggleStar() {
115
- this.starHandler(this.item);
71
+ },
72
+ starHandler: {
73
+ type: Function,
74
+ default() {
75
+ console.warn('Missing starHandler for DirectoryViewGridItem');
116
76
  },
117
- onActionMenu(event) {
118
- this.onSelect(event, true);
119
- this.$emit('action-menu', this.item, event);
77
+ },
78
+ selectHandler: {
79
+ type: Function,
80
+ default() {
81
+ console.warn('Missing selectHandler for DirectoryViewGridItem');
120
82
  },
121
- onRenameBegin() {
122
- this.rename = true;
123
- this.newName = this.item.name;
124
-
125
- setTimeout(() => {
126
- const elem = this.$refs.renameInput.$el;
127
- elem.focus();
128
-
129
- if (typeof elem.selectionStart !== 'undefined') {
130
- elem.selectionStart = 0;
131
- elem.selectionEnd = this.item.name.lastIndexOf('.');
132
- }
133
- }, 0);
83
+ },
84
+ dropHandler: {
85
+ type: Function,
86
+ default() {
87
+ console.warn('Missing dropHandler for DirectoryViewGridItem');
134
88
  },
135
- onRenameEnd() {
136
- this.rename = false;
137
- this.renameBusy = false;
138
- this.newName = '';
89
+ },
90
+ canDropHandler: {
91
+ type: Function,
92
+ default() {
93
+ console.warn('Missing canDropHandler for DirectoryViewGridItem');
139
94
  },
140
- async onRenameSubmit() {
141
- if (!this.newName) return;
95
+ },
96
+ });
142
97
 
143
- this.renameBusy = true;
144
- await this.renameHandler(this.item, this.newName);
145
- this.onRenameEnd();
146
- },
147
- onOpen(event) {
148
- if (event.ctrlKey || event.metaKey) return;
98
+ const emit = defineEmits(['activated', 'action-menu']);
149
99
 
150
- event.preventDefault();
151
- event.stopPropagation();
100
+ const rowWrapper = ref(null);
101
+ const renameCell = ref(null);
152
102
 
153
- this.$emit('activated', this.item);
154
- },
155
- onSelect(event, actionMenu = false) {
156
- if ((event.button === 2 || actionMenu) && event.ctrlKey) {
157
- this.selectHandler(this.item, event, true);
158
- } else {
159
- this.selectHandler(this.item, event);
160
- }
161
- },
162
- onDrop(event) {
163
- if (!this.canDropHandler(this.item)) return;
103
+ const visible = ref(false);
104
+ const rename = ref(false);
105
+ const renameBusy = ref(false);
106
+ const newName = ref('');
107
+ const dropTargetActive = ref(false);
108
+ const previewRetries = ref(0);
164
109
 
165
- event.stopPropagation();
110
+ function highlight() {
111
+ rowWrapper.value?.classList.add('pankow-directory-view-highlight-animation');
112
+ setTimeout(() => {
113
+ rowWrapper.value?.classList.remove('pankow-directory-view-highlight-animation');
114
+ }, 4000);
115
+ }
166
116
 
167
- this.dropHandler(this.item, event);
168
- this.dropTargetActive = false;
169
- },
170
- onDragOver(event) {
171
- if (!this.canDropHandler(this.item)) return;
117
+ function onToggleStar() {
118
+ props.starHandler(props.item);
119
+ }
172
120
 
173
- event.preventDefault();
174
- event.stopPropagation();
121
+ function onActionMenu(event) {
122
+ onSelect(event, true);
123
+ emit('action-menu', props.item, event);
124
+ }
175
125
 
176
- event.dataTransfer.dropEffect = 'move';
177
- this.dropTargetActive = true;
178
- },
179
- onDragExit(event) {
180
- if (!this.item.isDirectory) return;
126
+ function onRenameBegin() {
127
+ rename.value = true;
128
+ newName.value = props.item.name;
181
129
 
182
- this.dropTargetActive = false;
183
- },
184
- iconError(event) {
185
- event.target.src = this.fallbackIcon;
130
+ setTimeout(() => {
131
+ const elem = renameCell.value?.querySelector('input.pankow-text-input');
132
+ if (!elem) return;
186
133
 
187
- setTimeout(() => {
188
- if (this.previewRetries > 5) return;
189
- ++this.previewRetries;
134
+ elem.focus();
190
135
 
191
- event.target.src = this.item.previewUrl || this.item.icon;
192
- }, 1000);
136
+ if (typeof elem.selectionStart !== 'undefined') {
137
+ elem.selectionStart = 0;
138
+ elem.selectionEnd = props.item.name.lastIndexOf('.');
193
139
  }
194
- },
195
- mounted() {
196
- const observer = new IntersectionObserver(result => {
197
- if (result[0].isIntersecting) {
198
- this.visible = true;
199
- observer.unobserve(this.$el);
200
- }
201
- });
202
-
203
- observer.observe(this.$el);
140
+ }, 0);
141
+ }
142
+
143
+ function onRenameEnd() {
144
+ rename.value = false;
145
+ renameBusy.value = false;
146
+ newName.value = '';
147
+ }
148
+
149
+ async function onRenameSubmit() {
150
+ if (!newName.value) return;
151
+
152
+ renameBusy.value = true;
153
+ await props.renameHandler(props.item, newName.value);
154
+ onRenameEnd();
155
+ }
156
+
157
+ function onOpen(event) {
158
+ if (event.ctrlKey || event.metaKey) return;
159
+
160
+ event.preventDefault();
161
+ event.stopPropagation();
162
+
163
+ emit('activated', props.item);
164
+ }
165
+
166
+ function onSelect(event, actionMenu = false) {
167
+ if ((event.button === 2 || actionMenu) && event.ctrlKey) {
168
+ props.selectHandler(props.item, event, true);
169
+ } else {
170
+ props.selectHandler(props.item, event);
204
171
  }
205
- };
172
+ }
173
+
174
+ function onDrop(event) {
175
+ if (!props.canDropHandler(props.item)) return;
176
+
177
+ event.stopPropagation();
178
+
179
+ props.dropHandler(props.item, event);
180
+ dropTargetActive.value = false;
181
+ }
182
+
183
+ function onDragOver(event) {
184
+ if (!props.canDropHandler(props.item)) return;
185
+
186
+ event.preventDefault();
187
+ event.stopPropagation();
188
+
189
+ event.dataTransfer.dropEffect = 'move';
190
+ dropTargetActive.value = true;
191
+ }
192
+
193
+ function onDragExit() {
194
+ if (!props.item.isDirectory) return;
195
+
196
+ dropTargetActive.value = false;
197
+ }
198
+
199
+ function iconError(event) {
200
+ event.target.src = props.fallbackIcon;
201
+
202
+ setTimeout(() => {
203
+ if (previewRetries.value > 5) return;
204
+ previewRetries.value += 1;
205
+
206
+ event.target.src = props.item.previewUrl || props.item.icon;
207
+ }, 1000);
208
+ }
209
+
210
+ onMounted(() => {
211
+ const el = rowWrapper.value;
212
+ if (!el) return;
213
+
214
+ const observer = new IntersectionObserver((result) => {
215
+ if (result[0].isIntersecting) {
216
+ visible.value = true;
217
+ observer.unobserve(el);
218
+ }
219
+ });
220
+
221
+ observer.observe(el);
222
+ });
223
+
224
+ defineExpose({
225
+ highlight,
226
+ onRenameBegin,
227
+ get $el() {
228
+ return rowWrapper.value;
229
+ },
230
+ });
206
231
 
207
232
  </script>
208
233