mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-01-08 22:38:43 -05:00
Compare commits
5 Commits
v3.0.0
...
reset-scro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e16a16cd8 | ||
|
|
78a0f74f33 | ||
|
|
8b9e80358b | ||
|
|
2bae6e9d02 | ||
|
|
6b98a7cd74 |
@@ -31,7 +31,7 @@ To deploy mealie on your local network, it is highly recommended to use Docker t
|
||||
We've gone through a few versions of Mealie v1 deployment targets. We have settled on a single container deployment, and we've begun publishing the nightly container on github containers. If you're looking to move from the old nightly (split containers _or_ the omni image) to the new nightly, there are a few things you need to do:
|
||||
|
||||
1. Take a backup just in case!
|
||||
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v2.8.0`
|
||||
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.0.0`
|
||||
3. Take the external port from the frontend container and set that as the port mapped to port `9000` on the new container. The frontend is now served on port 9000 from the new container, so it will need to be mapped for you to have access.
|
||||
4. Restart the container
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
|
||||
```yaml
|
||||
services:
|
||||
mealie:
|
||||
image: ghcr.io/mealie-recipes/mealie:v2.8.0 # (3)
|
||||
image: ghcr.io/mealie-recipes/mealie:v3.0.0 # (3)
|
||||
container_name: mealie
|
||||
restart: always
|
||||
ports:
|
||||
|
||||
@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
|
||||
```yaml
|
||||
services:
|
||||
mealie:
|
||||
image: ghcr.io/mealie-recipes/mealie:v2.8.0 # (3)
|
||||
image: ghcr.io/mealie-recipes/mealie:v3.0.0 # (3)
|
||||
container_name: mealie
|
||||
restart: always
|
||||
ports:
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
:image="recipe.image!"
|
||||
:tags="recipe.tags!"
|
||||
:recipe-id="recipe.id!"
|
||||
@click="handleRecipeNavigation"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -147,6 +148,7 @@
|
||||
:image="recipe.image!"
|
||||
:tags="recipe.tags!"
|
||||
:recipe-id="recipe.id!"
|
||||
@selected="handleRecipeNavigation"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -171,6 +173,7 @@ import { useLazyRecipes } from "~/composables/recipes";
|
||||
import type { Recipe } from "~/lib/api/types/recipe";
|
||||
import { useUserSortPreferences } from "~/composables/use-users/preferences";
|
||||
import type { RecipeSearchQuery } from "~/lib/api/user/recipes/recipe";
|
||||
import { useRecipeListState } from "~/composables/recipe-page/use-recipe-list-state";
|
||||
|
||||
const REPLACE_RECIPES_EVENT = "replaceRecipes";
|
||||
const APPEND_RECIPES_EVENT = "appendRecipes";
|
||||
@@ -241,9 +244,11 @@ export default defineNuxtComponent({
|
||||
const route = useRoute();
|
||||
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
|
||||
|
||||
const page = ref(1);
|
||||
const recipeListState = useRecipeListState(props.query);
|
||||
|
||||
const page = ref(recipeListState.state.page || 1);
|
||||
const perPage = 32;
|
||||
const hasMore = ref(true);
|
||||
const hasMore = ref(recipeListState.state.hasMore);
|
||||
const ready = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
@@ -282,8 +287,33 @@ export default defineNuxtComponent({
|
||||
);
|
||||
}
|
||||
|
||||
// Save scroll position
|
||||
const throttledScrollSave = useThrottleFn(() => {
|
||||
recipeListState.saveScrollPosition();
|
||||
}, 1000);
|
||||
|
||||
onMounted(async () => {
|
||||
await initRecipes();
|
||||
window.addEventListener("scroll", throttledScrollSave);
|
||||
|
||||
// cached state with scroll position
|
||||
if (recipeListState.hasValidState() && recipeListState.isQueryMatch(props.query)) {
|
||||
// Restore from cached state
|
||||
page.value = recipeListState.state.page;
|
||||
hasMore.value = recipeListState.state.hasMore;
|
||||
ready.value = recipeListState.state.ready;
|
||||
|
||||
// Emit cached recipes
|
||||
context.emit(REPLACE_RECIPES_EVENT, recipeListState.state.recipes);
|
||||
|
||||
// Restore scroll position after recipes are rendered
|
||||
nextTick(() => {
|
||||
recipeListState.restoreScrollPosition();
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Initialize fresh recipes
|
||||
await initRecipes();
|
||||
}
|
||||
ready.value = true;
|
||||
});
|
||||
|
||||
@@ -294,6 +324,10 @@ export default defineNuxtComponent({
|
||||
const newValueString = JSON.stringify(newValue);
|
||||
if (lastQuery !== newValueString) {
|
||||
lastQuery = newValueString;
|
||||
|
||||
// Save scroll position before query change
|
||||
recipeListState.saveScrollPosition();
|
||||
|
||||
ready.value = false;
|
||||
await initRecipes();
|
||||
ready.value = true;
|
||||
@@ -315,6 +349,14 @@ export default defineNuxtComponent({
|
||||
// since we doubled the first call, we also need to advance the page
|
||||
page.value = page.value + 1;
|
||||
|
||||
// Save state after fetching recipes
|
||||
recipeListState.saveState({
|
||||
recipes: newRecipes,
|
||||
page: page.value,
|
||||
hasMore: hasMore.value,
|
||||
ready: true,
|
||||
});
|
||||
|
||||
context.emit(REPLACE_RECIPES_EVENT, newRecipes);
|
||||
}
|
||||
|
||||
@@ -331,6 +373,14 @@ export default defineNuxtComponent({
|
||||
hasMore.value = false;
|
||||
}
|
||||
if (newRecipes.length) {
|
||||
// Update cached state with new recipes
|
||||
const allRecipes = [...(recipeListState.state.recipes || []), ...newRecipes] as Recipe[];
|
||||
recipeListState.saveState({
|
||||
recipes: allRecipes,
|
||||
page: page.value,
|
||||
hasMore: hasMore.value,
|
||||
});
|
||||
|
||||
context.emit(APPEND_RECIPES_EVENT, newRecipes);
|
||||
}
|
||||
|
||||
@@ -408,6 +458,15 @@ export default defineNuxtComponent({
|
||||
|
||||
// fetch new recipes
|
||||
const newRecipes = await fetchRecipes();
|
||||
|
||||
// Update cached state
|
||||
recipeListState.saveState({
|
||||
recipes: newRecipes,
|
||||
page: page.value,
|
||||
hasMore: hasMore.value,
|
||||
ready: true,
|
||||
});
|
||||
|
||||
context.emit(REPLACE_RECIPES_EVENT, newRecipes);
|
||||
|
||||
state.sortLoading = false;
|
||||
@@ -427,6 +486,17 @@ export default defineNuxtComponent({
|
||||
preferences.value.useMobileCards = !preferences.value.useMobileCards;
|
||||
}
|
||||
|
||||
// Save scroll position when component is unmounted or when navigating away
|
||||
onBeforeUnmount(() => {
|
||||
recipeListState.saveScrollPosition();
|
||||
window.removeEventListener("scroll", throttledScrollSave);
|
||||
});
|
||||
|
||||
// Save scroll position when navigating to recipe pages
|
||||
function handleRecipeNavigation() {
|
||||
recipeListState.saveScrollPosition();
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
displayTitleIcon,
|
||||
@@ -439,6 +509,7 @@ export default defineNuxtComponent({
|
||||
sortRecipes,
|
||||
toggleMobileCards,
|
||||
useMobileCards,
|
||||
handleRecipeNavigation,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
94
frontend/composables/recipe-page/use-recipe-list-state.ts
Normal file
94
frontend/composables/recipe-page/use-recipe-list-state.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import type { Recipe } from "~/lib/api/types/recipe";
|
||||
import type { RecipeSearchQuery } from "~/lib/api/user/recipes/recipe";
|
||||
|
||||
interface RecipeListState {
|
||||
recipes: Recipe[];
|
||||
page: number;
|
||||
hasMore: boolean;
|
||||
scrollPosition: number;
|
||||
query: RecipeSearchQuery | null;
|
||||
ready: boolean;
|
||||
}
|
||||
|
||||
const recipeListStates = new Map<string, RecipeListState>();
|
||||
|
||||
function generateStateKey(query: RecipeSearchQuery | null): string {
|
||||
if (!query) return "default";
|
||||
|
||||
const keyParts = [
|
||||
query.search || "",
|
||||
query.orderBy || "",
|
||||
query.orderDirection || "",
|
||||
query.queryFilter || "",
|
||||
JSON.stringify(query.categories || []),
|
||||
JSON.stringify(query.tags || []),
|
||||
JSON.stringify(query.tools || []),
|
||||
JSON.stringify(query.foods || []),
|
||||
JSON.stringify(query.households || []),
|
||||
];
|
||||
|
||||
return keyParts.join("|");
|
||||
}
|
||||
|
||||
export function useRecipeListState(query: RecipeSearchQuery | null) {
|
||||
const stateKey = generateStateKey(query);
|
||||
|
||||
// Initialize state if it doesn't exist
|
||||
if (!recipeListStates.has(stateKey)) {
|
||||
recipeListStates.set(stateKey, {
|
||||
recipes: [],
|
||||
page: 1,
|
||||
hasMore: true,
|
||||
scrollPosition: 0,
|
||||
query,
|
||||
ready: false,
|
||||
});
|
||||
}
|
||||
|
||||
const state = recipeListStates.get(stateKey)!;
|
||||
|
||||
function saveState(newState: Partial<RecipeListState>) {
|
||||
Object.assign(state, newState);
|
||||
}
|
||||
|
||||
function saveScrollPosition() {
|
||||
state.scrollPosition = window.scrollY || document.documentElement.scrollTop || 0;
|
||||
}
|
||||
|
||||
function restoreScrollPosition() {
|
||||
if (state.scrollPosition > 0) {
|
||||
// Use nextTick to ensure DOM is updated before scrolling
|
||||
nextTick(() => {
|
||||
window.scrollTo(0, state.scrollPosition);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clearState() {
|
||||
recipeListStates.delete(stateKey);
|
||||
}
|
||||
|
||||
function hasValidState(): boolean {
|
||||
return state.recipes.length > 0 && state.ready;
|
||||
}
|
||||
|
||||
function isQueryMatch(newQuery: RecipeSearchQuery | null): boolean {
|
||||
const newKey = generateStateKey(newQuery);
|
||||
return newKey === stateKey;
|
||||
}
|
||||
|
||||
return {
|
||||
state: readonly(state),
|
||||
saveState,
|
||||
saveScrollPosition,
|
||||
restoreScrollPosition,
|
||||
clearState,
|
||||
hasValidState,
|
||||
isQueryMatch,
|
||||
};
|
||||
}
|
||||
|
||||
// Clean up old states when navigating away from recipe sections
|
||||
export function cleanupRecipeListStates() {
|
||||
recipeListStates.clear();
|
||||
}
|
||||
@@ -288,7 +288,7 @@
|
||||
"household-group": "Группа домохозяйства",
|
||||
"household-management": "Управление домохозяйствами",
|
||||
"manage-households": "Управление Домами",
|
||||
"admin-household-management": "Admin Household Management",
|
||||
"admin-household-management": "Управление Домохозяйством",
|
||||
"admin-household-management-text": "Изменения в данном домохозяйстве будут отражены немедленно.",
|
||||
"household-id-value": "Id домохозяйства: {0}",
|
||||
"private-household": "Частное домохозяйство",
|
||||
@@ -298,7 +298,7 @@
|
||||
"household-recipe-preferences": "Предпочтения для рецептов домашнего хозяйства",
|
||||
"default-recipe-preferences-description": "Это настройки по умолчанию, когда в вашем домашнем хозяйстве создается новый рецепт. Они могут быть изменены для отдельных рецептов в меню настроек рецепта.",
|
||||
"allow-users-outside-of-your-household-to-see-your-recipes": "Разрешить пользователям вне вашего домохозяйства видеть ваши рецепты",
|
||||
"allow-users-outside-of-your-household-to-see-your-recipes-description": "When enabled you can use a public share link to share specific recipes without authorizing the user. When disabled, you can only share recipes with users who are in your household or with a pre-generated private link",
|
||||
"allow-users-outside-of-your-household-to-see-your-recipes-description": "При включении данной функции, вы можете делиться публичной ссылкой на данный рецепт, чтобы поделиться им с людьми без аккаунта. Если функция выключена — поделиться рецептом можно только с пользователями внутри вашего домохозяйства или по предварительно сгенерированной приватной ссылке",
|
||||
"household-preferences": "Параметры домохозяйства"
|
||||
},
|
||||
"meal-plan": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mealie",
|
||||
"version": "2.8.0",
|
||||
"version": "3.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxt dev",
|
||||
|
||||
@@ -9,5 +9,11 @@ import RecipeExplorerPage from "~/components/Domain/Recipe/RecipeExplorerPage.vu
|
||||
|
||||
export default defineNuxtComponent({
|
||||
components: { RecipeExplorerPage },
|
||||
setup() {
|
||||
// Enable scroll restoration for this page to work with our state management
|
||||
definePageMeta({
|
||||
scrollToTop: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -595,8 +595,8 @@
|
||||
"broccoli slaw": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "broccoli slaw",
|
||||
"plural_name": "broccoli slaws"
|
||||
"name": "Brokkolisalat",
|
||||
"plural_name": "Brokkolisalate"
|
||||
},
|
||||
"arbol chile pepper": {
|
||||
"aliases": [],
|
||||
@@ -1182,55 +1182,55 @@
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "Pluot",
|
||||
"plural_name": "pluots"
|
||||
"plural_name": "Pluots"
|
||||
},
|
||||
"soursop": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "soursop",
|
||||
"plural_name": "soursops"
|
||||
"name": "Stachelannone",
|
||||
"plural_name": "Stachelannonen"
|
||||
},
|
||||
"hog plum": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "hog plum",
|
||||
"name": "Mombinpflaumen",
|
||||
"plural_name": "Mombinpflaume"
|
||||
},
|
||||
"bergamot orange": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "bergamot orange",
|
||||
"plural_name": "bergamot oranges"
|
||||
"name": "Bergamotte",
|
||||
"plural_name": "Bergamotten"
|
||||
},
|
||||
"luo han guo": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "luo han guo",
|
||||
"plural_name": "luo han guos"
|
||||
"name": "Mönchsfrucht",
|
||||
"plural_name": "Mönchsfrüchte"
|
||||
},
|
||||
"mamey": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mamey",
|
||||
"plural_name": "mameys"
|
||||
"name": "Mammiapfel",
|
||||
"plural_name": "Mammiäpfel"
|
||||
},
|
||||
"sapote": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "sapote",
|
||||
"plural_name": "sapotes"
|
||||
"name": "Sapote",
|
||||
"plural_name": "Sapote"
|
||||
},
|
||||
"green ume plum": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "green ume plum",
|
||||
"plural_name": "green ume plums"
|
||||
"name": "Japanische Pflaume",
|
||||
"plural_name": "Japanische Pflaumen"
|
||||
},
|
||||
"kiwano": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "kiwano",
|
||||
"plural_name": "kiwanoes"
|
||||
"name": "Horngurke",
|
||||
"plural_name": "Horngurken"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1419,13 +1419,13 @@
|
||||
"puffball": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "puffball",
|
||||
"plural_name": "puffballs"
|
||||
"name": "Riesenbovist",
|
||||
"plural_name": "Riesenboviste"
|
||||
},
|
||||
"honey fungu": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "honey fungu",
|
||||
"name": "",
|
||||
"plural_name": "honey fungus"
|
||||
},
|
||||
"caesar's mushroom": {
|
||||
@@ -1471,8 +1471,8 @@
|
||||
"cranberry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cranberry",
|
||||
"plural_name": "cranberries"
|
||||
"name": "Cranberry",
|
||||
"plural_name": "Cranberries"
|
||||
},
|
||||
"cherry": {
|
||||
"aliases": [],
|
||||
@@ -1483,7 +1483,7 @@
|
||||
"blackberry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "blackberry",
|
||||
"name": "Brombeere",
|
||||
"plural_name": "Brombeeren"
|
||||
},
|
||||
"berry mix": {
|
||||
@@ -1495,8 +1495,8 @@
|
||||
"maraschino cherry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "maraschino cherry",
|
||||
"plural_name": "maraschino cherries"
|
||||
"name": "maraschino Kirsche",
|
||||
"plural_name": "maraschino Kirschen"
|
||||
},
|
||||
"dried cherry": {
|
||||
"aliases": [],
|
||||
@@ -1507,8 +1507,8 @@
|
||||
"juniper berry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "juniper berry",
|
||||
"plural_name": "juniper berries"
|
||||
"name": "Wacholderbeere",
|
||||
"plural_name": "Wacholderbeeren"
|
||||
},
|
||||
"sour cherry": {
|
||||
"aliases": [],
|
||||
@@ -1519,8 +1519,8 @@
|
||||
"goji berry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "goji berry",
|
||||
"plural_name": "goji berries"
|
||||
"name": "Goji-Beere",
|
||||
"plural_name": "Goji-Beeren"
|
||||
},
|
||||
"dried blueberry": {
|
||||
"aliases": [],
|
||||
@@ -1561,8 +1561,8 @@
|
||||
"mulberry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mulberry",
|
||||
"plural_name": "mulberries"
|
||||
"name": "Maulbeere",
|
||||
"plural_name": "Maulbeeren"
|
||||
},
|
||||
"acai berry": {
|
||||
"aliases": [],
|
||||
@@ -1597,8 +1597,8 @@
|
||||
"huckleberry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "huckleberry",
|
||||
"plural_name": "huckleberries"
|
||||
"name": "Heidelbeere",
|
||||
"plural_name": "Heidelbeeren"
|
||||
},
|
||||
"dried elderberry": {
|
||||
"aliases": [],
|
||||
@@ -1615,8 +1615,8 @@
|
||||
"dried berry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "dried berry",
|
||||
"plural_name": "dried berries"
|
||||
"name": "getrocknete Beere",
|
||||
"plural_name": "getrocknete Beeren"
|
||||
},
|
||||
"sea buckthorn": {
|
||||
"aliases": [],
|
||||
@@ -1663,8 +1663,8 @@
|
||||
"aronia berry": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "aronia berry",
|
||||
"plural_name": "aronia berries"
|
||||
"name": "Apfelbeere",
|
||||
"plural_name": "Apfelbeeren"
|
||||
},
|
||||
"chokeberry": {
|
||||
"aliases": [],
|
||||
@@ -1681,8 +1681,8 @@
|
||||
"blackcurrant leaf": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "blackcurrant leaf",
|
||||
"plural_name": "blackcurrant leaves"
|
||||
"name": "Schwarzes Johannisbeerblatt",
|
||||
"plural_name": "Schwarze Johannisbeerblätter"
|
||||
},
|
||||
"haskap berry": {
|
||||
"aliases": [],
|
||||
@@ -1745,8 +1745,8 @@
|
||||
"pine nut": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "pine nut",
|
||||
"plural_name": "pine nuts"
|
||||
"name": "Pinienkern",
|
||||
"plural_name": "Pinienkerne"
|
||||
},
|
||||
"pistachio": {
|
||||
"aliases": [],
|
||||
@@ -1776,7 +1776,7 @@
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "slivered almond",
|
||||
"plural_name": "slivered almonds"
|
||||
"plural_name": "Mandelstifte"
|
||||
},
|
||||
"pumpkin seed": {
|
||||
"aliases": [],
|
||||
@@ -1853,8 +1853,8 @@
|
||||
"onion seed": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "onion seed",
|
||||
"plural_name": "onion seeds"
|
||||
"name": "Zwiebelsamen",
|
||||
"plural_name": "Zwiebelsamen"
|
||||
},
|
||||
"watermelon seed": {
|
||||
"aliases": [],
|
||||
@@ -1871,8 +1871,8 @@
|
||||
"melon seed": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "melon seed",
|
||||
"plural_name": "melon seeds"
|
||||
"name": "Melonensamen",
|
||||
"plural_name": "Melonensamen"
|
||||
},
|
||||
"lotus seed": {
|
||||
"aliases": [],
|
||||
@@ -1895,8 +1895,8 @@
|
||||
"basil seed": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "basil seed",
|
||||
"plural_name": "basil seeds"
|
||||
"name": "Basilikumsamen",
|
||||
"plural_name": "Basilikumsamen"
|
||||
},
|
||||
"candlenut": {
|
||||
"aliases": [],
|
||||
@@ -1907,8 +1907,8 @@
|
||||
"peanut brittle": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "peanut brittle",
|
||||
"plural_name": "peanut brittles"
|
||||
"name": "Erdnusskrokant",
|
||||
"plural_name": "Erdnusskrokant"
|
||||
},
|
||||
"jackfruit seed": {
|
||||
"aliases": [],
|
||||
|
||||
@@ -241,106 +241,106 @@
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "artisjok",
|
||||
"plural_name": "artichokes"
|
||||
"plural_name": "artisjokken"
|
||||
},
|
||||
"new potato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "new potato",
|
||||
"plural_name": "new potatoes"
|
||||
"name": "krieltjes",
|
||||
"plural_name": "krieltjes"
|
||||
},
|
||||
"summer squash": {
|
||||
"aliases": [
|
||||
"courgette",
|
||||
"gem squash"
|
||||
"edelpompoen"
|
||||
],
|
||||
"description": "",
|
||||
"name": "summer squash",
|
||||
"plural_name": "summer squashes"
|
||||
"plural_name": "edelpompoenen"
|
||||
},
|
||||
"mixed green": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mixed green",
|
||||
"plural_name": "mixed greens"
|
||||
"name": "gemengde groenten",
|
||||
"plural_name": "gemengde groenten"
|
||||
},
|
||||
"parsnip": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "parsnip",
|
||||
"plural_name": "parsnips"
|
||||
"name": "pastinaak",
|
||||
"plural_name": "pastinaken"
|
||||
},
|
||||
"baby carrot": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "baby carrot",
|
||||
"plural_name": "baby carrots"
|
||||
"name": "baby wortel",
|
||||
"plural_name": "baby wortels"
|
||||
},
|
||||
"mixed vegetable": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mixed vegetable",
|
||||
"plural_name": "mixed vegetables"
|
||||
"name": "gemengde groente",
|
||||
"plural_name": "gemengde groenten"
|
||||
},
|
||||
"poblano pepper": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "poblano pepper",
|
||||
"plural_name": "poblano peppers"
|
||||
"name": "poblano pepers",
|
||||
"plural_name": "poblano pepers"
|
||||
},
|
||||
"sweet pepper": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "sweet pepper",
|
||||
"plural_name": "sweet peppers"
|
||||
"name": "puntpaprika",
|
||||
"plural_name": "puntpaprikas"
|
||||
},
|
||||
"serrano pepper": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "serrano pepper",
|
||||
"plural_name": "serrano peppers"
|
||||
"name": "serranopeper",
|
||||
"plural_name": "serranopepers"
|
||||
},
|
||||
"cayenne pepper": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "cayenne pepper",
|
||||
"plural_name": "cayenne peppers"
|
||||
"name": "cayennepeper",
|
||||
"plural_name": "cayennepepers"
|
||||
},
|
||||
"green tomato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "green tomato",
|
||||
"plural_name": "green tomatoes"
|
||||
"name": "groene tomaat",
|
||||
"plural_name": "groene tomaten"
|
||||
},
|
||||
"watercress": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "watercress",
|
||||
"plural_name": "watercress"
|
||||
"name": "waterkers",
|
||||
"plural_name": "waterkersen"
|
||||
},
|
||||
"iceberg": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "iceberg",
|
||||
"plural_name": "icebergs"
|
||||
"name": "ijsbergsla",
|
||||
"plural_name": "ijsbergsla"
|
||||
},
|
||||
"mashed potato": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mashed potato",
|
||||
"plural_name": "mashed potatoes"
|
||||
"name": "aardappelpuree",
|
||||
"plural_name": "aardappelpurees"
|
||||
},
|
||||
"horseradish": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "horseradish",
|
||||
"plural_name": "horseradishes"
|
||||
"name": "mierikswortel",
|
||||
"plural_name": "mierikswortelen"
|
||||
},
|
||||
"chard": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "chard",
|
||||
"plural_name": "chards"
|
||||
"name": "snijbiet",
|
||||
"plural_name": "snijbieten"
|
||||
},
|
||||
"pimiento": {
|
||||
"aliases": [],
|
||||
@@ -351,40 +351,40 @@
|
||||
"spaghetti squash": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "spaghetti squash",
|
||||
"plural_name": "spaghetti squashes"
|
||||
"name": "spaghettipompoen",
|
||||
"plural_name": "spaghettipompoenen"
|
||||
},
|
||||
"butter lettuce": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "butter lettuce",
|
||||
"plural_name": "butter lettuces"
|
||||
"name": "kropsla",
|
||||
"plural_name": "kropsla"
|
||||
},
|
||||
"hash brown": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "hash brown",
|
||||
"plural_name": "hash browns"
|
||||
"name": "gehakte aardappel",
|
||||
"plural_name": "gehakte aardappels"
|
||||
},
|
||||
"napa cabbage": {
|
||||
"aliases": [
|
||||
"chinese leaves"
|
||||
"chinese kool"
|
||||
],
|
||||
"description": "",
|
||||
"name": "napa cabbage",
|
||||
"plural_name": "napa cabbages"
|
||||
"name": "chinese kool",
|
||||
"plural_name": "chinese kolen"
|
||||
},
|
||||
"celeriac": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "celeriac",
|
||||
"plural_name": "celeriacs"
|
||||
"name": "knolselderij",
|
||||
"plural_name": "knolselders"
|
||||
},
|
||||
"water chestnut": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "water chestnut",
|
||||
"plural_name": "water chestnuts"
|
||||
"name": "waterkastanje",
|
||||
"plural_name": "waterkastanjes"
|
||||
},
|
||||
"turnip": {
|
||||
"aliases": [],
|
||||
@@ -541,8 +541,8 @@
|
||||
"ancho chile pepper": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "ancho chile pepper",
|
||||
"plural_name": "ancho chile peppers"
|
||||
"name": "ancho peper",
|
||||
"plural_name": "ancho pepers"
|
||||
},
|
||||
"microgreen": {
|
||||
"aliases": [],
|
||||
@@ -553,8 +553,8 @@
|
||||
"boston lettuce": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "boston lettuce",
|
||||
"plural_name": "boston lettuces"
|
||||
"name": "botersla",
|
||||
"plural_name": "botersla"
|
||||
},
|
||||
"kohlrabi": {
|
||||
"aliases": [],
|
||||
@@ -608,19 +608,19 @@
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "golden beet",
|
||||
"plural_name": "golden beets"
|
||||
"plural_name": "gele biet"
|
||||
},
|
||||
"pea shoot": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "pea shoot",
|
||||
"plural_name": "pea shoots"
|
||||
"name": "erwtenspruit",
|
||||
"plural_name": "erwtenspruiten"
|
||||
},
|
||||
"alfalfa": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "alfalfa",
|
||||
"plural_name": "alfalfas"
|
||||
"name": "luzerne",
|
||||
"plural_name": "luzerne"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -630,61 +630,61 @@
|
||||
"aliases": [],
|
||||
"description": "Yes they are a fruit",
|
||||
"name": "tomato",
|
||||
"plural_name": "tomatoes"
|
||||
"plural_name": "tomaten"
|
||||
},
|
||||
"lemon": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "lemon",
|
||||
"plural_name": "lemons"
|
||||
"name": "citroen",
|
||||
"plural_name": "citroenen"
|
||||
},
|
||||
"lime": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "lime",
|
||||
"plural_name": "limes"
|
||||
"name": "limoen",
|
||||
"plural_name": "limoenen"
|
||||
},
|
||||
"apple": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "apple",
|
||||
"plural_name": "apples"
|
||||
"name": "appel",
|
||||
"plural_name": "appels"
|
||||
},
|
||||
"banana": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "banana",
|
||||
"plural_name": "bananas"
|
||||
"name": "banaan",
|
||||
"plural_name": "bananen"
|
||||
},
|
||||
"orange": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "orange",
|
||||
"plural_name": "oranges"
|
||||
"name": "sinaasappel",
|
||||
"plural_name": "sinaasappels"
|
||||
},
|
||||
"raisin": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "raisin",
|
||||
"plural_name": "raisins"
|
||||
"name": "rozijn",
|
||||
"plural_name": "rozijnen"
|
||||
},
|
||||
"pineapple": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "pineapple",
|
||||
"plural_name": "pineapples"
|
||||
"name": "ananas",
|
||||
"plural_name": "ananassen"
|
||||
},
|
||||
"mango": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "mango",
|
||||
"plural_name": "mangoes"
|
||||
"plural_name": "mango's"
|
||||
},
|
||||
"peach": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "peach",
|
||||
"plural_name": "peaches"
|
||||
"name": "perzik",
|
||||
"plural_name": "perziken"
|
||||
},
|
||||
"date": {
|
||||
"aliases": [],
|
||||
@@ -851,8 +851,8 @@
|
||||
"dried fruit": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "dried fruit",
|
||||
"plural_name": "dried fruits"
|
||||
"name": "gedroogd fruit",
|
||||
"plural_name": "gedroogd fruit"
|
||||
},
|
||||
"clementine": {
|
||||
"aliases": [],
|
||||
@@ -4349,14 +4349,14 @@
|
||||
"chicken breast": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "chicken breast",
|
||||
"plural_name": "chicken breasts"
|
||||
"name": "kipfilet",
|
||||
"plural_name": "kipfilet"
|
||||
},
|
||||
"chicken thigh": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "chicken thigh",
|
||||
"plural_name": "chicken thighs"
|
||||
"name": "kipdijfilet",
|
||||
"plural_name": "kipdijfilet"
|
||||
},
|
||||
"cooked chicken": {
|
||||
"aliases": [],
|
||||
@@ -4385,14 +4385,14 @@
|
||||
"chicken leg": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "chicken leg",
|
||||
"plural_name": "chicken legs"
|
||||
"name": "kippenpoot",
|
||||
"plural_name": "kippenpoten"
|
||||
},
|
||||
"chicken wing": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "chicken wing",
|
||||
"plural_name": "chicken wings"
|
||||
"name": "kippenpoot",
|
||||
"plural_name": "kippenpoten"
|
||||
},
|
||||
"turkey breast": {
|
||||
"aliases": [],
|
||||
@@ -8540,8 +8540,8 @@
|
||||
"rice": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "rice",
|
||||
"plural_name": "rices"
|
||||
"name": "rijst",
|
||||
"plural_name": "rijst"
|
||||
},
|
||||
"Rice Krispie Cereal": {
|
||||
"aliases": [
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"zucchini": {
|
||||
"aliases": [],
|
||||
"description": "",
|
||||
"name": "zucchini",
|
||||
"name": "цукини",
|
||||
"plural_name": "zucchinis"
|
||||
},
|
||||
"potato": {
|
||||
|
||||
6
poetry.lock
generated
6
poetry.lock
generated
@@ -1816,14 +1816,14 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.94.0"
|
||||
version = "1.95.0"
|
||||
description = "The official Python library for the openai API"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "openai-1.94.0-py3-none-any.whl", hash = "sha256:159c43b811669abe9bb4aafdc57a049966dfde2eac94b151aac3eb63bf9825b4"},
|
||||
{file = "openai-1.94.0.tar.gz", hash = "sha256:31c6c213cc80365d54632296c4aef7cda1800003ca5c784ac50a05d6bc05c197"},
|
||||
{file = "openai-1.95.0-py3-none-any.whl", hash = "sha256:a7afc9dca7e7d616371842af8ea6dbfbcb739a85d183f5f664ab1cc311b9ef18"},
|
||||
{file = "openai-1.95.0.tar.gz", hash = "sha256:54bc42df9f7142312647dd485d34cca5df20af825fa64a30ca55164be2cf4cc9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ authors = ["Hayden <hay-kot@pm.me>"]
|
||||
description = "A Recipe Manager"
|
||||
license = "AGPL"
|
||||
name = "mealie"
|
||||
version = "2.8.0"
|
||||
version = "3.0.0"
|
||||
include = [
|
||||
# Explicit include to override .gitignore when packaging the frontend
|
||||
{ path = "mealie/frontend/**/*", format = ["sdist", "wheel"] }
|
||||
|
||||
Reference in New Issue
Block a user