enrecipes/app/components/ViewRecipe.vue

941 lines
29 KiB
Vue
Raw Permalink Normal View History

2020-10-14 19:32:32 +00:00
<template>
2021-04-01 10:55:35 +00:00
<Page @loaded="onPageLoad" @unloaded="onPageUnload" actionBarHidden="true">
<GridLayout rows="*, auto" columns="*">
<DockLayout stretchLastChild="true" rowSpan="2">
<GridLayout
dock="top"
rows="auto,auto"
columns="*, auto"
2021-04-12 18:09:48 +00:00
paddingBottom="24"
2021-04-01 10:55:35 +00:00
>
<StackLayout>
<Label class="pageTitle" paddingBottom="8" :text="recipe.title" />
<StackLayout marginLeft="12" orientation="horizontal">
<Button
class="ico rate"
:class="{ rated: recipe.rating >= n }"
v-for="n in 5"
:key="n"
:text="recipe.rating < n ? icon.star : icon.starred"
@tap="
recipe.rating == 1 && n == 1 ? setRating(0) : setRating(n)
"
@longPress="setRating(n)"
/>
</StackLayout>
</StackLayout>
<Image
col="1"
v-if="recipe.imageSrc"
:src="recipe.imageSrc"
stretch="aspectFit"
class="photo"
decodeWidth="96"
decodeHeight="96"
2021-04-12 18:09:48 +00:00
@tap="viewPhoto"
2021-02-28 15:10:26 +00:00
/>
2021-04-01 10:55:35 +00:00
</GridLayout>
2021-04-14 09:27:40 +00:00
<AbsoluteLayout dock="bottom">
<ScrollView
2021-04-21 10:31:49 +00:00
dock="bottom"
2021-04-14 09:27:40 +00:00
width="100%"
height="100%"
@loaded="onScrollLoad"
2021-04-21 10:31:49 +00:00
@scroll="onScroll($event)"
2021-04-14 09:27:40 +00:00
>
<StackLayout>
<GridLayout rows="auto" columns="*, *">
<StackLayout class="attribute">
<Label class="title sub" :text="'cui' | L" />
<Label class="value" :text="recipe.cuisine | L" />
</StackLayout>
<StackLayout class="attribute" col="1">
<Label class="title sub" :text="'cat' | L" />
<Label class="value" :text="recipe.category | L" />
</StackLayout>
</GridLayout>
<StackLayout :hidden="!recipe.tags.length" class="attribute">
<Label class="title sub" :text="'ts' | L" />
<Label class="value" :text="getTags(recipe.tags)" />
2021-02-28 15:10:26 +00:00
</StackLayout>
2021-04-14 09:27:40 +00:00
<GridLayout rows="auto" columns="*, *">
<StackLayout
class="attribute"
:hidden="!hasTime(recipe.prepTime)"
>
<Label class="title sub" :text="'prepT' | L" />
<Label class="value" :text="formattedTime(recipe.prepTime)" />
</StackLayout>
<StackLayout
:col="hasTime(recipe.prepTime) ? 1 : 0"
class="attribute"
:hidden="!hasTime(recipe.cookTime)"
>
<Label class="title sub" :text="'cookT' | L" />
<Label class="value" :text="formattedTime(recipe.cookTime)" />
</StackLayout>
</GridLayout>
<GridLayout rows="auto" columns="*, *">
<StackLayout class="attribute">
<Label class="title sub" :text="'yld' | L" />
<Label
@touch="touchYield"
class="value clickable"
:text="`${tempYieldQuantity} ${$options.filters.L(
recipe.yield.unit
)}`"
/>
</StackLayout>
<StackLayout class="attribute" col="1">
<Label class="title sub" :text="'Difficulty level' | L" />
<Label class="value" :text="recipe.difficulty | L" />
</StackLayout>
</GridLayout>
<StackLayout @loaded="onIngsLoad">
2021-04-12 18:09:48 +00:00
<Label
2021-04-14 09:27:40 +00:00
padding="0 16"
class="sectionTitle"
:hidden="!recipe.ingredients.length"
:text="getTitleCount('ings', 'ingredients')"
2021-04-12 18:09:48 +00:00
/>
2021-04-14 09:27:40 +00:00
<StackLayout
orientation="horizontal"
v-for="(item, index) in recipe.ingredients"
:key="index + 'ing'"
class="ingredient"
@touch="touchIngredient($event, index)"
>
<Button class="ico min" :text="icon.uncheck" />
<Label
class="value tw"
:text="`${
roundedQuantity(item.quantity)
? roundedQuantity(item.quantity) + ' '
: ''
}${
roundedQuantity(item.quantity)
? $options.filters.L(item.unit) + ' '
: ''
}${item.item}`"
/>
</StackLayout>
2021-04-12 18:09:48 +00:00
</StackLayout>
2021-04-14 09:27:40 +00:00
<StackLayout @loaded="onInsLoad">
2021-04-12 18:09:48 +00:00
<Label
2021-04-14 09:27:40 +00:00
padding="0 16"
:hidden="!recipe.instructions.length"
class="sectionTitle"
:text="getTitleCount('inss', 'instructions')"
2021-04-12 18:09:48 +00:00
/>
2021-04-14 09:27:40 +00:00
<StackLayout
orientation="horizontal"
@touch="touchInstruction"
v-for="(instruction, index) in recipe.instructions"
:key="index + 'ins'"
class="instruction"
>
<Button class="count ico min" :text="index + 1" />
<Label class="value tw" :text="instruction" />
</StackLayout>
</StackLayout>
<Label
@loaded="onCmbLoad"
padding="0 16"
:hidden="!recipe.combinations.length"
class="sectionTitle"
:text="getTitleCount('cmbs', 'combinations')"
/>
<Button
v-for="(combination, index) in recipe.combinations"
:key="index + 'comb'"
class="combination"
:text="getCombinationTitle(combination)"
@tap="viewCombination(combination)"
/>
<Label
@loaded="onNosTLoad"
padding="0 16"
:hidden="!recipe.notes.length"
class="sectionTitle"
:text="getTitleCount('nos', 'notes')"
/>
<StackLayout @loaded="onNosLoad" padding="0 16"> </StackLayout>
<Label
class="dateInfo sub tw"
:text="`${$options.filters.L('Last updated')}: ${formattedDate(
recipe.lastModified
)}\n${$options.filters.L('Created')}: ${formattedDate(
recipe.created
)}`"
/>
2021-04-12 18:09:48 +00:00
</StackLayout>
2021-04-14 09:27:40 +00:00
</ScrollView>
<Label
2021-04-21 10:31:49 +00:00
@loaded="onStickyLoad"
2021-04-14 09:27:40 +00:00
class="sectionTitle sticky"
2021-04-21 10:31:49 +00:00
:hidden="!stickyTitle"
:text="stickyTitle"
2021-04-14 09:27:40 +00:00
/>
</AbsoluteLayout>
2021-04-01 10:55:35 +00:00
</DockLayout>
<GridLayout
row="1"
@loaded="onAppBarLoad"
class="appbar"
v-show="!toast"
columns="auto, *, auto, auto, auto, auto"
>
2021-04-12 18:09:48 +00:00
<Button
class="ico"
:text="photoOpen ? icon.x : icon.back"
@tap="navigateBack"
/>
2021-04-01 10:55:35 +00:00
<Button
col="2"
v-if="!filterTrylater"
class="ico"
:text="recipe.tried ? icon.try : icon.tried"
2021-04-12 18:09:48 +00:00
@tap="toggle('tried')"
2021-04-01 10:55:35 +00:00
/>
<Button
col="2"
v-else
class="ico"
:text="icon.done"
@tap="recipeTried"
/>
<Button
col="3"
class="ico"
:text="recipe.isFavorite ? icon.faved : icon.fav"
2021-04-12 18:09:48 +00:00
@tap="toggle('isFavorite')"
2021-04-01 10:55:35 +00:00
/>
<Button
col="4"
v-if="!busy"
class="ico"
:text="icon.edit"
@tap="editRecipe"
/>
<ActivityIndicator col="4" v-else :busy="busy" />
<Button
class="ico fab"
:text="icon.share"
col="5"
@tap="shareHandler"
/>
2021-02-28 15:10:26 +00:00
</GridLayout>
2021-04-01 10:55:35 +00:00
<GridLayout
v-show="toast"
row="1"
2021-04-12 18:09:48 +00:00
class="appbar snackBar"
2021-04-01 10:55:35 +00:00
columns="*"
@tap="toast = null"
>
<FlexboxLayout minHeight="48" alignItems="center">
<Label class="title msg" :text="toast" />
</FlexboxLayout>
</GridLayout>
2021-04-12 18:09:48 +00:00
<AbsoluteLayout rowSpan="2">
2021-04-21 10:31:49 +00:00
<Image
@tap="({ object }) => (object.cancel = true)"
backgroundColor="black"
stretch="aspectFit"
@loaded="onImgViewLoad"
2021-04-12 18:09:48 +00:00
:src="recipe.imageSrc"
class="photoviewer"
2021-04-21 10:31:49 +00:00
/>
2021-04-12 18:09:48 +00:00
</AbsoluteLayout>
2021-04-01 10:55:35 +00:00
</GridLayout>
2021-02-28 15:10:26 +00:00
</Page>
2020-10-14 19:32:32 +00:00
</template>
2021-04-21 10:31:49 +00:00
<script lang="ts">
2020-11-02 11:36:53 +00:00
import {
2020-12-02 10:37:45 +00:00
Application,
2021-04-12 18:09:48 +00:00
AndroidApplication,
2020-11-10 18:28:48 +00:00
ImageSource,
Utils,
2020-12-02 09:46:25 +00:00
Span,
FormattedString,
Label,
2020-12-29 10:35:19 +00:00
Observable,
2021-04-01 10:55:35 +00:00
Screen,
2021-04-12 18:09:48 +00:00
CoreTypes,
2021-02-28 15:10:26 +00:00
} from "@nativescript/core";
import { localize } from "@nativescript/localize";
const intl = require("nativescript-intl");
import { mapActions, mapState } from "vuex";
import EditRecipe from "./EditRecipe.vue";
2021-04-01 10:55:35 +00:00
import ActionDialog from "./modal/ActionDialog.vue";
import PromptDialog from "./modal/PromptDialog.vue";
2021-04-12 18:09:48 +00:00
import * as utils from "~/shared/utils";
2020-10-14 19:32:32 +00:00
export default {
2021-02-28 15:10:26 +00:00
props: ["filterTrylater", "recipeID"],
2020-10-14 19:32:32 +00:00
data() {
return {
2020-10-21 17:54:45 +00:00
busy: false,
2020-11-02 11:36:53 +00:00
yieldMultiplier: 1,
recipe: null,
2020-11-15 10:51:10 +00:00
currentRecipeID: this.recipeID,
2021-04-01 10:55:35 +00:00
scrollview: null,
appbar: null,
ingcon: null,
inscon: null,
2021-04-14 09:27:40 +00:00
cmbcon: null,
2021-04-01 10:55:35 +00:00
notescon: null,
2021-04-14 09:27:40 +00:00
notesT: null,
2021-04-21 10:31:49 +00:00
imgView: null,
2021-01-13 05:02:48 +00:00
checks: [],
2021-04-12 18:09:48 +00:00
checked: 0,
stepsDid: 0,
2021-04-01 10:55:35 +00:00
toast: null,
2021-04-12 18:09:48 +00:00
photoOpen: false,
2021-04-14 09:27:40 +00:00
showTitleArr: [false, false, false, false],
2021-04-21 10:31:49 +00:00
sticky: null,
2021-02-28 15:10:26 +00:00
};
2020-10-14 19:32:32 +00:00
},
computed: {
2021-02-28 15:10:26 +00:00
...mapState(["icon", "recipes"]),
2021-04-12 18:09:48 +00:00
tempYieldQuantity() {
2021-02-28 15:10:26 +00:00
return Math.abs(this.yieldMultiplier) > 0
? Math.abs(parseFloat(this.yieldMultiplier))
: 1;
2020-10-14 19:32:32 +00:00
},
2021-04-21 10:31:49 +00:00
stickyTitle() {
let val = null;
switch (this.showTitleArr.lastIndexOf(true)) {
case 0:
val = this.getTitleCount("ings", "ingredients");
break;
case 1:
val = this.getTitleCount("inss", "instructions");
break;
case 2:
val = this.getTitleCount("cmbs", "combinations");
break;
case 3:
val = this.getTitleCount("nos", "notes");
break;
}
return val;
},
2020-10-14 19:32:32 +00:00
},
methods: {
2021-02-28 15:10:26 +00:00
...mapActions([
"toggleStateAction",
2021-04-01 10:55:35 +00:00
"setComponent",
2021-02-28 15:10:26 +00:00
"overwriteRecipeAction",
"setRecipeAsTriedAction",
"setRatingAction",
"toggleCartAction",
]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
2021-04-18 18:34:17 +00:00
this.busy = this.photoOpen = false;
2021-04-12 18:09:48 +00:00
this.setComponent("ViewRecipe");
2021-02-28 15:10:26 +00:00
if (this.yieldMultiplier == this.recipe.yield.quantity)
this.yieldMultiplier = this.recipe.yield.quantity;
this.keepScreenOn(true);
this.syncCombinations();
},
2020-11-10 18:28:48 +00:00
onPageUnload() {
2021-02-28 15:10:26 +00:00
this.keepScreenOn(false);
2020-11-10 18:28:48 +00:00
},
2021-04-01 10:55:35 +00:00
onAppBarLoad({ object }) {
this.appbar = object;
},
onIngsLoad({ object }) {
this.ingcon = object;
},
onInsLoad({ object }) {
this.inscon = object;
},
2021-04-14 09:27:40 +00:00
onCmbLoad({ object }) {
this.cmbcon = object;
},
onNosTLoad({ object }) {
this.notesT = object;
},
2021-04-01 10:55:35 +00:00
onNosLoad({ object }) {
this.notescon = object;
this.createNotes();
2021-01-13 05:02:48 +00:00
},
2021-04-01 10:55:35 +00:00
onScrollLoad(args) {
this.scrollview = args.object;
},
2021-04-21 10:31:49 +00:00
onImgViewLoad({ object }) {
this.imgView = object;
this.imgView.visibility = "collapsed";
this.imgView.top = 24;
this.imgView.left = Screen.mainScreen.widthDIPs - 112;
},
onStickyLoad({ object }) {
this.sticky = object;
2021-04-12 18:09:48 +00:00
},
2021-04-14 09:27:40 +00:00
// FIX: scroll not smooth
2021-04-21 10:31:49 +00:00
fixTitle({ object }, swipeUp: boolean): void {
let ingL = this.recipe.ingredients.length;
let insL = this.recipe.instructions.length;
let cmbL = this.recipe.combinations.length;
let notL = this.recipe.notes.length;
const isTop = (label): boolean => {
let pos = label.getLocationRelativeTo(object).y;
return label === this.cmbcon || label === this.notesT
? pos < 0
: pos + 32 < 0;
};
const setVisibleTitle = (n: number): void => {
let arr = [ingL, insL, cmbL, notL];
this.showTitleArr = Array.from(
{ length: 4 },
(v, i) => (v = arr[i] ? i < n : false)
);
2021-04-23 14:30:50 +00:00
// this.sticky
// .animate({
// opacity: 0.5,
// duration: 0,
// })
// .then(() => {
// this.sticky.animate({
// opacity: 1,
// duration: 250,
// });
// });
2021-04-21 10:31:49 +00:00
};
if (swipeUp) {
if (ingL && !this.showTitleArr[0] && isTop(this.ingcon))
setVisibleTitle(1);
else if (insL && !this.showTitleArr[1] && isTop(this.inscon))
setVisibleTitle(2);
else if (cmbL && !this.showTitleArr[2] && isTop(this.cmbcon))
setVisibleTitle(3);
else if (notL && !this.showTitleArr[3] && isTop(this.notesT))
setVisibleTitle(4);
} else {
if (notL && this.showTitleArr[3] && !isTop(this.notesT))
setVisibleTitle(3);
else if (cmbL && this.showTitleArr[2] && !isTop(this.cmbcon))
setVisibleTitle(2);
else if (insL && this.showTitleArr[1] && !isTop(this.inscon))
setVisibleTitle(1);
else if (ingL && this.showTitleArr[0] && !isTop(this.ingcon))
setVisibleTitle(0);
}
2021-04-14 09:27:40 +00:00
},
2021-04-01 10:55:35 +00:00
onScroll(args) {
2021-04-21 10:31:49 +00:00
let swipeUp: boolean;
2021-04-01 10:55:35 +00:00
let y = args.scrollY;
if (y) {
2021-04-21 10:31:49 +00:00
swipeUp = y > this.scrollPos;
2021-04-01 10:55:35 +00:00
this.scrollPos = Math.abs(y);
2021-04-21 10:31:49 +00:00
this.fixTitle(args, swipeUp);
if (!this.toast) {
let ab = this.appbar.translateY;
if (swipeUp && ab == 0)
this.appbar.animate({
translate: { x: 0, y: 64 },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
});
else if (!swipeUp && ab == 64)
this.appbar.animate({
translate: { x: 0, y: 0 },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
});
}
2021-04-01 10:55:35 +00:00
}
},
2020-11-10 18:28:48 +00:00
// HELPERS
2021-04-12 18:09:48 +00:00
getTitleCount(title, type) {
let count = this.recipe[type].length;
let selected = null;
switch (title) {
case "ings":
selected = this.checked;
break;
case "inss":
selected = this.stepsDid;
break;
}
let text = selected ? ` (${selected}/${count})` : ` (${count})`;
return localize(title) + text;
},
2021-04-01 10:55:35 +00:00
changeYield() {
this.$showModal(PromptDialog, {
props: {
2021-04-16 04:50:04 +00:00
title: `${localize("req", localize(this.recipe.yield.unit))}`,
2021-04-01 10:55:35 +00:00
placeholder: Math.abs(parseFloat(this.yieldMultiplier)),
action: "SET",
},
}).then((item) => {
if (item) this.yieldMultiplier = item;
});
},
hasTime(time) {
return time != "00:00";
},
2021-02-28 15:10:26 +00:00
niceDate(time) {
let lastTried = new Date(time).getTime();
let now = new Date().getTime();
let midnight = new Date().setHours(0, 0, 0, 0);
let diff = (now - lastTried) / 1000;
let dayDiff = Math.ceil(diff / 86400);
if (isNaN(dayDiff) || dayDiff < 0) return "";
2021-04-21 10:31:49 +00:00
function duration(value, number?) {
2021-04-17 16:24:47 +00:00
return number ? localize(value, number) : localize(value);
}
return (
2021-02-28 15:10:26 +00:00
(diff < 86400 && lastTried > midnight && duration("today")) ||
(dayDiff == 1 && "yesterday") ||
2021-04-17 16:24:47 +00:00
(dayDiff < 7 && duration("dAgo", dayDiff)) ||
(dayDiff < 31 && duration("wAgo", Math.round(dayDiff / 7))) ||
(dayDiff < 366 && duration("mAgo", Math.round(dayDiff / 30))) ||
2021-02-28 15:10:26 +00:00
(dayDiff > 365 && duration("ltAgo"))
);
},
2020-11-10 18:28:48 +00:00
showLastTried() {
2021-04-15 17:24:14 +00:00
this.toast = localize("triedInfo", this.niceDate(this.recipe.lastTried));
2021-04-17 16:24:47 +00:00
utils.timer(10, (val) => {
2021-04-12 18:09:48 +00:00
if (!val) this.toast = val;
});
2021-02-28 15:10:26 +00:00
},
2021-04-21 10:31:49 +00:00
// getMeasure(value: number, unit: string) {
// let vm = this;
// function roundedQ(val: number) {
// return Math.abs(
// Math.round(
// (val / vm.recipe.yield.quantity) * vm.tempYieldQuantity * 100
// ) / 100
// );
// }
// if (value) {
// let rounded = Math.abs(
// Math.round(
// (value / this.recipe.yield.quantity) * this.tempYieldQuantity * 100
// ) / 100
// );
// let lUnit = localize(unit);
// switch (unit) {
// //IMPERIAL
// case "g":
// return rounded < 1000
// ? `${rounded} ${lUnit} `
// : `${roundedQ(rounded / 1000)} ${localize("kg")} `;
// case "ml":
// return rounded < 1000
// ? `${rounded} ${lUnit} `
// : `${roundedQ(rounded / 1000)} ${localize("l")} `;
// //METRIC
// case "tsp":
// return rounded < 3
// ? `${rounded} ${lUnit} `
// : `${roundedQ(rounded / 3)} ${localize("tbsp")} `;
// case "in":
// return rounded < 12
// ? `${rounded} ${lUnit} `
// : `${roundedQ(rounded / 12)} ${localize("ft")} `;
// default:
// return `${rounded} ${lUnit} `;
// }
// } else return "";
// },
roundedQuantity(quantity: number) {
2021-02-28 15:10:26 +00:00
return Math.abs(
Math.round(
2021-04-12 18:09:48 +00:00
(quantity / this.recipe.yield.quantity) * this.tempYieldQuantity * 100
2021-02-28 15:10:26 +00:00
) / 100
);
},
keepScreenOn(boolean) {
let activity =
Application.android.foregroundActivity ||
Application.android.startActivity;
let window = activity.getWindow();
2021-04-01 10:55:35 +00:00
let flag = android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
boolean ? window.addFlags(flag) : window.clearFlags(flag);
2021-02-28 15:10:26 +00:00
},
formattedTime(time) {
let t = 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}`;
},
formattedDate(date) {
let d = new Date(date);
var dateFormat = new intl.DateTimeFormat(null, {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
}).format(d);
return `${dateFormat}`;
},
isValidURL(string) {
let pattern = new RegExp("^https?|^www", "ig");
return pattern.test(string);
},
getCombinationTitle(id) {
return this.recipes.filter((e) => e.id === id)[0].title;
2020-11-15 10:51:10 +00:00
},
syncCombinations() {
2021-02-28 15:10:26 +00:00
let combinationForOtherRecipes = this.recipes
.filter(
(e) =>
e.combinations.indexOf(this.currentRecipeID) >= 0 ||
this.recipe.combinations.includes(e.id)
)
.map((e) => e.id);
this.recipe.combinations = combinationForOtherRecipes;
this.overwriteRecipeAction({
2020-11-15 10:51:10 +00:00
id: this.currentRecipeID,
recipe: this.recipe,
2021-02-28 15:10:26 +00:00
});
2020-11-15 10:51:10 +00:00
},
2021-04-01 10:55:35 +00:00
touchIngredient({ object, action }, index) {
object.className = action.match(/down|move/)
? "ingredient fade"
: "ingredient";
if (action == "up") this.checkChange(object, index);
2021-01-23 17:20:15 +00:00
},
2021-04-12 18:09:48 +00:00
checkChange(obj, index) {
this.checks[index] = !this.checks[index];
if (this.checks[index]) {
this.checked++;
obj.getChildAt(0).text = this.icon.check;
} else {
this.checked--;
obj.getChildAt(0).text = this.icon.uncheck;
}
},
2021-01-23 17:20:15 +00:00
clearChecks() {
2021-04-12 18:09:48 +00:00
this.checked = 0;
this.checks = [];
2021-04-14 09:27:40 +00:00
for (let i = 1; i < this.ingcon.getChildrenCount(); i++) {
2021-04-12 18:09:48 +00:00
this.ingcon.getChildAt(i).getChildAt(0).text = this.icon.uncheck;
2021-04-01 10:55:35 +00:00
}
},
touchInstruction({ object, action }) {
let hasDone = object.className.includes("done");
object.className = action.match(/down|move/)
2021-04-12 18:09:48 +00:00
? `instruction ${hasDone ? "done" : "fade"}`
2021-04-01 10:55:35 +00:00
: `instruction ${hasDone ? "done" : ""}`;
if (action == "up") this.stepDone(object);
2020-11-28 19:21:57 +00:00
},
2021-04-12 18:09:48 +00:00
stepDone(object) {
let a = object;
if (a.className.includes("done")) {
a.className = "instruction";
this.stepsDid--;
} else {
a.className = "instruction done";
this.stepsDid++;
}
},
2021-01-23 17:20:15 +00:00
clearSteps() {
2021-04-12 18:09:48 +00:00
this.stepsDid = 0;
2021-04-14 09:27:40 +00:00
for (let i = 1; i < this.inscon.getChildrenCount(); i++) {
2021-04-01 10:55:35 +00:00
this.inscon.getChildAt(i).className = "instruction";
}
2021-01-23 17:20:15 +00:00
},
// NAVIGATION HANDLERS
2020-10-14 19:32:32 +00:00
editRecipe() {
2021-02-28 15:10:26 +00:00
this.busy = true;
this.$navigateTo(EditRecipe, {
2020-10-21 17:54:45 +00:00
props: {
2020-11-28 19:21:57 +00:00
navigationFromView: true,
filterTrylater: this.filterTrylater,
2020-11-15 10:51:10 +00:00
recipeID: this.currentRecipeID,
2020-10-21 17:54:45 +00:00
},
2021-04-01 10:55:35 +00:00
// backstackVisible: false,
2021-02-28 15:10:26 +00:00
});
},
viewCombination(combination) {
2021-04-01 10:55:35 +00:00
this.scrollview.scrollToVerticalOffset(0, true);
2021-02-28 15:10:26 +00:00
this.recipe = this.recipes.filter((e) => e.id === combination)[0];
2021-04-21 10:31:49 +00:00
this.showTitleArr = new Array(4).fill(false);
2021-04-01 10:55:35 +00:00
this.clearChecks();
2021-04-12 18:09:48 +00:00
this.clearSteps();
this.recipe.ingredients.forEach(() => this.checks.push(false));
2021-02-28 15:10:26 +00:00
this.currentRecipeID = combination;
this.syncCombinations();
2021-04-01 10:55:35 +00:00
this.createNotes();
2021-04-12 18:09:48 +00:00
this.yieldMultiplier = this.recipe.yield.quantity;
2021-04-01 10:55:35 +00:00
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
2020-11-15 10:51:10 +00:00
},
2021-01-23 17:20:15 +00:00
2020-11-10 18:28:48 +00:00
// SHARE ACTION
shareHandler() {
2021-02-28 15:10:26 +00:00
if (this.recipe.imageSrc) {
2021-04-01 10:55:35 +00:00
this.$showModal(ActionDialog, {
2020-11-10 18:28:48 +00:00
props: {
2021-01-13 05:02:48 +00:00
title: "shr",
2021-04-18 13:28:25 +00:00
list: ["rec", "pht"],
2020-11-10 18:28:48 +00:00
},
2021-02-28 15:10:26 +00:00
}).then((result) => {
switch (result) {
2021-04-18 13:28:25 +00:00
case "rec":
this.shareRecipe();
break;
2021-04-01 10:55:35 +00:00
case "pht":
2021-04-12 19:25:14 +00:00
ImageSource.fromFile(this.recipe.imageSrc).then((res) =>
utils.shareImage(res, localize("srpu"))
);
2021-02-28 15:10:26 +00:00
break;
2020-11-10 18:28:48 +00:00
}
2021-02-28 15:10:26 +00:00
});
2020-12-29 10:35:19 +00:00
} else {
2021-02-28 15:10:26 +00:00
this.shareRecipe();
2020-11-10 18:28:48 +00:00
}
},
shareRecipe() {
2021-04-18 18:34:17 +00:00
let overview = `${this.recipe.title}\n\n`;
if (this.recipe.rating)
overview += `${localize("stars")}: ${this.recipe.rating}\n`;
overview += `${localize("cui")}: ${localize(
this.recipe.cuisine
)}\n${localize("cat")}: ${localize(this.recipe.category)}\n`;
if (this.recipe.tags.length)
overview += `${localize("ts")}: ${this.recipe.tags.join(", ")}\n`;
if (this.recipe.prepTime != "00:00")
overview += `${localize("prepT")}: ${this.formattedTime(
this.recipe.prepTime
)}\n`;
if (this.recipe.cookTime != "00:00")
overview += `${localize("cookT")}: ${this.formattedTime(
this.recipe.cookTime
)}\n`;
overview += `${localize("yld")}: ${this.tempYieldQuantity} ${localize(
this.recipe.yield.unit
)}\n${localize("Difficulty level")}: ${localize(
this.recipe.difficulty
)}\n`;
2021-02-28 15:10:26 +00:00
let shareContent = overview;
if (this.recipe.ingredients.length) {
2021-04-12 18:09:48 +00:00
let ingredients = `\n\n${localize("ings")}:\n\n`;
2021-02-28 15:10:26 +00:00
this.recipe.ingredients.forEach((e) => {
2020-11-10 18:28:48 +00:00
ingredients += `- ${
e.quantity
2021-02-28 15:10:26 +00:00
? this.roundedQuantity(e.quantity) +
" " +
this.$options.filters.L(e.unit) +
" "
2020-11-10 18:28:48 +00:00
: ""
2021-02-28 15:10:26 +00:00
}${e.item}\n`;
});
shareContent += ingredients;
}
2021-02-28 15:10:26 +00:00
if (this.recipe.instructions.length) {
2021-04-12 18:09:48 +00:00
let instructions = `\n\n${localize("inss")}:\n\n`;
2021-02-28 15:10:26 +00:00
this.recipe.instructions.forEach((e, i) => {
instructions += `${i + 1}. ${e}\n\n`;
});
shareContent += instructions;
}
2021-02-28 15:10:26 +00:00
if (this.recipe.combinations.length) {
let combinations = `\n${localize("cmbs")}:\n\n`;
this.recipe.combinations.forEach((e, i) => {
combinations += `${i + 1}. ${this.getCombinationTitle(e)}\n\n`;
});
shareContent += combinations;
2020-12-29 10:35:19 +00:00
}
2021-04-12 18:09:48 +00:00
if (this.recipe.notes.length) {
let notes = `\n${localize("nos")}:\n\n`;
this.recipe.notes.forEach((e, i) => {
notes += `${i + 1}. ${e}\n\n`;
});
shareContent += notes;
}
2021-02-28 15:10:26 +00:00
let sharenote = "\n" + localize("appCrd");
shareContent += sharenote;
2021-04-12 19:25:14 +00:00
utils.shareText(shareContent, localize("sru"));
},
2021-01-23 17:20:15 +00:00
2020-11-10 18:28:48 +00:00
// DATA HANDLERS
2021-02-28 15:10:26 +00:00
toggle(key, setDate) {
this.toggleStateAction({
2020-11-15 10:51:10 +00:00
id: this.currentRecipeID,
2020-10-26 20:49:54 +00:00
recipe: this.recipe,
key,
2020-11-02 11:36:53 +00:00
setDate,
2021-02-28 15:10:26 +00:00
});
2020-10-26 20:49:54 +00:00
},
recipeTried() {
2021-02-28 15:10:26 +00:00
this.setRecipeAsTriedAction({
id: this.currentRecipeID,
recipe: this.recipe,
2021-02-28 15:10:26 +00:00
});
this.$navigateBack();
2020-10-14 19:32:32 +00:00
},
2021-02-28 15:10:26 +00:00
setRating(rating) {
if (rating !== this.recipe.rating || rating === 1) {
this.setRatingAction({
2020-12-29 10:35:19 +00:00
id: this.currentRecipeID,
recipe: this.recipe,
rating,
2021-02-28 15:10:26 +00:00
});
2020-12-29 10:35:19 +00:00
}
},
2021-01-23 17:20:15 +00:00
2021-01-13 05:02:48 +00:00
// SHOPPINGLIST
toggleCart() {
2021-02-28 15:10:26 +00:00
if (!this.recipe.inBag) {
2021-01-13 05:02:48 +00:00
} else {
}
2021-02-28 15:10:26 +00:00
this.toggleCartAction({
2021-01-13 05:02:48 +00:00
id: this.currentRecipeID,
recipe: this.recipe,
2021-02-28 15:10:26 +00:00
});
2021-01-13 05:02:48 +00:00
},
2021-01-23 17:20:15 +00:00
2020-12-02 10:37:45 +00:00
// NOTES
2021-04-01 10:55:35 +00:00
createNote(note) {
2021-02-28 15:10:26 +00:00
let regex = /(https?:\/\/[^\s]+)/g;
2021-04-01 10:55:35 +00:00
const lbl = new Label();
2021-04-21 10:31:49 +00:00
lbl.className = "note";
2021-04-01 10:55:35 +00:00
lbl.textWrap = true;
let fString = new FormattedString();
let arr = note.split(regex);
2020-12-02 09:46:25 +00:00
2021-02-28 15:10:26 +00:00
function createSpan(text, isUrl) {
let span = new Span();
span.text = text;
span.fontSize = 14;
if (isUrl) {
span.textDecoration = "underline";
span.on("linkTap", () => Utils.openUrl(text));
2020-12-02 09:46:25 +00:00
}
2021-04-01 10:55:35 +00:00
fString.spans.push(span);
2020-12-02 09:46:25 +00:00
}
2021-04-01 10:55:35 +00:00
arr.forEach((text) => {
2021-02-28 15:10:26 +00:00
createSpan(text, regex.test(text));
});
2021-04-01 10:55:35 +00:00
lbl.formattedText = fString;
return lbl;
},
createNotes() {
const stack = this.notescon;
stack.removeChildren();
this.recipe.notes.forEach((note) =>
stack.addChild(this.createNote(note))
);
},
getTags(tags) {
return tags.join(" · ");
},
2021-04-12 18:09:48 +00:00
hijackBackEvent() {
2021-04-21 10:31:49 +00:00
Application.android.on(
2021-04-12 18:09:48 +00:00
AndroidApplication.activityBackPressedEvent,
this.backEvent
);
},
releaseBackEvent() {
2021-04-21 10:31:49 +00:00
Application.android.off(
2021-04-12 18:09:48 +00:00
AndroidApplication.activityBackPressedEvent,
this.backEvent
);
},
backEvent(args) {
if (this.photoOpen) {
args.cancel = true;
this.closePhoto();
} else this.$navigateBack();
},
viewPhoto() {
2021-04-21 10:31:49 +00:00
// this.imgView.initNativeView();
2021-04-12 18:09:48 +00:00
this.photoOpen = true;
this.hijackBackEvent();
2021-04-21 10:31:49 +00:00
let pv = this.imgView;
2021-04-12 18:09:48 +00:00
pv.visibility = "visible";
let sw = Screen.mainScreen.widthDIPs;
let sh = Screen.mainScreen.heightDIPs;
pv.animate({
opacity: 1,
duration: 50,
})
.then(() =>
pv.animate({
width: sw,
height: sw,
translate: { x: 112 - sw, y: (sh - sw) / 3 },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
})
)
.then(() =>
pv.animate({
2021-04-21 10:31:49 +00:00
height: sh,
2021-04-12 18:09:48 +00:00
translate: { x: -sw + 112, y: -((sh - sw) / 6) },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
})
2021-04-01 10:55:35 +00:00
);
},
2021-04-12 18:09:48 +00:00
closePhoto() {
2021-04-21 10:31:49 +00:00
let pv = this.imgView;
2021-04-12 18:09:48 +00:00
let sw = Screen.mainScreen.widthDIPs;
let sh = Screen.mainScreen.heightDIPs;
pv.animate({
width: sw,
height: sw,
translate: { x: 112 - sw, y: (sh - sw) / 3 },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
})
.then(() =>
pv.animate({
width: 96,
height: 96,
translate: { x: 0, y: 0 },
duration: 250,
curve: CoreTypes.AnimationCurve.ease,
})
)
.then(() =>
pv.animate({
opacity: 0,
duration: 50,
})
)
.then(() => {
pv.visibility = "collapsed";
this.photoOpen = false;
this.releaseBackEvent();
});
},
navigateBack() {
this.photoOpen ? this.closePhoto() : this.$navigateBack();
},
//HELPERS
2021-04-01 10:55:35 +00:00
touchYield({ object, action }) {
object.className = action.match(/down|move/)
? "value clickable fade"
: "value clickable";
if (action == "up") this.changeYield();
},
},
created() {
2021-02-28 15:10:26 +00:00
this.recipe = this.recipes.filter((e) => e.id === this.currentRecipeID)[0];
this.recipe.ingredients.forEach((e) => this.checks.push(false));
2020-10-14 19:32:32 +00:00
},
mounted() {
2021-02-28 15:10:26 +00:00
this.yieldMultiplier = this.recipe.yield.quantity;
2021-04-01 10:55:35 +00:00
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
},
2021-02-28 15:10:26 +00:00
};
2020-10-14 19:32:32 +00:00
</script>