added combinations feature
This commit is contained in:
parent
eaf5419e8c
commit
01c9c32162
7 changed files with 318 additions and 45 deletions
|
@ -202,6 +202,7 @@ MDActivityIndicator {
|
||||||
MDProgress {
|
MDProgress {
|
||||||
progress-color: $orange;
|
progress-color: $orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// ActionBar
|
// ActionBar
|
||||||
ActionBar {
|
ActionBar {
|
||||||
|
@ -480,6 +481,7 @@ RadListView {
|
||||||
.recipeLink {
|
.recipeLink {
|
||||||
padding: 16;
|
padding: 16;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
line-height: 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.recipeText {
|
.recipeText {
|
||||||
|
@ -522,6 +524,10 @@ MDButton.closeBtn {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
vertical-alignment: top;
|
vertical-alignment: top;
|
||||||
}
|
}
|
||||||
|
TextField.combinationToken {
|
||||||
|
border-width: 0;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// DIALOGS
|
// DIALOGS
|
||||||
.dialogContainer {
|
.dialogContainer {
|
||||||
|
@ -547,6 +553,7 @@ MDButton.closeBtn {
|
||||||
.actionItem {
|
.actionItem {
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
line-height: 6;
|
||||||
padding: 16 24;
|
padding: 16 24;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@
|
||||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
||||||
<StackLayout margin="0 16 24">
|
<StackLayout margin="0 16">
|
||||||
<Label text="References" class="sectionTitle" />
|
<Label text="References" class="sectionTitle" />
|
||||||
<GridLayout
|
<GridLayout
|
||||||
columns="*,8,auto"
|
columns="*,8,auto"
|
||||||
|
@ -254,6 +254,36 @@
|
||||||
text="+ ADD REFERENCE"
|
text="+ ADD REFERENCE"
|
||||||
@tap="addReference"
|
@tap="addReference"
|
||||||
/>
|
/>
|
||||||
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
<StackLayout margin="0 16 24" v-if="recipes.length">
|
||||||
|
<Label text="Combinations" 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="+ ADD COMBINATION"
|
||||||
|
@tap="showCombinations"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -273,6 +303,7 @@ import {
|
||||||
path,
|
path,
|
||||||
Screen,
|
Screen,
|
||||||
Utils,
|
Utils,
|
||||||
|
ObservableArray,
|
||||||
} from "@nativescript/core"
|
} from "@nativescript/core"
|
||||||
import * as Permissions from "@nativescript-community/perms"
|
import * as Permissions from "@nativescript-community/perms"
|
||||||
import * as Toast from "nativescript-toast"
|
import * as Toast from "nativescript-toast"
|
||||||
|
@ -281,13 +312,13 @@ import { ImageCropper } from "nativescript-imagecropper"
|
||||||
import { mapState, mapActions } from "vuex"
|
import { mapState, mapActions } from "vuex"
|
||||||
|
|
||||||
import ActionDialog from "./modal/ActionDialog.vue"
|
import ActionDialog from "./modal/ActionDialog.vue"
|
||||||
|
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue"
|
||||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||||
import PromptDialog from "./modal/PromptDialog.vue"
|
import PromptDialog from "./modal/PromptDialog.vue"
|
||||||
import ListPicker from "./modal/ListPicker.vue"
|
import ListPicker from "./modal/ListPicker.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
"recipeIndex",
|
|
||||||
"recipeID",
|
"recipeID",
|
||||||
"selectedCategory",
|
"selectedCategory",
|
||||||
"openAppSettingsPage",
|
"openAppSettingsPage",
|
||||||
|
@ -311,6 +342,7 @@ export default {
|
||||||
instructions: [],
|
instructions: [],
|
||||||
notes: [],
|
notes: [],
|
||||||
references: [],
|
references: [],
|
||||||
|
combinations: [],
|
||||||
isFavorite: false,
|
isFavorite: false,
|
||||||
tried: false,
|
tried: false,
|
||||||
lastTried: null,
|
lastTried: null,
|
||||||
|
@ -323,6 +355,7 @@ export default {
|
||||||
showFab: false,
|
showFab: false,
|
||||||
imageLoading: false,
|
imageLoading: false,
|
||||||
cacheImagePath: null,
|
cacheImagePath: null,
|
||||||
|
unSyncCombinations: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -360,6 +393,7 @@ export default {
|
||||||
"overwriteRecipeAction",
|
"overwriteRecipeAction",
|
||||||
"addCategoryAction",
|
"addCategoryAction",
|
||||||
"addYieldUnitAction",
|
"addYieldUnitAction",
|
||||||
|
"unSyncCombinationsAction",
|
||||||
]),
|
]),
|
||||||
onPageLoad() {
|
onPageLoad() {
|
||||||
this.showFab = true
|
this.showFab = true
|
||||||
|
@ -367,7 +401,7 @@ export default {
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
focusField(args, type) {
|
focusField(args, type) {
|
||||||
this.setInputTypeText(args, type)
|
if (type) this.setInputTypeText(args, type)
|
||||||
if (!args.object.text) {
|
if (!args.object.text) {
|
||||||
args.object.focus()
|
args.object.focus()
|
||||||
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1)
|
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1)
|
||||||
|
@ -719,15 +753,46 @@ export default {
|
||||||
} else this.recipeContent.instructions.splice(index, 1)
|
} 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() {
|
addNote() {
|
||||||
this.recipeContent.notes.push("")
|
this.recipeContent.notes.push("")
|
||||||
},
|
},
|
||||||
removeNote(index) {
|
removeNote(index) {
|
||||||
if (this.recipeContent.notes[index].length) {
|
if (this.recipeContent.notes[index].length) {
|
||||||
this.fieldDeletionConfirm("note").then((res) => {
|
this.fieldDeletionConfirm("note").then((res) => {
|
||||||
if (res) {
|
if (res) this.recipeContent.notes.splice(index, 1)
|
||||||
this.recipeContent.notes.splice(index, 1)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else this.recipeContent.notes.splice(index, 1)
|
} else this.recipeContent.notes.splice(index, 1)
|
||||||
},
|
},
|
||||||
|
@ -789,12 +854,15 @@ export default {
|
||||||
} else if (this.tempRecipeContent.imageSrc) {
|
} else if (this.tempRecipeContent.imageSrc) {
|
||||||
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc)
|
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc)
|
||||||
}
|
}
|
||||||
|
this.unSyncCombinationsAction({
|
||||||
|
id: this.recipeID,
|
||||||
|
combinations: this.unSyncCombinations,
|
||||||
|
})
|
||||||
this.saveRecipe()
|
this.saveRecipe()
|
||||||
},
|
},
|
||||||
saveRecipe() {
|
saveRecipe() {
|
||||||
if (this.recipeID) {
|
if (this.recipeID) {
|
||||||
this.overwriteRecipeAction({
|
this.overwriteRecipeAction({
|
||||||
index: this.recipeIndex,
|
|
||||||
id: this.recipeID,
|
id: this.recipeID,
|
||||||
recipe: this.recipeContent,
|
recipe: this.recipeContent,
|
||||||
})
|
})
|
||||||
|
|
|
@ -384,7 +384,6 @@ export default {
|
||||||
// },
|
// },
|
||||||
props: {
|
props: {
|
||||||
filterTrylater: this.filterTrylater,
|
filterTrylater: this.filterTrylater,
|
||||||
recipeIndex: index,
|
|
||||||
recipeID: item.id,
|
recipeID: item.id,
|
||||||
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
|
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
|
||||||
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
|
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
/>
|
/>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
row="1"
|
row="1"
|
||||||
col="1"
|
col="0"
|
||||||
colSpan="3"
|
colSpan="4"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
scrollBarIndicatorVisible="false"
|
scrollBarIndicatorVisible="false"
|
||||||
>
|
>
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<Label :text="` ${formattedTime(recipe.timeRequired)}`" />
|
<Label :text="` ${formattedTime(recipe.timeRequired)}`" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout
|
<GridLayout
|
||||||
rows="auto, auto"
|
rows="auto, auto, auto"
|
||||||
columns="*, *"
|
columns="*, *"
|
||||||
class="overviewContainer"
|
class="overviewContainer"
|
||||||
>
|
>
|
||||||
|
@ -142,12 +142,15 @@
|
||||||
class="itemCount"
|
class="itemCount"
|
||||||
:text="
|
:text="
|
||||||
`${recipe.instructions.length} ${
|
`${recipe.instructions.length} ${
|
||||||
recipe.instructions.length == 1 ? 'Step' : 'Steps'
|
recipe.instructions.length == 1
|
||||||
|
? 'Instruction'
|
||||||
|
: 'Instructions'
|
||||||
}`
|
}`
|
||||||
"
|
"
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
<GridLayout
|
<GridLayout
|
||||||
class="overviewItem"
|
class="overviewItem"
|
||||||
row="1"
|
row="1"
|
||||||
|
@ -190,6 +193,28 @@
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
<GridLayout
|
||||||
|
class="overviewItem"
|
||||||
|
row="2"
|
||||||
|
col="0"
|
||||||
|
rows="auto, auto"
|
||||||
|
columns="*"
|
||||||
|
>
|
||||||
|
<MDRipple rowSpan="2" @tap="selectedTabIndex = 5" />
|
||||||
|
<Label row="0" class="bx" :text="icon.outline" />
|
||||||
|
<Label
|
||||||
|
row="1"
|
||||||
|
class="itemCount"
|
||||||
|
:text="
|
||||||
|
`${recipe.combinations.length} ${
|
||||||
|
recipe.combinations.length == 1
|
||||||
|
? 'Combination'
|
||||||
|
: 'Combinations'
|
||||||
|
}`
|
||||||
|
"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
@ -415,6 +440,44 @@
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</TabViewItem>
|
</TabViewItem>
|
||||||
|
<TabViewItem title="Combinations">
|
||||||
|
<ScrollView scrollBarIndicatorVisible="false">
|
||||||
|
<GridLayout
|
||||||
|
v-if="!recipe.combinations.length"
|
||||||
|
rows="*, auto, *, 88"
|
||||||
|
columns="*"
|
||||||
|
class="emptyStateContainer"
|
||||||
|
>
|
||||||
|
<StackLayout col="0" row="1" class="emptyState">
|
||||||
|
<Label class="bx icon" :text="icon.outline" textWrap="true" />
|
||||||
|
<StackLayout orientation="horizontal" class="title orkm">
|
||||||
|
<Label text="Use the " />
|
||||||
|
<Label class="bx" :text="icon.edit" />
|
||||||
|
<Label text=" button" />
|
||||||
|
</StackLayout>
|
||||||
|
<Label text="to add some combinations" textWrap="true" />
|
||||||
|
</StackLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<StackLayout v-else padding="10 0 132">
|
||||||
|
<GridLayout
|
||||||
|
columns="*"
|
||||||
|
v-for="(combination, index) in recipe.combinations"
|
||||||
|
:key="index"
|
||||||
|
androidElevation="1"
|
||||||
|
class="referenceItem"
|
||||||
|
>
|
||||||
|
<MDRipple col="0" @tap="viewCombination(combination)" />
|
||||||
|
<Label
|
||||||
|
col="0"
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="recipeLink"
|
||||||
|
:text="getCombinationTitle(combination)"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</TabViewItem>
|
||||||
</TabView>
|
</TabView>
|
||||||
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
||||||
<MDFloatingActionButton
|
<MDFloatingActionButton
|
||||||
|
@ -440,6 +503,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
|
ApplicationSettings,
|
||||||
Color,
|
Color,
|
||||||
Device,
|
Device,
|
||||||
File,
|
File,
|
||||||
|
@ -457,6 +521,7 @@ import { Application } from "@nativescript/core"
|
||||||
import { mapActions, mapState } from "vuex"
|
import { mapActions, mapState } from "vuex"
|
||||||
|
|
||||||
import EditRecipe from "./EditRecipe.vue"
|
import EditRecipe from "./EditRecipe.vue"
|
||||||
|
import ViewRecipe from "./ViewRecipe.vue"
|
||||||
import ShareChooser from "./modal/ShareChooser.vue"
|
import ShareChooser from "./modal/ShareChooser.vue"
|
||||||
|
|
||||||
let feedback = new Feedback()
|
let feedback = new Feedback()
|
||||||
|
@ -464,8 +529,8 @@ let feedback = new Feedback()
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
"filterTrylater",
|
"filterTrylater",
|
||||||
"recipeIndex",
|
|
||||||
"recipeID",
|
"recipeID",
|
||||||
|
"recipeIndex",
|
||||||
"hijackGlobalBackEvent",
|
"hijackGlobalBackEvent",
|
||||||
"releaseGlobalBackEvent",
|
"releaseGlobalBackEvent",
|
||||||
],
|
],
|
||||||
|
@ -476,6 +541,7 @@ export default {
|
||||||
recipe: null,
|
recipe: null,
|
||||||
showFab: false,
|
showFab: false,
|
||||||
selectedTabIndex: 0,
|
selectedTabIndex: 0,
|
||||||
|
currentRecipeID: this.recipeID,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -491,7 +557,11 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["toggleStateAction", "setCurrentComponentAction"]),
|
...mapActions([
|
||||||
|
"toggleStateAction",
|
||||||
|
"setCurrentComponentAction",
|
||||||
|
"overwriteRecipeAction",
|
||||||
|
]),
|
||||||
onPageLoad() {
|
onPageLoad() {
|
||||||
this.releaseGlobalBackEvent()
|
this.releaseGlobalBackEvent()
|
||||||
this.busy = false
|
this.busy = false
|
||||||
|
@ -501,6 +571,7 @@ export default {
|
||||||
this.yieldMultiplier = this.recipe.yield.quantity
|
this.yieldMultiplier = this.recipe.yield.quantity
|
||||||
this.showFab = true
|
this.showFab = true
|
||||||
this.keepScreenOn(true)
|
this.keepScreenOn(true)
|
||||||
|
this.syncCombinations()
|
||||||
},
|
},
|
||||||
onPageUnload() {
|
onPageUnload() {
|
||||||
feedback.hide()
|
feedback.hide()
|
||||||
|
@ -569,24 +640,45 @@ export default {
|
||||||
let pattern = new RegExp("^https?|www", "ig")
|
let pattern = new RegExp("^https?|www", "ig")
|
||||||
return pattern.test(string)
|
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
|
// NAVIGATION HANDLERS
|
||||||
editRecipe() {
|
editRecipe() {
|
||||||
this.showFab = false
|
this.showFab = false
|
||||||
this.busy = true
|
this.busy = true
|
||||||
this.$navigateTo(EditRecipe, {
|
this.$navigateTo(EditRecipe, {
|
||||||
// transition: {
|
|
||||||
// name: "slide",
|
|
||||||
// duration: 250,
|
|
||||||
// curve: "easeOut",
|
|
||||||
// },
|
|
||||||
props: {
|
props: {
|
||||||
recipeIndex: this.recipeIndex,
|
recipeID: this.currentRecipeID,
|
||||||
recipeID: this.recipeID,
|
|
||||||
},
|
},
|
||||||
// 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
|
// SHARE ACTION
|
||||||
shareHandler() {
|
shareHandler() {
|
||||||
|
@ -598,20 +690,6 @@ export default {
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case "photo":
|
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) => {
|
ImageSource.fromFile(this.recipe.imageSrc).then((res) => {
|
||||||
SocialShare.shareImage(res, "Share recipe photo using")
|
SocialShare.shareImage(res, "Share recipe photo using")
|
||||||
})
|
})
|
||||||
|
@ -653,6 +731,13 @@ export default {
|
||||||
})
|
})
|
||||||
shareContent += instructions
|
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) {
|
if (this.recipe.notes.length) {
|
||||||
let notes = `\nNotes:\n\n`
|
let notes = `\nNotes:\n\n`
|
||||||
this.recipe.notes.forEach((e, i) => {
|
this.recipe.notes.forEach((e, i) => {
|
||||||
|
@ -677,8 +762,7 @@ export default {
|
||||||
// DATA HANDLERS
|
// DATA HANDLERS
|
||||||
toggle(key, setDate) {
|
toggle(key, setDate) {
|
||||||
this.toggleStateAction({
|
this.toggleStateAction({
|
||||||
index: this.recipeIndex,
|
id: this.currentRecipeID,
|
||||||
id: this.recipeID,
|
|
||||||
recipe: this.recipe,
|
recipe: this.recipe,
|
||||||
key,
|
key,
|
||||||
setDate,
|
setDate,
|
||||||
|
@ -716,7 +800,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
this.recipe = this.recipes.filter((e) => e.id === this.currentRecipeID)[0]
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.showFab = true
|
this.showFab = true
|
||||||
|
|
94
app/components/modal/ActionDialogWithSearch.vue
Normal file
94
app/components/modal/ActionDialogWithSearch.vue
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<template>
|
||||||
|
<Page>
|
||||||
|
<StackLayout class="dialogContainer" :class="appTheme">
|
||||||
|
<Label class="dialogTitle orkm" :text="title" />
|
||||||
|
<StackLayout padding="0 24 24">
|
||||||
|
<TextField hint="Search" v-model="searchTerm" />
|
||||||
|
</StackLayout>
|
||||||
|
<ScrollView width="100%" :height="height ? height : screenHeight - 320">
|
||||||
|
<StackLayout>
|
||||||
|
<MDButton
|
||||||
|
v-for="(recipe, index) in filteredRecipes"
|
||||||
|
:key="index"
|
||||||
|
class="actionItem"
|
||||||
|
variant="text"
|
||||||
|
:rippleColor="rippleColor"
|
||||||
|
:text="recipe.title"
|
||||||
|
@loaded="onLabelLoaded"
|
||||||
|
@tap="tapAction(recipe)"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
padding="0 24"
|
||||||
|
lineHeight="6"
|
||||||
|
v-if="!filteredRecipes.length"
|
||||||
|
text="Nothing here! Add some recipes that goes well with this and try again."
|
||||||
|
horizontalAlignment="center"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</StackLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<GridLayout rows="auto" columns="auto, *, auto" class="actionsContainer">
|
||||||
|
<MDButton
|
||||||
|
:rippleColor="rippleColor"
|
||||||
|
variant="text"
|
||||||
|
v-if="action"
|
||||||
|
col="0"
|
||||||
|
class="action orkm pull-left"
|
||||||
|
:text="action"
|
||||||
|
@tap="$modal.close(action)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
:rippleColor="rippleColor"
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm pull-right"
|
||||||
|
text="CANCEL"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Application, Screen } from "@nativescript/core"
|
||||||
|
export default {
|
||||||
|
props: ["title", "recipes", "height", "action"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchTerm: "",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
appTheme() {
|
||||||
|
return Application.systemAppearance()
|
||||||
|
},
|
||||||
|
rippleColor() {
|
||||||
|
return this.appTheme == "light"
|
||||||
|
? "rgba(134,142,150,0.2)"
|
||||||
|
: "rgba(206,212,218,0.1)"
|
||||||
|
},
|
||||||
|
screenHeight() {
|
||||||
|
return Math.round(Screen.mainScreen.heightDIPs)
|
||||||
|
},
|
||||||
|
filteredRecipes() {
|
||||||
|
return this.recipes
|
||||||
|
.map((e, i) => {
|
||||||
|
return {
|
||||||
|
id: e.id,
|
||||||
|
title: e.title,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter((e) => e.title.includes(this.searchTerm))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
tapAction(recipe) {
|
||||||
|
this.$modal.close(recipe.id)
|
||||||
|
},
|
||||||
|
onLabelLoaded(args) {
|
||||||
|
args.object.android.setGravity(16)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -20,9 +20,6 @@ Vue.use(FloatingActionButtonPlugin)
|
||||||
import ProgressPlugin from "@nativescript-community/ui-material-progress/vue"
|
import ProgressPlugin from "@nativescript-community/ui-material-progress/vue"
|
||||||
Vue.use(ProgressPlugin)
|
Vue.use(ProgressPlugin)
|
||||||
|
|
||||||
// import SpeedDialPlugin from "@nativescript-community/ui-material-speeddial/vue"
|
|
||||||
// Vue.use(SpeedDialPlugin)
|
|
||||||
|
|
||||||
Vue.registerElement(
|
Vue.registerElement(
|
||||||
"RadSideDrawer",
|
"RadSideDrawer",
|
||||||
() => require("nativescript-ui-sidedrawer").RadSideDrawer
|
() => require("nativescript-ui-sidedrawer").RadSideDrawer
|
||||||
|
|
28
app/store.js
28
app/store.js
|
@ -182,6 +182,7 @@ export default new Vuex.Store({
|
||||||
source: "\ueaa0",
|
source: "\ueaa0",
|
||||||
export: "\ued07",
|
export: "\ued07",
|
||||||
import: "\ued0c",
|
import: "\ued0c",
|
||||||
|
outline: "\ueb07",
|
||||||
},
|
},
|
||||||
currentComponent: "EnRecipes",
|
currentComponent: "EnRecipes",
|
||||||
},
|
},
|
||||||
|
@ -306,7 +307,10 @@ export default new Vuex.Store({
|
||||||
})
|
})
|
||||||
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
|
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)
|
Object.assign(state.recipes[index], recipe)
|
||||||
EnRecipesDB.updateDocument(id, recipe)
|
EnRecipesDB.updateDocument(id, recipe)
|
||||||
},
|
},
|
||||||
|
@ -314,8 +318,17 @@ export default new Vuex.Store({
|
||||||
getFileAccess().deleteFile(state.recipes[index].imageSrc)
|
getFileAccess().deleteFile(state.recipes[index].imageSrc)
|
||||||
state.recipes.splice(index, 1)
|
state.recipes.splice(index, 1)
|
||||||
EnRecipesDB.deleteDocument(id)
|
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]
|
state.recipes[index][key] = !state.recipes[index][key]
|
||||||
if (setDate) state.recipes[index].lastTried = new Date()
|
if (setDate) state.recipes[index].lastTried = new Date()
|
||||||
EnRecipesDB.updateDocument(id, recipe)
|
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: {
|
actions: {
|
||||||
initializeRecipes({ commit }) {
|
initializeRecipes({ commit }) {
|
||||||
|
@ -393,5 +414,8 @@ export default new Vuex.Store({
|
||||||
renameCategoryAction({ commit }, category) {
|
renameCategoryAction({ commit }, category) {
|
||||||
commit("renameCategory", category)
|
commit("renameCategory", category)
|
||||||
},
|
},
|
||||||
|
unSyncCombinationsAction({ commit }, combinations) {
|
||||||
|
commit("unSyncCombinations", combinations)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue