empty states started, minor fixes, try later added
This commit is contained in:
parent
52446b3cd7
commit
399fc6bc20
15 changed files with 915 additions and 545 deletions
|
@ -1,29 +1,28 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<!-- Application theme -->
|
|
||||||
<style name="AppTheme" parent="AppThemeBase">
|
<!-- Application theme -->
|
||||||
<item name="android:datePickerStyle">
|
<style name="AppThemeBase21" parent="AppThemeBase">
|
||||||
@style/SpinnerDatePicker
|
<item name="android:windowTranslucentStatus">true</item>
|
||||||
</item>
|
<item name="android:datePickerStyle">@style/SpinnerDatePicker</item>
|
||||||
<item name="android:timePickerStyle">
|
<item name="android:timePickerStyle">@style/SpinnerTimePicker</item>
|
||||||
@style/SpinnerTimePicker
|
</style>
|
||||||
</item>
|
|
||||||
</style>
|
<style name="AppTheme" parent="AppThemeBase21">
|
||||||
<!-- Default style for DatePicker - in spinner mode -->
|
</style>
|
||||||
<style name="SpinnerDatePicker" parent="android:Widget.Material.Light.DatePicker">
|
|
||||||
<item name="android:datePickerMode">
|
<!-- Default style for DatePicker - in spinner mode -->
|
||||||
spinner
|
<style name="SpinnerDatePicker" parent="android:Widget.Material.Light.DatePicker">
|
||||||
</item>
|
<item name="android:datePickerMode">spinner</item>
|
||||||
</style>
|
</style>
|
||||||
<!-- Default style for TimePicker - in spinner mode -->
|
|
||||||
<style name="SpinnerTimePicker" parent="android:Widget.Material.Light.TimePicker">
|
<!-- Default style for TimePicker - in spinner mode -->
|
||||||
<item name="android:timePickerMode">
|
<style name="SpinnerTimePicker" parent="android:Widget.Material.Light.TimePicker">
|
||||||
spinner
|
<item name="android:timePickerMode">spinner</item>
|
||||||
</item>
|
</style>
|
||||||
</style>
|
|
||||||
<style name="NativeScriptToolbarStyle" parent="NativeScriptToolbarStyleBase">
|
<style name="NativeScriptToolbarStyle" parent="NativeScriptToolbarStyleBase">
|
||||||
<item name="android:elevation">
|
<item name="android:elevation">4dp</item>
|
||||||
0dp
|
<item name="android:paddingTop">24dp</item>
|
||||||
</item>
|
</style>
|
||||||
</style>
|
</resources>
|
||||||
</resources>
|
|
12
app/App_Resources/Android/src/main/res/values-v29/styles.xml
Normal file
12
app/App_Resources/Android/src/main/res/values-v29/styles.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<!-- Application theme -->
|
||||||
|
<style name="AppThemeBase29" parent="AppThemeBase21">
|
||||||
|
<item name="android:forceDarkAllowed">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme" parent="AppThemeBase29">
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -20,9 +20,7 @@
|
||||||
|
|
||||||
<!-- theme to use AFTER launch screen is loaded-->
|
<!-- theme to use AFTER launch screen is loaded-->
|
||||||
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
<item name="android:forceDarkAllowed">false</item>
|
|
||||||
<item name="toolbarStyle">@style/NativeScriptToolbarStyle</item>
|
<item name="toolbarStyle">@style/NativeScriptToolbarStyle</item>
|
||||||
|
|
||||||
<item name="colorPrimary">@color/ns_primary</item>
|
<item name="colorPrimary">@color/ns_primary</item>
|
||||||
<item name="colorPrimaryDark">@color/ns_primaryDark</item>
|
<item name="colorPrimaryDark">@color/ns_primaryDark</item>
|
||||||
<item name="colorAccent">@color/ns_accent</item>
|
<item name="colorAccent">@color/ns_accent</item>
|
||||||
|
|
168
app/app.scss
168
app/app.scss
|
@ -53,6 +53,10 @@ Page {
|
||||||
.fieldLabel {
|
.fieldLabel {
|
||||||
background: $grayL4;
|
background: $grayL4;
|
||||||
}
|
}
|
||||||
|
.view-reference-text,
|
||||||
|
.view-reference-container {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
.option-highlight {
|
.option-highlight {
|
||||||
background: $grayL2;
|
background: $grayL2;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +112,9 @@ Page {
|
||||||
background: $grayD4;
|
background: $grayD4;
|
||||||
}
|
}
|
||||||
.recipe-li,
|
.recipe-li,
|
||||||
.option-highlight {
|
.option-highlight,
|
||||||
|
.view-reference-text,
|
||||||
|
.view-reference-container {
|
||||||
background: $grayD3;
|
background: $grayD3;
|
||||||
}
|
}
|
||||||
.sd-item,
|
.sd-item,
|
||||||
|
@ -151,7 +157,7 @@ TimePickerField {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-width: 1;
|
border-width: 1;
|
||||||
font-size: 14;
|
font-size: 14;
|
||||||
padding: 14;
|
padding: 14 14 13;
|
||||||
margin: 8 0 0 0;
|
margin: 8 0 0 0;
|
||||||
border-radius: 4;
|
border-radius: 4;
|
||||||
border-color: $gray;
|
border-color: $gray;
|
||||||
|
@ -188,7 +194,7 @@ TabView {
|
||||||
// ActionBar
|
// ActionBar
|
||||||
ActionBar {
|
ActionBar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 24 0 0 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 64;
|
height: 64;
|
||||||
.bx {
|
.bx {
|
||||||
|
@ -215,6 +221,10 @@ SearchBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Side Drawer
|
// Side Drawer
|
||||||
|
.sd {
|
||||||
|
margin-top: 24;
|
||||||
|
}
|
||||||
|
|
||||||
.sd-item {
|
.sd-item {
|
||||||
border-radius: 4;
|
border-radius: 4;
|
||||||
padding: 0 16;
|
padding: 0 16;
|
||||||
|
@ -238,7 +248,7 @@ SearchBar {
|
||||||
|
|
||||||
// Home
|
// Home
|
||||||
RadListView {
|
RadListView {
|
||||||
margin-bottom: 128;
|
margin: 8 0 128;
|
||||||
}
|
}
|
||||||
.recipe-li {
|
.recipe-li {
|
||||||
background: white;
|
background: white;
|
||||||
|
@ -265,12 +275,29 @@ RadListView {
|
||||||
color: $orange;
|
color: $orange;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.emptyState {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
.noResults {
|
.noResults {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
font-size: 16;
|
font-size: 16;
|
||||||
line-height: 8;
|
line-height: 8;
|
||||||
padding: 32 16;
|
padding: 64 16;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
horizontal-alignment: center;
|
||||||
|
// vertical-alignment: center;
|
||||||
|
.title {
|
||||||
|
font-size: 20;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.bx {
|
||||||
|
font-size: 64;
|
||||||
|
text-align: center;
|
||||||
|
color: $gray;
|
||||||
|
margin-bottom: 16;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.swipe-item {
|
.swipe-item {
|
||||||
margin: 0 8;
|
margin: 0 8;
|
||||||
|
@ -336,11 +363,11 @@ RadListView {
|
||||||
// View Recipe
|
// View Recipe
|
||||||
|
|
||||||
.view-cat {
|
.view-cat {
|
||||||
font-size: 14;
|
font-size: 16;
|
||||||
color: #ff7043;
|
color: #ff7043;
|
||||||
}
|
}
|
||||||
.view-other {
|
.view-other {
|
||||||
font-size: 14;
|
font-size: 16;
|
||||||
}
|
}
|
||||||
.view-title {
|
.view-title {
|
||||||
font-size: 22;
|
font-size: 22;
|
||||||
|
@ -348,46 +375,71 @@ RadListView {
|
||||||
margin-bottom: 16;
|
margin-bottom: 16;
|
||||||
}
|
}
|
||||||
.view-ingredient {
|
.view-ingredient {
|
||||||
font-size: 14;
|
font-size: 16;
|
||||||
line-height: 6;
|
line-height: 6;
|
||||||
padding-bottom: 16;
|
padding-bottom: 12;
|
||||||
}
|
|
||||||
.view-favorited {
|
|
||||||
color: #ff7043;
|
|
||||||
}
|
}
|
||||||
.activity-indicator {
|
.activity-indicator {
|
||||||
background: #ff7043;
|
background: #ff7043;
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-count {
|
.view-count {
|
||||||
font-size: 10;
|
font-size: 12;
|
||||||
width: 20;
|
width: 24;
|
||||||
height: 20;
|
height: 24;
|
||||||
padding-top: 3%;
|
padding-top: 4%;
|
||||||
margin: 0 0 0 6;
|
margin: 0 0 0 8;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 100;
|
border-radius: 100;
|
||||||
|
&.note {
|
||||||
|
clip-path: polygon(
|
||||||
|
5% 0,
|
||||||
|
95% 0,
|
||||||
|
100% 5%,
|
||||||
|
100% 65%,
|
||||||
|
65% 100%,
|
||||||
|
5% 100%,
|
||||||
|
0 95%,
|
||||||
|
0 5%
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-instruction,
|
.view-instruction,
|
||||||
.view-note,
|
.view-note,
|
||||||
.view-reference {
|
.view-reference {
|
||||||
font-size: 14;
|
font-size: 16;
|
||||||
line-height: 6;
|
line-height: 6;
|
||||||
padding: 0 0 16 24;
|
padding: 2 0 14 36;
|
||||||
margin: 0 0 0 15;
|
margin: 0 0 0 19;
|
||||||
border-width: 0 0 0 2;
|
border-width: 0 0 0 2;
|
||||||
}
|
}
|
||||||
.view-instruction.instructionWOBorder {
|
.view-instruction.instructionWOBorder {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-note {
|
.view-note {
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.view-reference-container {
|
||||||
|
padding: 14 16;
|
||||||
|
margin: 8 16 8;
|
||||||
|
border-radius: 6;
|
||||||
|
}
|
||||||
.view-reference {
|
.view-reference {
|
||||||
|
padding: 0 16 0 0;
|
||||||
|
margin: 0;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
.view-reference-text {
|
||||||
|
font-size: 16;
|
||||||
|
line-height: 6;
|
||||||
|
padding: 16;
|
||||||
|
margin: 8 16 8;
|
||||||
|
border-radius: 6;
|
||||||
|
}
|
||||||
|
// .view-copyReference {
|
||||||
|
// color: #ff7043;
|
||||||
|
// }
|
||||||
#btnFabContainer {
|
#btnFabContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -398,11 +450,15 @@ RadListView {
|
||||||
height: 56;
|
height: 56;
|
||||||
width: 56;
|
width: 56;
|
||||||
background-color: #ff7043;
|
background-color: #ff7043;
|
||||||
horizontal-align: center;
|
vertical-alignment: center;
|
||||||
vertical-align: center;
|
// horizontal-alignment: center;
|
||||||
border-radius: 28;
|
border-radius: 28;
|
||||||
padding: 16;
|
padding: 16;
|
||||||
margin: 16;
|
margin: 16;
|
||||||
|
android-elevation: 6;
|
||||||
|
&.negative {
|
||||||
|
background-color: #e53935;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.sectionTitle {
|
.sectionTitle {
|
||||||
font-size: 20;
|
font-size: 20;
|
||||||
|
@ -421,6 +477,7 @@ RadListView {
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
.dialogContainer {
|
.dialogContainer {
|
||||||
|
width: 100%;
|
||||||
&.light {
|
&.light {
|
||||||
color: $grayD4;
|
color: $grayD4;
|
||||||
background: $grayL4;
|
background: $grayL4;
|
||||||
|
@ -438,6 +495,7 @@ RadListView {
|
||||||
}
|
}
|
||||||
.dialogDescription {
|
.dialogDescription {
|
||||||
font-size: 16;
|
font-size: 16;
|
||||||
|
line-height: 4;
|
||||||
padding: 0 24 16;
|
padding: 0 24 16;
|
||||||
}
|
}
|
||||||
.action {
|
.action {
|
||||||
|
@ -456,3 +514,65 @@ RadListView {
|
||||||
color: #ff7043;
|
color: #ff7043;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ActivityIndicator {
|
||||||
|
color: #ff7043;
|
||||||
|
padding: 16 12;
|
||||||
|
margin: 16 10 16 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vue Transitions
|
||||||
|
.bounce-enter-active {
|
||||||
|
animation-name: bounce-in;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
.bounce-leave-active {
|
||||||
|
animation-name: bounce-in;
|
||||||
|
animation-duration: 0.1s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-direction: reverse;
|
||||||
|
animation-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dolly-enter-active {
|
||||||
|
animation-name: dolly;
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-delay: 0.25s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-timing-function: ease;
|
||||||
|
}
|
||||||
|
.dolly-leave-active {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
@keyframes dolly {
|
||||||
|
0% {
|
||||||
|
transform: rotate(20deg);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
transform: rotate(-20deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(10deg);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: rotate(-10deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -42,10 +42,18 @@
|
||||||
<Label class="bx" :text="icon.link" />
|
<Label class="bx" :text="icon.link" />
|
||||||
<Label text="View project on GitHub" class="option-title" />
|
<Label text="View project on GitHub" class="option-title" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout orientation="horizontal" class="icon-option">
|
<StackLayout
|
||||||
|
orientation="horizontal"
|
||||||
|
class="icon-option"
|
||||||
|
@tap="openURL($event, 'https://t.me/enrecipes')"
|
||||||
|
>
|
||||||
|
<Label class="bx" :text="icon.telegram" />
|
||||||
|
<Label text="Join the telegram group" class="option-title" />
|
||||||
|
</StackLayout>
|
||||||
|
<!-- <StackLayout orientation="horizontal" class="icon-option">
|
||||||
<Label class="bx" :text="icon.file" />
|
<Label class="bx" :text="icon.file" />
|
||||||
<Label text="Licenses" class="option-title" />
|
<Label text="Licenses" class="option-title" />
|
||||||
</StackLayout>
|
</StackLayout> -->
|
||||||
|
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
class="sd-group-header orkm"
|
class="sd-group-header orkm"
|
||||||
rows="auto"
|
rows="auto"
|
||||||
columns="*, auto"
|
columns="*, auto"
|
||||||
v-if="categories.length"
|
v-if="categoriesWithRecipes.length"
|
||||||
>
|
>
|
||||||
<Label col="0" text="Categories" />
|
<Label col="0" text="Categories" />
|
||||||
<Label
|
<Label
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<GridLayout
|
<GridLayout
|
||||||
@tap="navigateTo(item, false, true)"
|
@tap="navigateTo(item, false, true)"
|
||||||
v-for="(item, index) in categories"
|
v-for="(item, index) in categoriesWithRecipes"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="sd-item orkm"
|
class="sd-item orkm"
|
||||||
:class="{
|
:class="{
|
||||||
|
@ -75,14 +75,14 @@
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout row="1">
|
<StackLayout row="1">
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<StackLayout
|
<!-- <StackLayout
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="sd-item orkm"
|
class="sd-item orkm"
|
||||||
@tap="donate"
|
@tap="donate"
|
||||||
>
|
>
|
||||||
<Label class="bx" :text="icon.donate" margin="0 24 0 0" />
|
<Label class="bx" :text="icon.donate" margin="0 24 0 0" />
|
||||||
<Label text="Donate" />
|
<Label text="Donate" />
|
||||||
</StackLayout>
|
</StackLayout> -->
|
||||||
<StackLayout
|
<StackLayout
|
||||||
@tap="navigateTo(item.component, true, false)"
|
@tap="navigateTo(item.component, true, false)"
|
||||||
v-for="(item, index) in bottommenu"
|
v-for="(item, index) in bottommenu"
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
<EnRecipes
|
<EnRecipes
|
||||||
ref="enrecipes"
|
ref="enrecipes"
|
||||||
:filterFavorites="filterFavorites"
|
:filterFavorites="filterFavorites"
|
||||||
:filterMustTry="filterMustTry"
|
:filterTrylater="filterTrylater"
|
||||||
:selectedCategory="selectedCategory"
|
:selectedCategory="selectedCategory"
|
||||||
:showDrawer="showDrawer"
|
:showDrawer="showDrawer"
|
||||||
:hijackGlobalBackEvent="hijackGlobalBackEvent"
|
:hijackGlobalBackEvent="hijackGlobalBackEvent"
|
||||||
|
@ -145,7 +145,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
selectedCategory: null,
|
selectedCategory: null,
|
||||||
filterFavorites: false,
|
filterFavorites: false,
|
||||||
filterMustTry: false,
|
filterTrylater: false,
|
||||||
topmenu: [
|
topmenu: [
|
||||||
{
|
{
|
||||||
title: "Home",
|
title: "Home",
|
||||||
|
@ -158,9 +158,9 @@ export default {
|
||||||
icon: "heart",
|
icon: "heart",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Must-Try",
|
title: "Try later",
|
||||||
component: "Must-Try",
|
component: "Try later",
|
||||||
icon: "musttry",
|
icon: "trylater",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
bottommenu: [
|
bottommenu: [
|
||||||
|
@ -179,8 +179,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes", "currentComponent"]),
|
...mapState(["icon", "recipes", "categories", "currentComponent"]),
|
||||||
categories() {
|
categoriesWithRecipes() {
|
||||||
let arr = this.recipes.map((e) => {
|
let arr = this.recipes.map((e) => {
|
||||||
return e.category
|
return e.category
|
||||||
})
|
})
|
||||||
|
@ -197,7 +197,7 @@ export default {
|
||||||
toggleCatEdit() {
|
toggleCatEdit() {
|
||||||
this.catEditMode = !this.catEditMode
|
this.catEditMode = !this.catEditMode
|
||||||
this.setComponent("EnRecipes")
|
this.setComponent("EnRecipes")
|
||||||
this.filterFavorites = this.filterMustTry = false
|
this.filterFavorites = this.filterTrylater = false
|
||||||
this.selectedCategory = null
|
this.selectedCategory = null
|
||||||
this.$refs.enrecipes.updateFilter()
|
this.$refs.enrecipes.updateFilter()
|
||||||
},
|
},
|
||||||
|
@ -223,9 +223,7 @@ export default {
|
||||||
highlight(args) {
|
highlight(args) {
|
||||||
let temp = args.object.className
|
let temp = args.object.className
|
||||||
args.object.className = `${temp} option-highlight`
|
args.object.className = `${temp} option-highlight`
|
||||||
setTimeout(() => {
|
setTimeout(() => (args.object.className = temp), 100)
|
||||||
args.object.className = temp
|
|
||||||
}, 100)
|
|
||||||
},
|
},
|
||||||
// Navigation
|
// Navigation
|
||||||
setSelectedCategory(e) {
|
setSelectedCategory(e) {
|
||||||
|
@ -252,8 +250,8 @@ export default {
|
||||||
function isFiltered() {
|
function isFiltered() {
|
||||||
vm.filterFavorites
|
vm.filterFavorites
|
||||||
? vm.setComponent("Favorites")
|
? vm.setComponent("Favorites")
|
||||||
: vm.filterMustTry
|
: vm.filterTrylater
|
||||||
? vm.setComponent("Must-Try")
|
? vm.setComponent("Try later")
|
||||||
: vm.selectedCategory
|
: vm.selectedCategory
|
||||||
? vm.setComponent(vm.selectedCategory)
|
? vm.setComponent(vm.selectedCategory)
|
||||||
: vm.setComponent("EnRecipes")
|
: vm.setComponent("EnRecipes")
|
||||||
|
@ -263,13 +261,13 @@ export default {
|
||||||
this.closeDrawer()
|
this.closeDrawer()
|
||||||
this.catEditMode = false
|
this.catEditMode = false
|
||||||
} else if (
|
} else if (
|
||||||
["Favorites", "Must-Try", this.selectedCategory].includes(
|
["Favorites", "Try later", this.selectedCategory].includes(
|
||||||
this.currentComponent
|
this.currentComponent
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
preventDefault()
|
preventDefault()
|
||||||
this.setComponent("EnRecipes")
|
this.setComponent("EnRecipes")
|
||||||
this.filterFavorites = this.filterMustTry = false
|
this.filterFavorites = this.filterTrylater = false
|
||||||
this.selectedCategory = null
|
this.selectedCategory = null
|
||||||
this.$refs.enrecipes.updateFilter()
|
this.$refs.enrecipes.updateFilter()
|
||||||
this.releaseGlobalBackEvent()
|
this.releaseGlobalBackEvent()
|
||||||
|
@ -296,7 +294,7 @@ export default {
|
||||||
this.setComponent(to)
|
this.setComponent(to)
|
||||||
this.$navigateBack({ frame: "main-frame", backstackVisible: false })
|
this.$navigateBack({ frame: "main-frame", backstackVisible: false })
|
||||||
this.filterFavorites = to === "Favorites" ? true : false
|
this.filterFavorites = to === "Favorites" ? true : false
|
||||||
this.filterMustTry = to === "Must-Try" ? true : false
|
this.filterTrylater = to === "Try later" ? true : false
|
||||||
this.selectedCategory = isCategory ? to : null
|
this.selectedCategory = isCategory ? to : null
|
||||||
this.$refs.enrecipes.updateFilter()
|
this.$refs.enrecipes.updateFilter()
|
||||||
this.closeDrawer()
|
this.closeDrawer()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @unloaded="releaseBackEvent">
|
<Page @loaded="initialize" @unloaded="releaseBackEvent">
|
||||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||||
<GridLayout rows="*" columns="auto, *, auto," class="actionBarContainer">
|
<GridLayout rows="*" columns="auto, *, auto" class="actionBarContainer">
|
||||||
<Label
|
<Label
|
||||||
class="bx leftAction"
|
class="bx leftAction"
|
||||||
:text="icon.back"
|
:text="icon.back"
|
||||||
|
@ -10,7 +10,6 @@
|
||||||
@tap="navigateBack"
|
@tap="navigateBack"
|
||||||
/>
|
/>
|
||||||
<Label class="title orkm" :text="title" col="1" />
|
<Label class="title orkm" :text="title" col="1" />
|
||||||
|
|
||||||
<Label
|
<Label
|
||||||
v-if="hasEnoughDetails"
|
v-if="hasEnoughDetails"
|
||||||
class="bx"
|
class="bx"
|
||||||
|
@ -20,251 +19,237 @@
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<ScrollView
|
<AbsoluteLayout>
|
||||||
width="100%"
|
<ScrollView
|
||||||
height="100%"
|
width="100%"
|
||||||
@scroll="onScroll($event)"
|
height="100%"
|
||||||
scrollBarIndicatorVisible="false"
|
@scroll="onScroll($event)"
|
||||||
>
|
scrollBarIndicatorVisible="false"
|
||||||
<StackLayout width="100%">
|
>
|
||||||
<!-- Image and camera btn -->
|
<StackLayout width="100%" padding="0 0 128">
|
||||||
<AbsoluteLayout>
|
<!-- Image and camera btn -->
|
||||||
<StackLayout
|
<AbsoluteLayout>
|
||||||
width="100%"
|
<StackLayout
|
||||||
:height="screenWidth"
|
|
||||||
class="view-imageHolder"
|
|
||||||
verticalAlignment="center"
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
v-if="recipeContent.imageSrc"
|
|
||||||
:src="recipeContent.imageSrc"
|
|
||||||
stretch="aspectFill"
|
|
||||||
width="100%"
|
width="100%"
|
||||||
:height="screenWidth"
|
:height="screenWidth"
|
||||||
/>
|
class="view-imageHolder"
|
||||||
<Label
|
verticalAlignment="center"
|
||||||
v-else
|
>
|
||||||
horizontalAlignment="center"
|
<Image
|
||||||
class="bx"
|
v-if="recipeContent.imageSrc"
|
||||||
fontSize="160"
|
:src="recipeContent.imageSrc"
|
||||||
:text="icon.image"
|
stretch="aspectFill"
|
||||||
/>
|
width="100%"
|
||||||
</StackLayout>
|
:height="screenWidth"
|
||||||
<StackLayout
|
/>
|
||||||
width="100%"
|
|
||||||
horizontalAlignment="center"
|
|
||||||
:top="screenWidth - 42"
|
|
||||||
>
|
|
||||||
<Label
|
|
||||||
v-if="recipeContent.imageSrc"
|
|
||||||
@tap="removePicture"
|
|
||||||
class="bx fab-button"
|
|
||||||
:text="icon.close"
|
|
||||||
androidElevation="8"
|
|
||||||
/>
|
|
||||||
<GridLayout v-else rows="auto" columns="*, auto, auto, *">
|
|
||||||
<Label
|
<Label
|
||||||
col="1"
|
v-else
|
||||||
@tap="takePicture"
|
horizontalAlignment="center"
|
||||||
class="bx fab-button"
|
class="bx"
|
||||||
:text="icon.camera"
|
fontSize="160"
|
||||||
androidElevation="8"
|
:text="icon.image"
|
||||||
|
/>
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout width="100%" :top="screenWidth - 42">
|
||||||
|
<transition :name="recipeContent.imageSrc ? 'null' : 'bounce'">
|
||||||
|
<Label
|
||||||
|
v-if="showFab"
|
||||||
|
horizontalAlignment="right"
|
||||||
|
@tap="photoHandler"
|
||||||
|
class="bx fab-button"
|
||||||
|
:text="icon.camera"
|
||||||
|
androidElevation="6"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
|
</StackLayout>
|
||||||
|
</AbsoluteLayout>
|
||||||
|
|
||||||
|
<!-- Primary information -->
|
||||||
|
<StackLayout margin="0 16">
|
||||||
|
<AbsoluteLayout class="inputField">
|
||||||
|
<TextField
|
||||||
|
hint="My Healthy Recipe"
|
||||||
|
v-model="recipeContent.title"
|
||||||
|
autocapitalizationType="words"
|
||||||
|
/>
|
||||||
|
<Label top="0" class="fieldLabel" text="Title" />
|
||||||
|
</AbsoluteLayout>
|
||||||
|
<AbsoluteLayout class="inputField">
|
||||||
|
<TextField
|
||||||
|
v-model="recipeContent.category"
|
||||||
|
editable="false"
|
||||||
|
@tap="showCategories()"
|
||||||
|
/>
|
||||||
|
<Label top="0" class="fieldLabel" text="Category" />
|
||||||
|
</AbsoluteLayout>
|
||||||
|
<GridLayout columns="*, 8, *">
|
||||||
|
<AbsoluteLayout class="inputField" col="0">
|
||||||
|
<TimePickerField
|
||||||
|
titleTextColor="red"
|
||||||
|
timeFormat="HH:mm"
|
||||||
|
pickerTitle="Approx. preparation time"
|
||||||
|
@timeChange="onPrepTimeChange"
|
||||||
|
:time="recipeContent.prepTime"
|
||||||
|
></TimePickerField>
|
||||||
|
<Label top="0" class="fieldLabel" text="Preparation time" />
|
||||||
|
</AbsoluteLayout>
|
||||||
|
<AbsoluteLayout class="inputField" col="2">
|
||||||
|
<TimePickerField
|
||||||
|
timeFormat="HH:mm"
|
||||||
|
pickerTitle="Approx. cooking time"
|
||||||
|
@timeChange="onCookTimeChange"
|
||||||
|
:time="recipeContent.cookTime"
|
||||||
|
></TimePickerField>
|
||||||
|
<Label top="0" class="fieldLabel" text="Cooking time" />
|
||||||
|
</AbsoluteLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<GridLayout columns="*, 16, *">
|
||||||
|
<AbsoluteLayout class="inputField" col="0">
|
||||||
|
<TextField
|
||||||
|
width="100%"
|
||||||
|
keyboardType="number"
|
||||||
|
v-model="recipeContent.portionSize"
|
||||||
|
/>
|
||||||
|
<Label top="0" class="fieldLabel" text="Portion size" />
|
||||||
|
</AbsoluteLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
<!-- Ingredients section -->
|
||||||
|
<StackLayout margin="0 16">
|
||||||
|
<Label text="Ingredients" class="sectionTitle" />
|
||||||
|
<GridLayout
|
||||||
|
columns="*,8,auto,8,auto,8,auto"
|
||||||
|
v-for="(ingredient, index) in recipeContent.ingredients"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
col="0"
|
||||||
|
v-model="recipeContent.ingredients[index].item"
|
||||||
|
:hint="`Item ${index + 1}`"
|
||||||
|
autocapitalizationType="words"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
width="72"
|
||||||
|
col="2"
|
||||||
|
v-model="recipeContent.ingredients[index].quantity"
|
||||||
|
hint="1.000"
|
||||||
|
keyboardType="number"
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
width="64"
|
||||||
|
col="4"
|
||||||
|
v-model="recipeContent.ingredients[index].unit"
|
||||||
|
hint="Unit"
|
||||||
|
editable="false"
|
||||||
|
@tap="showUnits($event)"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
col="6"
|
||||||
|
class="bx closeBtn"
|
||||||
|
:text="icon.close"
|
||||||
|
@tap="removeIngredient(index)"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
<Label
|
||||||
|
class="sec-btn pull-left orkm"
|
||||||
|
text="+ ADD INGREDIENT"
|
||||||
|
@tap="addIngredient()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
|
||||||
|
<!-- Instructions section -->
|
||||||
|
<StackLayout margin="0 16">
|
||||||
|
<Label text="Instructions" class="sectionTitle" />
|
||||||
|
<GridLayout
|
||||||
|
columns="*,8,auto"
|
||||||
|
v-for="(instruction, index) in recipeContent.instructions"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
col="0"
|
||||||
|
:hint="`Step ${index + 1}`"
|
||||||
|
v-model="recipeContent.instructions[index]"
|
||||||
|
editable="true"
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
col="2"
|
col="2"
|
||||||
@tap="selectPicture"
|
class="bx closeBtn"
|
||||||
class="bx fab-button"
|
:text="icon.close"
|
||||||
:text="icon.image"
|
@tap="removeInstruction(index)"
|
||||||
androidElevation="8"
|
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
<Label
|
||||||
|
class="sec-btn pull-left orkm"
|
||||||
|
text="+ ADD STEP"
|
||||||
|
@tap="addInstruction()"
|
||||||
|
/>
|
||||||
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</AbsoluteLayout>
|
|
||||||
|
|
||||||
<!-- Primary information -->
|
<!-- Notes section -->
|
||||||
<StackLayout margin="0 16">
|
<StackLayout margin="0 16">
|
||||||
<AbsoluteLayout class="inputField">
|
<Label text="Notes" class="sectionTitle" />
|
||||||
<TextField
|
<GridLayout
|
||||||
hint="My Healthy Recipe"
|
columns="*,8,auto"
|
||||||
v-model="recipeContent.title"
|
v-for="(note, index) in recipeContent.notes"
|
||||||
autocapitalizationType="words"
|
:key="index"
|
||||||
/>
|
>
|
||||||
<Label top="0" class="fieldLabel" text="Title" />
|
<TextView
|
||||||
</AbsoluteLayout>
|
col="0"
|
||||||
<AbsoluteLayout class="inputField">
|
v-model="recipeContent.notes[index]"
|
||||||
<TextField
|
:hint="`Note ${index + 1}`"
|
||||||
v-model="recipeContent.category"
|
editable="true"
|
||||||
editable="false"
|
|
||||||
@tap="showCategories()"
|
|
||||||
/>
|
|
||||||
<Label top="0" class="fieldLabel" text="Category" />
|
|
||||||
</AbsoluteLayout>
|
|
||||||
<GridLayout columns="*, 8, *">
|
|
||||||
<AbsoluteLayout class="inputField" col="0">
|
|
||||||
<TimePickerField
|
|
||||||
titleTextColor="red"
|
|
||||||
timeFormat="HH:mm"
|
|
||||||
pickerTitle="Approx. preparation time"
|
|
||||||
@timeChange="onPrepTimeChange"
|
|
||||||
:time="recipeContent.prepTime"
|
|
||||||
></TimePickerField>
|
|
||||||
<Label top="0" class="fieldLabel" text="Preparation time" />
|
|
||||||
</AbsoluteLayout>
|
|
||||||
<AbsoluteLayout class="inputField" col="2">
|
|
||||||
<TimePickerField
|
|
||||||
timeFormat="HH:mm"
|
|
||||||
pickerTitle="Approx. cooking time"
|
|
||||||
@timeChange="onCookTimeChange"
|
|
||||||
:time="recipeContent.cookTime"
|
|
||||||
></TimePickerField>
|
|
||||||
<Label top="0" class="fieldLabel" text="Cooking time" />
|
|
||||||
</AbsoluteLayout>
|
|
||||||
</GridLayout>
|
|
||||||
<GridLayout columns="*, 16, *">
|
|
||||||
<AbsoluteLayout class="inputField" col="0">
|
|
||||||
<TextField
|
|
||||||
width="100%"
|
|
||||||
keyboardType="number"
|
|
||||||
v-model="recipeContent.portionSize"
|
|
||||||
/>
|
/>
|
||||||
<Label top="0" class="fieldLabel" text="Portion size" />
|
<Label
|
||||||
</AbsoluteLayout>
|
col="2"
|
||||||
</GridLayout>
|
class="bx closeBtn"
|
||||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
:text="icon.close"
|
||||||
</StackLayout>
|
@tap="removeNote(index)"
|
||||||
|
/>
|
||||||
<!-- Ingredients section -->
|
</GridLayout>
|
||||||
<StackLayout margin="0 16">
|
|
||||||
<Label text="Ingredients" class="sectionTitle" />
|
|
||||||
<GridLayout
|
|
||||||
columns="*,8,auto,8,auto,8,auto"
|
|
||||||
v-for="(ingredient, index) in recipeContent.ingredients"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
col="0"
|
|
||||||
v-model="recipeContent.ingredients[index].item"
|
|
||||||
:hint="`Item ${index + 1}`"
|
|
||||||
autocapitalizationType="words"
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
width="72"
|
|
||||||
col="2"
|
|
||||||
v-model="recipeContent.ingredients[index].quantity"
|
|
||||||
hint="1.000"
|
|
||||||
keyboardType="number"
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
width="64"
|
|
||||||
col="4"
|
|
||||||
v-model="recipeContent.ingredients[index].unit"
|
|
||||||
hint="Unit"
|
|
||||||
editable="false"
|
|
||||||
@tap="showUnits($event)"
|
|
||||||
/>
|
|
||||||
<Label
|
<Label
|
||||||
col="6"
|
class="sec-btn pull-left orkm"
|
||||||
class="bx closeBtn"
|
text="+ ADD NOTE"
|
||||||
:text="icon.close"
|
@tap="addNote()"
|
||||||
@tap="removeIngredient(index)"
|
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||||
<Label
|
</StackLayout>
|
||||||
class="sec-btn pull-left orkm"
|
|
||||||
text="+ ADD INGREDIENT"
|
|
||||||
@tap="addIngredient()"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
<!-- References section -->
|
||||||
</StackLayout>
|
<StackLayout margin="0 16">
|
||||||
|
<Label text="References" class="sectionTitle" />
|
||||||
<!-- Instructions section -->
|
<GridLayout
|
||||||
<StackLayout margin="0 16">
|
columns="*,8,auto"
|
||||||
<Label text="Instructions" class="sectionTitle" />
|
v-for="(reference, index) in recipeContent.references"
|
||||||
<GridLayout
|
:key="index"
|
||||||
columns="*,8,auto"
|
>
|
||||||
v-for="(instruction, index) in recipeContent.instructions"
|
<TextView
|
||||||
:key="index"
|
col="0"
|
||||||
>
|
v-model="recipeContent.references[index]"
|
||||||
<TextView
|
hint="Text or Website/Video URL"
|
||||||
col="0"
|
editable="true"
|
||||||
:hint="`Step ${index + 1}`"
|
/>
|
||||||
v-model="recipeContent.instructions[index]"
|
<Label
|
||||||
editable="true"
|
col="2"
|
||||||
/>
|
class="bx closeBtn"
|
||||||
|
:text="icon.close"
|
||||||
|
@tap="removeReference(index)"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
<Label
|
<Label
|
||||||
col="2"
|
class="sec-btn pull-left orkm"
|
||||||
class="bx closeBtn"
|
text="+ ADD REFERENCE"
|
||||||
:text="icon.close"
|
@tap="addReference()"
|
||||||
@tap="removeInstruction(index)"
|
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
<StackLayout margin="32"></StackLayout>
|
||||||
<Label
|
</StackLayout>
|
||||||
class="sec-btn pull-left orkm"
|
|
||||||
text="+ ADD STEP"
|
|
||||||
@tap="addInstruction()"
|
|
||||||
/>
|
|
||||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
</ScrollView>
|
||||||
<!-- Notes section -->
|
</AbsoluteLayout>
|
||||||
<StackLayout margin="0 16">
|
|
||||||
<Label text="Notes" class="sectionTitle" />
|
|
||||||
<GridLayout
|
|
||||||
columns="*,8,auto"
|
|
||||||
v-for="(note, index) in recipeContent.notes"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<TextView
|
|
||||||
col="0"
|
|
||||||
v-model="recipeContent.notes[index]"
|
|
||||||
:hint="`Note ${index + 1}`"
|
|
||||||
editable="true"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
col="2"
|
|
||||||
class="bx closeBtn"
|
|
||||||
:text="icon.close"
|
|
||||||
@tap="removeNote(index)"
|
|
||||||
/>
|
|
||||||
</GridLayout>
|
|
||||||
<Label
|
|
||||||
class="sec-btn pull-left orkm"
|
|
||||||
text="+ ADD NOTE"
|
|
||||||
@tap="addNote()"
|
|
||||||
/>
|
|
||||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
|
||||||
</StackLayout>
|
|
||||||
|
|
||||||
<!-- References section -->
|
|
||||||
<StackLayout margin="0 16">
|
|
||||||
<Label text="References" class="sectionTitle" />
|
|
||||||
<GridLayout
|
|
||||||
columns="*,8,auto"
|
|
||||||
v-for="(reference, index) in recipeContent.references"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
col="0"
|
|
||||||
v-model="recipeContent.references[index]"
|
|
||||||
hint="Website or Video URL"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
col="2"
|
|
||||||
class="bx closeBtn"
|
|
||||||
:text="icon.close"
|
|
||||||
@tap="removeReference(index)"
|
|
||||||
/>
|
|
||||||
</GridLayout>
|
|
||||||
<Label
|
|
||||||
class="sec-btn pull-left orkm"
|
|
||||||
text="+ ADD REFERENCE"
|
|
||||||
@tap="addReference()"
|
|
||||||
/>
|
|
||||||
<StackLayout margin="32"></StackLayout>
|
|
||||||
</StackLayout>
|
|
||||||
</StackLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -277,14 +262,13 @@ import {
|
||||||
getFileAccess,
|
getFileAccess,
|
||||||
knownFolders,
|
knownFolders,
|
||||||
} from "@nativescript/core"
|
} from "@nativescript/core"
|
||||||
import * as imagepicker from "nativescript-imagepicker"
|
import { Mediafilepicker } from "nativescript-mediafilepicker"
|
||||||
import * as camera from "@nativescript/camera"
|
|
||||||
|
|
||||||
import { mapState, mapActions } from "vuex"
|
import { mapState, mapActions } from "vuex"
|
||||||
|
|
||||||
import ActionDialog from "./modal/ActionDialog.vue"
|
import ActionDialog from "./modal/ActionDialog.vue"
|
||||||
import PromptDialog from "./modal/PromptDialog.vue"
|
|
||||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||||
|
import PromptDialog from "./modal/PromptDialog.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["recipeIndex", "recipeID", "selectedCategory"],
|
props: ["recipeIndex", "recipeID", "selectedCategory"],
|
||||||
|
@ -294,36 +278,15 @@ export default {
|
||||||
viewIsScrolled: false,
|
viewIsScrolled: false,
|
||||||
recipeContent: {
|
recipeContent: {
|
||||||
imageSrc: null,
|
imageSrc: null,
|
||||||
title: null,
|
title: undefined,
|
||||||
category: null,
|
category: "Undefined",
|
||||||
prepTime: "00:00",
|
prepTime: "00:00",
|
||||||
cookTime: "00:00",
|
cookTime: "00:00",
|
||||||
portionSize: 1,
|
portionSize: 1,
|
||||||
ingredients: [
|
ingredients: [
|
||||||
{
|
{
|
||||||
item: "",
|
item: "",
|
||||||
quantity: null,
|
quantity: undefined,
|
||||||
unit: "unit",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
instructions: [""],
|
|
||||||
notes: [""],
|
|
||||||
references: [""],
|
|
||||||
isFavorite: false,
|
|
||||||
tried: false,
|
|
||||||
lastModified: null,
|
|
||||||
},
|
|
||||||
tempRecipeContent: {
|
|
||||||
imageSrc: null,
|
|
||||||
title: null,
|
|
||||||
category: null,
|
|
||||||
prepTime: "00:00",
|
|
||||||
cookTime: "00:00",
|
|
||||||
portionSize: 1,
|
|
||||||
ingredients: [
|
|
||||||
{
|
|
||||||
item: "",
|
|
||||||
quantity: null,
|
|
||||||
unit: "unit",
|
unit: "unit",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -334,8 +297,10 @@ export default {
|
||||||
tried: false,
|
tried: false,
|
||||||
lastModified: null,
|
lastModified: null,
|
||||||
},
|
},
|
||||||
|
tempRecipeContent: {},
|
||||||
blockModal: false,
|
blockModal: false,
|
||||||
newRecipeID: null,
|
newRecipeID: null,
|
||||||
|
showFab: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -344,14 +309,10 @@ export default {
|
||||||
return Screen.mainScreen.widthDIPs
|
return Screen.mainScreen.widthDIPs
|
||||||
},
|
},
|
||||||
hasEnoughDetails() {
|
hasEnoughDetails() {
|
||||||
if (this.recipeID) {
|
return (
|
||||||
return (
|
JSON.stringify(this.recipeContent) !==
|
||||||
JSON.stringify(this.recipeContent) !==
|
JSON.stringify(this.tempRecipeContent)
|
||||||
JSON.stringify(this.tempRecipeContent)
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return this.recipeContent.title
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -361,6 +322,9 @@ export default {
|
||||||
"overwriteRecipeAction",
|
"overwriteRecipeAction",
|
||||||
"addCategoryAction",
|
"addCategoryAction",
|
||||||
]),
|
]),
|
||||||
|
initialize() {
|
||||||
|
this.showFab = true
|
||||||
|
},
|
||||||
getRandomID() {
|
getRandomID() {
|
||||||
let res = ""
|
let res = ""
|
||||||
let chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
let chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
|
@ -380,12 +344,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearEmptyFields() {
|
clearEmptyFields() {
|
||||||
|
if (!this.recipeContent.title) {
|
||||||
|
this.recipeContent.title = "Untitled Recipe"
|
||||||
|
}
|
||||||
if (!this.recipeContent.portionSize) {
|
if (!this.recipeContent.portionSize) {
|
||||||
this.recipeContent.portionSize = 1
|
this.recipeContent.portionSize = 1
|
||||||
}
|
}
|
||||||
if (!this.recipeContent.category) {
|
|
||||||
this.recipeContent.category = "Undefined"
|
|
||||||
}
|
|
||||||
this.recipeContent.ingredients.forEach((e, i) => {
|
this.recipeContent.ingredients.forEach((e, i) => {
|
||||||
if (!e.item.length) {
|
if (!e.item.length) {
|
||||||
this.recipeContent.ingredients.splice(i, 1)
|
this.recipeContent.ingredients.splice(i, 1)
|
||||||
|
@ -404,6 +368,10 @@ export default {
|
||||||
removeEmpty("references")
|
removeEmpty("references")
|
||||||
},
|
},
|
||||||
saveRecipe() {
|
saveRecipe() {
|
||||||
|
console.log(
|
||||||
|
JSON.stringify(this.recipeContent),
|
||||||
|
JSON.stringify(this.tempRecipeContent)
|
||||||
|
)
|
||||||
this.clearEmptyFields()
|
this.clearEmptyFields()
|
||||||
this.recipeContent.lastModified = new Date()
|
this.recipeContent.lastModified = new Date()
|
||||||
if (this.recipeID) {
|
if (this.recipeID) {
|
||||||
|
@ -471,15 +439,17 @@ export default {
|
||||||
this.blockModal = true
|
this.blockModal = true
|
||||||
this.$showModal(ConfirmDialog, {
|
this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: "Discard changes",
|
title: "Unsaved changes",
|
||||||
description:
|
description:
|
||||||
"Are you sure you want discard unsaved changes to this recipe?",
|
"Do you want to save the changes you made in this recipe?",
|
||||||
cancelButtonText: "KEEP EDITING",
|
cancelButtonText: "DISCARD",
|
||||||
okButtonText: "DISCARD",
|
okButtonText: "SAVE",
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
this.blockModal = false
|
this.blockModal = false
|
||||||
if (action) {
|
if (action) {
|
||||||
|
this.saveRecipe()
|
||||||
|
} else if (action != null) {
|
||||||
this.$navigateBack()
|
this.$navigateBack()
|
||||||
this.releaseBackEvent()
|
this.releaseBackEvent()
|
||||||
}
|
}
|
||||||
|
@ -507,59 +477,59 @@ export default {
|
||||||
this.navigateBack()
|
this.navigateBack()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
photoHandler() {
|
||||||
|
if (this.recipeContent.imageSrc) {
|
||||||
|
this.blockModal = true
|
||||||
|
this.$showModal(ConfirmDialog, {
|
||||||
|
props: {
|
||||||
|
title: "Recipe photo",
|
||||||
|
cancelButtonText: "REMOVE",
|
||||||
|
okButtonText: "REPLACE PHOTO",
|
||||||
|
},
|
||||||
|
}).then((action) => {
|
||||||
|
this.blockModal = false
|
||||||
|
if (action) {
|
||||||
|
this.takePicture()
|
||||||
|
} else if (action != null) {
|
||||||
|
this.removePicture()
|
||||||
|
this.releaseBackEvent()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.takePicture()
|
||||||
|
}
|
||||||
|
},
|
||||||
takePicture() {
|
takePicture() {
|
||||||
const vm = this
|
const vm = this
|
||||||
camera.requestPermissions().then(
|
const mediafilepicker = new Mediafilepicker()
|
||||||
() => {
|
mediafilepicker.openImagePicker({
|
||||||
camera
|
android: {
|
||||||
.takePicture({
|
isCaptureMood: false, // if true then camera will open directly.
|
||||||
width: vm.screenWidth,
|
isNeedCamera: true,
|
||||||
height: vm.screenWidth,
|
maxNumberFiles: 1,
|
||||||
keepAspectRatio: false,
|
isNeedFolderList: true,
|
||||||
saveToGallery: false,
|
|
||||||
})
|
|
||||||
.then((imageAsset) => {
|
|
||||||
let result = imageAsset._android
|
|
||||||
ImageSource.fromFile(result).then((savedImg) => {
|
|
||||||
let savedImgPath = path.join(
|
|
||||||
knownFolders.documents().getFolder("enrecipes").path,
|
|
||||||
`${vm.getRandomID()}.jpg`
|
|
||||||
)
|
|
||||||
savedImg.saveToFile(savedImgPath, "jpg")
|
|
||||||
vm.recipeContent.imageSrc = savedImgPath
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("Error -> " + err.message)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
() => {
|
|
||||||
console.log("permission request rejected")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
selectPicture() {
|
|
||||||
let context = imagepicker.create({
|
|
||||||
mode: "single",
|
|
||||||
mediaType: "Image",
|
|
||||||
})
|
})
|
||||||
context
|
mediafilepicker.on("getFiles", (image) => {
|
||||||
.authorize()
|
let result = image.object.get("results")[0].file
|
||||||
.then(() => context.present())
|
ImageSource.fromFile(result).then((savedImg) => {
|
||||||
.then((selection) => {
|
let savedImgPath = path.join(
|
||||||
let result = selection[0]._android
|
knownFolders.documents().getFolder("enrecipes").path,
|
||||||
ImageSource.fromFile(result).then((savedImg) => {
|
`${vm.getRandomID()}.jpg`
|
||||||
let savedImgPath = path.join(
|
)
|
||||||
knownFolders.documents().getFolder("enrecipes").path,
|
savedImg.saveToFile(savedImgPath, "jpg")
|
||||||
`${this.getRandomID()}.jpg`
|
vm.recipeContent.imageSrc = savedImgPath
|
||||||
)
|
|
||||||
savedImg.saveToFile(savedImgPath, "jpg")
|
|
||||||
this.recipeContent.imageSrc = savedImgPath
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(function(e) {
|
|
||||||
console.log(e)
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
mediafilepicker.on("error", function(res) {
|
||||||
|
let msg = res.object.get("msg")
|
||||||
|
console.log(msg)
|
||||||
|
})
|
||||||
|
|
||||||
|
mediafilepicker.on("cancel", function(res) {
|
||||||
|
let msg = res.object.get("msg")
|
||||||
|
console.log(msg)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
removePicture() {
|
removePicture() {
|
||||||
confirm({
|
confirm({
|
||||||
|
@ -627,9 +597,13 @@ export default {
|
||||||
this.title = this.recipeID ? "Edit recipe" : "New recipe"
|
this.title = this.recipeID ? "Edit recipe" : "New recipe"
|
||||||
if (this.recipeID) {
|
if (this.recipeID) {
|
||||||
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
||||||
Object.assign(this.recipeContent, recipe)
|
Object.assign(this.recipeContent, JSON.parse(JSON.stringify(recipe)))
|
||||||
Object.assign(this.tempRecipeContent, recipe)
|
Object.assign(this.tempRecipeContent, JSON.parse(JSON.stringify(recipe)))
|
||||||
} else {
|
} else {
|
||||||
|
Object.assign(
|
||||||
|
this.tempRecipeContent,
|
||||||
|
JSON.parse(JSON.stringify(this.recipeContent))
|
||||||
|
)
|
||||||
if (this.selectedCategory)
|
if (this.selectedCategory)
|
||||||
this.recipeContent.category = this.selectedCategory
|
this.recipeContent.category = this.selectedCategory
|
||||||
this.newRecipeID = this.getRandomID()
|
this.newRecipeID = this.getRandomID()
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
col="0"
|
col="0"
|
||||||
@tap="closeSearch"
|
@tap="closeSearch"
|
||||||
/>
|
/>
|
||||||
<!-- @loaded="searchBarLoaded" -->
|
|
||||||
<SearchBar
|
<SearchBar
|
||||||
col="1"
|
col="1"
|
||||||
hint="Search"
|
hint="Search"
|
||||||
|
@ -114,41 +113,92 @@
|
||||||
<StackLayout height="128"></StackLayout>
|
<StackLayout height="128"></StackLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
</RadListView>
|
</RadListView>
|
||||||
<Label
|
<GridLayout rows="*" columns="*" class="emptyState">
|
||||||
v-if="!recipes.length && !filterFavorites && !filterMustTry"
|
<StackLayout
|
||||||
class="noResults"
|
col="0"
|
||||||
text='Click the "+" icon to add a new recipe.'
|
row="0"
|
||||||
textWrap="true"
|
class="noResults"
|
||||||
/>
|
v-if="!recipes.length && !filterFavorites && !filterTrylater"
|
||||||
<Label
|
verticalAlignment="center"
|
||||||
v-if="!filteredRecipes.length && searchQuery"
|
>
|
||||||
class="noResults"
|
<Label
|
||||||
:text="
|
@tap="addRecipe"
|
||||||
`Your search "${searchQuery}" did not match any recipes in this category.`
|
class="bx"
|
||||||
"
|
:text="icon.plusCircle"
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
v-if="!filteredRecipes.length && filterFavorites && !searchQuery"
|
class="title orkb"
|
||||||
class="noResults"
|
text="Start adding your recipes!"
|
||||||
text="Your favorite recipes will be listed here."
|
textWrap="true"
|
||||||
textWrap="true"
|
/>
|
||||||
/>
|
<Label text='Tap the "+" icon to add a new recipe' textWrap="true" />
|
||||||
<Label
|
</StackLayout>
|
||||||
v-if="!filteredRecipes.length && filterMustTry && !searchQuery"
|
<StackLayout
|
||||||
class="noResults"
|
col="0"
|
||||||
text="Your must-try recipes will be listed here."
|
row="0"
|
||||||
textWrap="true"
|
class="noResults"
|
||||||
/>
|
v-if="!filteredRecipes.length && searchQuery"
|
||||||
<GridLayout id="btnFabContainer" rows="*,88" columns="*,88">
|
verticalAlignment="top"
|
||||||
<Label
|
>
|
||||||
row="1"
|
<Label class="bx" :text="icon.search" textWrap="true" />
|
||||||
col="1"
|
<Label class="title orkb" text="No recipes found" textWrap="true" />
|
||||||
class="bx fab-button"
|
<Label
|
||||||
:text="icon.plus"
|
:text="
|
||||||
androidElevation="8"
|
`Your search "${searchQuery}" did not match any recipes${
|
||||||
@tap="addRecipe"
|
filterFavorites || filterTrylater || selectedCategory
|
||||||
/>
|
? ' in this category'
|
||||||
|
: ''
|
||||||
|
}`
|
||||||
|
"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout
|
||||||
|
col="0"
|
||||||
|
row="0"
|
||||||
|
class="noResults"
|
||||||
|
verticalAlignment="center"
|
||||||
|
v-if="!filteredRecipes.length && filterFavorites && !searchQuery"
|
||||||
|
>
|
||||||
|
<Label class="bx" :text="icon.heartOutline" textWrap="true" />
|
||||||
|
<Label class="title orkb" text="No favorites yet!" textWrap="true" />
|
||||||
|
<Label
|
||||||
|
text="Your favorited recipes will be listed here"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout
|
||||||
|
col="0"
|
||||||
|
row="0"
|
||||||
|
class="noResults"
|
||||||
|
verticalAlignment="center"
|
||||||
|
v-if="!filteredRecipes.length && filterTrylater && !searchQuery"
|
||||||
|
>
|
||||||
|
<Label class="bx" :text="icon.trylaterOutline" textWrap="true" />
|
||||||
|
<Label
|
||||||
|
class="title orkb"
|
||||||
|
text="No recipes here to try!"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<!-- text="Your Try later recipes will be listed here" -->
|
||||||
|
<Label
|
||||||
|
text="Your recipes to try later will be listed here"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
</StackLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<GridLayout id="btnFabContainer" rows="*,auto" columns="*,auto">
|
||||||
|
<transition name="bounce">
|
||||||
|
<Label
|
||||||
|
v-if="showFAB"
|
||||||
|
row="1"
|
||||||
|
col="1"
|
||||||
|
class="bx fab-button"
|
||||||
|
:text="icon.plus"
|
||||||
|
@tap="addRecipe"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</AbsoluteLayout>
|
</AbsoluteLayout>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -166,7 +216,7 @@ import { mapState, mapActions } from "vuex"
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
"filterFavorites",
|
"filterFavorites",
|
||||||
"filterMustTry",
|
"filterTrylater",
|
||||||
"selectedCategory",
|
"selectedCategory",
|
||||||
"showDrawer",
|
"showDrawer",
|
||||||
"hijackGlobalBackEvent",
|
"hijackGlobalBackEvent",
|
||||||
|
@ -184,6 +234,7 @@ export default {
|
||||||
rightAction: false,
|
rightAction: false,
|
||||||
sortType: "Natural order",
|
sortType: "Natural order",
|
||||||
deletionDialogActive: false,
|
deletionDialogActive: false,
|
||||||
|
showFAB: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -194,7 +245,7 @@ export default {
|
||||||
(e) =>
|
(e) =>
|
||||||
e.isFavorite && e.title.toLowerCase().includes(this.searchQuery)
|
e.isFavorite && e.title.toLowerCase().includes(this.searchQuery)
|
||||||
)
|
)
|
||||||
} else if (this.filterMustTry) {
|
} else if (this.filterTrylater) {
|
||||||
return this.recipes.filter(
|
return this.recipes.filter(
|
||||||
(e) => !e.tried && e.title.toLowerCase().includes(this.searchQuery)
|
(e) => !e.tried && e.title.toLowerCase().includes(this.searchQuery)
|
||||||
)
|
)
|
||||||
|
@ -216,11 +267,12 @@ export default {
|
||||||
initializePage() {
|
initializePage() {
|
||||||
this.filterFavorites
|
this.filterFavorites
|
||||||
? this.setComponent("Favorites")
|
? this.setComponent("Favorites")
|
||||||
: this.filterMustTry
|
: this.filterTrylater
|
||||||
? this.setComponent("Must-Try")
|
? this.setComponent("Try later")
|
||||||
: this.selectedCategory
|
: this.selectedCategory
|
||||||
? this.setComponent(this.selectedCategory)
|
? this.setComponent(this.selectedCategory)
|
||||||
: this.setComponent("EnRecipes")
|
: this.setComponent("EnRecipes")
|
||||||
|
this.showFAB = true
|
||||||
},
|
},
|
||||||
openSearch() {
|
openSearch() {
|
||||||
this.showSearch = true
|
this.showSearch = true
|
||||||
|
@ -313,7 +365,7 @@ export default {
|
||||||
return item.isFavorite
|
return item.isFavorite
|
||||||
? item.title.toLowerCase().includes(this.searchQuery)
|
? item.title.toLowerCase().includes(this.searchQuery)
|
||||||
: false
|
: false
|
||||||
} else if (this.filterMustTry) {
|
} else if (this.filterTrylater) {
|
||||||
return item.tried
|
return item.tried
|
||||||
? false
|
? false
|
||||||
: item.title.toLowerCase().includes(this.searchQuery)
|
: item.title.toLowerCase().includes(this.searchQuery)
|
||||||
|
@ -387,13 +439,14 @@ export default {
|
||||||
: (this.viewIsScrolled = false)
|
: (this.viewIsScrolled = false)
|
||||||
},
|
},
|
||||||
addRecipe() {
|
addRecipe() {
|
||||||
|
this.showFAB = false
|
||||||
this.releaseGlobalBackEvent()
|
this.releaseGlobalBackEvent()
|
||||||
this.$navigateTo(EditRecipe, {
|
this.$navigateTo(EditRecipe, {
|
||||||
transition: {
|
// transition: {
|
||||||
name: "slide",
|
// name: "slide",
|
||||||
duration: 250,
|
// duration: 250,
|
||||||
curve: "easeIn",
|
// curve: "easeIn",
|
||||||
},
|
// },
|
||||||
props: {
|
props: {
|
||||||
viewIsScrolled: this.viewIsScrolled,
|
viewIsScrolled: this.viewIsScrolled,
|
||||||
selectedCategory: this.selectedCategory,
|
selectedCategory: this.selectedCategory,
|
||||||
|
@ -401,13 +454,15 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
viewRecipe({ item, index }) {
|
viewRecipe({ item, index }) {
|
||||||
|
this.showFAB = false
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
transition: {
|
// transition: {
|
||||||
name: "fade",
|
// name: "fade",
|
||||||
duration: 250,
|
// duration: 250,
|
||||||
curve: "easeIn",
|
// curve: "easeIn",
|
||||||
},
|
// },
|
||||||
props: {
|
props: {
|
||||||
|
filterTrylater: this.filterTrylater,
|
||||||
recipeIndex: index,
|
recipeIndex: index,
|
||||||
recipeID: item.id,
|
recipeID: item.id,
|
||||||
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
|
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
|
||||||
|
@ -416,5 +471,8 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.showFAB = true
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
|
|
||||||
<Label text="Backup/Restore" class="group-header" />
|
<Label text="Backup/Restore" class="group-header" />
|
||||||
<StackLayout
|
<!-- <StackLayout
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="option"
|
class="option"
|
||||||
@tap="selectBackupDir"
|
@tap="selectBackupDir"
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
<Label text="EnRecipes Backup Directory" class="option-title" />
|
<Label text="EnRecipes Backup Directory" class="option-title" />
|
||||||
<Label text="/storage/emulated/0/EnRecipes" class="option-info" />
|
<Label text="/storage/emulated/0/EnRecipes" class="option-info" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout> -->
|
||||||
<StackLayout orientation="horizontal" class="option" @tap="backupData">
|
<StackLayout orientation="horizontal" class="option" @tap="backupData">
|
||||||
<Label class="bx" :text="icon.backup" />
|
<Label class="bx" :text="icon.backup" />
|
||||||
<Label text="Backup Data" class="option-title" />
|
<Label text="Backup Data" class="option-title" />
|
||||||
|
@ -63,7 +63,6 @@ import {
|
||||||
path,
|
path,
|
||||||
getFileAccess,
|
getFileAccess,
|
||||||
knownFolders,
|
knownFolders,
|
||||||
Application,
|
|
||||||
} from "@nativescript/core"
|
} from "@nativescript/core"
|
||||||
import * as permissions from "nativescript-permissions"
|
import * as permissions from "nativescript-permissions"
|
||||||
import { Zip } from "nativescript-zip"
|
import { Zip } from "nativescript-zip"
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="initializePage">
|
<Page @loaded="initializePage">
|
||||||
<ActionBar height="128" margin="0" flat="true">
|
<ActionBar height="152" margin="0" flat="true">
|
||||||
<GridLayout
|
<GridLayout
|
||||||
rows="64, 64"
|
rows="24, 64, 64"
|
||||||
columns="auto, *, auto,auto, auto"
|
columns="auto, *, auto,auto, auto"
|
||||||
class="actionBarContainer"
|
class="actionBarContainer"
|
||||||
>
|
>
|
||||||
<Label
|
<Label
|
||||||
row="0"
|
row="1"
|
||||||
col="0"
|
col="0"
|
||||||
class="bx leftAction"
|
class="bx leftAction"
|
||||||
:text="icon.back"
|
:text="icon.back"
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
@tap="$navigateBack()"
|
@tap="$navigateBack()"
|
||||||
/>
|
/>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
row="1"
|
row="2"
|
||||||
col="1"
|
col="1"
|
||||||
colSpan="3"
|
colSpan="3"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
|
@ -28,28 +28,29 @@
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Label
|
<Label
|
||||||
row="0"
|
row="1"
|
||||||
col="2"
|
|
||||||
class="bx"
|
|
||||||
:text="icon.share"
|
|
||||||
@tap="shareRecipe"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
row="0"
|
|
||||||
col="3"
|
col="3"
|
||||||
class="bx"
|
class="bx"
|
||||||
:class="{ 'view-favorited': recipe.isFavorite }"
|
|
||||||
:text="recipe.isFavorite ? icon.heart : icon.heartOutline"
|
:text="recipe.isFavorite ? icon.heart : icon.heartOutline"
|
||||||
@tap="toggleFavorite"
|
@tap="toggleFavorite"
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
row="0"
|
v-if="!filterTrylater"
|
||||||
|
row="1"
|
||||||
col="4"
|
col="4"
|
||||||
class="bx"
|
class="bx"
|
||||||
:class="{ 'view-favorited': !recipe.tried }"
|
:text="recipe.tried ? icon.trylaterOutline : icon.trylater"
|
||||||
:text="recipe.tried ? icon.musttryOutline : icon.musttry"
|
@tap="toggleTrylater"
|
||||||
@tap="toggleMustTry"
|
|
||||||
/>
|
/>
|
||||||
|
<Label
|
||||||
|
v-if="!busy"
|
||||||
|
row="1"
|
||||||
|
col="2"
|
||||||
|
class="bx"
|
||||||
|
:text="icon.edit"
|
||||||
|
@tap="editRecipe"
|
||||||
|
/>
|
||||||
|
<ActivityIndicator v-else row="1" col="4" :busy="busy" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<AbsoluteLayout>
|
<AbsoluteLayout>
|
||||||
|
@ -93,10 +94,6 @@
|
||||||
class="view-other"
|
class="view-other"
|
||||||
:text="`Cooking time: ${getTime(recipe.cookTime)}`"
|
:text="`Cooking time: ${getTime(recipe.cookTime)}`"
|
||||||
/>
|
/>
|
||||||
<Label
|
|
||||||
class="view-other"
|
|
||||||
:text="`Portion size: ${recipe.portionSize}`"
|
|
||||||
/>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -112,7 +109,7 @@
|
||||||
<StackLayout v-else padding="16 16 124">
|
<StackLayout v-else padding="16 16 124">
|
||||||
<AbsoluteLayout class="inputField">
|
<AbsoluteLayout class="inputField">
|
||||||
<TextField
|
<TextField
|
||||||
width="50%"
|
width="165"
|
||||||
v-model="portionScale"
|
v-model="portionScale"
|
||||||
keyboardType="number"
|
keyboardType="number"
|
||||||
/>
|
/>
|
||||||
|
@ -207,7 +204,7 @@
|
||||||
<Label
|
<Label
|
||||||
verticalAlignment="top"
|
verticalAlignment="top"
|
||||||
horizontalAlignment="center"
|
horizontalAlignment="center"
|
||||||
class="view-count orkb"
|
class="view-count note orkb"
|
||||||
col="0"
|
col="0"
|
||||||
:text="index + 1"
|
:text="index + 1"
|
||||||
/>
|
/>
|
||||||
|
@ -223,52 +220,74 @@
|
||||||
text="Click the edit button to add references to this recipe"
|
text="Click the edit button to add references to this recipe"
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
<StackLayout v-else padding="32 16 132">
|
<StackLayout v-else padding="10 0 132">
|
||||||
<GridLayout
|
<StackLayout
|
||||||
columns="auto ,*"
|
|
||||||
v-for="(reference, index) in recipe.references"
|
v-for="(reference, index) in recipe.references"
|
||||||
:key="index"
|
:key="index"
|
||||||
@tap="openURL($event, reference)"
|
|
||||||
>
|
>
|
||||||
|
<GridLayout
|
||||||
|
v-if="isValidURL(reference)"
|
||||||
|
columns="*, auto"
|
||||||
|
class="view-reference-container"
|
||||||
|
androidElevation="1"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
col="0"
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="view-reference"
|
||||||
|
:text="reference"
|
||||||
|
textWrap="false"
|
||||||
|
@tap="openURL($event, reference)"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
col="1"
|
||||||
|
class="view-copyReference bx"
|
||||||
|
:text="icon.copy"
|
||||||
|
@tap="copyURL($event, reference)"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
<Label
|
<Label
|
||||||
col="0"
|
v-else
|
||||||
colSpan="2"
|
class="view-reference-text"
|
||||||
class="view-reference"
|
|
||||||
:text="reference"
|
:text="reference"
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
<Label
|
</StackLayout>
|
||||||
verticalAlignment="top"
|
|
||||||
horizontalAlignment="center"
|
|
||||||
class="orkb view-count"
|
|
||||||
col="0"
|
|
||||||
:text="index + 1"
|
|
||||||
/>
|
|
||||||
</GridLayout>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</TabViewItem>
|
</TabViewItem>
|
||||||
</TabView>
|
</TabView>
|
||||||
<GridLayout id="btnFabContainer" rows="*,88" columns="*,88">
|
<GridLayout id="btnFabContainer" rows="*,auto" columns="*,auto">
|
||||||
<Label
|
<Label
|
||||||
v-if="!busy"
|
|
||||||
@tap="editRecipe"
|
|
||||||
row="1"
|
row="1"
|
||||||
col="1"
|
col="1"
|
||||||
class="bx fab-button"
|
class="bx fab-button"
|
||||||
:text="icon.edit"
|
:text="icon.unchecked"
|
||||||
androidElevation="8"
|
@tap="recipeTried"
|
||||||
|
v-if="filterTrylater"
|
||||||
/>
|
/>
|
||||||
<ActivityIndicator v-else row="1" col="1" :busy="busy" />
|
<transition name="dolly" appear>
|
||||||
|
<Label
|
||||||
|
row="1"
|
||||||
|
col="1"
|
||||||
|
class="bx fab-button"
|
||||||
|
:text="icon.share"
|
||||||
|
@tap="shareRecipe"
|
||||||
|
v-if="!filterTrylater && showFab"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</AbsoluteLayout>
|
</AbsoluteLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Screen, Utils, ImageSource, Device } from "@nativescript/core"
|
import { Screen, Utils, ImageSource, Device, File } from "@nativescript/core"
|
||||||
|
import { Feedback, FeedbackType, FeedbackPosition } from "nativescript-feedback"
|
||||||
|
import * as application from "tns-core-modules/application"
|
||||||
import * as Toast from "nativescript-toast"
|
import * as Toast from "nativescript-toast"
|
||||||
import * as SocialShare from "nativescript-social-share"
|
import * as SocialShare from "nativescript-social-share-ns-7"
|
||||||
|
import { setText } from "nativescript-clipboard"
|
||||||
|
|
||||||
import { mapState, mapActions } from "vuex"
|
import { mapState, mapActions } from "vuex"
|
||||||
|
|
||||||
|
@ -276,6 +295,7 @@ import EditRecipe from "./EditRecipe.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
|
"filterTrylater",
|
||||||
"recipeIndex",
|
"recipeIndex",
|
||||||
"recipeID",
|
"recipeID",
|
||||||
"hijackGlobalBackEvent",
|
"hijackGlobalBackEvent",
|
||||||
|
@ -286,6 +306,7 @@ export default {
|
||||||
busy: false,
|
busy: false,
|
||||||
portionScale: 1,
|
portionScale: 1,
|
||||||
recipe: null,
|
recipe: null,
|
||||||
|
showFab: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -308,6 +329,47 @@ export default {
|
||||||
this.setCurrentComponentAction("ViewRecipe")
|
this.setCurrentComponentAction("ViewRecipe")
|
||||||
}, 500)
|
}, 500)
|
||||||
this.portionScale = this.recipe.portionSize
|
this.portionScale = this.recipe.portionSize
|
||||||
|
this.showFab = true
|
||||||
|
this.showInfo()
|
||||||
|
},
|
||||||
|
niceDates(time) {
|
||||||
|
let date = new Date(time)
|
||||||
|
let diff = (new Date().getTime() - date.getTime()) / 1000
|
||||||
|
console.log(diff)
|
||||||
|
let dayDiff = Math.ceil(diff / 86400)
|
||||||
|
console.log(dayDiff)
|
||||||
|
|
||||||
|
if (isNaN(dayDiff) || dayDiff < 0) return ""
|
||||||
|
|
||||||
|
return (
|
||||||
|
(dayDiff == 0 &&
|
||||||
|
((diff < 60 && "just now") ||
|
||||||
|
(diff < 120 && "1 minute ago") ||
|
||||||
|
(diff < 3600 && Math.floor(diff / 60) + " minutes ago") ||
|
||||||
|
(diff < 7200 && "1 hour ago") ||
|
||||||
|
(diff < 86400 && Math.floor(diff / 3600) + " hours ago"))) ||
|
||||||
|
(dayDiff == 1 && "yesterday") ||
|
||||||
|
(dayDiff < 7 && dayDiff + " days ago") ||
|
||||||
|
(dayDiff < 31 && Math.ceil(dayDiff / 7) + " week(s) ago") ||
|
||||||
|
(dayDiff > 30 &&
|
||||||
|
dayDiff < 365 &&
|
||||||
|
Math.round(dayDiff / 30) + " month(s) ago") ||
|
||||||
|
(dayDiff > 364 && Math.round(dayDiff / 365) + " year(s) ago")
|
||||||
|
)
|
||||||
|
},
|
||||||
|
showInfo() {
|
||||||
|
let feedback = new Feedback()
|
||||||
|
feedback.show({
|
||||||
|
type: FeedbackType.Info,
|
||||||
|
message: `You tried this recipe ${this.niceDates(
|
||||||
|
this.recipe.triedOn
|
||||||
|
)}!`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
highlight(args) {
|
||||||
|
let temp = args.object.className
|
||||||
|
args.object.className = `${temp} option-highlight`
|
||||||
|
setTimeout(() => (args.object.className = temp), 100)
|
||||||
},
|
},
|
||||||
roundedQuantity(quantity) {
|
roundedQuantity(quantity) {
|
||||||
return (
|
return (
|
||||||
|
@ -319,13 +381,14 @@ export default {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
editRecipe() {
|
editRecipe() {
|
||||||
|
this.showFab = false
|
||||||
this.busy = true
|
this.busy = true
|
||||||
this.$navigateTo(EditRecipe, {
|
this.$navigateTo(EditRecipe, {
|
||||||
transition: {
|
// transition: {
|
||||||
name: "slide",
|
// name: "slide",
|
||||||
duration: 250,
|
// duration: 250,
|
||||||
curve: "easeIn",
|
// curve: "easeOut",
|
||||||
},
|
// },
|
||||||
props: {
|
props: {
|
||||||
recipeIndex: this.recipeIndex,
|
recipeIndex: this.recipeIndex,
|
||||||
recipeID: this.recipeID,
|
recipeID: this.recipeID,
|
||||||
|
@ -333,6 +396,55 @@ export default {
|
||||||
// backstackVisible: false,
|
// backstackVisible: false,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
shareRecipe() {
|
||||||
|
let overview = `${
|
||||||
|
this.recipe.title
|
||||||
|
} Recipe\n\nPreparation time: ${this.getTime(
|
||||||
|
this.recipe.prepTime
|
||||||
|
)}\nCooking time: ${this.getTime(this.recipe.cookTime)}\n`
|
||||||
|
let shareContent = overview
|
||||||
|
if (this.recipe.ingredients.length) {
|
||||||
|
let ingredients = `\n\nIngredients for ${this.recipe.portionSize} ${
|
||||||
|
this.recipe.portionSize === 1 ? "postion:" : "portions:"
|
||||||
|
}\n\n`
|
||||||
|
this.recipe.ingredients.forEach((e) => {
|
||||||
|
ingredients += `- ${this.roundedQuantity(e.quantity)} ${e.unit} ${
|
||||||
|
e.item
|
||||||
|
}\n`
|
||||||
|
})
|
||||||
|
shareContent += ingredients
|
||||||
|
}
|
||||||
|
if (this.recipe.instructions.length) {
|
||||||
|
let instructions = `\n\nInstructions:\n\n`
|
||||||
|
this.recipe.instructions.forEach((e, i) => {
|
||||||
|
instructions += `${i + 1}. ${e}\n\n`
|
||||||
|
})
|
||||||
|
shareContent += instructions
|
||||||
|
}
|
||||||
|
if (this.recipe.notes.length) {
|
||||||
|
let notes = `\nNotes:\n\n`
|
||||||
|
this.recipe.notes.forEach((e, i) => {
|
||||||
|
notes += `${i + 1}. ${e}\n\n`
|
||||||
|
})
|
||||||
|
shareContent += notes
|
||||||
|
}
|
||||||
|
if (this.recipe.references.length) {
|
||||||
|
let references = `\nReferences:\n\n`
|
||||||
|
this.recipe.references.forEach((e, i) => {
|
||||||
|
references += `${e}\n\n`
|
||||||
|
})
|
||||||
|
shareContent += references
|
||||||
|
}
|
||||||
|
let sharenote =
|
||||||
|
"\nCreated and shared via EnRecipes.\n\nDownload the app on f-droid:\nhttps://www.vishnuraghav.com/"
|
||||||
|
|
||||||
|
shareContent += sharenote
|
||||||
|
|
||||||
|
SocialShare.shareText(
|
||||||
|
shareContent,
|
||||||
|
"How would you like to share this recipe?"
|
||||||
|
)
|
||||||
|
},
|
||||||
toggle(key) {
|
toggle(key) {
|
||||||
this.toggleStateAction({
|
this.toggleStateAction({
|
||||||
index: this.recipeIndex,
|
index: this.recipeIndex,
|
||||||
|
@ -341,39 +453,52 @@ export default {
|
||||||
key,
|
key,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
shareRecipe() {
|
|
||||||
// if (this.recipe.imageSrc) {
|
|
||||||
// let image = ImageSource.fromFile(this.recipe.imageSrc)
|
|
||||||
// SocialShare.shareImage(image)
|
|
||||||
// } else {
|
|
||||||
// SocialShare.shareText("Text only")
|
|
||||||
// }
|
|
||||||
alert(Device.sdkVersion)
|
|
||||||
},
|
|
||||||
toggleFavorite() {
|
toggleFavorite() {
|
||||||
this.recipe.isFavorite
|
this.recipe.isFavorite
|
||||||
? Toast.makeText("Removed from Favorites").show()
|
? Toast.makeText("Removed from Favorites").show()
|
||||||
: Toast.makeText("Added to Favorites").show()
|
: Toast.makeText("Added to Favorites").show()
|
||||||
this.toggle("isFavorite")
|
this.toggle("isFavorite")
|
||||||
},
|
},
|
||||||
toggleMustTry() {
|
toggleTrylater() {
|
||||||
this.recipe.tried
|
this.recipe.tried
|
||||||
? Toast.makeText("Added to Must-Try").show()
|
? this.filterTrylater
|
||||||
: Toast.makeText("Removed from Must-Try").show()
|
? Toast.makeText("Added back to Try later").show()
|
||||||
|
: Toast.makeText("Added to Try later").show()
|
||||||
|
: this.filterTrylater
|
||||||
|
? Toast.makeText("You tried this recipe").show()
|
||||||
|
: Toast.makeText("Removed from Try later").show()
|
||||||
|
// : Toast.makeText("You tried this recipe").show()
|
||||||
this.toggle("tried")
|
this.toggle("tried")
|
||||||
},
|
},
|
||||||
|
recipeTried() {
|
||||||
|
this.toggle("tried")
|
||||||
|
this.$navigateBack()
|
||||||
|
},
|
||||||
getTime(time) {
|
getTime(time) {
|
||||||
let t = time.split(":")
|
let t = time.split(":")
|
||||||
let h = t[0]
|
let h = t[0]
|
||||||
let m = t[1]
|
let m = t[1]
|
||||||
return h !== "00" ? `${h}h ${m}m` : `${m}m`
|
return h !== "00" ? `${h}h ${m}m` : `${m}m`
|
||||||
},
|
},
|
||||||
|
isValidURL(string) {
|
||||||
|
let pattern = new RegExp("^https?|www", "ig")
|
||||||
|
return pattern.test(string)
|
||||||
|
},
|
||||||
openURL(args, url) {
|
openURL(args, url) {
|
||||||
|
// this.highlight(args)
|
||||||
Utils.openUrl(url)
|
Utils.openUrl(url)
|
||||||
},
|
},
|
||||||
|
copyURL(args, url) {
|
||||||
|
setText(url).then((e) => {
|
||||||
|
Toast.makeText("URL Copied").show()
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
this.recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.showFab = true
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<Page>
|
<Page>
|
||||||
<StackLayout class="dialogContainer" :class="isLightMode">
|
<StackLayout class="dialogContainer" :class="isLightMode">
|
||||||
<Label class="dialogTitle orkm" :text="title" />
|
<Label class="dialogTitle orkm" :text="title" />
|
||||||
<Label class="dialogDescription" :text="description" textWrap="true" />
|
<Label v-if="description" class="dialogDescription" :text="description" textWrap="true" />
|
||||||
<StackLayout
|
<StackLayout
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="actionsContainer"
|
class="actionsContainer"
|
||||||
|
|
|
@ -14,9 +14,9 @@ Vue.registerElement(
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vue.registerElement(
|
// Vue.registerElement(
|
||||||
// "Fab",
|
// 'Fab',
|
||||||
// () => require("@nstudio/nativescript-floatingactionbutton").Fab
|
// () => require('@nstudio/nativescript-floatingactionbutton').Fab
|
||||||
// )
|
// );
|
||||||
|
|
||||||
if (TNS_ENV !== "production") {
|
if (TNS_ENV !== "production") {
|
||||||
// Vue.use(VueDevtools)
|
// Vue.use(VueDevtools)
|
||||||
|
|
67
app/store.js
67
app/store.js
|
@ -8,7 +8,59 @@ Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
recipes: [],
|
recipes: [
|
||||||
|
{
|
||||||
|
imageSrc: null,
|
||||||
|
title: "Mushroom & Spinach Risotto",
|
||||||
|
category: "Lunch",
|
||||||
|
prepTime: "00:25",
|
||||||
|
cookTime: "00:45",
|
||||||
|
portionSize: "8",
|
||||||
|
ingredients: [
|
||||||
|
{
|
||||||
|
item: "reduced-sodium chicken broth",
|
||||||
|
unit: "cup",
|
||||||
|
quantity: "5.25",
|
||||||
|
},
|
||||||
|
{ item: "sliced fresh mushrooms", unit: "cup", quantity: "2.5" },
|
||||||
|
{ item: "medium onion, finely chopped", unit: "unit", quantity: "1" },
|
||||||
|
{ item: "butter", unit: "Tbsp", quantity: "3" },
|
||||||
|
{ item: "Garlic", unit: "unit", quantity: "3" },
|
||||||
|
{
|
||||||
|
item: "white wine or reduced-sodium chicken broth",
|
||||||
|
unit: "cup",
|
||||||
|
quantity: ".75",
|
||||||
|
},
|
||||||
|
{ item: "heavy whipping cream", unit: "cup", quantity: "1" },
|
||||||
|
{ item: "uncooked arborio rice", unit: "cup", quantity: "1.75" },
|
||||||
|
{ item: "olive oil", unit: "Tbsp", quantity: "2" },
|
||||||
|
{
|
||||||
|
item: "frozen chopped spinach, thawed and squeezed dry",
|
||||||
|
unit: "cup",
|
||||||
|
quantity: "1.5",
|
||||||
|
},
|
||||||
|
{ item: "pepper", unit: "tsp", quantity: ".5" },
|
||||||
|
{ item: "Salt", unit: "tsp", quantity: ".25" },
|
||||||
|
{ item: "grated Parmesan cheese", unit: "cup", quantity: "1" },
|
||||||
|
],
|
||||||
|
instructions: [
|
||||||
|
"In a large saucepan, heat broth and keep warm. In a large skillet, saute mushrooms and onion in butter until tender. Add garlic; cook 1 minute longer. Stir in wine. Bring to a boil; cook until liquid is reduced by half. Add cream; cook and stir over medium heat until slightly thickened",
|
||||||
|
"In a large saucepan, saute rice in oil for 2-3 minutes or until rice is lightly browned. Stir in 1/2 cup hot broth. Reduce heat; cook and stir for 20 minutes or until broth is absorbed.",
|
||||||
|
"Continue adding hot broth, 1/2 cup at a time, and stirring until all the broth has been absorbed and rice is tender but firm. Add the mushroom mixture, spinach, pepper, salt and grated Parmesan cheese; cook and stir until heated through. If desired, sprinkle with parsley and shaved Parmesan cheese. Serve immediately.",
|
||||||
|
],
|
||||||
|
notes: [
|
||||||
|
"Nutrition Facts\n3/4 cup: 409 calories, 22g fat (12g saturated fat), 61mg cholesterol, 667mg sodium, 41g carbohydrate (3g sugars, 2g fiber), 11g protein.",
|
||||||
|
],
|
||||||
|
references: [
|
||||||
|
"https://www.tasteofhome.com/recipes/mushroom-spinach-risotto/",
|
||||||
|
],
|
||||||
|
isFavorite: false,
|
||||||
|
tried: true,
|
||||||
|
triedOn: "2020-10-28T18:19:06.528Z",
|
||||||
|
lastModified: "2020-10-28T06:19:06.528Z",
|
||||||
|
id: "57qm8oqxdr",
|
||||||
|
},
|
||||||
|
],
|
||||||
categories: [],
|
categories: [],
|
||||||
units: [
|
units: [
|
||||||
"unit",
|
"unit",
|
||||||
|
@ -45,10 +97,11 @@ export default new Vuex.Store({
|
||||||
plus: "\ueb89",
|
plus: "\ueb89",
|
||||||
close: "\uec4e",
|
close: "\uec4e",
|
||||||
image: "\ueae9",
|
image: "\ueae9",
|
||||||
|
addImage: "\ueae8",
|
||||||
back: "\ue988",
|
back: "\ue988",
|
||||||
save: "\uee48",
|
save: "\uee48",
|
||||||
camera: "\uecc2",
|
camera: "\uecc2",
|
||||||
share: "\uee51",
|
share: "\uee50",
|
||||||
edit: "\uee17",
|
edit: "\uee17",
|
||||||
theme: "\ued09",
|
theme: "\ued09",
|
||||||
folder: "\ued7c",
|
folder: "\ued7c",
|
||||||
|
@ -59,8 +112,14 @@ export default new Vuex.Store({
|
||||||
user: "\uee8e",
|
user: "\uee8e",
|
||||||
trash: "\uee83",
|
trash: "\uee83",
|
||||||
donate: "\ued41",
|
donate: "\ued41",
|
||||||
musttry: "\uec96",
|
trylater: "\uec96",
|
||||||
musttryOutline: "\ue9bb",
|
trylaterOutline: "\ue9bb",
|
||||||
|
note: "\uee0a",
|
||||||
|
copy: "\uea51",
|
||||||
|
plusCircle: "\ueb8a",
|
||||||
|
unchecked: "\uea16",
|
||||||
|
checked: "\uece6",
|
||||||
|
telegram: "\ue95e",
|
||||||
},
|
},
|
||||||
currentComponent: "EnRecipes",
|
currentComponent: "EnRecipes",
|
||||||
},
|
},
|
||||||
|
|
54
package-lock.json
generated
54
package-lock.json
generated
|
@ -1095,20 +1095,17 @@
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@nativescript-community/perms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nativescript-community/perms/-/perms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-Ay4v1lEGTQ5rYYlYA8CKcCXuxOuyU4633r/JXi9aRG8MgxfOT+rDuQLgSz+LLCYmBK1ndfHHfyUTilkaUj1H8Q=="
|
||||||
|
},
|
||||||
"@nativescript/android": {
|
"@nativescript/android": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-7.0.1.tgz",
|
||||||
"integrity": "sha512-VsZCJ5zfZo0+/lFwKz+S7iFb7MA2jgACB7y8dNje3/cnZl+moKPNjFqitoEP0DY4gLz9LJNbFIIaUt84tMdUSQ==",
|
"integrity": "sha512-VsZCJ5zfZo0+/lFwKz+S7iFb7MA2jgACB7y8dNje3/cnZl+moKPNjFqitoEP0DY4gLz9LJNbFIIaUt84tMdUSQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@nativescript/camera": {
|
|
||||||
"version": "5.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nativescript/camera/-/camera-5.0.2.tgz",
|
|
||||||
"integrity": "sha512-frNeCLhdQ+W6oXIv05pALdmZDcwilw/NopLtQILtUwuLS7xhE+UMx6CqQxxCxMYzWKsvET2k9VLAo3mJGAoSeg==",
|
|
||||||
"requires": {
|
|
||||||
"nativescript-permissions": "~1.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@nativescript/core": {
|
"@nativescript/core": {
|
||||||
"version": "7.0.12",
|
"version": "7.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-7.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-7.0.12.tgz",
|
||||||
|
@ -5096,17 +5093,28 @@
|
||||||
"to-regex": "^3.0.1"
|
"to-regex": "^3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nativescript-clipboard": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nativescript-clipboard/-/nativescript-clipboard-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-w7qRJiWiBeq55f3IW+pAkbrl+v+yqZf3bhcl1wH6Qm1JqZLWDv7HemzHTM5CvaqQ4gfz5dnGhJW1q1fsr5KSOw=="
|
||||||
|
},
|
||||||
"nativescript-couchbase-plugin": {
|
"nativescript-couchbase-plugin": {
|
||||||
"version": "0.9.6",
|
"version": "0.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/nativescript-couchbase-plugin/-/nativescript-couchbase-plugin-0.9.6.tgz",
|
"resolved": "https://registry.npmjs.org/nativescript-couchbase-plugin/-/nativescript-couchbase-plugin-0.9.6.tgz",
|
||||||
"integrity": "sha512-kMA9KHQX82TFaGnGUhY94KLOLss4pb5QmghgoEdu1sLwd94I/f1MQ+kHWbuBOdFmdQJw5oCK+Sey+A22Nd5jgA=="
|
"integrity": "sha512-kMA9KHQX82TFaGnGUhY94KLOLss4pb5QmghgoEdu1sLwd94I/f1MQ+kHWbuBOdFmdQJw5oCK+Sey+A22Nd5jgA=="
|
||||||
},
|
},
|
||||||
"nativescript-imagepicker": {
|
"nativescript-feedback": {
|
||||||
"version": "7.1.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/nativescript-imagepicker/-/nativescript-imagepicker-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/nativescript-feedback/-/nativescript-feedback-2.0.0.tgz",
|
||||||
"integrity": "sha512-YFVwmPz7mv7mNXA7vmnIXmqPZiWxH4RoJPDL3m34egV8Ae9mKJCXZxl2LyPraOP+T4v6iXsxV9NSbjg0kMDuNQ==",
|
"integrity": "sha512-6ZE/g+s1xxez3pMRJa/r0f144VuyapgDjbo8D37nMC4F0WDQLKk8dC0405czhQxD2djVq3GEMfM/n0cuMbY53A=="
|
||||||
|
},
|
||||||
|
"nativescript-mediafilepicker": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nativescript-mediafilepicker/-/nativescript-mediafilepicker-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-rBrZQR+46dCypIyLrzIlzmHgpmTSMGFR5a6snq8uUhtIqLlc674/nwWlNM1kFOxMh1kKxA+qyk74Of+NCKYoqQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"nativescript-permissions": "~1.3.0"
|
"@nativescript-community/perms": "^2.1.1",
|
||||||
|
"ts-node": "^9.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nativescript-permissions": {
|
"nativescript-permissions": {
|
||||||
|
@ -5122,10 +5130,10 @@
|
||||||
"nativescript-permissions": "~1.3.0"
|
"nativescript-permissions": "~1.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nativescript-social-share": {
|
"nativescript-social-share-ns-7": {
|
||||||
"version": "1.6.0",
|
"version": "11.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/nativescript-social-share/-/nativescript-social-share-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/nativescript-social-share-ns-7/-/nativescript-social-share-ns-7-11.6.0.tgz",
|
||||||
"integrity": "sha512-PjSMseCWPGJbW0KPMgQBiTQke6I8cYxf0CGXtuJ0BnRhXrEjF3d+3kAnI8E3O8PeW/BFwNIqLYG4fkoQF4obyA=="
|
"integrity": "sha512-NI6U8iOz3CKKV6nuZYSYUwA5JYFt1uPZAaMAWxySbMVQaKdP7H3lt+Sa/4ENZTvOkaAparD3ZZUxf0PITsrstA=="
|
||||||
},
|
},
|
||||||
"nativescript-toast": {
|
"nativescript-toast": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
@ -7356,6 +7364,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
|
||||||
|
"requires": {
|
||||||
|
"arg": "^4.1.0",
|
||||||
|
"diff": "^4.0.1",
|
||||||
|
"make-error": "^1.1.1",
|
||||||
|
"source-map-support": "^0.5.17",
|
||||||
|
"yn": "3.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
"run": "ns run android"
|
"run": "ns run android"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nativescript/camera": "^5.0.2",
|
|
||||||
"@nativescript/core": "~7.0.0",
|
"@nativescript/core": "~7.0.0",
|
||||||
"@nativescript/datetimepicker": "^2.0.4",
|
"@nativescript/datetimepicker": "^2.0.4",
|
||||||
"@nativescript/theme": "^3.0.0",
|
"@nativescript/theme": "^3.0.0",
|
||||||
"@nativescript/webpack": "3.0.0",
|
"@nativescript/webpack": "3.0.0",
|
||||||
|
"nativescript-clipboard": "^2.0.0",
|
||||||
"nativescript-couchbase-plugin": "^0.9.6",
|
"nativescript-couchbase-plugin": "^0.9.6",
|
||||||
"nativescript-imagepicker": "^7.1.0",
|
"nativescript-feedback": "^2.0.0",
|
||||||
"nativescript-permissions": "^1.3.9",
|
"nativescript-mediafilepicker": "^4.0.1",
|
||||||
"nativescript-plugin-filepicker": "^1.0.0",
|
"nativescript-plugin-filepicker": "^1.0.0",
|
||||||
"nativescript-social-share": "^1.6.0",
|
"nativescript-social-share-ns-7": "^11.6.0",
|
||||||
"nativescript-toast": "^2.0.0",
|
"nativescript-toast": "^2.0.0",
|
||||||
"nativescript-ui-listview": "^9.0.4",
|
"nativescript-ui-listview": "^9.0.4",
|
||||||
"nativescript-ui-sidedrawer": "^9.0.3",
|
"nativescript-ui-sidedrawer": "^9.0.3",
|
||||||
|
|
Loading…
Reference in a new issue