Compare commits

..

2 Commits

Author SHA1 Message Date
GitHub Action
9d4bb320b7 chore: automatic locale sync 2025-07-05 00:30:52 +00:00
Hayden
e417a2001d duh 2025-07-04 19:29:07 -05:00
179 changed files with 28502 additions and 667029 deletions

View File

@@ -105,7 +105,11 @@ jobs:
## Changes ## Changes
- Updated frontend locale files - Updated frontend locale files
- Generated from latest translation sources" \ - Generated from latest translation sources
## Test plan
- [ ] Verify locale files are properly formatted
- [ ] Test that translations load correctly in the frontend" \
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -12,7 +12,7 @@ repos:
exclude: ^tests/data/ exclude: ^tests/data/
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version. # Ruff version.
rev: v0.12.2 rev: v0.12.1
hooks: hooks:
- id: ruff - id: ruff
- id: ruff-format - id: ruff-format

View File

@@ -76,7 +76,7 @@ export const LOCALES = [{% for locale in locales %}
progress: {{ locale.progress }}, progress: {{ locale.progress }},
dir: "{{ locale.dir }}", dir: "{{ locale.dir }}",
},{% endfor %} },{% endfor %}
]; ]
""" """

View File

@@ -0,0 +1,24 @@
![Recipe Image](../../images/{{ recipe.slug }}/original.jpg)
# {{ recipe.name }}
{{ recipe.description }}
## Ingredients
{% for ingredient in recipe.recipeIngredient %}
- [ ] {{ ingredient }} {% endfor %}
## Instructions
{% for step in recipe.recipeInstructions %}
- [ ] {{ step.text }} {% endfor %}
{% for note in recipe.notes %}
**{{ note.title }}:** {{ note.text }}
{% endfor %}
---
Tags: {{ recipe.tags }}
Categories: {{ recipe.categories }}
Original URL: {{ recipe.orgURL }}

View File

@@ -20,7 +20,7 @@ RUN yarn generate
############################################### ###############################################
# Base Image - Python # Base Image - Python
############################################### ###############################################
FROM python:3.12-slim AS python-base FROM python:3.12-slim as python-base
ENV MEALIE_HOME="/app" ENV MEALIE_HOME="/app"
@@ -119,7 +119,7 @@ RUN . $VENV_PATH/bin/activate \
############################################### ###############################################
# Production Image # Production Image
############################################### ###############################################
FROM python-base AS production FROM python-base as production
LABEL org.opencontainers.image.source="https://github.com/mealie-recipes/mealie" LABEL org.opencontainers.image.source="https://github.com/mealie-recipes/mealie"
ENV PRODUCTION=true ENV PRODUCTION=true
ENV TESTING=false ENV TESTING=false

View File

@@ -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: 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! 1. Take a backup just in case!
2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v3.0.0` 2. Replace the image for the API container with `ghcr.io/mealie-recipes/mealie:v2.8.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. 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 4. Restart the container

View File

@@ -7,7 +7,7 @@ PostgreSQL might be considered if you need to support many concurrent users. In
```yaml ```yaml
services: services:
mealie: mealie:
image: ghcr.io/mealie-recipes/mealie:v3.0.0 # (3) image: ghcr.io/mealie-recipes/mealie:v2.8.0 # (3)
container_name: mealie container_name: mealie
restart: always restart: always
ports: ports:

View File

@@ -11,7 +11,7 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
```yaml ```yaml
services: services:
mealie: mealie:
image: ghcr.io/mealie-recipes/mealie:v3.0.0 # (3) image: ghcr.io/mealie-recipes/mealie:v2.8.0 # (3)
container_name: mealie container_name: mealie
restart: always restart: always
ports: ports:

View File

@@ -0,0 +1,390 @@
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-cyrillic-ext1.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-cyrillic2.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-greek-ext3.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-greek4.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-vietnamese5.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-latin-ext6.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("~assets/fonts/Roboto-100-latin7.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-cyrillic-ext8.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-cyrillic9.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-greek-ext10.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-greek11.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-vietnamese12.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-latin-ext13.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("~assets/fonts/Roboto-300-latin14.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-cyrillic-ext15.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-cyrillic16.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-greek-ext17.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-greek18.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-vietnamese19.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-latin-ext20.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("~assets/fonts/Roboto-400-latin21.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-cyrillic-ext22.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-cyrillic23.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-greek-ext24.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-greek25.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-vietnamese26.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-latin-ext27.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("~assets/fonts/Roboto-500-latin28.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-cyrillic-ext29.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-cyrillic30.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-greek-ext31.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-greek32.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-vietnamese33.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-latin-ext34.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("~assets/fonts/Roboto-700-latin35.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-cyrillic-ext36.woff2") format("woff2");
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-cyrillic37.woff2") format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-greek-ext38.woff2") format("woff2");
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-greek39.woff2") format("woff2");
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-vietnamese40.woff2") format("woff2");
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-latin-ext41.woff2") format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("~assets/fonts/Roboto-900-latin42.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,23 +1,23 @@
<template> <template>
<div v-if="model.length > 0 || edit"> <div v-if="value.length > 0 || edit">
<v-card class="mt-4"> <v-card class="mt-4">
<v-card-title class="py-2"> <v-card-title class="py-2">
{{ $t("asset.assets") }} {{ $t("asset.assets") }}
</v-card-title> </v-card-title>
<v-divider class="mx-2" /> <v-divider class="mx-2" />
<v-list <v-list
v-if="model.length > 0" v-if="value.length > 0"
:flat="!edit" :flat="!edit"
> >
<v-list-item <v-list-item
v-for="(item, i) in model" v-for="(item, i) in value"
:key="i" :key="i"
> >
<template #prepend> <template #prepend>
<div class="ma-auto"> <div class="ma-auto">
<v-tooltip bottom> <v-tooltip bottom>
<template #activator="{ props: tooltipProps }"> <template #activator="{ props }">
<v-icon v-bind="tooltipProps"> <v-icon v-bind="props">
{{ getIconDefinition(item.icon).icon }} {{ getIconDefinition(item.icon).icon }}
</v-icon> </v-icon>
</template> </template>
@@ -44,7 +44,7 @@
color="error" color="error"
icon icon
top top
@click="model.splice(i, 1)" @click="value.splice(i, 1)"
> >
<v-icon>{{ $globals.icons.delete }}</v-icon> <v-icon>{{ $globals.icons.delete }}</v-icon>
</v-btn> </v-btn>
@@ -113,109 +113,124 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script lang="ts">
import { useStaticRoutes, useUserApi } from "~/composables/api"; import { useStaticRoutes, useUserApi } from "~/composables/api";
import { alert } from "~/composables/use-toast"; import { alert } from "~/composables/use-toast";
import type { RecipeAsset } from "~/lib/api/types/recipe"; import type { RecipeAsset } from "~/lib/api/types/recipe";
const props = defineProps({ export default defineNuxtComponent({
slug: { props: {
type: String, slug: {
required: true, type: String,
required: true,
},
recipeId: {
type: String,
required: true,
},
modelValue: {
type: Array as () => RecipeAsset[],
required: true,
},
edit: {
type: Boolean,
default: true,
},
}, },
recipeId: { emits: ["update:modelValue"],
type: String, setup(props, context) {
required: true, const api = useUserApi();
},
edit: { const state = reactive({
type: Boolean, newAssetDialog: false,
default: true, fileObject: {} as File,
newAsset: {
name: "",
icon: "mdi-file",
},
});
const i18n = useI18n();
const { $globals } = useNuxtApp();
const iconOptions = [
{
name: "mdi-file",
title: i18n.t("asset.file"),
icon: $globals.icons.file,
},
{
name: "mdi-file-pdf-box",
title: i18n.t("asset.pdf"),
icon: $globals.icons.filePDF,
},
{
name: "mdi-file-image",
title: i18n.t("asset.image"),
icon: $globals.icons.fileImage,
},
{
name: "mdi-code-json",
title: i18n.t("asset.code"),
icon: $globals.icons.codeJson,
},
{
name: "mdi-silverware-fork-knife",
title: i18n.t("asset.recipe"),
icon: $globals.icons.primary,
},
];
const serverBase = useRequestURL().origin;
function getIconDefinition(icon: string) {
return iconOptions.find(item => item.name === icon) || iconOptions[0];
}
const { recipeAssetPath } = useStaticRoutes();
function assetURL(assetName: string) {
return recipeAssetPath(props.recipeId, assetName);
}
function assetEmbed(name: string) {
return `<img src="${serverBase}${assetURL(name)}" height="100%" width="100%"> </img>`;
}
function setFileObject(fileObject: File) {
state.fileObject = fileObject;
}
function validFields() {
return state.newAsset.name.length > 0 && state.fileObject.name.length > 0;
}
async function addAsset() {
if (!validFields()) {
alert.error(i18n.t("asset.error-submitting-form") as string);
return;
}
const { data } = await api.recipes.createAsset(props.slug, {
name: state.newAsset.name,
icon: state.newAsset.icon,
file: state.fileObject,
extension: state.fileObject.name.split(".").pop() || "",
});
context.emit("update:modelValue", [...props.modelValue, data]);
state.newAsset = { name: "", icon: "mdi-file" };
state.fileObject = {} as File;
}
return {
state,
addAsset,
assetURL,
assetEmbed,
getIconDefinition,
iconOptions,
setFileObject,
};
}, },
}); });
const model = defineModel<RecipeAsset[]>({ required: true });
const api = useUserApi();
const state = reactive({
newAssetDialog: false,
fileObject: {} as File,
newAsset: {
name: "",
icon: "mdi-file",
},
});
const i18n = useI18n();
const { $globals } = useNuxtApp();
const iconOptions = [
{
name: "mdi-file",
title: i18n.t("asset.file"),
icon: $globals.icons.file,
},
{
name: "mdi-file-pdf-box",
title: i18n.t("asset.pdf"),
icon: $globals.icons.filePDF,
},
{
name: "mdi-file-image",
title: i18n.t("asset.image"),
icon: $globals.icons.fileImage,
},
{
name: "mdi-code-json",
title: i18n.t("asset.code"),
icon: $globals.icons.codeJson,
},
{
name: "mdi-silverware-fork-knife",
title: i18n.t("asset.recipe"),
icon: $globals.icons.primary,
},
];
const serverBase = useRequestURL().origin;
function getIconDefinition(icon: string) {
return iconOptions.find(item => item.name === icon) || iconOptions[0];
}
const { recipeAssetPath } = useStaticRoutes();
function assetURL(assetName: string) {
return recipeAssetPath(props.recipeId, assetName);
}
function assetEmbed(name: string) {
return `<img src="${serverBase}${assetURL(name)}" height="100%" width="100%"> </img>`;
}
function setFileObject(fileObject: File) {
state.fileObject = fileObject;
}
function validFields() {
return state.newAsset.name.length > 0 && state.fileObject.name.length > 0;
}
async function addAsset() {
if (!validFields()) {
alert.error(i18n.t("asset.error-submitting-form") as string);
return;
}
const { data } = await api.recipes.createAsset(props.slug, {
name: state.newAsset.name,
icon: state.newAsset.icon,
file: state.fileObject,
extension: state.fileObject.name.split(".").pop() || "",
});
if (data) {
model.value = [...model.value, data];
}
state.newAsset = { name: "", icon: "mdi-file" };
state.fileObject = {} as File;
}
</script> </script>

View File

@@ -123,7 +123,6 @@
:image="recipe.image!" :image="recipe.image!"
:tags="recipe.tags!" :tags="recipe.tags!"
:recipe-id="recipe.id!" :recipe-id="recipe.id!"
@click="handleRecipeNavigation"
/> />
</v-col> </v-col>
</v-row> </v-row>
@@ -148,7 +147,6 @@
:image="recipe.image!" :image="recipe.image!"
:tags="recipe.tags!" :tags="recipe.tags!"
:recipe-id="recipe.id!" :recipe-id="recipe.id!"
@selected="handleRecipeNavigation"
/> />
</v-col> </v-col>
</v-row> </v-row>
@@ -173,7 +171,6 @@ import { useLazyRecipes } from "~/composables/recipes";
import type { Recipe } from "~/lib/api/types/recipe"; import type { Recipe } from "~/lib/api/types/recipe";
import { useUserSortPreferences } from "~/composables/use-users/preferences"; import { useUserSortPreferences } from "~/composables/use-users/preferences";
import type { RecipeSearchQuery } from "~/lib/api/user/recipes/recipe"; 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 REPLACE_RECIPES_EVENT = "replaceRecipes";
const APPEND_RECIPES_EVENT = "appendRecipes"; const APPEND_RECIPES_EVENT = "appendRecipes";
@@ -244,11 +241,9 @@ export default defineNuxtComponent({
const route = useRoute(); const route = useRoute();
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || ""); const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const recipeListState = useRecipeListState(props.query); const page = ref(1);
const page = ref(recipeListState.state.page || 1);
const perPage = 32; const perPage = 32;
const hasMore = ref(recipeListState.state.hasMore); const hasMore = ref(true);
const ready = ref(false); const ready = ref(false);
const loading = ref(false); const loading = ref(false);
@@ -287,33 +282,8 @@ export default defineNuxtComponent({
); );
} }
// Save scroll position
const throttledScrollSave = useThrottleFn(() => {
recipeListState.saveScrollPosition();
}, 1000);
onMounted(async () => { onMounted(async () => {
window.addEventListener("scroll", throttledScrollSave); await initRecipes();
// 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; ready.value = true;
}); });
@@ -324,10 +294,6 @@ export default defineNuxtComponent({
const newValueString = JSON.stringify(newValue); const newValueString = JSON.stringify(newValue);
if (lastQuery !== newValueString) { if (lastQuery !== newValueString) {
lastQuery = newValueString; lastQuery = newValueString;
// Save scroll position before query change
recipeListState.saveScrollPosition();
ready.value = false; ready.value = false;
await initRecipes(); await initRecipes();
ready.value = true; ready.value = true;
@@ -349,14 +315,6 @@ export default defineNuxtComponent({
// since we doubled the first call, we also need to advance the page // since we doubled the first call, we also need to advance the page
page.value = page.value + 1; 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); context.emit(REPLACE_RECIPES_EVENT, newRecipes);
} }
@@ -373,14 +331,6 @@ export default defineNuxtComponent({
hasMore.value = false; hasMore.value = false;
} }
if (newRecipes.length) { 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); context.emit(APPEND_RECIPES_EVENT, newRecipes);
} }
@@ -458,15 +408,6 @@ export default defineNuxtComponent({
// fetch new recipes // fetch new recipes
const newRecipes = await fetchRecipes(); 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); context.emit(REPLACE_RECIPES_EVENT, newRecipes);
state.sortLoading = false; state.sortLoading = false;
@@ -486,17 +427,6 @@ export default defineNuxtComponent({
preferences.value.useMobileCards = !preferences.value.useMobileCards; 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 { return {
...toRefs(state), ...toRefs(state),
displayTitleIcon, displayTitleIcon,
@@ -509,7 +439,6 @@ export default defineNuxtComponent({
sortRecipes, sortRecipes,
toggleMobileCards, toggleMobileCards,
useMobileCards, useMobileCards,
handleRecipeNavigation,
}; };
}, },
}); });

View File

@@ -17,7 +17,6 @@
:suffix="labels[key].suffix" :suffix="labels[key].suffix"
type="number" type="number"
autocomplete="off" autocomplete="off"
variant="underlined"
@update:model-value="updateValue(key, $event)" @update:model-value="updateValue(key, $event)"
/> />
</div> </div>
@@ -32,13 +31,15 @@
:key="index" :key="index"
style="min-height: 25px" style="min-height: 25px"
> >
<v-list-item-title class="pl-2 d-flex"> <div>
<div>{{ item.label }}</div> <v-list-item-title class="pl-4 caption flex row">
<div class="ml-auto mr-1"> <div>{{ item.label }}</div>
{{ item.value }} <div class="ml-auto mr-1">
</div> {{ item.value }}
<div>{{ item.suffix }}</div> </div>
</v-list-item-title> <div>{{ item.suffix }}</div>
</v-list-item-title>
</div>
</v-list-item> </v-list-item>
</v-list> </v-list>
</v-card> </v-card>

View File

@@ -42,8 +42,6 @@ export default defineNuxtComponent({
.v-main { .v-main {
display: block; display: block;
padding: 0 !important;
margin: 0 !important;
} }
.v-main__wrap { .v-main__wrap {

View File

@@ -23,17 +23,18 @@
</v-icon> </v-icon>
{{ recipe.name }} {{ recipe.name }}
</v-card-title> </v-card-title>
<div <div v-if="recipeYield"
v-if="recipeYield" class="d-flex justify-space-between align-center px-4 pb-2"
class="d-flex justify-space-between align-center pb-6"
> >
<div> <v-chip :size="$vuetify.display.smAndDown ? 'small' : undefined"
label
>
<v-icon start> <v-icon start>
{{ $globals.icons.potSteam }} {{ $globals.icons.potSteam }}
</v-icon> </v-icon>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="recipeYield" /> <span v-html="recipeYield" />
</div> </v-chip>
</div> </div>
<v-row class="d-flex justify-start"> <v-row class="d-flex justify-start">
<RecipeTimeCard :prep-time="recipe.prepTime" <RecipeTimeCard :prep-time="recipe.prepTime"

View File

@@ -138,48 +138,14 @@ export default defineNuxtComponent({
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || ""); const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const cookbookPreferences = useCookbookPreferences(); const cookbookPreferences = useCookbookPreferences();
const { store: cookbooks, actions: cookbooksActions } = isOwnGroup.value ? useCookbookStore() : usePublicCookbookStore(groupSlug.value || "");
const ownCookbookStore = useCookbookStore(i18n); onMounted(() => {
const ownHouseholdStore = useHouseholdStore(i18n); if (!cookbooks.value.length) {
cookbooksActions.refresh();
const publicCookbookStoreCache = ref<Record<string, ReturnType<typeof usePublicCookbookStore>>>({});
const publicHouseholdStoreCache = ref<Record<string, ReturnType<typeof usePublicHouseholdStore>>>({});
function getPublicCookbookStore(slug: string) {
if (!publicCookbookStoreCache.value[slug]) {
publicCookbookStoreCache.value[slug] = usePublicCookbookStore(slug, i18n);
} }
return publicCookbookStoreCache.value[slug];
}
function getPublicHouseholdStore(slug: string) {
if (!publicHouseholdStoreCache.value[slug]) {
publicHouseholdStoreCache.value[slug] = usePublicHouseholdStore(slug, i18n);
}
return publicHouseholdStoreCache.value[slug];
}
const cookbooks = computed(() => {
if (isOwnGroup.value) {
return ownCookbookStore.store.value;
}
else if (groupSlug.value) {
const publicStore = getPublicCookbookStore(groupSlug.value);
return unref(publicStore.store);
}
return [];
}); });
const households = computed(() => { const { store: households } = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value || "");
if (isOwnGroup.value) {
return ownHouseholdStore.store.value;
}
else if (groupSlug.value) {
const publicStore = getPublicHouseholdStore(groupSlug.value);
return unref(publicStore.store);
}
return [];
});
const householdsById = computed(() => { const householdsById = computed(() => {
return households.value.reduce((acc, household) => { return households.value.reduce((acc, household) => {
@@ -212,10 +178,6 @@ export default defineNuxtComponent({
const currentUserHouseholdId = computed(() => $auth.user.value?.householdId); const currentUserHouseholdId = computed(() => $auth.user.value?.householdId);
const cookbookLinks = computed<SideBarLink[]>(() => { const cookbookLinks = computed<SideBarLink[]>(() => {
if (!cookbooks.value?.length) {
return [];
}
const sortedCookbooks = [...cookbooks.value].sort((a, b) => (a.position || 0) - (b.position || 0)); const sortedCookbooks = [...cookbooks.value].sort((a, b) => (a.position || 0) - (b.position || 0));
const ownLinks: SideBarLink[] = []; const ownLinks: SideBarLink[] = [];

View File

@@ -2,6 +2,7 @@
<v-tooltip <v-tooltip
ref="copyToolTip" ref="copyToolTip"
v-model="show" v-model="show"
:color="copied? 'success-lighten-1' : 'red-lighten-1'"
top top
:open-on-hover="false" :open-on-hover="false"
:open-on-click="true" :open-on-click="true"
@@ -23,12 +24,15 @@
{{ icon ? "" : $t("general.copy") }} {{ icon ? "" : $t("general.copy") }}
</v-btn> </v-btn>
</template> </template>
<span v-if="!isSupported || copiedSuccess !== null"> <span>
<v-icon start> <v-icon
start
dark
>
{{ $globals.icons.clipboardCheck }} {{ $globals.icons.clipboardCheck }}
</v-icon> </v-icon>
<slot v-if="!isSupported"> {{ $t("general.your-browser-does-not-support-clipboard") }} </slot> <slot v-if="!isSupported"> {{ $t("general.your-browser-does-not-support-clipboard") }} </slot>
<slot v-else> {{ copiedSuccess ? $t("general.copied_message") : $t("general.clipboard-copy-failure") }} </slot> <slot v-else> {{ copied ? $t("general.copied_message") : $t("general.clipboard-copy-failure") }} </slot>
</span> </span>
</v-tooltip> </v-tooltip>
</template> </template>
@@ -59,18 +63,19 @@ export default defineNuxtComponent({
const { copy, copied, isSupported } = useClipboard(); const { copy, copied, isSupported } = useClipboard();
const show = ref(false); const show = ref(false);
const copyToolTip = ref<VTooltip | null>(null); const copyToolTip = ref<VTooltip | null>(null);
const copiedSuccess = ref<boolean | null>(null);
function toggleBlur() {
copyToolTip.value?.deactivate();
}
async function textToClipboard() { async function textToClipboard() {
if (isSupported.value) { if (isSupported.value) {
await copy(props.copyText); await copy(props.copyText);
if (copied.value) { if (copied.value) {
copiedSuccess.value = true; console.log(`Copied\n${props.copyText}`);
console.info(`Copied\n${props.copyText}`);
} }
else { else {
copiedSuccess.value = false; console.warn("Copy failed: ", copied.value);
console.error("Copy failed: ", copied.value);
} }
} }
else { else {
@@ -79,8 +84,8 @@ export default defineNuxtComponent({
show.value = true; show.value = true;
setTimeout(() => { setTimeout(() => {
show.value = false; toggleBlur();
}, 3000); }, 500);
} }
return { return {
@@ -89,7 +94,6 @@ export default defineNuxtComponent({
textToClipboard, textToClipboard,
copied, copied,
isSupported, isSupported,
copiedSuccess,
}; };
}, },
}); });

View File

@@ -1,5 +1,4 @@
import type { AxiosInstance, AxiosResponse, AxiosRequestConfig } from "axios"; import type { AxiosInstance, AxiosResponse, AxiosRequestConfig } from "axios";
import type { Composer } from "vue-i18n";
import type { ApiRequestInstance, RequestResponse } from "~/lib/api/types/non-generated"; import type { ApiRequestInstance, RequestResponse } from "~/lib/api/types/non-generated";
import { AdminAPI, PublicApi, UserApi } from "~/lib/api"; import { AdminAPI, PublicApi, UserApi } from "~/lib/api";
import { PublicExploreApi } from "~/lib/api/client-public"; import { PublicExploreApi } from "~/lib/api/client-public";
@@ -53,34 +52,31 @@ function getRequests(axiosInstance: AxiosInstance): ApiRequestInstance {
}; };
} }
export const useRequests = function (i18n?: Composer): ApiRequestInstance { export const useRequests = function (): ApiRequestInstance {
const i18n = useI18n();
const { $axios } = useNuxtApp(); const { $axios } = useNuxtApp();
if (!i18n) {
// Only works in a setup block
i18n = useI18n();
}
$axios.defaults.headers.common["Accept-Language"] = i18n.locale.value; $axios.defaults.headers.common["Accept-Language"] = i18n.locale.value;
return getRequests($axios); return getRequests($axios);
}; };
export const useAdminApi = function (i18n?: Composer): AdminAPI { export const useAdminApi = function (): AdminAPI {
const requests = useRequests(i18n); const requests = useRequests();
return new AdminAPI(requests); return new AdminAPI(requests);
}; };
export const useUserApi = function (i18n?: Composer): UserApi { export const useUserApi = function (): UserApi {
const requests = useRequests(i18n); const requests = useRequests();
return new UserApi(requests); return new UserApi(requests);
}; };
export const usePublicApi = function (i18n?: Composer): PublicApi { export const usePublicApi = function (): PublicApi {
const requests = useRequests(i18n); const requests = useRequests();
return new PublicApi(requests); return new PublicApi(requests);
}; };
export const usePublicExploreApi = function (groupSlug: string, i18n?: Composer): PublicExploreApi { export const usePublicExploreApi = function (groupSlug: string): PublicExploreApi {
const requests = useRequests(i18n); const requests = useRequests();
return new PublicExploreApi(requests, groupSlug); return new PublicExploreApi(requests, groupSlug);
}; };

View File

@@ -1,94 +0,0 @@
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();
}

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory"; import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { RecipeCategory } from "~/lib/api/types/recipe"; import type { RecipeCategory } from "~/lib/api/types/recipe";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -15,12 +14,12 @@ export const useCategoryData = function () {
}); });
}; };
export const useCategoryStore = function (i18n?: Composer) { export const useCategoryStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<RecipeCategory>(store, loading, api.categories); return useStore<RecipeCategory>(store, loading, api.categories);
}; };
export const usePublicCategoryStore = function (groupSlug: string, i18n?: Composer) { export const usePublicCategoryStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<RecipeCategory>(store, publicLoading, api.categories); return useReadOnlyStore<RecipeCategory>(store, publicLoading, api.categories);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useReadOnlyStore, useStore } from "../partials/use-store-factory"; import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { RecipeCookBook } from "~/lib/api/types/cookbook"; import type { RecipeCookBook } from "~/lib/api/types/cookbook";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -7,12 +6,12 @@ const store: Ref<RecipeCookBook[]> = ref([]);
const loading = ref(false); const loading = ref(false);
const publicLoading = ref(false); const publicLoading = ref(false);
export const useCookbookStore = function (i18n?: Composer) { export const useCookbookStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<RecipeCookBook>(store, loading, api.cookbooks); return useStore<RecipeCookBook>(store, loading, api.cookbooks);
}; };
export const usePublicCookbookStore = function (groupSlug: string, i18n?: Composer) { export const usePublicCookbookStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks); return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory"; import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { IngredientFood } from "~/lib/api/types/recipe"; import type { IngredientFood } from "~/lib/api/types/recipe";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -16,12 +15,12 @@ export const useFoodData = function () {
}); });
}; };
export const useFoodStore = function (i18n?: Composer) { export const useFoodStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<IngredientFood>(store, loading, api.foods); return useStore<IngredientFood>(store, loading, api.foods);
}; };
export const usePublicFoodStore = function (groupSlug: string, i18n?: Composer) { export const usePublicFoodStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<IngredientFood>(store, publicLoading, api.foods); return useReadOnlyStore<IngredientFood>(store, publicLoading, api.foods);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useReadOnlyStore } from "../partials/use-store-factory"; import { useReadOnlyStore } from "../partials/use-store-factory";
import type { HouseholdSummary } from "~/lib/api/types/household"; import type { HouseholdSummary } from "~/lib/api/types/household";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -7,12 +6,12 @@ const store: Ref<HouseholdSummary[]> = ref([]);
const loading = ref(false); const loading = ref(false);
const publicLoading = ref(false); const publicLoading = ref(false);
export const useHouseholdStore = function (i18n?: Composer) { export const useHouseholdStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useReadOnlyStore<HouseholdSummary>(store, loading, api.households); return useReadOnlyStore<HouseholdSummary>(store, loading, api.households);
}; };
export const usePublicHouseholdStore = function (groupSlug: string, i18n?: Composer) { export const usePublicHouseholdStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<HouseholdSummary>(store, publicLoading, api.households); return useReadOnlyStore<HouseholdSummary>(store, publicLoading, api.households);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useStore } from "../partials/use-store-factory"; import { useData, useStore } from "../partials/use-store-factory";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels"; import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import { useUserApi } from "~/composables/api"; import { useUserApi } from "~/composables/api";
@@ -15,7 +14,7 @@ export const useLabelData = function () {
}); });
}; };
export const useLabelStore = function (i18n?: Composer) { export const useLabelStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<MultiPurposeLabelOut>(store, loading, api.multiPurposeLabels); return useStore<MultiPurposeLabelOut>(store, loading, api.multiPurposeLabels);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory"; import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { RecipeTag } from "~/lib/api/types/recipe"; import type { RecipeTag } from "~/lib/api/types/recipe";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -15,12 +14,12 @@ export const useTagData = function () {
}); });
}; };
export const useTagStore = function (i18n?: Composer) { export const useTagStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<RecipeTag>(store, loading, api.tags); return useStore<RecipeTag>(store, loading, api.tags);
}; };
export const usePublicTagStore = function (groupSlug: string, i18n?: Composer) { export const usePublicTagStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<RecipeTag>(store, publicLoading, api.tags); return useReadOnlyStore<RecipeTag>(store, publicLoading, api.tags);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory"; import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { RecipeTool } from "~/lib/api/types/recipe"; import type { RecipeTool } from "~/lib/api/types/recipe";
import { usePublicExploreApi, useUserApi } from "~/composables/api"; import { usePublicExploreApi, useUserApi } from "~/composables/api";
@@ -21,12 +20,12 @@ export const useToolData = function () {
}); });
}; };
export const useToolStore = function (i18n?: Composer) { export const useToolStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<RecipeTool>(store, loading, api.tools); return useStore<RecipeTool>(store, loading, api.tools);
}; };
export const usePublicToolStore = function (groupSlug: string, i18n?: Composer) { export const usePublicToolStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug, i18n).explore; const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<RecipeTool>(store, publicLoading, api.tools); return useReadOnlyStore<RecipeTool>(store, publicLoading, api.tools);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useData, useStore } from "../partials/use-store-factory"; import { useData, useStore } from "../partials/use-store-factory";
import type { IngredientUnit } from "~/lib/api/types/recipe"; import type { IngredientUnit } from "~/lib/api/types/recipe";
import { useUserApi } from "~/composables/api"; import { useUserApi } from "~/composables/api";
@@ -16,7 +15,7 @@ export const useUnitData = function () {
}); });
}; };
export const useUnitStore = function (i18n?: Composer) { export const useUnitStore = function () {
const api = useUserApi(i18n); const api = useUserApi();
return useStore<IngredientUnit>(store, loading, api.units); return useStore<IngredientUnit>(store, loading, api.units);
}; };

View File

@@ -1,4 +1,3 @@
import type { Composer } from "vue-i18n";
import { useReadOnlyStore } from "../partials/use-store-factory"; import { useReadOnlyStore } from "../partials/use-store-factory";
import { useRequests } from "../api/api-client"; import { useRequests } from "../api/api-client";
import type { UserSummary } from "~/lib/api/types/user"; import type { UserSummary } from "~/lib/api/types/user";
@@ -12,8 +11,8 @@ class GroupUserAPIReadOnly extends BaseCRUDAPIReadOnly<UserSummary> {
itemRoute = (idOrUsername: string | number) => `/groups/members/${idOrUsername}`; itemRoute = (idOrUsername: string | number) => `/groups/members/${idOrUsername}`;
} }
export const useUserStore = function (i18n?: Composer) { export const useUserStore = function () {
const requests = useRequests(i18n); const requests = useRequests();
const api = new GroupUserAPIReadOnly(requests); const api = new GroupUserAPIReadOnly(requests);
return useReadOnlyStore<UserSummary>(store, loading, api, { orderBy: "full_name" }); return useReadOnlyStore<UserSummary>(store, loading, api, { orderBy: "full_name" });

View File

@@ -9,7 +9,7 @@ export const LOCALES = [
{ {
name: "简体中文 (Chinese simplified)", name: "简体中文 (Chinese simplified)",
value: "zh-CN", value: "zh-CN",
progress: 33, progress: 32,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -33,7 +33,7 @@ export const LOCALES = [
{ {
name: "Svenska (Swedish)", name: "Svenska (Swedish)",
value: "sv-SE", value: "sv-SE",
progress: 39, progress: 37,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -45,7 +45,7 @@ export const LOCALES = [
{ {
name: "Slovenščina (Slovenian)", name: "Slovenščina (Slovenian)",
value: "sl-SI", value: "sl-SI",
progress: 39, progress: 37,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -93,7 +93,7 @@ export const LOCALES = [
{ {
name: "Nederlands (Dutch)", name: "Nederlands (Dutch)",
value: "nl-NL", value: "nl-NL",
progress: 39, progress: 37,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -159,7 +159,7 @@ export const LOCALES = [
{ {
name: "Français (French)", name: "Français (French)",
value: "fr-FR", value: "fr-FR",
progress: 38, progress: 37,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -213,7 +213,7 @@ export const LOCALES = [
{ {
name: "Deutsch (German)", name: "Deutsch (German)",
value: "de-DE", value: "de-DE",
progress: 46, progress: 37,
dir: "ltr", dir: "ltr",
}, },
{ {
@@ -252,4 +252,4 @@ export const LOCALES = [
progress: 26, progress: 26,
dir: "ltr", dir: "ltr",
}, },
]; ]

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Grootmaat-URL-invoer", "bulk-url-import": "Grootmaat-URL-invoer",
"debug-scraper": "Debug skraper", "debug-scraper": "Debug skraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Skep 'n resep deur dit 'n naam te gee. Alle resepte moet unieke name hê.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Skep 'n resep deur dit 'n naam te gee. Alle resepte moet unieke name hê.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "إنشاء وصفة عن طريق صورة", "create-recipe-from-an-image": "إنشاء وصفة عن طريق صورة",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "إنشاء عن طريق صورة",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "الاستيراد باستخدام أكثر من URL ", "bulk-url-import": "الاستيراد باستخدام أكثر من URL ",
"debug-scraper": "تصحيح أخطاء المحلل\n", "debug-scraper": "تصحيح أخطاء المحلل\n",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.",
@@ -661,10 +660,7 @@
"no-food": "لا يوجد طعام" "no-food": "لا يوجد طعام"
}, },
"reset-servings-count": "إعادة تعيين عدد الحصص", "reset-servings-count": "إعادة تعيين عدد الحصص",
"not-linked-ingredients": "مكونات إضافية", "not-linked-ingredients": "مكونات إضافية"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "البحث عن الوصفات", "recipe-finder": "البحث عن الوصفات",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Импортиране на рецепти от линк", "bulk-url-import": "Импортиране на рецепти от линк",
"debug-scraper": "Отстраняване на грешки на скрейпъра", "debug-scraper": "Отстраняване на грешки на скрейпъра",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Добави рецепта като предоставиш име. Всички рецепти трябва да имат уникални имена.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Добави рецепта като предоставиш име. Всички рецепти трябва да имат уникални имена.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Crear una recepta a partir d'una imatge", "create-recipe-from-an-image": "Crear una recepta a partir d'una imatge",
"create-recipe-from-an-image-description": "Crear una recepta pujant una imatge d'ella. Mealie intentarà extreure el text de la imatge mitjançant IA i crear-ne la recepta.", "create-recipe-from-an-image-description": "Crear una recepta pujant una imatge d'ella. Mealie intentarà extreure el text de la imatge mitjançant IA i crear-ne la recepta.",
"crop-and-rotate-the-image": "Retalla i rota la imatge, per tal que només el text sigui visible, i estigui orientat correctament.", "crop-and-rotate-the-image": "Retalla i rota la imatge, per tal que només el text sigui visible, i estigui orientat correctament.",
"create-from-images": "Create from Images", "create-from-image": "Crear des d'una imatge",
"should-translate-description": "Tradueix la recepta a la meva llengua", "should-translate-description": "Tradueix la recepta a la meva llengua",
"please-wait-image-procesing": "Si us plau, esperi, la imatge s'està processant. Això pot tardar un temps.", "please-wait-image-procesing": "Si us plau, esperi, la imatge s'està processant. Això pot tardar un temps.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importació d'URL en massa", "bulk-url-import": "Importació d'URL en massa",
"debug-scraper": "Rastrejador de depuració", "debug-scraper": "Rastrejador de depuració",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crea la recepta proporcionant-ne un nom. Totes les receptes han de tenir un nom únic.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crea la recepta proporcionant-ne un nom. Totes les receptes han de tenir un nom únic.",
@@ -661,10 +660,7 @@
"no-food": "Sense menjar" "no-food": "Sense menjar"
}, },
"reset-servings-count": "Reiniciar racions servides", "reset-servings-count": "Reiniciar racions servides",
"not-linked-ingredients": "Ingredients addicionals", "not-linked-ingredients": "Ingredients addicionals"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Cercador de receptes", "recipe-finder": "Cercador de receptes",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Vytvořit recept z obrázku", "create-recipe-from-an-image": "Vytvořit recept z obrázku",
"create-recipe-from-an-image-description": "Vytvořte recept nahráním obrázku. Mealie se pokusí z obrázku extrahovat text pomocí AI a vytvořit z něj recept.", "create-recipe-from-an-image-description": "Vytvořte recept nahráním obrázku. Mealie se pokusí z obrázku extrahovat text pomocí AI a vytvořit z něj recept.",
"crop-and-rotate-the-image": "Oříznout a otočit obrázek tak, aby byl viditelný pouze text a aby byl ve správné orientaci.", "crop-and-rotate-the-image": "Oříznout a otočit obrázek tak, aby byl viditelný pouze text a aby byl ve správné orientaci.",
"create-from-images": "Create from Images", "create-from-image": "Vytvořit z obrázku",
"should-translate-description": "Přeložit recept do mého jazyka", "should-translate-description": "Přeložit recept do mého jazyka",
"please-wait-image-procesing": "Počkejte prosím, obrázek se zpracovává. Může to chvíli trvat.", "please-wait-image-procesing": "Počkejte prosím, obrázek se zpracovává. Může to chvíli trvat.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Hromadný import adres URL", "bulk-url-import": "Hromadný import adres URL",
"debug-scraper": "Ladící Scraper", "debug-scraper": "Ladící Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Vytvořte recept zadáním názvu. Všechny recepty musí mít jedinečná jména.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Vytvořte recept zadáním názvu. Všechny recepty musí mít jedinečná jména.",
@@ -661,10 +660,7 @@
"no-food": "Žádné jídlo" "no-food": "Žádné jídlo"
}, },
"reset-servings-count": "Resetovat počet porcí", "reset-servings-count": "Resetovat počet porcí",
"not-linked-ingredients": "Další ingredience", "not-linked-ingredients": "Další ingredience"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Vyhledávač receptů", "recipe-finder": "Vyhledávač receptů",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Opret opskrift fra et billede", "create-recipe-from-an-image": "Opret opskrift fra et billede",
"create-recipe-from-an-image-description": "Opret en opskrift ved at overføre et billede af den. Mealie vil forsøge at udtrække teksten fra billedet med AI og oprette en opskrift fra det.", "create-recipe-from-an-image-description": "Opret en opskrift ved at overføre et billede af den. Mealie vil forsøge at udtrække teksten fra billedet med AI og oprette en opskrift fra det.",
"crop-and-rotate-the-image": "Beskær og roter billedet, så kun teksten er synlig, og det vises i den rigtige retning.", "crop-and-rotate-the-image": "Beskær og roter billedet, så kun teksten er synlig, og det vises i den rigtige retning.",
"create-from-images": "Create from Images", "create-from-image": "Opret fra billede",
"should-translate-description": "Oversæt opskriften til mit sprog", "should-translate-description": "Oversæt opskriften til mit sprog",
"please-wait-image-procesing": "Vent venligst, billedet behandles. Dette kan tage lidt tid.", "please-wait-image-procesing": "Vent venligst, billedet behandles. Dette kan tage lidt tid.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Import fra flere URL-adresser", "bulk-url-import": "Import fra flere URL-adresser",
"debug-scraper": "Fejlsøg indlæser", "debug-scraper": "Fejlsøg indlæser",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Opret en opskrift ved at angive navnet. Alle opskrifter skal have unikke navne.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Opret en opskrift ved at angive navnet. Alle opskrifter skal have unikke navne.",
@@ -661,10 +660,7 @@
"no-food": "Ingen fødevarer" "no-food": "Ingen fødevarer"
}, },
"reset-servings-count": "Nulstil antal serveringer", "reset-servings-count": "Nulstil antal serveringer",
"not-linked-ingredients": "Yderligere ingredienser", "not-linked-ingredients": "Yderligere ingredienser"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Opskriftssøger", "recipe-finder": "Opskriftssøger",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Rezept von einem Bild erstellen", "create-recipe-from-an-image": "Rezept von einem Bild erstellen",
"create-recipe-from-an-image-description": "Erstelle ein Rezept, indem du ein Bild hochlädst. Mealie wird versuchen, den Text aus dem Bild mit Hilfe von KI zu extrahieren und ein Rezept daraus zu erstellen.", "create-recipe-from-an-image-description": "Erstelle ein Rezept, indem du ein Bild hochlädst. Mealie wird versuchen, den Text aus dem Bild mit Hilfe von KI zu extrahieren und ein Rezept daraus zu erstellen.",
"crop-and-rotate-the-image": "Beschneide und drehe das Bild so, dass nur der Text zu sehen ist und die Ausrichtung stimmt.", "crop-and-rotate-the-image": "Beschneide und drehe das Bild so, dass nur der Text zu sehen ist und die Ausrichtung stimmt.",
"create-from-images": "Aus Bildern erstellen", "create-from-image": "Vom Bild erstellen",
"should-translate-description": "Übersetze das Rezept in meine Sprache", "should-translate-description": "Übersetze das Rezept in meine Sprache",
"please-wait-image-procesing": "Warte bitte, das Bild wird gerade bearbeitet. Dies kann einige Zeit dauern.", "please-wait-image-procesing": "Warte bitte, das Bild wird gerade bearbeitet. Dies kann einige Zeit dauern.",
"please-wait-images-processing": "Bitte warten, die Bilder werden verarbeitet. Dies kann einige Zeit dauern.",
"bulk-url-import": "URL Massenimport", "bulk-url-import": "URL Massenimport",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Erstelle ein Rezept, indem du den Namen angibst. Alle Rezepte müssen eindeutige Namen haben.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Erstelle ein Rezept, indem du den Namen angibst. Alle Rezepte müssen eindeutige Namen haben.",
@@ -661,10 +660,7 @@
"no-food": "Kein Lebensmittel" "no-food": "Kein Lebensmittel"
}, },
"reset-servings-count": "Portionen zurücksetzen", "reset-servings-count": "Portionen zurücksetzen",
"not-linked-ingredients": "Zusätzliche Zutaten", "not-linked-ingredients": "Zusätzliche Zutaten"
"upload-another-image": "Weiteres Bild hochladen",
"upload-images": "Bilder hochladen",
"upload-more-images": "Weitere Bilder hochladen"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Rezept-Suche", "recipe-finder": "Rezept-Suche",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Δημιουργία συνταγής από μια εικόνα", "create-recipe-from-an-image": "Δημιουργία συνταγής από μια εικόνα",
"create-recipe-from-an-image-description": "Δημιουργήστε μια συνταγή ανεβάζοντας μια εικόνα της. Το Mealie θα προσπαθήσει να εξάγει το κείμενο από την εικόνα χρησιμοποιώντας τεχνητή νοημοσύνη και να δημιουργήσει μια συνταγή από αυτό.", "create-recipe-from-an-image-description": "Δημιουργήστε μια συνταγή ανεβάζοντας μια εικόνα της. Το Mealie θα προσπαθήσει να εξάγει το κείμενο από την εικόνα χρησιμοποιώντας τεχνητή νοημοσύνη και να δημιουργήσει μια συνταγή από αυτό.",
"crop-and-rotate-the-image": "Περικοπή και περιστροφή της εικόνας, έτσι ώστε να είναι μόνο το κείμενο ορατό και να είναι στο σωστό προσανατολισμό.", "crop-and-rotate-the-image": "Περικοπή και περιστροφή της εικόνας, έτσι ώστε να είναι μόνο το κείμενο ορατό και να είναι στο σωστό προσανατολισμό.",
"create-from-images": "Δημιουργία από εικόνες", "create-from-image": "Δημιουργία από εικόνα",
"should-translate-description": "Μετάφραση της συνταγής στη γλώσσα μου", "should-translate-description": "Μετάφραση της συνταγής στη γλώσσα μου",
"please-wait-image-procesing": "Παρακαλώ περιμένετε, η εικόνα είναι υπό επεξεργασία. Αυτό μπορεί να πάρει κάποιο χρόνο.", "please-wait-image-procesing": "Παρακαλώ περιμένετε, η εικόνα είναι υπό επεξεργασία. Αυτό μπορεί να πάρει κάποιο χρόνο.",
"please-wait-images-processing": "Παρακαλώ περιμένετε, οι εικόνες επεξεργάζονται. Αυτό μπορεί να πάρει κάποιο χρόνο.",
"bulk-url-import": "Μαζική Εισαγωγή URL", "bulk-url-import": "Μαζική Εισαγωγή URL",
"debug-scraper": "Εντοπισμός σφαλμάτων scraper", "debug-scraper": "Εντοπισμός σφαλμάτων scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Δημιουργήστε μια συνταγή δίνοντας το όνομα. Ολες οι συνταγές πρέπει να έχουν μοναδικά ονόματα.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Δημιουργήστε μια συνταγή δίνοντας το όνομα. Ολες οι συνταγές πρέπει να έχουν μοναδικά ονόματα.",
@@ -661,10 +660,7 @@
"no-food": "Χωρίς Τρόφιμο" "no-food": "Χωρίς Τρόφιμο"
}, },
"reset-servings-count": "Επαναφορά μέτρησης μερίδων", "reset-servings-count": "Επαναφορά μέτρησης μερίδων",
"not-linked-ingredients": "Πρόσθετα συστατικά", "not-linked-ingredients": "Πρόσθετα συστατικά"
"upload-another-image": "Ανέβασμα άλλης εικόνας",
"upload-images": "Ανέβασμα εικόνων",
"upload-more-images": "Ανέβασμα περισσότερων εικόνων"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Εύρεση συνταγών", "recipe-finder": "Εύρεση συνταγών",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Bulk URL Import", "bulk-url-import": "Bulk URL Import",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Crear receta a partir de una imagen", "create-recipe-from-an-image": "Crear receta a partir de una imagen",
"create-recipe-from-an-image-description": "Crea una receta cargando una imagen de ella. Mealie intentará extraer el texto de la imagen usando IA y crear una receta de ella.", "create-recipe-from-an-image-description": "Crea una receta cargando una imagen de ella. Mealie intentará extraer el texto de la imagen usando IA y crear una receta de ella.",
"crop-and-rotate-the-image": "Recortar y rotar la imagen de manera que sólo el texto sea visible, y esté en la orientación correcta.", "crop-and-rotate-the-image": "Recortar y rotar la imagen de manera que sólo el texto sea visible, y esté en la orientación correcta.",
"create-from-images": "Create from Images", "create-from-image": "Crear desde imagen",
"should-translate-description": "Traducir la receta a mi idioma", "should-translate-description": "Traducir la receta a mi idioma",
"please-wait-image-procesing": "Por favor, espere, la imagen se está procesando. Esto puede tardar un tiempo.", "please-wait-image-procesing": "Por favor, espere, la imagen se está procesando. Esto puede tardar un tiempo.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importación masiva desde URL", "bulk-url-import": "Importación masiva desde URL",
"debug-scraper": "Depurar analizador", "debug-scraper": "Depurar analizador",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crear una receta proporcionando el nombre. Todas las recetas deben tener nombres únicos.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crear una receta proporcionando el nombre. Todas las recetas deben tener nombres únicos.",
@@ -661,10 +660,7 @@
"no-food": "Sin Comida" "no-food": "Sin Comida"
}, },
"reset-servings-count": "Restablecer contador de porciones", "reset-servings-count": "Restablecer contador de porciones",
"not-linked-ingredients": "Ingredientes adicionales", "not-linked-ingredients": "Ingredientes adicionales"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Buscador de recetas", "recipe-finder": "Buscador de recetas",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Retsepti loomine pildist", "create-recipe-from-an-image": "Retsepti loomine pildist",
"create-recipe-from-an-image-description": "Retsepti loomiseks lae üles selle pilt. Mealie üritab ekstraheerida pildil oleva teksti ning luua retsepti sellest kasutades AI-d.", "create-recipe-from-an-image-description": "Retsepti loomiseks lae üles selle pilt. Mealie üritab ekstraheerida pildil oleva teksti ning luua retsepti sellest kasutades AI-d.",
"crop-and-rotate-the-image": "Kärpige ja pöörake pilti nii, et ainult tekst oleks nähtaval ja see oleks suunatud ülespoole.", "crop-and-rotate-the-image": "Kärpige ja pöörake pilti nii, et ainult tekst oleks nähtaval ja see oleks suunatud ülespoole.",
"create-from-images": "Create from Images", "create-from-image": "Pildist loomine",
"should-translate-description": "Tõlgi retsept minu keelde", "should-translate-description": "Tõlgi retsept minu keelde",
"please-wait-image-procesing": "Palun oota, pilti töödeldakse veel. See võib võtta veidi aega.", "please-wait-image-procesing": "Palun oota, pilti töödeldakse veel. See võib võtta veidi aega.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Hulgiimport URL-ist", "bulk-url-import": "Hulgiimport URL-ist",
"debug-scraper": "Otsige Scraperis probleeme", "debug-scraper": "Otsige Scraperis probleeme",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Loo retsept selle nime kasutades. Igal retseptil peab olema unikaalne nimi", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Loo retsept selle nime kasutades. Igal retseptil peab olema unikaalne nimi",
@@ -661,10 +660,7 @@
"no-food": "Toit puudub" "no-food": "Toit puudub"
}, },
"reset-servings-count": "Lähtesta portsionite arv", "reset-servings-count": "Lähtesta portsionite arv",
"not-linked-ingredients": "Lisa-koostisosad", "not-linked-ingredients": "Lisa-koostisosad"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Retsepti otsing", "recipe-finder": "Retsepti otsing",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Luo resepti kuvasta", "create-recipe-from-an-image": "Luo resepti kuvasta",
"create-recipe-from-an-image-description": "Luo resepti tuomalla siitä kuva. Mealie pyrkii poimimaan tekstin kuvasta tekoälyllä ja luomaan siitä reseptin.", "create-recipe-from-an-image-description": "Luo resepti tuomalla siitä kuva. Mealie pyrkii poimimaan tekstin kuvasta tekoälyllä ja luomaan siitä reseptin.",
"crop-and-rotate-the-image": "Rajaa ja kierrä kuvaa niin, että vain teksti näkyy, ja että se on oikein päin.", "crop-and-rotate-the-image": "Rajaa ja kierrä kuvaa niin, että vain teksti näkyy, ja että se on oikein päin.",
"create-from-images": "Create from Images", "create-from-image": "Luo kuvasta",
"should-translate-description": "Käännä resepti kielelleni", "should-translate-description": "Käännä resepti kielelleni",
"please-wait-image-procesing": "Odota, että kuva käsitellään. Tämä voi kestää hetken.", "please-wait-image-procesing": "Odota, että kuva käsitellään. Tämä voi kestää hetken.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Massa tuonti URL-osoitteesta", "bulk-url-import": "Massa tuonti URL-osoitteesta",
"debug-scraper": "Etsi ongelmia Scraperista", "debug-scraper": "Etsi ongelmia Scraperista",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Luo resepti antamalla nimi. Kaikilla resepteillä on oltava yksilölliset nimet.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Luo resepti antamalla nimi. Kaikilla resepteillä on oltava yksilölliset nimet.",
@@ -661,10 +660,7 @@
"no-food": "Ei ruokaa" "no-food": "Ei ruokaa"
}, },
"reset-servings-count": "Palauta Annoksien Määrä", "reset-servings-count": "Palauta Annoksien Määrä",
"not-linked-ingredients": "Muut ainesosat", "not-linked-ingredients": "Muut ainesosat"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Reseptin etsijä", "recipe-finder": "Reseptin etsijä",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Créer une recette à partir dune image", "create-recipe-from-an-image": "Créer une recette à partir dune image",
"create-recipe-from-an-image-description": "Créez une recette en téléchargeant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.", "create-recipe-from-an-image-description": "Créez une recette en téléchargeant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.",
"crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible, et quil soit dans la bonne orientation.", "crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible, et quil soit dans la bonne orientation.",
"create-from-images": "Create from Images", "create-from-image": "Créer à partir dune image",
"should-translate-description": "Traduire la recette dans ma langue", "should-translate-description": "Traduire la recette dans ma langue",
"please-wait-image-procesing": "Veuillez patienter, limage est en cours de traitement. Cela peut prendre du temps.", "please-wait-image-procesing": "Veuillez patienter, limage est en cours de traitement. Cela peut prendre du temps.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importation en masse d'URL", "bulk-url-import": "Importation en masse d'URL",
"debug-scraper": "Déboguer le récupérateur", "debug-scraper": "Déboguer le récupérateur",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.",
@@ -661,10 +660,7 @@
"no-food": "Aucun aliment" "no-food": "Aucun aliment"
}, },
"reset-servings-count": "Réinitialiser le nombre de portions", "reset-servings-count": "Réinitialiser le nombre de portions",
"not-linked-ingredients": "Ingrédients supplémentaires", "not-linked-ingredients": "Ingrédients supplémentaires"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recherche de recette", "recipe-finder": "Recherche de recette",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Créer une recette à partir dune image", "create-recipe-from-an-image": "Créer une recette à partir dune image",
"create-recipe-from-an-image-description": "Créez une recette en téléversant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.", "create-recipe-from-an-image-description": "Créez une recette en téléversant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.",
"crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible et quil soit dans la bonne orientation.", "crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible et quil soit dans la bonne orientation.",
"create-from-images": "Create from Images", "create-from-image": "Créer à partir dune image",
"should-translate-description": "Traduire la recette dans ma langue", "should-translate-description": "Traduire la recette dans ma langue",
"please-wait-image-procesing": "Veuillez patienter, l'image est en cours de traitement. Cela peut prendre un certain temps.", "please-wait-image-procesing": "Veuillez patienter, l'image est en cours de traitement. Cela peut prendre un certain temps.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importation en masse d'URL", "bulk-url-import": "Importation en masse d'URL",
"debug-scraper": "Déboguer le récupérateur", "debug-scraper": "Déboguer le récupérateur",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.",
@@ -661,10 +660,7 @@
"no-food": "Aucun aliment" "no-food": "Aucun aliment"
}, },
"reset-servings-count": "Réinitialiser le nombre de portions", "reset-servings-count": "Réinitialiser le nombre de portions",
"not-linked-ingredients": "Ingrédients supplémentaires", "not-linked-ingredients": "Ingrédients supplémentaires"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recherche de recette", "recipe-finder": "Recherche de recette",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Créer une recette à partir dune image", "create-recipe-from-an-image": "Créer une recette à partir dune image",
"create-recipe-from-an-image-description": "Créez une recette en téléchargeant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.", "create-recipe-from-an-image-description": "Créez une recette en téléchargeant une image de celle-ci. Mealie utilisera lIA pour tenter dextraire le texte et de créer une recette.",
"crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible, et quil soit dans la bonne orientation.", "crop-and-rotate-the-image": "Rogner et pivoter limage pour que seul le texte soit visible, et quil soit dans la bonne orientation.",
"create-from-images": "Create from Images", "create-from-image": "Créer à partir dune image",
"should-translate-description": "Traduire la recette dans ma langue", "should-translate-description": "Traduire la recette dans ma langue",
"please-wait-image-procesing": "Veuillez patienter, limage est en cours de traitement. Cela peut prendre du temps.", "please-wait-image-procesing": "Veuillez patienter, limage est en cours de traitement. Cela peut prendre du temps.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importation en masse d'URL", "bulk-url-import": "Importation en masse d'URL",
"debug-scraper": "Déboguer le récupérateur", "debug-scraper": "Déboguer le récupérateur",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Créer une recette en fournissant le nom. Toutes les recettes doivent avoir des noms uniques.",
@@ -661,10 +660,7 @@
"no-food": "Aucun aliment" "no-food": "Aucun aliment"
}, },
"reset-servings-count": "Réinitialiser le nombre de portions", "reset-servings-count": "Réinitialiser le nombre de portions",
"not-linked-ingredients": "Ingrédients supplémentaires", "not-linked-ingredients": "Ingrédients supplémentaires"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recherche de recette", "recipe-finder": "Recherche de recette",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Crear receita a partir dunha imaxen", "create-recipe-from-an-image": "Crear receita a partir dunha imaxen",
"create-recipe-from-an-image-description": "Cree unha receita cargando unha imaxen da mesma. O Mealie tentará extrair o texto da imaxen utilizando IA e creará unha receita a partir da mesma.", "create-recipe-from-an-image-description": "Cree unha receita cargando unha imaxen da mesma. O Mealie tentará extrair o texto da imaxen utilizando IA e creará unha receita a partir da mesma.",
"crop-and-rotate-the-image": "Recorte e vire a imaxen de modo a que só o texto sexa visível e na orientación correta.", "crop-and-rotate-the-image": "Recorte e vire a imaxen de modo a que só o texto sexa visível e na orientación correta.",
"create-from-images": "Crear a partir de imaxens", "create-from-image": "Crear a partir da imaxen",
"should-translate-description": "Traducir a receita para a miña língua", "should-translate-description": "Traducir a receita para a miña língua",
"please-wait-image-procesing": "Por favor agarde, a imaxen está sendo procesada. Isto pode levar algun tempo.", "please-wait-image-procesing": "Por favor agarde, a imaxen está sendo procesada. Isto pode levar algun tempo.",
"please-wait-images-processing": "Por favor agarde, as imaxens están a ser procesadas. Isto pode levar algún tempo.",
"bulk-url-import": "Importación de URL en Masa", "bulk-url-import": "Importación de URL en Masa",
"debug-scraper": "Depurar Scraper", "debug-scraper": "Depurar Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Cree unha receita introducindo o nome. Todas as receitas deven ter nomes únicos.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Cree unha receita introducindo o nome. Todas as receitas deven ter nomes únicos.",
@@ -661,10 +660,7 @@
"no-food": "Sen Comida" "no-food": "Sen Comida"
}, },
"reset-servings-count": "Reiniciar Contador de Porcións", "reset-servings-count": "Reiniciar Contador de Porcións",
"not-linked-ingredients": "Ingredientes Adicionais", "not-linked-ingredients": "Ingredientes Adicionais"
"upload-another-image": "Cargar outra imaxen",
"upload-images": "Cargar imaxens",
"upload-more-images": "Cargar mais imaxens"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Localizador de Receitas", "recipe-finder": "Localizador de Receitas",

View File

@@ -45,7 +45,7 @@
"category-filter": "סינון קטגוריות", "category-filter": "סינון קטגוריות",
"category-update-failed": "עדכון קטגוריה נכשל", "category-update-failed": "עדכון קטגוריה נכשל",
"category-updated": "קטגוריה עודכנה", "category-updated": "קטגוריה עודכנה",
"uncategorized-count": "{count} לא קיבלו קטגוריה", "uncategorized-count": "{count} לא קוטלגו",
"create-a-category": "יצירת קטגוריה", "create-a-category": "יצירת קטגוריה",
"category-name": "שם קטגוריה", "category-name": "שם קטגוריה",
"category": "קטגוריה" "category": "קטגוריה"
@@ -60,17 +60,17 @@
"new-notification-form-description": "Mקשךןק עושה שימוש בספריה בשם Apprise לשליחת התראות. Apprise מציעה אפשרויות רבות עבור התראות לבעלי שירותים. פנה לאתר הWiki של Apprise להסבר מלא על יצירת לינקים לשירות שלך.", "new-notification-form-description": "Mקשךןק עושה שימוש בספריה בשם Apprise לשליחת התראות. Apprise מציעה אפשרויות רבות עבור התראות לבעלי שירותים. פנה לאתר הWiki של Apprise להסבר מלא על יצירת לינקים לשירות שלך.",
"new-version": "גרסה חדשה זמינה!", "new-version": "גרסה חדשה זמינה!",
"notification": "התראה", "notification": "התראה",
"refresh": "רענון", "refresh": "רענן",
"scheduled": "מתוזמן", "scheduled": "מתוזמן",
"something-went-wrong": "משהו השתבש!", "something-went-wrong": "משהו השתבש!",
"subscribed-events": "אירועים שנרשמת אליהם", "subscribed-events": "אירועים שנרשמת אליהם",
"test-message-sent": "הודעת בדיקה נשלחה", "test-message-sent": "הודעת בדיקה נשלחה",
"message-sent": "ההודעה נשלחה", "message-sent": "ההודעה נשלחה",
"new-notification": "התראה חדשה", "new-notification": "התראה חדשה",
"event-notifiers": "מנגנוני התרעה על אירועים", "event-notifiers": "אירועי נוטיפיקציות",
"apprise-url-skipped-if-blank": "כתובת Apprise (דלג אם ריק)", "apprise-url-skipped-if-blank": "כתובת Apprise (דלג אם ריק)",
"enable-notifier": "הפעלת מתריע", "enable-notifier": "אישור נוטיפיקציות",
"what-events": "לאילו אירועים לרשום את מתריע זה?", "what-events": "לאילו אירועים להרשם בערוץ התראות זה?",
"user-events": "אירועי משתמש", "user-events": "אירועי משתמש",
"mealplan-events": "אירועי תכנון ארוחות", "mealplan-events": "אירועי תכנון ארוחות",
"when-a-user-in-your-group-creates-a-new-mealplan": "כאשר משתמש בקבוצה שלך יוצר תכנון ארוחות חדש", "when-a-user-in-your-group-creates-a-new-mealplan": "כאשר משתמש בקבוצה שלך יוצר תכנון ארוחות חדש",
@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "יצירת מתכון מתמונה", "create-recipe-from-an-image": "יצירת מתכון מתמונה",
"create-recipe-from-an-image-description": "יצירת מתכון ע\"י העלאת תמונה שלו. Mealie תנסה לחלץ את הטקסט מהתמונה באמצעות AI ותייצר ממנו מתכון.", "create-recipe-from-an-image-description": "יצירת מתכון ע\"י העלאת תמונה שלו. Mealie תנסה לחלץ את הטקסט מהתמונה באמצעות AI ותייצר ממנו מתכון.",
"crop-and-rotate-the-image": "נא לחתוך ולסובב את התמונה כך שרואים רק את הטקסט, והוא בכיוון הנכון.", "crop-and-rotate-the-image": "נא לחתוך ולסובב את התמונה כך שרואים רק את הטקסט, והוא בכיוון הנכון.",
"create-from-images": "יצירה מתמונה", "create-from-image": "יצירה מתמונה",
"should-translate-description": "תרגום המתכון לשפה שלי", "should-translate-description": "תרגום המתכון לשפה שלי",
"please-wait-image-procesing": "נה להמתין, התמונה עוברת עיבוץ. זה יכול לקחת זמן.", "please-wait-image-procesing": "נה להמתין, התמונה עוברת עיבוץ. זה יכול לקחת זמן.",
"please-wait-images-processing": "נא להמתין, מנתח את התמונות. זה יכול לקחת זמן מה.",
"bulk-url-import": "ייבוא מספר לינקים", "bulk-url-import": "ייבוא מספר לינקים",
"debug-scraper": "סורק לניפוי שגיאות", "debug-scraper": "סורק לניפוי שגיאות",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "יצירת מתכון באמצעות שם. כל שמות המתכונים צריכים להיות שונים.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "יצירת מתכון באמצעות שם. כל שמות המתכונים צריכים להיות שונים.",
@@ -661,10 +660,7 @@
"no-food": "אין אוכל" "no-food": "אין אוכל"
}, },
"reset-servings-count": "איפוס מספר המנות", "reset-servings-count": "איפוס מספר המנות",
"not-linked-ingredients": "מרכיבים נוספים", "not-linked-ingredients": "מרכיבים נוספים"
"upload-another-image": "העלאת תמונה נוספת",
"upload-images": "העלאת תמונות",
"upload-more-images": "העלאת תמונות נוספות"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "מצא מתכון", "recipe-finder": "מצא מתכון",
@@ -1342,7 +1338,7 @@
"manage-cookbooks": "ניהול ספרי בישול", "manage-cookbooks": "ניהול ספרי בישול",
"manage-members": "ניהול משתמשים", "manage-members": "ניהול משתמשים",
"manage-webhooks": "ניהול Webhooks", "manage-webhooks": "ניהול Webhooks",
"manage-notifiers": "ניהול מתריעים", "manage-notifiers": "ניהול ערוצי התראות",
"manage-data-migrations": "ניהול מיגרציות מידע" "manage-data-migrations": "ניהול מיגרציות מידע"
}, },
"cookbook": { "cookbook": {

View File

@@ -15,7 +15,7 @@
"docs": "Dokumenti", "docs": "Dokumenti",
"download-log": "Preuzmi zapisnik", "download-log": "Preuzmi zapisnik",
"download-recipe-json": "Posljednji prikupljeni JSON", "download-recipe-json": "Posljednji prikupljeni JSON",
"github": "Github", "github": "GitHub",
"log-lines": "Bilježi zapisnik", "log-lines": "Bilježi zapisnik",
"not-demo": "Nije Demo", "not-demo": "Nije Demo",
"portfolio": "Portfelj", "portfolio": "Portfelj",
@@ -253,9 +253,9 @@
"default-recipe-preferences": "Zadane Postavke Recepata", "default-recipe-preferences": "Zadane Postavke Recepata",
"group-preferences": "Postavke Grupe", "group-preferences": "Postavke Grupe",
"private-group": "Privatna Grupa", "private-group": "Privatna Grupa",
"private-group-description": "Postavljanje tvoje grupe na privatni režim će onemogućiti sve opcije javnog prikaza. To će poništiti bilo koju pojedinačnu postavku za javni prikaz", "private-group-description": "Setting your group to private will disable all public view options. This overrides any individual public view settings",
"enable-public-access": "Dozvoli javni pristup", "enable-public-access": "Enable Public Access",
"enable-public-access-description": "Napravite grupne recepte javnim kao zadanu vrijednost i omogući posjetiteljima pregled recepata bez prijave", "enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
"allow-users-outside-of-your-group-to-see-your-recipes": "Dopustite korisnicima izvan vaše grupe da vide vaše recepte", "allow-users-outside-of-your-group-to-see-your-recipes": "Dopustite korisnicima izvan vaše grupe da vide vaše recepte",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Kada je omogućeno, možete koristiti javnu povezncu dijeljene veze za dijeljenje određenih recepata bez autorizacije korisnika. Kada je onemogućeno, recepte možete dijeliti samo s korisnicima koji su u vašoj grupi ili s prethodno generiranom privatnom vezom", "allow-users-outside-of-your-group-to-see-your-recipes-description": "Kada je omogućeno, možete koristiti javnu povezncu dijeljene veze za dijeljenje određenih recepata bez autorizacije korisnika. Kada je onemogućeno, recepte možete dijeliti samo s korisnicima koji su u vašoj grupi ili s prethodno generiranom privatnom vezom",
"show-nutrition-information": "Prikaži prehrambene vrijednosti", "show-nutrition-information": "Prikaži prehrambene vrijednosti",
@@ -267,36 +267,36 @@
"disable-users-from-commenting-on-recipes": "Onemogući korisnicima da komentiraju recepte", "disable-users-from-commenting-on-recipes": "Onemogući korisnicima da komentiraju recepte",
"disable-users-from-commenting-on-recipes-description": "Skriva sekciju komentara na stranici recepta i onemogućuje komentiranje", "disable-users-from-commenting-on-recipes-description": "Skriva sekciju komentara na stranici recepta i onemogućuje komentiranje",
"disable-organizing-recipe-ingredients-by-units-and-food": "Onemogući organiziranje sastojaka recepata prema jedinicama i namirnicama", "disable-organizing-recipe-ingredients-by-units-and-food": "Onemogući organiziranje sastojaka recepata prema jedinicama i namirnicama",
"disable-organizing-recipe-ingredients-by-units-and-food-description": "Sakriva polja za Hranu, Jedinicu i Količinu za sastojke te tretira sastojke kao obična tekstualna polja", "disable-organizing-recipe-ingredients-by-units-and-food-description": "Hides the Food, Unit, and Amount fields for ingredients and treats ingredients as plain text fields",
"general-preferences": "Opće postavke", "general-preferences": "Opće postavke",
"group-recipe-preferences": "Postavke Recepata Grupe", "group-recipe-preferences": "Postavke Recepata Grupe",
"report": "Izvješće", "report": "Izvješće",
"report-with-id": "ID Izvješća: {id}", "report-with-id": "Report ID: {id}",
"group-management": "Upravljanje Grupom", "group-management": "Upravljanje Grupom",
"admin-group-management": "Upravljanje Grupom od strane Administratora", "admin-group-management": "Upravljanje Grupom od strane Administratora",
"admin-group-management-text": "Promjene u ovoj grupi će se odmah odraziti.", "admin-group-management-text": "Promjene u ovoj grupi će se odmah odraziti.",
"group-id-value": "Id grupe: {0}", "group-id-value": "Id grupe: {0}",
"total-households": "Ukupno kućanstava", "total-households": "Total Households",
"you-must-select-a-group-before-selecting-a-household": "Prije odabira kućanstva morate odabrati grupu" "you-must-select-a-group-before-selecting-a-household": "You must select a group before selecting a household"
}, },
"household": { "household": {
"household": "Domaćinstvo", "household": "Household",
"households": "Domaćinstva", "households": "Households",
"user-household": "Korisničko domaćinstvo", "user-household": "User Household",
"create-household": "Napravi domaćinstvo", "create-household": "Create Household",
"household-name": "Ime domaćinstva", "household-name": "Household Name",
"household-group": "Grupa domaćinstva", "household-group": "Household Group",
"household-management": "Upravitelji domaćinstva", "household-management": "Household Management",
"manage-households": "Upravljanje domaćinstvom", "manage-households": "Manage Households",
"admin-household-management": "Administratorsko upravljanje domaćinstvom", "admin-household-management": "Admin Household Management",
"admin-household-management-text": "Promjene u ovom domaćinstvo će se odraziti odmah.", "admin-household-management-text": "Changes to this household will be reflected immediately.",
"household-id-value": "ID domaćinstva: {0}", "household-id-value": "Household Id: {0}",
"private-household": "Privatno domaćinstvo", "private-household": "Private Household",
"private-household-description": "Postavljanje tvojeg domaćinstva na privatni režim će onemogućiti sve opcije javnog prikaza. To će poništiti bilo koju pojedinačnu postavku za javni prikaz", "private-household-description": "Setting your household to private will disable all public view options. This overrides any individual public view settings",
"lock-recipe-edits-from-other-households": "Onemogućite izmjene recepata iz drugih domaćinstva", "lock-recipe-edits-from-other-households": "Lock recipe edits from other households",
"lock-recipe-edits-from-other-households-description": "Kada je omogućeno, samo korisnici u tvojem domaćinstvu mogu uređivati recepte izrađene u tvojem domaćinstvu", "lock-recipe-edits-from-other-households-description": "When enabled only users in your household can edit recipes created by your household",
"household-recipe-preferences": "Postavke recepata u domaćinstvu", "household-recipe-preferences": "Household Recipe Preferences",
"default-recipe-preferences-description": "Ovo su zadane postavke, kada se u tvojem domaćinstvu izradi novi recept. Ove postavke se mogu promijeniti za pojedinačne recepte u izborniku postavki recepata.", "default-recipe-preferences-description": "These are the default settings when a new recipe is created in your household. These can be changed for individual recipes in the recipe settings menu.",
"allow-users-outside-of-your-household-to-see-your-recipes": "Allow users outside of your household to see your recipes", "allow-users-outside-of-your-household-to-see-your-recipes": "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": "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",
"household-preferences": "Household Preferences" "household-preferences": "Household Preferences"
@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Uvoz više URL-ova", "bulk-url-import": "Uvoz više URL-ova",
"debug-scraper": "Debugiranje skraper-a", "debug-scraper": "Debugiranje skraper-a",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Kreirajte recept pružajući naziv. Svi recepti moraju imati jedinstvena imena.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Kreirajte recept pružajući naziv. Svi recepti moraju imati jedinstvena imena.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Recept készítése képről", "create-recipe-from-an-image": "Recept készítése képről",
"create-recipe-from-an-image-description": "Hozzon létre egy receptet egy kép feltöltésével. A Mealie megpróbálja a kép szövegét mesterséges intelligencia segítségével kinyerni, és létrehozni belőle a receptet.", "create-recipe-from-an-image-description": "Hozzon létre egy receptet egy kép feltöltésével. A Mealie megpróbálja a kép szövegét mesterséges intelligencia segítségével kinyerni, és létrehozni belőle a receptet.",
"crop-and-rotate-the-image": "Vágja ki és forgassa el a képet úgy, hogy csak a szöveg legyen látható, és megfelelő tájolásban legyen.", "crop-and-rotate-the-image": "Vágja ki és forgassa el a képet úgy, hogy csak a szöveg legyen látható, és megfelelő tájolásban legyen.",
"create-from-images": "Létrehozás képekről", "create-from-image": "Létrehozás képről",
"should-translate-description": "Fordítsa le a receptet a saját nyelvemre", "should-translate-description": "Fordítsa le a receptet a saját nyelvemre",
"please-wait-image-procesing": "Kérjük várjon, a kép feldolgozása folyamatban van. Ez eltarthat egy ideig.", "please-wait-image-procesing": "Kérjük várjon, a kép feldolgozása folyamatban van. Ez eltarthat egy ideig.",
"please-wait-images-processing": "Kérjük várjon, a képek feldolgozása folyamatban van. Ez eltarthat egy ideig.",
"bulk-url-import": "Tömeges URL importálás", "bulk-url-import": "Tömeges URL importálás",
"debug-scraper": "Hibakeresés az adatkinyerőben", "debug-scraper": "Hibakeresés az adatkinyerőben",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Hozzon létre egy receptet a név megadásával. Minden receptnek egyedi névvel kell rendelkeznie.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Hozzon létre egy receptet a név megadásával. Minden receptnek egyedi névvel kell rendelkeznie.",
@@ -661,10 +660,7 @@
"no-food": "Élelmiszer nélküli" "no-food": "Élelmiszer nélküli"
}, },
"reset-servings-count": "Adagok számának visszaállítása", "reset-servings-count": "Adagok számának visszaállítása",
"not-linked-ingredients": "Kiegészítő hozzávalók", "not-linked-ingredients": "Kiegészítő hozzávalók"
"upload-another-image": "Másik kép feltöltése",
"upload-images": "Képek feltöltése",
"upload-more-images": "További képek feltöltése"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Receptkereső", "recipe-finder": "Receptkereső",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Bulk URL Import", "bulk-url-import": "Bulk URL Import",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Crea ricetta da un'immagine", "create-recipe-from-an-image": "Crea ricetta da un'immagine",
"create-recipe-from-an-image-description": "Crea una ricetta caricando un'immagine di essa. Mealie tenterà di estrarre il testo dall'immagine usando l'IA e creare una ricetta da esso.", "create-recipe-from-an-image-description": "Crea una ricetta caricando un'immagine di essa. Mealie tenterà di estrarre il testo dall'immagine usando l'IA e creare una ricetta da esso.",
"crop-and-rotate-the-image": "Ritaglia e ruota l'immagine in modo che solo il testo sia visibile e che sia orientato correttamente.", "crop-and-rotate-the-image": "Ritaglia e ruota l'immagine in modo che solo il testo sia visibile e che sia orientato correttamente.",
"create-from-images": "Create from Images", "create-from-image": "Crea da Immagine",
"should-translate-description": "Traduci la ricetta nella mia lingua", "should-translate-description": "Traduci la ricetta nella mia lingua",
"please-wait-image-procesing": "Attendere, l'immagine è in fase di elaborazione. Potrebbe volerci un po' di tempo.", "please-wait-image-procesing": "Attendere, l'immagine è in fase di elaborazione. Potrebbe volerci un po' di tempo.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importazione multipla URL", "bulk-url-import": "Importazione multipla URL",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crea una ricetta fornendo il nome. Tutte le ricette devono avere nomi univoci.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crea una ricetta fornendo il nome. Tutte le ricette devono avere nomi univoci.",
@@ -661,10 +660,7 @@
"no-food": "Nessun Alimento" "no-food": "Nessun Alimento"
}, },
"reset-servings-count": "Reimposta conteggio porzioni", "reset-servings-count": "Reimposta conteggio porzioni",
"not-linked-ingredients": "Ingredienti Aggiuntivi", "not-linked-ingredients": "Ingredienti Aggiuntivi"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Trova ricette", "recipe-finder": "Trova ricette",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "画像からレシピを作成", "create-recipe-from-an-image": "画像からレシピを作成",
"create-recipe-from-an-image-description": "画像をアップロードしてレシピを作成します。 Mealieは、AIを使用して画像からテキストを抽出し、そこからレシピを作成しようとします。", "create-recipe-from-an-image-description": "画像をアップロードしてレシピを作成します。 Mealieは、AIを使用して画像からテキストを抽出し、そこからレシピを作成しようとします。",
"crop-and-rotate-the-image": "テキストのみが表示され、正しい方向になるように画像をトリミングして回転します。", "crop-and-rotate-the-image": "テキストのみが表示され、正しい方向になるように画像をトリミングして回転します。",
"create-from-images": "Create from Images", "create-from-image": "画像から作成",
"should-translate-description": "レシピを自分の言語に翻訳", "should-translate-description": "レシピを自分の言語に翻訳",
"please-wait-image-procesing": "しばらくお待ちください。画像は処理中です。時間がかかる場合があります。", "please-wait-image-procesing": "しばらくお待ちください。画像は処理中です。時間がかかる場合があります。",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "URL 一括インポート", "bulk-url-import": "URL 一括インポート",
"debug-scraper": "デバッグスクレーパー", "debug-scraper": "デバッグスクレーパー",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "名前を指定してレシピを作成します。すべてのレシピには固有の名前が必要です。", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "名前を指定してレシピを作成します。すべてのレシピには固有の名前が必要です。",
@@ -661,10 +660,7 @@
"no-food": "食材はありません" "no-food": "食材はありません"
}, },
"reset-servings-count": "サービング数をリセット", "reset-servings-count": "サービング数をリセット",
"not-linked-ingredients": "追加の材料", "not-linked-ingredients": "追加の材料"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "レシピ検索", "recipe-finder": "レシピ検索",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Bulk URL Import", "bulk-url-import": "Bulk URL Import",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Create a recipe by providing the name. All recipes must have unique names.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Create from Image",
"should-translate-description": "Translate the recipe into my language", "should-translate-description": "Translate the recipe into my language",
"please-wait-image-procesing": "Please wait, the image is processing. This may take some time.", "please-wait-image-procesing": "Please wait, the image is processing. This may take some time.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Masinis URL importavimas", "bulk-url-import": "Masinis URL importavimas",
"debug-scraper": "Ieškoti nuskaitymo klaidų", "debug-scraper": "Ieškoti nuskaitymo klaidų",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Sukurti receptą įrašant pavadinimą. Visi receptai privalo turėti unikalius pavadinimus.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Sukurti receptą įrašant pavadinimą. Visi receptai privalo turėti unikalius pavadinimus.",
@@ -661,10 +660,7 @@
"no-food": "No Food" "no-food": "No Food"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Izveidojiet recepti no attēla", "create-recipe-from-an-image": "Izveidojiet recepti no attēla",
"create-recipe-from-an-image-description": "Izveidojiet recepti, augšupielādējot tās attēlu. Mealie mēģinās iegūt tekstu no attēla, izmantojot AI, un no tā izveidot recepti.", "create-recipe-from-an-image-description": "Izveidojiet recepti, augšupielādējot tās attēlu. Mealie mēģinās iegūt tekstu no attēla, izmantojot AI, un no tā izveidot recepti.",
"crop-and-rotate-the-image": "Apgrieziet un pagrieziet attēlu tā, lai būtu redzams tikai teksts un tas būtu pareizajā orientācijā.", "crop-and-rotate-the-image": "Apgrieziet un pagrieziet attēlu tā, lai būtu redzams tikai teksts un tas būtu pareizajā orientācijā.",
"create-from-images": "Create from Images", "create-from-image": "Izveidot no attēla",
"should-translate-description": "Tulkojiet recepti manā valodā", "should-translate-description": "Tulkojiet recepti manā valodā",
"please-wait-image-procesing": "Lūdzu, pagaidiet, attēls tiek apstrādāts. Tas var aizņemt kādu laiku.", "please-wait-image-procesing": "Lūdzu, pagaidiet, attēls tiek apstrādāts. Tas var aizņemt kādu laiku.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Lielapjoma URL importēšana", "bulk-url-import": "Lielapjoma URL importēšana",
"debug-scraper": "Atkļūdošanas skrāpis", "debug-scraper": "Atkļūdošanas skrāpis",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Izveidojiet recepti, norādot nosaukumu. Visām receptēm jābūt unikāliem nosaukumiem.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Izveidojiet recepti, norādot nosaukumu. Visām receptēm jābūt unikāliem nosaukumiem.",
@@ -661,10 +660,7 @@
"no-food": "Nav pārtikas" "no-food": "Nav pārtikas"
}, },
"reset-servings-count": "Atiestatīt porciju skaitu", "reset-servings-count": "Atiestatīt porciju skaitu",
"not-linked-ingredients": "Additional Ingredients", "not-linked-ingredients": "Additional Ingredients"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recipe Finder", "recipe-finder": "Recipe Finder",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Maak recept van de tekst op een afbeelding", "create-recipe-from-an-image": "Maak recept van de tekst op een afbeelding",
"create-recipe-from-an-image-description": "Maak een recept door een afbeelding ervan te uploaden. Mealie probeert de tekst met behulp van AI uit de afbeelding te halen en er een recept uit te maken.", "create-recipe-from-an-image-description": "Maak een recept door een afbeelding ervan te uploaden. Mealie probeert de tekst met behulp van AI uit de afbeelding te halen en er een recept uit te maken.",
"crop-and-rotate-the-image": "Snijd de afbeelding bij zodat alleen tekst zichtbaar is. En draai t plaatje zodat het leesbaar is.", "crop-and-rotate-the-image": "Snijd de afbeelding bij zodat alleen tekst zichtbaar is. En draai t plaatje zodat het leesbaar is.",
"create-from-images": "Maak recept van een afbeelding", "create-from-image": "Maken vanuit afbeelding",
"should-translate-description": "Vertaal het recept in mijn taal", "should-translate-description": "Vertaal het recept in mijn taal",
"please-wait-image-procesing": "Even wachten. Mealie verwerkt de afbeelding. Dit kan even duren.", "please-wait-image-procesing": "Even wachten. Mealie verwerkt de afbeelding. Dit kan even duren.",
"please-wait-images-processing": "Even wachten. Mealie verwerkt de afbeelding. Dit kan even duren.",
"bulk-url-import": "URL-import in bulk", "bulk-url-import": "URL-import in bulk",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Maak een recept door het een naam te geven. Alle recepten moeten unieke namen hebben.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Maak een recept door het een naam te geven. Alle recepten moeten unieke namen hebben.",
@@ -661,10 +660,7 @@
"no-food": "Geen levensmiddel" "no-food": "Geen levensmiddel"
}, },
"reset-servings-count": "Zet de teller van aantal keer gegeten op nul", "reset-servings-count": "Zet de teller van aantal keer gegeten op nul",
"not-linked-ingredients": "Extra ingrediënten", "not-linked-ingredients": "Extra ingrediënten"
"upload-another-image": "Een andere afbeelding uploaden",
"upload-images": "Afbeelding uploaden",
"upload-more-images": "Meer afbeeldingen uploaden"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Recept zoeker", "recipe-finder": "Recept zoeker",

View File

@@ -323,8 +323,8 @@
"mealplan-updated": "Måltidsplan oppdatert", "mealplan-updated": "Måltidsplan oppdatert",
"mealplan-households-description": "Hvis ingen husholdning er valgt, kan oppskrifter legges til fra hvilken som helst husholdning", "mealplan-households-description": "Hvis ingen husholdning er valgt, kan oppskrifter legges til fra hvilken som helst husholdning",
"any-category": "Enhver kategori", "any-category": "Enhver kategori",
"any-tag": "Hvilken som helst emne", "any-tag": "Any Tag",
"any-household": "Hvilken som helst husholdning", "any-household": "Any Household",
"no-meal-plan-defined-yet": "Ingen måltidsplan er definert ennå", "no-meal-plan-defined-yet": "Ingen måltidsplan er definert ennå",
"no-meal-planned-for-today": "Ingen måltid planlagt i dag", "no-meal-planned-for-today": "Ingen måltid planlagt i dag",
"numberOfDays-hint": "Antall dager på sideinnlasting", "numberOfDays-hint": "Antall dager på sideinnlasting",
@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Opprett oppskrift fra et bilde", "create-recipe-from-an-image": "Opprett oppskrift fra et bilde",
"create-recipe-from-an-image-description": "Opprett en oppskrift ved å laste opp et bilde av den. Mealie vil forsøke å hente ut teksten fra bildet ved bruk av AI, og lage en ny oppskrift.", "create-recipe-from-an-image-description": "Opprett en oppskrift ved å laste opp et bilde av den. Mealie vil forsøke å hente ut teksten fra bildet ved bruk av AI, og lage en ny oppskrift.",
"crop-and-rotate-the-image": "Beskjær og roter bildet slik at bare teksten er synlig, og at det er i riktig retning.", "crop-and-rotate-the-image": "Beskjær og roter bildet slik at bare teksten er synlig, og at det er i riktig retning.",
"create-from-images": "Create from Images", "create-from-image": "Opprett fra bilde",
"should-translate-description": "Oversett oppskriften til mitt språk", "should-translate-description": "Oversett oppskriften til mitt språk",
"please-wait-image-procesing": "Vent litt, bildet blir prosessert. Dette kan ta litt tid.", "please-wait-image-procesing": "Vent litt, bildet blir prosessert. Dette kan ta litt tid.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importer flere nettadresser", "bulk-url-import": "Importer flere nettadresser",
"debug-scraper": "Feilsøk skraper", "debug-scraper": "Feilsøk skraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Opprett en oppskrift ved å angi navnet. Alle oppskrifter må ha unike navn.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Opprett en oppskrift ved å angi navnet. Alle oppskrifter må ha unike navn.",
@@ -661,10 +660,7 @@
"no-food": "Ingen matvarer" "no-food": "Ingen matvarer"
}, },
"reset-servings-count": "Nullstill antall porsjoner", "reset-servings-count": "Nullstill antall porsjoner",
"not-linked-ingredients": "Tilleggsingredienser", "not-linked-ingredients": "Tilleggsingredienser"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Oppskriftsfinner", "recipe-finder": "Oppskriftsfinner",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Utwórz przepis z obrazu", "create-recipe-from-an-image": "Utwórz przepis z obrazu",
"create-recipe-from-an-image-description": "Utwórz przepis poprzez przesłanie obrazka. Mealie spróbuje wyodrębnić tekst z obrazu za pomocą AI i utworzyć z niego przepis.", "create-recipe-from-an-image-description": "Utwórz przepis poprzez przesłanie obrazka. Mealie spróbuje wyodrębnić tekst z obrazu za pomocą AI i utworzyć z niego przepis.",
"crop-and-rotate-the-image": "Przytnij i obróć obraz, tak aby był w odpowiedniej orientacji i był widoczny tylko tekst.", "crop-and-rotate-the-image": "Przytnij i obróć obraz, tak aby był w odpowiedniej orientacji i był widoczny tylko tekst.",
"create-from-images": "Create from Images", "create-from-image": "Utwórz z obrazu",
"should-translate-description": "Przetłumacz przepis na mój język", "should-translate-description": "Przetłumacz przepis na mój język",
"please-wait-image-procesing": "Proszę czekać, obraz jest przetwarzany. To może chwilę potrwać.", "please-wait-image-procesing": "Proszę czekać, obraz jest przetwarzany. To może chwilę potrwać.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Import Zbiorczy z URL", "bulk-url-import": "Import Zbiorczy z URL",
"debug-scraper": "Debuguj Scraper", "debug-scraper": "Debuguj Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Utwórz przepis, podając nazwę. Wszystkie przepisy muszą mieć unikalne nazwy.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Utwórz przepis, podając nazwę. Wszystkie przepisy muszą mieć unikalne nazwy.",
@@ -661,10 +660,7 @@
"no-food": "Brak potrawy" "no-food": "Brak potrawy"
}, },
"reset-servings-count": "Zresetuj liczbę porcji", "reset-servings-count": "Zresetuj liczbę porcji",
"not-linked-ingredients": "Dodatkowe składniki", "not-linked-ingredients": "Dodatkowe składniki"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Wyszukiwarka przepisów", "recipe-finder": "Wyszukiwarka przepisów",

View File

@@ -599,10 +599,9 @@
"create-recipe-from-an-image": "Create Recipe from an Image", "create-recipe-from-an-image": "Create Recipe from an Image",
"create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.", "create-recipe-from-an-image-description": "Create a recipe by uploading an image of it. Mealie will attempt to extract the text from the image using AI and create a recipe from it.",
"crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.", "crop-and-rotate-the-image": "Crop and rotate the image so that only the text is visible, and it's in the correct orientation.",
"create-from-images": "Create from Images", "create-from-image": "Criar a partir da imagem",
"should-translate-description": "Traduza a receita para o meu idioma", "should-translate-description": "Traduza a receita para o meu idioma",
"please-wait-image-procesing": "Por favor aguarde, a imagem está sendo processada. Isto pode levar algum tempo.", "please-wait-image-procesing": "Por favor aguarde, a imagem está sendo processada. Isto pode levar algum tempo.",
"please-wait-images-processing": "Please wait, the images are processing. This may take some time.",
"bulk-url-import": "Importação de URL em massa", "bulk-url-import": "Importação de URL em massa",
"debug-scraper": "Debug Scraper", "debug-scraper": "Debug Scraper",
"create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crie uma receita fornecendo o nome. Todas as receitas devem ter nomes exclusivos.", "create-a-recipe-by-providing-the-name-all-recipes-must-have-unique-names": "Crie uma receita fornecendo o nome. Todas as receitas devem ter nomes exclusivos.",
@@ -661,10 +660,7 @@
"no-food": "Sem Comida" "no-food": "Sem Comida"
}, },
"reset-servings-count": "Reset Servings Count", "reset-servings-count": "Reset Servings Count",
"not-linked-ingredients": "Ingredientes adicionais", "not-linked-ingredients": "Ingredientes adicionais"
"upload-another-image": "Upload another image",
"upload-images": "Upload images",
"upload-more-images": "Upload more images"
}, },
"recipe-finder": { "recipe-finder": {
"recipe-finder": "Localizador de Receitas", "recipe-finder": "Localizador de Receitas",

Some files were not shown because too many files have changed in this diff Show More