diff --git a/frontend/components/Domain/Recipe/RecipeCardSection.vue b/frontend/components/Domain/Recipe/RecipeCardSection.vue index 62ca93d54..6ca7e0a0a 100644 --- a/frontend/components/Domain/Recipe/RecipeCardSection.vue +++ b/frontend/components/Domain/Recipe/RecipeCardSection.vue @@ -205,23 +205,14 @@ export default defineComponent({ const route = useRoute(); const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); - const router = useRouter(); - function navigateRandom() { - if (props.recipes.length > 0) { - const recipe = props.recipes[Math.floor(Math.random() * props.recipes.length)]; - if (recipe.slug !== undefined) { - router.push(`/g/${groupSlug.value}/r/${recipe.slug}`); - } - } - } - const page = ref(1); const perPage = 32; const hasMore = ref(true); const ready = ref(false); const loading = ref(false); - const { fetchMore } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value); + const { fetchMore, getRandom } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value); + const router = useRouter(); const queryFilter = computed(() => { const orderBy = props.query?.orderBy || preferences.value.orderBy; @@ -383,6 +374,15 @@ export default defineComponent({ }, useAsyncKey()); } + async function navigateRandom() { + const recipe = await getRandom(props.query, queryFilter.value); + if (!recipe?.slug) { + return; + } + + router.push(`/g/${groupSlug.value}/r/${recipe.slug}`); + } + function toggleMobileCards() { preferences.value.useMobileCards = !preferences.value.useMobileCards; } diff --git a/frontend/composables/recipes/use-recipes.ts b/frontend/composables/recipes/use-recipes.ts index c51149a29..aef1c0c1c 100644 --- a/frontend/composables/recipes/use-recipes.ts +++ b/frontend/composables/recipes/use-recipes.ts @@ -8,6 +8,32 @@ import { RecipeSearchQuery } from "~/lib/api/user/recipes/recipe"; export const allRecipes = ref([]); export const recentRecipes = ref([]); +function getParams( + orderBy: string | null = null, + orderDirection = "desc", + query: RecipeSearchQuery | null = null, + queryFilter: string | null = null +) { + return { + orderBy, + orderDirection, + paginationSeed: query?._searchSeed, // propagate searchSeed to stabilize random order pagination + searchSeed: query?._searchSeed, // unused, but pass it along for completeness of data + search: query?.search, + cookbook: query?.cookbook, + households: query?.households, + categories: query?.categories, + requireAllCategories: query?.requireAllCategories, + tags: query?.tags, + requireAllTags: query?.requireAllTags, + tools: query?.tools, + requireAllTools: query?.requireAllTools, + foods: query?.foods, + requireAllFoods: query?.requireAllFoods, + queryFilter, + }; +}; + export const useLazyRecipes = function (publicGroupSlug: string | null = null) { const router = useRouter(); @@ -25,24 +51,11 @@ export const useLazyRecipes = function (publicGroupSlug: string | null = null) { queryFilter: string | null = null, ) { - const { data, error } = await api.recipes.getAll(page, perPage, { - orderBy, - orderDirection, - paginationSeed: query?._searchSeed, // propagate searchSeed to stabilize random order pagination - searchSeed: query?._searchSeed, // unused, but pass it along for completeness of data - search: query?.search, - cookbook: query?.cookbook, - households: query?.households, - categories: query?.categories, - requireAllCategories: query?.requireAllCategories, - tags: query?.tags, - requireAllTags: query?.requireAllTags, - tools: query?.tools, - requireAllTools: query?.requireAllTools, - foods: query?.foods, - requireAllFoods: query?.requireAllFoods, - queryFilter, - }); + const { data, error } = await api.recipes.getAll( + page, + perPage, + getParams(orderBy, orderDirection, query, queryFilter), + ); if (error?.response?.status === 404) { router.push("/login"); @@ -74,6 +87,13 @@ export const useLazyRecipes = function (publicGroupSlug: string | null = null) { recipes.value = val; } + async function getRandom(query: RecipeSearchQuery | null = null, queryFilter: string | null = null) { + const { data } = await api.recipes.getAll(1, 1, getParams("random", "desc", query, queryFilter)); + if (data?.items.length) { + return data.items[0]; + } + } + return { recipes, fetchMore, @@ -81,6 +101,7 @@ export const useLazyRecipes = function (publicGroupSlug: string | null = null) { assignSorted, removeRecipe, replaceRecipes, + getRandom, }; };