added mealPlanner

This commit is contained in:
Vishnu Raghav B 2020-11-23 15:19:58 +05:30
parent 4621821597
commit ef215c7321
81 changed files with 760 additions and 965 deletions

View file

@ -10,7 +10,7 @@
<uses-permission android:name="android.permission.INTERNET" tools:node="remove" /> <uses-permission android:name="android.permission.INTERNET" tools:node="remove" />
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" /> <uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" />
<application android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:hardwareAccelerated="true" android:largeHeap="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true"> <application android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:hardwareAccelerated="true" android:largeHeap="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true">
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:screenOrientation="portrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize"> <activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:screenOrientation="userPortrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize">
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" /> <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 687 B

View file

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 567 B

View file

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 339 B

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

View file

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

View file

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 519 B

View file

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 390 B

View file

Before

Width:  |  Height:  |  Size: 336 B

After

Width:  |  Height:  |  Size: 336 B

View file

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 229 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

View file

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View file

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 312 B

View file

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

View file

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 324 B

View file

Before

Width:  |  Height:  |  Size: 198 B

After

Width:  |  Height:  |  Size: 198 B

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 300 B

View file

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 161 B

View file

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 341 B

View file

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 626 B

View file

Before

Width:  |  Height:  |  Size: 547 B

After

Width:  |  Height:  |  Size: 547 B

View file

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

View file

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

Before

Width:  |  Height:  |  Size: 437 B

After

Width:  |  Height:  |  Size: 437 B

View file

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View file

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 550 B

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 969 B

After

Width:  |  Height:  |  Size: 969 B

View file

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 797 B

View file

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View file

Before

Width:  |  Height:  |  Size: 930 B

After

Width:  |  Height:  |  Size: 930 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 818 B

View file

Before

Width:  |  Height:  |  Size: 449 B

After

Width:  |  Height:  |  Size: 449 B

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 697 B

View file

Before

Width:  |  Height:  |  Size: 171 B

After

Width:  |  Height:  |  Size: 171 B

View file

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 928 B

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ns_primary"> <color name="ns_primary">
#fafafa #ff5200
</color> </color>
<color name="ns_primaryDark"> <color name="ns_primaryDark">
#ff5200 #ff5200

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ns_primary"> <color name="ns_primary">
#f1f3f5 #ff5200
</color> </color>
<color name="ns_primaryDark"> <color name="ns_primaryDark">
#ff5200 #ff5200

View file

@ -57,9 +57,6 @@
<item name="contentInsetEnd"> <item name="contentInsetEnd">
0dp 0dp
</item> </item>
<item name="android:divider">
#ff0000
</item>
<item name="android:background"> <item name="android:background">
@color/ns_primary @color/ns_primary
</item> </item>
@ -77,8 +74,10 @@
<item name="searchHintIcon"> <item name="searchHintIcon">
@null @null
</item> </item>
<!-- <item name="closeIcon"> <!--
<item name="closeIcon">
@null @null
</item> --> </item>
-->
</style> </style>
</resources> </resources>

View file

@ -6,7 +6,7 @@ $gray1: #f1f3f5;
$gray2: #e9ecef; $gray2: #e9ecef;
$gray3: #dee2e6; $gray3: #dee2e6;
$gray4: #ced4da; $gray4: #ced4da;
$gray5: #adb5bd; // rgb(173,181,189) $gray5: #adb5bd;
$gray6: #868e96; $gray6: #868e96;
$gray7: #495057; $gray7: #495057;
$gray8: #343a40; $gray8: #343a40;
@ -255,7 +255,7 @@ ActionBar {
} }
// prettier-ignore // prettier-ignore
Label { Label {
padding: 0 16 0 0; padding: 2 16 0 0;
font-size: 16; font-size: 16;
vertical-alignment: center; vertical-alignment: center;
&.bx{ &.bx{
@ -544,14 +544,13 @@ TextField.combinationToken {
} }
// ----------------------------- // -----------------------------
// MEAL PLANNER // MEAL PLANNER
.mealPlanner { .dayPlan {
padding: 16 16 128; padding: 0;
width: 100%; width: 100%;
.dayContainer { .plansContainer {
padding: 8 0; padding: 8 4;
color: $gray9; color: $gray9;
&.breakfast { &.breakfast {
border-radius: 4 4 0 0;
background: $breakfast; background: $breakfast;
} }
&.lunch { &.lunch {
@ -561,17 +560,16 @@ TextField.combinationToken {
background: $dinner; background: $dinner;
} }
&.snacks { &.snacks {
border-radius: 0 0 4 4;
background: $snacks; background: $snacks;
} }
.periodLabel { .periodLabel {
text-transform: uppercase; text-transform: uppercase;
vertical-alignment: center; vertical-alignment: center;
font-size: 16; font-size: 14;
padding: 0 0 0 16; padding: 0 0 0 16;
} }
.recipes { .recipes {
margin: 8 8 0; margin: 4 8 4;
.recipeTitle { .recipeTitle {
font-size: 14; font-size: 14;
padding: 6 8; padding: 6 8;
@ -591,6 +589,7 @@ TextField.combinationToken {
// ----------------------------- // -----------------------------
// DIALOGS // DIALOGS
.dialogContainer { .dialogContainer {
max-width: 480;
width: 100%; width: 100%;
color: $gray9; color: $gray9;
background: $gray1; background: $gray1;
@ -600,6 +599,7 @@ TextField.combinationToken {
background: $gray9; background: $gray9;
} }
.dialogTitle { .dialogTitle {
line-height: 6;
padding: 24 24 16; padding: 24 24 16;
font-size: 20; font-size: 20;
} }

View file

@ -13,7 +13,7 @@
<Label class="title orkm" text="About" col="1" /> <Label class="title orkm" text="About" col="1" />
</GridLayout> </GridLayout>
</ActionBar> </ActionBar>
<ScrollView scrollBarIndicatorVisible="false" @scroll="onScroll"> <ScrollView scrollBarIndicatorVisible="true" @scroll="onScroll">
<StackLayout class="main-container"> <StackLayout class="main-container">
<StackLayout <StackLayout
horizontalAlignment="center" horizontalAlignment="center"
@ -64,7 +64,7 @@
@tap="openURL('https://www.vishnuraghav.com')" @tap="openURL('https://www.vishnuraghav.com')"
/> />
<Label col="0" class="bx" :text="icon.user" /> <Label col="0" class="bx" :text="icon.user" />
<Label verticalAlignment="center" col="1" text="Vishnu Raghav" /> <Label verticalAlignment="center" col="1" text="Vishnu Raghav B" />
</GridLayout> </GridLayout>
<GridLayout columns="auto, *" class="option"> <GridLayout columns="auto, *" class="option">
<MDRipple <MDRipple
@ -90,8 +90,10 @@
<script> <script>
import { Application, Utils } from "@nativescript/core" import { Application, Utils } from "@nativescript/core"
import { mapActions, mapState } from "vuex" import { mapActions, mapState } from "vuex"
import * as utils from "~/shared/utils"
export default { export default {
props: ["showDrawer", "title"],
computed: { computed: {
...mapState(["icon", "currentComponent"]), ...mapState(["icon", "currentComponent"]),
getVersion() { getVersion() {
@ -112,6 +114,9 @@ export default {
this.setCurrentComponentAction("About") this.setCurrentComponentAction("About")
}, },
// HELPERS // HELPERS
showDrawer() {
utils.showDrawer()
},
onScroll(args) { onScroll(args) {
args.scrollY args.scrollY
? (this.viewIsScrolled = true) ? (this.viewIsScrolled = true)

View file

@ -1,14 +1,16 @@
<template> <template>
<Page <Page
@loaded="onPageLoad" @loaded="onPageLoad"
@unloaded="onPageUnload"
actionBarHidden="true" actionBarHidden="true"
:androidStatusBarBackground="appTheme == 'Light' ? '#f1f3f5' : '#212529'" :androidStatusBarBackground="appTheme == 'Light' ? '#f1f3f5' : '#212529'"
> >
<RadSideDrawer <RadSideDrawer
ref="drawer"
allowEdgeSwipe="true" allowEdgeSwipe="true"
drawerContentSize="270"
showOverNavigation="true" showOverNavigation="true"
ref="drawer"
id="sideDrawer"
drawerContentSize="270"
gesturesEnabled="true" gesturesEnabled="true"
drawerTransition="SlideInOnTopTransition" drawerTransition="SlideInOnTopTransition"
> >
@ -44,8 +46,9 @@
<MDRipple <MDRipple
row="0" row="0"
colSpan="3" colSpan="3"
@tap="navigateTo(mealPlanner, true, false)" @tap="navigateTo(MealPlanner, true, false)"
/> />
<Label col="0" row="0" class="bx" :text="icon.calendar" /> <Label col="0" row="0" class="bx" :text="icon.calendar" />
<Label col="2" row="0" text="Meal Planner" /> <Label col="2" row="0" text="Meal Planner" />
</GridLayout> </GridLayout>
@ -120,21 +123,18 @@
</GridLayout> </GridLayout>
</StackLayout> </StackLayout>
</GridLayout> </GridLayout>
<GridLayout ~mainContent rows="*" columns="*"> <Frame ~mainContent id="main-frame">
<Frame row="0" col="0" ref="mainFrame" id="main-frame">
<!-- Home --> <!-- Home -->
<EnRecipes <EnRecipes
ref="enrecipes" ref="enrecipes"
:filterFavorites="filterFavorites" :filterFavorites="filterFavorites"
:filterTrylater="filterTrylater" :filterTrylater="filterTrylater"
:selectedCategory="selectedCategory" :selectedCategory="selectedCategory"
:showDrawer="showDrawer" :closeDrawer="closeDrawer"
:hijackGlobalBackEvent="hijackGlobalBackEvent" :hijackGlobalBackEvent="hijackGlobalBackEvent"
:releaseGlobalBackEvent="releaseGlobalBackEvent" :releaseGlobalBackEvent="releaseGlobalBackEvent"
:openAppSettingsPage="openAppSettingsPage"
/> />
</Frame> </Frame>
</GridLayout>
</RadSideDrawer> </RadSideDrawer>
</Page> </Page>
</template> </template>
@ -153,22 +153,20 @@ import * as Toast from "nativescript-toast"
import * as application from "tns-core-modules/application" import * as application from "tns-core-modules/application"
import { mapActions, mapState } from "vuex" import { mapActions, mapState } from "vuex"
import EnRecipes from "./EnRecipes.vue" import EnRecipes from "./EnRecipes"
import MealPlanner from "./MealPlanner.vue" import MealPlanner from "./MealPlanner"
import Settings from "./Settings.vue" import Settings from "./Settings"
import About from "./About.vue" import About from "./About"
import PromptDialog from "./modal/PromptDialog.vue" import PromptDialog from "./modal/PromptDialog"
export default { export default {
components: {
EnRecipes,
},
data() { data() {
return { return {
selectedCategory: null, selectedCategory: null,
filterFavorites: false, filterFavorites: false,
filterTrylater: false, filterTrylater: false,
MealPlanner: MealPlanner,
topmenu: [ topmenu: [
{ {
title: "Home", title: "Home",
@ -200,15 +198,19 @@ export default {
], ],
editCategory: false, editCategory: false,
appTheme: "Light", appTheme: "Light",
mealPlanner: MealPlanner,
} }
}, },
components: {
EnRecipes,
MealPlanner,
},
computed: { computed: {
...mapState([ ...mapState([
"icon", "icon",
"recipes", "recipes",
"categories", "categories",
"yieldUnits", "yieldUnits",
"mealPlans",
"currentComponent", "currentComponent",
]), ]),
categoriesWithRecipes() { categoriesWithRecipes() {
@ -224,6 +226,7 @@ export default {
"initializeRecipes", "initializeRecipes",
"initializeCategories", "initializeCategories",
"initializeYieldUnits", "initializeYieldUnits",
"initializeMealPlans",
"renameCategoryAction", "renameCategoryAction",
]), ]),
onPageLoad() { onPageLoad() {
@ -235,6 +238,9 @@ export default {
// window.setNavigationBarColor(new Color("#e0e0e0").android) // window.setNavigationBarColor(new Color("#e0e0e0").android)
} }
}, },
onPageUnload() {
// this.releaseGlobalBackEvent()
},
// HELPERS // HELPERS
toggleCatEdit() { toggleCatEdit() {
@ -268,44 +274,7 @@ export default {
this.selectedCategory = e.item this.selectedCategory = e.item
this.closeDrawer() this.closeDrawer()
}, },
restartApp() {
// Code from nativescript-master-technology
const mStartActivity = new android.content.Intent(
application.android.context,
application.android.startActivity.getClass()
)
const mPendingIntentId = parseInt(Math.random() * 100000, 10)
const mPendingIntent = android.app.PendingIntent.getActivity(
application.android.context,
mPendingIntentId,
mStartActivity,
android.app.PendingIntent.FLAG_CANCEL_CURRENT
)
const mgr = application.android.context.getSystemService(
android.content.Context.ALARM_SERVICE
)
mgr.set(
android.app.AlarmManager.RTC,
java.lang.System.currentTimeMillis() + 100,
mPendingIntent
)
android.os.Process.killProcess(android.os.Process.myPid())
},
openAppSettingsPage() {
const intent = new android.content.Intent(
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
)
intent.addCategory(android.content.Intent.CATEGORY_DEFAULT)
intent.setData(
android.net.Uri.parse(
"package:" + Application.android.context.getPackageName()
)
)
Application.android.foregroundActivity.startActivity(intent)
},
showDrawer() {
this.$refs.drawer.nativeView.showDrawer()
},
closeDrawer() { closeDrawer() {
this.$refs.drawer.nativeView.closeDrawer() this.$refs.drawer.nativeView.closeDrawer()
}, },
@ -358,13 +327,6 @@ export default {
if (isTrueComponent) { if (isTrueComponent) {
this.$navigateTo(to, { this.$navigateTo(to, {
frame: "main-frame", frame: "main-frame",
props: {
showDrawer: this.showDrawer,
restartApp: this.restartApp,
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
openAppSettingsPage: this.openAppSettingsPage,
},
backstackVisible: false, backstackVisible: false,
}) })
this.closeDrawer() this.closeDrawer()
@ -391,9 +353,10 @@ export default {
setTimeout((e) => { setTimeout((e) => {
Theme.setMode(Theme[this.appTheme]) Theme.setMode(Theme[this.appTheme])
}, 10) }, 10)
this.initializeRecipes() if (!this.recipes.length) this.initializeRecipes()
this.initializeCategories() if (!this.categories.length) this.initializeCategories()
this.initializeYieldUnits() if (!this.yieldUnits.length) this.initializeYieldUnits()
if (!this.mealPlans.length) this.initializeMealPlans()
}, },
} }
</script> </script>

View file

@ -13,20 +13,20 @@
<Label class="title orkm" :text="title" col="1" /> <Label class="title orkm" :text="title" col="1" />
<MDButton <MDButton
variant="text" variant="text"
v-if="hasChanges && !imageLoading" v-if="hasChanges && !saving"
class="bx" class="bx"
:text="icon.save" :text="icon.save"
col="2" col="2"
@tap="saveOperation" @tap="saveOperation"
/> />
<MDActivityIndicator col="2" v-if="imageLoading" :busy="imageLoading" /> <MDActivityIndicator col="2" v-if="saving" :busy="saving" />
</GridLayout> </GridLayout>
</ActionBar> </ActionBar>
<ScrollView <ScrollView
width="100%" width="100%"
height="100%" height="100%"
@scroll="onScroll" @scroll="onScroll"
scrollBarIndicatorVisible="false" scrollBarIndicatorVisible="true"
> >
<StackLayout width="100%" padding="0 0 128"> <StackLayout width="100%" padding="0 0 128">
<AbsoluteLayout> <AbsoluteLayout>
@ -257,7 +257,7 @@
<StackLayout class="hr" margin="24 16"></StackLayout> <StackLayout class="hr" margin="24 16"></StackLayout>
</StackLayout> </StackLayout>
<StackLayout margin="0 16 24" v-if="recipes.length"> <StackLayout margin="0 16 24">
<Label text="Combinations" class="sectionTitle" /> <Label text="Combinations" class="sectionTitle" />
<GridLayout <GridLayout
columns="*,8,auto" columns="*,8,auto"
@ -316,14 +316,10 @@ import ConfirmDialog from "./modal/ConfirmDialog.vue"
import PromptDialog from "./modal/PromptDialog.vue" import PromptDialog from "./modal/PromptDialog.vue"
import ListPicker from "./modal/ListPicker.vue" import ListPicker from "./modal/ListPicker.vue"
import * as utils from "~/shared/utils"
export default { export default {
props: [ props: ["recipeID", "selectedCategory", "filterFavorites", "filterTrylater"],
"recipeID",
"selectedCategory",
"openAppSettingsPage",
"filterFavorites",
"filterTrylater",
],
data() { data() {
return { return {
title: "New recipe", title: "New recipe",
@ -343,7 +339,7 @@ export default {
references: [], references: [],
combinations: [], combinations: [],
isFavorite: false, isFavorite: false,
tried: false, tried: true,
lastTried: null, lastTried: null,
lastModified: null, lastModified: null,
}, },
@ -352,7 +348,7 @@ export default {
modalOpen: false, modalOpen: false,
newRecipeID: null, newRecipeID: null,
showFab: false, showFab: false,
imageLoading: false, saving: false,
cacheImagePath: null, cacheImagePath: null,
unSyncCombinations: [], unSyncCombinations: [],
} }
@ -680,7 +676,7 @@ export default {
} else { } else {
Permissions.check("photo").then((res) => { Permissions.check("photo").then((res) => {
res[0] !== "authorized" res[0] !== "authorized"
? confirmation().then((e) => e && this.openAppSettingsPage()) ? confirmation().then((e) => e && utils.openAppSettingsPage())
: action() : action()
}) })
} }
@ -771,7 +767,6 @@ export default {
...this.recipeContent.combinations, ...this.recipeContent.combinations,
this.recipeContent.id, this.recipeContent.id,
] ]
console.log(existingCombinations)
let filteredRecipes = this.recipes.filter( let filteredRecipes = this.recipes.filter(
(e) => !existingCombinations.includes(e.id) (e) => !existingCombinations.includes(e.id)
) )
@ -838,7 +833,7 @@ export default {
clearEmpty("references") clearEmpty("references")
}, },
saveOperation() { saveOperation() {
this.imageLoading = true this.saving = true
this.clearEmptyFields() this.clearEmptyFields()
this.recipeContent.lastModified = new Date() this.recipeContent.lastModified = new Date()
if (this.cacheImagePath) { if (this.cacheImagePath) {
@ -884,7 +879,7 @@ export default {
}) })
} }
setTimeout(() => { setTimeout(() => {
this.imageLoading = false this.saving = false
}, 100) }, 100)
this.$navigateBack() this.$navigateBack()
}, },

View file

@ -237,15 +237,16 @@ import ViewRecipe from "./ViewRecipe.vue"
import ActionDialog from "./modal/ActionDialog.vue" import ActionDialog from "./modal/ActionDialog.vue"
import ConfirmDialog from "./modal/ConfirmDialog.vue" import ConfirmDialog from "./modal/ConfirmDialog.vue"
import * as utils from "~/shared/utils"
export default { export default {
props: [ props: [
"filterFavorites", "filterFavorites",
"filterTrylater", "filterTrylater",
"closeDrawer",
"selectedCategory", "selectedCategory",
"showDrawer",
"hijackGlobalBackEvent", "hijackGlobalBackEvent",
"releaseGlobalBackEvent", "releaseGlobalBackEvent",
"openAppSettingsPage",
], ],
components: { components: {
EditRecipe, EditRecipe,
@ -301,6 +302,9 @@ export default {
}, },
// HELPERS // HELPERS
showDrawer() {
utils.showDrawer()
},
openSearch() { openSearch() {
this.showSearch = true this.showSearch = true
this.showFAB = false this.showFAB = false
@ -355,6 +359,7 @@ export default {
}, },
searchBackEvent(args) { searchBackEvent(args) {
args.cancel = true args.cancel = true
this.closeDrawer()
this.closeSearch() this.closeSearch()
}, },
addRecipe() { addRecipe() {
@ -363,7 +368,6 @@ export default {
this.$navigateTo(EditRecipe, { this.$navigateTo(EditRecipe, {
props: { props: {
selectedCategory: this.selectedCategory, selectedCategory: this.selectedCategory,
openAppSettingsPage: this.openAppSettingsPage,
filterFavorites: this.filterFavorites, filterFavorites: this.filterFavorites,
}, },
}) })
@ -371,16 +375,9 @@ export default {
viewRecipe(recipeID) { viewRecipe(recipeID) {
this.showFAB = false this.showFAB = false
this.$navigateTo(ViewRecipe, { this.$navigateTo(ViewRecipe, {
// transition: {
// name: "fade",
// duration: 200,
// curve: "easeOut",
// },
props: { props: {
filterTrylater: this.filterTrylater, filterTrylater: this.filterTrylater,
recipeID, recipeID,
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
}, },
}) })
}, },

View file

@ -1,7 +1,7 @@
<template> <template>
<Page @loaded="onPageLoad"> <Page @loaded="onPageLoad">
<ActionBar :flat="viewIsScrolled ? false : true"> <ActionBar :flat="viewIsScrolled ? false : true">
<GridLayout rows="*" columns="auto, *"> <GridLayout rows="*" columns="auto, *, auto">
<MDButton <MDButton
class="bx left" class="bx left"
variant="text" variant="text"
@ -11,39 +11,65 @@
col="0" col="0"
/> />
<Label class="title orkm" text="Meal Planner" col="1" /> <Label class="title orkm" text="Meal Planner" col="1" />
<MDButton
class="bx left"
variant="text"
:text="icon.today"
automationText="today"
@tap="goToToday"
col="2"
/>
</GridLayout> </GridLayout>
</ActionBar> </ActionBar>
<GridLayout rows="280, *">
<RadCalendar
class="orkm"
row="0"
ref="calendar"
locale="en-US"
@loaded="onCalendarLoad"
@dateSelected="onDateSelected"
:viewMode="viewMode"
:transitionMode="transitionMode"
:selectionMode="selectionMode"
:eventsViewMode="eventsViewMode"
:eventSource="getMealPlans"
></RadCalendar>
<ScrollView <ScrollView
row="1"
width="100%" width="100%"
height="100%" height="100%"
scrollBarIndicatorVisible="false" scrollBarIndicatorVisible="true"
@scroll="onScroll"
> >
<StackLayout class="mealPlanner"> <StackLayout class="dayPlan">
<RadCalendar ref="calendar" @dateSelected="onDateSelected">
</RadCalendar>
<StackLayout <StackLayout
v-for="(meal, indexB) in mealTimes" v-for="(mealType, index) in mealTimes"
:key="'meal' + indexB" :key="'mealType' + index"
class="dayContainer" class="plansContainer"
:class="meal" :class="mealType"
> >
<GridLayout columns="*, auto" class="header"> <GridLayout columns="*, auto" class="header">
<Label col="0" class="periodLabel orkm" :text="meal" /> <Label col="0" class="periodLabel orkm" :text="mealType" />
<MDButton <MDButton
col="1" col="1"
variant="text" variant="text"
class="bx addMeal" class="bx addMeal"
:text="icon.plus" :text="icon.plus"
@tap="addRecipe(mealType)"
/> />
</GridLayout> </GridLayout>
<GridLayout class="recipes" columns="*, auto"> <GridLayout
<MDRipple /> class="recipes"
columns="*, auto"
v-for="(recipeID, index) in getRecipes[mealType]"
:key="mealType + index"
>
<MDRipple @tap="viewRecipe(recipeID)" />
<Label <Label
verticalAlignment="center" verticalAlignment="center"
class="recipeTitle" class="recipeTitle"
col="0" col="0"
text="getRecipeTitle(recipeID, indexA, meal)" :text="getRecipeTitle(recipeID)"
textWrap="true" textWrap="true"
/> />
<MDButton <MDButton
@ -51,21 +77,31 @@
col="1" col="1"
class="bx closeBtn" class="bx closeBtn"
:text="icon.close" :text="icon.close"
@tap="removeRecipe(mealType, recipeID)"
/> />
</GridLayout> </GridLayout>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ScrollView> </ScrollView>
<!-- <GridLayout rows="*, auto, *, 88" columns="*" class="emptyStateContainer"> </GridLayout>
<StackLayout row="1" class="emptyState">
<Label class="title orkm" text="Coming soon!" textWrap="true" />
</StackLayout>
</GridLayout> -->
</Page> </Page>
</template> </template>
<script> <script>
import { ApplicationSettings, Color } from "@nativescript/core" import { ApplicationSettings, Color, Page } from "@nativescript/core"
import {
CalendarViewMode,
CalendarTransitionMode,
CalendarSelectionMode,
CalendarMonthViewStyle,
CalendarSelectionShape,
DayCellStyle,
CalendarFontStyle,
CalendarCellAlignment,
CellStyle,
CalendarEventsViewMode,
CalendarEvent,
} from "nativescript-ui-calendar"
import { mapState, mapActions } from "vuex" import { mapState, mapActions } from "vuex"
import ViewRecipe from "./ViewRecipe.vue" import ViewRecipe from "./ViewRecipe.vue"
@ -73,26 +109,224 @@ import ViewRecipe from "./ViewRecipe.vue"
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue" import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue"
import ConfirmDialog from "./modal/ConfirmDialog.vue" import ConfirmDialog from "./modal/ConfirmDialog.vue"
import * as utils from "~/shared/utils"
export default { export default {
props: ["showDrawer", "hijackGlobalBackEvent", "releaseGlobalBackEvent"],
data() { data() {
return { return {
viewIsScrolled: false, viewIsScrolled: false,
appTheme: "Light", appTheme: "Light",
mealTimes: ["breakfast", "lunch", "dinner", "snacks"], mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
eventList: [],
selectedDayMealPlans: [],
viewMode: CalendarViewMode.Month,
transitionMode: CalendarTransitionMode.Slide,
selectionMode: CalendarSelectionMode.Single,
eventsViewMode: CalendarEventsViewMode.None,
color: {
white: new Color("#ffffff"),
gray1: new Color("#f1f3f5"),
gray2: new Color("#e9ecef"),
gray3: new Color("#dee2e6"),
gray4: new Color("#ced4da"),
gray5: new Color("#adb5bd"),
gray6: new Color("#868e96"),
gray7: new Color("#495057"),
gray8: new Color("#343a40"),
gray9: new Color("#212529"),
black: new Color("#111111"),
orange: new Color("#ff5200"),
breakfast: "#ffb180",
lunch: "#ceff80",
dinner: "#80ceff",
snacks: "#b180ff",
},
appFontRegular: "Orkney-Regular",
appFontMedium: "Orkney-Medium",
selectedDate: null,
} }
}, },
computed: { computed: {
...mapState(["icon", "recipes"]), ...mapState(["icon", "recipes", "mealPlans"]),
isLightMode() {
return this.appTheme === "Light"
},
monthViewStyle() {
const monthViewStyle = new CalendarMonthViewStyle()
monthViewStyle.backgroundColor = this.isLightMode
? this.color.gray1
: this.color.gray9
monthViewStyle.showTitle = true
monthViewStyle.showWeekNumbers = false
monthViewStyle.showDayNames = true
const titleCellStyle = new DayCellStyle()
titleCellStyle.cellBackgroundColor = this.isLightMode
? this.color.gray2
: this.color.black
titleCellStyle.cellBorderWidth = 1
titleCellStyle.cellBorderColor = this.isLightMode
? this.color.gray2
: this.color.black
titleCellStyle.cellTextSize = 16
titleCellStyle.cellTextColor = this.isLightMode
? this.color.gray9
: this.color.gray1
titleCellStyle.cellTextFontName = this.appFontMedium
monthViewStyle.titleCellStyle = titleCellStyle
const dayNameCellStyle = new CellStyle()
dayNameCellStyle.cellBackgroundColor = this.isLightMode
? this.color.gray2
: this.color.black
dayNameCellStyle.cellTextColor = this.isLightMode
? this.color.gray9
: this.color.gray1
dayNameCellStyle.cellBorderWidth = 1
dayNameCellStyle.cellBorderColor = this.isLightMode
? this.color.gray2
: this.color.black
dayNameCellStyle.cellTextSize = 12
dayNameCellStyle.cellAlignment = CalendarCellAlignment.Center
dayNameCellStyle.cellTextFontName = this.appFontMedium
monthViewStyle.dayNameCellStyle = dayNameCellStyle
const dayCellStyle = new DayCellStyle()
dayCellStyle.showEventsText = false
dayCellStyle.eventTextColor = this.color.orange
dayCellStyle.eventFontName = this.appFontRegular
dayCellStyle.eventFontStyle = CalendarFontStyle.Bold
dayCellStyle.eventTextSize = 8
dayCellStyle.cellTextSize = 16
dayCellStyle.cellTextColor = this.isLightMode
? this.color.gray9
: this.color.gray2
dayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
dayCellStyle.cellBackgroundColor = this.isLightMode
? this.color.gray1
: this.color.gray9
dayCellStyle.cellTextFontName = this.appFontRegular
dayCellStyle.cellBorderWidth = 1
dayCellStyle.cellBorderColor = this.isLightMode
? this.color.gray2
: this.color.black
monthViewStyle.dayCellStyle = dayCellStyle
const todayCellStyle = new DayCellStyle()
todayCellStyle.cellBackgroundColor = this.isLightMode
? this.color.gray1
: this.color.gray9
todayCellStyle.cellTextColor = this.color.orange
todayCellStyle.cellBorderWidth = 1
todayCellStyle.cellTextFontName = this.appFontMedium
todayCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
todayCellStyle.cellTextSize = 16
todayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
todayCellStyle.cellBorderColor = this.isLightMode
? this.color.gray2
: this.color.black
monthViewStyle.todayCellStyle = todayCellStyle
const selectedCellStyle = new DayCellStyle()
selectedCellStyle.eventTextSize = 1
selectedCellStyle.cellAlignment = CalendarCellAlignment.Bottom
selectedCellStyle.cellBackgroundColor = this.isLightMode
? this.color.white
: this.color.gray8
selectedCellStyle.cellBorderWidth = 1
selectedCellStyle.cellBorderColor = this.color.orange
selectedCellStyle.cellTextColor = this.isLightMode
? this.color.gray9
: this.color.gray1
selectedCellStyle.cellTextFontName = this.appFontMedium
selectedCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
selectedCellStyle.cellTextSize = 16
monthViewStyle.selectedDayCellStyle = selectedCellStyle
return monthViewStyle
},
getRecipes() {
if (this.selectedDayMealPlans.length) {
return this.selectedDayMealPlans.reduce((acc, e) => {
switch (e.startDate.getHours()) {
case 0: //breakfast
acc["breakfast"] = [...(acc["breakfast"] || []), e.title]
break
case 5: //lunch
acc["lunch"] = [...(acc["lunch"] || []), e.title]
break
case 10: //dinner
acc["dinner"] = [...(acc["dinner"] || []), e.title]
break
case 15: //snacks
acc["snacks"] = [...(acc["snacks"] || []), e.title]
break
default:
break
}
return acc
}, {})
} else return 0
},
getMealPlans() {
const getDate = (date) => {
let d = new Date(date)
let result = new Date(
d.getFullYear(),
d.getMonth(),
d.getDate(),
d.getHours()
)
return result
}
let events = []
this.mealPlans.forEach((plan) => {
let e = new CalendarEvent(
plan.title,
getDate(plan.startDate),
getDate(plan.endDate),
false,
new Color(plan.eventColor)
)
events = [...events, e]
})
return events
},
}, },
methods: { methods: {
...mapActions(["setCurrentComponentAction"]), ...mapActions([
onPageLoad() { "setCurrentComponentAction",
"initializeMealPlans",
"addMealPlanAction",
"deleteMealPlanAction",
]),
onPageLoad(args) {
this.setCurrentComponentAction("MealPlanner") this.setCurrentComponentAction("MealPlanner")
this.releaseGlobalBackEvent() },
onCalendarLoad(args) {
args.object.monthViewStyle = this.monthViewStyle
args.object.android
.getGestureManager()
.setDoubleTapToChangeDisplayMode(false)
args.object.android
.getGestureManager()
.setPinchCloseToChangeDisplayMode(false)
if (args.object.selectedDate == null)
args.object.selectedDate = new Date()
if (args.object.nativeView.getEventAdapter()) {
args.object.nativeView
.getEventAdapter()
.getRenderer()
.setEventRenderMode(
com.telerik.widget.calendar.events.EventRenderMode.Shape
)
}
}, },
// HELPERS // HELPERS
showDrawer() {
utils.showDrawer()
},
onScroll(args) { onScroll(args) {
args.scrollY args.scrollY
? (this.viewIsScrolled = true) ? (this.viewIsScrolled = true)
@ -109,58 +343,134 @@ export default {
return date.toDateString().slice(0, -5) return date.toDateString().slice(0, -5)
}, },
getRecipeTitle(id) { getRecipeTitle(id) {
return this.recipes.filter((e) => e.id === id)[0].title let recipe = this.recipes.filter((e) => e.id === id)[0]
return recipe ? recipe.title : "[Recipe not found]"
}, },
// NAVIGATION HANDLERS // NAVIGATION HANDLERS
viewRecipe(recipeID) { viewRecipe(recipeID) {
let recipe = this.recipes.filter((e) => e.id === recipeID)[0]
if (recipe) {
this.$navigateTo(ViewRecipe, { this.$navigateTo(ViewRecipe, {
props: { props: {
filterTrylater: true, filterTrylater: true,
recipeID, recipeID,
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
}, },
}) })
}
}, },
// DATA HANDLERS // DATA HANDLERS
addRecipe(indexA, meal) { addRecipe(mealType) {
let existingRecipes = [...this.meals[indexA][meal]] let filteredRecipes = this.recipes.filter((e) =>
let filteredRecipes = this.recipes.filter( this.getRecipes[mealType]
(e) => !existingRecipes.includes(e.id) ? !this.getRecipes[mealType].includes(e.id)
: true
) )
this.$showModal(ActionDialogWithSearch, { this.$showModal(ActionDialogWithSearch, {
props: { props: {
title: "Select a recipe", title: "Select a recipe",
recipes: filteredRecipes, recipes: filteredRecipes,
}, },
}).then((res) => { }).then((recipeID) => {
res && this.meals[indexA][meal].push(res) recipeID && this.newEvent(recipeID, mealType)
}) })
}, },
removeRecipeConfirm() { removeRecipeConfirm(mealType) {
return this.$showModal(ConfirmDialog, { return this.$showModal(ConfirmDialog, {
props: { props: {
title: `Remove recipe`, title: `Remove recipe from ${mealType}`,
cancelButtonText: "CANCEL", cancelButtonText: "CANCEL",
okButtonText: "REMOVE", okButtonText: "REMOVE",
}, },
}) })
}, },
removeRecipe(indexA, meal, indexC) { removeRecipe(mealType, recipeID) {
this.removeRecipeConfirm().then((res) => { let startHour = {
res && this.meals[indexA][meal].splice(indexC, 1) breakfast: 0,
lunch: 5,
dinner: 10,
snacks: 15,
}
this.removeRecipeConfirm(mealType).then((res) => {
if (res) {
let actualMealPlan = this.selectedDayMealPlans.filter(
(e) =>
e.startDate.getHours() === startHour[mealType] &&
e.title === recipeID
)[0]
let mealPlan = {
title: actualMealPlan.title,
startDate: actualMealPlan.startDate,
}
this.deleteMealPlanAction(mealPlan)
this.updateSelectedDatePlans()
}
}) })
}, },
// CALENDAR // CALENDAR
onDateSelected() { updateSelectedDatePlans() {
console.log("hello") let date = new Date(this.selectedDate)
setTimeout(() => {
this.selectedDayMealPlans = this.$refs.calendar.nativeView.getEventsForDate(
date
)
}, 100)
},
onDateSelected(args) {
this.selectedDate = args.date
this.selectedDayMealPlans = args.object.getEventsForDate(args.date)
},
newEvent(recipeID, mealType) {
let date = new Date(this.selectedDate)
const selectedDate = () => {
return {
y: date.getFullYear(),
m: date.getMonth(),
d: date.getDate(),
}
}
let { y, m, d } = selectedDate()
let mealTime = {
breakfast: {
start: new Date(y, m, d, 0),
end: new Date(y, m, d, 4),
},
lunch: {
start: new Date(y, m, d, 5),
end: new Date(y, m, d, 9),
},
dinner: {
start: new Date(y, m, d, 10),
end: new Date(y, m, d, 14),
},
snacks: {
start: new Date(y, m, d, 15),
end: new Date(y, m, d, 19),
},
}
let event = new CalendarEvent(
recipeID,
mealTime[mealType].start,
mealTime[mealType].end,
false,
new Color(this.color[mealType])
)
this.addMealPlanAction({ event, eventColor: this.color[mealType] })
this.updateSelectedDatePlans()
},
goToToday() {
const date = new Date()
this.$refs.calendar.goToDate(date)
this.$refs.calendar.nativeView.selectedDate = date
}, },
}, },
created() { created() {
this.appTheme = ApplicationSettings.getString("appTheme", "Light") this.appTheme = ApplicationSettings.getString("appTheme", "Light")
let d = new Date()
d.setHours(0, 0, 0)
this.selectedDate = d
}, },
} }
</script> </script>

View file

@ -13,7 +13,7 @@
<Label class="title orkm" text="Settings" col="1" /> <Label class="title orkm" text="Settings" col="1" />
</GridLayout> </GridLayout>
</ActionBar> </ActionBar>
<ScrollView scrollBarIndicatorVisible="false" @scroll="onScroll"> <ScrollView scrollBarIndicatorVisible="true" @scroll="onScroll">
<StackLayout class="main-container"> <StackLayout class="main-container">
<Label text="Interface" class="group-header orkm" /> <Label text="Interface" class="group-header orkm" />
<GridLayout columns="auto, *" class="option"> <GridLayout columns="auto, *" class="option">
@ -26,7 +26,7 @@
/> />
<StackLayout col="1"> <StackLayout col="1">
<Label text="Theme" /> <Label text="Theme" />
<Label :text="appTheme" class="info" textWrap="true" /> <Label :text="appTheme" class="info" />
</StackLayout> </StackLayout>
</GridLayout> </GridLayout>
<StackLayout class="hr m-10"></StackLayout> <StackLayout class="hr m-10"></StackLayout>
@ -37,11 +37,13 @@
<Label col="0" class="bx" :text="icon.export" /> <Label col="0" class="bx" :text="icon.export" />
<StackLayout col="1"> <StackLayout col="1">
<Label text="Export a full backup" /> <Label text="Export a full backup" />
<GridLayout <Label
class="progressContainer" v-if="!backupInProgress"
v-if="backupInProgress" text="Generates a zip file that contains all your data. This file can be imported back."
columns="*, 64" class="info"
> textWrap="true"
/>
<GridLayout class="progressContainer" v-else columns="*, 64">
<MDProgress <MDProgress
col="0" col="0"
:value="backupProgress" :value="backupProgress"
@ -49,12 +51,6 @@
></MDProgress> ></MDProgress>
<Label col="1" :text="` ${backupProgress}%`" /> <Label col="1" :text="` ${backupProgress}%`" />
</GridLayout> </GridLayout>
<Label
v-else
text="Generates a zip file that contains all your data. This file can be imported back."
class="info"
textWrap="true"
/>
</StackLayout> </StackLayout>
</GridLayout> </GridLayout>
<GridLayout columns="auto, *" class="option" <GridLayout columns="auto, *" class="option"
@ -95,13 +91,9 @@ import { mapState, mapActions } from "vuex"
import ActionDialog from "./modal/ActionDialog.vue" import ActionDialog from "./modal/ActionDialog.vue"
import ConfirmDialog from "./modal/ConfirmDialog.vue" import ConfirmDialog from "./modal/ConfirmDialog.vue"
import * as utils from "~/shared/utils"
export default { export default {
props: [
"showDrawer",
"restartApp",
"releaseGlobalBackEvent",
"openAppSettingsPage",
],
data() { data() {
return { return {
viewIsScrolled: false, viewIsScrolled: false,
@ -116,6 +108,7 @@ export default {
"recipes", "recipes",
"userCategories", "userCategories",
"userYieldUnits", "userYieldUnits",
"mealPlans",
"currentComponent", "currentComponent",
]), ]),
}, },
@ -125,13 +118,15 @@ export default {
"importCategoriesAction", "importCategoriesAction",
"importYieldUnitsAction", "importYieldUnitsAction",
"importRecipesAction", "importRecipesAction",
"importMealPlansAction",
]), ]),
onPageLoad() { onPageLoad() {
this.setCurrentComponentAction("Settings") this.setCurrentComponentAction("Settings")
this.releaseGlobalBackEvent()
}, },
// HELPERS // HELPERS
showDrawer() {
utils.showDrawer()
},
onScroll(args) { onScroll(args) {
args.scrollY args.scrollY
? (this.viewIsScrolled = true) ? (this.viewIsScrolled = true)
@ -160,7 +155,7 @@ export default {
if (result) { if (result) {
this.appTheme = action this.appTheme = action
ApplicationSettings.setString("appTheme", action) ApplicationSettings.setString("appTheme", action)
setTimeout((e) => this.restartApp(), 250) setTimeout((e) => utils.restartApp(), 250)
} }
}) })
} }
@ -209,11 +204,6 @@ export default {
archive: destPath, archive: destPath,
onProgress: (progress) => { onProgress: (progress) => {
this.backupProgress = progress this.backupProgress = progress
if (progress == 100) {
setTimeout((e) => {
this.backupInProgress = false
}, 2000)
}
}, },
}).then((success) => { }).then((success) => {
Toast.makeText( Toast.makeText(
@ -225,8 +215,8 @@ export default {
}, },
exportFiles(option) { exportFiles(option) {
const folder = path.join(knownFolders.documents().path, "EnRecipes") const folder = path.join(knownFolders.documents().path, "EnRecipes")
const EnRecipesFile = File.fromPath(path.join(folder, "EnRecipes.json")) const EnRecipesFile = File.fromPath(path.join(folder, "recipes.json"))
let userCategoriesFile, userYieldUnitsFile let userCategoriesFile, userYieldUnitsFile, mealPlansFile
if (this.userCategories.length) { if (this.userCategories.length) {
userCategoriesFile = File.fromPath( userCategoriesFile = File.fromPath(
path.join(folder, "userCategories.json") path.join(folder, "userCategories.json")
@ -237,6 +227,9 @@ export default {
path.join(folder, "userYieldUnits.json") path.join(folder, "userYieldUnits.json")
) )
} }
if (this.mealPlans.length) {
mealPlansFile = File.fromPath(path.join(folder, "mealPlans.json"))
}
switch (option) { switch (option) {
case "create": case "create":
this.writeDataToFile(EnRecipesFile, this.recipes) this.writeDataToFile(EnRecipesFile, this.recipes)
@ -244,11 +237,14 @@ export default {
this.writeDataToFile(userCategoriesFile, this.userCategories) this.writeDataToFile(userCategoriesFile, this.userCategories)
this.userYieldUnits.length && this.userYieldUnits.length &&
this.writeDataToFile(userYieldUnitsFile, this.userYieldUnits) this.writeDataToFile(userYieldUnitsFile, this.userYieldUnits)
this.mealPlans.length &&
this.writeDataToFile(mealPlansFile, this.mealPlans)
break break
case "delete": case "delete":
EnRecipesFile.remove() EnRecipesFile.remove()
this.userCategories.length && userCategoriesFile.remove() this.userCategories.length && userCategoriesFile.remove()
this.userYieldUnits.length && userYieldUnitsFile.remove() this.userYieldUnits.length && userYieldUnitsFile.remove()
this.mealPlans.length && mealPlansFile.remove()
break break
default: default:
break break
@ -290,6 +286,9 @@ export default {
case "userYieldUnitsDB": case "userYieldUnitsDB":
this.importYieldUnitsAction(data) this.importYieldUnitsAction(data)
break break
case "mealPlansDB":
this.importMealPlansAction(data)
break
default: default:
break break
} }
@ -312,9 +311,10 @@ export default {
overwrite: true, overwrite: true,
}).then((extractedFolderPath) => { }).then((extractedFolderPath) => {
let cacheFolderPath = extractedFolderPath + "/EnRecipes" let cacheFolderPath = extractedFolderPath + "/EnRecipes"
const EnRecipesFilePath = cacheFolderPath + "/EnRecipes.json" const EnRecipesFilePath = cacheFolderPath + "/recipes.json"
const userCategoriesFilePath = cacheFolderPath + "/userCategories.json" const userCategoriesFilePath = cacheFolderPath + "/userCategories.json"
const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json" const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json"
const mealPlansFilePath = cacheFolderPath + "/mealPlans.json"
if (Folder.exists(cacheFolderPath)) { if (Folder.exists(cacheFolderPath)) {
this.isFileDataValid([ this.isFileDataValid([
{ {
@ -324,6 +324,7 @@ export default {
}, },
{ zipPath, path: userCategoriesFilePath, db: "userCategoriesDB" }, { zipPath, path: userCategoriesFilePath, db: "userCategoriesDB" },
{ zipPath, path: userYieldUnitsFilePath, db: "userYieldUnitsDB" }, { zipPath, path: userYieldUnitsFilePath, db: "userYieldUnitsDB" },
{ zipPath, path: mealPlansFilePath, db: "mealPlansDB" },
]) ])
} else { } else {
Folder.fromPath(extractedFolderPath).remove() Folder.fromPath(extractedFolderPath).remove()
@ -368,7 +369,7 @@ export default {
let status = res[Object.keys(res)[0]] let status = res[Object.keys(res)[0]]
if (status !== "authorized") { if (status !== "authorized") {
confirmation(description).then((e) => { confirmation(description).then((e) => {
e && this.openAppSettingsPage() e && utils.openAppSettingsPage()
}) })
} else action() } else action()
}) })
@ -385,7 +386,7 @@ export default {
}) })
}, },
}, },
created() { mounted() {
this.appTheme = ApplicationSettings.getString("appTheme", "Light") this.appTheme = ApplicationSettings.getString("appTheme", "Light")
}, },
} }

View file

@ -66,7 +66,7 @@
class="viewRecipe" class="viewRecipe"
> >
<TabViewItem title="Overview"> <TabViewItem title="Overview">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<StackLayout> <StackLayout>
<StackLayout <StackLayout
width="100%" width="100%"
@ -221,7 +221,7 @@
</ScrollView> </ScrollView>
</TabViewItem> </TabViewItem>
<TabViewItem title="Ingredients"> <TabViewItem title="Ingredients">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<GridLayout <GridLayout
v-if="!recipe.ingredients.length" v-if="!recipe.ingredients.length"
rows="*, auto, *, 88" rows="*, auto, *, 88"
@ -265,7 +265,6 @@
:key="index" :key="index"
> >
<check-box <check-box
v-if="filterTrylater"
class="ingredient-check" class="ingredient-check"
checkPadding="16" checkPadding="16"
fillColor="#ff5200" fillColor="#ff5200"
@ -279,26 +278,12 @@
}` }`
" "
/> />
<Label
v-else
class="ingredient"
textWrap="true"
:text="
`${
roundedQuantity(item.quantity)
? roundedQuantity(item.quantity) + ' '
: ''
}${roundedQuantity(item.quantity) ? item.unit + ' ' : ''}${
item.item
}`
"
/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ScrollView> </ScrollView>
</TabViewItem> </TabViewItem>
<TabViewItem title="Instructions"> <TabViewItem title="Instructions">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<GridLayout <GridLayout
v-if="!recipe.instructions.length" v-if="!recipe.instructions.length"
rows="*, auto, *, 88" rows="*, auto, *, 88"
@ -343,7 +328,7 @@
</ScrollView> </ScrollView>
</TabViewItem> </TabViewItem>
<TabViewItem title="Notes"> <TabViewItem title="Notes">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<GridLayout <GridLayout
v-if="!recipe.notes.length" v-if="!recipe.notes.length"
rows="*, auto, *, 88" rows="*, auto, *, 88"
@ -385,7 +370,7 @@
</ScrollView> </ScrollView>
</TabViewItem> </TabViewItem>
<TabViewItem title="References"> <TabViewItem title="References">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<GridLayout <GridLayout
v-if="!recipe.references.length" v-if="!recipe.references.length"
rows="*, auto, *, 88" rows="*, auto, *, 88"
@ -438,7 +423,7 @@
</ScrollView> </ScrollView>
</TabViewItem> </TabViewItem>
<TabViewItem title="Combinations"> <TabViewItem title="Combinations">
<ScrollView scrollBarIndicatorVisible="false"> <ScrollView scrollBarIndicatorVisible="true">
<GridLayout <GridLayout
v-if="!recipe.combinations.length" v-if="!recipe.combinations.length"
rows="*, auto, *, 88" rows="*, auto, *, 88"
@ -523,13 +508,7 @@ import ShareChooser from "./modal/ShareChooser.vue"
let feedback = new Feedback() let feedback = new Feedback()
export default { export default {
props: [ props: ["filterTrylater", "recipeID"],
"filterTrylater",
"recipeID",
"recipeIndex",
"hijackGlobalBackEvent",
"releaseGlobalBackEvent",
],
data() { data() {
return { return {
busy: false, busy: false,
@ -560,7 +539,6 @@ export default {
"setRecipeAsTriedAction", "setRecipeAsTriedAction",
]), ]),
onPageLoad() { onPageLoad() {
this.releaseGlobalBackEvent()
this.busy = false this.busy = false
setTimeout((e) => { setTimeout((e) => {
this.setCurrentComponentAction("ViewRecipe") this.setCurrentComponentAction("ViewRecipe")

View file

@ -2,7 +2,10 @@
<Page> <Page>
<StackLayout class="dialogContainer" :class="appTheme"> <StackLayout class="dialogContainer" :class="appTheme">
<Label class="dialogTitle orkm" :text="title" /> <Label class="dialogTitle orkm" :text="title" />
<StackLayout padding="0 24 24"> <StackLayout
v-if="filteredRecipes.length || searchTerm"
padding="0 24 24"
>
<TextField hint="Search" v-model="searchTerm" /> <TextField hint="Search" v-model="searchTerm" />
</StackLayout> </StackLayout>
<ScrollView width="100%" :height="height ? height : screenHeight - 320"> <ScrollView width="100%" :height="height ? height : screenHeight - 320">
@ -18,11 +21,11 @@
@tap="tapAction(recipe)" @tap="tapAction(recipe)"
/> />
<Label <Label
padding="0 24" padding="24"
lineHeight="6" lineHeight="6"
v-if="!filteredRecipes.length" v-if="!filteredRecipes.length"
text="Nothing here! Add some recipes that goes well with this and try again." text="Nothing here! Add some recipes and try again."
horizontalAlignment="center" textAlignment="center"
textWrap="true" textWrap="true"
/> />
</StackLayout> </StackLayout>

View file

@ -1,7 +1,7 @@
<template> <template>
<Page> <Page>
<StackLayout class="dialogContainer" :class="appTheme"> <StackLayout class="dialogContainer" :class="appTheme">
<Label class="dialogTitle orkm" :text="title" /> <Label class="dialogTitle orkm" :text="title" textWrap="true"/>
<Label <Label
v-if="description" v-if="description"
class="dialogDescription" class="dialogDescription"

View file

@ -23,10 +23,9 @@ Vue.use(ProgressPlugin)
import CalendarView from "nativescript-ui-calendar/vue" import CalendarView from "nativescript-ui-calendar/vue"
Vue.use(CalendarView) Vue.use(CalendarView)
Vue.registerElement( import RadSideDrawer from "nativescript-ui-sidedrawer/vue"
"RadSideDrawer", Vue.use(RadSideDrawer)
() => require("nativescript-ui-sidedrawer").RadSideDrawer
)
import { CheckBox } from "@nstudio/nativescript-checkbox" import { CheckBox } from "@nstudio/nativescript-checkbox"
Vue.registerElement("CheckBox", () => CheckBox, { Vue.registerElement("CheckBox", () => CheckBox, {
model: { model: {
@ -35,11 +34,6 @@ Vue.registerElement("CheckBox", () => CheckBox, {
}, },
}) })
if (TNS_ENV !== "production") {
// Vue.use(VueDevtools)
}
// Prints Vue logs when --env.production is *NOT* set while building
Vue.config.silent = TNS_ENV === "production" Vue.config.silent = TNS_ENV === "production"
new Vue({ new Vue({

42
app/shared/utils.js Normal file
View file

@ -0,0 +1,42 @@
import { Application } from "@nativescript/core"
export const showDrawer = () => {
let sideDrawer = Application.getRootView().getViewById("sideDrawer")
sideDrawer && sideDrawer.showDrawer()
}
export const restartApp = () => {
const mStartActivity = new android.content.Intent(
Application.android.context,
Application.android.startActivity.getClass()
)
const mPendingIntentId = parseInt(Math.random() * 100000, 10)
const mPendingIntent = android.app.PendingIntent.getActivity(
Application.android.context,
mPendingIntentId,
mStartActivity,
android.app.PendingIntent.FLAG_CANCEL_CURRENT
)
const mgr = Application.android.context.getSystemService(
android.content.Context.ALARM_SERVICE
)
mgr.set(
android.app.AlarmManager.RTC,
java.lang.System.currentTimeMillis() + 100,
mPendingIntent
)
android.os.Process.killProcess(android.os.Process.myPid())
}
export const openAppSettingsPage = () => {
const intent = new android.content.Intent(
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
)
intent.addCategory(android.content.Intent.CATEGORY_DEFAULT)
intent.setData(
android.net.Uri.parse(
"package:" + Application.android.context.getPackageName()
)
)
Application.android.foregroundActivity.startActivity(intent)
}

View file

@ -1,10 +1,13 @@
import Vue from "vue" import Vue from "vue"
import Vuex from "vuex" import Vuex from "vuex"
import { Couchbase } from "nativescript-couchbase-plugin" import { Couchbase } from "nativescript-couchbase-plugin"
import { getFileAccess } from "@nativescript/core" import { Color, getFileAccess } from "@nativescript/core"
import { CalendarEvent } from "nativescript-ui-calendar"
import { stat } from "fs"
const EnRecipesDB = new Couchbase("EnRecipes") const EnRecipesDB = new Couchbase("EnRecipes")
const userCategoriesDB = new Couchbase("userCategories") const userCategoriesDB = new Couchbase("userCategories")
const userYieldUnitsDB = new Couchbase("userYieldUnits") const userYieldUnitsDB = new Couchbase("userYieldUnits")
const mealPlansDB = new Couchbase("mealPlans")
Vue.use(Vuex) Vue.use(Vuex)
@ -116,6 +119,7 @@ export default new Vuex.Store({
units: [ units: [
"unit", "unit",
"tsp", "tsp",
"dsp",
"tbsp", "tbsp",
"fl oz", "fl oz",
"cup", "cup",
@ -131,6 +135,7 @@ export default new Vuex.Store({
"kg", "kg",
"cm", "cm",
"in", "in",
"leaf",
"clove", "clove",
"pinch", "pinch",
"drop", "drop",
@ -142,6 +147,7 @@ export default new Vuex.Store({
], ],
yieldUnits: [], yieldUnits: [],
userYieldUnits: [], userYieldUnits: [],
mealPlans: [],
icon: { icon: {
home: "\ued3b", home: "\ued3b",
heart: "\ued36", heart: "\ued36",
@ -183,7 +189,8 @@ export default new Vuex.Store({
export: "\ued07", export: "\ued07",
import: "\ued0c", import: "\ued0c",
outline: "\ueb07", outline: "\ueb07",
calendar: "\uec57", calendar: "\uec55",
today: "\ue97c",
}, },
currentComponent: "EnRecipes", currentComponent: "EnRecipes",
}, },
@ -230,12 +237,16 @@ export default new Vuex.Store({
} }
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits] state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
}, },
addRecipe(state, { id, recipe }) { initializeMealPlans(state) {
state.recipes.push(recipe) let isMealPlansDBStored = mealPlansDB.query({ select: [] }).length
EnRecipesDB.createDocument(recipe, id) if (isMealPlansDBStored) {
state.mealPlans = mealPlansDB.getDocument("mealPlans").mealPlans
} else {
mealPlansDB.createDocument({ mealPlans: [] }, "mealPlans")
}
}, },
importRecipes(state, recipes) { importRecipes(state, recipes) {
console.log("hello")
let localRecipesIDs, partition let localRecipesIDs, partition
if (state.recipes.length) { if (state.recipes.length) {
localRecipesIDs = state.recipes.map((e) => e.id) localRecipesIDs = state.recipes.map((e) => e.id)
@ -254,24 +265,59 @@ export default new Vuex.Store({
createDocuments(recipes) createDocuments(recipes)
} }
function createDocuments(data) { function createDocuments(data) {
console.log("creating")
state.recipes = [...state.recipes, ...data] state.recipes = [...state.recipes, ...data]
data.forEach((recipe) => { data.forEach((recipe) => {
EnRecipesDB.createDocument(recipe, recipe.id) EnRecipesDB.createDocument(recipe, recipe.id)
}) })
} }
function updateDocuments(data) { function updateDocuments(data) {
console.log("updating")
data.forEach((recipe) => { data.forEach((recipe) => {
let recipeIndex = state.recipes let recipeIndex = state.recipes
.map((e, i) => (e.id === recipe.id ? i : -1)) .map((e, i) => {
let d1 = new Date(e.lastModified).getTime()
let d2 = new Date(recipe.lastModified).getTime()
return e.id === recipe.id && d1 < d2 ? i : -1
})
.filter((e) => e >= 0)[0] .filter((e) => e >= 0)[0]
console.log(recipeIndex) if (recipeIndex >= 0) {
Object.assign(state.recipes[recipeIndex], recipe) Object.assign(state.recipes[recipeIndex], recipe)
EnRecipesDB.updateDocument(recipe.id, recipe) EnRecipesDB.updateDocument(recipe.id, recipe)
}
}) })
} }
}, },
importCategories(state, categories) {
state.userCategories = new Set([...state.userCategories, ...categories])
userCategoriesDB.updateDocument("userCategories", {
userCategories: [...state.userCategories],
})
state.categories = [...defaultCategories, ...state.userCategories]
state.categories.sort()
},
importYieldUnits(state, yieldUnits) {
state.userYieldUnits = new Set([...state.userYieldUnits, ...yieldUnits])
userYieldUnitsDB.updateDocument("userYieldUnits", {
userYieldUnits: [...state.userYieldUnits],
})
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
},
importMealPlans(state, mealPlans) {
let newMealPlans = mealPlans.filter(
(e) =>
!state.mealPlans.some(
(f) => f.title === e.title && f.startDate === e.startDate
)
)
state.mealPlans = [...state.mealPlans, ...newMealPlans]
mealPlansDB.updateDocument("mealPlans", {
mealPlans: [...state.mealPlans],
})
},
addRecipe(state, { id, recipe }) {
state.recipes.push(recipe)
EnRecipesDB.createDocument(recipe, id)
},
addCategory(state, category) { addCategory(state, category) {
let lowercase = state.categories.map((e) => e.toLowerCase()) let lowercase = state.categories.map((e) => e.toLowerCase())
if (lowercase.indexOf(category.toLowerCase()) == -1) { if (lowercase.indexOf(category.toLowerCase()) == -1) {
@ -283,14 +329,6 @@ export default new Vuex.Store({
state.categories.sort() state.categories.sort()
} }
}, },
importCategories(state, categories) {
state.userCategories = new Set([...state.userCategories, ...categories])
userCategoriesDB.updateDocument("userCategories", {
userCategories: [...state.userCategories],
})
state.categories = [...defaultCategories, ...state.userCategories]
state.categories.sort()
},
addYieldUnit(state, yieldUnit) { addYieldUnit(state, yieldUnit) {
let lowercase = state.yieldUnits.map((e) => e.toLowerCase()) let lowercase = state.yieldUnits.map((e) => e.toLowerCase())
if (lowercase.indexOf(yieldUnit.toLowerCase()) == -1) { if (lowercase.indexOf(yieldUnit.toLowerCase()) == -1) {
@ -301,20 +339,18 @@ export default new Vuex.Store({
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits] state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
} }
}, },
importYieldUnits(state, yieldUnits) { addMealPlan(state, { event, eventColor }) {
state.userYieldUnits = new Set([...state.userYieldUnits, ...yieldUnits]) state.mealPlans.push({
userYieldUnitsDB.updateDocument("userYieldUnits", { title: event.title,
userYieldUnits: [...state.userYieldUnits], startDate: event.startDate,
endDate: event.endDate,
eventColor,
})
mealPlansDB.updateDocument("mealPlans", {
mealPlans: [...state.mealPlans],
}) })
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
},
overwriteRecipe(state, { id, recipe }) {
let index = state.recipes.indexOf(
state.recipes.filter((e) => e.id === id)[0]
)
Object.assign(state.recipes[index], recipe)
EnRecipesDB.updateDocument(id, recipe)
}, },
deleteRecipe(state, { index, id }) { deleteRecipe(state, { index, id }) {
getFileAccess().deleteFile(state.recipes[index].imageSrc) getFileAccess().deleteFile(state.recipes[index].imageSrc)
state.recipes.splice(index, 1) state.recipes.splice(index, 1)
@ -326,6 +362,29 @@ export default new Vuex.Store({
} }
}) })
}, },
deleteMealPlan(state, { title, startDate }) {
let mealPlan = state.mealPlans.filter((e) => {
console.log(e.startDate, startDate)
let sd = new Date(e.startDate).getTime()
return e.title === title && sd === startDate.getTime()
})[0]
let index = state.mealPlans.indexOf(mealPlan)
state.mealPlans.splice(index, 1)
state.mealPlans = [...state.mealPlans]
let mealPlans = mealPlansDB.getDocument("mealPlans").mealPlans
mealPlans.splice(index, 1)
mealPlansDB.updateDocument("mealPlans", {
mealPlans: [...mealPlans],
})
},
overwriteRecipe(state, { id, recipe }) {
let index = state.recipes.indexOf(
state.recipes.filter((e) => e.id === id)[0]
)
Object.assign(state.recipes[index], recipe)
EnRecipesDB.updateDocument(id, recipe)
},
toggleState(state, { id, recipe, key, setDate }) { toggleState(state, { id, recipe, key, setDate }) {
let index = state.recipes.indexOf( let index = state.recipes.indexOf(
state.recipes.filter((e) => e.id === id)[0] state.recipes.filter((e) => e.id === id)[0]
@ -346,9 +405,6 @@ export default new Vuex.Store({
state.recipes[index].lastTried = new Date() state.recipes[index].lastTried = new Date()
EnRecipesDB.updateDocument(state.recipes[index].id, state.recipes[index]) EnRecipesDB.updateDocument(state.recipes[index].id, state.recipes[index])
}, },
setCurrentComponent(state, comp) {
state.currentComponent = comp
},
renameCategory(state, { current, updated }) { renameCategory(state, { current, updated }) {
let lowercase = state.categories.map((e) => e.toLowerCase()) let lowercase = state.categories.map((e) => e.toLowerCase())
if (lowercase.indexOf(updated.toLowerCase()) == -1) { if (lowercase.indexOf(updated.toLowerCase()) == -1) {
@ -368,6 +424,9 @@ export default new Vuex.Store({
} }
}) })
}, },
setCurrentComponent(state, comp) {
state.currentComponent = comp
},
unSyncCombinations(state, { id, combinations }) { unSyncCombinations(state, { id, combinations }) {
state.recipes.forEach((e, i) => { state.recipes.forEach((e, i) => {
if (combinations.includes(e.id)) { if (combinations.includes(e.id)) {
@ -387,30 +446,46 @@ export default new Vuex.Store({
initializeYieldUnits({ commit }) { initializeYieldUnits({ commit }) {
commit("initializeYieldUnits") commit("initializeYieldUnits")
}, },
addRecipeAction({ commit }, recipe) { initializeMealPlans({ commit }) {
commit("addRecipe", recipe) commit("initializeMealPlans")
}, },
importRecipesAction({ commit }, recipes) { importRecipesAction({ commit }, recipes) {
commit("importRecipes", recipes) commit("importRecipes", recipes)
}, },
addCategoryAction({ commit }, category) {
commit("addCategory", category)
},
importCategoriesAction({ commit }, categories) { importCategoriesAction({ commit }, categories) {
commit("importCategories", categories) commit("importCategories", categories)
}, },
addYieldUnitAction({ commit }, yieldUnit) {
commit("addYieldUnit", yieldUnit)
},
importYieldUnitsAction({ commit }, yieldUnits) { importYieldUnitsAction({ commit }, yieldUnits) {
commit("importYieldUnits", yieldUnits) commit("importYieldUnits", yieldUnits)
}, },
overwriteRecipeAction({ commit }, updatedRecipe) { importMealPlansAction({ commit }, mealPlans) {
commit("overwriteRecipe", updatedRecipe) commit("importMealPlans", mealPlans)
},
addRecipeAction({ commit }, recipe) {
commit("addRecipe", recipe)
},
addYieldUnitAction({ commit }, yieldUnit) {
commit("addYieldUnit", yieldUnit)
},
addCategoryAction({ commit }, category) {
commit("addCategory", category)
},
addMealPlanAction({ commit }, mealPlan) {
commit("addMealPlan", mealPlan)
},
deleteMealPlanAction({ commit }, mealPlan) {
commit("deleteMealPlan", mealPlan)
}, },
deleteRecipeAction({ commit }, recipe) { deleteRecipeAction({ commit }, recipe) {
commit("deleteRecipe", recipe) commit("deleteRecipe", recipe)
}, },
overwriteRecipeAction({ commit }, updatedRecipe) {
commit("overwriteRecipe", updatedRecipe)
},
toggleStateAction({ commit }, toggledRecipe) { toggleStateAction({ commit }, toggledRecipe) {
commit("toggleState", toggledRecipe) commit("toggleState", toggledRecipe)
}, },
@ -420,12 +495,12 @@ export default new Vuex.Store({
setLastTriedDateAction({ commit }, index) { setLastTriedDateAction({ commit }, index) {
commit("setLastTriedDate", index) commit("setLastTriedDate", index)
}, },
setCurrentComponentAction({ commit }, comp) {
commit("setCurrentComponent", comp)
},
renameCategoryAction({ commit }, category) { renameCategoryAction({ commit }, category) {
commit("renameCategory", category) commit("renameCategory", category)
}, },
setCurrentComponentAction({ commit }, comp) {
commit("setCurrentComponent", comp)
},
unSyncCombinationsAction({ commit }, combinations) { unSyncCombinationsAction({ commit }, combinations) {
commit("unSyncCombinations", combinations) commit("unSyncCombinations", combinations)
}, },

View file

@ -2,11 +2,11 @@ import { NativeScriptConfig } from "@nativescript/core"
export default { export default {
id: "com.vishnuraghav.enrecipes", id: "com.vishnuraghav.enrecipes",
appResourcesPath: "app/App_Resources", appResourcesPath: "App_Resources",
android: { android: {
v8Flags: "--expose_gc", v8Flags: "--expose_gc",
markingMode: "none", markingMode: "none",
codeCache: true, codeCache: true,
}, }
appPath: "app", // appPath: "app",
} as NativeScriptConfig } as NativeScriptConfig

688
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,6 @@
"description": "A native application built with NativeScript-Vue", "description": "A native application built with NativeScript-Vue",
"author": "Vishnu Raghav <design@vishnuraghav.com>", "author": "Vishnu Raghav <design@vishnuraghav.com>",
"license": "GPL", "license": "GPL",
"scripts": {
"run": "ns run android"
},
"dependencies": { "dependencies": {
"@nativescript-community/perms": "^2.1.1", "@nativescript-community/perms": "^2.1.1",
"@nativescript-community/ui-material-activityindicator": "^5.0.30", "@nativescript-community/ui-material-activityindicator": "^5.0.30",
@ -27,19 +24,19 @@
"nativescript-ui-calendar": "^7.0.2", "nativescript-ui-calendar": "^7.0.2",
"nativescript-ui-listview": "^9.0.4", "nativescript-ui-listview": "^9.0.4",
"nativescript-ui-sidedrawer": "^9.0.3", "nativescript-ui-sidedrawer": "^9.0.3",
"nativescript-vue": "^2.6.1", "nativescript-vue": "^2.8.1",
"vuex": "^3.3.0" "vuex": "^3.5.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0", "@babel/core": "^7.12.3",
"@babel/preset-env": "^7.0.0", "@babel/preset-env": "^7.12.1",
"@nativescript/android": "7.0.1", "@nativescript/android": "7.0.1",
"@types/node": "^14.0.27", "@nativescript/webpack": "^3.0.8",
"babel-loader": "^8.1.0", "@types/node": "^14.14.8",
"nativescript-vue-template-compiler": "^2.6.0", "babel-loader": "^8.2.1",
"node-sass": "^4.13.1", "nativescript-vue-template-compiler": "^2.8.1",
"vue-loader": "^15.9.1", "node-sass": "^4.14.1",
"@nativescript/webpack": "~3.0.0" "vue-loader": "^15.9.5"
}, },
"main": "main" "main": "main"
} }