something done
This commit is contained in:
parent
fe6d6d1d60
commit
eb9e2da756
15 changed files with 2891 additions and 790 deletions
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ns_accent">#3d5afe</color>
|
||||
<color name="ns_accent">#ff7043</color>
|
||||
</resources>
|
|
@ -1,7 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ns_primary">#F5F5F5</color>
|
||||
<color name="ns_primaryDark">#757575</color>
|
||||
<color name="ns_accent">#33B5E5</color>
|
||||
<color name="ns_blue">#272734</color>
|
||||
<color name="ns_primary">
|
||||
#FFFFFF
|
||||
</color>
|
||||
<color name="ns_primaryDark">
|
||||
#ff7043
|
||||
</color>
|
||||
<color name="ns_accent">
|
||||
#ff7043
|
||||
</color>
|
||||
<color name="ns_blue">
|
||||
#272734
|
||||
</color>
|
||||
</resources>
|
|
@ -25,6 +25,7 @@
|
|||
<item name="colorPrimary">@color/ns_primary</item>
|
||||
<item name="colorPrimaryDark">@color/ns_primaryDark</item>
|
||||
<item name="colorAccent">@color/ns_accent</item>
|
||||
<item name="android:forceDarkAllowed">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="AppThemeBase">
|
||||
|
|
360
app/app.scss
360
app/app.scss
|
@ -1,22 +1,370 @@
|
|||
// NativeScript core theme
|
||||
// @see https://docs.nativescript.org/ui/theme
|
||||
@import '~@nativescript/theme/core';
|
||||
@import "~@nativescript/theme/core";
|
||||
|
||||
// Override variables here
|
||||
|
||||
$grayD4: #212121;
|
||||
$grayD3: #424242;
|
||||
$grayD2: #616161;
|
||||
$grayD1: #757575;
|
||||
$gray: #9e9e9e;
|
||||
$grayL1: #e0e0e0;
|
||||
$grayL2: #eeeeee;
|
||||
$grayL3: #f5f5f5;
|
||||
$grayL4: #fafafa;
|
||||
|
||||
$orange: #ff7043;
|
||||
$paleOrange: #fbe9e7;
|
||||
|
||||
// Global SCSS styling
|
||||
// @see https://docs.nativescript.org/ui/styling
|
||||
|
||||
Page {
|
||||
font-family: 'Orkney-Regular';
|
||||
font-family: "Orkney-Regular";
|
||||
}
|
||||
.orkm {
|
||||
font-family: 'Orkney-Medium';
|
||||
font-family: "Orkney-Medium";
|
||||
}
|
||||
.orkb {
|
||||
font-family: 'Orkney-Bold';
|
||||
font-family: "Orkney-Bold";
|
||||
}
|
||||
.bx {
|
||||
font-family: 'boxicons';
|
||||
font-size: 24;
|
||||
font-family: "boxicons";
|
||||
font-size: 24;
|
||||
}
|
||||
|
||||
.ns-light {
|
||||
Page,
|
||||
ActionBar,
|
||||
SearchBar {
|
||||
background: $grayL4;
|
||||
color: $grayD4;
|
||||
}
|
||||
TabView {
|
||||
tab-background-color: $grayL4;
|
||||
tab-text-color: $gray;
|
||||
selected-tab-text-color: $grayD4;
|
||||
}
|
||||
.hr {
|
||||
border-color: $grayL2;
|
||||
}
|
||||
TextField,
|
||||
TextView,
|
||||
TimePickerField {
|
||||
border-color: $gray;
|
||||
}
|
||||
.sd,
|
||||
.fieldLabel {
|
||||
background: $grayL4;
|
||||
}
|
||||
.recipe-li,
|
||||
.option-highlight {
|
||||
background: white;
|
||||
}
|
||||
.sd-item,
|
||||
.sd-group-header,
|
||||
.recipe-time {
|
||||
color: $grayD2;
|
||||
}
|
||||
.selected-sd-item {
|
||||
background: $paleOrange;
|
||||
color: $orange;
|
||||
}
|
||||
.option,
|
||||
.icon-option {
|
||||
.bx,
|
||||
.option-info {
|
||||
color: $grayD2;
|
||||
}
|
||||
.option-title {
|
||||
color: $grayD4;
|
||||
}
|
||||
}
|
||||
.view-imageHolder {
|
||||
background: $grayL2;
|
||||
color: $grayL1;
|
||||
}
|
||||
.view-other {
|
||||
color: $grayD2;
|
||||
}
|
||||
.view-count {
|
||||
color: $grayL4;
|
||||
background: $grayD4;
|
||||
}
|
||||
.view-instruction {
|
||||
border-color: $grayD4;
|
||||
}
|
||||
.instructionWOBorder {
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
.ns-dark {
|
||||
Page,
|
||||
ActionBar,
|
||||
SearchBar {
|
||||
background: $grayD4;
|
||||
color: $grayL4;
|
||||
}
|
||||
TabView {
|
||||
tab-background-color: $grayD4;
|
||||
tab-text-color: $gray;
|
||||
selected-tab-text-color: $grayL4;
|
||||
}
|
||||
.hr {
|
||||
border-color: #111;
|
||||
}
|
||||
TextField,
|
||||
TextView,
|
||||
TimePickerField {
|
||||
border-color: $gray;
|
||||
}
|
||||
.sd,
|
||||
.fieldLabel {
|
||||
background: $grayD4;
|
||||
}
|
||||
.recipe-li,
|
||||
.option-highlight {
|
||||
background: $grayD3;
|
||||
}
|
||||
.sd-item,
|
||||
.sd-group-header,
|
||||
.recipe-time {
|
||||
color: $grayL2;
|
||||
}
|
||||
.selected-sd-item {
|
||||
background: $paleOrange;
|
||||
color: $orange;
|
||||
}
|
||||
.option,
|
||||
.icon-option {
|
||||
.bx,
|
||||
.option-info {
|
||||
color: $grayL2;
|
||||
}
|
||||
.option-title {
|
||||
color: $grayL4;
|
||||
}
|
||||
}
|
||||
.view-imageHolder {
|
||||
background: black;
|
||||
color: $grayD4;
|
||||
}
|
||||
.view-other {
|
||||
color: $grayL2;
|
||||
}
|
||||
.view-count {
|
||||
color: $grayD4;
|
||||
background: $grayL4;
|
||||
}
|
||||
.view-instruction {
|
||||
border-color: $grayL4;
|
||||
}
|
||||
.instructionWOBorder {
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// Elements
|
||||
TextField,
|
||||
TextView,
|
||||
TimePickerField {
|
||||
border-width: 1;
|
||||
font-size: 15;
|
||||
padding: 16;
|
||||
margin: 8 0 0 0;
|
||||
border-radius: 4;
|
||||
placeholder-color: $gray;
|
||||
}
|
||||
TextView {
|
||||
line-height: 12;
|
||||
}
|
||||
.inputField {
|
||||
margin-top: 16;
|
||||
}
|
||||
.fieldLabel {
|
||||
font-size: 13;
|
||||
margin-left: 8;
|
||||
padding: 0 8;
|
||||
}
|
||||
|
||||
// ActionBar
|
||||
ActionBar {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 64;
|
||||
.bx {
|
||||
padding: 16;
|
||||
}
|
||||
.leftAction {
|
||||
padding: 16 16 16 4;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.actionBarContainer {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
SearchBar {
|
||||
font-size: 16;
|
||||
margin-top: 4;
|
||||
}
|
||||
.title {
|
||||
padding-left: 8;
|
||||
text-align: left;
|
||||
font-size: 18;
|
||||
}
|
||||
|
||||
// Side Drawer
|
||||
.sd-item {
|
||||
border-radius: 4;
|
||||
padding: 12 16;
|
||||
font-size: 14;
|
||||
}
|
||||
.sd-group-header {
|
||||
padding: 12;
|
||||
font-size: 12;
|
||||
}
|
||||
|
||||
// Home
|
||||
.recipe-li {
|
||||
margin: 8 16;
|
||||
border-radius: 6;
|
||||
.recipe-info {
|
||||
margin: 4 0;
|
||||
}
|
||||
.recipe-cat {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.recipe-title {
|
||||
font-size: 16;
|
||||
line-height: 4;
|
||||
margin: 0;
|
||||
padding: 4 0;
|
||||
}
|
||||
.recipe-time {
|
||||
padding: 0;
|
||||
}
|
||||
.recipe-favorite {
|
||||
font-size: 14;
|
||||
padding: 14 12 0 0;
|
||||
}
|
||||
.recipe-cat,
|
||||
.recipe-favorite {
|
||||
color: $orange;
|
||||
}
|
||||
.recipe-favorite.hide {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Settings
|
||||
.group-header {
|
||||
padding: 12;
|
||||
color: #ff7043;
|
||||
}
|
||||
.main-container {
|
||||
padding: 16 8 128;
|
||||
.option {
|
||||
padding: 16;
|
||||
border-radius: 4;
|
||||
font-size: 16;
|
||||
.bx {
|
||||
margin: 0 24 0 0;
|
||||
}
|
||||
|
||||
.option-info {
|
||||
font-size: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// About
|
||||
.app-icon-container {
|
||||
margin: 32 0;
|
||||
width: 100%;
|
||||
.app-icon {
|
||||
width: 56;
|
||||
height: 56;
|
||||
margin: 0 6 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.app-name {
|
||||
font-size: 24;
|
||||
}
|
||||
}
|
||||
.icon-option {
|
||||
padding: 16;
|
||||
border-radius: 4;
|
||||
.bx {
|
||||
margin: 0 24 0 0;
|
||||
}
|
||||
.option-title {
|
||||
font-size: 16;
|
||||
}
|
||||
}
|
||||
|
||||
// View Recipe
|
||||
|
||||
.view-cat {
|
||||
font-size: 14;
|
||||
color: #ff7043;
|
||||
}
|
||||
.view-other {
|
||||
font-size: 14;
|
||||
}
|
||||
.view-title {
|
||||
font-size: 22;
|
||||
}
|
||||
.view-ingredient {
|
||||
font-size: 14;
|
||||
line-height: 6;
|
||||
margin-top: 12;
|
||||
}
|
||||
.view-favorited {
|
||||
color: #ff7043;
|
||||
}
|
||||
|
||||
.view-count {
|
||||
font-size: 10;
|
||||
width: 20;
|
||||
height: 20;
|
||||
padding: 3 0 0;
|
||||
margin-left: 6;
|
||||
text-align: center;
|
||||
border-radius: 100;
|
||||
}
|
||||
|
||||
.view-instruction,
|
||||
.view-note,
|
||||
.view-reference {
|
||||
font-size: 14;
|
||||
line-height: 6;
|
||||
padding: 0 0 12 24;
|
||||
margin: 0 0 0 15;
|
||||
border-width: 0 0 0 2;
|
||||
}
|
||||
|
||||
.view-note {
|
||||
border-width: 0;
|
||||
}
|
||||
.view-reference {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
// Edit Recipe
|
||||
.btnFab {
|
||||
margin: 16;
|
||||
}
|
||||
.sectionTitle {
|
||||
font-size: 20;
|
||||
}
|
||||
.sec-btn {
|
||||
font-size: 14;
|
||||
color: #ff7043;
|
||||
text-align: left;
|
||||
padding: 16;
|
||||
margin: 8 0 0 0;
|
||||
}
|
||||
|
|
BIN
app/assets/images/food.jpg
Normal file
BIN
app/assets/images/food.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 93 KiB |
|
@ -1,76 +1,91 @@
|
|||
<template>
|
||||
<StackLayout class="main-container">
|
||||
<StackLayout orientation="horizontal" class="app-icon-container">
|
||||
<Image src="res://icon" class="app-icon" stretch="fill" />
|
||||
<Label
|
||||
text="EnRecipes"
|
||||
verticalAlignment="center"
|
||||
class="app-name orkb"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="icon-option">
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.info" />
|
||||
<StackLayout>
|
||||
<Label text="Version" class="option-title" />
|
||||
<Label text="1.0.0" class="option-info" textWrap="true" />
|
||||
<Page>
|
||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||
<!-- Settings Actionbar -->
|
||||
<GridLayout rows="*" columns="auto, *" class="actionBarContainer">
|
||||
<Label
|
||||
class="bx leftAction"
|
||||
:text="icon.menu"
|
||||
automationText="Menu"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" :text="title" col="1" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout class="main-container">
|
||||
<StackLayout
|
||||
horizontalAlignment="center"
|
||||
orientation="horizontal"
|
||||
class="app-icon-container"
|
||||
>
|
||||
<Image src="res://icon" class="app-icon" stretch="fill" />
|
||||
<Label
|
||||
text="EnRecipes"
|
||||
verticalAlignment="center"
|
||||
class="app-name orkb"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="icon-option">
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.info" />
|
||||
<StackLayout>
|
||||
<Label text="Version" class="option-title" />
|
||||
<Label text="1.0.0" class="option-info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://github.com/vishnuraghavb/enrecipes')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="View project on GitHub" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="icon-option">
|
||||
<Label class="bx" :text="icon.file" />
|
||||
<Label text="Licenses" class="option-title" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label text="Author" class="group-header" />
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://www.vishnuraghav.com')"
|
||||
>
|
||||
<Label class="bx" :text="icon.user" />
|
||||
<Label text="Vishnu Raghav" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://github.com/vishnuraghavb')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="Follow on GitHub" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://mastodon.social/@vishnuraghavb')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="Follow on Mastodon" class="option-title" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://github.com/vishnuraghavb/enrecipes')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="View project on GitHub" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="icon-option">
|
||||
<Label class="bx" :text="icon.file" />
|
||||
<Label text="Licenses" class="option-title" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label text="Author" class="group-header" />
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://www.vishnuraghav.com')"
|
||||
>
|
||||
<Label class="bx" :text="icon.user" />
|
||||
<Label text="Vishnu Raghav" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://github.com/vishnuraghavb')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="Follow on GitHub" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="icon-option"
|
||||
@tap="openURL($event, 'https://mastodon.social/@vishnuraghavb')"
|
||||
>
|
||||
<Label class="bx" :text="icon.link" />
|
||||
<Label text="Follow on Mastodon" class="option-title" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as utils from "tns-core-modules/utils/utils"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
export default {
|
||||
props: ["highlight"],
|
||||
data() {
|
||||
return {
|
||||
icon: {
|
||||
info: "\ueda7",
|
||||
link: "\ueb09",
|
||||
file: "\ued60",
|
||||
user: "\uee8e",
|
||||
},
|
||||
}
|
||||
props: ["highlight", "viewIsScrolled", "showDrawer", "title"],
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
methods: {
|
||||
openURL(args, url) {
|
||||
|
@ -80,32 +95,3 @@ export default {
|
|||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.app-icon-container {
|
||||
.app-icon {
|
||||
width: 56;
|
||||
height: 56;
|
||||
margin: 0 6 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.app-name {
|
||||
font-size: 24;
|
||||
}
|
||||
}
|
||||
.icon-option {
|
||||
padding: 16;
|
||||
border-radius: 4;
|
||||
background: white;
|
||||
.bx {
|
||||
color: #546e7a;
|
||||
margin: 0 24 0 0;
|
||||
}
|
||||
.option-title {
|
||||
color: #333333;
|
||||
font-size: 16;
|
||||
}
|
||||
.option-info {
|
||||
color: #546e7a;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<RadSideDrawer
|
||||
ref="drawer"
|
||||
allowEdgeSwipe="true"
|
||||
drawerContentSize="300"
|
||||
drawerContentSize="270"
|
||||
showOverNavigation="true"
|
||||
gesturesEnabled="true"
|
||||
drawerTransition="RevealTransition"
|
||||
|
@ -12,55 +12,59 @@
|
|||
rows="auto, auto, *, auto, auto"
|
||||
columns="*"
|
||||
~drawerContent
|
||||
backgroundColor="#ffffff"
|
||||
padding="8"
|
||||
class="sd"
|
||||
>
|
||||
<StackLayout row="0">
|
||||
<StackLayout
|
||||
@tap="navigateTo('EnRecipes', true, false)"
|
||||
@tap="localNavigation('EnRecipes', 'EnRecipes', true, false)"
|
||||
orientation="horizontal"
|
||||
class="drawer-item orkm"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-drawer-item':
|
||||
currentComponent == 'EnRecipes' &&
|
||||
'selected-sd-item':
|
||||
currentComponent === 'EnRecipes' &&
|
||||
!filterFavorites &&
|
||||
!selectedCategory,
|
||||
}"
|
||||
>
|
||||
<Label class="bx" :text="icon.home" margin="0 24 0 0" />
|
||||
<Label text="Home" />
|
||||
<Label verticalAlignment="center" text="Home" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
@tap="navigateTo('Favorites', true, false)"
|
||||
@tap="localNavigation('Favorites', 'Favorites', true, false)"
|
||||
orientation="horizontal"
|
||||
class="drawer-item orkm"
|
||||
:class="{ 'selected-drawer-item': filterFavorites }"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-sd-item':
|
||||
currentComponent === 'EnRecipes' && filterFavorites,
|
||||
}"
|
||||
>
|
||||
<Label class="bx" :text="icon.heart" margin="0 24 0 0" />
|
||||
<Label text="Favorites" />
|
||||
<Label verticalAlignment="center" text="Favorites" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
row="1"
|
||||
class="drawer-group-header orkr"
|
||||
class="sd-group-header orkr"
|
||||
>
|
||||
<Label text="Categories" />
|
||||
</StackLayout>
|
||||
<ScrollView row="2">
|
||||
<ScrollView row="2" scrollBarIndicatorVisible="false">
|
||||
<StackLayout>
|
||||
<StackLayout
|
||||
@tap="navigateTo(item, false, true)"
|
||||
@tap="localNavigation(item, item, false, true)"
|
||||
v-for="(item, index) in categories"
|
||||
:key="index"
|
||||
orientation="horizontal"
|
||||
class="drawer-item orkm"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-drawer-item': selectedCategory == item,
|
||||
'selected-sd-item':
|
||||
currentComponent === 'EnRecipes' && selectedCategory == item,
|
||||
}"
|
||||
>
|
||||
<Label class="bx" :text="icon.label" margin="0 24 0 0" />
|
||||
<Label :text="item" />
|
||||
<Label verticalAlignment="center" :text="item" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
@ -68,102 +72,30 @@
|
|||
<StackLayout row="3" class="hr m-10"></StackLayout>
|
||||
<StackLayout row="4">
|
||||
<StackLayout
|
||||
@tap="navigateTo(item.title, false, false)"
|
||||
@tap="navigateTo(item.component, item.title)"
|
||||
v-for="(item, index) in bottommenu"
|
||||
:key="index"
|
||||
orientation="horizontal"
|
||||
class="drawer-item orkm"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-drawer-item': currentComponent == item.title,
|
||||
'selected-sd-item': currentComponent == item.title,
|
||||
}"
|
||||
>
|
||||
<Label class="bx" :text="item.icon" margin="0 24 0 0" />
|
||||
<Label :text="item.title" />
|
||||
<Label class="bx" :text="icon[item.icon]" margin="0 24 0 0" />
|
||||
<Label verticalAlignment="center" :text="item.title" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
|
||||
<GridLayout ~mainContent rows="*" columns="*">
|
||||
<Frame ref="page">
|
||||
<Page>
|
||||
<ActionBar margin="0" flat="true" row="0" col="0">
|
||||
<GridLayout v-if="showSearch" rows="auto" columns="auto, *">
|
||||
<Label
|
||||
color="#000000"
|
||||
class="bx"
|
||||
padding="16 16 16 8"
|
||||
margin="0"
|
||||
:text="icon.back"
|
||||
automationText="Back"
|
||||
col="0"
|
||||
@tap="closeSearch"
|
||||
/>
|
||||
<SearchBar
|
||||
@loaded="searchBarLoaded()"
|
||||
id="searchField"
|
||||
col="1"
|
||||
hint="Search"
|
||||
textFieldHintColor="#555555"
|
||||
v-model="searchQuery"
|
||||
/>
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
v-else
|
||||
rows="auto"
|
||||
columns="auto, *, auto, auto"
|
||||
margin="0"
|
||||
padding="0"
|
||||
>
|
||||
<Label
|
||||
color="#000000"
|
||||
class="bx"
|
||||
padding="16 16 16 8"
|
||||
margin="0"
|
||||
:text="icon.menu"
|
||||
automationText="Menu"
|
||||
@tap="$refs.drawer.nativeView.showDrawer()"
|
||||
col="0"
|
||||
/>
|
||||
<Label
|
||||
color="#000000"
|
||||
class="title orkm"
|
||||
:text="title"
|
||||
col="1"
|
||||
/>
|
||||
<Label
|
||||
v-if="currentComponent == 'EnRecipes'"
|
||||
color="#000000"
|
||||
class="bx"
|
||||
:text="icon.search"
|
||||
col="2"
|
||||
@tap="showSearch = true"
|
||||
/>
|
||||
<Label
|
||||
v-if="currentComponent == 'EnRecipes'"
|
||||
color="#000000"
|
||||
class="bx"
|
||||
:text="icon.sort"
|
||||
@tap="sortTapped"
|
||||
col="3"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<GridLayout rows="*" columns="*">
|
||||
<component
|
||||
row="0"
|
||||
col="0"
|
||||
v-for="(component, index) in componentsArray"
|
||||
v-show="component === currentComponent"
|
||||
:key="index"
|
||||
:is="component"
|
||||
:recipes="recipes"
|
||||
:selectedCategory="selectedCategory"
|
||||
:searchQuery="searchQuery"
|
||||
:filterFavorites="filterFavorites"
|
||||
:highlight="highlight"
|
||||
/>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
<Frame id="main-frame">
|
||||
<!-- Home -->
|
||||
<EnRecipes
|
||||
:selectedCategory="selectedCategory"
|
||||
:filterFavorites="filterFavorites"
|
||||
:title="title"
|
||||
:showDrawer="showDrawer"
|
||||
/>
|
||||
</Frame>
|
||||
</GridLayout>
|
||||
</RadSideDrawer>
|
||||
|
@ -174,14 +106,12 @@
|
|||
import * as utils from "tns-core-modules/utils/utils"
|
||||
import { isAndroid } from "tns-core-modules/platform"
|
||||
import * as application from "tns-core-modules/application"
|
||||
import { Label } from "tns-core-modules/ui/label"
|
||||
|
||||
import { Menu } from "nativescript-menu"
|
||||
import { Popup } from "nativescript-popup"
|
||||
import EnRecipes from "./EnRecipes.vue"
|
||||
import Settings from "./Settings.vue"
|
||||
import About from "./About.vue"
|
||||
|
||||
import EnRecipes from "./EnRecipes"
|
||||
import Settings from "./Settings"
|
||||
import About from "./About"
|
||||
import { mapState } from "vuex"
|
||||
|
||||
let page
|
||||
export default {
|
||||
|
@ -193,98 +123,27 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
title: "EnRecipes",
|
||||
currentComponent: "EnRecipes",
|
||||
componentsArray: ["EnRecipes", "Settings", "About"],
|
||||
selectedCategory: null,
|
||||
filterFavorites: false,
|
||||
searchQuery: "",
|
||||
showSearch: false,
|
||||
icon: {
|
||||
menu: "\ueb2a",
|
||||
home: "\ued99",
|
||||
heart: "\ued94",
|
||||
search: "\uebbc",
|
||||
sort: "\ueb2b",
|
||||
cog: "\ued05",
|
||||
info: "\ueda7",
|
||||
label: "\uedaf",
|
||||
plus: "\ueb89",
|
||||
close: "\uec4e",
|
||||
back: "\ue988",
|
||||
},
|
||||
topmenu: [
|
||||
{
|
||||
title: "EnRecipes",
|
||||
icon: "\ued99",
|
||||
},
|
||||
{
|
||||
title: "Favorites",
|
||||
icon: "\ued94",
|
||||
},
|
||||
],
|
||||
currentComponent: "EnRecipes",
|
||||
bottommenu: [
|
||||
{
|
||||
title: "Settings",
|
||||
icon: "\ued05",
|
||||
component: Settings,
|
||||
icon: "cog",
|
||||
},
|
||||
{
|
||||
title: "About",
|
||||
icon: "\ueda7",
|
||||
},
|
||||
],
|
||||
recipes: [
|
||||
{
|
||||
id: 1,
|
||||
img: "",
|
||||
category: "Salads",
|
||||
title: "Mediterranean Salad",
|
||||
time: "30m",
|
||||
isFavorite: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
img: "",
|
||||
category: "Sauces",
|
||||
title: "Fresh Tomato Sauce",
|
||||
time: "45m",
|
||||
isFavorite: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
img: "",
|
||||
category: "Lunch",
|
||||
title: "Creamy Mushroom Herb Pasta Creamy Mushroom Herb Pasta",
|
||||
time: "30m",
|
||||
isFavorite: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
img: "",
|
||||
category: "Lunch",
|
||||
title: "Grilled Cheese Sandwich",
|
||||
time: "20m",
|
||||
isFavorite: false,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
img: "",
|
||||
category: "Lunch",
|
||||
title: "Creamy Mushroom Herb Pasta Creamy Mushroom Herb Pasta",
|
||||
time: "30m",
|
||||
isFavorite: false,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
img: "",
|
||||
category: "Lunch",
|
||||
title: "Grilled Cheese Sandwich",
|
||||
time: "20m",
|
||||
isFavorite: false,
|
||||
component: About,
|
||||
icon: "info",
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["recipes", "icon"]),
|
||||
categories() {
|
||||
let arr = this.recipes.map((e) => {
|
||||
return e.category
|
||||
|
@ -294,188 +153,117 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
highlight(args) {
|
||||
console.log(args.object.className)
|
||||
let temp = args.object.className
|
||||
args.object.className = `${temp} option-highlight`
|
||||
setTimeout(() => {
|
||||
args.object.className = temp
|
||||
}, 100)
|
||||
},
|
||||
|
||||
// Navigation
|
||||
setSelectedCategory(e) {
|
||||
this.selectedCategory = e.item
|
||||
console.log(e)
|
||||
this.closeDrawer()
|
||||
},
|
||||
// SearchBar
|
||||
closeSearch() {
|
||||
this.searchQuery = ""
|
||||
this.showSearch = false
|
||||
utils.ad.dismissSoftInput()
|
||||
},
|
||||
searchBarLoaded() {
|
||||
application.android.on(
|
||||
application.AndroidApplication.activityBackPressedEvent,
|
||||
this.backEvent
|
||||
)
|
||||
},
|
||||
removeBackEvent() {
|
||||
application.android.off(
|
||||
application.AndroidApplication.activityBackPressedEvent,
|
||||
this.backEvent
|
||||
)
|
||||
},
|
||||
|
||||
// Sort
|
||||
sortTapped(args) {
|
||||
let anchor = args.object
|
||||
const popup = new Popup({
|
||||
backgroundColor: "white" | "#fff",
|
||||
height: 100,
|
||||
width: 100,
|
||||
unit: "dp" | "px" | "%",
|
||||
elevation: 10, // android only
|
||||
borderRadius: 25, // android only
|
||||
})
|
||||
const View = new Label()
|
||||
View.text = "Test"
|
||||
|
||||
popup.showPopup(anchor, View)
|
||||
},
|
||||
|
||||
// Navigation
|
||||
backEvent(args) {
|
||||
if (this.showSearch) {
|
||||
args.cancel = true
|
||||
this.closeSearch()
|
||||
this.removeBackEvent()
|
||||
} else if (
|
||||
this.currentComponent !== "EnRecipes" ||
|
||||
this.filterFavorites
|
||||
) {
|
||||
args.cancel = true
|
||||
console.log("backEvent")
|
||||
args.cancel = true
|
||||
if (this.$refs.drawer.nativeView.getIsOpen()) this.closeDrawer()
|
||||
else if (this.currentComponent !== "EnRecipes") {
|
||||
this.$navigateBack({ frame: "main-frame" })
|
||||
this.currentComponent = "EnRecipes"
|
||||
this.filterFavorites = false
|
||||
} else if (this.filterFavorites || this.selectedCategory) {
|
||||
this.title = "EnRecipes"
|
||||
this.filterFavorites = false
|
||||
this.selectedCategory = null
|
||||
this.removeBackEvent()
|
||||
}
|
||||
},
|
||||
navigateBackToHome() {
|
||||
localNavigation(to, title, filter, filterCategory) {
|
||||
// navigateBackToHome
|
||||
application.android.on(
|
||||
application.AndroidApplication.activityBackPressedEvent,
|
||||
this.backEvent
|
||||
)
|
||||
console.log("navigateBackToHome")
|
||||
},
|
||||
navigateTo(to, filter, filterCategory) {
|
||||
this.navigateBackToHome()
|
||||
if (this.currentComponent !== "EnRecipes") {
|
||||
this.currentComponent = "EnRecipes"
|
||||
this.$navigateBack({ frame: "main-frame" })
|
||||
}
|
||||
this.filterFavorites = false
|
||||
this.selectedCategory = null
|
||||
this.title = to
|
||||
this.title = title
|
||||
console.log(title)
|
||||
if (filter) {
|
||||
this.currentComponent = "EnRecipes"
|
||||
if (to === "Favorites") {
|
||||
this.filterFavorites = true
|
||||
}
|
||||
} else if (filterCategory) {
|
||||
this.currentComponent = "EnRecipes"
|
||||
this.selectedCategory = to
|
||||
} else {
|
||||
this.currentComponent = to
|
||||
}
|
||||
if (to === "Favorites") this.filterFavorites = true
|
||||
} else if (filterCategory) this.selectedCategory = to
|
||||
if (!this.filterFavorites && !this.selectedCategory)
|
||||
this.removeBackEvent()
|
||||
this.closeDrawer()
|
||||
},
|
||||
navigateTo(to, title) {
|
||||
this.currentComponent = title
|
||||
this.$navigateTo(to, {
|
||||
frame: "main-frame",
|
||||
// transition: {
|
||||
// name: "slide",
|
||||
// duration: 250,
|
||||
// curve: "easeIn",
|
||||
// },
|
||||
props: {
|
||||
highlight: this.highlight,
|
||||
viewIsScrolled: this.viewIsScrolled,
|
||||
showDrawer: this.showDrawer,
|
||||
title,
|
||||
},
|
||||
backstackVisible: false,
|
||||
})
|
||||
this.closeDrawer()
|
||||
},
|
||||
showDrawer() {
|
||||
this.$refs.drawer.nativeView.showDrawer()
|
||||
},
|
||||
closeDrawer() {
|
||||
this.$refs.drawer.nativeView.toggleDrawerState()
|
||||
this.$refs.drawer.nativeView.closeDrawer()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
ActionBar {
|
||||
background: white;
|
||||
color: #000000;
|
||||
height: 64;
|
||||
.bx {
|
||||
background: white;
|
||||
padding: 16;
|
||||
}
|
||||
}
|
||||
SearchBar {
|
||||
background: #fff;
|
||||
color: #333333;
|
||||
.noResults {
|
||||
width: 100%;
|
||||
padding: 16;
|
||||
font-size: 16;
|
||||
margin-top: 4;
|
||||
line-height: 8;
|
||||
}
|
||||
.hr {
|
||||
border-color: #eeeeee;
|
||||
}
|
||||
.title {
|
||||
text-align: left;
|
||||
padding-left: 8;
|
||||
font-size: 20;
|
||||
.swipe-item {
|
||||
margin: 0 8;
|
||||
background: #ff7043;
|
||||
color: #fff;
|
||||
height: 128;
|
||||
border-radius: 6;
|
||||
}
|
||||
|
||||
.message {
|
||||
vertical-align: center;
|
||||
text-align: center;
|
||||
font-size: 20;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.drawer-item {
|
||||
border-radius: 4;
|
||||
padding: 12 16;
|
||||
color: #546e7a;
|
||||
font-size: 16;
|
||||
}
|
||||
.drawer-group-header {
|
||||
padding: 12;
|
||||
color: #546e7a;
|
||||
font-size: 12;
|
||||
}
|
||||
.selected-drawer-item {
|
||||
background: #fbe9e7;
|
||||
color: #ff7043;
|
||||
}
|
||||
.recipe-list-item {
|
||||
background: white;
|
||||
margin: 16 16 0;
|
||||
border-radius: 4;
|
||||
&:last-of-type {
|
||||
margin-bottom: 16;
|
||||
}
|
||||
.recipeCategory {
|
||||
font-size: 14;
|
||||
padding: 0;
|
||||
color: #ff7043;
|
||||
}
|
||||
.recipeTitle {
|
||||
font-size: 16;
|
||||
line-height: 4;
|
||||
// height: 48;
|
||||
// width: 128;
|
||||
}
|
||||
.recipeTime {
|
||||
font-size: 12;
|
||||
color: #546e7a;
|
||||
}
|
||||
}
|
||||
#categoriesMenu {
|
||||
max-height: 336;
|
||||
}
|
||||
#btnFabContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#btnFab {
|
||||
.btnFab {
|
||||
width: 56;
|
||||
height: 56;
|
||||
padding: 16;
|
||||
background-color: #ff7043;
|
||||
color: #000;
|
||||
color: #fff;
|
||||
border-radius: 28;
|
||||
text-align: center;
|
||||
}
|
||||
// prettier-ignore
|
||||
Button {
|
||||
color: #ff7043;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,515 @@
|
|||
<template>
|
||||
<Page>
|
||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||
<GridLayout rows="*" columns="auto, *, auto," class="actionBarContainer">
|
||||
<Label
|
||||
class="bx leftAction"
|
||||
:text="icon.back"
|
||||
automationText="Back"
|
||||
col="0"
|
||||
@tap="navigateBack"
|
||||
/>
|
||||
<Label class="title orkm" text="New recipe" col="1" />
|
||||
<Label
|
||||
v-if="hasEnoughDetails"
|
||||
class="bx"
|
||||
:text="icon.save"
|
||||
col="2"
|
||||
@tap="saveRecipe"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView
|
||||
width="100%"
|
||||
height="100%"
|
||||
@scroll="onScroll($event)"
|
||||
scrollBarIndicatorVisible="false"
|
||||
>
|
||||
<StackLayout width="100%">
|
||||
<!-- Image and camera btn -->
|
||||
<AbsoluteLayout>
|
||||
<StackLayout
|
||||
width="100%"
|
||||
:height="screenWidth"
|
||||
class="view-imageHolder"
|
||||
verticalAlignment="center"
|
||||
>
|
||||
<Image
|
||||
v-if="recipeContent.imageSrc"
|
||||
:src="recipeContent.imageSrc"
|
||||
stretch="aspectFill"
|
||||
width="100%"
|
||||
:height="screenWidth"
|
||||
/>
|
||||
<Label
|
||||
v-else
|
||||
horizontalAlignment="center"
|
||||
class="bx"
|
||||
fontSize="160"
|
||||
:text="icon.dish"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
width="100%"
|
||||
horizontalAlignment="center"
|
||||
:top="screenWidth - 42"
|
||||
>
|
||||
<Label
|
||||
v-if="recipeContent.imageSrc"
|
||||
class="bx btnFab"
|
||||
:text="icon.close"
|
||||
androidElevation="8"
|
||||
@tap="removePicture()"
|
||||
/>
|
||||
<Label
|
||||
v-else
|
||||
class="bx btnFab"
|
||||
:text="icon.camera"
|
||||
androidElevation="8"
|
||||
@tap="takePicture()"
|
||||
/>
|
||||
</StackLayout>
|
||||
</AbsoluteLayout>
|
||||
|
||||
<!-- Primary information -->
|
||||
<StackLayout margin="0 16">
|
||||
<AbsoluteLayout class="inputField">
|
||||
<TextField
|
||||
width="100%"
|
||||
hint="My Healthy Recipe"
|
||||
v-model="recipeContent.title"
|
||||
autocapitalizationType="words"
|
||||
maxLength="32"
|
||||
/>
|
||||
<Label top="0" class="fieldLabel" text="Title" />
|
||||
</AbsoluteLayout>
|
||||
<AbsoluteLayout class="inputField">
|
||||
<TextField
|
||||
width="100%"
|
||||
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
|
||||
width="100%"
|
||||
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
|
||||
width="100%"
|
||||
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
|
||||
verticalAlignment="center"
|
||||
col="6"
|
||||
padding="4"
|
||||
margin="8 0 0 0"
|
||||
class="bx"
|
||||
: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"
|
||||
/>
|
||||
|
||||
<!-- <TextField
|
||||
col="0"
|
||||
v-model="recipeContent.instructions[index]"
|
||||
:hint="`Step ${index + 1}`"
|
||||
/> -->
|
||||
<Label
|
||||
verticalAlignment="center"
|
||||
col="2"
|
||||
padding="4"
|
||||
margin="8 0 0 0"
|
||||
class="bx"
|
||||
:text="icon.close"
|
||||
@tap="removeInstruction(index)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<Label
|
||||
class="sec-btn pull-left orkm"
|
||||
text="+ ADD STEP"
|
||||
@tap="addInstruction()"
|
||||
/>
|
||||
<StackLayout class="hr" margin="24 16"></StackLayout>
|
||||
</StackLayout>
|
||||
|
||||
<!-- Notes section -->
|
||||
<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
|
||||
verticalAlignment="center"
|
||||
col="2"
|
||||
padding="4"
|
||||
margin="8 0 0 0"
|
||||
class="bx"
|
||||
: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
|
||||
verticalAlignment="center"
|
||||
col="2"
|
||||
padding="4"
|
||||
margin="8 0 0 0"
|
||||
class="bx"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { screen } from "tns-core-modules/platform"
|
||||
import { Mediafilepicker } from "nativescript-mediafilepicker"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
viewIsScrolled: false,
|
||||
units: [
|
||||
"unit",
|
||||
"tsp",
|
||||
"Tbsp",
|
||||
"oz",
|
||||
"cup",
|
||||
"pt",
|
||||
"qt",
|
||||
"lb",
|
||||
"gal",
|
||||
"ml",
|
||||
"L",
|
||||
"mg",
|
||||
"g",
|
||||
"kg",
|
||||
"mm",
|
||||
"cm",
|
||||
"m",
|
||||
"in",
|
||||
"°C",
|
||||
"°F",
|
||||
],
|
||||
recipeContent: {
|
||||
imageSrc: null,
|
||||
title: null,
|
||||
category: null,
|
||||
prepTime: "00:00",
|
||||
cookTime: "00:00",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: null,
|
||||
quantity: null,
|
||||
unit: "unit",
|
||||
},
|
||||
],
|
||||
instructions: [""],
|
||||
notes: [""],
|
||||
references: [""],
|
||||
isFavorite: false,
|
||||
},
|
||||
categories: [
|
||||
"Appetizers",
|
||||
"BBQ",
|
||||
"Beverages",
|
||||
"Breads",
|
||||
"Breakfast",
|
||||
"Desserts",
|
||||
"Dinner",
|
||||
"Drinks",
|
||||
"Healthy",
|
||||
"Lunch",
|
||||
"Main dishes",
|
||||
"Meat",
|
||||
"Noodles",
|
||||
"Pasta",
|
||||
"Poultry",
|
||||
"Rice",
|
||||
"Salads",
|
||||
"Sauces",
|
||||
"Seafood",
|
||||
"Side dishes",
|
||||
"Snacks",
|
||||
"Soups",
|
||||
"Vegan",
|
||||
"Vegetarian",
|
||||
"ADD NEW CATEGORY",
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
screenWidth() {
|
||||
return screen.mainScreen.widthDIPs
|
||||
},
|
||||
hasEnoughDetails() {
|
||||
let recipe = this.recipeContent
|
||||
return recipe.title && recipe.category
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setTime(time) {
|
||||
if (Date.parse(this.recipeContent[time])) {
|
||||
let date = new Date(this.recipeContent[time])
|
||||
let h = date.getHours()
|
||||
let m = date.getMinutes()
|
||||
|
||||
this.recipeContent[time] =
|
||||
(h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m)
|
||||
}
|
||||
// console.log(this.recipeContent[time])
|
||||
},
|
||||
saveRecipe() {
|
||||
this.setTime("prepTime")
|
||||
this.setTime("cookTime")
|
||||
// console.log(this.recipeContent)
|
||||
|
||||
this.$store.dispatch("addRecipe", this.recipeContent)
|
||||
this.$navigateBack()
|
||||
},
|
||||
onPrepTimeChange(args) {
|
||||
this.recipeContent.prepTime = args.value
|
||||
},
|
||||
onCookTimeChange(args) {
|
||||
this.recipeContent.cookTime = args.value
|
||||
},
|
||||
onScroll(args) {
|
||||
args.scrollY
|
||||
? (this.viewIsScrolled = true)
|
||||
: (this.viewIsScrolled = false)
|
||||
},
|
||||
showCategories() {
|
||||
action("Select a category", "Cancel", [...this.categories]).then(
|
||||
(result) => {
|
||||
if (result != "Cancel") this.recipeContent.category = result
|
||||
}
|
||||
)
|
||||
},
|
||||
navigateBack() {
|
||||
confirm({
|
||||
message:
|
||||
"Are you sure you want discard unsaved changes to this recipe?",
|
||||
cancelButtonText: "Keep Editing",
|
||||
okButtonText: "Discard",
|
||||
}).then((res) => {
|
||||
if (res) {
|
||||
this.$navigateBack()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
takePicture() {
|
||||
let mediafilepicker = new Mediafilepicker()
|
||||
let vm = this
|
||||
const options = { width: 800, height: 800, lockSquare: true }
|
||||
const androidOptions = {
|
||||
isFreeStyleCropEnabled: true,
|
||||
statusBarColor: "black",
|
||||
setAspectRatioOptions: {
|
||||
defaultIndex: 0,
|
||||
aspectRatios: [
|
||||
{
|
||||
aspectRatioTitle: "1:1",
|
||||
aspectRatioX: 1,
|
||||
aspectRatioY: 1,
|
||||
},
|
||||
{
|
||||
aspectRatioTitle: "16:9",
|
||||
aspectRatioX: 16,
|
||||
aspectRatioY: 9,
|
||||
},
|
||||
{
|
||||
aspectRatioTitle: "18:9",
|
||||
aspectRatioX: 18,
|
||||
aspectRatioY: 9,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
mediafilepicker.openImagePicker({
|
||||
android: {
|
||||
isCaptureMood: false, // if true then camera will open directly.
|
||||
isNeedCamera: true,
|
||||
maxNumberFiles: 1,
|
||||
isNeedFolderList: false,
|
||||
},
|
||||
})
|
||||
mediafilepicker.on("getFiles", function(res) {
|
||||
let result = res.object.get("results")
|
||||
vm.recipeContent.imageSrc = result[0].file
|
||||
})
|
||||
},
|
||||
removePicture() {
|
||||
confirm({
|
||||
title: "Delete Recipe Photo",
|
||||
message: "Are you sure you want to delete the recipe photo?",
|
||||
okButtonText: "Delete",
|
||||
cancelButtonText: "Cancel",
|
||||
}).then((e) => {
|
||||
if (e) this.recipeContent.imageSrc = null
|
||||
})
|
||||
},
|
||||
|
||||
addIngredient() {
|
||||
this.recipeContent.ingredients.push({
|
||||
item: null,
|
||||
quantity: null,
|
||||
unit: "unit",
|
||||
})
|
||||
},
|
||||
removeIngredient(index) {
|
||||
this.recipeContent.ingredients.splice(index, 1)
|
||||
},
|
||||
|
||||
addInstruction() {
|
||||
this.recipeContent.instructions.push("")
|
||||
},
|
||||
removeInstruction(index) {
|
||||
this.recipeContent.instructions.splice(index, 1)
|
||||
},
|
||||
|
||||
addNote() {
|
||||
this.recipeContent.notes.push("")
|
||||
},
|
||||
removeNote(index) {
|
||||
this.recipeContent.notes.splice(index, 1)
|
||||
},
|
||||
|
||||
addReference() {
|
||||
this.recipeContent.references.push("")
|
||||
},
|
||||
removeReference(index) {
|
||||
this.recipeContent.references.splice(index, 1)
|
||||
},
|
||||
|
||||
showUnits(e) {
|
||||
action("Select measuring unit", "Cancel", [...this.units]).then(
|
||||
(result) => {
|
||||
if (result != "Cancel") e.object.text = result
|
||||
}
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -1,109 +1,186 @@
|
|||
<template>
|
||||
<AbsoluteLayout>
|
||||
<ScrollView scrollBarIndicatorVisible="false" width="100%" height="100%">
|
||||
<StackLayout v-if="filteredRecipes.length">
|
||||
<!-- <RadListView
|
||||
ref="listView"
|
||||
for="item in filteredRecipes"
|
||||
swipeActions="true"
|
||||
@itemSwipeProgressStarted="onSwipeStarted"
|
||||
>
|
||||
<v-template>
|
||||
<StackLayout class="item p-t-10" orientation="vertical">
|
||||
<Label :text="item.name" class="nameLabel"></Label>
|
||||
<Label :text="item.description" class="descriptionLabel"></Label>
|
||||
</StackLayout>
|
||||
</v-template>
|
||||
<v-template name="itemswipe">
|
||||
<GridLayout columns="auto, *, auto" backgroundColor="White">
|
||||
<StackLayout
|
||||
id="mark-view"
|
||||
col="0"
|
||||
class="swipe-item left"
|
||||
orientation="horizontal"
|
||||
@tap="onLeftSwipeClick"
|
||||
>
|
||||
<Label
|
||||
text="mark"
|
||||
verticalAlignment="center"
|
||||
horizontalAlignment="center"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
id="delete-view"
|
||||
col="2"
|
||||
class="swipe-item right"
|
||||
orientation="horizontal"
|
||||
@tap="onRightSwipeClick"
|
||||
>
|
||||
<Label
|
||||
text="delete"
|
||||
verticalAlignment="center"
|
||||
horizontalAlignment="center"
|
||||
/>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</RadListView>-->
|
||||
<GridLayout
|
||||
v-for="recipe in filteredRecipes"
|
||||
:key="recipe.id"
|
||||
rows="128"
|
||||
columns="128, *"
|
||||
class="recipe-list-item"
|
||||
androidElevation="2"
|
||||
>
|
||||
<Image src="res://icon" stretch="fill" col="0" />
|
||||
<StackLayout
|
||||
col="1"
|
||||
horizontalAlignment="left"
|
||||
verticalAlignment="top"
|
||||
margin="16"
|
||||
>
|
||||
<Label :text="recipe.category" class="orkm recipeCategory" />
|
||||
<Label :text="recipe.title" class="orkb recipeTitle" />
|
||||
<Label :text="recipe.time" class="orkr recipeTime" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<StackLayout height="128"></StackLayout>
|
||||
</StackLayout>
|
||||
<Label
|
||||
<Page>
|
||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||
<!-- Search Actionbar -->
|
||||
<GridLayout
|
||||
v-if="showSearch"
|
||||
rows="*"
|
||||
columns="auto, *"
|
||||
class="actionBarContainer"
|
||||
>
|
||||
<Label
|
||||
class="bx leftAction"
|
||||
:text="icon.back"
|
||||
automationText="Back"
|
||||
col="0"
|
||||
@tap="closeSearch"
|
||||
/>
|
||||
<SearchBar
|
||||
@loaded="searchBarLoaded"
|
||||
id="searchField"
|
||||
col="1"
|
||||
hint="Search"
|
||||
textFieldHintColor="#bdbdbd"
|
||||
v-model="searchQuery"
|
||||
/>
|
||||
</GridLayout>
|
||||
<!-- Home Actionbar -->
|
||||
<GridLayout
|
||||
v-else
|
||||
class="recipe-list-item"
|
||||
rows="*"
|
||||
columns="auto, *, auto,"
|
||||
class="actionBarContainer"
|
||||
>
|
||||
<Label
|
||||
class="bx leftAction"
|
||||
:text="icon.menu"
|
||||
automationText="Menu"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" :text="title" col="1" />
|
||||
<Label
|
||||
class="bx"
|
||||
:text="icon.search"
|
||||
col="2"
|
||||
@tap="showSearch = true"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<AbsoluteLayout>
|
||||
<RadListView
|
||||
v-if="filteredRecipes.length"
|
||||
ref="listView"
|
||||
for="recipe in filteredRecipes"
|
||||
swipeActions="true"
|
||||
@itemSwipeProgressChanged="onSwiping"
|
||||
@itemSwipeProgressEnded="onSwipeEnded"
|
||||
@scrolled="onScroll($event)"
|
||||
@itemTap="viewRecipe"
|
||||
>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
class="recipe-li"
|
||||
rows="128"
|
||||
columns="auto, *, auto"
|
||||
androidElevation="2"
|
||||
>
|
||||
<Image
|
||||
src="res://icon"
|
||||
stretch="fill"
|
||||
col="0"
|
||||
width="128"
|
||||
height="128"
|
||||
/>
|
||||
<StackLayout
|
||||
class="recipe-info"
|
||||
col="1"
|
||||
horizontalAlignment="left"
|
||||
verticalAlignment="top"
|
||||
>
|
||||
<Label :text="recipe.category" class="orkm h4 recipe-cat" />
|
||||
<Label :text="recipe.title" class="orkm recipe-title" />
|
||||
<Label
|
||||
:text="recipeTotalTime(recipe.prepTime, recipe.cookTime)"
|
||||
class="h4 recipe-time"
|
||||
/>
|
||||
</StackLayout>
|
||||
<Label
|
||||
verticalAlignment="top"
|
||||
col="2"
|
||||
class="bx recipe-favorite"
|
||||
:class="{ hide: !recipe.isFavorite }"
|
||||
:text="icon.heart"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
|
||||
<v-template name="itemswipe">
|
||||
<GridLayout columns="auto, *, auto">
|
||||
<StackLayout
|
||||
id="favorite-action"
|
||||
col="0"
|
||||
class="swipe-item left"
|
||||
verticalAlignment="top"
|
||||
>
|
||||
<Label class="bx" padding="8 6 0 0" :text="icon.heart" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
id="delete-action"
|
||||
col="2"
|
||||
class="swipe-item right"
|
||||
verticalAlignment="top"
|
||||
>
|
||||
<Label class="bx" padding="8 0 0 6" :text="icon.trash" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</RadListView>
|
||||
<Label
|
||||
v-if="!filteredRecipes.length && searchQuery"
|
||||
class="noResults"
|
||||
horizontalAlignment="center"
|
||||
:text="
|
||||
`Your search '${searchQuery}' did not match any recipes in this category.`
|
||||
`Your search "${searchQuery}" did not match any recipes in this category.`
|
||||
"
|
||||
textAlignment="center"
|
||||
textWrap="true"
|
||||
/>
|
||||
</ScrollView>
|
||||
<GridLayout id="btnFabContainer" rows="*,88" columns="*,88">
|
||||
<Label
|
||||
row="1"
|
||||
col="1"
|
||||
id="btnFab"
|
||||
class="bx"
|
||||
:text="icon.plus"
|
||||
androidElevation="8"
|
||||
@tap="FabTapped"
|
||||
v-if="!filteredRecipes.length && filterFavorites && !searchQuery"
|
||||
class="noResults"
|
||||
horizontalAlignment="center"
|
||||
text="Your favorite recipes will be listed here."
|
||||
textAlignment="center"
|
||||
textWrap="true"
|
||||
/>
|
||||
</GridLayout>
|
||||
</AbsoluteLayout>
|
||||
<GridLayout
|
||||
id="btnFabContainer"
|
||||
rows="*,88"
|
||||
columns="*,88"
|
||||
v-if="!showSearch"
|
||||
>
|
||||
<Label
|
||||
row="1"
|
||||
col="1"
|
||||
class="bx btnFab"
|
||||
:text="icon.plus"
|
||||
androidElevation="8"
|
||||
@tap="addRecipe"
|
||||
/>
|
||||
</GridLayout>
|
||||
</AbsoluteLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ["searchQuery", "filterFavorites", "recipes", "selectedCategory"],
|
||||
import * as utils from "tns-core-modules/utils/utils"
|
||||
import * as application from "tns-core-modules/application"
|
||||
import * as gestures from "tns-core-modules/ui/gestures"
|
||||
|
||||
import { ObservableArray } from "tns-core-modules/data/observable-array"
|
||||
|
||||
import EditRecipe from "./EditRecipe.vue"
|
||||
import ViewRecipe from "./ViewRecipe.vue"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
export default {
|
||||
props: ["filterFavorites", "selectedCategory", "title", "showDrawer"],
|
||||
components: {
|
||||
EditRecipe,
|
||||
ViewRecipe,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
icon: {
|
||||
plus: "\ueb89",
|
||||
},
|
||||
searchQuery: "",
|
||||
showSearch: false,
|
||||
viewIsScrolled: false,
|
||||
leftAction: false,
|
||||
rightAction: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["recipes", "icon"]),
|
||||
recipesByCategory() {
|
||||
return this.recipes.reduce((acc, e) => {
|
||||
acc[e.category] = [...(acc[e.category] || []), e]
|
||||
|
@ -130,12 +207,114 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
onSwiping({ data, object }) {
|
||||
const swipeLimits = data.swipeLimits
|
||||
const swipeView = object
|
||||
const leftItem = swipeView.getViewById("favorite-action")
|
||||
const rightItem = swipeView.getViewById("delete-action")
|
||||
swipeLimits.left = leftItem.getMeasuredWidth() - 12
|
||||
swipeLimits.right = rightItem.getMeasuredWidth() - 12
|
||||
swipeLimits.threshold = swipeLimits.left - 4
|
||||
if (data.x > swipeLimits.threshold) {
|
||||
this.leftAction = true
|
||||
this.$refs.listView.notifySwipeToExecuteFinished()
|
||||
} else if (data.x < -swipeLimits.threshold) {
|
||||
this.rightAction = true
|
||||
this.$refs.listView.notifySwipeToExecuteFinished()
|
||||
}
|
||||
},
|
||||
onSwipeEnded({ index }) {
|
||||
let context = this.recipes.indexOf(this.filteredRecipes[index])
|
||||
if (this.leftAction) this.toggleFavorite(context)
|
||||
else if (this.rightAction) this.deleteRecipe()
|
||||
this.leftAction = this.rightAction = false
|
||||
},
|
||||
toggleFavorite(index) {
|
||||
this.$store.dispatch("toggleFavorite", index)
|
||||
},
|
||||
deleteRecipe() {
|
||||
alert("Are you sure you want to delete?")
|
||||
},
|
||||
// swipeAction(args, index) {
|
||||
// let vm = this
|
||||
// args.object.on(gestures.GestureTypes.swipe, function(args) {
|
||||
// console.log("Swipe Direction: " + args.direction)
|
||||
// if (args.direction === 1) {
|
||||
// vm.filteredRecipes[index].isFavorite = !vm.filteredRecipes[index]
|
||||
// .isFavorite
|
||||
// console.log(vm.filteredRecipes[index].isFavorite)
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
recipeTotalTime(prepTime, cookTime) {
|
||||
let pT = prepTime.split(":")
|
||||
let cT = cookTime.split(":")
|
||||
let hrs = parseInt(pT[0]) + parseInt(cT[0])
|
||||
let mins = parseInt(pT[1]) + parseInt(cT[1])
|
||||
if (mins > 60) {
|
||||
hrs += Math.floor(mins / 60)
|
||||
mins -= 60
|
||||
}
|
||||
return hrs ? `${hrs}h ${mins}m` : `${mins}m`
|
||||
},
|
||||
onScroll(args) {
|
||||
args.scrollOffset
|
||||
? (this.viewIsScrolled = true)
|
||||
: (this.viewIsScrolled = false)
|
||||
},
|
||||
// SearchBar
|
||||
searchBarLoaded() {
|
||||
application.android.on(
|
||||
application.AndroidApplication.activityBackPressedEvent,
|
||||
this.backEvent
|
||||
)
|
||||
},
|
||||
backEvent(args) {
|
||||
if (this.showSearch) {
|
||||
args.cancel = true
|
||||
this.closeSearch()
|
||||
}
|
||||
this.removeBackEvent()
|
||||
},
|
||||
removeBackEvent() {
|
||||
application.android.off(
|
||||
application.AndroidApplication.activityBackPressedEvent,
|
||||
this.backEvent
|
||||
)
|
||||
},
|
||||
closeSearch() {
|
||||
this.searchQuery = ""
|
||||
this.showSearch = false
|
||||
utils.ad.dismissSoftInput()
|
||||
},
|
||||
FabTapped() {
|
||||
alert("fab tapped")
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// console.log(this.recipesByCategory)
|
||||
addRecipe() {
|
||||
this.$navigateTo(EditRecipe, {
|
||||
transition: {
|
||||
name: "slide",
|
||||
duration: 250,
|
||||
curve: "easeIn",
|
||||
},
|
||||
props: {
|
||||
viewIsScrolled: this.viewIsScrolled,
|
||||
},
|
||||
})
|
||||
},
|
||||
viewRecipe({ item }) {
|
||||
// console.log(item)
|
||||
this.$navigateTo(ViewRecipe, {
|
||||
transition: {
|
||||
name: "fade",
|
||||
duration: 250,
|
||||
curve: "easeIn",
|
||||
},
|
||||
props: {
|
||||
recipe: item,
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,79 +1,105 @@
|
|||
<template>
|
||||
<StackLayout class="main-container">
|
||||
<Label text="Interface" class="group-header" />
|
||||
<Page>
|
||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||
<!-- Settings Actionbar -->
|
||||
<GridLayout rows="*" columns="auto, *" class="actionBarContainer">
|
||||
<Label
|
||||
class="bx leftAction"
|
||||
:text="icon.menu"
|
||||
automationText="Menu"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" :text="title" col="1" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout class="main-container">
|
||||
<Label text="Interface" class="group-header" />
|
||||
|
||||
<StackLayout orientation="horizontal" class="option" @tap="selectThemes">
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.theme" />
|
||||
<StackLayout>
|
||||
<Label text="Theme" class="option-title" />
|
||||
<Label :text="themeName" class="option-info" textWrap="true" />
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="option"
|
||||
@tap="selectThemes"
|
||||
>
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.theme" />
|
||||
<StackLayout>
|
||||
<Label text="Theme" class="option-title" />
|
||||
<Label :text="themeName" class="option-info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label text="Backup/Restore" class="group-header" />
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="option"
|
||||
@tap="selectBackupDir"
|
||||
>
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.folder" />
|
||||
<StackLayout>
|
||||
<Label text="EnRecipes Backup Directory" class="option-title" />
|
||||
<Label text="/storage/emulated/0/EnRecipes" class="option-info" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="option" @tap="backupData">
|
||||
<Label class="bx" :text="icon.backup" />
|
||||
<Label text="Backup Data" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="option" @tap="restoreData">
|
||||
<Label class="bx" :text="icon.restore" />
|
||||
<Label text="Restore Data" class="option-title" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label text="Backup/Restore" class="group-header" />
|
||||
<StackLayout orientation="horizontal" class="option" @tap="selectBackupDir">
|
||||
<Label verticalAlignment="center" class="bx" :text="icon.folder" />
|
||||
<StackLayout>
|
||||
<Label text="EnRecipes Backup Directory" class="option-title" />
|
||||
<Label text="/storage/emulated/0/EnRecipes" class="option-info" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="option" @tap="backupData">
|
||||
<Label class="bx" :text="icon.backup" />
|
||||
<Label text="Backup Data" class="option-title" />
|
||||
</StackLayout>
|
||||
<StackLayout orientation="horizontal" class="option" @tap="restoreData">
|
||||
<Label class="bx" :text="icon.restore" />
|
||||
<Label text="Restore Data" class="option-title" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Menu } from "nativescript-menu"
|
||||
import * as permissions from "nativescript-permissions"
|
||||
import * as application from "tns-core-modules/application"
|
||||
|
||||
import { getString, setString } from "application-settings"
|
||||
import Theme from "@nativescript/theme"
|
||||
|
||||
import { mapState, mapActions } from "vuex"
|
||||
export default {
|
||||
props: ["highlight"],
|
||||
props: ["highlight", "viewIsScrolled", "showDrawer", "title"],
|
||||
data() {
|
||||
return {
|
||||
icon: {
|
||||
theme: "\ued09",
|
||||
folder: "\ued7c",
|
||||
backup: "\uee48",
|
||||
restore: "\ueadc",
|
||||
},
|
||||
options: {
|
||||
interface: [
|
||||
{
|
||||
title: "Theme",
|
||||
subTitle: "Light",
|
||||
icon: "\ued09",
|
||||
},
|
||||
],
|
||||
backupRestore: [
|
||||
{
|
||||
title: "EnRecipes Backup Directory",
|
||||
subTitle: "/storage/emulated/0/EnRecipes",
|
||||
icon: "\ued7c",
|
||||
},
|
||||
{
|
||||
title: "Backup Data",
|
||||
subTitle: null,
|
||||
icon: "\uee48",
|
||||
},
|
||||
{
|
||||
title: "Restore Data",
|
||||
subTitle: null,
|
||||
icon: "\ueadc",
|
||||
},
|
||||
],
|
||||
interface: {
|
||||
theme: {
|
||||
title: "Theme",
|
||||
subTitle: "Light",
|
||||
icon: "\ued09",
|
||||
},
|
||||
},
|
||||
backupRestore: [
|
||||
{
|
||||
title: "EnRecipes Backup Directory",
|
||||
subTitle: "/storage/emulated/0/EnRecipes",
|
||||
icon: "\ued7c",
|
||||
},
|
||||
{
|
||||
title: "Backup Data",
|
||||
subTitle: null,
|
||||
icon: "\uee48",
|
||||
},
|
||||
{
|
||||
title: "Restore Data",
|
||||
subTitle: null,
|
||||
icon: "\ueadc",
|
||||
},
|
||||
],
|
||||
themeName: "Light",
|
||||
themesArray: ["Light", "Dark", "Black"],
|
||||
themesArray: ["Light", "Dark"],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
methods: {
|
||||
selectThemes(args) {
|
||||
this.highlight(args)
|
||||
|
@ -83,10 +109,10 @@ export default {
|
|||
actions: this.themesArray,
|
||||
})
|
||||
.then((action) => {
|
||||
if (this.themesArray.includes(action.title)) {
|
||||
this.options.interface[0].subTitle = this.themeName = action.title
|
||||
}
|
||||
// alert(action.id + " - " + action.title)
|
||||
this.interface.theme.subTitle = this.themeName = action.title
|
||||
console.log(this.themeName)
|
||||
setString("application-theme", action.title)
|
||||
Theme.toggleMode()
|
||||
})
|
||||
.catch(console.log)
|
||||
},
|
||||
|
@ -127,35 +153,11 @@ export default {
|
|||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.interface.theme.subTitle = this.themeName = getString(
|
||||
"application-theme",
|
||||
"Light"
|
||||
)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.option-highlight {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.group-header {
|
||||
padding: 12;
|
||||
color: #ff7043;
|
||||
}
|
||||
.main-container {
|
||||
padding: 16 8 0;
|
||||
.option {
|
||||
padding: 16;
|
||||
border-radius: 4;
|
||||
background: transparent;
|
||||
font-size: 16;
|
||||
.bx {
|
||||
margin: 0 24 0 0;
|
||||
color: #546e7a;
|
||||
}
|
||||
.option-title {
|
||||
color: #333333;
|
||||
background: transparent;
|
||||
}
|
||||
.option-info {
|
||||
font-size: 12;
|
||||
color: #546e7a;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
<template>
|
||||
<Page>
|
||||
<ActionBar margin="0" flat="true">
|
||||
<GridLayout
|
||||
rows="*"
|
||||
columns="auto, *, auto,auto"
|
||||
class="actionBarContainer"
|
||||
>
|
||||
<Label
|
||||
col="0"
|
||||
class="bx leftAction"
|
||||
:text="icon.back"
|
||||
automationText="Back"
|
||||
@tap="navigateBack"
|
||||
verticalAlignment="top"
|
||||
/>
|
||||
<Label
|
||||
class="title orkm"
|
||||
:text="recipe.title"
|
||||
lineHeight="4"
|
||||
col="1"
|
||||
textWrap="true"
|
||||
verticalAlignment="bottom"
|
||||
/>
|
||||
<Label
|
||||
col="2"
|
||||
class="bx"
|
||||
:text="icon.share"
|
||||
@tap=""
|
||||
verticalAlignment="top"
|
||||
/>
|
||||
<Label
|
||||
col="3"
|
||||
class="bx"
|
||||
:class="{ 'view-favorited': recipe.isFavorite }"
|
||||
:text="recipe.isFavorite ? icon.heart : icon.heartOutline"
|
||||
@tap="toggleFavorite"
|
||||
verticalAlignment="top"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<AbsoluteLayout>
|
||||
<TabView androidElevation="0" width="100%" height="100%">
|
||||
<TabViewItem title="Overview">
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout class="">
|
||||
<StackLayout
|
||||
width="100%"
|
||||
:height="screenWidth"
|
||||
verticalAlignment="center"
|
||||
class="view-imageHolder"
|
||||
>
|
||||
<Image
|
||||
v-if="recipe.imageSrc"
|
||||
:src="recipe.imageSrc"
|
||||
stretch="aspectFill"
|
||||
width="100%"
|
||||
:height="screenWidth"
|
||||
/>
|
||||
<Label
|
||||
v-else
|
||||
horizontalAlignment="center"
|
||||
class="bx"
|
||||
fontSize="160"
|
||||
:text="icon.dish"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout margin="16 16 128">
|
||||
<Label class="view-cat orkm" :text="recipe.category" />
|
||||
<Label
|
||||
class="view-title p-b-8 orkm"
|
||||
:text="recipe.title"
|
||||
textWrap="true"
|
||||
/>
|
||||
<Label
|
||||
class="view-other"
|
||||
:text="`Preparation time: ${getTime(recipe.prepTime)}`"
|
||||
/>
|
||||
<Label
|
||||
class="view-other"
|
||||
:text="`Cooking time: ${getTime(recipe.cookTime)}`"
|
||||
/>
|
||||
<Label
|
||||
class="view-other"
|
||||
:text="`Portion size: ${recipe.portionSize}`"
|
||||
/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</TabViewItem>
|
||||
<TabViewItem title="Ingredients" v-if="recipe.ingredients[0].item">
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout padding="16 16 128">
|
||||
<AbsoluteLayout class="inputField">
|
||||
<TextField
|
||||
width="50%"
|
||||
v-model="portionScale"
|
||||
keyboardType="number"
|
||||
/>
|
||||
<Label top="0" class="fieldLabel" text="Set portion size" />
|
||||
</AbsoluteLayout>
|
||||
<StackLayout margin="24 0 8 0">
|
||||
<Label
|
||||
class="view-title p-b-8 orkm"
|
||||
:text="
|
||||
`Ingredients for ${portionScale}${
|
||||
portionScale > 1
|
||||
? ' portions'
|
||||
: portionScale == 0
|
||||
? '1 portion'
|
||||
: ' portion'
|
||||
}`
|
||||
"
|
||||
textWrap="true"
|
||||
/>
|
||||
<Label
|
||||
class="view-ingredient"
|
||||
v-for="(item, index) in recipe.ingredients"
|
||||
:key="index"
|
||||
:text="
|
||||
`${roundedQuantity(item.quantity)}${
|
||||
item.unit ? ' ' + item.unit : ''
|
||||
} ${item.item}`
|
||||
"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</TabViewItem>
|
||||
<TabViewItem title="Instructions" v-if="recipe.instructions[0].length">
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout padding="16 16 128">
|
||||
<GridLayout
|
||||
columns="auto ,*"
|
||||
v-for="(instruction, index) in recipe.instructions"
|
||||
:key="index"
|
||||
>
|
||||
<Label
|
||||
col="0"
|
||||
colSpan="2"
|
||||
class="view-instruction"
|
||||
:class="{
|
||||
instructionWOBorder:
|
||||
index === recipe.instructions.length - 1,
|
||||
}"
|
||||
:text="instruction"
|
||||
textWrap="true"
|
||||
/>
|
||||
<Label
|
||||
verticalAlignment="top"
|
||||
horizontalAlignment="center"
|
||||
class="view-count orkb"
|
||||
col="0"
|
||||
:text="index + 1"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</TabViewItem>
|
||||
<TabViewItem title="Notes" v-if="recipe.notes[0].length">
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout padding="16 16 128">
|
||||
<GridLayout
|
||||
columns="auto ,*"
|
||||
v-for="(note, index) in recipe.notes"
|
||||
:key="index"
|
||||
>
|
||||
<Label
|
||||
col="0"
|
||||
colSpan="2"
|
||||
class="view-note"
|
||||
:text="note"
|
||||
textWrap="true"
|
||||
/>
|
||||
<Label
|
||||
verticalAlignment="top"
|
||||
horizontalAlignment="center"
|
||||
class="view-count orkb"
|
||||
col="0"
|
||||
:text="index + 1"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</TabViewItem>
|
||||
<TabViewItem title="References" v-if="recipe.references[0].length">
|
||||
<ScrollView scrollBarIndicatorVisible="false">
|
||||
<StackLayout padding="16 16 128">
|
||||
<GridLayout
|
||||
columns="auto ,*"
|
||||
v-for="(reference, index) in recipe.references"
|
||||
:key="index"
|
||||
@tap="openURL($event, reference)"
|
||||
>
|
||||
<Label
|
||||
col="0"
|
||||
colSpan="2"
|
||||
class="view-reference"
|
||||
:text="reference"
|
||||
textWrap="true"
|
||||
/>
|
||||
<Label
|
||||
verticalAlignment="top"
|
||||
horizontalAlignment="center"
|
||||
class="orkb view-count"
|
||||
col="0"
|
||||
:text="index + 1"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</TabViewItem>
|
||||
</TabView>
|
||||
<GridLayout id="btnFabContainer" rows="*,88" columns="*,88">
|
||||
<Label
|
||||
row="1"
|
||||
col="1"
|
||||
class="bx btnFab"
|
||||
:text="icon.edit"
|
||||
androidElevation="8"
|
||||
@tap="editRecipe"
|
||||
/>
|
||||
</GridLayout>
|
||||
</AbsoluteLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { screen } from "tns-core-modules/platform"
|
||||
import * as utils from "tns-core-modules/utils/utils"
|
||||
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
export default {
|
||||
props: ["recipe"],
|
||||
data() {
|
||||
return {
|
||||
portionScale: 1,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "recipes"]),
|
||||
screenWidth() {
|
||||
return screen.mainScreen.widthDIPs
|
||||
},
|
||||
isPortionScalePositive() {
|
||||
return this.portionScale && !isNaN(this.portionScale)
|
||||
? parseFloat(this.portionScale)
|
||||
: 1
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
roundedQuantity(quantity, unit) {
|
||||
return Math.round(quantity * this.isPortionScalePositive * 100) / 100
|
||||
},
|
||||
// indexChange(args) {
|
||||
// let newIndex = args.value
|
||||
// console.log("Current tab index: " + newIndex)
|
||||
// },
|
||||
navigateBack() {
|
||||
this.$navigateBack()
|
||||
},
|
||||
editRecipe() {
|
||||
alert("edit recipe")
|
||||
},
|
||||
toggleFavorite() {
|
||||
this.$store.dispatch("toggleFavorite", this.recipes.indexOf(this.recipe))
|
||||
},
|
||||
getTime(time) {
|
||||
let t = time.split(":")
|
||||
let h = t[0]
|
||||
let m = t[1]
|
||||
return h !== "00" ? `${h}h ${m}m` : `${m}m`
|
||||
},
|
||||
openURL(args, url) {
|
||||
utils.openUrl(url)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
ActionBar {
|
||||
height: 128;
|
||||
}
|
||||
.actionBarContainer .bx {
|
||||
margin-top: 4;
|
||||
}
|
||||
</style>
|
35
app/main.js
35
app/main.js
|
@ -1,18 +1,29 @@
|
|||
// import VueDevtools from "nativescript-vue-devtools"
|
||||
import Vue from "nativescript-vue"
|
||||
import App from "./components/App"
|
||||
// import RadListView from "nativescript-ui-listview/vue"
|
||||
import RadListView from "nativescript-ui-listview/vue"
|
||||
|
||||
Vue.registerElement(
|
||||
"CheckBox",
|
||||
() => require("@nstudio/nativescript-checkbox").CheckBox,
|
||||
{
|
||||
model: {
|
||||
prop: "checked",
|
||||
event: "checkedChange",
|
||||
},
|
||||
}
|
||||
)
|
||||
// Vue.use('RadListView')
|
||||
|
||||
// Vue.registerElement(
|
||||
// "RadListView",
|
||||
// () => require("nativescript-ui-listview/vue").RadListView
|
||||
// )
|
||||
Vue.use(RadListView)
|
||||
|
||||
// Vue.use(VueDevtools)
|
||||
|
||||
// Vue.registerElement(
|
||||
// "CheckBox",
|
||||
// () => require("@nstudio/nativescript-checkbox").CheckBox,
|
||||
// {
|
||||
// model: {
|
||||
// prop: "checked",
|
||||
// event: "checkedChange",
|
||||
// },
|
||||
// }
|
||||
// )
|
||||
import DateTimePicker from "nativescript-datetimepicker/vue"
|
||||
Vue.use(DateTimePicker)
|
||||
// import VueDevtools from 'nativescript-vue-devtools'
|
||||
|
||||
// import { TNSFontIcon, fonticon } from 'nativescript-fonticon'
|
||||
|
|
237
app/store.js
237
app/store.js
|
@ -1,16 +1,237 @@
|
|||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import Vue from "vue"
|
||||
import Vuex from "vuex"
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
|
||||
recipes: [
|
||||
{
|
||||
imageSrc: null,
|
||||
title: "Mediterranean Salad",
|
||||
category: "Salads",
|
||||
prepTime: "00:10",
|
||||
cookTime: "00:20",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: "Cucumbers, Seeded And Sliced",
|
||||
quantity: 3,
|
||||
unit: null,
|
||||
},
|
||||
{
|
||||
item: "Crumbled Feta Cheese",
|
||||
quantity: 1.5,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Black Olives, Pitted And Sliced",
|
||||
quantity: 1,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Roma Tomatoes",
|
||||
quantity: 3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Oil Packed Sun Dried Tomatoes, Drained, Oil Reserved",
|
||||
quantity: 0.3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Onion, Sliced",
|
||||
quantity: 1.5,
|
||||
unit: null,
|
||||
},
|
||||
{
|
||||
item: "Cucumbers, Seeded And Sliced",
|
||||
quantity: 3,
|
||||
unit: null,
|
||||
},
|
||||
{
|
||||
item: "Crumbled Feta Cheese",
|
||||
quantity: 1.5,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Black Olives, Pitted And Sliced",
|
||||
quantity: 1,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Roma Tomatoes",
|
||||
quantity: 3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Oil Packed Sun Dried Tomatoes, Drained, Oil Reserved",
|
||||
quantity: 0.3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Onion, Sliced",
|
||||
quantity: 1.5,
|
||||
unit: null,
|
||||
},
|
||||
{
|
||||
item: "Cucumbers, Seeded And Sliced",
|
||||
quantity: 3,
|
||||
unit: null,
|
||||
},
|
||||
{
|
||||
item: "Crumbled Feta Cheese",
|
||||
quantity: 1.5,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Black Olives, Pitted And Sliced",
|
||||
quantity: 1,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Roma Tomatoes",
|
||||
quantity: 3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Diced Oil Packed Sun Dried Tomatoes, Drained, Oil Reserved",
|
||||
quantity: 0.3,
|
||||
unit: "cup",
|
||||
},
|
||||
{
|
||||
item: "Onion, Sliced",
|
||||
quantity: 1.5,
|
||||
unit: null,
|
||||
},
|
||||
],
|
||||
instructions: [
|
||||
"In a large salad bowl, toss together the cucumbers, feta cheese, olives, roma tomatoes, sun-dried tomatoes, 2 tablespoons reserved sun-dried tomato oil, and red onion.",
|
||||
"Chill until serving.",
|
||||
"In a large salad bowl, toss together the cucumbers, feta cheese, olives, roma tomatoes, sun-dried tomatoes, 2 tablespoons reserved sun-dried tomato oil, and red onion. In a large salad bowl, toss together the cucumbers, feta cheese, olives, roma tomatoes, sun-dried tomatoes, 2 tablespoons reserved sun-dried tomato oil, and red onion.",
|
||||
"Chill until serving.",
|
||||
"Chill until serving.",
|
||||
"In a large salad bowl, toss together the cucumbers, feta cheese, olives, roma tomatoes, sun-dried tomatoes, 2 tablespoons reserved sun-dried tomato oil, and red onion.",
|
||||
"Chill until serving.",
|
||||
"Chill until serving.",
|
||||
"Chill until serving.",
|
||||
"Chill until serving.",
|
||||
"Chill until serving.",
|
||||
],
|
||||
notes: [
|
||||
"Per Serving: 130.6 calories; protein 5.5g 11% DV; carbohydrates 9.3g 3% DV; fat 8.8g 14% DV; cholesterol 25mg 8% DV; sodium 486.4mg 20% DV.",
|
||||
"Per Serving: 130.6 calories; protein 5.5g 11% DV; carbohydrates 9.3g 3% DV; fat 8.8g 14% DV; cholesterol 25mg 8% DV; sodium 486.4mg 20% DV.",
|
||||
"Per Serving: 130.6 calories; protein 5.5g 11% DV; carbohydrates 9.3g 3% DV; fat 8.8g 14% DV; cholesterol 25mg 8% DV; sodium 486.4mg 20% DV.",
|
||||
],
|
||||
references: [
|
||||
"https://www.allrecipes.com/recipe/14403/mediterranean-greek-salad/",
|
||||
"https://www.allrecipes.com/recipe/14403/mediterranean-greek-salad/",
|
||||
"https://www.allrecipes.com/recipe/14403/mediterranean-greek-salad/",
|
||||
"https://www.allrecipes.com/recipe/14403/mediterranean-greek-salad/",
|
||||
],
|
||||
isFavorite: true,
|
||||
},
|
||||
{
|
||||
imageSrc: null,
|
||||
title: "Fresh Tomato Sauce",
|
||||
category: "Sauces",
|
||||
prepTime: "00:20",
|
||||
cookTime: "00:25",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: null,
|
||||
quantity: null,
|
||||
unit: null,
|
||||
},
|
||||
],
|
||||
instructions: [""],
|
||||
notes: [""],
|
||||
references: [""],
|
||||
isFavorite: true,
|
||||
},
|
||||
{
|
||||
imageSrc: null,
|
||||
title: "Creamy Mushroom Herb Pasta",
|
||||
category: "Lunch",
|
||||
prepTime: "00:45",
|
||||
cookTime: "00:25",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: null,
|
||||
quantity: null,
|
||||
unit: null,
|
||||
},
|
||||
],
|
||||
instructions: [""],
|
||||
notes: [""],
|
||||
references: [""],
|
||||
isFavorite: false,
|
||||
},
|
||||
{
|
||||
imageSrc: null,
|
||||
title: "Grilled Cheese Sandwich",
|
||||
category: "Lunch",
|
||||
prepTime: "00:20",
|
||||
cookTime: "00:10",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: null,
|
||||
quantity: null,
|
||||
unit: null,
|
||||
},
|
||||
],
|
||||
instructions: [""],
|
||||
notes: [""],
|
||||
references: [""],
|
||||
isFavorite: false,
|
||||
},
|
||||
],
|
||||
viewIsScrolled: false,
|
||||
icon: {
|
||||
home: "\ued99",
|
||||
heart: "\ued94",
|
||||
heartOutline: "\uead6",
|
||||
label: "\uedaf",
|
||||
cog: "\ued05",
|
||||
info: "\ueda7",
|
||||
menu: "\ueb2a",
|
||||
search: "\uebbc",
|
||||
sort: "\ueb2b",
|
||||
plus: "\ueb89",
|
||||
close: "\uec4e",
|
||||
dish: "\uea71",
|
||||
back: "\ue988",
|
||||
save: "\uee48",
|
||||
camera: "\uecc2",
|
||||
share: "\uee51",
|
||||
edit: "\uee17",
|
||||
theme: "\ued09",
|
||||
folder: "\ued7c",
|
||||
backup: "\uee48",
|
||||
restore: "\ueadc",
|
||||
link: "\ueb09",
|
||||
file: "\ued60",
|
||||
user: "\uee8e",
|
||||
trash: "\uee83",
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
|
||||
addRecipe(state, recipe) {
|
||||
state.recipes.push(recipe)
|
||||
},
|
||||
toggleFavorite(state, index) {
|
||||
state.recipes[index].isFavorite = !state.recipes[index].isFavorite
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
|
||||
}
|
||||
});
|
||||
addRecipe({ commit }, recipe) {
|
||||
commit("addRecipe", recipe)
|
||||
},
|
||||
toggleFavorite({ commit }, index) {
|
||||
commit("toggleFavorite", index)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
1064
package-lock.json
generated
1064
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -14,16 +14,25 @@
|
|||
"version": "6.5.0"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"run": "tns run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nativescript/theme": "^2.2.1",
|
||||
"@nstudio/nativescript-checkbox": "^1.0.0",
|
||||
"@vue/devtools": "^5.3.3",
|
||||
"nativescript-camera": "^4.5.0",
|
||||
"nativescript-datetimepicker": "^1.2.3",
|
||||
"nativescript-fonticon": "^2.0.2",
|
||||
"nativescript-mediafilepicker": "^4.0.0",
|
||||
"nativescript-menu": "^1.1.6",
|
||||
"nativescript-permissions": "^1.3.9",
|
||||
"nativescript-popup": "^1.5.0",
|
||||
"nativescript-ui-listview": "^9.0.2",
|
||||
"nativescript-socketio": "^3.3.1",
|
||||
"nativescript-toasty": "^3.0.0-alpha.2",
|
||||
"nativescript-ui-listview": "^8.2.0",
|
||||
"nativescript-ui-sidedrawer": "^8.0.1",
|
||||
"nativescript-vue": "^2.6.1",
|
||||
"nativescript-vue-devtools": "^1.4.0",
|
||||
"tns-core-modules": "^6.5.1",
|
||||
"vuex": "^3.3.0"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue