2020-10-14 19:32:32 +00:00
< template >
2020-12-07 14:45:00 +00:00
< Page @loaded ="onPageLoad" @unloaded ="releaseBackEvent" >
< ActionBar : androidElevation = "viewIsScrolled ? 4 : 0" >
< GridLayout rows = "*" columns = "auto, *, auto" >
< MDButton variant = "text" class = "bx" :text = "icon.back" automationText = "Back" col = "0" @tap ="navigateBack" / >
< Label class = "title orkm" : text = "`${title}` | L" col = "1" / >
< MDButton variant = "text" v-if = "hasChanges && !saving" class="bx" :text="icon.save" col="2" @tap="saveOperation" / >
< MDActivityIndicator col = "2" v-if = "saving" :busy="saving" / >
< / GridLayout >
< / ActionBar >
< ScrollView width = "100%" height = "100%" @scroll ="onScroll" >
< 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 = "bx" fontSize = "160" :text = "icon.image" / >
< / StackLayout >
< transition : name = "recipeContent.imageSrc ? 'null' : 'bounce'" >
< MDFloatingActionButton v-if = "showFab" :top="screenWidth - 44" :left="screenWidth - 88" class="bx" src="res://camera" @tap="imageHandler" / >
< / transition >
< / AbsoluteLayout >
< StackLayout margin = "0 16" >
< AbsoluteLayout class = "inputField" >
< TextField : hint = "'My Healthy Recipe' | L" v-model = "recipeContent.title" @loaded="setInputTypeText($event, 'words')" / >
< Label top = "0" class = "fieldLabel" : text = "'Title' | L" / >
2020-11-17 21:21:08 +00:00
< / AbsoluteLayout >
2020-12-29 10:35:19 +00:00
< GridLayout columns = "*, 8, *" >
< AbsoluteLayout class = "inputField" col = "0" >
< TextField : text = "`${recipeContent.cuisine}` | L" editable = "false" @ focus = "modalOpen === false && showCuisine(true)" @tap ="showCuisine(false)" / >
< Label top = "0" class = "fieldLabel" : text = "'Cuisine' | L" / >
< / AbsoluteLayout >
< AbsoluteLayout class = "inputField" col = "2" >
< TextField ref = 'category' : text = "`${recipeContent.category}` | L" editable = "false" @ focus = "modalOpen === false && showCategories(true)" @tap ="showCategories(false)" / >
< Label top = "0" class = "fieldLabel" : text = "'Category' | L" / >
< / AbsoluteLayout >
< / GridLayout >
2020-12-07 14:45:00 +00:00
< AbsoluteLayout class = "inputField" >
2020-12-29 10:35:19 +00:00
< TextField autocapitalizationType = "words" ref = 'tags' : hint = "`${$options.filters.L('separate with spaces')}`" v-model = "tags" @textChange="splitTags" returnKeyType="next" / >
< Label top = "0" class = "fieldLabel" : text = "`${$options.filters.L('Tags')} (${$options.filters.L('separate with spaces')})`" / >
2020-12-07 14:45:00 +00:00
< / AbsoluteLayout >
< GridLayout columns = "*, 8, *" >
< AbsoluteLayout class = "inputField" col = "0" >
2020-12-29 10:35:19 +00:00
< TextField :text = "timeRequired('prepTime')" editable = "false" @ focus = "
2020-12-01 09:22:22 +00:00
modalOpen === false && setTimeRequired ( true , 'prepTime' )
2020-12-07 14:45:00 +00:00
" @tap=" setTimeRequired ( false , 'prepTime' ) " / >
< Label top = "0" class = "fieldLabel" : text = "'Preparation time' | L" / >
< / AbsoluteLayout >
< AbsoluteLayout class = "inputField" col = "2" >
< TextField ref = "cookTime" :text = "timeRequired('cookTime')" editable = "false" @ focus = "
2020-12-01 09:22:22 +00:00
modalOpen === false && setTimeRequired ( true , 'cookTime' )
2020-12-07 14:45:00 +00:00
" @tap=" setTimeRequired ( false , 'cookTime' ) " / >
< Label top = "0" class = "fieldLabel" : text = "'Cooking time' | L" / >
< / AbsoluteLayout >
< / GridLayout >
< GridLayout columns = "*, 8, *" >
< AbsoluteLayout class = "inputField" col = "0" >
< TextField ref = "yieldQuantity" v-model = "recipeContent.yield.quantity" hint="1" keyboardType="number" returnKeyType="next" / >
< Label top = "0" class = "fieldLabel" : text = "'Yield quantity' | L" / >
< / AbsoluteLayout >
< AbsoluteLayout class = "inputField" col = "2" >
< TextField : text = "`${recipeContent.yield.unit}` | L" editable = "false" @ focus = "modalOpen === false && showYieldUnits(true)" @tap ="showYieldUnits(false)" / >
< Label top = "0" class = "fieldLabel" : text = "'Yield measured in' | L" / >
< / AbsoluteLayout >
< / GridLayout >
2020-12-29 10:35:19 +00:00
< GridLayout columns = "*, 8, *" >
< AbsoluteLayout class = "inputField" col = "0" >
< TextField ref = "difficultyLevel" : text = "`${recipeContent.difficulty}` | L" editable = "false" @ focus = "modalOpen === false && showDifficultyLevel(true)" @tap ="showDifficultyLevel(false)" / >
< Label top = "0" class = "fieldLabel" : text = "'Difficulty level' | L" / >
< / AbsoluteLayout >
< / GridLayout >
2020-12-07 14:45:00 +00:00
< StackLayout class = "hr" margin = "24 16" > < / StackLayout >
< / StackLayout >
< StackLayout margin = "0 16" >
< Label : text = "'Ingredients' | L" class = "sectionTitle" / >
2020-12-29 10:35:19 +00:00
< GridLayout columns = "auto,8,auto,8,*,8,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" / >
< 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)" / >
< TextField ref = "ingredient" @ loaded = "setInputTypeText($event, 'sentence')" col = "4" v-model = "recipeContent.ingredients[index].item" :hint="`${$options.filters.L('Item')} ${index + 1}`"
@ returnPress = "index+1 == recipeContent.ingredients.length && addIngredient()" / >
2020-12-07 14:45:00 +00:00
< MDButton variant = "text" col = "6" class = "bx closeBtn" :text = "icon.close" @tap ="removeIngredient(index)" / >
< / GridLayout >
< MDButton variant = "text" class = "text-btn orkm" : text = "`+ ${$options.filters.L('ADD INGREDIENT')}`" @tap ="addIngredient()" / >
< StackLayout class = "hr" margin = "24 16" > < / StackLayout >
2020-11-17 21:21:08 +00:00
< / StackLayout >
2020-12-07 14:45:00 +00:00
< StackLayout margin = "0 16" >
< Label : text = "'Instructions' | 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('Step')} ${index + 1}`" v-model = "recipeContent.instructions[index]" / >
< MDButton variant = "text" col = "2" class = "bx closeBtn" :text = "icon.close" @tap ="removeInstruction(index)" / >
< / GridLayout >
< MDButton variant = "text" class = "text-btn orkm" : text = "`+ ${$options.filters.L('ADD STEP')}`" @tap ="addInstruction" / >
< StackLayout class = "hr" margin = "24 16" > < / StackLayout >
< / StackLayout >
< StackLayout margin = "0 16" >
< Label : text = "'Notes' | 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('Note')} ${index + 1}`" v-model = "recipeContent.notes[index]" / >
< MDButton variant = "text" col = "2" class = "bx closeBtn" :text = "icon.close" @tap ="removeNote(index)" / >
< / GridLayout >
< MDButton variant = "text" class = "text-btn orkm" : text = "`+ ${$options.filters.L('ADD NOTE')}`" @tap ="addNote" / >
2020-12-29 10:35:19 +00:00
< StackLayout class = "hr" margin = "24 16" > < / StackLayout >
< / StackLayout >
< StackLayout margin = "0 16" >
< Label : text = "'Combinations' | 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 = "bx closeBtn" :text = "icon.close" @tap ="removeCombination(combination)" / >
< / GridLayout >
< MDButton variant = "text" class = "text-btn orkm" : text = "`+ ${$options.filters.L('ADD COMBINATION')}`" @tap ="showCombinations" / >
2020-12-07 14:45:00 +00:00
< / StackLayout >
< / StackLayout >
< / ScrollView >
< / Page >
2020-10-14 19:32:32 +00:00
< / template >
< script >
2020-10-24 18:02:35 +00:00
import {
AndroidApplication ,
2020-11-10 18:28:48 +00:00
Application ,
ApplicationSettings ,
File ,
2020-10-24 18:02:35 +00:00
getFileAccess ,
2020-11-10 18:28:48 +00:00
ImageSource ,
2020-10-24 18:02:35 +00:00
knownFolders ,
2020-11-10 18:28:48 +00:00
path ,
Screen ,
2020-11-02 11:36:53 +00:00
Utils ,
2020-12-07 14:45:00 +00:00
Observable
}
from "@nativescript/core"
2020-11-10 18:28:48 +00:00
import * as Permissions from "@nativescript-community/perms"
import * as Toast from "nativescript-toast"
2020-11-11 13:50:33 +00:00
import * as Filepicker from "nativescript-plugin-filepicker"
2020-12-07 14:45:00 +00:00
import {
ImageCropper
}
from "nativescript-imagecropper"
import {
localize
}
from "@nativescript/localize"
import {
mapState ,
mapActions
}
from "vuex"
2020-11-28 19:21:57 +00:00
import ViewRecipe from "./ViewRecipe.vue"
2020-10-21 17:54:45 +00:00
import ActionDialog from "./modal/ActionDialog.vue"
2020-11-15 10:51:10 +00:00
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue"
2020-10-21 17:54:45 +00:00
import ConfirmDialog from "./modal/ConfirmDialog.vue"
2020-10-29 20:12:53 +00:00
import PromptDialog from "./modal/PromptDialog.vue"
2020-11-02 11:36:53 +00:00
import ListPicker from "./modal/ListPicker.vue"
2020-11-23 09:49:58 +00:00
import * as utils from "~/shared/utils"
2020-10-14 19:32:32 +00:00
export default {
2020-12-29 10:35:19 +00:00
props : [ "recipeID" , "selectedCuisine" , "selectedCategory" , "selectedTag" , "filterFavourites" , "filterTrylater" , "navigationFromView" , ] ,
2020-10-14 19:32:32 +00:00
data ( ) {
return {
2020-10-21 17:54:45 +00:00
title : "New recipe" ,
2020-10-14 19:32:32 +00:00
viewIsScrolled : false ,
recipeContent : {
imageSrc : null ,
2020-10-29 20:12:53 +00:00
title : undefined ,
2020-12-29 10:35:19 +00:00
cuisine : "Undefined" ,
2020-10-29 20:12:53 +00:00
category : "Undefined" ,
2020-12-29 10:35:19 +00:00
tags : [ ] ,
2020-12-01 09:22:22 +00:00
prepTime : "00:00" ,
cookTime : "00:00" ,
2020-11-02 11:36:53 +00:00
yield : {
quantity : undefined ,
2020-12-07 14:45:00 +00:00
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 ,
2020-10-26 20:49:54 +00:00
} ,
2020-10-29 20:12:53 +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 ,
2020-10-24 18:02:35 +00:00
newRecipeID : null ,
2020-10-29 20:12:53 +00:00
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 : [ ] ,
2020-12-29 10:35:19 +00:00
difficultyLevels : [
"Easy" ,
"Moderate" ,
"Challenging" ,
] ,
2020-10-14 19:32:32 +00:00
}
} ,
computed : {
2020-12-29 10:35:19 +00:00
... mapState ( [ "icon" , "units" , "yieldUnits" , "recipes" , "cuisines" , "categories" , "currentComponent" , ] ) ,
2020-10-14 19:32:32 +00:00
screenWidth ( ) {
2020-10-22 18:36:50 +00:00
return Screen . mainScreen . widthDIPs
2020-10-14 19:32:32 +00:00
} ,
2020-11-10 18:28:48 +00:00
appTheme ( ) {
return Application . systemAppearance ( )
} ,
hasChanges ( ) {
2020-12-07 14:45:00 +00:00
return ( JSON . stringify ( this . recipeContent ) !== JSON . stringify ( this . tempRecipeContent ) )
2020-10-14 19:32:32 +00:00
} ,
} ,
methods : {
2020-12-29 10:35:19 +00:00
... mapActions ( [ "setCurrentComponentAction" , "addRecipeAction" , "overwriteRecipeAction" , "addListItemAction" , "unSyncCombinationsAction" , ] ) ,
2020-12-07 14:45:00 +00:00
onPageLoad ( args ) {
const page = args . object ;
page . bindingContext = new Observable ( ) ;
2020-10-29 20:12:53 +00:00
this . showFab = true
} ,
2020-12-07 14:45:00 +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-12-01 09:22:22 +00:00
} ,
2020-11-02 11:36:53 +00:00
// HELPERS
2020-12-07 14:45:00 +00:00
focusField ( args , type ) {
if ( type ) this . setInputTypeText ( args , type )
if ( ! args . object . text ) {
2020-11-02 11:36:53 +00:00
args . object . focus ( )
2020-12-29 10:35:19 +00:00
setTimeout ( ( e ) => Utils . ad . showSoftInput ( args . object . android ) , 100 )
2020-11-02 11:36:53 +00:00
}
} ,
2020-12-07 14:45:00 +00:00
setInputTypeText ( args , type ) {
2020-11-11 13:50:33 +00:00
let field = args . object
2020-12-29 10:35:19 +00:00
let common = android . text . InputType . TYPE _CLASS _TEXT | android . text . InputType . TYPE _TEXT _FLAG _AUTO _CORRECT
2020-12-07 14:45:00 +00:00
switch ( type ) {
2020-11-11 13:50:33 +00:00
case "words" :
2020-12-29 10:35:19 +00:00
field . android . setInputType ( android . text . InputType . TYPE _TEXT _FLAG _CAP _WORDS | common )
2020-11-11 13:50:33 +00:00
break
case "sentence" :
2020-12-29 10:35:19 +00:00
field . android . setInputType ( android . text . InputType . TYPE _TEXT _FLAG _CAP _SENTENCES | common )
2020-11-11 13:50:33 +00:00
break
case "multiLine" :
2020-12-29 10:35:19 +00:00
field . android . setInputType ( android . text . InputType . TYPE _TEXT _FLAG _MULTI _LINE | android . text . InputType . TYPE _TEXT _FLAG _CAP _SENTENCES | common )
2020-11-11 13:50:33 +00:00
break
default :
break
}
} ,
2020-10-24 18:02:35 +00:00
getRandomID ( ) {
let res = ""
let chars = "abcdefghijklmnopqrstuvwxyz0123456789"
2020-12-29 10:35:19 +00:00
for ( let i = 0 ; i < 20 ; i ++ ) {
2020-12-07 14:45:00 +00:00
res += chars . charAt ( Math . floor ( Math . random ( ) * chars . length ) )
2020-10-24 18:02:35 +00:00
}
return res
2020-10-21 17:54:45 +00:00
} ,
2020-12-07 14:45:00 +00:00
setTimeRequired ( focus , time ) {
2020-11-11 13:50:33 +00:00
this . modalOpen = true
2020-12-07 14:45:00 +00:00
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 : {
2020-12-01 09:22:22 +00:00
title : ` ${ time == "prepTime" ? "Preparation" : "Cooking" } time ` ,
2020-11-02 11:36:53 +00:00
action : "SET" ,
selectedHr : hr ,
selectedMin : min ,
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( result ) => {
if ( result ) {
this . recipeContent [ time ] = result
2020-11-11 13:50:33 +00:00
this . modalOpen = false
2020-12-07 14:45:00 +00:00
if ( focus ) {
switch ( time ) {
2020-12-01 09:22:22 +00:00
case "prepTime" :
2020-12-07 14:45:00 +00:00
this . autoFocusField ( "cookTime" , false )
2020-12-01 09:22:22 +00:00
break
case "cookTime" :
2020-12-07 14:45:00 +00:00
this . autoFocusField ( "yieldQuantity" , true )
2020-12-01 09:22:22 +00:00
break
default :
break
}
}
2020-10-21 17:54:45 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-10-14 19:32:32 +00:00
} ,
2020-12-07 14:45:00 +00:00
onScroll ( args ) {
2020-11-28 19:21:57 +00:00
this . viewIsScrolled = args . scrollY ? true : false
2020-10-14 19:32:32 +00:00
} ,
2020-11-02 11:36:53 +00:00
// DATA LIST
2020-12-29 10:35:19 +00:00
showCuisine ( focus ) {
this . modalOpen = true
this . releaseBackEvent ( )
this . $showModal ( ActionDialog , {
props : {
title : "Cuisine" ,
list : this . cuisines ,
stretch : true ,
action : "ADD NEW" ,
} ,
} ) . then ( ( action ) => {
if ( action == "ADD NEW" ) {
this . $showModal ( PromptDialog , {
props : {
title : "New cuisine" ,
action : "ADD" ,
} ,
} ) . then ( ( item ) => {
this . hijackBackEvent ( )
if ( item . length ) {
this . recipeContent . cuisine = item
ApplicationSettings . setString ( "previousCuisine" , item )
this . addListItemAction ( {
item ,
listName : 'cuisines'
} )
this . modalOpen = false
if ( focus ) this . autoFocusField ( "category" , false )
}
} )
} else if ( action ) {
this . recipeContent . cuisine = action
ApplicationSettings . setString ( "previousCuisine" , action )
this . hijackBackEvent ( )
this . modalOpen = false
if ( focus ) this . autoFocusField ( "category" , false )
} else {
this . cuisines . includes ( this . recipeContent . cuisine ) ? mull : this . recipeContent . cuisine = 'Undefined'
this . hijackBackEvent ( )
}
} )
} ,
2020-12-07 14:45:00 +00:00
showCategories ( focus ) {
2020-11-11 13:50:33 +00:00
this . modalOpen = true
2020-10-21 17:54:45 +00:00
this . releaseBackEvent ( )
2020-12-07 14:45:00 +00:00
this . $showModal ( ActionDialog , {
2020-10-21 17:54:45 +00:00
props : {
title : "Category" ,
2020-12-29 10:35:19 +00:00
list : this . categories ,
stretch : true ,
2020-11-10 18:28:48 +00:00
action : "ADD NEW" ,
2020-10-21 17:54:45 +00:00
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( action ) => {
if ( action == "ADD NEW" ) {
this . $showModal ( PromptDialog , {
2020-10-21 17:54:45 +00:00
props : {
title : "New category" ,
action : "ADD" ,
} ,
2020-12-29 10:35:19 +00:00
} ) . then ( ( item ) => {
2020-10-21 17:54:45 +00:00
this . hijackBackEvent ( )
2020-12-29 10:35:19 +00:00
if ( item . length ) {
this . recipeContent . category = item
ApplicationSettings . setString ( "previousCategory" , item )
this . addListItemAction ( {
item ,
listName : 'categories'
} )
2020-11-11 13:50:33 +00:00
this . modalOpen = false
2020-12-29 10:35:19 +00:00
if ( focus ) this . autoFocusField ( "tags" , true )
2020-10-21 17:54:45 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else if ( action ) {
2020-10-21 17:54:45 +00:00
this . recipeContent . category = action
2020-12-29 10:35:19 +00:00
ApplicationSettings . setString ( "previousCategory" , action )
2020-10-21 17:54:45 +00:00
this . hijackBackEvent ( )
2020-11-11 13:50:33 +00:00
this . modalOpen = false
2020-12-29 10:35:19 +00:00
if ( focus ) this . autoFocusField ( "tags" , true )
2020-12-12 18:06:10 +00:00
} else {
2020-12-29 10:35:19 +00:00
this . categories . includes ( this . recipeContent . category ) ? mull : this . recipeContent . category = 'Undefined'
2020-10-21 17:54:45 +00:00
this . hijackBackEvent ( )
2020-10-14 19:32:32 +00:00
}
2020-12-07 14:45:00 +00:00
} )
} ,
showYieldUnits ( focus ) {
2020-11-11 13:50:33 +00:00
this . modalOpen = true
2020-11-02 11:36:53 +00:00
this . releaseBackEvent ( )
2020-12-07 14:45:00 +00:00
this . $showModal ( ActionDialog , {
2020-11-02 11:36:53 +00:00
props : {
title : "Yield measured in" ,
2020-12-29 10:35:19 +00:00
list : this . yieldUnits ,
stretch : true ,
2020-11-10 18:28:48 +00:00
action : "ADD NEW" ,
2020-11-02 11:36:53 +00:00
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( action ) => {
if ( action == "ADD NEW" ) {
this . $showModal ( PromptDialog , {
2020-11-02 11:36:53 +00:00
props : {
title : "New yield unit" ,
action : "ADD" ,
} ,
2020-12-29 10:35:19 +00:00
} ) . then ( ( item ) => {
2020-11-02 11:36:53 +00:00
this . hijackBackEvent ( )
2020-12-29 10:35:19 +00:00
if ( item . length ) {
this . recipeContent . yield . unit = item
ApplicationSettings . setString ( "previousYieldUnit" , item )
this . addListItemAction ( {
item ,
listName : 'yieldUnits'
} )
2020-11-11 13:50:33 +00:00
this . modalOpen = false
2020-12-29 10:35:19 +00:00
if ( focus ) this . autoFocusField ( "difficultyLevel" , false )
2020-11-02 11:36:53 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else if ( action ) {
2020-11-02 11:36:53 +00:00
this . recipeContent . yield . unit = action
2020-12-29 10:35:19 +00:00
ApplicationSettings . setString ( "previousYieldUnit" , action )
this . hijackBackEvent ( )
this . modalOpen = false
if ( focus ) this . autoFocusField ( "difficultyLevel" , false )
} else {
this . yieldUnits . includes ( this . recipeContent . yield . unit ) ? mull : this . recipeContent . yield . unit = 'Serving'
this . hijackBackEvent ( )
}
} )
} ,
showDifficultyLevel ( focus ) {
this . modalOpen = true
this . releaseBackEvent ( )
this . $showModal ( ActionDialog , {
props : {
title : "Difficulty level" ,
list : this . difficultyLevels ,
stretch : false ,
} ,
} ) . then ( ( action ) => {
if ( action ) {
this . recipeContent . difficulty = action
2020-11-02 11:36:53 +00:00
this . hijackBackEvent ( )
2020-11-11 13:50:33 +00:00
this . modalOpen = false
2020-12-07 14:45:00 +00:00
if ( focus ) this . addIngredient ( )
2020-12-12 18:06:10 +00:00
} else {
2020-12-29 10:35:19 +00:00
this . difficultyLevels . includes ( this . recipeContent . difficulty ) ? mull : this . recipeContent . difficulty = 'Easy'
2020-11-02 11:36:53 +00:00
this . hijackBackEvent ( )
}
2020-12-07 14:45:00 +00:00
} )
2020-11-02 11:36:53 +00:00
} ,
2020-12-07 14:45:00 +00:00
showUnits ( e , focus , index ) {
2020-11-11 13:50:33 +00:00
this . modalOpen = true
2020-11-02 11:36:53 +00:00
this . releaseBackEvent ( )
2020-12-07 14:45:00 +00:00
this . $showModal ( ActionDialog , {
2020-11-02 11:36:53 +00:00
props : {
2020-12-29 10:35:19 +00:00
title : "Units" ,
list : this . units ,
stretch : true ,
action : "ADD NEW" ,
2020-11-02 11:36:53 +00:00
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( action ) => {
2020-11-02 11:36:53 +00:00
this . hijackBackEvent ( )
2020-12-29 10:35:19 +00:00
if ( action == "ADD NEW" ) {
this . $showModal ( PromptDialog , {
props : {
title : "New unit" ,
action : "ADD" ,
} ,
} ) . then ( ( item ) => {
this . hijackBackEvent ( )
if ( item . length ) {
this . recipeContent . ingredients [ index ] . unit = item
this . addListItemAction ( {
item ,
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
}
2020-12-29 10:35:19 +00:00
} )
} else if ( action ) {
this . recipeContent . ingredients [ index ] . unit = action
this . modalOpen = false
if ( focus && this . recipeContent . ingredients . length - 1 === index ) this . autoFocusRefField ( 'ingredient' , index )
2020-11-11 13:50:33 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-11-02 11:36:53 +00:00
} ,
2020-12-29 10:35:19 +00:00
autoFocusField ( ref , showSoftInput ) {
this . $refs [ ref ] . nativeView . focus ( )
if ( showSoftInput ) {
setTimeout ( ( ) => {
Utils . ad . showSoftInput ( this . $refs [ ref ] . nativeView . android )
} , 100 )
}
} ,
autoFocusRefField ( ref , index ) {
this . $refs [ ref ] [ index ] . nativeView . focus ( )
setTimeout ( ( ) => {
Utils . ad . showSoftInput ( this . $refs [ ref ] [ index ] . nativeView . android )
} , 100 )
} ,
2020-11-02 11:36:53 +00:00
// NAVIGATION HANDLERS
2020-11-28 19:21:57 +00:00
navigateBackController ( ) {
2020-12-07 14:45:00 +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 ,
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else this . $navigateBack ( )
2020-11-28 19:21:57 +00:00
} ,
2020-10-14 19:32:32 +00:00
navigateBack ( ) {
2020-12-07 14:45:00 +00:00
if ( this . hasChanges ) {
2020-10-21 17:54:45 +00:00
this . blockModal = true
2020-12-07 14:45:00 +00:00
this . $showModal ( ConfirmDialog , {
2020-10-21 17:54:45 +00:00
props : {
2020-10-29 20:12:53 +00:00
title : "Unsaved changes" ,
2020-12-07 14:45:00 +00:00
description : localize ( "Are you sure you want to discard unsaved changes to this recipe?" ) ,
2020-10-29 20:12:53 +00:00
cancelButtonText : "DISCARD" ,
2020-11-10 18:28:48 +00:00
okButtonText : "KEEP EDITING" ,
2020-10-21 17:54:45 +00:00
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( action ) => {
2020-10-21 17:54:45 +00:00
this . blockModal = false
2020-12-07 14:45:00 +00:00
if ( action != null && ! action ) {
2020-11-28 19:21:57 +00:00
this . navigateBackController ( )
2020-10-21 17:54:45 +00:00
this . releaseBackEvent ( )
}
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else {
2020-11-28 19:21:57 +00:00
this . navigateBackController ( )
2020-10-21 17:54:45 +00:00
this . releaseBackEvent ( )
}
} ,
hijackBackEvent ( ) {
2020-12-07 14:45:00 +00:00
AndroidApplication . on ( AndroidApplication . activityBackPressedEvent , this . backEvent )
2020-10-21 17:54:45 +00:00
} ,
releaseBackEvent ( ) {
2020-12-07 14:45:00 +00:00
AndroidApplication . off ( AndroidApplication . activityBackPressedEvent , this . backEvent )
2020-10-21 17:54:45 +00:00
} ,
2020-12-07 14:45:00 +00:00
backEvent ( args ) {
if ( this . hasChanges && ! this . blockModal ) {
2020-10-21 17:54:45 +00:00
args . cancel = true
this . navigateBack ( )
}
2020-10-14 19:32:32 +00:00
} ,
2020-11-02 11:36:53 +00:00
// DATA HANDLERS
imageHandler ( ) {
2020-12-29 10:35:19 +00:00
this . clearEmptyFields ( )
2020-12-07 14:45:00 +00:00
if ( this . recipeContent . imageSrc ) {
2020-10-29 20:12:53 +00:00
this . blockModal = true
2020-12-07 14:45:00 +00:00
this . $showModal ( ConfirmDialog , {
2020-10-29 20:12:53 +00:00
props : {
title : "Recipe photo" ,
cancelButtonText : "REMOVE" ,
okButtonText : "REPLACE PHOTO" ,
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( action ) => {
2020-10-29 20:12:53 +00:00
this . blockModal = false
2020-12-07 14:45:00 +00:00
if ( action ) {
this . permissionCheck ( this . permissionConfirmation , this . imagePicker )
2020-12-12 18:06:10 +00:00
} else if ( action != null ) {
2020-11-02 11:36:53 +00:00
this . recipeContent . imageSrc = null
2020-10-29 20:12:53 +00:00
this . releaseBackEvent ( )
}
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else {
2020-12-07 14:45:00 +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 ( ) {
2020-12-07 14:45:00 +00:00
return this . $showModal ( ConfirmDialog , {
2020-11-06 09:07:41 +00:00
props : {
title : "Grant permission" ,
2020-12-07 14:45:00 +00:00
description : localize ( "EnRecipes requires storage permission in order to set recipe photo." ) ,
2020-11-06 09:07:41 +00:00
cancelButtonText : "NOT NOW" ,
okButtonText : "CONTINUE" ,
} ,
2020-12-07 14:45:00 +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" :
action ( )
break
case "never_ask_again" :
2020-12-07 14:45:00 +00:00
ApplicationSettings . setBoolean ( "storagePermissionAsked" , true )
2020-11-10 18:28:48 +00:00
break
case "denied" :
2020-12-07 14:45:00 +00:00
Toast . makeText ( localize ( "Permission denied" ) ) . show ( )
2020-11-10 18:28:48 +00:00
break
default :
break
}
2020-12-07 14:45:00 +00:00
} )
2020-11-06 09:07:41 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else {
2020-12-07 14:45:00 +00:00
Permissions . check ( "photo" ) . then ( ( res ) => {
res [ 0 ] !== "authorized" ? confirmation ( ) . then ( ( e ) => e && utils . openAppSettingsPage ( ) ) : action ( )
} )
2020-10-29 20:12:53 +00:00
}
} ,
2020-11-02 11:36:53 +00:00
imagePicker ( ) {
2020-12-07 14:45:00 +00:00
ApplicationSettings . setBoolean ( "storagePermissionAsked" , true )
this . cacheImagePath = path . join ( knownFolders . temp ( ) . path , ` ${ this . getRandomID ( ) } .jpg ` )
Filepicker . create ( {
2020-11-10 18:28:48 +00:00
mode : "single" ,
2020-12-07 14:45:00 +00:00
extensions : [ "png" , "jpeg" , "jpg" ] ,
} ) . present ( ) . then ( ( selection ) => {
let imgPath = selection [ 0 ]
ImageSource . fromFile ( imgPath ) . then ( ( image ) => {
ImageCropper . prototype . show ( image , {
width : 1080 ,
height : 1080 ,
} , {
hideBottomControls : true ,
toolbarTitle : localize ( "Crop photo" ) ,
statusBarColor : "#ff5200" ,
toolbarTextColor : this . appTheme == "light" ? "#212529" : "#f1f3f5" ,
toolbarColor : this . appTheme == "light" ? "#f1f3f5" : "#212529" ,
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 ( ) {
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
}
} ,
joinTags ( ) {
this . tags = this . recipeContent . tags . join ( " " )
} ,
2020-12-07 14:45:00 +00:00
fieldDeletionConfirm ( title ) {
return this . $showModal ( ConfirmDialog , {
2020-11-10 18:28:48 +00:00
props : {
2020-11-28 19:21:57 +00:00
title ,
2020-11-10 18:28:48 +00:00
cancelButtonText : "CANCEL" ,
2020-11-28 19:21:57 +00:00
okButtonText : "REMOVE" ,
2020-11-10 18:28:48 +00:00
} ,
2020-12-07 14:45:00 +00:00
} )
2020-11-10 18:28:48 +00:00
} ,
2020-10-14 19:32:32 +00:00
addIngredient ( ) {
2020-12-29 10:35:19 +00:00
let ingredients = this . recipeContent . ingredients
let unit = ingredients . length ? ingredients [ ingredients . length - 1 ] . unit : "unit"
2020-12-07 14:45:00 +00:00
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 ,
2020-12-07 14:45:00 +00:00
} )
2020-10-14 19:32:32 +00:00
} ,
2020-12-07 14:45:00 +00:00
removeIngredient ( index ) {
2020-12-29 10:35:19 +00:00
this . modalOpen = true
2020-12-07 14:45:00 +00:00
if ( this . recipeContent . ingredients [ index ] . item . length ) {
this . fieldDeletionConfirm ( "Remove ingredient?" ) . then ( ( res ) => {
if ( res ) {
this . recipeContent . ingredients . splice ( index , 1 )
2020-11-10 18:28:48 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-12-29 10:35:19 +00:00
} else {
this . recipeContent . ingredients . splice ( index , 1 )
}
setTimeout ( e => this . modalOpen = false , 200 )
2020-10-14 19:32:32 +00:00
} ,
addInstruction ( ) {
2020-12-07 14:45:00 +00:00
this . recipeContent . instructions . push ( "" )
2020-10-14 19:32:32 +00:00
} ,
2020-12-07 14:45:00 +00:00
removeInstruction ( index ) {
if ( this . recipeContent . instructions [ index ] . length ) {
this . fieldDeletionConfirm ( "Remove instruction?" ) . then ( ( res ) => {
res && this . recipeContent . instructions . splice ( index , 1 )
} )
2020-12-12 18:06:10 +00:00
} else this . recipeContent . instructions . splice ( index , 1 )
2020-10-14 19:32:32 +00:00
} ,
2020-12-07 14:45:00 +00:00
getCombinationTitle ( id ) {
return this . recipes . filter ( ( e ) => e . id === id ) [ 0 ] . title
2020-11-15 10:51:10 +00:00
} ,
showCombinations ( ) {
2020-12-07 14:45:00 +00:00
let existingCombinations = [ ... this . recipeContent . combinations ,
2020-11-15 10:51:10 +00:00
this . recipeContent . id ,
]
let filteredRecipes = this . recipes . filter (
2020-12-07 14:45:00 +00:00
( e ) => ! existingCombinations . includes ( e . id ) )
this . $showModal ( ActionDialogWithSearch , {
2020-11-15 10:51:10 +00:00
props : {
title : "Select a recipe" ,
recipes : filteredRecipes ,
} ,
2020-12-07 14:45:00 +00:00
} ) . then ( ( res ) => {
if ( res ) {
this . recipeContent . combinations . push ( res )
2020-11-15 10:51:10 +00:00
}
2020-12-07 14:45:00 +00:00
} )
} ,
removeCombination ( id ) {
let index = this . recipeContent . combinations . indexOf ( id )
this . fieldDeletionConfirm ( "Remove combination?" ) . then ( res => {
if ( res ) {
this . recipeContent . combinations . splice ( index , 1 )
this . unSyncCombinations . push ( id )
2020-11-15 10:51:10 +00:00
}
2020-12-07 14:45:00 +00:00
} )
2020-11-15 10:51:10 +00:00
} ,
2020-10-14 19:32:32 +00:00
addNote ( ) {
2020-12-07 14:45:00 +00:00
this . recipeContent . notes . push ( "" )
2020-10-14 19:32:32 +00:00
} ,
2020-12-07 14:45:00 +00:00
removeNote ( index ) {
if ( this . recipeContent . notes [ index ] . length ) {
this . fieldDeletionConfirm ( "Remove note?" ) . then ( ( res ) => {
if ( res ) this . recipeContent . notes . splice ( index , 1 )
} )
2020-12-12 18:06:10 +00:00
} else this . recipeContent . notes . splice ( index , 1 )
2020-10-14 19:32:32 +00:00
} ,
2020-11-10 18:28:48 +00:00
// SAVE OPERATION
2020-11-02 11:36:53 +00:00
clearEmptyFields ( ) {
2020-12-29 10:35:19 +00:00
if ( ! this . recipeContent . title ) this . recipeContent . title = localize ( "Untitled Recipe" )
2020-12-07 14:45:00 +00:00
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 (
2020-12-07 14:45:00 +00:00
( e ) => e . item )
2020-11-02 11:36:53 +00:00
let vm = this
2020-12-07 14:45:00 +00:00
function clearEmpty ( arr ) {
vm . recipeContent [ arr ] = vm . recipeContent [ arr ] . filter ( ( e ) => e )
2020-11-02 11:36:53 +00:00
}
2020-12-07 14:45:00 +00:00
clearEmpty ( "instructions" )
clearEmpty ( "notes" )
2020-11-02 11:36:53 +00:00
} ,
saveOperation ( ) {
2020-11-28 19:21:57 +00:00
this . saving = this . modalOpen = true
2020-11-02 11:36:53 +00:00
this . clearEmptyFields ( )
this . recipeContent . lastModified = new Date ( )
2020-12-07 14:45:00 +00:00
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 )
2020-11-10 18:28:48 +00:00
this . recipeContent . imageSrc = recipeImage
knownFolders . temp ( ) . clear ( )
}
2020-12-07 14:45:00 +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
}
2020-12-12 18:06:10 +00:00
} else if ( this . tempRecipeContent . imageSrc ) {
2020-12-07 14:45:00 +00:00
getFileAccess ( ) . deleteFile ( this . tempRecipeContent . imageSrc )
}
this . unSyncCombinationsAction ( {
2020-11-15 10:51:10 +00:00
id : this . recipeID ,
combinations : this . unSyncCombinations ,
2020-12-07 14:45:00 +00:00
} )
2020-11-10 18:28:48 +00:00
this . saveRecipe ( )
2020-11-02 11:36:53 +00:00
} ,
saveRecipe ( ) {
2020-12-07 14:45:00 +00:00
if ( this . recipeID ) {
this . overwriteRecipeAction ( {
2020-11-02 11:36:53 +00:00
id : this . recipeID ,
recipe : this . recipeContent ,
2020-12-07 14:45:00 +00:00
} )
2020-12-12 18:06:10 +00:00
} else {
2020-11-02 11:36:53 +00:00
this . recipeContent . id = this . newRecipeID
2020-12-07 14:45:00 +00:00
this . addRecipeAction ( {
2020-11-02 11:36:53 +00:00
id : this . newRecipeID ,
recipe : this . recipeContent ,
2020-12-07 14:45:00 +00:00
} )
2020-11-02 11:36:53 +00:00
}
2020-12-07 14:45:00 +00:00
setTimeout ( ( ) => {
2020-11-23 09:49:58 +00:00
this . saving = false
2020-12-07 14:45:00 +00:00
} , 100 )
2020-11-28 19:21:57 +00:00
this . navigateBackController ( )
2020-10-14 19:32:32 +00:00
} ,
} ,
2020-10-26 20:49:54 +00:00
created ( ) {
2020-12-07 14:45:00 +00:00
setTimeout ( ( e ) => {
this . setCurrentComponentAction ( "EditRecipe" )
} , 500 )
2020-10-26 20:49:54 +00:00
this . title = this . recipeID ? "Edit recipe" : "New recipe"
2020-12-07 14:45:00 +00:00
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 ) ) )
2020-12-29 10:35:19 +00:00
if ( this . recipeContent . tags . length ) this . joinTags ( )
2020-12-12 18:06:10 +00:00
} else {
2020-12-29 10:35:19 +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 ( )
}
this . recipeContent . yield . unit = ApplicationSettings . getString ( "previousYieldUnit" , "Serving" )
2020-12-07 14:45:00 +00:00
if ( this . filterFavourites ) this . recipeContent . isFavorite = true
2020-12-29 10:35:19 +00:00
if ( this . filterTrylater ) this . recipeContent . tried = false
this . recipeContent . created = new Date ( )
2020-12-07 14:45:00 +00:00
Object . assign ( this . tempRecipeContent , JSON . parse ( JSON . stringify ( this . recipeContent ) ) )
2020-10-26 20:49:54 +00:00
this . newRecipeID = this . getRandomID ( )
}
this . hijackBackEvent ( )
} ,
2020-10-14 19:32:32 +00:00
}
< / script >