mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-21 22:13:31 -07:00
feat: Button to choose recipe cover image when creating recipe from images
This commit is contained in:
parent
138aa3b054
commit
bede092990
2 changed files with 66 additions and 13 deletions
|
@ -664,7 +664,9 @@
|
|||
"not-linked-ingredients": "Additional Ingredients",
|
||||
"upload-another-image": "Upload another image",
|
||||
"upload-images": "Upload images",
|
||||
"upload-more-images": "Upload more images"
|
||||
"upload-more-images": "Upload more images",
|
||||
"set-as-cover-image": "Set as recipe cover image",
|
||||
"cover-image": "Cover image"
|
||||
},
|
||||
"recipe-finder": {
|
||||
"recipe-finder": "Recipe Finder",
|
||||
|
|
|
@ -32,15 +32,30 @@
|
|||
lg="4"
|
||||
xl="3"
|
||||
>
|
||||
<ImageCropper
|
||||
:img="imageUrl"
|
||||
cropper-height="100%"
|
||||
cropper-width="100%"
|
||||
:submitted="loading"
|
||||
class="mt-4"
|
||||
@save="(croppedImage) => updateUploadedImage(index, croppedImage)"
|
||||
@delete="clearImage(index)"
|
||||
/>
|
||||
<v-col>
|
||||
<ImageCropper
|
||||
:img="imageUrl"
|
||||
cropper-height="100%"
|
||||
cropper-width="100%"
|
||||
:submitted="loading"
|
||||
class="mt-4 mb-2"
|
||||
@save="(croppedImage) => updateUploadedImage(index, croppedImage)"
|
||||
@delete="clearImage(index)"
|
||||
/>
|
||||
|
||||
<v-btn
|
||||
v-if="uploadedImages.length > 1"
|
||||
:disabled="loading || coverImageIndex === index"
|
||||
color="primary"
|
||||
@click="() => (coverImageIndex = index)"
|
||||
>
|
||||
<v-icon start>
|
||||
{{ coverImageIndex === index ? $globals.icons.check : $globals.icons.fileImage }}
|
||||
</v-icon>
|
||||
|
||||
{{ coverImageIndex === index ? $t("recipe.cover-image") : $t("recipe.set-as-cover-image") }}
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
|
@ -95,6 +110,7 @@ export default defineNuxtComponent({
|
|||
const uploadedImageNames = ref<string[]>([]);
|
||||
const uploadedImagesPreviewUrls = ref<string[]>([]);
|
||||
const shouldTranslate = ref(true);
|
||||
const coverImageIndex = ref<number | null>(null);
|
||||
|
||||
function uploadImages(files: File[]) {
|
||||
uploadedImages.value = [...uploadedImages.value, ...files];
|
||||
|
@ -103,14 +119,23 @@ export default defineNuxtComponent({
|
|||
...uploadedImagesPreviewUrls.value,
|
||||
...files.map(file => URL.createObjectURL(file)),
|
||||
];
|
||||
|
||||
if (files.length && coverImageIndex.value === null) {
|
||||
coverImageIndex.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function clearImage(index: number) {
|
||||
// Revoke _before_ splicing
|
||||
URL.revokeObjectURL(uploadedImagesPreviewUrls.value[index]);
|
||||
|
||||
uploadedImages.value = uploadedImages.value.filter((_, i) => i !== index);
|
||||
uploadedImageNames.value = uploadedImageNames.value.filter((_, i) => i !== index);
|
||||
uploadedImagesPreviewUrls.value = uploadedImagesPreviewUrls.value.filter((_, i) => i !== index);
|
||||
uploadedImages.value.splice(index, 1);
|
||||
uploadedImageNames.value.splice(index, 1);
|
||||
uploadedImagesPreviewUrls.value.splice(index, 1);
|
||||
|
||||
if (coverImageIndex.value === index) {
|
||||
coverImageIndex.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function createRecipe() {
|
||||
|
@ -119,6 +144,15 @@ export default defineNuxtComponent({
|
|||
}
|
||||
|
||||
state.loading = true;
|
||||
|
||||
// Put the intended cover image at the start of the array
|
||||
// The backend currently sets the first image as the cover image
|
||||
if (coverImageIndex.value !== null && coverImageIndex.value !== 0) {
|
||||
swapImages(0, coverImageIndex.value);
|
||||
|
||||
coverImageIndex.value = 0;
|
||||
}
|
||||
|
||||
const translateLanguage = shouldTranslate.value ? i18n.locale : undefined;
|
||||
const { data, error } = await api.recipes.createOneFromImages(uploadedImages.value, translateLanguage?.value);
|
||||
if (error || !data) {
|
||||
|
@ -135,12 +169,29 @@ export default defineNuxtComponent({
|
|||
uploadedImagesPreviewUrls.value[index] = URL.createObjectURL(croppedImage);
|
||||
}
|
||||
|
||||
function swapItem(array: any[], i: number, j: number) {
|
||||
if (i < 0 || j < 0 || i >= array.length || j >= array.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const temp = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = temp;
|
||||
}
|
||||
|
||||
function swapImages(i: number, j: number) {
|
||||
swapItem(uploadedImages.value, i, j);
|
||||
swapItem(uploadedImageNames.value, i, j);
|
||||
swapItem(uploadedImagesPreviewUrls.value, i, j);
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
domUrlForm,
|
||||
uploadedImages,
|
||||
uploadedImagesPreviewUrls,
|
||||
shouldTranslate,
|
||||
coverImageIndex,
|
||||
uploadImages,
|
||||
clearImage,
|
||||
createRecipe,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue