diff --git a/app/app.scss b/app/app.scss
index 281d714a..8dc44d12 100644
--- a/app/app.scss
+++ b/app/app.scss
@@ -202,6 +202,7 @@ MDActivityIndicator {
MDProgress {
progress-color: $orange;
}
+
// -----------------------------
// ActionBar
ActionBar {
@@ -480,6 +481,7 @@ RadListView {
.recipeLink {
padding: 16;
margin: 0;
+ line-height: 6;
}
}
.recipeText {
@@ -522,6 +524,10 @@ MDButton.closeBtn {
min-width: 0;
vertical-alignment: top;
}
+TextField.combinationToken {
+ border-width: 0;
+ background: white;
+}
// -----------------------------
// DIALOGS
.dialogContainer {
@@ -547,6 +553,7 @@ MDButton.closeBtn {
.actionItem {
letter-spacing: 0;
text-transform: none;
+ line-height: 6;
padding: 16 24;
margin: 0;
}
diff --git a/app/components/EditRecipe.vue b/app/components/EditRecipe.vue
index 537a9fb2..a2984641 100644
--- a/app/components/EditRecipe.vue
+++ b/app/components/EditRecipe.vue
@@ -227,7 +227,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -273,6 +303,7 @@ import {
path,
Screen,
Utils,
+ ObservableArray,
} from "@nativescript/core"
import * as Permissions from "@nativescript-community/perms"
import * as Toast from "nativescript-toast"
@@ -281,13 +312,13 @@ import { ImageCropper } from "nativescript-imagecropper"
import { mapState, mapActions } from "vuex"
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"
export default {
props: [
- "recipeIndex",
"recipeID",
"selectedCategory",
"openAppSettingsPage",
@@ -311,6 +342,7 @@ export default {
instructions: [],
notes: [],
references: [],
+ combinations: [],
isFavorite: false,
tried: false,
lastTried: null,
@@ -323,6 +355,7 @@ export default {
showFab: false,
imageLoading: false,
cacheImagePath: null,
+ unSyncCombinations: [],
}
},
computed: {
@@ -360,6 +393,7 @@ export default {
"overwriteRecipeAction",
"addCategoryAction",
"addYieldUnitAction",
+ "unSyncCombinationsAction",
]),
onPageLoad() {
this.showFab = true
@@ -367,7 +401,7 @@ export default {
// HELPERS
focusField(args, type) {
- this.setInputTypeText(args, type)
+ if (type) this.setInputTypeText(args, type)
if (!args.object.text) {
args.object.focus()
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1)
@@ -719,15 +753,46 @@ export default {
} else this.recipeContent.instructions.splice(index, 1)
},
+ getCombinationTitle(id) {
+ return this.recipes.filter((e) => e.id === id)[0].title
+ },
+ showCombinations() {
+ let existingCombinations = [
+ ...this.recipeContent.combinations,
+ this.recipeContent.id,
+ ]
+ console.log(existingCombinations)
+ let filteredRecipes = this.recipes.filter(
+ (e) => !existingCombinations.includes(e.id)
+ )
+ this.$showModal(ActionDialogWithSearch, {
+ props: {
+ title: "Select a recipe",
+ recipes: filteredRecipes,
+ },
+ }).then((res) => {
+ if (res) {
+ this.recipeContent.combinations.push(res)
+ }
+ })
+ },
+ removeCombination(id) {
+ let index = this.recipeContent.combinations.indexOf(id)
+ this.fieldDeletionConfirm("combination").then((res) => {
+ if (res) {
+ this.recipeContent.combinations.splice(index, 1)
+ this.unSyncCombinations.push(id)
+ }
+ })
+ },
+
addNote() {
this.recipeContent.notes.push("")
},
removeNote(index) {
if (this.recipeContent.notes[index].length) {
this.fieldDeletionConfirm("note").then((res) => {
- if (res) {
- this.recipeContent.notes.splice(index, 1)
- }
+ if (res) this.recipeContent.notes.splice(index, 1)
})
} else this.recipeContent.notes.splice(index, 1)
},
@@ -789,12 +854,15 @@ export default {
} else if (this.tempRecipeContent.imageSrc) {
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc)
}
+ this.unSyncCombinationsAction({
+ id: this.recipeID,
+ combinations: this.unSyncCombinations,
+ })
this.saveRecipe()
},
saveRecipe() {
if (this.recipeID) {
this.overwriteRecipeAction({
- index: this.recipeIndex,
id: this.recipeID,
recipe: this.recipeContent,
})
diff --git a/app/components/EnRecipes.vue b/app/components/EnRecipes.vue
index 9cf37b31..88f784c1 100644
--- a/app/components/EnRecipes.vue
+++ b/app/components/EnRecipes.vue
@@ -384,7 +384,6 @@ export default {
// },
props: {
filterTrylater: this.filterTrylater,
- recipeIndex: index,
recipeID: item.id,
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
diff --git a/app/components/ViewRecipe.vue b/app/components/ViewRecipe.vue
index 6225078b..096d8a17 100644
--- a/app/components/ViewRecipe.vue
+++ b/app/components/ViewRecipe.vue
@@ -13,8 +13,8 @@
/>
@@ -102,8 +102,8 @@
+
+
+
+
+
+
@@ -415,6 +440,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
import {
+ ApplicationSettings,
Color,
Device,
File,
@@ -457,6 +521,7 @@ import { Application } from "@nativescript/core"
import { mapActions, mapState } from "vuex"
import EditRecipe from "./EditRecipe.vue"
+import ViewRecipe from "./ViewRecipe.vue"
import ShareChooser from "./modal/ShareChooser.vue"
let feedback = new Feedback()
@@ -464,8 +529,8 @@ let feedback = new Feedback()
export default {
props: [
"filterTrylater",
- "recipeIndex",
"recipeID",
+ "recipeIndex",
"hijackGlobalBackEvent",
"releaseGlobalBackEvent",
],
@@ -476,6 +541,7 @@ export default {
recipe: null,
showFab: false,
selectedTabIndex: 0,
+ currentRecipeID: this.recipeID,
}
},
computed: {
@@ -491,7 +557,11 @@ export default {
},
},
methods: {
- ...mapActions(["toggleStateAction", "setCurrentComponentAction"]),
+ ...mapActions([
+ "toggleStateAction",
+ "setCurrentComponentAction",
+ "overwriteRecipeAction",
+ ]),
onPageLoad() {
this.releaseGlobalBackEvent()
this.busy = false
@@ -501,6 +571,7 @@ export default {
this.yieldMultiplier = this.recipe.yield.quantity
this.showFab = true
this.keepScreenOn(true)
+ this.syncCombinations()
},
onPageUnload() {
feedback.hide()
@@ -569,24 +640,45 @@ export default {
let pattern = new RegExp("^https?|www", "ig")
return pattern.test(string)
},
+ getCombinationTitle(id) {
+ return this.recipes.filter((e) => e.id === id)[0].title
+ },
+ syncCombinations() {
+ 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({
+ id: this.currentRecipeID,
+ recipe: this.recipe,
+ })
+ },
// NAVIGATION HANDLERS
editRecipe() {
this.showFab = false
this.busy = true
this.$navigateTo(EditRecipe, {
- // transition: {
- // name: "slide",
- // duration: 250,
- // curve: "easeOut",
- // },
props: {
- recipeIndex: this.recipeIndex,
- recipeID: this.recipeID,
+ recipeID: this.currentRecipeID,
},
- // backstackVisible: false,
})
},
+ viewCombination(combination) {
+ this.recipe = this.recipes.filter((e) => e.id === combination)[0]
+ this.currentRecipeID = combination
+ this.syncCombinations()
+ this.selectedTabIndex = 0
+ setTimeout(
+ (e) =>
+ this.recipe.tried && this.recipe.lastTried && this.showLastTried(),
+ 500
+ )
+ },
// SHARE ACTION
shareHandler() {
@@ -598,20 +690,6 @@ export default {
}).then((result) => {
switch (result) {
case "photo":
- // let cacheFilePath = path.join(
- // knownFolders.temp().path,
- // `${this.recipe.title}.jpg`
- // )
- // if (!File.exists(cacheFilePath)) {
- // File.fromPath(cacheFilePath).writeSync(
- // File.fromPath(this.recipe.imageSrc).readSync()
- // )
- // }
- // let shareFile = new ShareFile()
- // shareFile.open({
- // path: cacheFilePath,
- // title: "Share recipe photo using",
- // })
ImageSource.fromFile(this.recipe.imageSrc).then((res) => {
SocialShare.shareImage(res, "Share recipe photo using")
})
@@ -653,6 +731,13 @@ export default {
})
shareContent += instructions
}
+ if (this.recipe.combinations.length) {
+ let combinations = `\nCombinations:\n\n`
+ this.recipe.combinations.forEach((e, i) => {
+ combinations += `${i + 1}. ${this.getCombinationTitle(e)}\n\n`
+ })
+ shareContent += combinations
+ }
if (this.recipe.notes.length) {
let notes = `\nNotes:\n\n`
this.recipe.notes.forEach((e, i) => {
@@ -677,8 +762,7 @@ export default {
// DATA HANDLERS
toggle(key, setDate) {
this.toggleStateAction({
- index: this.recipeIndex,
- id: this.recipeID,
+ id: this.currentRecipeID,
recipe: this.recipe,
key,
setDate,
@@ -716,7 +800,7 @@ export default {
},
},
created() {
- this.recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
+ this.recipe = this.recipes.filter((e) => e.id === this.currentRecipeID)[0]
},
mounted() {
this.showFab = true
diff --git a/app/components/modal/ActionDialogWithSearch.vue b/app/components/modal/ActionDialogWithSearch.vue
new file mode 100644
index 00000000..39a6042e
--- /dev/null
+++ b/app/components/modal/ActionDialogWithSearch.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/main.js b/app/main.js
index 846ad6f1..11018eae 100644
--- a/app/main.js
+++ b/app/main.js
@@ -20,9 +20,6 @@ Vue.use(FloatingActionButtonPlugin)
import ProgressPlugin from "@nativescript-community/ui-material-progress/vue"
Vue.use(ProgressPlugin)
-// import SpeedDialPlugin from "@nativescript-community/ui-material-speeddial/vue"
-// Vue.use(SpeedDialPlugin)
-
Vue.registerElement(
"RadSideDrawer",
() => require("nativescript-ui-sidedrawer").RadSideDrawer
diff --git a/app/store.js b/app/store.js
index b46497e0..9a1ffe9c 100644
--- a/app/store.js
+++ b/app/store.js
@@ -182,6 +182,7 @@ export default new Vuex.Store({
source: "\ueaa0",
export: "\ued07",
import: "\ued0c",
+ outline: "\ueb07",
},
currentComponent: "EnRecipes",
},
@@ -306,7 +307,10 @@ export default new Vuex.Store({
})
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
},
- overwriteRecipe(state, { index, id, recipe }) {
+ overwriteRecipe(state, { id, recipe }) {
+ let index = state.recipes.indexOf(
+ state.recipes.filter((e) => e.id === id)[0]
+ )
Object.assign(state.recipes[index], recipe)
EnRecipesDB.updateDocument(id, recipe)
},
@@ -314,8 +318,17 @@ export default new Vuex.Store({
getFileAccess().deleteFile(state.recipes[index].imageSrc)
state.recipes.splice(index, 1)
EnRecipesDB.deleteDocument(id)
+ state.recipes.forEach((e, i) => {
+ if (e.combinations.includes(id)) {
+ state.recipes[i].combinations.splice(e.combinations.indexOf(id), 1)
+ EnRecipesDB.updateDocument(state.recipes[i].id, state.recipes[i])
+ }
+ })
},
- toggleState(state, { index, id, recipe, key, setDate }) {
+ toggleState(state, { id, recipe, key, setDate }) {
+ let index = state.recipes.indexOf(
+ state.recipes.filter((e) => e.id === id)[0]
+ )
state.recipes[index][key] = !state.recipes[index][key]
if (setDate) state.recipes[index].lastTried = new Date()
EnRecipesDB.updateDocument(id, recipe)
@@ -346,6 +359,14 @@ export default new Vuex.Store({
}
})
},
+ unSyncCombinations(state, { id, combinations }) {
+ state.recipes.forEach((e, i) => {
+ if (combinations.includes(e.id)) {
+ state.recipes[i].combinations.splice(e.combinations.indexOf(id), 1)
+ EnRecipesDB.updateDocument(state.recipes[i].id, state.recipes[i])
+ }
+ })
+ },
},
actions: {
initializeRecipes({ commit }) {
@@ -393,5 +414,8 @@ export default new Vuex.Store({
renameCategoryAction({ commit }, category) {
commit("renameCategory", category)
},
+ unSyncCombinationsAction({ commit }, combinations) {
+ commit("unSyncCombinations", combinations)
+ },
},
})