1515 </template >
1616
1717 <!-- Decorative images, should not be aria documented -->
18- <span v-else-if =" previewUrl " class =" files-list__row-icon-preview-container" >
18+ <span v-else-if =" background " class =" files-list__row-icon-preview-container" >
1919 <canvas v-if =" hasBlurhash && (backgroundFailed === true || !backgroundLoaded)"
2020 ref =" canvas"
2121 class =" files-list__row-icon-blurhash"
2626 class =" files-list__row-icon-preview"
2727 :class =" {'files-list__row-icon-preview--loaded': backgroundFailed === false}"
2828 loading =" lazy"
29- :src =" previewUrl"
30- @error =" onBackgroundError"
29+ :src =" background"
3130 @load =" onBackgroundLoad" >
3231 </span >
3332
@@ -121,6 +120,7 @@ export default defineComponent({
121120
122121 data() {
123122 return {
123+ background: ' ' as string | null ,
124124 backgroundFailed: undefined as boolean | undefined ,
125125 backgroundLoaded: false ,
126126 }
@@ -138,54 +138,6 @@ export default defineComponent({
138138 return this .userConfig .crop_image_previews === true
139139 },
140140
141- previewUrl() {
142- if (this .source .type === FileType .Folder ) {
143- return null
144- }
145-
146- if (this .source .attributes [' has-preview' ] === false
147- && this .source .mime
148- && this .source .mime !== ' application/octet-stream'
149- ) {
150- return generateUrl (' /core/mimeicon?mime={mime}' , {
151- mime: this .source .mime ,
152- })
153- }
154-
155- if (this .backgroundFailed === true ) {
156- return null
157- }
158-
159- try {
160- const previewUrl = this .source .attributes .previewUrl
161- || (this .isPublic
162- ? generateUrl (' /apps/files_sharing/publicpreview/{token}?file={file}' , {
163- token: this .publicSharingToken ,
164- file: this .source .path ,
165- })
166- : generateUrl (' /core/preview?fileId={fileid}' , {
167- fileid: String (this .source .fileid ),
168- })
169- )
170- const url = new URL (window .location .origin + previewUrl )
171-
172- // Request tiny previews
173- url .searchParams .set (' x' , this .gridMode ? ' 128' : ' 32' )
174- url .searchParams .set (' y' , this .gridMode ? ' 128' : ' 32' )
175- url .searchParams .set (' mimeFallback' , ' true' )
176-
177- // Etag to force refresh preview on change
178- const etag = this .source ?.attributes ?.etag || ' '
179- url .searchParams .set (' v' , etag .slice (0 , 6 ))
180-
181- // Handle cropping
182- url .searchParams .set (' a' , this .cropPreviews === true ? ' 0' : ' 1' )
183- return url .href
184- } catch (e ) {
185- return null
186- }
187- },
188-
189141 fileOverlay() {
190142 if (isLivePhoto (this .source )) {
191143 return PlayCircleIcon
@@ -241,20 +193,71 @@ export default defineComponent({
241193 },
242194
243195 mounted() {
196+ this .reset ()
197+
244198 if (this .hasBlurhash && this .$refs .canvas ) {
245199 this .drawBlurhash ()
246200 }
247201 },
248202
249203 methods: {
250204 // Called from FileEntry
251- reset() {
205+ async reset() {
252206 // Reset background state to cancel any ongoing requests
207+ this .background = ' '
253208 this .backgroundFailed = undefined
254209 this .backgroundLoaded = false
255- const previewImg = this .$refs .previewImg as HTMLImageElement | undefined
256- if (previewImg ) {
257- previewImg .src = ' '
210+
211+ // Then update the new background
212+ await this .$nextTick ()
213+ this .updateBackground ()
214+ },
215+
216+ updateBackground() {
217+ if (this .source .type === FileType .Folder ) {
218+ this .background = null
219+ return
220+ }
221+
222+ if (this .source .attributes [' has-preview' ] !== true
223+ && this .source .mime !== undefined
224+ && this .source .mime !== ' application/octet-stream'
225+ ) {
226+ const previewUrl = generateUrl (' /core/mimeicon?mime={mime}' , {
227+ mime: this .source .mime ,
228+ })
229+ const url = new URL (window .location .origin + previewUrl )
230+ this .background = url .href
231+ return
232+ }
233+
234+ try {
235+ const previewUrl = this .source .attributes .previewUrl
236+ || (this .isPublic
237+ ? generateUrl (' /apps/files_sharing/publicpreview/{token}?file={file}' , {
238+ token: this .publicSharingToken ,
239+ file: this .source .path ,
240+ })
241+ : generateUrl (' /core/preview?fileId={fileid}' , {
242+ fileid: String (this .source .fileid ),
243+ })
244+ )
245+ const url = new URL (window .location .origin + previewUrl )
246+
247+ // Request tiny previews
248+ url .searchParams .set (' x' , this .gridMode ? ' 128' : ' 32' )
249+ url .searchParams .set (' y' , this .gridMode ? ' 128' : ' 32' )
250+ url .searchParams .set (' mimeFallback' , ' true' )
251+
252+ // Etag to force refresh preview on change
253+ const etag = this .source ?.attributes ?.etag || ' '
254+ url .searchParams .set (' v' , etag .slice (0 , 6 ))
255+
256+ // Handle cropping
257+ url .searchParams .set (' a' , this .cropPreviews === true ? ' 0' : ' 1' )
258+ this .background = url .href
259+ } catch (e ) {
260+ this .background = null
258261 }
259262 },
260263
@@ -265,7 +268,7 @@ export default defineComponent({
265268
266269 onBackgroundError(event ) {
267270 // Do not fail if we just reset the background
268- if (event .target ?.src === ' ' ) {
271+ if (event .target ?.src === ' ' || ! this . background ) {
269272 return
270273 }
271274 this .backgroundFailed = true
0 commit comments