ns update

This commit is contained in:
vishnuraghavb 2021-04-01 16:25:35 +05:30
parent 9dc8270709
commit b22669fc63
75 changed files with 3872 additions and 4464 deletions

File diff suppressed because it is too large Load diff

View file

@ -2,32 +2,30 @@
"name": "enrecipes",
"version": "1.0.0",
"description": "A native application built with NativeScript-Vue",
"author": "Vishnu Raghav <apps@vishnuraghav.com>",
"homepage": "https://enrecipes.vercel.app/",
"bugs": {
"url": "https://github.com/vishnuraghavb/EnRecipes/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vishnuraghavb/EnRecipes.git"
},
"license": "GPL",
"author": "Vishnu Raghav <apps@vishnuraghav.com>",
"main": "main",
"dependencies": {
"@nativescript-community/gesturehandler": "^0.1.39",
"@nativescript-community/perms": "^2.1.5",
"@nativescript-community/ui-collectionview": "^4.0.29",
"@nativescript-community/ui-drawer": "^0.0.24",
"@nativescript-community/ui-material-activityindicator": "^5.2.10",
"@nativescript-community/ui-material-button": "^5.2.10",
"@nativescript-community/ui-material-floatingactionbutton": "^5.2.10",
"@nativescript-community/ui-material-progress": "^5.2.10",
"@nativescript-community/ui-material-snackbar": "^5.2.10",
"@nativescript/core": "7.3.0",
"@nativescript/localize": "^5.0.4",
"@nativescript/social-share": "^2.0.4",
"@nativescript/theme": "^3.0.1",
"@nativescript/zip": "^5.0.0",
"@nstudio/nativescript-checkbox": "^2.0.4",
"@triniwiz/nativescript-accelerometer": "^4.0.3",
"@triniwiz/nativescript-couchbase": "^1.2.2",
"nativescript-feedback": "^2.0.0",
"nativescript-imagecropper": "^4.0.1",
"nativescript-intl": "^4.0.2",
"nativescript-plugin-filepicker": "^1.0.0",
"nativescript-toast": "^2.0.0",
"nativescript-vibrate": "^4.0.1",
"nativescript-vue": "^2.8.4",
"vuex": "^3.6.2"
},
@ -35,20 +33,11 @@
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@nativescript/android": "7.0.1",
"@nativescript/webpack": "^3.0.8",
"@nativescript/webpack": "4.1.0",
"@types/node": "^14.14.20",
"babel-loader": "^8.2.2",
"nativescript-vue-template-compiler": "^2.8.3",
"node-sass": "^4.14.1",
"vue-loader": "^15.9.6"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vishnuraghavb/EnRecipes.git"
},
"bugs": {
"url": "https://github.com/vishnuraghavb/EnRecipes/issues"
},
"homepage": "https://enrecipes.vercel.app/",
"main": "main"
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,495 +0,0 @@
<template>
<Page
@loaded="onPageLoad"
actionBarHidden="true"
:androidStatusBarBackground="appTheme == 'Light' ? '#f0f0f0' : '#1A1A1A'"
>
<Drawer
@loaded="drawerLoad"
:gestureEnabled="gestures"
leftSwipeDistance="32"
>
<GridLayout ~leftDrawer rows="*, auto" columns="*" width="280" class="sd">
<StackLayout row="0">
<GridLayout
rows="48"
columns="auto, *, auto"
v-for="(item, index) in topmenu"
:key="index"
class="sd-item mdr"
:class="{
selected: currentComponent === item.component,
}"
@tap="navigateTo(item.component, item.component, false)"
>
<Label col="0" class="er" :text="icon[item.icon]" />
<Label col="1" :text="`${item.title}` | L" />
<Label
class="recipeCount"
v-if="getRecipeCount(item.title)"
:text="getRecipeCount(item.title)"
col="2"
/>
</GridLayout>
<GridLayout
class="sd-group-header"
rows="auto"
columns="*, auto"
v-if="cuisinesWithRecipes.length"
>
<Label
class="filterPath"
verticalAlignment="center"
col="0"
:text="getCurrentPath | L"
textWrap="true"
/>
<MDButton
:visibility="selectedCuisine ? 'visible' : 'hidden'"
variant="text"
@tap="previousRecipeFilter"
class="er"
col="2"
:text="icon.back"
/>
</GridLayout>
<ScrollView height="100%">
<StackLayout>
<GridLayout
v-for="(item, index) in getRecipeList"
:key="index"
class="sd-item mdr"
:class="{
selected: selectedTag == item,
}"
columns="auto, *, auto"
@tap="setFilter && setRecipeFilter(item)"
>
<Label col="0" class="er" :text="icon[selectedFilterType]" />
<Label col="1" :text="`${item}` | L" />
<Label
class="recipeCount"
:text="getRecipeCount(item)"
col="2"
/>
</GridLayout>
<GridLayout
v-if="selectedFilterType == 'tag' && !tagsWithRecipes.length"
columns="*"
rows="*"
>
<Label class="noTags" :text="'noTs' | L" textWrap="true" />
</GridLayout>
</StackLayout>
</ScrollView>
</StackLayout>
<StackLayout row="1">
<GridLayout
rows="48"
columns="auto, *"
class="sd-item mdr"
marginTop="8"
:class="{
selected: currentComponent == 'MealPlanner',
}"
@tap="navigateTo(MealPlanner, 'MealPlanner', true)"
>
<Label col="0" class="er" :text="icon.cal" />
<Label col="2" :text="'planner' | L" />
</GridLayout>
<!-- <GridLayout
rows="48"
columns="auto, *"
class="sd-item tb mdr"
:class="{
selected: currentComponent == 'GroceryList',
}"
@tap="navigateTo(GroceryList, 'GroceryList', true)"
>
<Label col="0" class="er" :text="icon.bag" />
<Label col="2" :text="'grocery' | L" />
</GridLayout>
<GridLayout
rows="48"
columns="auto, *"
class="sd-item tb mdr"
:class="{
selected: currentComponent == 'GroceryList',
}"
@tap="navigateTo(GroceryList, 'GroceryList', true)"
>
<Label col="0" class="er" :text="icon.price" />
<Label col="2" :text="'Price List' | L" />
</GridLayout> -->
<GridLayout
class="sd-item mdr"
:class="{
selected: currentComponent == 'Settings',
}"
rows="48"
columns="auto, *"
@tap="navigateTo(Settings, 'Settings', true)"
>
<Label class="er" col="0" :text="icon.cog" />
<Label col="2" :text="'Settings' | L" />
</GridLayout>
</StackLayout>
</GridLayout>
<Frame ~mainContent id="main-frame">
<EnRecipes
ref="enrecipes"
:filterFavourites="filterFavourites"
:filterTrylater="filterTrylater"
:selectedCuisine="selectedCuisine"
:selectedCategory="selectedCategory"
:selectedTag="selectedTag"
:closeDrawer="closeDrawer"
:hijackGlobalBackEvent="hijackGlobalBackEvent"
:releaseGlobalBackEvent="releaseGlobalBackEvent"
@backToHome="backToHome"
:showDrawer="showDrawer"
@selectModeOn="selectModeOn"
/>
</Frame>
</Drawer>
</Page>
</template>
<script>
import {
ApplicationSettings,
AndroidApplication,
Application,
} from "@nativescript/core";
import Theme from "@nativescript/theme";
import { localize } from "@nativescript/localize";
import { mapActions, mapState } from "vuex";
import EnRecipes from "./EnRecipes";
import ViewRecipe from "./ViewRecipe";
import MealPlanner from "./MealPlanner";
import GroceryList from "./GroceryList";
import Settings from "./Settings";
let filterTimer;
export default {
data() {
return {
selectedCuisine: null,
selectedCategory: null,
selectedTag: null,
selectedFilterType: "cuisine",
filterFavourites: false,
filterTrylater: false,
MealPlanner: MealPlanner,
GroceryList: GroceryList,
Settings: Settings,
topmenu: [
{
title: "EnRecipes",
component: "EnRecipes",
icon: "home",
},
{
title: "trylater",
component: "Try Later",
icon: "try",
},
{
title: "favourites",
component: "Favourites",
icon: "fav",
},
],
appTheme: "Light",
setFilter: true,
gestures: true,
drawer: null,
};
},
components: {
EnRecipes,
ViewRecipe,
MealPlanner,
GroceryList,
Settings,
},
computed: {
...mapState([
"icon",
"recipes",
"cuisines",
"categories",
"yieldUnits",
"mealPlans",
"currentComponent",
]),
getCurrentPath() {
let path = null;
if (this.selectedCuisine) path = localize(this.selectedCuisine);
else path = "cuis";
if (this.selectedCategory)
path += " > " + localize(this.selectedCategory);
if (this.selectedTag) path += " > " + localize(this.selectedTag);
return path;
},
getRecipeList() {
switch (this.selectedFilterType) {
case "cuisine":
return this.cuisinesWithRecipes;
break;
case "category":
return this.categoriesWithRecipes;
break;
case "tag":
return this.tagsWithRecipes;
break;
}
},
cuisinesWithRecipes() {
let arr = this.recipes.map((e) => e.cuisine).sort();
return arr.length ? ["allCuis", ...new Set(arr)] : [];
},
categoriesWithRecipes() {
let arr = this.recipes
.map(
(e) =>
(this.selectedCuisine === "allCuis" ||
e.cuisine === this.selectedCuisine) &&
e.category
)
.filter((e) => e)
.sort();
return arr.length ? ["allCats", ...new Set(arr)] : [];
},
tagsWithRecipes() {
let arr = this.recipes
.map((e) => {
if (
this.selectedCuisine === "allCuis" &&
this.selectedCategory === "allCats" &&
e.tags.length
)
return e.tags;
else if (
this.selectedCuisine === "allCuis" &&
e.category === this.selectedCategory &&
e.tags.length
)
return e.tags;
else if (
this.selectedCategory === "allCats" &&
e.cuisine === this.selectedCuisine &&
e.tags.length
)
return e.tags;
else if (
e.category === this.selectedCategory &&
e.cuisine === this.selectedCuisine &&
e.tags.length
)
return e.tags;
})
.flat()
.filter((e) => e)
.sort();
let showAllTags =
this.selectedCuisine === "allCuis" &&
this.selectedCategory === "allCats";
return arr.length
? [!showAllTags && "allTs", ...new Set(arr)].filter((e) => e)
: [];
},
},
methods: {
...mapActions([
"setCurrentComponentAction",
"initializeListItems",
"initializeRecipes",
"initializeMealPlans",
"setShakeAction",
"setLayout",
]),
onPageLoad() {
if (this.appTheme === "Light") {
const View = android.view.View;
const window = Application.android.startActivity.getWindow();
const decorView = window.getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
},
drawerLoad(args) {
this.drawer = args.object;
},
// HELPERS
setRecipeFilter(item) {
this.setFilter = this.filterFavourites = this.filterTrylater = false;
this.$navigateBack({
frame: "main-frame",
backstackVisible: false,
});
setTimeout((e) => {
if (this.selectedCuisine == null) {
this.selectedCuisine = item;
this.selectedFilterType = "category";
} else if (this.selectedCategory == null) {
this.selectedCategory = item;
this.selectedFilterType = "tag";
if (!this.tagsWithRecipes.length) this.closeDrawer();
} else {
this.selectedTag = item;
this.closeDrawer();
}
this.setFilter = true;
}, 250);
this.setCurrentComponentAction("Filtered recipes");
},
previousRecipeFilter() {
if (this.selectedCategory) {
this.selectedFilterType = "category";
this.selectedTag = this.selectedCategory = null;
this.setCurrentComponentAction("Filtered recipes");
} else {
this.selectedFilterType = "cuisine";
this.selectedCuisine = null;
this.setCurrentComponentAction("EnRecipes");
}
},
showDrawer() {
this.drawer.open();
},
closeDrawer() {
this.drawer.close();
},
getRecipeCount(arg) {
let count = "";
switch (arg) {
case "EnRecipes":
count = this.recipes.length;
break;
case "trylater":
count = this.recipes.filter((e) => !e.tried).length;
break;
case "favourites":
count = this.recipes.filter((e) => e.isFavorite).length;
break;
default: {
switch (this.selectedFilterType) {
case "cuisine":
count = this.recipes.filter((e) =>
arg === "allCuis" ? e.cuisine : e.cuisine === arg
).length;
break;
case "category":
count = this.recipes.filter((e) =>
this.selectedCuisine === "allCuis"
? arg === "allCats"
? e.category
: e.category === arg
: arg === "allCats"
? e.cuisine === this.selectedCuisine && e.category
: e.cuisine === this.selectedCuisine && e.category === arg
).length;
break;
case "tag":
count = this.recipes.filter((e) => {
if (
this.selectedCuisine === "allCuis" &&
this.selectedCategory === "allCats"
) {
return e.tags.includes(arg) || arg === "allTs";
} else if (
this.selectedCuisine === "allCuis" &&
e.category === this.selectedCategory
) {
return e.tags.includes(arg) || arg === "allTs";
} else if (
this.selectedCategory === "allCats" &&
e.cuisine === this.selectedCuisine
) {
return e.tags.includes(arg) || arg === "allTs";
} else if (
e.category === this.selectedCategory &&
e.cuisine === this.selectedCuisine
) {
return e.tags.includes(arg) || arg === "allTs";
}
}).length;
break;
}
}
}
return count;
},
selectModeOn(bool) {
this.gestures = bool;
},
// NAVIGATION HANDLERS
hijackGlobalBackEvent() {
AndroidApplication.on(
AndroidApplication.activityBackPressedEvent,
this.globalBackEvent
);
},
releaseGlobalBackEvent() {
AndroidApplication.off(
AndroidApplication.activityBackPressedEvent,
this.globalBackEvent
);
},
globalBackEvent(args) {
if (this.drawer && this.drawer.isOpened()) {
args.cancel = true;
this.closeDrawer();
} else if (
["Favourites", "Try Later", "Filtered recipes"].includes(
this.currentComponent
)
) {
args.cancel = true;
this.backToHome();
}
},
backToHome() {
this.setCurrentComponentAction("EnRecipes");
this.filterFavourites = this.filterTrylater = false;
this.selectedTag = this.selectedCategory = this.selectedCuisine = null;
this.selectedFilterType = "cuisine";
},
navigateTo(to, title, isTrueComponent) {
if (title !== this.currentComponent) {
if (isTrueComponent) {
this.$navigateTo(to, {
backstackVisible: true,
});
this.closeDrawer();
} else {
this.setCurrentComponentAction(to);
this.$navigateBack({
frame: "main-frame",
backstackVisible: false,
});
this.filterFavourites = to === "Favourites";
this.filterTrylater = to === "Try Later";
this.closeDrawer();
this.selectedTag = this.selectedCategory = this.selectedCuisine = null;
this.selectedFilterType = "cuisine";
}
} else {
this.closeDrawer();
}
},
},
created() {
this.setLayout(ApplicationSettings.getString("layout", "detailed"));
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
setTimeout((e) => {
Theme.setMode(Theme[this.appTheme]);
}, 10);
if (!this.recipes.length) this.initializeRecipes();
this.initializeListItems();
if (!this.mealPlans.length) this.initializeMealPlans();
this.setShakeAction(ApplicationSettings.getBoolean("shakeEnabled", true));
},
};
</script>

View file

@ -1,63 +1,34 @@
<template>
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *, auto">
<MDButton
variant="text"
class="er"
:text="icon.back"
automationText="Back"
col="0"
@tap="navigateBack"
/>
<Label class="title tb" :text="`${title}` | L" col="1" />
<MDButton
variant="text"
v-if="hasChanges && !saving"
class="er"
:text="icon.save"
col="2"
@tap="saveOperation"
/>
<MDActivityIndicator col="2" v-if="saving" :busy="saving" />
</GridLayout>
</ActionBar>
<ScrollView width="100%" height="100%">
<StackLayout width="100%" padding="0 0 88">
<AbsoluteLayout>
<StackLayout
width="100%"
:height="screenWidth"
class="imageHolder"
verticalAlignment="center"
>
<Image
v-if="recipeContent.imageSrc"
:src="recipeContent.imageSrc"
stretch="aspectFill"
width="100%"
:height="screenWidth"
/>
<Label
v-else
horizontalAlignment="center"
class="er"
fontSize="160"
:text="icon.img"
/>
</StackLayout>
<!-- <transition :name="recipeContent.imageSrc ? 'null' : 'bounce'">
<MDFloatingActionButton
v-if="showFab"
:top="screenWidth - 44"
:left="screenWidth - 88"
class="er"
src="res://cam"
@tap="imageHandler"
/>
</transition> -->
</AbsoluteLayout>
<StackLayout margin="0 16 24">
<Page @loaded="onPageLoad" @unloaded="onPageUnload" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ScrollView
rowSpan="2"
colSpan="2"
@scroll="!showUndo && onScroll($event)"
>
<StackLayout padding="0 16 72">
<Label class="pageTitle" padding="16 0" :text="`${title}` | L" />
<Image
margin="8 0 32"
v-if="recipeContent.imageSrc"
:src="recipeContent.imageSrc"
stretch="aspectFit"
class="imgHolder"
:width="screenWidth - 32"
:height="screenWidth - 32"
@tap="imageHandler"
/>
<Button
v-else
margin="8 0 32"
class="ico imgHolder"
fontSize="128"
:width="screenWidth - 32"
:height="screenWidth - 32"
:text="icon.img"
@tap="imageHandler"
/>
<!-- OVERVIEW -->
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'title' | L" />
<TextField
@ -66,11 +37,11 @@
@loaded="setInputTypeText($event, 'words')"
/>
</StackLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<GridLayout columns="*, 8, *">
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'cui' | L" />
<TextField
:text="`${recipeContent.cuisine}` | L"
:text="recipeContent.cuisine | L"
editable="false"
@focus="modalOpen === false && showCuisine(true)"
@tap="showCuisine(false)"
@ -80,7 +51,7 @@
<Label class="fieldLabel" :text="'cat' | L" />
<TextField
ref="category"
:text="`${recipeContent.category}` | L"
:text="recipeContent.category | L"
editable="false"
@focus="modalOpen === false && showCategories(true)"
@tap="showCategories(false)"
@ -88,23 +59,18 @@
</StackLayout>
</GridLayout>
<StackLayout class="inputField">
<Label
class="fieldLabel"
:text="`${$options.filters.L('ts')} (${$options.filters.L(
'tsInfo'
)})`"
/>
<Label class="fieldLabel" :text="'ts' | L" />
<TextField
:hint="'tsInfo' | L"
autocapitalizationType="words"
ref="tags"
:hint="`${$options.filters.L('tsInfo')}`"
v-model="tags"
@textChange="splitTags"
returnKeyType="next"
/>
</StackLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<GridLayout columns="*, 8, *">
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'prepT' | L" />
<TextField
:text="timeRequired('prepTime')"
@ -128,8 +94,8 @@
/>
</StackLayout>
</GridLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<GridLayout columns="*, 8, *">
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'yieldQ' | L" />
<TextField
ref="yieldQuantity"
@ -149,8 +115,8 @@
/>
</StackLayout>
</GridLayout>
<GridLayout columns="*, 16, *">
<StackLayout class="inputField" col="0">
<GridLayout columns="*, 8, *">
<StackLayout class="inputField">
<Label class="fieldLabel" :text="'Difficulty level' | L" />
<TextField
ref="difficultyLevel"
@ -161,25 +127,18 @@
/>
</StackLayout>
</GridLayout>
</StackLayout>
<StackLayout margin="0 16 32">
<!-- INGREDIENTS -->
<Label
margin="0 0 16"
:text="`${$options.filters.L('ings')}${
recipeContent.ingredients.length
? ' - ' + recipeContent.ingredients.length
: ''
}`"
:text="getTitleCount('ings', 'ingredients')"
class="sectionTitle"
/>
<GridLayout
columns="auto,16,auto,16,*,16,auto"
columns="auto,8,auto,8,*,8,auto"
v-for="(ingredient, index) in recipeContent.ingredients"
:key="index"
:key="'ing' + index"
>
<TextField
width="60"
col="0"
@loaded="
!recipeContent.ingredients[index].item && focusField($event)
"
@ -209,107 +168,121 @@
"
/>
<MDButton
variant="text"
<Button
col="6"
class="er x"
class="ico x"
:text="icon.x"
@tap="removeIngredient(index)"
/>
</GridLayout>
<MDButton
variant="text"
class="text-btn tb"
:text="`+ ${$options.filters.L('aIngBtn')}`"
<Button
class="text big"
:text="'aIngBtn' | L"
@tap="addIngredient()"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'inss' | L" class="sectionTitle" />
<!-- INSTRUCTIONS -->
<Label
:text="getTitleCount('inss', 'instructions')"
class="sectionTitle"
/>
<GridLayout
columns="*,8,auto"
v-for="(instruction, index) in recipeContent.instructions"
:key="index"
:key="'ins' + index"
>
<TextView
@loaded="focusField($event, 'multiLine')"
col="0"
:hint="`${$options.filters.L('stp')} ${index + 1}`"
v-model="recipeContent.instructions[index]"
/>
<MDButton
variant="text"
<Button
col="2"
class="er x"
class="ico x"
:text="icon.x"
@tap="removeInstruction(index)"
/>
</GridLayout>
<MDButton
variant="text"
class="text-btn tb"
:text="`+ ${$options.filters.L('aStpBtn')}`"
<Button
class="text big"
:text="'aStpBtn' | L"
@tap="addInstruction"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'nos' | L" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(note, index) in recipeContent.notes"
:key="index"
>
<TextView
@loaded="focusField($event, 'multiLine')"
col="0"
:hint="`${$options.filters.L('no')} ${index + 1}`"
v-model="recipeContent.notes[index]"
/>
<MDButton
variant="text"
col="2"
class="er x"
:text="icon.x"
@tap="removeNote(index)"
/>
</GridLayout>
<MDButton
variant="text"
class="text-btn tb"
:text="`+ ${$options.filters.L('aNoBtn')}`"
@tap="addNote"
<!-- COMBINATIONS -->
<Label
:text="getTitleCount('cmbs', 'combinations')"
class="sectionTitle"
/>
</StackLayout>
<StackLayout margin="0 16 32">
<Label margin="0 0 16" :text="'cmbs' | L" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(combination, index) in recipeContent.combinations"
:key="index"
:key="'cmbs' + index"
>
<TextField
class="combinationToken"
col="0"
class="combField"
:text="getCombinationTitle(combination)"
editable="false"
/>
<MDButton
variant="text"
<Button
col="2"
class="er x"
class="ico x"
:text="icon.x"
@tap="removeCombination(combination)"
/>
</GridLayout>
<MDButton
variant="text"
class="text-btn tb"
:text="`+ ${$options.filters.L('addCmbBtn')}`"
<Button
class="text big"
:text="'addCmbBtn' | L"
@tap="showCombinations"
/>
<!-- NOTES -->
<Label :text="getTitleCount('nos', 'notes')" class="sectionTitle" />
<GridLayout
columns="*,8,auto"
v-for="(note, index) in recipeContent.notes"
:key="'nos' + index"
>
<TextView
@loaded="focusField($event, 'multiLine')"
:hint="`${$options.filters.L('no')} ${index + 1}`"
v-model="recipeContent.notes[index]"
/>
<Button
col="2"
class="ico x"
:text="icon.x"
@tap="removeNote(index)"
/>
</GridLayout>
<Button class="text big" :text="'aNoBtn' | L" @tap="addNote" />
</StackLayout>
</StackLayout>
</ScrollView>
</ScrollView>
<GridLayout
row="1"
@loaded="onAppBarLoad"
:colSpan="hasChanges || showUndo ? '2' : '1'"
class="appbar"
:class="{ snackBar: showUndo }"
columns="auto, *, auto"
>
<Button v-if="showUndo" :text="countdown" class="countdown tb" />
<Button v-else class="ico" :text="icon.back" @tap="navigateBack" />
<Label
class="title"
verticalAlignment="center"
col="1"
v-if="showUndo"
:text="snackMsg | L"
/>
<Button
v-if="(hasChanges && !saving) || showUndo"
class="ico fab"
:text="showUndo ? icon.alert : icon.save"
col="2"
@tap="showUndo ? undoDel() : saveOperation()"
/>
<ActivityIndicator margin="16" col="2" v-if="saving" :busy="saving" />
</GridLayout>
</GridLayout>
</Page>
</template>
@ -332,22 +305,18 @@ import * as Toast from "nativescript-toast";
import * as Filepicker from "nativescript-plugin-filepicker";
import { ImageCropper } from "nativescript-imagecropper";
import { localize } from "@nativescript/localize";
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
const snackbar = new SnackBar();
import { mapState, mapActions } from "vuex";
import ViewRecipe from "./ViewRecipe.vue";
import ActionDialog from "./modal/ActionDialog.vue";
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
import ConfirmDialog from "./modal/ConfirmDialog.vue";
import PromptDialog from "./modal/PromptDialog.vue";
import ListPicker from "./modal/ListPicker.vue";
import ViewRecipe from "./ViewRecipe";
import * as utils from "~/shared/utils";
let undoTimer;
export default {
props: [
"recipeID",
"selectedCuisine",
"selectedCategory",
"selectedTag",
"filterFavourites",
"filterTrylater",
"navigationFromView",
@ -390,6 +359,12 @@ export default {
cacheImagePath: null,
unSyncCombinations: [],
difficultyLevels: ["Easy", "Moderate", "Challenging"],
appbar: null,
scrollPos: 1,
countdown: 5,
snackMsg: null,
showUndo: false,
undo: false,
};
},
computed: {
@ -401,6 +376,9 @@ export default {
"cuisines",
"categories",
"currentComponent",
"selectedCuisine",
"selectedCategory",
"selectedTag",
]),
screenWidth() {
return Screen.mainScreen.widthDIPs;
@ -417,7 +395,7 @@ export default {
},
methods: {
...mapActions([
"setCurrentComponentAction",
"setComponent",
"addRecipeAction",
"overwriteRecipeAction",
"addListItemAction",
@ -430,7 +408,32 @@ export default {
},
onPageUnload() {
this.releaseBackEvent();
snackbar.dismiss();
},
onAppBarLoad({ object }) {
this.appbar = object;
},
onScroll(args) {
let scrollUp;
let y = args.scrollY;
if (y) {
scrollUp = y < this.scrollPos;
this.scrollPos = Math.abs(y);
let ab = this.appbar.translateY;
if (!scrollUp && ab == 0) {
this.animateInOut(
250,
false,
(val) => (this.appbar.translateY = val * 64)
);
} else if (scrollUp && ab == 64) {
Utils.ad.dismissSoftInput();
this.animateInOut(
250,
true,
(val) => (this.appbar.translateY = val * 64)
);
}
}
},
timeRequired(time) {
let t = this.recipeContent[time].split(":");
@ -514,6 +517,11 @@ export default {
}
});
},
getTitleCount(title, type) {
let count = this.recipeContent[type].length;
let text = count ? ` (${count})` : "";
return localize(title) + text;
},
// DATA LIST
showCuisine(focus) {
this.modalOpen = true;
@ -522,9 +530,7 @@ export default {
props: {
title: "cui",
list: this.cuisines,
stretch: true,
action: "aNBtn",
helpIcon: "cuisine",
},
}).then((action) => {
if (action == "aNBtn") {
@ -532,7 +538,6 @@ export default {
props: {
title: "newCui",
action: "aBtn",
helpIcon: "cuisine",
},
}).then((item) => {
this.hijackBackEvent();
@ -566,9 +571,7 @@ export default {
props: {
title: "cat",
list: this.categories,
stretch: true,
action: "aNBtn",
helpIcon: "category",
},
}).then((action) => {
if (action == "aNBtn") {
@ -576,7 +579,6 @@ export default {
props: {
title: "nwCat",
action: "aBtn",
helpIcon: "category",
},
}).then((item) => {
this.hijackBackEvent();
@ -610,9 +612,7 @@ export default {
props: {
title: "yieldU",
list: this.yieldUnits,
stretch: true,
action: "aNBtn",
helpIcon: "yield",
},
}).then((action) => {
if (action == "aNBtn") {
@ -620,7 +620,6 @@ export default {
props: {
title: "nwYiU",
action: "aBtn",
helpIcon: "yield",
},
}).then((item) => {
this.hijackBackEvent();
@ -654,9 +653,6 @@ export default {
props: {
title: "Difficulty level",
list: this.difficultyLevels,
stretch: false,
helpIcon: "diff",
count: 3,
},
}).then((action) => {
if (action) {
@ -679,9 +675,7 @@ export default {
props: {
title: "Unit",
list: this.units,
stretch: true,
action: "aNBtn",
helpIcon: "unit",
},
}).then((action) => {
if (action == "aNBtn") {
@ -689,7 +683,6 @@ export default {
props: {
title: "newUnit",
action: "aBtn",
helpIcon: "unit",
},
}).then((item) => {
this.hijackBackEvent();
@ -728,17 +721,6 @@ export default {
}, 100);
},
// NAVIGATION HANDLERS
navigateBackController() {
if (this.navigationFromView) {
this.$navigateTo(ViewRecipe, {
props: {
filterTrylater: this.filterTrylater,
recipeID: this.recipeID,
},
backstackVisible: false,
});
} else this.$navigateBack();
},
navigateBack() {
if (this.hasChanges) {
this.blockModal = true;
@ -748,18 +730,16 @@ export default {
description: localize("disc"),
cancelButtonText: "disBtn",
okButtonText: "kEdit",
helpIcon: "alert",
iconColor: "#c92a2a",
},
}).then((action) => {
this.blockModal = false;
if (action != null && !action) {
this.navigateBackController();
this.$navigateBack();
this.releaseBackEvent();
}
});
} else {
this.navigateBackController();
this.$navigateBack();
this.releaseBackEvent();
}
},
@ -783,24 +763,25 @@ export default {
},
// DATA HANDLERS
imageHandler() {
this.clearEmptyFields();
this.clearEmptyFields(true);
if (this.recipeContent.imageSrc) {
this.blockModal = true;
this.$showModal(ConfirmDialog, {
props: {
title: "recPic",
cancelButtonText: "rBtn",
secondButtonText: "rBtn",
cancelButtonText: "cBtn",
okButtonText: "repBtn",
helpIcon: "img",
iconColor: "#1a1a1a",
},
}).then((action) => {
this.blockModal = false;
if (action) {
if (action > 0) {
this.permissionCheck(this.permissionConfirmation, this.imagePicker);
} else if (action != null) {
} else if (action < 0) {
this.recipeContent.imageSrc = null;
this.releaseBackEvent();
} else if (action != null) {
this.releaseBackEvent();
}
});
} else {
@ -814,8 +795,6 @@ export default {
description: localize("reqAcc"),
cancelButtonText: "nNBtn",
okButtonText: "conBtn",
helpIcon: "folder",
iconColor: "#ff5200",
},
});
},
@ -877,9 +856,9 @@ export default {
toolbarTitle: localize("cPic"),
statusBarColor: "#ff5200",
toolbarTextColor:
this.appTheme == "light" ? "#1A1A1A" : "#e0e0e0",
this.appTheme == "light" ? "#1A1A1A" : "#e9ecef",
toolbarColor:
this.appTheme == "light" ? "#e0e0e0" : "#1A1A1A",
this.appTheme == "light" ? "#e9ecef" : "#1A1A1A",
cropFrameColor: "#ff5200",
}
)
@ -892,9 +871,10 @@ export default {
},
// INPUT FIELD HANDLERS
splitTags() {
let tags = [];
let string;
if (this.tags) {
let tags = this.tags
tags = this.tags
.split(" ")
.map((e) => {
string = e.replace(/^[^\w\s]+/, "");
@ -903,22 +883,38 @@ export default {
}
})
.filter((e) => e);
this.recipeContent.tags = tags;
}
this.recipeContent.tags = tags;
},
joinTags() {
this.tags = this.recipeContent.tags.join(" ");
},
undoDeletion(message) {
return snackbar.action({
message,
textColor: this.appTheme == "light" ? "#fff" : "#292929",
actionTextColor: "#ff5200",
backgroundColor: this.appTheme == "light" ? "#292929" : "#fff",
actionText: localize("undo"),
hideDelay: 5000,
showUndoBar(message) {
return new Promise((resolve, reject) => {
this.showUndo = true;
this.appbar.translateY = 0;
this.snackMsg = message;
this.countdown = 5;
let a = 5;
clearTimeout(undoTimer);
undoTimer = setInterval(() => {
if (this.undo) {
this.showUndo = this.undo = false;
clearTimeout(undoTimer);
resolve(true);
}
this.countdown = Math.round((a -= 0.1));
if (this.countdown < 1) {
this.showUndo = false;
clearTimeout(undoTimer);
reject(true);
}
}, 100);
});
},
undoDel() {
this.undo = true;
},
addIngredient() {
let ingredients = this.recipeContent.ingredients;
let unit = ingredients.length
@ -935,10 +931,9 @@ export default {
if (this.recipeContent.ingredients[index].item.length) {
let item = this.recipeContent.ingredients[index];
this.recipeContent.ingredients.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmIng")}`).then((res) => {
if (res.command === "action")
this.recipeContent.ingredients.splice(index, 0, item);
});
this.showUndoBar("rmIng").then(
(res) => res && this.recipeContent.ingredients.splice(index, 0, item)
);
} else {
this.recipeContent.ingredients.splice(index, 1);
}
@ -951,11 +946,9 @@ export default {
if (this.recipeContent.instructions[index].length) {
let item = this.recipeContent.instructions[index];
this.recipeContent.instructions.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmIns")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.instructions.splice(index, 0, item);
}
});
this.showUndoBar("rmIns").then(
(res) => res && this.recipeContent.instructions.splice(index, 0, item)
);
} else this.recipeContent.instructions.splice(index, 1);
},
addNote() {
@ -965,17 +958,16 @@ export default {
if (this.recipeContent.notes[index].length) {
let item = this.recipeContent.notes[index];
this.recipeContent.notes.splice(index, 1);
this.undoDeletion(`${this.$options.filters.L("rmN")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.notes.splice(index, 0, item);
}
});
this.showUndoBar("rmN").then((res) =>
this.recipeContent.notes.splice(index, 0, item)
);
} else this.recipeContent.notes.splice(index, 1);
},
getCombinationTitle(id) {
return this.recipes.filter((e) => e.id === id)[0].title;
},
showCombinations() {
Utils.ad.dismissSoftInput();
this.modalOpen = true;
this.releaseBackEvent();
let existingCombinations = [
@ -989,7 +981,6 @@ export default {
props: {
title: "selRec",
recipes: filteredRecipes,
helpIcon: "comb",
},
}).then((res) => {
this.hijackBackEvent();
@ -1002,15 +993,13 @@ export default {
let index = this.recipeContent.combinations.indexOf(id);
this.recipeContent.combinations.splice(index, 1);
this.unSyncCombinations.push(id);
this.undoDeletion(`${this.$options.filters.L("rmCmb")}`).then((res) => {
if (res.command === "action") {
this.recipeContent.combinations.splice(index, 0, id);
}
});
this.showUndoBar("rmCmb").then((res) =>
this.recipeContent.combinations.splice(index, 0, id)
);
},
// SAVE OPERATION
clearEmptyFields() {
if (!this.recipeContent.title)
clearEmptyFields(bool) {
if (!this.recipeContent.title && !bool)
this.recipeContent.title = localize("untRec");
if (!this.recipeContent.yield.quantity)
this.recipeContent.yield.quantity = 1;
@ -1084,12 +1073,12 @@ export default {
setTimeout(() => {
this.saving = false;
}, 100);
this.navigateBackController();
this.$navigateBack();
},
},
created() {
setTimeout((e) => {
this.setCurrentComponentAction("EditRecipe");
this.setComponent("EditRecipe");
}, 500);
this.title = this.recipeID ? "editRec" : "newRec";
if (this.recipeID) {

File diff suppressed because it is too large Load diff

View file

@ -2,22 +2,9 @@
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *, auto">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Button class="ico left" :text="icon.back" @tap="$navigateBack()" />
<Label class="title tb" :text="'grocery' | L" col="1" />
<MDButton
class="er left"
variant="text"
:text="icon.today"
automationText="today"
col="2"
/>
<Button class="ico left" :text="icon.today" col="2" />
</GridLayout>
</ActionBar>
<GridLayout columns="" rows=""> </GridLayout>
@ -26,8 +13,6 @@
<script>
import { ApplicationSettings, Observable } from "@nativescript/core";
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
const snackbar = new SnackBar();
import { mapState, mapActions } from "vuex";
export default {
data() {
@ -42,11 +27,11 @@ export default {
},
},
methods: {
...mapActions(["setCurrentComponentAction"]),
...mapActions(["setComponent"]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
this.setCurrentComponentAction("GroceryList");
this.setComponent("GroceryList");
},
// HELPERS
@ -64,16 +49,6 @@ export default {
}
},
// DATA HANDLERS
undoRemove(message) {
return snackbar.action({
message,
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
actionTextColor: "#ff5200",
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
actionText: "Undo",
hideDelay: 5000,
});
},
},
created() {
this.appTheme = ApplicationSettings.getString("appTheme", "Light");

View file

@ -1,159 +1,138 @@
<template>
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *, auto, auto">
<MDButton
class="er"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'planner' | L" col="1" />
<MDButton
class="er"
variant="text"
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="*">
<ScrollView
@scroll="!edit && onScroll($event)"
rowSpan="2"
scrollBarIndicatorVisible="false"
>
<StackLayout>
<Label class="pageTitle" :text="'planner' | L" />
<GridLayout
class="calendar"
columns="*, *, *, *, *, *, *"
rows="auto, auto, auto, auto, auto, auto, auto, auto"
>
<Button class="ico navBtn" :text="icon.left" @tap="prevMonth" />
<Label
class="monthName"
col="1"
colSpan="5"
:text="$options.filters.L(mNames[month]) + ' ' + year"
/>
<Button
class="ico navBtn"
col="6"
:text="icon.right"
@tap="nextMonth"
/>
<Label
class="dayName"
row="1"
:col="i"
v-for="(d, i) in dNames"
:key="d"
:text="d | L"
/>
<Button
class="min day"
:class="{
tb: isToday(d),
activeDay: isActive(d),
hasPlans: hasPlans(d),
}"
:row="getrow(i)"
:col="i % 7"
v-for="(d, i) in getCal"
:key="i"
:text="d ? d : null"
@tap="setToday(d)"
/>
</GridLayout>
<StackLayout class="dayPlan">
<StackLayout
v-for="(mealType, index) in mealTimesWithRecipes"
:key="'mealType' + index"
>
<GridLayout columns="auto, auto">
<Label
class="periodLabel tb"
:class="mealType"
:text="mealType | L"
/>
<Button
:visibility="edit ? 'visible' : 'hidden'"
col="1"
class="ico"
:text="icon.plus"
@tap="addRecipe(mealType)"
/>
</GridLayout>
<GridLayout
:columns="`*, ${edit ? 'auto' : 0}`"
v-for="(recipeID, index) in getRecipes[mealType]"
:key="mealType + index"
>
<Button
class="recipeTitle"
:text="getRecipeTitle(recipeID)"
@tap="viewRecipe(recipeID)"
/>
<Button
:visibility="edit ? 'visible' : 'hidden'"
col="1"
class="ico x"
:text="icon.x"
@tap="removeRecipe(recipeID, mealType)"
/>
</GridLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
<GridLayout
row="1"
@loaded="onAppBarLoad"
class="appbar"
v-show="!showUndo"
columns="auto, *, auto, auto"
>
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
<Button
class="ico"
:text="icon.tod"
automationText="today"
v-if="!isExactlyToday"
@tap="goToToday"
col="2"
/>
<MDButton
class="er"
variant="text"
<Button
class="ico fab"
:text="edit ? icon.done : icon.edit"
automationText="edit"
@tap="edit = !edit"
@tap="toggleEditMode"
col="3"
/>
</GridLayout>
</ActionBar>
<ScrollView width="100%" height="100%">
<GridLayout rows="auto, *">
<GridLayout
class="calendar"
width="100%"
row="0"
columns="*, *, *, *, *, *, *"
rows="auto, auto, auto, auto, auto, auto, auto, auto"
>
<MDButton
variant="text"
class="er navBtn"
col="0"
:text="icon.left"
@tap="prevMonth"
/>
<Label
class="monthName"
col="1"
colSpan="5"
:text="$options.filters.L(mNames[month]) + ' ' + year"
/>
<MDButton
variant="text"
class="er navBtn"
col="6"
:text="icon.right"
@tap="nextMonth"
/>
<Label
class="dayName"
row="1"
:col="i"
v-for="(d, i) in dNames"
:key="d"
:text="$options.filters.L(d)"
/>
<Label
@loaded="centerLabel"
class="day tb"
:class="{
today: isToday(d),
activeDay: isActive(d),
hasPlans: hasPlans(d),
}"
:row="getrow(i)"
:col="i % 7"
v-for="(d, i) in getCal"
:key="i"
:text="d ? d : null"
@tap="setToday(d)"
/>
</GridLayout>
<StackLayout row="1" class="dayPlan" margin="16 0 0">
<StackLayout
v-for="(mealType, index) in mealTimes"
:key="'mealType' + index"
class="plansContainer"
:class="mealType"
>
<GridLayout columns="auto, auto" class="header">
<Label
col="0"
@tap="edit = true"
class="periodLabel tb"
:text="mealType | L"
/>
<MDButton
:visibility="edit ? 'visible' : 'hidden'"
col="1"
variant="text"
class="er"
:text="icon.plus"
@tap="addRecipe(mealType)"
/>
</GridLayout>
<GridLayout
class="recipe"
:paddingTop="index == 0 ? 8 : 0"
:columns="`*, ${edit ? 'auto' : 0}`"
v-for="(recipeID, index) in getRecipes[mealType]"
:key="mealType + index"
>
<!-- elevation="1" -->
<GridLayout
col="0"
columns="*"
class="titleContainer mdr"
@tap="viewRecipe(recipeID)"
>
<Label
verticalAlignment="center"
class="recipeTitle"
:text="getRecipeTitle(recipeID)"
textWrap="true"
/>
</GridLayout>
<MDButton
:visibility="edit ? 'visible' : 'hidden'"
variant="text"
col="1"
class="er x"
:text="icon.x"
@tap="removeRecipe(recipeID, mealType)"
/>
</GridLayout>
</StackLayout>
</StackLayout>
<GridLayout
row="1"
class="appbar snackBar"
v-show="showUndo"
columns="auto, *, auto"
>
<Button :text="countdown" class="countdown tb" />
<Label class="title" col="1" :text="snackMsg | L" />
<Button class="ico fab" :text="icon.alert" @tap="undoDel" col="3" />
</GridLayout>
</ScrollView>
</GridLayout>
</Page>
</template>
<script>
import {
ApplicationSettings,
Page,
Observable,
GestureTypes,
} from "@nativescript/core";
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
const snackbar = new SnackBar();
import { ApplicationSettings, Observable } from "@nativescript/core";
import { mapState, mapActions } from "vuex";
import ViewRecipe from "./ViewRecipe.vue";
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
let undoTimer;
export default {
data() {
return {
@ -178,6 +157,12 @@ export default {
month: 0,
today: null,
edit: false,
scrollPos: 1,
appbar: null,
countdown: 5,
snackMsg: null,
showUndo: false,
undo: false,
};
},
computed: {
@ -208,23 +193,61 @@ export default {
}
return days;
},
isExactlyToday() {
let d = new Date();
return (
this.year == d.getFullYear() &&
this.month == d.getMonth() &&
this.today == d.getDate()
);
},
mealTimesWithRecipes() {
return this.mealTimes.filter(
(e) => (this.getRecipes[e] && this.getRecipes[e].length) || this.edit
);
},
},
methods: {
...mapActions([
"setCurrentComponentAction",
"setComponent",
"addMealPlanAction",
"deleteMealPlanAction",
]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
this.setCurrentComponentAction("MealPlanner");
this.setComponent("MealPlanner");
if (!this.today || this.today === new Date().getDate()) this.goToToday();
},
onPageUnload(args) {
snackbar.dismiss();
onAppBarLoad({ object }) {
this.appbar = object;
},
onScroll(args) {
let scrollUp;
let y = args.scrollY;
if (y) {
scrollUp = y < this.scrollPos;
this.scrollPos = Math.abs(y);
let ab = this.appbar.translateY;
if (!scrollUp && ab == 0) {
this.animateInOut(
250,
false,
(val) => (this.appbar.translateY = val * 64)
);
} else if (scrollUp && ab == 64) {
this.animateInOut(
250,
true,
(val) => (this.appbar.translateY = val * 64)
);
}
}
},
// HELPERS
showAppBar() {
this.appbar.translateY = 0;
},
getrow(i) {
return Math.floor(2 + i / 7);
},
@ -237,9 +260,6 @@ export default {
let recipe = this.recipes.filter((e) => e.id === id)[0];
return recipe ? recipe.title : `[ ${this.$options.filters.L("resNF")} ]`;
},
centerLabel(args) {
args.object.android.setGravity(17);
},
// NAVIGATION HANDLERS
viewRecipe(recipeID) {
@ -250,6 +270,12 @@ export default {
filterTrylater: true,
recipeID,
},
transition: {
name: "fade",
duration: 250,
curve: "easeOut",
},
// backstackVisible: false,
});
}
},
@ -259,18 +285,21 @@ export default {
this.year--;
this.month = 11;
} else this.month--;
this.showAppBar();
},
nextMonth() {
if (this.month == 11) {
this.year++;
this.month = 0;
} else this.month++;
this.showAppBar();
},
goToToday() {
let d = new Date();
this.year = d.getFullYear();
this.month = d.getMonth();
this.today = d.getDate();
this.showAppBar();
},
isToday(date) {
let d = new Date();
@ -298,6 +327,9 @@ export default {
index,
});
},
toggleEditMode() {
this.edit = !this.edit;
},
// DATA HANDLERS
addRecipe(type) {
let filteredRecipes = this.recipes.filter((e) =>
@ -307,7 +339,6 @@ export default {
props: {
title: "selRec",
recipes: filteredRecipes,
helpIcon: "cal",
},
}).then((title) => {
title && this.newMealPlan(title, null, type, null);
@ -325,21 +356,34 @@ export default {
index,
};
this.deleteMealPlanAction(mealPlan);
this.undoRemove(`${this.$options.filters.L("recRm")}`).then((res) => {
if (res.command === "action") {
this.newMealPlan(title, date, type, index);
}
this.showUndoBar("recRm").then((res) =>
this.newMealPlan(title, date, type, index)
);
},
showUndoBar(message) {
return new Promise((resolve, reject) => {
this.showUndo = true;
this.snackMsg = message;
this.countdown = 5;
let a = 5;
clearTimeout(undoTimer);
undoTimer = setInterval(() => {
if (this.undo) {
this.showUndo = this.undo = false;
clearTimeout(undoTimer);
resolve(true);
}
this.countdown = Math.round((a -= 0.1));
if (this.countdown < 1) {
this.showUndo = false;
clearTimeout(undoTimer);
reject(true);
}
}, 100);
});
},
undoRemove(message) {
return snackbar.action({
message,
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
actionTextColor: "#ff5200",
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
actionText: "Undo",
hideDelay: 5000,
});
undoDel() {
this.undo = true;
},
},
created() {

View file

@ -1,36 +1,41 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'Settings' | L" col="1" />
</GridLayout>
</ActionBar>
<GridLayout rows="*" columns="*" class="main-container">
<ListView @loaded="listViewLoad" for="item in items">
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
@loaded="listViewLoad"
for="item in items"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'Settings' | L" />
</v-template>
<v-template if="$index == 7">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout
columns="auto, *"
class="option mdr"
@tap="navigateTo(item.view)"
class="option"
@touch="touch($event, item.view)"
>
<Label
col="0"
verticalAlignment="center"
class="er"
class="ico"
:text="icon[item.icon]"
/>
<Label verticalAlignment="center" col="1" :text="item.title | L" />
</GridLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
@tap="$navigateBack()"
/>
</GridLayout>
</GridLayout>
</Page>
</template>
@ -48,6 +53,7 @@ export default {
data() {
return {
items: [
{},
{
icon: "theme",
title: "intf",
@ -78,6 +84,7 @@ export default {
title: "About",
view: About,
},
{},
],
};
},
@ -85,21 +92,25 @@ export default {
...mapState(["icon"]),
},
methods: {
...mapActions(["setCurrentComponentAction"]),
...mapActions(["setComponent"]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
this.setCurrentComponentAction("Settings");
},
listViewLoad(args) {
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
this.setComponent("Settings");
},
// HELPERS
navigateTo(view) {
this.$navigateTo(view);
this.$navigateTo(view, {
transition: {
name: "slide",
duration: 200,
curve: "easeOut",
},
});
},
touch({ object, action }, view) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") this.navigateTo(view);
},
},
};

View file

@ -1,48 +1,50 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'About' | L" col="1" />
</GridLayout>
</ActionBar>
<GridLayout rows="auto, *" columns="*" class="main-container">
<StackLayout row="0" class="app-info-container">
<Image
class="app-icon"
src="res://ic_launcher_foreground"
stretch="none"
/>
<Label class="app-name tb" :text="'EnRecipes' | L" textWrap="true" />
<Label :text="getVersion" class="app-version tb" textWrap="true" />
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
rowSpan="2"
colSpan="2"
class="options-list"
for="item in items"
@loaded="listViewLoad"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'About' | L" />
</v-template>
<v-template if="$index == 1">
<StackLayout class="app-info">
<Image
class="icon"
src="res://ic_launcher_foreground"
stretch="none"
/>
<Label class="name tb tac" :text="'EnRecipes' | L" />
<Label :text="getVersion" class="version tb tac" />
<Label class="app-info" :text="'appInfo' | L" textWrap="true" />
</StackLayout>
<ListView row="1" for="item in items" @loaded="listViewLoad">
<Label class="info tac tw" :text="'appInfo' | L" />
</StackLayout>
</v-template>
<v-template if="$index == 6">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout
columns="auto, *"
class="option mdr"
@tap="openURL(item.url)"
class="option"
@touch="touch($event, item.url)"
>
<Label
col="0"
verticalAlignment="center"
class="er"
:text="icon[item.icon]"
/>
<Label class="ico" :text="icon[item.icon]" />
<Label col="1" :text="item.title | L" />
</GridLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
@tap="$navigateBack()"
/>
</GridLayout>
</GridLayout>
</Page>
</template>
@ -56,11 +58,19 @@ export default {
...mapState(["icon"]),
items() {
return [
{},
{},
{
icon: "gh",
title: "gh",
url: "https://github.com/vishnuraghavb/EnRecipes",
},
{
icon: "priv",
title: "priv",
url:
"https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md",
},
{
icon: "don",
title: "donate",
@ -71,6 +81,7 @@ export default {
title: "trnsl",
url: "https://hosted.weblate.org/projects/enrecipes/app-translations",
},
{},
];
},
getVersion() {
@ -87,16 +98,14 @@ export default {
const page = args.object;
page.bindingContext = new Observable();
},
listViewLoad(args) {
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
},
// HELPERS
openURL(url) {
Utils.openUrl(url);
},
touch({ object, action }, url) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") this.openURL(url);
},
},
};
</script>

View file

@ -0,0 +1,15 @@
<template>
<Page>
<GridLayout class="progressContainer" columns="*, 64">
<Progress col="0" :value="backupProgress" maxValue="100" />
<Label col="1" :text="` ${backupProgress}%`" />
</GridLayout>
</Page>
</template>
<script>
export default {};
</script>
<style>
</style>

View file

@ -1,57 +1,41 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'db' | L" col="1" />
</GridLayout>
</ActionBar>
<StackLayout class="main-container">
<GridLayout
rows="auto"
columns="auto, *"
class="option mdr"
@tap="exportCheck"
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
@loaded="listViewLoad"
for="item in items"
>
<Label col="0" class="er" :text="icon.exp" />
<StackLayout col="1">
<Label :text="'expBu' | L" textWrap="true" />
<Label
v-if="!backupInProgress"
:text="'buInfo' | L"
class="info"
textWrap="true"
/>
<GridLayout class="progressContainer" v-else columns="*, 64">
<MDProgress
col="0"
:value="backupProgress"
maxValue="100"
></MDProgress>
<Label col="1" :text="` ${backupProgress}%`" />
<v-template if="$index == 0">
<Label class="pageTitle" :text="'db' | L" />
</v-template>
<v-template if="$index == 3">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout
columns="auto, *"
class="option"
@touch="touch($event, item.action)"
>
<Label class="ico" :text="icon[item.icon]" />
<StackLayout col="1">
<Label :text="item.title | L" class="info" />
<Label :text="item.subTitle | L" class="sub" />
</StackLayout>
</GridLayout>
</StackLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
@tap="$navigateBack()"
/>
</GridLayout>
<GridLayout
rows="auto"
columns="auto, *"
class="option mdr"
@tap="importCheck"
>
<Label col="0" class="er" :text="icon.imp" />
<StackLayout col="1">
<Label :text="'impBu' | L" textWrap="true" />
<Label :text="'impInfo' | L" class="info" textWrap="true" />
</StackLayout>
</GridLayout>
</StackLayout>
</GridLayout>
</Page>
</template>
@ -92,6 +76,24 @@ export default {
"mealPlans",
"importSummary",
]),
items() {
return [
{},
{
icon: "exp",
title: "expBu",
subTitle: "buInfo",
action: this.exportCheck,
},
{
icon: "imp",
title: "impBu",
subTitle: "impInfo",
action: this.importCheck,
},
{},
];
},
},
methods: {
...mapActions([
@ -310,8 +312,6 @@ export default {
title: "impFail",
description,
okButtonText: "OK",
helpIcon: "alert",
iconColor: "#c92a2a",
},
});
},
@ -399,8 +399,6 @@ export default {
"recF"
)}${importedNote}${existsNote}${updatedNote}`,
okButtonText: "OK",
helpIcon: "succ",
iconColor: "#69db7c",
},
});
},
@ -436,11 +434,14 @@ export default {
description,
cancelButtonText: "nNBtn",
okButtonText: "conBtn",
helpIcon: "folder",
bgColor: "#ff5200",
},
});
},
// HELPERS
touch({ object, action }, method) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") method();
},
},
};
</script>

View file

@ -1,36 +1,37 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'help' | L" col="1" />
</GridLayout>
</ActionBar>
<GridLayout rows="*" columns="*" class="main-container">
<ListView for="item in items" @loaded="listViewLoad">
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
for="item in items"
@loaded="listViewLoad"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'help' | L" />
</v-template>
<v-template if="$index == 3">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout
columns="auto, *"
class="option mdr"
@tap="openURL(item.url)"
class="option"
@touch="touch($event, item.url)"
>
<Label
col="0"
verticalAlignment="center"
class="er"
:text="icon[item.icon]"
/>
<Label col="1" :text="item.title | L" />
<Label class="ico" :text="icon[item.icon]" />
<Label col="1" :text="item.title | L" class="info" />
</GridLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
@tap="$navigateBack()"
/>
</GridLayout>
</GridLayout>
</Page>
</template>
@ -44,6 +45,7 @@ export default {
...mapState(["icon"]),
items() {
return [
{},
{
icon: "tg",
title: "joinTG",
@ -54,12 +56,7 @@ export default {
title: "guide",
url: "https://github.com/vishnuraghavb/EnRecipes/wiki/User-Guide",
},
{
icon: "priv",
title: "priv",
url:
"https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md",
},
{},
];
},
},
@ -68,16 +65,14 @@ export default {
const page = args.object;
page.bindingContext = new Observable();
},
listViewLoad(args) {
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
},
// HELPERS
openURL(url) {
Utils.openUrl(url);
},
touch({ object, action }, url) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") this.openURL(url);
},
},
};
</script>

View file

@ -1,59 +1,67 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'intf' | L" col="1" />
</GridLayout>
</ActionBar>
<GridLayout rows="*" columns="*" class="main-container">
<ListView for="item in items" @loaded="listViewLoad">
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
@loaded="listViewLoad"
for="item in items"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'intf' | L" />
</v-template>
<v-template if="$index == 4">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout columns="auto, *" class="option mdr" @tap="item.action">
<Label
col="0"
verticalAlignment="center"
class="er"
:text="icon[item.icon]"
/>
<GridLayout
columns="auto, *"
class="option"
@touch="touch($event, item.action)"
>
<Label class="ico" :text="icon[item.icon]" />
<StackLayout col="1">
<Label :text="item.title | L" />
<Label :text="item.subTitle" class="info" />
<Label :text="item.title | L" class="info" />
<Label :text="item.subTitle" class="sub" />
</StackLayout>
</GridLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
@tap="$navigateBack()"
/>
</GridLayout>
</GridLayout>
</Page>
</template>
<script>
import { ApplicationSettings, Observable, Device } from "@nativescript/core";
import {
ApplicationSettings,
Observable,
Device,
Frame,
} from "@nativescript/core";
import { localize, overrideLocale } from "@nativescript/localize";
import ActionDialog from "../modal/ActionDialog.vue";
import ConfirmDialog from "../modal/ConfirmDialog.vue";
import { mapState, mapActions } from "vuex";
import * as utils from "~/shared/utils";
export default {
data() {
return {
appLanguage: "English",
appTheme: "Light",
};
},
computed: {
...mapState(["icon", "language", "layout"]),
...mapState(["icon", "language", "appTheme", "layout"]),
items() {
return [
{},
{
icon: "lang",
title: "lang",
@ -67,26 +75,21 @@ export default {
action: this.selectThemes,
},
{
icon: "theme",
icon: "l1",
title: "listVM",
subTitle: localize(this.layout),
action: this.setLayoutMode,
},
{},
];
},
},
methods: {
...mapActions(["setLayout"]),
...mapActions(["setTheme", "setLayout"]),
onPageLoad(args) {
const page = args.object;
page.bindingContext = new Observable();
},
listViewLoad(args) {
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
},
// LANGUAGE SELECTION
selectAppLanguage() {
let languages = this.language.map((e) => e.title);
@ -94,8 +97,6 @@ export default {
props: {
title: "lang",
list: [...languages],
stretch: true,
helpIcon: "lang",
},
}).then((action) => {
if (action && action !== "Cancel" && this.appLanguage !== action) {
@ -109,8 +110,6 @@ export default {
description: localize("nLangInfo"),
cancelButtonText: "cBtn",
okButtonText: "rst",
helpIcon: "res",
iconColor: "#ff5200",
},
}).then((result) => {
if (result) {
@ -129,29 +128,12 @@ export default {
this.$showModal(ActionDialog, {
props: {
title: "Theme",
list: ["Light", "Dark"],
stretch: false,
helpIcon: "theme",
count: 2,
list: ["Light", "Dark", "Black"],
},
}).then((action) => {
if (action && action !== "Cancel" && this.appTheme !== action) {
this.$showModal(ConfirmDialog, {
props: {
title: "appRst",
description: localize("nThmInfo"),
cancelButtonText: "cBtn",
okButtonText: "rst",
helpIcon: "res",
iconColor: "#ff5200",
},
}).then((result) => {
if (result) {
this.appTheme = action;
ApplicationSettings.setString("appTheme", action);
setTimeout(utils.restartApp, 250);
}
});
this.setTheme(action);
Frame.reloadPage();
}
});
},
@ -160,10 +142,7 @@ export default {
this.$showModal(ActionDialog, {
props: {
title: "List view mode",
list: ["Detailed", "Simple", "Grid"],
stretch: false,
helpIcon: "theme",
count: 3,
list: ["Detailed", "Grid", "Simple", "Minimal"],
},
}).then((action) => {
if (action && action !== "Cancel" && this.layoutMode !== action) {
@ -173,9 +152,13 @@ export default {
}
});
},
// HELPERS
touch({ object, action }, method) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") method();
},
},
mounted() {
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
this.appLanguage = ApplicationSettings.getString(
"appLanguage",
localize("sysDef")

View file

@ -1,39 +1,44 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
@loaded="listViewLoad"
for="item in items"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'opts' | L" />
</v-template>
<v-template if="item.type == 'switch'">
<GridLayout columns="auto, *, auto" class="option">
<Label class="ico" :text="icon[item.icon]" />
<StackLayout col="1">
<Label :text="item.title | L" class="info" />
<Label :text="item.subTitle | L" class="sub" />
</StackLayout>
<Switch
:color="item.subAction ? '#ff5200' : '#858585'"
verticalAlignment="center"
col="2"
:checked="item.subAction"
@checkedChange="item.action"
/>
</GridLayout>
</v-template>
<v-template>
<StackLayout class="listSpace"> </StackLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button
class="ico"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'opts' | L" col="1" />
</GridLayout>
</ActionBar>
<StackLayout class="main-container">
<GridLayout rows="auto" columns="auto, *, auto" class="option mdr">
<Label
col="0"
verticalAlignment="center"
class="er"
:text="icon.shuf"
/>
<StackLayout col="1">
<Label :text="'sVw' | L" textWrap="true" />
<Label :text="`sVwInfo` | L" class="info" textWrap="true" />
</StackLayout>
<Switch
:color="shakeEnabled ? '#ff5200' : '#858585'"
verticalAlignment="center"
col="2"
:checked="shakeEnabled"
@checkedChange="toggleShake"
/>
</GridLayout>
</StackLayout>
</GridLayout>
</Page>
</template>
@ -47,6 +52,20 @@ import * as utils from "~/shared/utils";
export default {
computed: {
...mapState(["icon", "shakeEnabled"]),
items() {
return [
{},
{
type: "switch",
icon: "shuf",
title: "sVw",
subTitle: "sVwInfo",
action: this.toggleShake,
subAction: this.shakeEnabled,
},
{},
];
},
},
methods: {
...mapActions(["setShakeAction"]),

View file

@ -1,47 +1,36 @@
<template>
<Page @loaded="onPageLoad">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *">
<MDButton
class="er left"
variant="text"
:text="icon.back"
automationText="Back"
@tap="$navigateBack()"
col="0"
/>
<Label class="title tb" :text="'rest' | L" col="1" />
</GridLayout>
</ActionBar>
<GridLayout rows="auto, *" columns="*" class="main-container">
<Label
row="0"
class="group-info"
:text="'restInfo' | L"
textWrap="true"
/>
<ListView row="1" for="item in items" @loaded="listViewLoad">
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<ListView
colSpan="2"
rowSpan="2"
class="options-list"
@loaded="listViewLoad"
for="item in items"
>
<v-template if="$index == 0">
<Label class="pageTitle" :text="'rest' | L" />
</v-template>
<v-template if="$index == 5">
<Label class="group-info sub tw" :text="'restInfo' | L" />
</v-template>
<v-template if="$index == 6">
<StackLayout class="listSpace"> </StackLayout>
</v-template>
<v-template>
<GridLayout
columns="auto, *"
class="option mdr"
@tap="resetListItems(item.type)"
class="option"
@touch="touch($event, item.type)"
>
<Label
col="0"
verticalAlignment="center"
class="er"
:text="icon.reset"
/>
<Label
col="1"
verticalAlignment="center"
:text="item.title | L"
textWrap="true"
/>
<Label class="ico" :text="icon.reset" />
<Label col="1" :text="item.title | L" class="info" />
</GridLayout>
</v-template>
</ListView>
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
</GridLayout>
</GridLayout>
</Page>
</template>
@ -57,6 +46,7 @@ export default {
...mapState(["icon"]),
items() {
return [
{},
{
type: "cuisines",
title: "restCuiL",
@ -73,6 +63,8 @@ export default {
type: "units",
title: "restUL",
},
{},
{},
];
},
},
@ -82,17 +74,15 @@ export default {
const page = args.object;
page.bindingContext = new Observable();
},
listViewLoad(args) {
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
},
// RESET
resetListItems(listName) {
this.resetListItemsAction(listName);
Toast.makeText(localize("restDone")).show();
},
touch({ object, action }, type) {
object.className = action.match(/down|move/) ? "option fade" : "option";
if (action == "up") this.resetListItems(type);
},
},
};
</script>

File diff suppressed because it is too large Load diff

View file

@ -1,53 +1,40 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout
columns="*"
:rows="`auto, auto, ${stretch ? '*' : 'auto'}, auto`"
class="dialogContainer"
:class="appTheme"
class="modal"
>
<StackLayout row="0" class="dialogHeader" orientation="horizontal">
<Label class="er dialogIcon" :text="icon[helpIcon]" />
<Label class="dialogTitle" :text="`${title}` | L" />
</StackLayout>
<Label class="title" :text="title | L" />
<ListView
rowHeight="48"
row="2"
@loaded="listViewLoad"
for="item in newList"
:height="stretch ? '100%' : itemInView"
:height="stretch ? '100%' : listHeight"
>
<v-template>
<StackLayout margin="0" padding="0">
<Label
class="actionItem mdr"
:class="{ tb: title === 'srt' && sortType === item }"
:color="title === 'srt' && sortType === item ? '#ff5200' : ''"
:text="`${localized(item)}`"
@tap="tapAction(item)"
@longPress="removeItem(item)"
/>
</StackLayout>
<Label
class="listItem"
:class="{ tb: title === 'srt' && sortType === item }"
:color="title === 'srt' && sortType === item ? '#ff5200' : ''"
:text="`${localized(item)}`"
@touch="touch"
@tap="tapAction(item)"
@longPress="removeItem(item)"
/>
</v-template>
</ListView>
<GridLayout
row="3"
rows="auto"
columns="auto, *, auto"
class="actionsContainer"
>
<MDButton
variant="text"
<GridLayout row="3" columns="auto, *, auto" class="actions">
<Button
v-if="action"
col="0"
class="action tb pull-left"
:text="`${action}` | L"
class="text sm"
:text="action | L"
@tap="$modal.close(action)"
/>
<MDButton
variant="text"
<Button
col="2"
class="action tb pull-right"
class="text sm"
:text="'cBtn' | L"
@tap="$modal.close(false)"
/>
@ -57,28 +44,22 @@
</template>
<script>
import { Application } from "@nativescript/core";
import * as Toast from "nativescript-toast";
import { Screen } from "@nativescript/core";
import { localize } from "@nativescript/localize";
import { mapState, mapActions } from "vuex";
import ConfirmDialog from "./ConfirmDialog.vue";
export default {
props: ["title", "list", "stretch", "action", "helpIcon", "count"],
props: ["title", "list", "action"],
data() {
return {
newList: this.list,
rowHeight: null,
stretch: false,
listHeight: 0,
};
},
computed: {
...mapState(["sortType", "icon"]),
appTheme() {
return Application.systemAppearance();
},
itemInView() {
return this.rowHeight * this.count;
},
...mapState(["sortType", "icon", "appTheme"]),
},
methods: {
...mapActions(["removeListItemAction"]),
@ -92,13 +73,6 @@ export default {
)
);
},
listViewLoad(args) {
this.rowHeight = args.object.rowHeight;
let e = args.object.android;
e.setSelector(new android.graphics.drawable.StateListDrawable());
e.setDivider(null);
e.setDividerHeight(0);
},
localized(item) {
if (this.title !== "lang") return localize(item);
else return item;
@ -106,9 +80,6 @@ export default {
tapAction(item) {
this.$modal.close(item);
},
// centerLabel(args) {
// args.object.android.setGravity(16);
// },
deletionConfirmation(type, description) {
return this.$showModal(ConfirmDialog, {
props: {
@ -116,13 +87,10 @@ export default {
description,
cancelButtonText: "cBtn",
okButtonText: "rBtn",
helpIcon: "err",
iconColor: "#c92a2a",
},
});
},
removeItem(item) {
// let item = this.newList[index];
let vm = this;
function removeListItem(type, listName, desc) {
@ -153,6 +121,23 @@ export default {
default:
}
},
touch({ object, action }) {
object.className = action.match(/down|move/)
? "listItem fade"
: "listItem";
},
},
created() {
let screenHeight = Screen.mainScreen.heightDIPs;
let usableHeight = screenHeight - 144 - 24; // margin and statusbar
let count = this.newList.length;
let listHeight = 48 * count;
let modalHeight = 104 + listHeight; // header + actions height = 104
if (modalHeight < usableHeight) {
this.listHeight = listHeight;
} else {
this.stretch = true;
}
},
};
</script>

View file

@ -1,73 +1,49 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<GridLayout
columns="*"
rows="auto, auto, auto, *, auto"
class="dialogContainer"
:class="appTheme"
>
<StackLayout row="0" class="dialogHeader" orientation="horizontal">
<Label class="er dialogIcon" :text="icon[helpIcon]" />
<Label
class="dialogTitle"
:text="`${title}` | L"
textWrap="true"
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout columns="*" rows="auto, auto, *, auto" class="modal">
<Label class="title" :text="title | L" />
<StackLayout
row="1"
v-if="filteredRecipes.length || searchQuery"
class="input"
>
<TextField
class="modalInput"
:hint="'Search' | L"
v-model="searchQuery"
/>
</StackLayout>
<StackLayout
row="2"
v-if="filteredRecipes.length || searchQuery"
padding="0 24 8"
>
<TextField :hint="'Search' | L" v-model="searchQuery" />
</StackLayout>
<ScrollView row="3" width="100%" :height="height ? height : ''">
<StackLayout>
<MDButton
v-for="(recipe, index) in filteredRecipes"
:key="index"
class="actionItem"
variant="text"
<ListView row="2" for="recipe in filteredRecipes" @loaded="listViewLoad">
<v-template>
<Label
class="listItem"
:text="recipe.title"
@loaded="centerLabel"
@tap="tapAction(recipe)"
@touch="touch($event, recipe)"
/>
<Label
padding="24"
lineHeight="6"
v-if="!filteredRecipes.length && !searchQuery"
:text="'recListEmp' | L"
textAlignment="center"
textWrap="true"
/>
<Label
padding="24"
lineHeight="6"
v-if="!filteredRecipes.length && searchQuery"
:text="'noRecs' | L"
textAlignment="center"
textWrap="true"
/>
</StackLayout>
</ScrollView>
<GridLayout
row="4"
rows="auto"
columns="auto, *, auto"
class="actionsContainer"
>
<MDButton
variant="text"
</v-template>
</ListView>
<Label
row="2"
class="noResInfo"
v-if="!filteredRecipes.length && !searchQuery"
:text="'recListEmp' | L"
/>
<Label
row="2"
class="noResInfo"
v-if="!filteredRecipes.length && searchQuery"
:text="'noRecs' | L"
/>
<GridLayout row="3" columns="auto, *, auto" class="actions">
<Button
v-if="action"
col="0"
class="action tb pull-left"
:text="`${action}` | L"
class="text sm"
:text="action | L"
@tap="$modal.close(action)"
/>
<MDButton
variant="text"
<Button
col="2"
class="action tb pull-right"
class="text sm"
:text="'CANCEL' | L"
@tap="$modal.close(false)"
/>
@ -77,20 +53,16 @@
</template>
<script>
import { Application } from "@nativescript/core";
import { mapState } from "vuex";
export default {
props: ["title", "recipes", "height", "action", "helpIcon"],
props: ["title", "recipes", "height", "action"],
data() {
return {
searchQuery: "",
};
},
computed: {
...mapState(["icon"]),
appTheme() {
return Application.systemAppearance();
},
...mapState(["icon", "appTheme"]),
filteredRecipes() {
return this.recipes
.map((e, i) => {
@ -133,6 +105,12 @@ export default {
e.ingredients.includes(searchQuery)
);
},
touch({ object, action }, recipe) {
object.className = action.match(/down|move/)
? "listItem fade"
: "listItem";
if (action == "up") this.tapAction(recipe);
},
},
};
</script>

View file

@ -1,62 +1,51 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<StackLayout class="dialogContainer" :class="appTheme">
<StackLayout class="dialogHeader" orientation="horizontal">
<Label
class="er dialogIcon"
:color="iconColor"
:text="icon[helpIcon]"
/>
<Label
class="dialogTitle "
:text="`${title}` | L"
textWrap="true"
/>
</StackLayout>
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout rows="auto, auto, auto" class="modal">
<Label class="title" :text="title | L" />
<Label
row="1"
v-if="description"
class="dialogDescription"
class="description tw"
:text="description"
textWrap="true"
/>
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
<MDButton
<GridLayout row="2" columns="auto, *, auto, auto" class="actions">
<Button
v-if="secondButtonText"
col="0"
class="text sm"
:text="secondButtonText | L"
@tap="$modal.close(-1)"
/>
<Button
v-if="cancelButtonText"
variant="text"
col="1"
class="action tb"
:text="`${cancelButtonText}` | L"
col="2"
class="text sm"
:text="cancelButtonText | L"
@tap="$modal.close(false)"
/>
<MDButton
variant="text"
col="2"
class="action tb"
:text="`${okButtonText}` | L"
<Button
col="3"
class="text sm"
:text="okButtonText | L"
@tap="$modal.close(true)"
/>
</GridLayout>
</StackLayout>
</GridLayout>
</Page>
</template>
<script>
import { Application, Color } from "@nativescript/core";
import { mapState } from "vuex";
export default {
props: [
"title",
"description",
"secondButtonText",
"cancelButtonText",
"okButtonText",
"helpIcon",
"iconColor",
],
computed: {
...mapState(["icon"]),
appTheme() {
return Application.systemAppearance();
},
...mapState(["icon", "appTheme"]),
},
methods: {
onPageLoad(args) {

View file

@ -0,0 +1,272 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout rows="auto, auto, *, auto" columns="*" class="modal">
<Label class="title" :text="`fltr` | L" />
<ScrollView orientation="horizontal" row="1" @loaded="onScrollLoad">
<StackLayout class="filters" orientation="horizontal">
<GridLayout
rows="48"
columns="auto, auto"
class="segment"
v-for="(item, index) in pathList"
:key="index"
:class="{
select: filterType === item.type,
}"
@touch="touchSelector($event, item.type)"
>
<Label class="ico" :text="icon[item.type]" />
<Label v-if="item.title" class="value" :text="item.title" col="1" />
</GridLayout>
</StackLayout>
</ScrollView>
<ListView
row="2"
class="options-list"
@loaded="listViewLoad"
for="item in filterList"
>
<v-template>
<Label
class="listItem"
verticalAlignment="center"
col="1"
:text="item | L"
@touch="touch($event, item)"
/>
</v-template>
</ListView>
<GridLayout row="3" columns="auto, *, auto, auto" class="actions">
<Button class="text sm" :text="'rest' | L" @tap="resetFilter" />
<Button
col="2"
class="text sm"
:text="'cBtn' | L"
@tap="$modal.close()"
/>
<Button
col="3"
class="text sm"
:text="'apply' | L"
@tap="applyFilter"
/>
</GridLayout>
</GridLayout>
</Page>
</template>
<script>
import { localize } from "@nativescript/localize";
import { mapActions, mapState } from "vuex";
let filterTimer;
export default {
data() {
return {
filterType: "cuisine",
localCuisine: null,
localCategory: null,
localTag: null,
reset: false,
};
},
computed: {
...mapState([
"icon",
"recipes",
"cuisines",
"categories",
"selectedCuisine",
"selectedCategory",
"selectedTag",
"appTheme",
]),
pathList() {
let arr = [
{
type: "cuisine",
title: localize(this.localCuisine),
},
{
type: "category",
title: localize(this.localCategory),
},
{
type: "tag",
title: localize(this.localTag),
},
];
switch (this.filterType) {
case "cuisine":
return arr.slice(0, -2);
break;
case "category":
return arr.slice(0, -1);
break;
}
return arr;
},
filterList() {
switch (this.filterType) {
case "cuisine":
return this.cuisineList;
break;
case "category":
return this.categoryList;
break;
case "tag":
return this.tagList;
break;
}
},
cuisineList() {
let arr = this.recipes.map((e) => e.cuisine).sort();
return arr.length ? ["allCuis", ...new Set(arr)] : [];
},
categoryList() {
let arr = this.recipes
.map(
(e) =>
(this.localCuisine === "allCuis" ||
e.cuisine === this.localCuisine) &&
e.category
)
.filter((e) => e)
.sort();
return arr.length ? ["allCats", ...new Set(arr)] : [];
},
tagList() {
let arr = this.recipes
.map((e) => {
if (
this.localCuisine === "allCuis" &&
this.localCategory === "allCats" &&
e.tags.length
)
return e.tags;
else if (
this.localCuisine === "allCuis" &&
e.category === this.localCategory &&
e.tags.length
)
return e.tags;
else if (
this.localCategory === "allCats" &&
e.cuisine === this.localCuisine &&
e.tags.length
)
return e.tags;
else if (
e.category === this.localCategory &&
e.cuisine === this.localCuisine &&
e.tags.length
)
return e.tags;
})
.flat()
.filter((e) => e)
.sort();
let showAllTags =
this.localCuisine === "allCuis" && this.localCategory === "allCats";
return arr.length
? [!showAllTags && "allTs", ...new Set(arr)].filter((e) => e)
: [];
},
},
methods: {
...mapActions([
"setComponent",
"setCuisine",
"setCategory",
"setTag",
"clearFilter",
]),
onPageLoad(args) {
args.object._dialogFragment
.getDialog()
.getWindow()
.setBackgroundDrawable(
new android.graphics.drawable.ColorDrawable(
android.graphics.Color.TRANSPARENT
)
);
this.localCuisine = this.selectedCuisine;
this.localCategory = this.selectedCategory;
this.localTag = this.selectedTag;
if (this.localCuisine) this.filterType = "category";
if (this.localCategory || this.localTag) this.filterType = "tag";
this.scrollToRight();
},
onScrollLoad(args) {
this.scrollview = args.object;
},
setFilterType(type) {
this.filterType = type;
switch (type) {
case "cuisine":
this.localCategory = null;
this.localTag = null;
break;
case "category":
this.localTag = null;
break;
default:
break;
}
},
scrollToRight() {
setTimeout(
() =>
this.scrollview.scrollToHorizontalOffset(
this.scrollview.scrollableWidth,
true
),
10
);
},
setRecipeFilter(item) {
this.reset = false;
switch (this.filterType) {
case "cuisine":
this.localCuisine = item;
this.filterType = "category";
break;
case "category":
this.localCategory = item;
if (this.tagList.length) this.filterType = "tag";
break;
default:
this.localTag = item;
break;
}
this.scrollToRight();
},
applyFilter() {
this.setCuisine(this.localCuisine);
this.setCategory(this.localCategory);
this.setTag(this.localTag);
this.filterFavourites = this.filterTrylater = false;
if (this.reset) this.setComponent("EnRecipes");
else this.setComponent("Filtered recipes");
this.$modal.close();
},
resetFilter() {
this.filterType = "cuisine";
this.localCuisine = this.localCategory = this.localTag = null;
this.reset = true;
},
touch({ object, action }, item) {
object.className = action.match(/down|move/)
? "listItem fade"
: "listItem";
if (action == "up") this.setRecipeFilter(item);
},
touchSelector({ object, action }, type) {
let selected = this.filterType == type;
object.className = action.match(/down|move/)
? `segment ${selected ? "select" : "fade"}`
: `segment ${selected && "select"}`;
if (action == "up") this.setFilterType(type);
},
},
};
</script>

View file

@ -1,11 +1,9 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<StackLayout class="dialogContainer" :class="appTheme">
<StackLayout class="dialogHeader" orientation="horizontal">
<Label class="er dialogIcon" :text="icon.time" />
<Label class="dialogTitle " :text="`${title}` | L" />
</StackLayout>
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout rows="auto, auto, auto" class="modal">
<Label class="title" :text="title | L" />
<StackLayout
row="1"
class="dialogListPicker"
orientation="horizontal"
horizontalAlignment="center"
@ -23,23 +21,21 @@
@selectedIndexChange="setMins"
></ListPicker>
</StackLayout>
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
<MDButton
variant="text"
<GridLayout row="2" columns="*, auto, auto" class="actions">
<Button
col="1"
class="action tb"
class="text sm"
:text="'cBtn' | L"
@tap="$modal.close(false)"
/>
<MDButton
variant="text"
<Button
col="2"
class="action tb"
:text="`${action}` | L"
class="text sm"
:text="action | L"
@tap="$modal.close(selectedTime)"
/>
</GridLayout>
</StackLayout>
</GridLayout>
</Page>
</template>
@ -58,7 +54,7 @@ export default {
};
},
computed: {
...mapState(["icon"]),
...mapState(["icon", "appTheme"]),
hrsList() {
let h = [...Array(24).keys()];
this.hrs = h;
@ -80,9 +76,6 @@ export default {
minIndex() {
return this.mins.indexOf(parseInt(this.selectedMin));
},
appTheme() {
return Application.systemAppearance();
},
selectedTime() {
return this.selectedHrs + ":" + this.selectedMins;
},

View file

@ -1,62 +1,46 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<StackLayout class="dialogContainer" :class="appTheme">
<StackLayout class="dialogHeader" orientation="horizontal">
<Label class="er dialogIcon" :text="icon[helpIcon]" />
<Label
class="dialogTitle "
:text="`${title}` | L"
textWrap="true"
/>
</StackLayout>
<StackLayout class="dialogInput">
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
<GridLayout rows="auto, auto, auto" class="modal">
<Label class="title" :text="title | L" />
<StackLayout row="1" class="input">
<TextField
class="modalInput"
@loaded="focusField"
:hint="hint ? hint : ''"
v-model="category"
autocapitalizationType="words"
@returnPress="$modal.close(category)"
v-model="text"
@returnPress="$modal.close(text)"
/>
</StackLayout>
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
<MDButton
variant="text"
<GridLayout row="2" columns="*, auto, auto" class="actions">
<Button
col="1"
class="action tb"
class="text sm"
:text="'cBtn' | L"
@tap="$modal.close(false)"
/>
<MDButton
variant="text"
<Button
col="2"
class="action tb"
:text="`${action}` | L"
@tap="$modal.close(category)"
class="text sm"
:text="action | L"
@tap="$modal.close(text)"
/>
</GridLayout>
</StackLayout>
</GridLayout>
</Page>
</template>
<script>
import { Application, Utils } from "@nativescript/core";
import { Utils } from "@nativescript/core";
import { localize } from "@nativescript/localize";
import { mapState } from "vuex";
export default {
props: ["title", "hint", "text", "action", "helpIcon"],
props: ["title", "hint", "placeholder", "action"],
data() {
return {
category: null,
text: null,
};
},
computed: {
...mapState(["icon"]),
appTheme() {
return Application.systemAppearance();
},
isLightMode() {
return this.appTheme == "light";
},
...mapState(["icon", "appTheme"]),
},
methods: {
onPageLoad(args) {
@ -69,15 +53,19 @@ export default {
)
);
},
focusField(args) {
args.object.focus();
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1);
focusField({ object }) {
let a = this.placeholder;
typeof a == "number"
? (object.keyboardType = "number")
: (object.autocapitalizationType = "words");
object.hint = this.hint;
object.focus();
setTimeout(() => Utils.ad.showSoftInput(object.android), 1);
},
},
mounted() {
if (this.text) {
this.category = localize(this.text);
}
created() {
let a = this.placeholder;
if (a) this.text = typeof a == "number" ? a : localize(a);
},
};
</script>

View file

@ -1,89 +0,0 @@
<template>
<Page @loaded="onPageLoad" backgroundColor="transparent">
<StackLayout class="dialogContainer" :class="appTheme">
<StackLayout class="dialogHeader" orientation="horizontal">
<Label
class="er dialogIcon"
:text="icon[helpIcon]"
/>
<Label class="dialogTitle " :text="`${title}` | L" />
</StackLayout>
<GridLayout rows="auto, auto, auto" columns="*" class="actionsContainer">
<GridLayout
class="shareItem mdr"
:backgroundColor="bgColor"
row="0"
columns="*"
rows="auto, auto"
@tap="$modal.close('photo')"
>
<Label row="0" class="er" :text="icon.img" />
<Label row="1" class="item" :text="'pht' | L" textWrap="true" />
</GridLayout>
<GridLayout
class="shareItem mdr"
:backgroundColor="bgColor"
row="1"
columns="*"
rows="auto, auto"
@tap="$modal.close('recipe')"
>
<Label row="0" class="er" :text="icon.text" />
<Label row="1" class="item" :text="'rec' | L" textWrap="true" />
</GridLayout>
<!-- <GridLayout
class="shareItem mdr"
:backgroundColor="bgColor"
row="2"
columns="*"
rows="auto, auto"
@tap="$modal.close('file')"
>
<Label row="0" class="er" :text="icon.zip" />
<Label row="1" class="item" :text="'fil' | L" textWrap="true" />
</GridLayout> -->
</GridLayout>
<GridLayout rows="auto" columns="*, auto" class="actionsContainer">
<MDButton
variant="text"
col="1"
class="action tb mdr"
:text="'cBtn' | L"
@tap="$modal.close()"
/>
</GridLayout>
</StackLayout>
</Page>
</template>
<script>
import { Application } from "@nativescript/core";
import { mapState } from "vuex";
export default {
props: ["title", "helpIcon"],
computed: {
...mapState(["icon"]),
appTheme() {
return Application.systemAppearance();
},
isLightMode() {
return this.appTheme == "light";
},
bgColor() {
return this.isLightMode ? "#fff" : "#292929";
},
},
methods: {
onPageLoad(args) {
args.object._dialogFragment
.getDialog()
.getWindow()
.setBackgroundDrawable(
new android.graphics.drawable.ColorDrawable(
android.graphics.Color.TRANSPARENT
)
);
},
},
};
</script>

View file

@ -126,7 +126,7 @@
"aNoBtn": "ADD NOTE",
"it": "Item",
"stp": "Step",
"srt": "Sort by",
"srt": "Sort",
"cBtn": "CANCEL",
"rBtn": "REMOVE",
"rmCuiInfo": "You are about to remove the cuisine:",
@ -149,7 +149,6 @@
"SET": "SET",
"appRst": "App restart required",
"rst": "RESTART",
"nThmInfo": "Restart EnRecipes to use the new theme",
"nLangInfo": "Restart EnRecipes to use the new language",
"grant": "Grant access",
"reqAcc": "EnRecipes requires storage permission in order to set recipe photo, export and import data",
@ -180,7 +179,7 @@
"nwCat": "New category",
"req": "Required",
"recPic": "Recipe photo",
"repBtn": "REPLACE PHOTO",
"repBtn": "REPLACE",
"cPic": "Crop photo",
"breakfast": "Breakfast",
"lunch": "lunch",
@ -306,5 +305,9 @@
"listVM": "List view mode",
"detailed": "Detailed",
"simple": "Simple",
"grid": "Grid"
"grid": "Grid",
"minimal": "Minimal",
"apply": "APPLY",
"fltr": "Filter",
"yld": "Yield"
}

View file

@ -9,37 +9,14 @@ on(launchEvent, (args) => {
}
})
import Vue from 'nativescript-vue'
import App from './components/App'
import EnRecipes from './components/EnRecipes'
import store from './store'
import { installMixins } from '@nativescript-community/ui-material-core'
installMixins()
import CollectionView from '@nativescript-community/ui-collectionview/vue'
Vue.use(CollectionView)
import { install } from '@nativescript-community/ui-drawer'
install()
import DrawerPlugin from '@nativescript-community/ui-drawer/vue'
Vue.use(DrawerPlugin)
import CollectionView from '@nativescript-community/ui-collectionview/vue';
Vue.use(CollectionView);
import ButtonPlugin from '@nativescript-community/ui-material-button/vue'
Vue.use(ButtonPlugin)
import ActivityIndicatorPlugin from '@nativescript-community/ui-material-activityindicator/vue'
Vue.use(ActivityIndicatorPlugin)
import ProgressPlugin from '@nativescript-community/ui-material-progress/vue'
Vue.use(ProgressPlugin)
import { CheckBox } from '@nstudio/nativescript-checkbox'
Vue.registerElement('CheckBox', () => CheckBox, {
model: {
prop: 'checked',
event: 'checkedChange',
},
})
import { lvMixin } from './shared/mixins.js'
Vue.mixin(lvMixin)
Vue.config.silent = TNS_ENV === 'production'
@ -47,5 +24,5 @@ Vue.filter('L', localize)
new Vue({
store,
render: (h) => h('frame', [h(App)]),
render: (h) => h(EnRecipes),
}).$start()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -304,6 +304,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -304,6 +304,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -304,6 +304,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -305,6 +305,10 @@
<string name="_app_name_1k3Sbz">"என்ரெசிபீஸ்"</string>
<string name="app_name">"என்ரெசிபீஸ்"</string>
<string name="title_activity_kimera">"என்ரெசிபீஸ்"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -304,6 +304,10 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>

View file

@ -1,28 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Application theme -->
<style name="AppThemeBase21" parent="AppThemeBase">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:datePickerStyle">@style/SpinnerDatePicker</item>
<item name="android:timePickerStyle">@style/SpinnerTimePicker</item>
</style>
<style name="AppTheme" parent="AppThemeBase21">
</style>
<!-- Default style for DatePicker - in spinner mode -->
<style name="SpinnerDatePicker" parent="android:Widget.Material.Light.DatePicker">
<item name="android:datePickerMode">spinner</item>
</style>
<!-- Default style for TimePicker - in spinner mode -->
<style name="SpinnerTimePicker" parent="android:Widget.Material.Light.TimePicker">
<item name="android:timePickerMode">spinner</item>
</style>
<style name="NativeScriptToolbarStyle" parent="NativeScriptToolbarStyleBase">
<item name="android:elevation">4dp</item>
<!-- <item name="android:paddingTop">24dp</item> -->
</style>
</resources>

View file

@ -1,12 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Application theme -->
<style name="AppThemeBase29" parent="AppThemeBase21">
<item name="android:forceDarkAllowed">false</item>
</style>
<style name="AppTheme" parent="AppThemeBase29">
</style>
</resources>

View file

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="yld">"Yield"</string>
<string name="fltr">"Filter"</string>
<string name="apply">"APPLY"</string>
<string name="minimal">"Minimal"</string>
<string name="grid">"Grid"</string>
<string name="simple">"Simple"</string>
<string name="detailed">"Detailed"</string>
@ -126,7 +130,7 @@
<string name="lunch">"lunch"</string>
<string name="breakfast">"Breakfast"</string>
<string name="cPic">"Crop photo"</string>
<string name="repBtn">"REPLACE PHOTO"</string>
<string name="repBtn">"REPLACE"</string>
<string name="recPic">"Recipe photo"</string>
<string name="req">"Required"</string>
<string name="nwCat">"New category"</string>
@ -157,7 +161,6 @@
<string name="reqAcc">"EnRecipes requires storage permission in order to set recipe photo, export and import data"</string>
<string name="grant">"Grant access"</string>
<string name="nLangInfo">"Restart EnRecipes to use the new language"</string>
<string name="nThmInfo">"Restart EnRecipes to use the new theme"</string>
<string name="rst">"RESTART"</string>
<string name="appRst">"App restart required"</string>
<string name="SET">"SET"</string>
@ -180,7 +183,7 @@
<string name="rmCuiInfo">"You are about to remove the cuisine:"</string>
<string name="rBtn">"REMOVE"</string>
<string name="cBtn">"CANCEL"</string>
<string name="srt">"Sort by"</string>
<string name="srt">"Sort"</string>
<string name="stp">"Step"</string>
<string name="it">"Item"</string>
<string name="aNoBtn">"ADD NOTE"</string>
@ -310,4 +313,5 @@
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
<string name="app_name">"EnRecipes"</string>
<string name="title_activity_kimera">"EnRecipes"</string>
<string name="nThmInfo">"nThmInfo"</string>
</resources>

View file

@ -1,10 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- theme to use FOR launch screen -->
<style name="LaunchScreenThemeBase" parent="Theme.MaterialComponents.NoActionBar">
<item name="toolbarStyle">
@style/NativeScriptToolbarStyle
</item>
<style name="LaunchScreenThemeBase" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">
@color/ns_primary
</item>
@ -26,14 +22,7 @@
</style>
<style name="LaunchScreenTheme" parent="LaunchScreenThemeBase">
</style>
<!-- theme to use AFTER launch screen is loaded -->
<style name="AppThemeBase" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="searchViewStyle">
@style/SearchViewMy
</item>
<item name="toolbarStyle">
@style/NativeScriptToolbarStyle
</item>
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">
@color/ns_primary
</item>
@ -44,38 +33,20 @@
@color/ns_accent
</item>
<item name="colorControlNormal">
#858585
#00858585
</item>
<item name="android:windowTranslucentStatus">
false
</item>
</style>
<style name="AppTheme" parent="AppThemeBase">
<item name="android:listViewStyle">@style/Widget.MyTheme.ListView</item>
<item name="android:scrollViewStyle">@style/Widget.MyTheme.ScrollView</item>
</style>
<!-- theme for action-bar -->
<style name="NativeScriptToolbarStyleBase" parent="Widget.MaterialComponents.Toolbar">
<item name="contentInsetStart">
0dp
</item>
<item name="contentInsetEnd">
0dp
</item>
<item name="android:background">
@color/ns_primary
</item>
<item name="theme">
@style/ThemeOverlay.MaterialComponents.ActionBar
</item>
<item name="popupTheme">
@style/ThemeOverlay.MaterialComponents
</item>
<style name="Widget.MyTheme.ListView" parent="android:Widget.ListView">
<item name="android:overScrollMode">never</item>
</style>
<style name="NativeScriptToolbarStyle" parent="NativeScriptToolbarStyleBase">
</style>
<!-- theme for searchview -->
<style name="SearchViewMy" parent="Widget.AppCompat.Light.SearchView">
<item name="searchHintIcon">
@null
</item>
<item name="closeIcon">
@null
</item>
<style name="Widget.MyTheme.ScrollView" parent="android:Widget.ScrollView">
<item name="android:overScrollMode">never</item>
</style>
</resources>

20
app/shared/mixins.js Normal file
View file

@ -0,0 +1,20 @@
export const lvMixin = {
methods: {
listViewLoad(args) {
let e = args.object.android
e.setSelector(new android.graphics.drawable.StateListDrawable())
e.setDivider(null)
e.setDividerHeight(0)
},
animateInOut(dur, rev, draw) {
const start = Date.now()
let timer = setInterval(() => {
const passed = Date.now() - start
let val = passed / dur
if (val > 1) val = 1
draw(rev ? 1 - val : val)
if (val === 1) clearInterval(timer)
}, 17) // 1000ms/60fps=16.66ms => 17ms
},
},
}

View file

@ -1,17 +1,17 @@
import { Application, Utils } from '@nativescript/core'
export const restartApp = () => {
const mStartActivity = new android.content.Intent(
let 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(
let mPendingIntentId = Math.random() * 100000
let mPendingIntent = android.app.PendingIntent.getActivity(
Application.android.context,
mPendingIntentId,
mStartActivity,
android.app.PendingIntent.FLAG_CANCEL_CURRENT
)
const mgr = Application.android.context.getSystemService(
let mgr = Application.android.context.getSystemService(
android.content.Context.ALARM_SERVICE
)
mgr.set(
@ -22,7 +22,7 @@ export const restartApp = () => {
android.os.Process.killProcess(android.os.Process.myPid())
}
export const openAppSettingsPage = () => {
const intent = new android.content.Intent(
let intent = new android.content.Intent(
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
)
intent.addCategory(android.content.Intent.CATEGORY_DEFAULT)
@ -42,3 +42,9 @@ export const hasAccelerometer = () => {
android.hardware.Sensor.TYPE_ACCELEROMETER
)
}
export const vibrate = (duration) => {
let vibratorService = Application.android.context.getSystemService(
android.content.Context.VIBRATOR_SERVICE
)
if (vibratorService.hasVibrator()) vibratorService.vibrate(duration)
}

View file

@ -2,7 +2,12 @@ import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import { CouchBase } from '@triniwiz/nativescript-couchbase'
import { getFileAccess, File, ApplicationSettings } from '@nativescript/core'
import {
Application,
getFileAccess,
File,
ApplicationSettings,
} from '@nativescript/core'
const EnRecipesDB = new CouchBase('EnRecipes')
const userCuisinesDB = new CouchBase('userCuisines')
const userCategoriesDB = new CouchBase('userCategories')
@ -145,6 +150,7 @@ const listItems = {
defaultItems: defaultUnits,
},
}
export default new Vuex.Store({
state: {
recipes: [],
@ -288,15 +294,26 @@ export default new Vuex.Store({
updated: 0,
},
layout: 'detailed',
selectedCuisine: null,
selectedCategory: null,
selectedTag: null,
appTheme: 'Light',
},
mutations: {
setTheme(state, theme) {
ApplicationSettings.setString('appTheme', theme)
state.appTheme = theme
},
clearFilter(state) {
state.selectedCuisine = state.selectedCategory = state.selectedTag = null
},
setLayout(state, type) {
state.layout = type
},
setSortType(state, sortType) {
state.sortType = sortType
},
initializeRecipes(state) {
initRecipes(state) {
EnRecipesDB.query({ select: [] }).forEach((r) => {
if (r.timeRequired) {
r.prepTime = '00:00'
@ -418,7 +435,7 @@ export default new Vuex.Store({
})
})
},
initializeListItems(state) {
initListItems(state) {
function initialize(listName) {
let userItems
let db = listItems[listName].db
@ -490,7 +507,7 @@ export default new Vuex.Store({
state[stateName].sort()
}
},
initializeMealPlans(state) {
initMealPlans(state) {
let isMealPlansDBStored = mealPlansDB.query({ select: [] }).length
if (isMealPlansDBStored) {
let plans = mealPlansDB.getDocument('mealPlans').mealPlans
@ -641,7 +658,7 @@ export default new Vuex.Store({
state.recipes[index].lastTried = new Date()
EnRecipesDB.updateDocument(state.recipes[index].id, state.recipes[index])
},
setCurrentComponent(state, comp) {
setComponent(state, comp) {
state.currentComponent = comp
},
unSyncCombinations(state, { id, combinations }) {
@ -678,16 +695,31 @@ export default new Vuex.Store({
}
})
},
setCuisine(state, value) {
state.selectedCuisine = value
},
setCategory(state, value) {
state.selectedCategory = value
},
setTag(state, value) {
state.selectedTag = value
},
},
actions: {
setTheme({ commit }, theme) {
commit('setTheme', theme)
},
clearFilter({ commit }) {
commit('clearFilter')
},
setLayout({ commit }, type) {
commit('setLayout', type)
},
setSortTypeAction({ commit }, sortType) {
commit('setSortType', sortType)
},
initializeRecipes({ commit }) {
commit('initializeRecipes')
initRecipes({ commit }) {
commit('initRecipes')
},
importRecipesAction({ commit }, recipes) {
commit('importRecipes', recipes)
@ -704,8 +736,8 @@ export default new Vuex.Store({
deleteRecipesAction({ commit }, ids) {
commit('deleteRecipes', ids)
},
initializeListItems({ commit }) {
commit('initializeListItems')
initListItems({ commit }) {
commit('initListItems')
},
importListItemsAction({ commit }, data) {
commit('importListItems', data)
@ -719,8 +751,8 @@ export default new Vuex.Store({
resetListItemsAction({ commit }, listName) {
commit('resetListItems', listName)
},
initializeMealPlans({ commit }) {
commit('initializeMealPlans')
initMealPlans({ commit }) {
commit('initMealPlans')
},
importMealPlansAction({ commit }, mealPlans) {
commit('importMealPlans', mealPlans)
@ -740,8 +772,8 @@ export default new Vuex.Store({
setLastTriedDateAction({ commit }, index) {
commit('setLastTriedDate', index)
},
setCurrentComponentAction({ commit }, comp) {
commit('setCurrentComponent', comp)
setComponent({ commit }, comp) {
commit('setComponent', comp)
},
unSyncCombinationsAction({ commit }, combinations) {
commit('unSyncCombinations', combinations)
@ -758,5 +790,14 @@ export default new Vuex.Store({
unlinkBrokenImages({ commit }) {
commit('unlinkBrokenImages')
},
setCuisine({ commit }, value) {
commit('setCuisine', value)
},
setCategory({ commit }, value) {
commit('setCategory', value)
},
setTag({ commit }, value) {
commit('setTag', value)
},
},
})

View file

@ -1,10 +1,8 @@
- New: Redesigned user interface
- New: Recipe list view modes
- New: Black theme
- Fixed: Crash on app start with blocked sensors #30
- Improvement: Better search & filtering
- Improvement: Tap to strike off completed instructions
- Deprecated: Swipe to delete recipe
- Deprecated: Search recipe with tag
- Refreshed: Meal Planner calendar, Dialog boxes and UI icons
- Improvement: Faster app start and navigation
- Added app languages: French, Italian, Norwegian Bokmål
- Updated translations
- Several UI improvements and bug fixes
- Several bug fixes

516
package-lock.json generated
View file

@ -9,35 +9,25 @@
"version": "1.0.0",
"license": "GPL",
"dependencies": {
"@nativescript-community/gesturehandler": "^0.1.39",
"@nativescript-community/perms": "^2.1.5",
"@nativescript-community/ui-collectionview": "^4.0.29",
"@nativescript-community/ui-drawer": "^0.0.24",
"@nativescript-community/ui-material-activityindicator": "^5.2.10",
"@nativescript-community/ui-material-button": "^5.2.10",
"@nativescript-community/ui-material-progress": "^5.2.10",
"@nativescript-community/ui-material-snackbar": "^5.2.10",
"@nativescript/core": "7.3.0",
"@nativescript/core": "8.0.0",
"@nativescript/localize": "^5.0.4",
"@nativescript/social-share": "^2.0.4",
"@nativescript/theme": "^3.0.1",
"@nativescript/zip": "^5.0.0",
"@nstudio/nativescript-checkbox": "^2.0.4",
"@triniwiz/nativescript-accelerometer": "^4.0.3",
"@triniwiz/nativescript-couchbase": "^1.2.2",
"nativescript-feedback": "^2.0.0",
"nativescript-imagecropper": "^4.0.1",
"nativescript-intl": "^4.0.2",
"nativescript-plugin-filepicker": "^1.0.0",
"nativescript-toast": "^2.0.0",
"nativescript-vibrate": "^4.0.1",
"nativescript-vue": "^2.8.4",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@nativescript/android": "7.0.1",
"@nativescript/android": "8.0.0",
"@nativescript/webpack": "4.1.0",
"@types/node": "^14.14.20",
"babel-loader": "^8.2.2",
@ -89,25 +79,24 @@
"dev": true
},
"node_modules/@babel/core": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz",
"integrity": "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz",
"integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
"@babel/helper-compilation-targets": "^7.13.10",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.13",
"@babel/helper-module-transforms": "^7.13.14",
"@babel/helpers": "^7.13.10",
"@babel/parser": "^7.13.10",
"@babel/parser": "^7.13.13",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0",
"@babel/traverse": "^7.13.13",
"@babel/types": "^7.13.14",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
"lodash": "^4.17.19",
"semver": "^6.3.0",
"source-map": "^0.5.0"
},
@ -150,12 +139,12 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz",
"integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz",
"integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.13.8",
"@babel/compat-data": "^7.13.12",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "^6.3.0"
@ -270,9 +259,9 @@
}
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.12.tgz",
"integrity": "sha512-7zVQqMO3V+K4JOOj40kxiCrMf6xlQAkewBB0eu2b03OO/Q21ZutOzjpfD79A5gtE/2OWi1nv625MrDlGlkbknQ==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz",
"integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==",
"dev": true,
"dependencies": {
"@babel/helper-module-imports": "^7.13.12",
@ -281,8 +270,8 @@
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/helper-validator-identifier": "^7.12.11",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.12"
"@babel/traverse": "^7.13.13",
"@babel/types": "^7.13.14"
}
},
"node_modules/@babel/helper-optimise-call-expression": {
@ -397,9 +386,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.12.tgz",
"integrity": "sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz",
"integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@ -1268,26 +1257,25 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz",
"integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz",
"integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.0",
"@babel/generator": "^7.13.9",
"@babel/helper-function-name": "^7.12.13",
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/parser": "^7.13.0",
"@babel/types": "^7.13.0",
"@babel/parser": "^7.13.13",
"@babel/types": "^7.13.13",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.19"
"globals": "^11.1.0"
}
},
"node_modules/@babel/types": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz",
"integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz",
"integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.12.11",
@ -1295,98 +1283,31 @@
"to-fast-properties": "^2.0.0"
}
},
"node_modules/@nativescript-community/gesturehandler": {
"version": "0.1.39",
"resolved": "https://registry.npmjs.org/@nativescript-community/gesturehandler/-/gesturehandler-0.1.39.tgz",
"integrity": "sha512-QVI9fOQvrjSnHGTZxj362bGsLwblloeJAs5ITX6UvjOW7A4IoaBl7++RBL5E9z0WkEHFX8A3Vvj4CoNBnhgH0g==",
"dependencies": {
"@nativescript-community/observable": "^2.0.8"
}
},
"node_modules/@nativescript-community/observable": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/@nativescript-community/observable/-/observable-2.0.9.tgz",
"integrity": "sha512-JsNztvBEdUH7I3+ECnIOOJ39J2sEdeaBSFk4JIkrsFeVGOx1E21SSJNkkQNN9H2BUsF9JgDoQ6rGKl3hmJkXTw=="
},
"node_modules/@nativescript-community/perms": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nativescript-community/perms/-/perms-2.1.5.tgz",
"integrity": "sha512-YHYgzeOvYkb6Nj2JAgor8D5YLxYvj0sxr2JfnVrkb7c/Z41lTr0PaoHvhElvK6iERobbGQ1w3HmV9eCHrDgv9g=="
},
"node_modules/@nativescript-community/text": {
"version": "1.4.9",
"resolved": "https://registry.npmjs.org/@nativescript-community/text/-/text-1.4.9.tgz",
"integrity": "sha512-U90qiuD513AY38rtNqyy67+7g2foup95kpnxkCiaJuBSkBf8nbdLpuLur9oOuCqndAw0X/N1gklE+tq2/BF0DA=="
},
"node_modules/@nativescript-community/ui-collectionview": {
"version": "4.0.29",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-collectionview/-/ui-collectionview-4.0.29.tgz",
"integrity": "sha512-u+HR3XNbws8ORus4lcKzMr5TWUR/w43OszscJIfv1orGI7ZnqrUHvPyiVz2Ff5+W78s1VPTQdMg0tyGjSX/qEg=="
},
"node_modules/@nativescript-community/ui-drawer": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-drawer/-/ui-drawer-0.0.24.tgz",
"integrity": "sha512-Vv+ix4PMks88VFypWPRv/1OkKFyehRIbuJRi5/EjDVMMA5SOiDEmkBwxzKzglBEx2mq+VNT7/QGZ11WVxHD04g==",
"dependencies": {
"@nativescript-community/gesturehandler": "^0.1.35"
}
},
"node_modules/@nativescript-community/ui-material-activityindicator": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-activityindicator/-/ui-material-activityindicator-5.2.10.tgz",
"integrity": "sha512-1SWwnMj/QTr0FjjY32P+nigT4qzIMBFiPEfN8/eswJSkPWswJ4ZbJxYewP1jjgShEBOuap98x4KfWVSQ611DIw==",
"dependencies": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"node_modules/@nativescript-community/ui-material-button": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-button/-/ui-material-button-5.2.10.tgz",
"integrity": "sha512-Mv53d54L6mMt5IftylMJ/PAkjpOH34hXgEqJhmvcyr9oWzgckqYusp4LmIfvALc1uf7RQwS0NqSJuLF6N4Fl9Q==",
"dependencies": {
"@nativescript-community/text": "^1.3.10",
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"node_modules/@nativescript-community/ui-material-core": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-core/-/ui-material-core-5.2.10.tgz",
"integrity": "sha512-iaMZCc1lTCwCbAvfZcNEKQKZD6no3Zs6GJAq0Z9DQyo9A4JHTyl9bvW+M8I6h8q5ozjwnklhtMVHLnwa2dGPHg==",
"hasInstallScript": true,
"dependencies": {
"@nativescript/hook": "~2.0.0"
}
},
"node_modules/@nativescript-community/ui-material-progress": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-progress/-/ui-material-progress-5.2.10.tgz",
"integrity": "sha512-+eRODG/Ti0bsFbZbWxCnx39sjzzRmChVlsmJsvB8jSTSeUBJ2+1Putv3supGoh/hFpc5eRZoi84ZnpYioV04YQ==",
"dependencies": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"node_modules/@nativescript-community/ui-material-snackbar": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-snackbar/-/ui-material-snackbar-5.2.10.tgz",
"integrity": "sha512-VK6H8rnc7zHFoKxHvEQyR51+OM/J32RHgryd7A4JVAbIbCpD3d5+Hre7z24ZH6PM4MHzD0tmHhW3ZqdyXcGYMA==",
"dependencies": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"node_modules/@nativescript/android": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-7.0.1.tgz",
"integrity": "sha512-VsZCJ5zfZo0+/lFwKz+S7iFb7MA2jgACB7y8dNje3/cnZl+moKPNjFqitoEP0DY4gLz9LJNbFIIaUt84tMdUSQ==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-8.0.0.tgz",
"integrity": "sha512-p7eGwmE2+EvkQ4vt4scIrWqVuXytKv+GiHofrVRME1zUaTNMLSdB9ZyQOukfIvCx09iIufD42wN2a0IkgcDBvw==",
"dev": true
},
"node_modules/@nativescript/core": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-7.3.0.tgz",
"integrity": "sha512-YfRbMxojiCHjrdYl2OqxYrmf6YPi4eB/xUGr4SFsIY/ruPojWpmb+cW3NvqIHJ+rPpYRAjhKL+FpQ6QdZK6dTw==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-8.0.0.tgz",
"integrity": "sha512-SgftvD0jE3cKLLB2PV/Pd/aKvJVQqb44502mKgLxg0QayKaQcNNxt6rpnRfck0FLfxmNCS6zKMVbRY8oNy/EQQ==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@nativescript/hook": "~2.0.0",
"css-tree": "^1.0.0-alpha.39",
"css-tree": "^1.1.2",
"reduce-css-calc": "^2.1.7",
"tslib": "~2.0.0"
}
@ -1417,11 +1338,6 @@
"resolved": "https://registry.npmjs.org/@nativescript/social-share/-/social-share-2.0.4.tgz",
"integrity": "sha512-fP/lK/wMmHDmWo4Uq8gG/mpsgUjT+/y7Qc+IdCgiqQkgWQtgXTM7H1ecemMYD9dCZo+gZ5UyOXE/E23ZN0DBAg=="
},
"node_modules/@nativescript/theme": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@nativescript/theme/-/theme-3.0.1.tgz",
"integrity": "sha512-5rduFdEjjGyUgK+jaJ/2EHxi+qAgTZuK9XgfxHw0KJAIIWP9HNL8JV8IVUBeIodRPHhSJZJVQT7t+8peH/4dVQ=="
},
"node_modules/@nativescript/webpack": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@nativescript/webpack/-/webpack-4.1.0.tgz",
@ -1534,11 +1450,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@nstudio/nativescript-checkbox": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@nstudio/nativescript-checkbox/-/nativescript-checkbox-2.0.4.tgz",
"integrity": "sha512-ypIGAHxDE/2o3CzYohSdypdhiw4GjMcZ3H/qtF4z97HMcMqj+g5bYPDC9cRH97qgAez8jf/z3UX5OzOtnrNxug=="
},
"node_modules/@triniwiz/nativescript-accelerometer": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@triniwiz/nativescript-accelerometer/-/nativescript-accelerometer-4.0.3.tgz",
@ -1547,7 +1458,8 @@
"node_modules/@triniwiz/nativescript-couchbase": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@triniwiz/nativescript-couchbase/-/nativescript-couchbase-1.2.2.tgz",
"integrity": "sha512-ZnDVDFDR9oHu16KiQszjzFbEl3wWyFrKuTGoYmR7J5K2yIUsMD9UdvwXelZyXN45Hw7d595JrhgXJZNJpuvHXw=="
"integrity": "sha512-ZnDVDFDR9oHu16KiQszjzFbEl3wWyFrKuTGoYmR7J5K2yIUsMD9UdvwXelZyXN45Hw7d595JrhgXJZNJpuvHXw==",
"license": "Apache-2.0"
},
"node_modules/@types/anymatch": {
"version": "1.3.1",
@ -1572,15 +1484,15 @@
"dev": true
},
"node_modules/@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==",
"dev": true
},
"node_modules/@types/node": {
"version": "14.14.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==",
"version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
"dev": true
},
"node_modules/@types/parse-json": {
@ -1596,9 +1508,9 @@
"dev": true
},
"node_modules/@types/tapable": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz",
"integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz",
"integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==",
"dev": true
},
"node_modules/@types/uglify-js": {
@ -1620,14 +1532,14 @@
}
},
"node_modules/@types/webpack": {
"version": "4.41.26",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz",
"integrity": "sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA==",
"version": "4.41.27",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.27.tgz",
"integrity": "sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA==",
"dev": true,
"dependencies": {
"@types/anymatch": "*",
"@types/node": "*",
"@types/tapable": "*",
"@types/tapable": "^1",
"@types/uglify-js": "*",
"@types/webpack-sources": "*",
"source-map": "^0.6.0"
@ -2863,9 +2775,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001204",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz",
"integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==",
"version": "1.0.30001205",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz",
"integrity": "sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==",
"dev": true
},
"node_modules/caseless": {
@ -3488,9 +3400,9 @@
}
},
"node_modules/core-js-compat": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.1.tgz",
"integrity": "sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.0.tgz",
"integrity": "sha512-9yVewub2MXNYyGvuLnMHcN1k9RkvB7/ofktpeKTIaASyB88YYqGzUnu0ywMMhJrDHOMiTjSHWGzR+i7Wb9Z1kQ==",
"dev": true,
"dependencies": {
"browserslist": "^4.16.3",
@ -3687,9 +3599,9 @@
"dev": true
},
"node_modules/css-tree": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
"integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"dependencies": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
@ -4052,9 +3964,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.3.694",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.694.tgz",
"integrity": "sha512-8YJ/OZjbK5luOd27dmk34B47oa/zNGRHrKTEmfO3qPns1kFAJ36Lb+OtYzNlCoXtkPYuDbX0ztofuL7ArMHJkQ==",
"version": "1.3.704",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.704.tgz",
"integrity": "sha512-6cz0jvawlUe4h5AbfQWxPzb+8LzVyswGAWiGc32EJEmfj39HTQyNPkLXirc7+L4x5I6RgRkzua8Ryu5QZqc8cA==",
"dev": true
},
"node_modules/elliptic": {
@ -6530,9 +6442,9 @@
}
},
"node_modules/memfs": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.0.tgz",
"integrity": "sha512-f/xxz2TpdKv6uDn6GtHee8ivFyxwxmPuXatBb1FBwxYNuVpbM3k/Y1Z+vC0mH/dIXXrukYfe3qe5J32Dfjg93A==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.1.tgz",
"integrity": "sha512-Y5vcpQzWTime4fBTr/fEnxXUxEYUgKbDlty1WX0gaa4ae14I6KmvK1S8HtXOX0elKAE6ENZJctkGtbTFYcRIUw==",
"dev": true,
"dependencies": {
"fs-monkey": "1.0.1"
@ -6886,11 +6798,6 @@
"node": ">=0.10.0"
}
},
"node_modules/nativescript-feedback": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nativescript-feedback/-/nativescript-feedback-2.0.0.tgz",
"integrity": "sha512-6ZE/g+s1xxez3pMRJa/r0f144VuyapgDjbo8D37nMC4F0WDQLKk8dC0405czhQxD2djVq3GEMfM/n0cuMbY53A=="
},
"node_modules/nativescript-imagecropper": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nativescript-imagecropper/-/nativescript-imagecropper-4.0.1.tgz",
@ -6925,11 +6832,6 @@
"tns-core-modules": ">=2.x|| >= 3.x || >=4.x || >=5.x"
}
},
"node_modules/nativescript-vibrate": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nativescript-vibrate/-/nativescript-vibrate-4.0.1.tgz",
"integrity": "sha512-T9VspAu+pgYM/AWLradA4HPv/tdfx8jrhIOD02PZs09KhJyjQE3BoubnHcmg0neeQAhgxHiuXGdit8QOAyKaBA=="
},
"node_modules/nativescript-vue": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/nativescript-vue/-/nativescript-vue-2.8.4.tgz",
@ -7736,13 +7638,13 @@
}
},
"node_modules/plist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
"integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz",
"integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==",
"dependencies": {
"base64-js": "^1.2.3",
"base64-js": "^1.5.1",
"xmlbuilder": "^9.0.7",
"xmldom": "0.1.x"
"xmldom": "^0.5.0"
},
"engines": {
"node": ">=6"
@ -8367,9 +8269,9 @@
"dev": true
},
"node_modules/regjsparser": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.8.tgz",
"integrity": "sha512-3weFrFQREJhJ2PW+iCGaG6TenyzNSZgsBKZ/oEf6Trme31COSeIWhHw9O6FPkuXktfx+b6Hf/5e6dKPHaROq2g==",
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
"integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
"dev": true,
"dependencies": {
"jsesc": "~0.5.0"
@ -10104,9 +10006,9 @@
"dev": true
},
"node_modules/ts-loader": {
"version": "8.0.18",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.18.tgz",
"integrity": "sha512-hRZzkydPX30XkLaQwJTDcWDoxZHK6IrEMDQpNd7tgcakFruFkeUp/aY+9hBb7BUGb+ZWKI0jiOGMo0MckwzdDQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz",
"integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==",
"dev": true,
"dependencies": {
"chalk": "^4.1.0",
@ -11767,12 +11669,11 @@
}
},
"node_modules/xmldom": {
"version": "0.1.31",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
"deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
"integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==",
"engines": {
"node": ">=0.1"
"node": ">=10.0.0"
}
},
"node_modules/xtend": {
@ -12015,25 +11916,24 @@
"dev": true
},
"@babel/core": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz",
"integrity": "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz",
"integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.9",
"@babel/helper-compilation-targets": "^7.13.10",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.13",
"@babel/helper-module-transforms": "^7.13.14",
"@babel/helpers": "^7.13.10",
"@babel/parser": "^7.13.10",
"@babel/parser": "^7.13.13",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0",
"@babel/traverse": "^7.13.13",
"@babel/types": "^7.13.14",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
"lodash": "^4.17.19",
"semver": "^6.3.0",
"source-map": "^0.5.0"
}
@ -12069,12 +11969,12 @@
}
},
"@babel/helper-compilation-targets": {
"version": "7.13.10",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz",
"integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz",
"integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.13.8",
"@babel/compat-data": "^7.13.12",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "^6.3.0"
@ -12177,9 +12077,9 @@
}
},
"@babel/helper-module-transforms": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.12.tgz",
"integrity": "sha512-7zVQqMO3V+K4JOOj40kxiCrMf6xlQAkewBB0eu2b03OO/Q21ZutOzjpfD79A5gtE/2OWi1nv625MrDlGlkbknQ==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz",
"integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.13.12",
@ -12188,8 +12088,8 @@
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/helper-validator-identifier": "^7.12.11",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.12"
"@babel/traverse": "^7.13.13",
"@babel/types": "^7.13.14"
}
},
"@babel/helper-optimise-call-expression": {
@ -12304,9 +12204,9 @@
}
},
"@babel/parser": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.12.tgz",
"integrity": "sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz",
"integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==",
"dev": true
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
@ -12986,26 +12886,25 @@
}
},
"@babel/traverse": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz",
"integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==",
"version": "7.13.13",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz",
"integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.0",
"@babel/generator": "^7.13.9",
"@babel/helper-function-name": "^7.12.13",
"@babel/helper-split-export-declaration": "^7.12.13",
"@babel/parser": "^7.13.0",
"@babel/types": "^7.13.0",
"@babel/parser": "^7.13.13",
"@babel/types": "^7.13.13",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.19"
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.13.12",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz",
"integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==",
"version": "7.13.14",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz",
"integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.12.11",
@ -13013,96 +12912,29 @@
"to-fast-properties": "^2.0.0"
}
},
"@nativescript-community/gesturehandler": {
"version": "0.1.39",
"resolved": "https://registry.npmjs.org/@nativescript-community/gesturehandler/-/gesturehandler-0.1.39.tgz",
"integrity": "sha512-QVI9fOQvrjSnHGTZxj362bGsLwblloeJAs5ITX6UvjOW7A4IoaBl7++RBL5E9z0WkEHFX8A3Vvj4CoNBnhgH0g==",
"requires": {
"@nativescript-community/observable": "^2.0.8"
}
},
"@nativescript-community/observable": {
"version": "2.0.9",
"resolved": "https://registry.npmjs.org/@nativescript-community/observable/-/observable-2.0.9.tgz",
"integrity": "sha512-JsNztvBEdUH7I3+ECnIOOJ39J2sEdeaBSFk4JIkrsFeVGOx1E21SSJNkkQNN9H2BUsF9JgDoQ6rGKl3hmJkXTw=="
},
"@nativescript-community/perms": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nativescript-community/perms/-/perms-2.1.5.tgz",
"integrity": "sha512-YHYgzeOvYkb6Nj2JAgor8D5YLxYvj0sxr2JfnVrkb7c/Z41lTr0PaoHvhElvK6iERobbGQ1w3HmV9eCHrDgv9g=="
},
"@nativescript-community/text": {
"version": "1.4.9",
"resolved": "https://registry.npmjs.org/@nativescript-community/text/-/text-1.4.9.tgz",
"integrity": "sha512-U90qiuD513AY38rtNqyy67+7g2foup95kpnxkCiaJuBSkBf8nbdLpuLur9oOuCqndAw0X/N1gklE+tq2/BF0DA=="
},
"@nativescript-community/ui-collectionview": {
"version": "4.0.29",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-collectionview/-/ui-collectionview-4.0.29.tgz",
"integrity": "sha512-u+HR3XNbws8ORus4lcKzMr5TWUR/w43OszscJIfv1orGI7ZnqrUHvPyiVz2Ff5+W78s1VPTQdMg0tyGjSX/qEg=="
},
"@nativescript-community/ui-drawer": {
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-drawer/-/ui-drawer-0.0.24.tgz",
"integrity": "sha512-Vv+ix4PMks88VFypWPRv/1OkKFyehRIbuJRi5/EjDVMMA5SOiDEmkBwxzKzglBEx2mq+VNT7/QGZ11WVxHD04g==",
"requires": {
"@nativescript-community/gesturehandler": "^0.1.35"
}
},
"@nativescript-community/ui-material-activityindicator": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-activityindicator/-/ui-material-activityindicator-5.2.10.tgz",
"integrity": "sha512-1SWwnMj/QTr0FjjY32P+nigT4qzIMBFiPEfN8/eswJSkPWswJ4ZbJxYewP1jjgShEBOuap98x4KfWVSQ611DIw==",
"requires": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"@nativescript-community/ui-material-button": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-button/-/ui-material-button-5.2.10.tgz",
"integrity": "sha512-Mv53d54L6mMt5IftylMJ/PAkjpOH34hXgEqJhmvcyr9oWzgckqYusp4LmIfvALc1uf7RQwS0NqSJuLF6N4Fl9Q==",
"requires": {
"@nativescript-community/text": "^1.3.10",
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"@nativescript-community/ui-material-core": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-core/-/ui-material-core-5.2.10.tgz",
"integrity": "sha512-iaMZCc1lTCwCbAvfZcNEKQKZD6no3Zs6GJAq0Z9DQyo9A4JHTyl9bvW+M8I6h8q5ozjwnklhtMVHLnwa2dGPHg==",
"requires": {
"@nativescript/hook": "~2.0.0"
}
},
"@nativescript-community/ui-material-progress": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-progress/-/ui-material-progress-5.2.10.tgz",
"integrity": "sha512-+eRODG/Ti0bsFbZbWxCnx39sjzzRmChVlsmJsvB8jSTSeUBJ2+1Putv3supGoh/hFpc5eRZoi84ZnpYioV04YQ==",
"requires": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"@nativescript-community/ui-material-snackbar": {
"version": "5.2.10",
"resolved": "https://registry.npmjs.org/@nativescript-community/ui-material-snackbar/-/ui-material-snackbar-5.2.10.tgz",
"integrity": "sha512-VK6H8rnc7zHFoKxHvEQyR51+OM/J32RHgryd7A4JVAbIbCpD3d5+Hre7z24ZH6PM4MHzD0tmHhW3ZqdyXcGYMA==",
"requires": {
"@nativescript-community/ui-material-core": "^5.2.10"
}
},
"@nativescript/android": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-7.0.1.tgz",
"integrity": "sha512-VsZCJ5zfZo0+/lFwKz+S7iFb7MA2jgACB7y8dNje3/cnZl+moKPNjFqitoEP0DY4gLz9LJNbFIIaUt84tMdUSQ==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-8.0.0.tgz",
"integrity": "sha512-p7eGwmE2+EvkQ4vt4scIrWqVuXytKv+GiHofrVRME1zUaTNMLSdB9ZyQOukfIvCx09iIufD42wN2a0IkgcDBvw==",
"dev": true
},
"@nativescript/core": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-7.3.0.tgz",
"integrity": "sha512-YfRbMxojiCHjrdYl2OqxYrmf6YPi4eB/xUGr4SFsIY/ruPojWpmb+cW3NvqIHJ+rPpYRAjhKL+FpQ6QdZK6dTw==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-8.0.0.tgz",
"integrity": "sha512-SgftvD0jE3cKLLB2PV/Pd/aKvJVQqb44502mKgLxg0QayKaQcNNxt6rpnRfck0FLfxmNCS6zKMVbRY8oNy/EQQ==",
"requires": {
"@nativescript/hook": "~2.0.0",
"css-tree": "^1.0.0-alpha.39",
"css-tree": "^1.1.2",
"reduce-css-calc": "^2.1.7",
"tslib": "~2.0.0"
}
@ -13132,11 +12964,6 @@
"resolved": "https://registry.npmjs.org/@nativescript/social-share/-/social-share-2.0.4.tgz",
"integrity": "sha512-fP/lK/wMmHDmWo4Uq8gG/mpsgUjT+/y7Qc+IdCgiqQkgWQtgXTM7H1ecemMYD9dCZo+gZ5UyOXE/E23ZN0DBAg=="
},
"@nativescript/theme": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@nativescript/theme/-/theme-3.0.1.tgz",
"integrity": "sha512-5rduFdEjjGyUgK+jaJ/2EHxi+qAgTZuK9XgfxHw0KJAIIWP9HNL8JV8IVUBeIodRPHhSJZJVQT7t+8peH/4dVQ=="
},
"@nativescript/webpack": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@nativescript/webpack/-/webpack-4.1.0.tgz",
@ -13226,11 +13053,6 @@
}
}
},
"@nstudio/nativescript-checkbox": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@nstudio/nativescript-checkbox/-/nativescript-checkbox-2.0.4.tgz",
"integrity": "sha512-ypIGAHxDE/2o3CzYohSdypdhiw4GjMcZ3H/qtF4z97HMcMqj+g5bYPDC9cRH97qgAez8jf/z3UX5OzOtnrNxug=="
},
"@triniwiz/nativescript-accelerometer": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@triniwiz/nativescript-accelerometer/-/nativescript-accelerometer-4.0.3.tgz",
@ -13264,15 +13086,15 @@
"dev": true
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==",
"dev": true
},
"@types/node": {
"version": "14.14.35",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==",
"version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
"dev": true
},
"@types/parse-json": {
@ -13288,9 +13110,9 @@
"dev": true
},
"@types/tapable": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz",
"integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz",
"integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==",
"dev": true
},
"@types/uglify-js": {
@ -13311,14 +13133,14 @@
}
},
"@types/webpack": {
"version": "4.41.26",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz",
"integrity": "sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA==",
"version": "4.41.27",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.27.tgz",
"integrity": "sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA==",
"dev": true,
"requires": {
"@types/anymatch": "*",
"@types/node": "*",
"@types/tapable": "*",
"@types/tapable": "^1",
"@types/uglify-js": "*",
"@types/webpack-sources": "*",
"source-map": "^0.6.0"
@ -14359,9 +14181,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001204",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz",
"integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==",
"version": "1.0.30001205",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz",
"integrity": "sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==",
"dev": true
},
"caseless": {
@ -14878,9 +14700,9 @@
}
},
"core-js-compat": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.1.tgz",
"integrity": "sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.0.tgz",
"integrity": "sha512-9yVewub2MXNYyGvuLnMHcN1k9RkvB7/ofktpeKTIaASyB88YYqGzUnu0ywMMhJrDHOMiTjSHWGzR+i7Wb9Z1kQ==",
"dev": true,
"requires": {
"browserslist": "^4.16.3",
@ -15059,9 +14881,9 @@
}
},
"css-tree": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
"integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
"integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
"requires": {
"mdn-data": "2.0.14",
"source-map": "^0.6.1"
@ -15346,9 +15168,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.3.694",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.694.tgz",
"integrity": "sha512-8YJ/OZjbK5luOd27dmk34B47oa/zNGRHrKTEmfO3qPns1kFAJ36Lb+OtYzNlCoXtkPYuDbX0ztofuL7ArMHJkQ==",
"version": "1.3.704",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.704.tgz",
"integrity": "sha512-6cz0jvawlUe4h5AbfQWxPzb+8LzVyswGAWiGc32EJEmfj39HTQyNPkLXirc7+L4x5I6RgRkzua8Ryu5QZqc8cA==",
"dev": true
},
"elliptic": {
@ -17322,9 +17144,9 @@
"dev": true
},
"memfs": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.0.tgz",
"integrity": "sha512-f/xxz2TpdKv6uDn6GtHee8ivFyxwxmPuXatBb1FBwxYNuVpbM3k/Y1Z+vC0mH/dIXXrukYfe3qe5J32Dfjg93A==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.1.tgz",
"integrity": "sha512-Y5vcpQzWTime4fBTr/fEnxXUxEYUgKbDlty1WX0gaa4ae14I6KmvK1S8HtXOX0elKAE6ENZJctkGtbTFYcRIUw==",
"dev": true,
"requires": {
"fs-monkey": "1.0.1"
@ -17619,11 +17441,6 @@
"to-regex": "^3.0.1"
}
},
"nativescript-feedback": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/nativescript-feedback/-/nativescript-feedback-2.0.0.tgz",
"integrity": "sha512-6ZE/g+s1xxez3pMRJa/r0f144VuyapgDjbo8D37nMC4F0WDQLKk8dC0405czhQxD2djVq3GEMfM/n0cuMbY53A=="
},
"nativescript-imagecropper": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nativescript-imagecropper/-/nativescript-imagecropper-4.0.1.tgz",
@ -17655,11 +17472,6 @@
"resolved": "https://registry.npmjs.org/nativescript-toast/-/nativescript-toast-2.0.0.tgz",
"integrity": "sha512-xqyNfFS894oGfrEVO7CjpioAQLiLNNcd77Euq9XIUTf1U3W0PsIgAJbLP7+kkVGIJxdLtlBkbcQ4wDmf2DCi1w=="
},
"nativescript-vibrate": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nativescript-vibrate/-/nativescript-vibrate-4.0.1.tgz",
"integrity": "sha512-T9VspAu+pgYM/AWLradA4HPv/tdfx8jrhIOD02PZs09KhJyjQE3BoubnHcmg0neeQAhgxHiuXGdit8QOAyKaBA=="
},
"nativescript-vue": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/nativescript-vue/-/nativescript-vue-2.8.4.tgz",
@ -18305,13 +18117,13 @@
}
},
"plist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
"integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz",
"integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==",
"requires": {
"base64-js": "^1.2.3",
"base64-js": "^1.5.1",
"xmlbuilder": "^9.0.7",
"xmldom": "0.1.x"
"xmldom": "^0.5.0"
}
},
"posix-character-classes": {
@ -18828,9 +18640,9 @@
"dev": true
},
"regjsparser": {
"version": "0.6.8",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.8.tgz",
"integrity": "sha512-3weFrFQREJhJ2PW+iCGaG6TenyzNSZgsBKZ/oEf6Trme31COSeIWhHw9O6FPkuXktfx+b6Hf/5e6dKPHaROq2g==",
"version": "0.6.9",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
"integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
"dev": true,
"requires": {
"jsesc": "~0.5.0"
@ -20246,9 +20058,9 @@
"dev": true
},
"ts-loader": {
"version": "8.0.18",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.18.tgz",
"integrity": "sha512-hRZzkydPX30XkLaQwJTDcWDoxZHK6IrEMDQpNd7tgcakFruFkeUp/aY+9hBb7BUGb+ZWKI0jiOGMo0MckwzdDQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz",
"integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==",
"dev": true,
"requires": {
"chalk": "^4.1.0",
@ -21589,9 +21401,9 @@
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
},
"xmldom": {
"version": "0.1.31",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
"integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA=="
},
"xtend": {
"version": "4.0.2",

View file

@ -2,52 +2,42 @@
"name": "enrecipes",
"version": "1.0.0",
"description": "A native application built with NativeScript-Vue",
"author": "Vishnu Raghav <apps@vishnuraghav.com>",
"homepage": "https://enrecipes.vercel.app/",
"bugs": {
"url": "https://github.com/vishnuraghavb/EnRecipes/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vishnuraghavb/EnRecipes.git"
},
"license": "GPL",
"author": "Vishnu Raghav <apps@vishnuraghav.com>",
"main": "main",
"dependencies": {
"@nativescript-community/gesturehandler": "^0.1.39",
"@nativescript-community/perms": "^2.1.5",
"@nativescript-community/ui-collectionview": "^4.0.29",
"@nativescript-community/ui-drawer": "^0.0.24",
"@nativescript-community/ui-material-activityindicator": "^5.2.10",
"@nativescript-community/ui-material-button": "^5.2.10",
"@nativescript-community/ui-material-progress": "^5.2.10",
"@nativescript-community/ui-material-snackbar": "^5.2.10",
"@nativescript/core": "7.3.0",
"@nativescript/core": "8.0.0",
"@nativescript/localize": "^5.0.4",
"@nativescript/social-share": "^2.0.4",
"@nativescript/theme": "^3.0.1",
"@nativescript/zip": "^5.0.0",
"@nstudio/nativescript-checkbox": "^2.0.4",
"@triniwiz/nativescript-accelerometer": "^4.0.3",
"@triniwiz/nativescript-couchbase": "^1.2.2",
"nativescript-feedback": "^2.0.0",
"nativescript-imagecropper": "^4.0.1",
"nativescript-intl": "^4.0.2",
"nativescript-plugin-filepicker": "^1.0.0",
"nativescript-toast": "^2.0.0",
"nativescript-vibrate": "^4.0.1",
"nativescript-vue": "^2.8.4",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@nativescript/android": "7.0.1",
"@nativescript/android": "8.0.0",
"@nativescript/webpack": "4.1.0",
"@types/node": "^14.14.20",
"babel-loader": "^8.2.2",
"nativescript-vue-template-compiler": "^2.8.3",
"node-sass": "^4.14.1",
"vue-loader": "^15.9.6"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vishnuraghavb/EnRecipes.git"
},
"bugs": {
"url": "https://github.com/vishnuraghavb/EnRecipes/issues"
},
"homepage": "https://enrecipes.vercel.app/",
"main": "main"
}
}