Skip to content

Commit cec35dc

Browse files
authored
fix: project card preload on hover (#5348)
1 parent a536d79 commit cec35dc

2 files changed

Lines changed: 22 additions & 16 deletions

File tree

apps/frontend/src/pages/discover/[type]/index.vue

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
} from '@modrinth/ui'
3838
import { capitalizeString, cycleValue, type Mod as InstallableMod } from '@modrinth/utils'
3939
import { useQueryClient } from '@tanstack/vue-query'
40-
import { useThrottleFn } from '@vueuse/core'
40+
import { useThrottleFn, useTimeoutFn } from '@vueuse/core'
4141
import { computed, type Reactive, watch } from 'vue'
4242
4343
import LogoAnimated from '~/components/brand/LogoAnimated.vue'
@@ -63,18 +63,21 @@ const { handleError } = injectNotificationManager()
6363
const modrinthClient = injectModrinthClient()
6464
const queryClient = useQueryClient()
6565
66-
let prefetchTimeout: ReturnType<typeof setTimeout> | null = null
67-
68-
function handleProjectHover(result: Labrinth.Search.v2.ResultSearchProject) {
69-
if (prefetchTimeout) clearTimeout(prefetchTimeout)
70-
prefetchTimeout = setTimeout(() => {
71-
const slug = result.slug || result.project_id
72-
queryClient.prefetchQuery(projectQueryOptions.v2(slug, modrinthClient))
73-
queryClient.prefetchQuery(projectQueryOptions.v3(result.project_id, modrinthClient))
74-
queryClient.prefetchQuery(projectQueryOptions.members(result.project_id, modrinthClient))
75-
queryClient.prefetchQuery(projectQueryOptions.dependencies(result.project_id, modrinthClient))
76-
queryClient.prefetchQuery(projectQueryOptions.versionsV3(result.project_id, modrinthClient))
77-
}, 150)
66+
let prefetchTimeout: ReturnType<typeof useTimeoutFn> | null = null
67+
const HOVER_DURATION_TO_PREFETCH_MS = 500
68+
69+
const handleProjectMouseEnter = (result: Labrinth.Search.v2.ResultSearchProject) => {
70+
const slug = result.slug || result.project_id
71+
prefetchTimeout = useTimeoutFn(
72+
() => queryClient.prefetchQuery(projectQueryOptions.v2(slug, modrinthClient)),
73+
HOVER_DURATION_TO_PREFETCH_MS,
74+
{ immediate: false },
75+
)
76+
prefetchTimeout.start()
77+
}
78+
79+
const handleProjectHoverEnd = () => {
80+
if (prefetchTimeout) prefetchTimeout.stop()
7881
}
7982
8083
const currentType = computed(() =>
@@ -694,7 +697,8 @@ useSeoMeta({
694697
:layout="
695698
resultsDisplayMode === 'grid' || resultsDisplayMode === 'gallery' ? 'grid' : 'list'
696699
"
697-
@hover="handleProjectHover(result)"
700+
@mouseenter="handleProjectMouseEnter(result)"
701+
@mouseleave="handleProjectHoverEnd"
698702
>
699703
<template v-if="flags.showDiscoverProjectButtons || server" #actions>
700704
<template v-if="flags.showDiscoverProjectButtons">

packages/ui/src/components/project/card/ProjectCard.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<AutoLink
55
:to="link"
66
class="rounded-xl no-outline no-click-animation custom-focus-indicator"
7-
@mouseenter="$emit('hover')"
7+
@mouseenter="$emit('mouseenter')"
8+
@mouseleave="$emit('mouseleave')"
89
></AutoLink>
910
</template>
1011
<div v-if="layout === 'grid'" :class="[baseCardStyle, 'flex flex-col']">
@@ -153,7 +154,8 @@ import ProjectCardTags from './ProjectCardTags.vue'
153154
import ProjectCardTitle from './ProjectCardTitle.vue'
154155
155156
defineEmits<{
156-
hover: []
157+
mouseenter: []
158+
mouseleave: []
157159
}>()
158160
159161
const props = defineProps<{

0 commit comments

Comments
 (0)