quasar-ui-danx 0.4.52 → 0.4.54
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/dist/danx.es.js +4353 -4286
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +70 -70
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +34 -3
- package/src/components/Utility/Files/FilePreview.vue +13 -6
- package/src/helpers/objectStore.ts +52 -3
package/package.json
CHANGED
@@ -41,6 +41,14 @@
|
|
41
41
|
:alt="file.filename"
|
42
42
|
:src="getPreviewUrl(file)"
|
43
43
|
>
|
44
|
+
<div
|
45
|
+
v-else-if="isText(file)"
|
46
|
+
class="w-[60vw] min-w-96 bg-slate-800 rounded-lg"
|
47
|
+
>
|
48
|
+
<div class="whitespace-pre-wrap p-4">
|
49
|
+
{{ fileTexts[file.id] }}
|
50
|
+
</div>
|
51
|
+
</div>
|
44
52
|
<div v-else>
|
45
53
|
<h3 class="text-center mb-4">
|
46
54
|
No Preview Available
|
@@ -71,8 +79,9 @@
|
|
71
79
|
</div>
|
72
80
|
</QDialog>
|
73
81
|
</template>
|
74
|
-
<script setup>
|
75
|
-
import {
|
82
|
+
<script setup lang="ts">
|
83
|
+
import { QCarousel } from "quasar";
|
84
|
+
import { onMounted, ref, shallowRef } from "vue";
|
76
85
|
import { XIcon as CloseIcon } from "../../../svg";
|
77
86
|
|
78
87
|
defineEmits(["close"]);
|
@@ -97,6 +106,10 @@ function isImage(file) {
|
|
97
106
|
return file.mime?.startsWith("image");
|
98
107
|
}
|
99
108
|
|
109
|
+
function isText(file) {
|
110
|
+
return file.mime?.startsWith("text");
|
111
|
+
}
|
112
|
+
|
100
113
|
function getPreviewUrl(file) {
|
101
114
|
// Use the optimized URL first if available. If not, use the URL directly if its an image, otherwise use the thumb URL
|
102
115
|
return file.optimized?.url || (isImage(file) ? (file.blobUrl || file.url) : file.thumb?.url);
|
@@ -111,8 +124,26 @@ function getThumbUrl(file) {
|
|
111
124
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><path d="M0 0h24v24H0z" fill="none"/><path d="M8 5v14l11-7z"/></svg>`
|
112
125
|
)}`;
|
113
126
|
} else {
|
114
|
-
return getPreviewUrl(file);
|
127
|
+
return getPreviewUrl(file) || "https://placehold.co/40x50?text=T";
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
onMounted(() => {
|
132
|
+
for (let file of props.files) {
|
133
|
+
if (isText(file)) {
|
134
|
+
loadFileText(file);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
});
|
138
|
+
|
139
|
+
const fileTexts = shallowRef<{ [key: string]: string }>({});
|
140
|
+
|
141
|
+
async function loadFileText(file) {
|
142
|
+
if (fileTexts.value[file.id]) {
|
143
|
+
return fileTexts.value[file.id];
|
115
144
|
}
|
145
|
+
|
146
|
+
fileTexts.value[file.id] = await fetch(file.url).then((res) => res.text());
|
116
147
|
}
|
117
148
|
</script>
|
118
149
|
<style module="cls" lang="scss">
|
@@ -69,7 +69,8 @@
|
|
69
69
|
class="absolute-bottom w-full bg-slate-800"
|
70
70
|
>
|
71
71
|
<QLinearProgress
|
72
|
-
:
|
72
|
+
:key="'progress-' + isUploading ? 'uploading' : 'transcoding'"
|
73
|
+
:value="isUploading ? file.progress : ((transcodingStatus?.progress || 0) / 100)"
|
73
74
|
size="36px"
|
74
75
|
:color="isUploading ? 'green-800' : 'blue-800'"
|
75
76
|
:animation-speed="transcodingStatus?.estimate_ms || 3000"
|
@@ -77,12 +78,17 @@
|
|
77
78
|
>
|
78
79
|
<div class="absolute-full flex items-center flex-nowrap text-[.7rem] text-slate-200 justify-start px-1">
|
79
80
|
<QSpinnerPie
|
80
|
-
class="mr-2 text-slate-50 ml-1"
|
81
|
-
size="20"
|
81
|
+
class="mr-2 text-slate-50 ml-1 flex-shrink-0"
|
82
|
+
:size="btnSize === 'xs' ? 10 : 20"
|
82
83
|
/>
|
83
|
-
<
|
84
|
-
|
85
|
-
|
84
|
+
<template v-if="statusMessage">
|
85
|
+
<div class="whitespace-nowrap overflow-hidden ellipsis">
|
86
|
+
{{ statusMessage }}
|
87
|
+
</div>
|
88
|
+
<QTooltip class="text-sm">
|
89
|
+
{{ statusMessage }}
|
90
|
+
</QTooltip>
|
91
|
+
</template>
|
86
92
|
</div>
|
87
93
|
</QLinearProgress>
|
88
94
|
</div>
|
@@ -202,6 +208,7 @@ const computedImage: ComputedRef<UploadedFile | null> = computed(() => {
|
|
202
208
|
});
|
203
209
|
|
204
210
|
const isUploading = computed(() => !props.file || props.file?.progress !== undefined);
|
211
|
+
const statusMessage = computed(() => isUploading.value ? "Uploading..." : transcodingStatus.value?.message);
|
205
212
|
const previewableFiles: ComputedRef<(UploadedFile | null)[] | null> = computed(() => {
|
206
213
|
return props.relatedFiles?.length > 0 ? uniqueBy([computedImage.value, ...props.relatedFiles], filesHaveSameUrl) : [computedImage.value];
|
207
214
|
});
|
@@ -44,10 +44,10 @@ export function storeObject<T extends TypedObject>(newObject: T, recentlyStoredO
|
|
44
44
|
// Retrieve the existing object if it already exists in the store
|
45
45
|
const oldObject = store.get(objectKey);
|
46
46
|
|
47
|
-
// If an old object exists, and it is newer than the new object, do not store the new object,
|
47
|
+
// If an old object exists, and it is newer than the new object, and all the child objects are not newer than the original do not store the new object,
|
48
|
+
// just return the old
|
48
49
|
// NOTE: If the timestamp is the same, its possible the intention is to update the existing object, so DO NOT return old object in this case
|
49
|
-
|
50
|
-
if (oldObject && newObject.__timestamp < oldObject.__timestamp) {
|
50
|
+
if (!hasRecentUpdates(newObject, oldObject)) {
|
51
51
|
recentlyStoredObjects[objectKey] = oldObject;
|
52
52
|
|
53
53
|
// Recursively store all the children of the object as well
|
@@ -105,6 +105,55 @@ function storeObjectChildren<T extends TypedObject>(object: T, recentlyStoredObj
|
|
105
105
|
}
|
106
106
|
}
|
107
107
|
|
108
|
+
/**
|
109
|
+
* Recursively check the current object and all its child objects
|
110
|
+
* to see if any of the objects are newer than the currently stored objects
|
111
|
+
*/
|
112
|
+
function hasRecentUpdates(newObject: TypedObject, oldObject: TypedObject | null) {
|
113
|
+
// If there are no timestamps to compare, assume there are updates
|
114
|
+
if (!newObject.__timestamp || !oldObject?.__timestamp) return true;
|
115
|
+
|
116
|
+
// If the new object has a newer timestamp than the old then there are updates
|
117
|
+
if (newObject.__timestamp > oldObject.__timestamp) return true;
|
118
|
+
|
119
|
+
for (const key of Object.keys(newObject)) {
|
120
|
+
const newObjectValue = newObject[key];
|
121
|
+
const oldObjectValue = oldObject[key];
|
122
|
+
|
123
|
+
// If the old object does not have this key, this is new information, therefore there are updates
|
124
|
+
if (!oldObjectValue?.__timestamp) {
|
125
|
+
return true;
|
126
|
+
}
|
127
|
+
|
128
|
+
if (Array.isArray(newObjectValue) && newObjectValue.length > 0) {
|
129
|
+
for (const newObjectItem of newObjectValue as TypedObject[]) {
|
130
|
+
// Only compare the object if it is a TypedObject
|
131
|
+
if (newObjectItem?.__type) {
|
132
|
+
const oldObjectItem = (oldObjectValue as TypedObject[]).find((v: TypedObject) => v.id === newObjectItem.id && v.__type === newObjectItem.__type);
|
133
|
+
|
134
|
+
// If the oldObject does not have this entry, then there is new information, therefore there are updates
|
135
|
+
if (!oldObjectItem?.__timestamp) {
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
|
139
|
+
// Compare the child objects to see if there are updates
|
140
|
+
if (hasRecentUpdates(newObjectItem, oldObjectItem)) {
|
141
|
+
return true;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
} else if (newObjectValue?.__type) {
|
146
|
+
// Only compare the object if it is a TypedObject
|
147
|
+
if (hasRecentUpdates(newObjectValue, oldObjectValue)) {
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
// If no updates were found, return false
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
|
108
157
|
/**
|
109
158
|
* Remove an object from all lists in the store
|
110
159
|
*/
|