Improve link preview loading

This commit is contained in:
Pavel Djundik 2019-11-25 21:37:51 +02:00
parent c70d0fb224
commit c2ed3fae56
2 changed files with 43 additions and 13 deletions

View File

@ -1,5 +1,11 @@
<template> <template>
<div v-if="link.shown" v-show="link.canDisplay" ref="container" class="preview" dir="ltr"> <div
v-if="link.shown"
v-show="link.sourceLoaded || link.type === 'link'"
ref="container"
class="preview"
dir="ltr"
>
<div <div
ref="content" ref="content"
:class="['toggle-content', 'toggle-type-' + link.type, {opened: isContentShown}]" :class="['toggle-content', 'toggle-type-' + link.type, {opened: isContentShown}]"
@ -7,6 +13,7 @@
<template v-if="link.type === 'link'"> <template v-if="link.type === 'link'">
<a <a
v-if="link.thumb" v-if="link.thumb"
v-show="link.sourceLoaded"
:href="link.link" :href="link.link"
class="toggle-thumbnail" class="toggle-thumbnail"
target="_blank" target="_blank"
@ -62,16 +69,32 @@
rel="noopener" rel="noopener"
@click="onThumbnailClick" @click="onThumbnailClick"
> >
<img :src="link.thumb" decoding="async" alt="" @load="onPreviewReady" /> <img
v-show="link.sourceLoaded"
:src="link.thumb"
decoding="async"
alt=""
@load="onPreviewReady"
/>
</a> </a>
</template> </template>
<template v-else-if="link.type === 'video'"> <template v-else-if="link.type === 'video'">
<video preload="metadata" controls @canplay="onPreviewReady"> <video
v-show="link.sourceLoaded"
preload="metadata"
controls
@canplay="onPreviewReady"
>
<source :src="link.media" :type="link.mediaType" /> <source :src="link.media" :type="link.mediaType" />
</video> </video>
</template> </template>
<template v-else-if="link.type === 'audio'"> <template v-else-if="link.type === 'audio'">
<audio controls preload="metadata" @canplay="onPreviewReady"> <audio
v-show="link.sourceLoaded"
controls
preload="metadata"
@canplay="onPreviewReady"
>
<source :src="link.media" :type="link.mediaType" /> <source :src="link.media" :type="link.mediaType" />
</audio> </audio>
</template> </template>
@ -126,6 +149,10 @@ export default {
return this.isContentShown ? "Less" : "More"; return this.isContentShown ? "Less" : "More";
}, },
imageMaxSize() { imageMaxSize() {
if (!this.link.maxSize) {
return;
}
return friendlysize(this.link.maxSize); return friendlysize(this.link.maxSize);
}, },
}, },
@ -149,7 +176,7 @@ export default {
destroyed() { destroyed() {
// Let this preview go through load/canplay events again, // Let this preview go through load/canplay events again,
// Otherwise the browser can cause a resize on video elements // Otherwise the browser can cause a resize on video elements
this.link.canDisplay = false; this.link.sourceLoaded = false;
}, },
methods: { methods: {
onPreviewUpdate() { onPreviewUpdate() {
@ -158,26 +185,25 @@ export default {
return; return;
} }
// Error don't have any media to render // Error does not have any media to render
if (this.link.type === "error") { if (this.link.type === "error") {
this.onPreviewReady(); this.onPreviewReady();
} }
// If link doesn't have a thumbnail, render it // If link doesn't have a thumbnail, render it
if (this.link.type === "link" && !this.link.thumb) { if (this.link.type === "link") {
this.onPreviewReady(); this.handleResize();
this.keepScrollPosition();
} }
}, },
onPreviewReady() { onPreviewReady() {
this.$set(this.link, "canDisplay", true); this.$set(this.link, "sourceLoaded", true);
this.keepScrollPosition(); this.keepScrollPosition();
if (this.link.type !== "link") { if (this.link.type === "link") {
return; this.handleResize();
} }
this.handleResize();
}, },
onThumbnailError() { onThumbnailError() {
// If thumbnail fails to load, hide it and show the preview without it // If thumbnail fails to load, hide it and show the preview without it

View File

@ -1467,6 +1467,10 @@ background on hover (unless active) */
transform: rotate(90deg); transform: rotate(90deg);
} }
#chat .preview {
display: flex; /* Fix odd margin added by inline-flex in .toggle-content */
}
#chat .toggle-content { #chat .toggle-content {
background: #f6f6f6; background: #f6f6f6;
border-radius: 5px; border-radius: 5px;