enrecipes/app/components/EditRecipe.vue

1135 lines
35 KiB
Vue
Raw Normal View History

2020-10-14 19:32:32 +00:00
<template>
2021-03-21 17:02:04 +00:00
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *, auto">
<MDButton
variant="text"
class="er"
:text="icon.back"
automationText="Back"
col="0"
@tap="navigateBack"
/>
2021-03-23 06:16:25 +00:00
<Label class="title tb" :text="`${title}` | L" col="1" />
2021-03-21 17:02:04 +00:00
<MDButton
variant="text"
v-if="hasChanges && !saving"
class="er"
:text="icon.save"
col="2"
@tap="saveOperation"
/>
<MDActivityIndicator col="2" v-if="saving" :busy="saving" />
</GridLayout>
</ActionBar>
<ScrollView width="100%" height="100%">
<StackLayout width="100%" padding="0 0 88">
<AbsoluteLayout>
<StackLayout
width="100%"
:height="screenWidth"
class="imageHolder"
verticalAlignment="center"
>
<Image
v-if="recipeContent.imageSrc"
:src="recipeContent.imageSrc"
stretch="aspectFill"
width="100%"
:height="screenWidth"
/>
<Label
v-else
horizontalAlignment="center"
class="er"
fontSize="160"
:text="icon.img"
/>
</StackLayout>
2021-03-23 09:59:00 +00:00
<!-- <transition :name="recipeContent.imageSrc ? 'null' : 'bounce'">
2021-03-21 17:02:04 +00:00
<MDFloatingActionButton
v-if="showFab"
:top="screenWidth - 44"
:left="screenWidth - 88"
class="er"
src="res://cam"
@tap="imageHandler"
/>
2021-03-23 09:59:00 +00:00
</transition> -->
</AbsoluteLayout>
2021-03-21 17:02:04 +00:00
<StackLayout margin="0 16 24">
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'title' | L" />
<TextField
:hint="'recTitle' | L"
v-model="recipeContent.title"
@loaded="setInputTypeText($event, 'words')"
/>
</StackLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<Label class="fieldLabel" :text="'cui' | L" />
<TextField
:text="`${recipeContent.cuisine}` | L"
editable="false"
@focus="modalOpen === false && showCuisine(true)"
@tap="showCuisine(false)"
/>
</StackLayout>
<StackLayout class="inputField" col="2">
<Label class="fieldLabel" :text="'cat' | L" />
<TextField
ref="category"
:text="`${recipeContent.category}` | L"
editable="false"
@focus="modalOpen === false && showCategories(true)"
@tap="showCategories(false)"
/>
</StackLayout>
</GridLayout>
<StackLayout class="inputField">
<Label
class="fieldLabel"
:text="`${$options.filters.L('ts')} (${$options.filters.L(
'tsInfo'
)})`"
/>
<TextField
autocapitalizationType="words"
ref="tags"
:hint="`${$options.filters.L('tsInfo')}`"
v-model="tags"
@textChange="splitTags"
returnKeyType="next"
/>
</StackLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<Label class="fieldLabel" :text="'prepT' | L" />
<TextField
:text="timeRequired('prepTime')"
editable="false"
@focus="
modalOpen === false && setTimeRequired(true, 'prepTime')
2021-03-21 17:02:04 +00:00
"
@tap="setTimeRequired(false, 'prepTime')"
/>
</StackLayout>
<StackLayout class="inputField" col="2">
<Label class="fieldLabel" :text="'cookT' | L" />
<TextField
ref="cookTime"
:text="timeRequired('cookTime')"
editable="false"
@focus="
modalOpen === false && setTimeRequired(true, 'cookTime')
2021-03-21 17:02:04 +00:00
"
@tap="setTimeRequired(false, 'cookTime')"
/>
</StackLayout>
</GridLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<Label class="fieldLabel" :text="'yieldQ' | L" />
<TextField
ref="yieldQuantity"
v-model="recipeContent.yield.quantity"
hint="1"
keyboardType="number"
returnKeyType="next"
/>
</StackLayout>
<StackLayout class="inputField" col="2">
<Label class="fieldLabel" :text="'yieldU' | L" />
<TextField
:text="`${recipeContent.yield.unit}` | L"
editable="false"
@focus="modalOpen === false && showYieldUnits(true)"
@tap="showYieldUnits(false)"
/>
</StackLayout>
</GridLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<Label class="fieldLabel" :text="'Difficulty level' | L" />
<TextField
ref="difficultyLevel"
:text="`${recipeContent.difficulty}` | L"
editable="false"
@focus="modalOpen === false && showDifficultyLevel(true)"
@tap="showDifficultyLevel(false)"
/>
</StackLayout>
</GridLayout>
</StackLayout>
<StackLayout margin="0 16 32">
<Label
margin="0 0 16"
:text="`${$options.filters.L('ings')}${
recipeContent.ingredients.length
? ' - ' + recipeContent.ingredients.length
: ''
}`"
class="sectionTitle"
/>
<GridLayout
columns="auto,16,auto,16,*,16,auto"
v-for="(ingredient, index) in recipeContent.ingredients"
:key="index"
>
<TextField
width="60"
col="0"
@loaded="
!recipeContent.ingredients[index].item && focusField($event)
"
v-model="recipeContent.ingredients[index].quantity"
hint="1.00"
keyboardType="number"
returnKeyType="next"
/>
2020-12-29 10:35:19 +00:00
2021-03-21 17:02:04 +00:00
<TextField
width="76"
col="2"
:text="`${recipeContent.ingredients[index].unit}` | L"
editable="false"
@focus="modalOpen === false && showUnits($event, true, index)"
@tap="showUnits($event, false, index)"
/>
2020-12-29 10:35:19 +00:00
2021-03-21 17:02:04 +00:00
<TextField
ref="ingredient"
@loaded="setInputTypeText($event, 'sentence')"
col="4"
v-model="recipeContent.ingredients[index].item"
:hint="`${$options.filters.L('it')} ${index + 1}`"
@returnPress="
index + 1 == recipeContent.ingredients.length && addIngredient()
"
/>
2020-12-29 10:35:19 +00:00
2021-03-21 17:02:04 +00:00
<MDButton
variant="text"
col="6"
class="er x"
:text="icon.x"
@tap="removeIngredient(index)"
/>
</GridLayout>
<MDButton
variant="text"
2021-03-23 06:16:25 +00:00
class="text-btn tb"
2021-03-21 17:02:04 +00:00
:text="`+ ${$options.filters.L('aIngBtn')}`"
@tap="addIngredient()"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'inss' | L" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(instruction, index) in recipeContent.instructions"
:key="index"
>
<TextView
@loaded="focusField($event, 'multiLine')"
col="0"
:hint="`${$options.filters.L('stp')} ${index + 1}`"
v-model="recipeContent.instructions[index]"
/>
<MDButton
variant="text"
col="2"
class="er x"
:text="icon.x"
@tap="removeInstruction(index)"
/>
</GridLayout>
<MDButton
variant="text"
2021-03-23 06:16:25 +00:00
class="text-btn tb"
2021-03-21 17:02:04 +00:00
:text="`+ ${$options.filters.L('aStpBtn')}`"
@tap="addInstruction"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'nos' | L" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(note, index) in recipeContent.notes"
:key="index"
>
<TextView
@loaded="focusField($event, 'multiLine')"
col="0"
:hint="`${$options.filters.L('no')} ${index + 1}`"
v-model="recipeContent.notes[index]"
/>
<MDButton
variant="text"
col="2"
class="er x"
:text="icon.x"
@tap="removeNote(index)"
/>
</GridLayout>
<MDButton
variant="text"
2021-03-23 06:16:25 +00:00
class="text-btn tb"
2021-03-21 17:02:04 +00:00
:text="`+ ${$options.filters.L('aNoBtn')}`"
@tap="addNote"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'cmbs' | L" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(combination, index) in recipeContent.combinations"
:key="index"
>
<TextField
class="combinationToken"
col="0"
:text="getCombinationTitle(combination)"
editable="false"
/>
<MDButton
variant="text"
col="2"
class="er x"
:text="icon.x"
@tap="removeCombination(combination)"
/>
</GridLayout>
<MDButton
variant="text"
2021-03-23 06:16:25 +00:00
class="text-btn tb"
2021-03-21 17:02:04 +00:00
:text="`+ ${$options.filters.L('addCmbBtn')}`"
@tap="showCombinations"
/>
</StackLayout>
</StackLayout>
2021-03-21 17:02:04 +00:00
</ScrollView>
</Page>
2020-10-14 19:32:32 +00:00
</template>
<script>
import {
AndroidApplication,
2020-11-10 18:28:48 +00:00
Application,
ApplicationSettings,
File,
getFileAccess,
2020-11-10 18:28:48 +00:00
ImageSource,
knownFolders,
2020-11-10 18:28:48 +00:00
path,
Screen,
2020-11-02 11:36:53 +00:00
Utils,
2021-03-21 17:02:04 +00:00
Observable,
} from "@nativescript/core";
import * as Permissions from "@nativescript-community/perms";
import * as Toast from "nativescript-toast";
import * as Filepicker from "nativescript-plugin-filepicker";
import { ImageCropper } from "nativescript-imagecropper";
import { localize } from "@nativescript/localize";
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
2021-01-13 05:02:48 +00:00
const snackbar = new SnackBar();
2021-03-21 17:02:04 +00:00
import { mapState, mapActions } from "vuex";
import ViewRecipe from "./ViewRecipe.vue";
import ActionDialog from "./modal/ActionDialog.vue";
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
import ConfirmDialog from "./modal/ConfirmDialog.vue";
import PromptDialog from "./modal/PromptDialog.vue";
import ListPicker from "./modal/ListPicker.vue";
import * as utils from "~/shared/utils";
2020-10-14 19:32:32 +00:00
export default {
2021-03-21 17:02:04 +00:00
props: [
"recipeID",
"selectedCuisine",
"selectedCategory",
"selectedTag",
"filterFavourites",
"filterTrylater",
"navigationFromView",
],
2020-10-14 19:32:32 +00:00
data() {
return {
2021-01-13 05:02:48 +00:00
title: "newRec",
2020-10-14 19:32:32 +00:00
recipeContent: {
imageSrc: null,
title: undefined,
2020-12-29 10:35:19 +00:00
cuisine: "Undefined",
category: "Undefined",
2020-12-29 10:35:19 +00:00
tags: [],
prepTime: "00:00",
cookTime: "00:00",
2020-11-02 11:36:53 +00:00
yield: {
quantity: undefined,
unit: "Serving",
2020-11-02 11:36:53 +00:00
},
2020-12-29 10:35:19 +00:00
difficulty: "Easy",
rating: 0,
2020-11-02 11:36:53 +00:00
ingredients: [],
instructions: [],
2020-11-15 10:51:10 +00:00
combinations: [],
2020-11-28 19:21:57 +00:00
notes: [],
2020-10-26 20:49:54 +00:00
isFavorite: false,
2020-11-23 09:49:58 +00:00
tried: true,
2020-11-02 11:36:53 +00:00
lastTried: null,
2020-10-26 20:49:54 +00:00
lastModified: null,
2020-12-29 10:35:19 +00:00
created: null,
2021-01-23 17:20:15 +00:00
inBag: false,
2020-10-26 20:49:54 +00:00
},
tempRecipeContent: {},
2020-12-29 10:35:19 +00:00
tags: undefined,
2020-10-21 17:54:45 +00:00
blockModal: false,
2020-11-11 13:50:33 +00:00
modalOpen: false,
newRecipeID: null,
showFab: false,
2020-11-23 09:49:58 +00:00
saving: false,
2020-11-10 18:28:48 +00:00
cacheImagePath: null,
2020-11-15 10:51:10 +00:00
unSyncCombinations: [],
2021-03-21 17:02:04 +00:00
difficultyLevels: ["Easy", "Moderate", "Challenging"],
};
2020-10-14 19:32:32 +00:00
},
computed: {
2021-03-21 17:02:04 +00:00
...mapState([
"icon",
"units",
"yieldUnits",
"recipes",
"cuisines",
"categories",
"currentComponent",
]),
2020-10-14 19:32:32 +00:00
screenWidth() {
2021-03-21 17:02:04 +00:00
return Screen.mainScreen.widthDIPs;
2020-10-14 19:32:32 +00:00
},
2020-11-10 18:28:48 +00:00
appTheme() {
2021-03-21 17:02:04 +00:00
return Application.systemAppearance();
2020-11-10 18:28:48 +00:00
},
hasChanges() {
2021-03-21 17:02:04 +00:00
return (
JSON.stringify(this.recipeContent) !==
JSON.stringify(this.tempRecipeContent)
);
2020-10-14 19:32:32 +00:00
},
},
methods: {
2021-03-21 17:02:04 +00:00
...mapActions([
"setCurrentComponentAction",
"addRecipeAction",
"overwriteRecipeAction",
"addListItemAction",
"unSyncCombinationsAction",
]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
2021-03-21 17:02:04 +00:00
this.showFab = true;
},
2021-01-13 05:02:48 +00:00
onPageUnload() {
2021-03-21 17:02:04 +00:00
this.releaseBackEvent();
snackbar.dismiss();
2021-01-13 05:02:48 +00:00
},
2021-03-21 17:02:04 +00:00
timeRequired(time) {
let t = this.recipeContent[time].split(":");
let h = parseInt(t[0]);
let m = parseInt(t[1]);
let hr = localize("hr");
let min = localize("min");
return h ? (m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}`) : `${m} ${min}`;
},
2020-11-02 11:36:53 +00:00
// HELPERS
2021-03-21 17:02:04 +00:00
focusField(args, type) {
if (type) this.setInputTypeText(args, type);
if (!args.object.text) {
args.object.focus();
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 100);
2020-11-02 11:36:53 +00:00
}
},
2021-03-21 17:02:04 +00:00
setInputTypeText(args, type) {
let field = args.object;
let common =
android.text.InputType.TYPE_CLASS_TEXT |
android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
switch (type) {
2020-11-11 13:50:33 +00:00
case "words":
2021-03-21 17:02:04 +00:00
field.android.setInputType(
android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS | common
);
break;
2020-11-11 13:50:33 +00:00
case "sentence":
2021-03-21 17:02:04 +00:00
field.android.setInputType(
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | common
);
break;
2020-11-11 13:50:33 +00:00
case "multiLine":
2021-03-21 17:02:04 +00:00
field.android.setInputType(
android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE |
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
common
);
break;
2020-11-11 13:50:33 +00:00
default:
2021-03-21 17:02:04 +00:00
break;
2020-11-11 13:50:33 +00:00
}
},
getRandomID() {
2021-03-21 17:02:04 +00:00
let res = "";
let chars = "abcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 20; i++) {
res += chars.charAt(Math.floor(Math.random() * chars.length));
}
2021-03-21 17:02:04 +00:00
return res;
},
setTimeRequired(focus, time) {
this.modalOpen = true;
let t = this.recipeContent[time].split(":");
let hr = t[0];
let min = t[1];
this.$showModal(ListPicker, {
2020-11-02 11:36:53 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: `${time == "prepTime" ? "prepT" : "cookT"}`,
2020-11-02 11:36:53 +00:00
action: "SET",
selectedHr: hr,
selectedMin: min,
},
2021-03-21 17:02:04 +00:00
}).then((result) => {
if (result) {
this.recipeContent[time] = result;
this.modalOpen = false;
if (focus) {
switch (time) {
case "prepTime":
2021-03-21 17:02:04 +00:00
this.autoFocusField("cookTime", false);
break;
case "cookTime":
2021-03-21 17:02:04 +00:00
this.autoFocusField("yieldQuantity", true);
break;
default:
2021-03-21 17:02:04 +00:00
break;
}
}
2020-10-21 17:54:45 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-10-14 19:32:32 +00:00
},
2020-11-02 11:36:53 +00:00
// DATA LIST
2021-03-21 17:02:04 +00:00
showCuisine(focus) {
this.modalOpen = true;
this.releaseBackEvent();
this.$showModal(ActionDialog, {
2020-12-29 10:35:19 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "cui",
2020-12-29 10:35:19 +00:00
list: this.cuisines,
stretch: true,
2021-01-13 05:02:48 +00:00
action: "aNBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "cuisine",
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
if (action == "aNBtn") {
this.$showModal(PromptDialog, {
2020-12-29 10:35:19 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "newCui",
action: "aBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "cuisine",
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((item) => {
this.hijackBackEvent();
if (item.length) {
this.recipeContent.cuisine = item;
this.addListItemAction({
2020-12-29 10:35:19 +00:00
item,
2021-03-21 17:02:04 +00:00
listName: "cuisines",
});
this.modalOpen = false;
if (focus) this.autoFocusField("category", false);
2020-12-29 10:35:19 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else if (action) {
this.recipeContent.cuisine = action;
this.hijackBackEvent();
this.modalOpen = false;
if (focus) this.autoFocusField("category", false);
2020-12-29 10:35:19 +00:00
} else {
2021-03-21 17:02:04 +00:00
this.cuisines.includes(this.recipeContent.cuisine)
? mull
: (this.recipeContent.cuisine = "Undefined");
this.hijackBackEvent();
2020-12-29 10:35:19 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
showCategories(focus) {
this.modalOpen = true;
this.releaseBackEvent();
this.$showModal(ActionDialog, {
2020-10-21 17:54:45 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "cat",
2020-12-29 10:35:19 +00:00
list: this.categories,
stretch: true,
2021-01-13 05:02:48 +00:00
action: "aNBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "category",
2020-10-21 17:54:45 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
if (action == "aNBtn") {
this.$showModal(PromptDialog, {
2020-10-21 17:54:45 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "nwCat",
action: "aBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "category",
2020-10-21 17:54:45 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((item) => {
this.hijackBackEvent();
if (item.length) {
this.recipeContent.category = item;
this.addListItemAction({
2020-12-29 10:35:19 +00:00
item,
2021-03-21 17:02:04 +00:00
listName: "categories",
});
this.modalOpen = false;
if (focus) this.autoFocusField("tags", true);
2020-10-21 17:54:45 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else if (action) {
this.recipeContent.category = action;
this.hijackBackEvent();
this.modalOpen = false;
if (focus) this.autoFocusField("tags", true);
} else {
2021-03-21 17:02:04 +00:00
this.categories.includes(this.recipeContent.category)
? mull
: (this.recipeContent.category = "Undefined");
this.hijackBackEvent();
2020-10-14 19:32:32 +00:00
}
2021-03-21 17:02:04 +00:00
});
},
2021-03-21 17:02:04 +00:00
showYieldUnits(focus) {
this.modalOpen = true;
this.releaseBackEvent();
this.$showModal(ActionDialog, {
2020-11-02 11:36:53 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "yieldU",
2020-12-29 10:35:19 +00:00
list: this.yieldUnits,
stretch: true,
2021-01-13 05:02:48 +00:00
action: "aNBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "yield",
2020-11-02 11:36:53 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
if (action == "aNBtn") {
this.$showModal(PromptDialog, {
2020-11-02 11:36:53 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "nwYiU",
action: "aBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "yield",
2020-11-02 11:36:53 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((item) => {
this.hijackBackEvent();
if (item.length) {
this.recipeContent.yield.unit = item;
this.addListItemAction({
2020-12-29 10:35:19 +00:00
item,
2021-03-21 17:02:04 +00:00
listName: "yieldUnits",
});
this.modalOpen = false;
if (focus) this.autoFocusField("difficultyLevel", false);
2020-11-02 11:36:53 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else if (action) {
this.recipeContent.yield.unit = action;
this.hijackBackEvent();
this.modalOpen = false;
if (focus) this.autoFocusField("difficultyLevel", false);
2020-12-29 10:35:19 +00:00
} else {
2021-03-21 17:02:04 +00:00
this.yieldUnits.includes(this.recipeContent.yield.unit)
? mull
: (this.recipeContent.yield.unit = "Serving");
this.hijackBackEvent();
2020-12-29 10:35:19 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
showDifficultyLevel(focus) {
this.modalOpen = true;
this.releaseBackEvent();
this.$showModal(ActionDialog, {
2020-12-29 10:35:19 +00:00
props: {
title: "Difficulty level",
list: this.difficultyLevels,
stretch: false,
2021-03-21 17:02:04 +00:00
helpIcon: "diff",
count: 3,
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
if (action) {
this.recipeContent.difficulty = action;
this.hijackBackEvent();
this.modalOpen = false;
if (focus) this.addIngredient();
} else {
2021-03-21 17:02:04 +00:00
this.difficultyLevels.includes(this.recipeContent.difficulty)
? mull
: (this.recipeContent.difficulty = "Easy");
this.hijackBackEvent();
2020-11-02 11:36:53 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-11-02 11:36:53 +00:00
},
2021-03-21 17:02:04 +00:00
showUnits(e, focus, index) {
this.modalOpen = true;
this.releaseBackEvent();
this.$showModal(ActionDialog, {
2020-11-02 11:36:53 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "Unit",
2020-12-29 10:35:19 +00:00
list: this.units,
stretch: true,
2021-01-13 05:02:48 +00:00
action: "aNBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "unit",
2020-11-02 11:36:53 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
if (action == "aNBtn") {
this.$showModal(PromptDialog, {
2020-12-29 10:35:19 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "newUnit",
action: "aBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "unit",
2020-12-29 10:35:19 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((item) => {
this.hijackBackEvent();
if (item.length) {
this.recipeContent.ingredients[index].unit = item;
this.addListItemAction({
2020-12-29 10:35:19 +00:00
item,
2021-03-21 17:02:04 +00:00
listName: "units",
});
this.modalOpen = false;
if (focus && this.recipeContent.ingredients.length - 1 === index)
this.autoFocusRefField("ingredient", index);
2020-11-15 21:13:06 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else if (action) {
this.recipeContent.ingredients[index].unit = action;
this.hijackBackEvent();
this.modalOpen = false;
if (focus && this.recipeContent.ingredients.length - 1 === index)
this.autoFocusRefField("ingredient", index);
2020-11-11 13:50:33 +00:00
}
2021-03-21 17:02:04 +00:00
});
},
autoFocusField(ref, showSoftInput) {
this.$refs[ref].nativeView.focus();
if (showSoftInput) {
setTimeout(() => {
Utils.ad.showSoftInput(this.$refs[ref].nativeView.android);
}, 100);
2020-12-29 10:35:19 +00:00
}
},
2021-03-21 17:02:04 +00:00
autoFocusRefField(ref, index) {
this.$refs[ref][index].nativeView.focus();
setTimeout(() => {
Utils.ad.showSoftInput(this.$refs[ref][index].nativeView.android);
}, 100);
2020-12-29 10:35:19 +00:00
},
2020-11-02 11:36:53 +00:00
// NAVIGATION HANDLERS
2020-11-28 19:21:57 +00:00
navigateBackController() {
2021-03-21 17:02:04 +00:00
if (this.navigationFromView) {
this.$navigateTo(ViewRecipe, {
2020-11-28 19:21:57 +00:00
props: {
filterTrylater: this.filterTrylater,
recipeID: this.recipeID,
},
backstackVisible: false,
2021-03-21 17:02:04 +00:00
});
} else this.$navigateBack();
2020-11-28 19:21:57 +00:00
},
2020-10-14 19:32:32 +00:00
navigateBack() {
2021-03-21 17:02:04 +00:00
if (this.hasChanges) {
this.blockModal = true;
this.$showModal(ConfirmDialog, {
2020-10-21 17:54:45 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "unsaved",
2021-03-21 17:02:04 +00:00
description: localize("disc"),
2021-01-13 05:02:48 +00:00
cancelButtonText: "disBtn",
okButtonText: "kEdit",
2021-03-21 17:02:04 +00:00
helpIcon: "alert",
iconColor: "#c92a2a",
2020-10-21 17:54:45 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
this.blockModal = false;
if (action != null && !action) {
this.navigateBackController();
this.releaseBackEvent();
2020-10-21 17:54:45 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else {
2021-03-21 17:02:04 +00:00
this.navigateBackController();
this.releaseBackEvent();
2020-10-21 17:54:45 +00:00
}
},
hijackBackEvent() {
2021-03-21 17:02:04 +00:00
AndroidApplication.on(
AndroidApplication.activityBackPressedEvent,
this.backEvent
);
2020-10-21 17:54:45 +00:00
},
releaseBackEvent() {
2021-03-21 17:02:04 +00:00
AndroidApplication.off(
AndroidApplication.activityBackPressedEvent,
this.backEvent
);
2020-10-21 17:54:45 +00:00
},
2021-03-21 17:02:04 +00:00
backEvent(args) {
if (this.hasChanges && !this.blockModal) {
args.cancel = true;
this.navigateBack();
2020-10-21 17:54:45 +00:00
}
2020-10-14 19:32:32 +00:00
},
2020-11-02 11:36:53 +00:00
// DATA HANDLERS
imageHandler() {
2021-03-21 17:02:04 +00:00
this.clearEmptyFields();
if (this.recipeContent.imageSrc) {
this.blockModal = true;
this.$showModal(ConfirmDialog, {
props: {
2021-01-13 05:02:48 +00:00
title: "recPic",
cancelButtonText: "rBtn",
okButtonText: "repBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "img",
iconColor: "#1a1a1a",
},
2021-03-21 17:02:04 +00:00
}).then((action) => {
this.blockModal = false;
if (action) {
this.permissionCheck(this.permissionConfirmation, this.imagePicker);
} else if (action != null) {
this.recipeContent.imageSrc = null;
this.releaseBackEvent();
}
2021-03-21 17:02:04 +00:00
});
} else {
2021-03-21 17:02:04 +00:00
this.permissionCheck(this.permissionConfirmation, this.imagePicker);
2020-11-06 09:07:41 +00:00
}
},
2020-11-10 18:28:48 +00:00
permissionConfirmation() {
2021-03-21 17:02:04 +00:00
return this.$showModal(ConfirmDialog, {
2020-11-06 09:07:41 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "grant",
2021-03-21 17:02:04 +00:00
description: localize("reqAcc"),
2021-01-13 05:02:48 +00:00
cancelButtonText: "nNBtn",
okButtonText: "conBtn",
2021-03-21 17:02:04 +00:00
helpIcon: "folder",
iconColor: "#ff5200",
2020-11-06 09:07:41 +00:00
},
2021-03-21 17:02:04 +00:00
});
},
permissionCheck(confirmation, action) {
if (!ApplicationSettings.getBoolean("storagePermissionAsked", false)) {
confirmation().then((e) => {
if (e) {
Permissions.request("photo").then((status) => {
switch (status[0]) {
2020-11-10 18:28:48 +00:00
case "authorized":
2021-03-21 17:02:04 +00:00
action();
break;
2020-11-10 18:28:48 +00:00
case "never_ask_again":
2021-03-21 17:02:04 +00:00
ApplicationSettings.setBoolean(
"storagePermissionAsked",
true
);
break;
2020-11-10 18:28:48 +00:00
case "denied":
2021-03-21 17:02:04 +00:00
Toast.makeText(localize("dend")).show();
break;
2020-11-10 18:28:48 +00:00
default:
2021-03-21 17:02:04 +00:00
break;
2020-11-10 18:28:48 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-11-06 09:07:41 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else {
2021-03-21 17:02:04 +00:00
Permissions.check("photo").then((res) => {
res[0] !== "authorized"
? confirmation().then((e) => e && utils.openAppSettingsPage())
: action();
});
}
},
2020-11-02 11:36:53 +00:00
imagePicker() {
2021-03-21 17:02:04 +00:00
ApplicationSettings.setBoolean("storagePermissionAsked", true);
Filepicker.create({
2020-11-10 18:28:48 +00:00
mode: "single",
2021-03-21 17:02:04 +00:00
extensions: ["png", "jpeg", "jpg"],
})
.present()
.then((selection) => {
this.cacheImagePath = path.join(
knownFolders.temp().path,
`${this.getRandomID()}.jpg`
);
let imgPath = selection[0];
ImageSource.fromFile(imgPath).then((image) => {
ImageCropper.prototype
.show(
image,
{
width: 1080,
height: 1080,
},
{
hideBottomControls: true,
toolbarTitle: localize("cPic"),
statusBarColor: "#ff5200",
toolbarTextColor:
this.appTheme == "light" ? "#1A1A1A" : "#e0e0e0",
toolbarColor:
this.appTheme == "light" ? "#e0e0e0" : "#1A1A1A",
cropFrameColor: "#ff5200",
}
)
.then((cropped) => {
cropped.image.saveToFile(this.cacheImagePath, "jpg", 75);
this.recipeContent.imageSrc = this.cacheImagePath;
});
});
});
2020-10-14 19:32:32 +00:00
},
2020-11-10 18:28:48 +00:00
// INPUT FIELD HANDLERS
2020-12-29 10:35:19 +00:00
splitTags() {
2021-03-21 17:02:04 +00:00
let string;
if (this.tags) {
let tags = this.tags
.split(" ")
.map((e) => {
string = e.replace(/^[^\w\s]+/, "");
if (/^[A-Za-z]+/.test(string)) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
})
.filter((e) => e);
this.recipeContent.tags = tags;
2020-12-29 10:35:19 +00:00
}
},
joinTags() {
2021-03-21 17:02:04 +00:00
this.tags = this.recipeContent.tags.join(" ");
},
undoDeletion(message) {
return snackbar.action({
message,
textColor: this.appTheme == "light" ? "#fff" : "#292929",
actionTextColor: "#ff5200",
backgroundColor: this.appTheme == "light" ? "#292929" : "#fff",
actionText: localize("undo"),
hideDelay: 5000,
});
2020-11-10 18:28:48 +00:00
},
2020-10-14 19:32:32 +00:00
addIngredient() {
2021-03-21 17:02:04 +00:00
let ingredients = this.recipeContent.ingredients;
let unit = ingredients.length
? ingredients[ingredients.length - 1].unit
: "unit";
this.recipeContent.ingredients.push({
2020-10-21 17:54:45 +00:00
item: "",
2020-10-14 19:32:32 +00:00
quantity: null,
2020-12-29 10:35:19 +00:00
unit,
2021-03-21 17:02:04 +00:00
});
},
removeIngredient(index) {
this.modalOpen = true;
if (this.recipeContent.ingredients[index].item.length) {
let item = this.recipeContent.ingredients[index];
this.recipeContent.ingredients.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmIng")}`).then((res) => {
if (res.command === "action")
this.recipeContent.ingredients.splice(index, 0, item);
});
2020-12-29 10:35:19 +00:00
} else {
2021-03-21 17:02:04 +00:00
this.recipeContent.ingredients.splice(index, 1);
2020-12-29 10:35:19 +00:00
}
2021-03-21 17:02:04 +00:00
setTimeout((e) => (this.modalOpen = false), 200);
2020-10-14 19:32:32 +00:00
},
addInstruction() {
2021-03-21 17:02:04 +00:00
this.recipeContent.instructions.push("");
},
removeInstruction(index) {
if (this.recipeContent.instructions[index].length) {
let item = this.recipeContent.instructions[index];
this.recipeContent.instructions.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmIns")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.instructions.splice(index, 0, item);
2021-01-13 05:02:48 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else this.recipeContent.instructions.splice(index, 1);
2020-10-14 19:32:32 +00:00
},
2021-01-13 05:02:48 +00:00
addNote() {
2021-03-21 17:02:04 +00:00
this.recipeContent.notes.push("");
},
removeNote(index) {
if (this.recipeContent.notes[index].length) {
let item = this.recipeContent.notes[index];
this.recipeContent.notes.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmN")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.notes.splice(index, 0, item);
2021-01-13 05:02:48 +00:00
}
2021-03-21 17:02:04 +00:00
});
} else this.recipeContent.notes.splice(index, 1);
2021-01-13 05:02:48 +00:00
},
2021-03-21 17:02:04 +00:00
getCombinationTitle(id) {
return this.recipes.filter((e) => e.id === id)[0].title;
2020-11-15 10:51:10 +00:00
},
showCombinations() {
2021-03-21 17:02:04 +00:00
this.modalOpen = true;
this.releaseBackEvent();
let existingCombinations = [
...this.recipeContent.combinations,
2020-11-15 10:51:10 +00:00
this.recipeContent.id,
2021-03-21 17:02:04 +00:00
];
2020-11-15 10:51:10 +00:00
let filteredRecipes = this.recipes.filter(
2021-03-21 17:02:04 +00:00
(e) => !existingCombinations.includes(e.id)
);
this.$showModal(ActionDialogWithSearch, {
2020-11-15 10:51:10 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "selRec",
2020-11-15 10:51:10 +00:00
recipes: filteredRecipes,
2021-03-21 17:02:04 +00:00
helpIcon: "comb",
2020-11-15 10:51:10 +00:00
},
2021-03-21 17:02:04 +00:00
}).then((res) => {
this.hijackBackEvent();
if (res) {
this.recipeContent.combinations.push(res);
2020-11-15 10:51:10 +00:00
}
2021-03-21 17:02:04 +00:00
});
},
removeCombination(id) {
let index = this.recipeContent.combinations.indexOf(id);
this.recipeContent.combinations.splice(index, 1);
this.unSyncCombinations.push(id);
this.undoDeletion(`${this.$options.filters.L("rmCmb")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.combinations.splice(index, 0, id);
2020-11-15 10:51:10 +00:00
}
2021-03-21 17:02:04 +00:00
});
2020-11-15 10:51:10 +00:00
},
2020-11-10 18:28:48 +00:00
// SAVE OPERATION
2020-11-02 11:36:53 +00:00
clearEmptyFields() {
2021-03-21 17:02:04 +00:00
if (!this.recipeContent.title)
this.recipeContent.title = localize("untRec");
if (!this.recipeContent.yield.quantity)
this.recipeContent.yield.quantity = 1;
2020-11-02 11:36:53 +00:00
this.recipeContent.ingredients = this.recipeContent.ingredients.filter(
2021-03-21 17:02:04 +00:00
(e) => e.item
);
let vm = this;
2021-03-21 17:02:04 +00:00
function clearEmpty(arr) {
vm.recipeContent[arr] = vm.recipeContent[arr].filter((e) => e);
2020-11-02 11:36:53 +00:00
}
2021-03-21 17:02:04 +00:00
clearEmpty("instructions");
clearEmpty("notes");
2020-11-02 11:36:53 +00:00
},
saveOperation() {
2021-03-21 17:02:04 +00:00
this.saving = this.modalOpen = true;
this.clearEmptyFields();
this.recipeContent.lastModified = new Date();
ApplicationSettings.setString(
"previousCuisine",
this.recipeContent.cuisine
);
ApplicationSettings.setString(
"previousCategory",
this.recipeContent.category
);
ApplicationSettings.setString(
"previousYieldUnit",
this.recipeContent.yield.unit
);
if (this.cacheImagePath) {
let recipeImage = path.join(
knownFolders.documents().getFolder("EnRecipes").getFolder("Images")
.path,
`${this.getRandomID()}.jpg`
);
let binarySource = File.fromPath(this.cacheImagePath).readSync();
File.fromPath(recipeImage).writeSync(binarySource);
this.recipeContent.imageSrc = recipeImage;
knownFolders.temp().clear();
2020-11-10 18:28:48 +00:00
}
2021-03-21 17:02:04 +00:00
if (this.recipeContent.imageSrc) {
if (
this.tempRecipeContent.imageSrc &&
this.tempRecipeContent.imageSrc !== this.recipeContent.imageSrc
) {
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc);
2020-11-10 18:28:48 +00:00
}
2021-03-21 17:02:04 +00:00
} else if (this.tempRecipeContent.imageSrc) {
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc);
}
2021-03-21 17:02:04 +00:00
this.unSyncCombinationsAction({
2020-11-15 10:51:10 +00:00
id: this.recipeID,
combinations: this.unSyncCombinations,
2021-03-21 17:02:04 +00:00
});
this.saveRecipe();
2020-11-02 11:36:53 +00:00
},
saveRecipe() {
2021-03-21 17:02:04 +00:00
if (this.recipeID) {
this.overwriteRecipeAction({
2020-11-02 11:36:53 +00:00
id: this.recipeID,
recipe: this.recipeContent,
2021-03-21 17:02:04 +00:00
});
} else {
2021-03-21 17:02:04 +00:00
this.recipeContent.id = this.newRecipeID;
this.addRecipeAction({
2020-11-02 11:36:53 +00:00
id: this.newRecipeID,
recipe: this.recipeContent,
2021-03-21 17:02:04 +00:00
});
2020-11-02 11:36:53 +00:00
}
2021-03-21 17:02:04 +00:00
setTimeout(() => {
this.saving = false;
}, 100);
this.navigateBackController();
2020-10-14 19:32:32 +00:00
},
},
2020-10-26 20:49:54 +00:00
created() {
2021-03-21 17:02:04 +00:00
setTimeout((e) => {
this.setCurrentComponentAction("EditRecipe");
}, 500);
this.title = this.recipeID ? "editRec" : "newRec";
if (this.recipeID) {
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0];
Object.assign(this.recipeContent, JSON.parse(JSON.stringify(recipe)));
Object.assign(
this.tempRecipeContent,
JSON.parse(JSON.stringify(this.recipeContent))
);
if (this.recipeContent.tags.length) this.joinTags();
} else {
2021-03-21 17:02:04 +00:00
this.recipeContent.cuisine = this.selectedCuisine
? /all/.test(this.selectedCuisine)
? "Undefined"
: this.selectedCuisine
: ApplicationSettings.getString("previousCuisine", "Undefined");
this.recipeContent.category = this.selectedCategory
? /all/.test(this.selectedCategory)
? "Undefined"
: this.selectedCategory
: ApplicationSettings.getString("previousCategory", "Undefined");
if (this.selectedTag && !/all/.test(this.selectedTag)) {
this.tags = this.selectedTag;
this.splitTags();
2020-12-29 10:35:19 +00:00
}
2021-03-21 17:02:04 +00:00
this.recipeContent.yield.unit = ApplicationSettings.getString(
"previousYieldUnit",
"Serving"
);
if (this.filterFavourites) this.recipeContent.isFavorite = true;
if (this.filterTrylater) this.recipeContent.tried = false;
this.recipeContent.created = new Date();
Object.assign(
this.tempRecipeContent,
JSON.parse(JSON.stringify(this.recipeContent))
);
this.newRecipeID = this.getRandomID();
2020-10-26 20:49:54 +00:00
}
2021-03-21 17:02:04 +00:00
this.hijackBackEvent();
2020-10-26 20:49:54 +00:00
},
2021-03-21 17:02:04 +00:00
};
2020-10-14 19:32:32 +00:00
</script>