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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="ns_accent">#3d5afe</color>
|
<color name="ns_accent">#ff7043</color>
|
||||||
</resources>
|
</resources>
|
|
@ -1,7 +1,15 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="ns_primary">#F5F5F5</color>
|
<color name="ns_primary">
|
||||||
<color name="ns_primaryDark">#757575</color>
|
#FFFFFF
|
||||||
<color name="ns_accent">#33B5E5</color>
|
</color>
|
||||||
<color name="ns_blue">#272734</color>
|
<color name="ns_primaryDark">
|
||||||
|
#ff7043
|
||||||
|
</color>
|
||||||
|
<color name="ns_accent">
|
||||||
|
#ff7043
|
||||||
|
</color>
|
||||||
|
<color name="ns_blue">
|
||||||
|
#272734
|
||||||
|
</color>
|
||||||
</resources>
|
</resources>
|
|
@ -25,6 +25,7 @@
|
||||||
<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>
|
||||||
|
<item name="android:forceDarkAllowed">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme" parent="AppThemeBase">
|
<style name="AppTheme" parent="AppThemeBase">
|
||||||
|
|
360
app/app.scss
360
app/app.scss
|
@ -1,22 +1,370 @@
|
||||||
// NativeScript core theme
|
// NativeScript core theme
|
||||||
// @see https://docs.nativescript.org/ui/theme
|
// @see https://docs.nativescript.org/ui/theme
|
||||||
@import '~@nativescript/theme/core';
|
@import "~@nativescript/theme/core";
|
||||||
|
|
||||||
// Override variables here
|
// 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
|
// Global SCSS styling
|
||||||
// @see https://docs.nativescript.org/ui/styling
|
// @see https://docs.nativescript.org/ui/styling
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
font-family: 'Orkney-Regular';
|
font-family: "Orkney-Regular";
|
||||||
}
|
}
|
||||||
.orkm {
|
.orkm {
|
||||||
font-family: 'Orkney-Medium';
|
font-family: "Orkney-Medium";
|
||||||
}
|
}
|
||||||
.orkb {
|
.orkb {
|
||||||
font-family: 'Orkney-Bold';
|
font-family: "Orkney-Bold";
|
||||||
}
|
}
|
||||||
.bx {
|
.bx {
|
||||||
font-family: 'boxicons';
|
font-family: "boxicons";
|
||||||
font-size: 24;
|
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>
|
<template>
|
||||||
<StackLayout class="main-container">
|
<Page>
|
||||||
<StackLayout orientation="horizontal" class="app-icon-container">
|
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||||
<Image src="res://icon" class="app-icon" stretch="fill" />
|
<!-- Settings Actionbar -->
|
||||||
<Label
|
<GridLayout rows="*" columns="auto, *" class="actionBarContainer">
|
||||||
text="EnRecipes"
|
<Label
|
||||||
verticalAlignment="center"
|
class="bx leftAction"
|
||||||
class="app-name orkb"
|
:text="icon.menu"
|
||||||
/>
|
automationText="Menu"
|
||||||
</StackLayout>
|
@tap="showDrawer"
|
||||||
<StackLayout orientation="horizontal" class="icon-option">
|
col="0"
|
||||||
<Label verticalAlignment="center" class="bx" :text="icon.info" />
|
/>
|
||||||
<StackLayout>
|
<Label class="title orkm" :text="title" col="1" />
|
||||||
<Label text="Version" class="option-title" />
|
</GridLayout>
|
||||||
<Label text="1.0.0" class="option-info" textWrap="true" />
|
</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>
|
</ScrollView>
|
||||||
<StackLayout
|
</Page>
|
||||||
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>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as utils from "tns-core-modules/utils/utils"
|
import * as utils from "tns-core-modules/utils/utils"
|
||||||
|
import { mapState, mapActions } from "vuex"
|
||||||
export default {
|
export default {
|
||||||
props: ["highlight"],
|
props: ["highlight", "viewIsScrolled", "showDrawer", "title"],
|
||||||
data() {
|
computed: {
|
||||||
return {
|
...mapState(["icon"]),
|
||||||
icon: {
|
|
||||||
info: "\ueda7",
|
|
||||||
link: "\ueb09",
|
|
||||||
file: "\ued60",
|
|
||||||
user: "\uee8e",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openURL(args, url) {
|
openURL(args, url) {
|
||||||
|
@ -80,32 +95,3 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</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
|
<RadSideDrawer
|
||||||
ref="drawer"
|
ref="drawer"
|
||||||
allowEdgeSwipe="true"
|
allowEdgeSwipe="true"
|
||||||
drawerContentSize="300"
|
drawerContentSize="270"
|
||||||
showOverNavigation="true"
|
showOverNavigation="true"
|
||||||
gesturesEnabled="true"
|
gesturesEnabled="true"
|
||||||
drawerTransition="RevealTransition"
|
drawerTransition="RevealTransition"
|
||||||
|
@ -12,55 +12,59 @@
|
||||||
rows="auto, auto, *, auto, auto"
|
rows="auto, auto, *, auto, auto"
|
||||||
columns="*"
|
columns="*"
|
||||||
~drawerContent
|
~drawerContent
|
||||||
backgroundColor="#ffffff"
|
|
||||||
padding="8"
|
padding="8"
|
||||||
|
class="sd"
|
||||||
>
|
>
|
||||||
<StackLayout row="0">
|
<StackLayout row="0">
|
||||||
<StackLayout
|
<StackLayout
|
||||||
@tap="navigateTo('EnRecipes', true, false)"
|
@tap="localNavigation('EnRecipes', 'EnRecipes', true, false)"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="drawer-item orkm"
|
class="sd-item orkm"
|
||||||
:class="{
|
:class="{
|
||||||
'selected-drawer-item':
|
'selected-sd-item':
|
||||||
currentComponent == 'EnRecipes' &&
|
currentComponent === 'EnRecipes' &&
|
||||||
!filterFavorites &&
|
!filterFavorites &&
|
||||||
!selectedCategory,
|
!selectedCategory,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<Label class="bx" :text="icon.home" margin="0 24 0 0" />
|
<Label class="bx" :text="icon.home" margin="0 24 0 0" />
|
||||||
<Label text="Home" />
|
<Label verticalAlignment="center" text="Home" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout
|
<StackLayout
|
||||||
@tap="navigateTo('Favorites', true, false)"
|
@tap="localNavigation('Favorites', 'Favorites', true, false)"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="drawer-item orkm"
|
class="sd-item orkm"
|
||||||
:class="{ 'selected-drawer-item': filterFavorites }"
|
:class="{
|
||||||
|
'selected-sd-item':
|
||||||
|
currentComponent === 'EnRecipes' && filterFavorites,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<Label class="bx" :text="icon.heart" margin="0 24 0 0" />
|
<Label class="bx" :text="icon.heart" margin="0 24 0 0" />
|
||||||
<Label text="Favorites" />
|
<Label verticalAlignment="center" text="Favorites" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout
|
<StackLayout
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
row="1"
|
row="1"
|
||||||
class="drawer-group-header orkr"
|
class="sd-group-header orkr"
|
||||||
>
|
>
|
||||||
<Label text="Categories" />
|
<Label text="Categories" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<ScrollView row="2">
|
<ScrollView row="2" scrollBarIndicatorVisible="false">
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<StackLayout
|
<StackLayout
|
||||||
@tap="navigateTo(item, false, true)"
|
@tap="localNavigation(item, item, false, true)"
|
||||||
v-for="(item, index) in categories"
|
v-for="(item, index) in categories"
|
||||||
:key="index"
|
:key="index"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="drawer-item orkm"
|
class="sd-item orkm"
|
||||||
:class="{
|
: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 class="bx" :text="icon.label" margin="0 24 0 0" />
|
||||||
<Label :text="item" />
|
<Label verticalAlignment="center" :text="item" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -68,102 +72,30 @@
|
||||||
<StackLayout row="3" class="hr m-10"></StackLayout>
|
<StackLayout row="3" class="hr m-10"></StackLayout>
|
||||||
<StackLayout row="4">
|
<StackLayout row="4">
|
||||||
<StackLayout
|
<StackLayout
|
||||||
@tap="navigateTo(item.title, false, false)"
|
@tap="navigateTo(item.component, item.title)"
|
||||||
v-for="(item, index) in bottommenu"
|
v-for="(item, index) in bottommenu"
|
||||||
:key="index"
|
:key="index"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
class="drawer-item orkm"
|
class="sd-item orkm"
|
||||||
:class="{
|
: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 class="bx" :text="icon[item.icon]" margin="0 24 0 0" />
|
||||||
<Label :text="item.title" />
|
<Label verticalAlignment="center" :text="item.title" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
<GridLayout ~mainContent rows="*" columns="*">
|
<GridLayout ~mainContent rows="*" columns="*">
|
||||||
<Frame ref="page">
|
<Frame id="main-frame">
|
||||||
<Page>
|
<!-- Home -->
|
||||||
<ActionBar margin="0" flat="true" row="0" col="0">
|
<EnRecipes
|
||||||
<GridLayout v-if="showSearch" rows="auto" columns="auto, *">
|
:selectedCategory="selectedCategory"
|
||||||
<Label
|
:filterFavorites="filterFavorites"
|
||||||
color="#000000"
|
:title="title"
|
||||||
class="bx"
|
:showDrawer="showDrawer"
|
||||||
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>
|
</Frame>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</RadSideDrawer>
|
</RadSideDrawer>
|
||||||
|
@ -174,14 +106,12 @@
|
||||||
import * as utils from "tns-core-modules/utils/utils"
|
import * as utils from "tns-core-modules/utils/utils"
|
||||||
import { isAndroid } from "tns-core-modules/platform"
|
import { isAndroid } from "tns-core-modules/platform"
|
||||||
import * as application from "tns-core-modules/application"
|
import * as application from "tns-core-modules/application"
|
||||||
import { Label } from "tns-core-modules/ui/label"
|
|
||||||
|
|
||||||
import { Menu } from "nativescript-menu"
|
import EnRecipes from "./EnRecipes.vue"
|
||||||
import { Popup } from "nativescript-popup"
|
import Settings from "./Settings.vue"
|
||||||
|
import About from "./About.vue"
|
||||||
|
|
||||||
import EnRecipes from "./EnRecipes"
|
import { mapState } from "vuex"
|
||||||
import Settings from "./Settings"
|
|
||||||
import About from "./About"
|
|
||||||
|
|
||||||
let page
|
let page
|
||||||
export default {
|
export default {
|
||||||
|
@ -193,98 +123,27 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: "EnRecipes",
|
title: "EnRecipes",
|
||||||
currentComponent: "EnRecipes",
|
|
||||||
componentsArray: ["EnRecipes", "Settings", "About"],
|
|
||||||
selectedCategory: null,
|
selectedCategory: null,
|
||||||
filterFavorites: false,
|
filterFavorites: false,
|
||||||
searchQuery: "",
|
searchQuery: "",
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
icon: {
|
currentComponent: "EnRecipes",
|
||||||
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",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
bottommenu: [
|
bottommenu: [
|
||||||
{
|
{
|
||||||
title: "Settings",
|
title: "Settings",
|
||||||
icon: "\ued05",
|
component: Settings,
|
||||||
|
icon: "cog",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "About",
|
title: "About",
|
||||||
icon: "\ueda7",
|
component: About,
|
||||||
},
|
icon: "info",
|
||||||
],
|
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState(["recipes", "icon"]),
|
||||||
categories() {
|
categories() {
|
||||||
let arr = this.recipes.map((e) => {
|
let arr = this.recipes.map((e) => {
|
||||||
return e.category
|
return e.category
|
||||||
|
@ -294,188 +153,117 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
highlight(args) {
|
highlight(args) {
|
||||||
console.log(args.object.className)
|
|
||||||
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
|
args.object.className = temp
|
||||||
}, 100)
|
}, 100)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Navigation
|
||||||
setSelectedCategory(e) {
|
setSelectedCategory(e) {
|
||||||
this.selectedCategory = e.item
|
this.selectedCategory = e.item
|
||||||
console.log(e)
|
|
||||||
this.closeDrawer()
|
this.closeDrawer()
|
||||||
},
|
},
|
||||||
// SearchBar
|
|
||||||
closeSearch() {
|
|
||||||
this.searchQuery = ""
|
|
||||||
this.showSearch = false
|
|
||||||
utils.ad.dismissSoftInput()
|
|
||||||
},
|
|
||||||
searchBarLoaded() {
|
|
||||||
application.android.on(
|
|
||||||
application.AndroidApplication.activityBackPressedEvent,
|
|
||||||
this.backEvent
|
|
||||||
)
|
|
||||||
},
|
|
||||||
removeBackEvent() {
|
removeBackEvent() {
|
||||||
application.android.off(
|
application.android.off(
|
||||||
application.AndroidApplication.activityBackPressedEvent,
|
application.AndroidApplication.activityBackPressedEvent,
|
||||||
this.backEvent
|
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) {
|
backEvent(args) {
|
||||||
if (this.showSearch) {
|
args.cancel = true
|
||||||
args.cancel = true
|
if (this.$refs.drawer.nativeView.getIsOpen()) this.closeDrawer()
|
||||||
this.closeSearch()
|
else if (this.currentComponent !== "EnRecipes") {
|
||||||
this.removeBackEvent()
|
this.$navigateBack({ frame: "main-frame" })
|
||||||
} else if (
|
|
||||||
this.currentComponent !== "EnRecipes" ||
|
|
||||||
this.filterFavorites
|
|
||||||
) {
|
|
||||||
args.cancel = true
|
|
||||||
console.log("backEvent")
|
|
||||||
this.currentComponent = "EnRecipes"
|
this.currentComponent = "EnRecipes"
|
||||||
this.filterFavorites = false
|
} else if (this.filterFavorites || this.selectedCategory) {
|
||||||
this.title = "EnRecipes"
|
this.title = "EnRecipes"
|
||||||
|
this.filterFavorites = false
|
||||||
|
this.selectedCategory = null
|
||||||
this.removeBackEvent()
|
this.removeBackEvent()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navigateBackToHome() {
|
localNavigation(to, title, filter, filterCategory) {
|
||||||
|
// navigateBackToHome
|
||||||
application.android.on(
|
application.android.on(
|
||||||
application.AndroidApplication.activityBackPressedEvent,
|
application.AndroidApplication.activityBackPressedEvent,
|
||||||
this.backEvent
|
this.backEvent
|
||||||
)
|
)
|
||||||
console.log("navigateBackToHome")
|
if (this.currentComponent !== "EnRecipes") {
|
||||||
},
|
this.currentComponent = "EnRecipes"
|
||||||
navigateTo(to, filter, filterCategory) {
|
this.$navigateBack({ frame: "main-frame" })
|
||||||
this.navigateBackToHome()
|
}
|
||||||
this.filterFavorites = false
|
this.filterFavorites = false
|
||||||
this.selectedCategory = null
|
this.selectedCategory = null
|
||||||
this.title = to
|
this.title = title
|
||||||
|
console.log(title)
|
||||||
if (filter) {
|
if (filter) {
|
||||||
this.currentComponent = "EnRecipes"
|
if (to === "Favorites") this.filterFavorites = true
|
||||||
if (to === "Favorites") {
|
} else if (filterCategory) this.selectedCategory = to
|
||||||
this.filterFavorites = true
|
if (!this.filterFavorites && !this.selectedCategory)
|
||||||
}
|
this.removeBackEvent()
|
||||||
} else if (filterCategory) {
|
|
||||||
this.currentComponent = "EnRecipes"
|
|
||||||
this.selectedCategory = to
|
|
||||||
} else {
|
|
||||||
this.currentComponent = to
|
|
||||||
}
|
|
||||||
this.closeDrawer()
|
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() {
|
closeDrawer() {
|
||||||
this.$refs.drawer.nativeView.toggleDrawerState()
|
this.$refs.drawer.nativeView.closeDrawer()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
ActionBar {
|
.noResults {
|
||||||
background: white;
|
width: 100%;
|
||||||
color: #000000;
|
padding: 16;
|
||||||
height: 64;
|
|
||||||
.bx {
|
|
||||||
background: white;
|
|
||||||
padding: 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SearchBar {
|
|
||||||
background: #fff;
|
|
||||||
color: #333333;
|
|
||||||
font-size: 16;
|
font-size: 16;
|
||||||
margin-top: 4;
|
line-height: 8;
|
||||||
}
|
}
|
||||||
.hr {
|
.swipe-item {
|
||||||
border-color: #eeeeee;
|
margin: 0 8;
|
||||||
}
|
background: #ff7043;
|
||||||
.title {
|
color: #fff;
|
||||||
text-align: left;
|
height: 128;
|
||||||
padding-left: 8;
|
border-radius: 6;
|
||||||
font-size: 20;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 {
|
#btnFabContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
#btnFab {
|
.btnFab {
|
||||||
width: 56;
|
width: 56;
|
||||||
height: 56;
|
height: 56;
|
||||||
padding: 16;
|
padding: 16;
|
||||||
background-color: #ff7043;
|
background-color: #ff7043;
|
||||||
color: #000;
|
color: #fff;
|
||||||
border-radius: 28;
|
border-radius: 28;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
// prettier-ignore
|
||||||
|
Button {
|
||||||
|
color: #ff7043;
|
||||||
|
}
|
||||||
</style>
|
</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>
|
<template>
|
||||||
<AbsoluteLayout>
|
<Page>
|
||||||
<ScrollView scrollBarIndicatorVisible="false" width="100%" height="100%">
|
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||||
<StackLayout v-if="filteredRecipes.length">
|
<!-- Search Actionbar -->
|
||||||
<!-- <RadListView
|
<GridLayout
|
||||||
ref="listView"
|
v-if="showSearch"
|
||||||
for="item in filteredRecipes"
|
rows="*"
|
||||||
swipeActions="true"
|
columns="auto, *"
|
||||||
@itemSwipeProgressStarted="onSwipeStarted"
|
class="actionBarContainer"
|
||||||
>
|
>
|
||||||
<v-template>
|
<Label
|
||||||
<StackLayout class="item p-t-10" orientation="vertical">
|
class="bx leftAction"
|
||||||
<Label :text="item.name" class="nameLabel"></Label>
|
:text="icon.back"
|
||||||
<Label :text="item.description" class="descriptionLabel"></Label>
|
automationText="Back"
|
||||||
</StackLayout>
|
col="0"
|
||||||
</v-template>
|
@tap="closeSearch"
|
||||||
<v-template name="itemswipe">
|
/>
|
||||||
<GridLayout columns="auto, *, auto" backgroundColor="White">
|
<SearchBar
|
||||||
<StackLayout
|
@loaded="searchBarLoaded"
|
||||||
id="mark-view"
|
id="searchField"
|
||||||
col="0"
|
col="1"
|
||||||
class="swipe-item left"
|
hint="Search"
|
||||||
orientation="horizontal"
|
textFieldHintColor="#bdbdbd"
|
||||||
@tap="onLeftSwipeClick"
|
v-model="searchQuery"
|
||||||
>
|
/>
|
||||||
<Label
|
</GridLayout>
|
||||||
text="mark"
|
<!-- Home Actionbar -->
|
||||||
verticalAlignment="center"
|
<GridLayout
|
||||||
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
|
|
||||||
v-else
|
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"
|
horizontalAlignment="center"
|
||||||
:text="
|
: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"
|
textAlignment="center"
|
||||||
textWrap="true"
|
textWrap="true"
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
|
||||||
<GridLayout id="btnFabContainer" rows="*,88" columns="*,88">
|
|
||||||
<Label
|
<Label
|
||||||
row="1"
|
v-if="!filteredRecipes.length && filterFavorites && !searchQuery"
|
||||||
col="1"
|
class="noResults"
|
||||||
id="btnFab"
|
horizontalAlignment="center"
|
||||||
class="bx"
|
text="Your favorite recipes will be listed here."
|
||||||
:text="icon.plus"
|
textAlignment="center"
|
||||||
androidElevation="8"
|
textWrap="true"
|
||||||
@tap="FabTapped"
|
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
<GridLayout
|
||||||
</AbsoluteLayout>
|
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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import * as utils from "tns-core-modules/utils/utils"
|
||||||
props: ["searchQuery", "filterFavorites", "recipes", "selectedCategory"],
|
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() {
|
data() {
|
||||||
return {
|
return {
|
||||||
icon: {
|
searchQuery: "",
|
||||||
plus: "\ueb89",
|
showSearch: false,
|
||||||
},
|
viewIsScrolled: false,
|
||||||
|
leftAction: false,
|
||||||
|
rightAction: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState(["recipes", "icon"]),
|
||||||
recipesByCategory() {
|
recipesByCategory() {
|
||||||
return this.recipes.reduce((acc, e) => {
|
return this.recipes.reduce((acc, e) => {
|
||||||
acc[e.category] = [...(acc[e.category] || []), e]
|
acc[e.category] = [...(acc[e.category] || []), e]
|
||||||
|
@ -130,12 +207,114 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
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() {
|
FabTapped() {
|
||||||
alert("fab tapped")
|
alert("fab tapped")
|
||||||
},
|
},
|
||||||
},
|
addRecipe() {
|
||||||
mounted() {
|
this.$navigateTo(EditRecipe, {
|
||||||
// console.log(this.recipesByCategory)
|
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>
|
</script>
|
||||||
|
|
|
@ -1,79 +1,105 @@
|
||||||
<template>
|
<template>
|
||||||
<StackLayout class="main-container">
|
<Page>
|
||||||
<Label text="Interface" class="group-header" />
|
<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">
|
<StackLayout
|
||||||
<Label verticalAlignment="center" class="bx" :text="icon.theme" />
|
orientation="horizontal"
|
||||||
<StackLayout>
|
class="option"
|
||||||
<Label text="Theme" class="option-title" />
|
@tap="selectThemes"
|
||||||
<Label :text="themeName" class="option-info" textWrap="true" />
|
>
|
||||||
|
<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>
|
</ScrollView>
|
||||||
|
</Page>
|
||||||
<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>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Menu } from "nativescript-menu"
|
import { Menu } from "nativescript-menu"
|
||||||
import * as permissions from "nativescript-permissions"
|
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 {
|
export default {
|
||||||
props: ["highlight"],
|
props: ["highlight", "viewIsScrolled", "showDrawer", "title"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
icon: {
|
interface: {
|
||||||
theme: "\ued09",
|
theme: {
|
||||||
folder: "\ued7c",
|
title: "Theme",
|
||||||
backup: "\uee48",
|
subTitle: "Light",
|
||||||
restore: "\ueadc",
|
icon: "\ued09",
|
||||||
},
|
},
|
||||||
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",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
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",
|
themeName: "Light",
|
||||||
themesArray: ["Light", "Dark", "Black"],
|
themesArray: ["Light", "Dark"],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(["icon"]),
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectThemes(args) {
|
selectThemes(args) {
|
||||||
this.highlight(args)
|
this.highlight(args)
|
||||||
|
@ -83,10 +109,10 @@ export default {
|
||||||
actions: this.themesArray,
|
actions: this.themesArray,
|
||||||
})
|
})
|
||||||
.then((action) => {
|
.then((action) => {
|
||||||
if (this.themesArray.includes(action.title)) {
|
this.interface.theme.subTitle = this.themeName = action.title
|
||||||
this.options.interface[0].subTitle = this.themeName = action.title
|
console.log(this.themeName)
|
||||||
}
|
setString("application-theme", action.title)
|
||||||
// alert(action.id + " - " + action.title)
|
Theme.toggleMode()
|
||||||
})
|
})
|
||||||
.catch(console.log)
|
.catch(console.log)
|
||||||
},
|
},
|
||||||
|
@ -127,35 +153,11 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.interface.theme.subTitle = this.themeName = getString(
|
||||||
|
"application-theme",
|
||||||
|
"Light"
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</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 Vue from "nativescript-vue"
|
||||||
import App from "./components/App"
|
import App from "./components/App"
|
||||||
// import RadListView from "nativescript-ui-listview/vue"
|
import RadListView from "nativescript-ui-listview/vue"
|
||||||
|
|
||||||
Vue.registerElement(
|
|
||||||
"CheckBox",
|
// Vue.registerElement(
|
||||||
() => require("@nstudio/nativescript-checkbox").CheckBox,
|
// "RadListView",
|
||||||
{
|
// () => require("nativescript-ui-listview/vue").RadListView
|
||||||
model: {
|
// )
|
||||||
prop: "checked",
|
Vue.use(RadListView)
|
||||||
event: "checkedChange",
|
|
||||||
},
|
// Vue.use(VueDevtools)
|
||||||
}
|
|
||||||
)
|
// Vue.registerElement(
|
||||||
// Vue.use('RadListView')
|
// "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 VueDevtools from 'nativescript-vue-devtools'
|
||||||
|
|
||||||
// import { TNSFontIcon, fonticon } from 'nativescript-fonticon'
|
// import { TNSFontIcon, fonticon } from 'nativescript-fonticon'
|
||||||
|
|
237
app/store.js
237
app/store.js
|
@ -1,16 +1,237 @@
|
||||||
import Vue from 'vue';
|
import Vue from "vue"
|
||||||
import Vuex from 'vuex';
|
import Vuex from "vuex"
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex)
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state: {
|
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: {
|
mutations: {
|
||||||
|
addRecipe(state, recipe) {
|
||||||
|
state.recipes.push(recipe)
|
||||||
|
},
|
||||||
|
toggleFavorite(state, index) {
|
||||||
|
state.recipes[index].isFavorite = !state.recipes[index].isFavorite
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
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"
|
"version": "6.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"scripts": {
|
||||||
|
"run": "tns run"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nativescript/theme": "^2.2.1",
|
"@nativescript/theme": "^2.2.1",
|
||||||
"@nstudio/nativescript-checkbox": "^1.0.0",
|
"@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-fonticon": "^2.0.2",
|
||||||
|
"nativescript-mediafilepicker": "^4.0.0",
|
||||||
"nativescript-menu": "^1.1.6",
|
"nativescript-menu": "^1.1.6",
|
||||||
"nativescript-permissions": "^1.3.9",
|
"nativescript-permissions": "^1.3.9",
|
||||||
"nativescript-popup": "^1.5.0",
|
"nativescript-socketio": "^3.3.1",
|
||||||
"nativescript-ui-listview": "^9.0.2",
|
"nativescript-toasty": "^3.0.0-alpha.2",
|
||||||
|
"nativescript-ui-listview": "^8.2.0",
|
||||||
"nativescript-ui-sidedrawer": "^8.0.1",
|
"nativescript-ui-sidedrawer": "^8.0.1",
|
||||||
"nativescript-vue": "^2.6.1",
|
"nativescript-vue": "^2.6.1",
|
||||||
|
"nativescript-vue-devtools": "^1.4.0",
|
||||||
"tns-core-modules": "^6.5.1",
|
"tns-core-modules": "^6.5.1",
|
||||||
"vuex": "^3.3.0"
|
"vuex": "^3.3.0"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue