mirror of
https://github.com/directus/directus.git
synced 2026-02-19 10:14:33 -05:00
Reload image view when src is updated (#14646)
* Reload image view when src is updated * Regenerate random ID after saving to bust cache
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, onUnmounted, useAttrs } from 'vue';
|
||||
import { ref, computed, onMounted, onUnmounted, useAttrs, watch } from 'vue';
|
||||
import { omit } from 'lodash';
|
||||
import api from '@/api';
|
||||
|
||||
@@ -30,42 +30,53 @@ const observer = new IntersectionObserver(async (entries) => {
|
||||
inView.value = entries[0].isIntersecting;
|
||||
|
||||
if (entries[0].isIntersecting && !loaded && props.src) {
|
||||
try {
|
||||
const res = await api.get(props.src, {
|
||||
responseType: 'arraybuffer',
|
||||
params: {
|
||||
download: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.headers['content-type'].startsWith('image') === false) return;
|
||||
|
||||
const contentType = res.headers['content-type'];
|
||||
|
||||
const data = new Uint8Array(res.data);
|
||||
|
||||
// 5mb
|
||||
if (data.length > 1048576 * 5) {
|
||||
emit('error', new Error('Image too big to render'));
|
||||
return;
|
||||
}
|
||||
|
||||
let raw = '';
|
||||
|
||||
data.forEach((byte) => {
|
||||
raw += String.fromCharCode(byte);
|
||||
});
|
||||
|
||||
const base64 = btoa(raw);
|
||||
srcData.value = `data:${contentType};base64,${base64}`;
|
||||
} catch (err) {
|
||||
emit('error', err);
|
||||
} finally {
|
||||
loaded = true;
|
||||
}
|
||||
loadImage();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.src,
|
||||
() => {
|
||||
loadImage();
|
||||
}
|
||||
);
|
||||
|
||||
async function loadImage() {
|
||||
try {
|
||||
loaded = true;
|
||||
|
||||
const res = await api.get(props.src, {
|
||||
responseType: 'arraybuffer',
|
||||
params: {
|
||||
download: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.headers['content-type'].startsWith('image') === false) return;
|
||||
|
||||
const contentType = res.headers['content-type'];
|
||||
|
||||
const data = new Uint8Array(res.data);
|
||||
|
||||
// 5mb
|
||||
if (data.length > 1048576 * 5) {
|
||||
emit('error', new Error('Image too big to render'));
|
||||
return;
|
||||
}
|
||||
|
||||
let raw = '';
|
||||
|
||||
data.forEach((byte) => {
|
||||
raw += String.fromCharCode(byte);
|
||||
});
|
||||
|
||||
const base64 = btoa(raw);
|
||||
srcData.value = `data:${contentType};base64,${base64}`;
|
||||
} catch (err) {
|
||||
emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!imageElement.value) return;
|
||||
observer.observe(imageElement.value);
|
||||
|
||||
@@ -189,8 +189,10 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
const randomId = ref<string>(nanoid());
|
||||
|
||||
const imageURL = computed(() => {
|
||||
return addTokenToURL(`${getRootPath()}assets/${props.id}?${nanoid()}`);
|
||||
return addTokenToURL(`${getRootPath()}assets/${props.id}?${randomId.value}`);
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -273,6 +275,7 @@ export default defineComponent({
|
||||
await api.patch(`/files/${props.id}`, formData);
|
||||
emit('refresh');
|
||||
internalActive.value = false;
|
||||
randomId.value = nanoid();
|
||||
} catch (err: any) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user