Skip to content

Commit d437df4

Browse files
authored
feat(client): expose preloadProgress / preloadComplete from the image preloader (#2650)
1 parent f324c65 commit d437df4

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

packages/client/composables/usePreloadImages.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SlideRoute } from '@slidev/types'
22
import type { ComputedRef, Ref } from 'vue'
3-
import { watchEffect } from 'vue'
3+
import { computed, ref, watchEffect } from 'vue'
44
import configs from '#slidev/configs'
55

66
const loaded = new Set<string>()
@@ -17,6 +17,20 @@ function resolveUrl(url: string): string {
1717
const RETRY_LIMIT = 2
1818
const retries = new Map<string, number>()
1919

20+
const preloadedCount = ref(0)
21+
const totalImagesCount = ref(0)
22+
23+
/**
24+
* Progress of slide-image preloading, from 0 to 1 (1 when every preloadable
25+
* image in the deck has loaded, or when the deck has no images).
26+
*/
27+
export const preloadProgress = computed(() =>
28+
totalImagesCount.value === 0 ? 1 : preloadedCount.value / totalImagesCount.value,
29+
)
30+
31+
/** Whether all preloadable slide images have finished loading. */
32+
export const preloadComplete = computed(() => preloadProgress.value >= 1)
33+
2034
function preloadImage(url: string): void {
2135
const resolved = resolveUrl(url)
2236
if (loaded.has(resolved) || loading.has(resolved))
@@ -27,6 +41,7 @@ function preloadImage(url: string): void {
2741
loading.delete(resolved)
2842
loaded.add(resolved)
2943
retries.delete(resolved)
44+
preloadedCount.value = loaded.size
3045
}
3146
img.onerror = () => {
3247
loading.delete(resolved)
@@ -61,6 +76,19 @@ export function usePreloadImages(
6176

6277
const ahead = (typeof config === 'object' && config?.ahead) || 3
6378

79+
// Track total preloadable images across the deck for progress reporting
80+
watchEffect(() => {
81+
const all = slides.value
82+
if (!all?.length)
83+
return
84+
const urls = new Set<string>()
85+
for (const route of all) {
86+
for (const url of route.meta?.slide?.images ?? [])
87+
urls.add(resolveUrl(url))
88+
}
89+
totalImagesCount.value = urls.size
90+
})
91+
6492
// Preload current + prev + next + look-ahead window
6593
watchEffect(() => {
6694
const current = currentRoute.value

0 commit comments

Comments
 (0)