@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.
- package/components/DirectoryView.vue +742 -624
- package/components/DirectoryViewGridItem.vue +167 -142
- package/components/DirectoryViewListItem.vue +178 -159
- package/components/FileUploader.vue +161 -150
- package/package.json +2 -2
|
@@ -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
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
TextInput
|
|
55
|
+
const props = defineProps({
|
|
56
|
+
item: Object,
|
|
57
|
+
showStar: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: false,
|
|
56
60
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
65
|
+
fallbackIcon: String,
|
|
66
|
+
renameHandler: {
|
|
67
|
+
type: Function,
|
|
68
|
+
default() {
|
|
69
|
+
console.warn('Missing renameHandler for DirectoryViewGridItem');
|
|
113
70
|
},
|
|
114
|
-
|
|
115
|
-
|
|
71
|
+
},
|
|
72
|
+
starHandler: {
|
|
73
|
+
type: Function,
|
|
74
|
+
default() {
|
|
75
|
+
console.warn('Missing starHandler for DirectoryViewGridItem');
|
|
116
76
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
77
|
+
},
|
|
78
|
+
selectHandler: {
|
|
79
|
+
type: Function,
|
|
80
|
+
default() {
|
|
81
|
+
console.warn('Missing selectHandler for DirectoryViewGridItem');
|
|
120
82
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
89
|
+
},
|
|
90
|
+
canDropHandler: {
|
|
91
|
+
type: Function,
|
|
92
|
+
default() {
|
|
93
|
+
console.warn('Missing canDropHandler for DirectoryViewGridItem');
|
|
139
94
|
},
|
|
140
|
-
|
|
141
|
-
|
|
95
|
+
},
|
|
96
|
+
});
|
|
142
97
|
|
|
143
|
-
|
|
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
|
-
|
|
151
|
-
|
|
100
|
+
const rowWrapper = ref(null);
|
|
101
|
+
const renameCell = ref(null);
|
|
152
102
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
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
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
onDragOver(event) {
|
|
171
|
-
if (!this.canDropHandler(this.item)) return;
|
|
117
|
+
function onToggleStar() {
|
|
118
|
+
props.starHandler(props.item);
|
|
119
|
+
}
|
|
172
120
|
|
|
173
|
-
|
|
174
|
-
|
|
121
|
+
function onActionMenu(event) {
|
|
122
|
+
onSelect(event, true);
|
|
123
|
+
emit('action-menu', props.item, event);
|
|
124
|
+
}
|
|
175
125
|
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
188
|
-
if (this.previewRetries > 5) return;
|
|
189
|
-
++this.previewRetries;
|
|
134
|
+
elem.focus();
|
|
190
135
|
|
|
191
|
-
|
|
192
|
-
|
|
136
|
+
if (typeof elem.selectionStart !== 'undefined') {
|
|
137
|
+
elem.selectionStart = 0;
|
|
138
|
+
elem.selectionEnd = props.item.name.lastIndexOf('.');
|
|
193
139
|
}
|
|
194
|
-
},
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
|