diff --git a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue index 57cecb355019..8e73c1767c62 100644 --- a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue +++ b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue @@ -146,6 +146,10 @@ text: 'Merge Above', event: 'merge-above', }, + { + text: 'Upload image', + event: 'upload-image' + }, { icon: previewStates[index] ? $globals.icons.edit : $globals.icons.eye, text: previewStates[index] ? 'Edit Markdown' : 'Preview Markdown', @@ -158,6 +162,7 @@ @toggle-section="toggleShowTitle(step.id)" @link-ingredients="openDialog(index, step.text, step.ingredientReferences)" @preview-step="togglePreviewState(index)" + @upload-image="openImageUpload(index)" @delete="value.splice(index, 1)" /> @@ -169,6 +174,8 @@ + + ({}); + async function handleImageDrop(index: number, files: File[]) { if (!files) { return; @@ -559,6 +568,8 @@ export default defineComponent({ return; } + loadingStates.value[index] = true; + const { data } = await api.recipes.createAsset(props.recipe.slug, { name: file.name, icon: "mdi-file-image", @@ -566,6 +577,8 @@ export default defineComponent({ extension: file.name.split(".").pop() || "", }); + loadingStates.value[index] = false; + if (!data) { return; // TODO: Handle error } @@ -576,11 +589,26 @@ export default defineComponent({ props.value[index].text += text; } + function openImageUpload(index: number) { + const input = document.createElement("input"); + input.type = "file"; + input.accept = "image/*"; + input.onchange = async () => { + if (input.files) { + await handleImageDrop(index, Array.from(input.files)); + input.remove(); + } + }; + input.click(); + } + return { // Image Uploader toggleDragMode, handleImageDrop, imageUploadMode, + openImageUpload, + loadingStates, // Rest drag,