bug fixes, added localize, minor ui improvements
|
@ -25,7 +25,7 @@ EnRecipes is an easy to use, privacy-friendly digital cookbook that lets you cre
|
|||
- Add photo, notes and combinations to your recipes
|
||||
- Organise your recipes by category
|
||||
- Quickly search for your recipes
|
||||
- Mark recipes as favorites and add them to your Try Later list
|
||||
- Mark recipes as favourites and add them to your Try Later list
|
||||
- Scale your recipe ingredients to serve more or less people
|
||||
- Get notified of the last time you tried a recipe
|
||||
- Share your recipe to anyone by any means as a nicely formatted message. You can share the recipe photo too.
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">EnRecipes</string>
|
||||
<string name="title_activity_kimera">EnRecipes</string>
|
||||
</resources>
|
118
app/app.scss
|
@ -1,7 +1,6 @@
|
|||
// NativeScript core theme
|
||||
// @see https://docs.nativescript.org/ui/theme
|
||||
@import "~@nativescript/theme/core";
|
||||
// Override variables here
|
||||
@import "~@nativescript/theme/core"; // Override variables here
|
||||
$gray1: #f1f3f5;
|
||||
$gray2: #e9ecef;
|
||||
$gray3: #dee2e6;
|
||||
|
@ -17,20 +16,17 @@ $red: #c92a2a;
|
|||
$breakfast: #ffb180;
|
||||
$lunch: #ceff80;
|
||||
$dinner: #80ceff;
|
||||
$snacks: #b180ff;
|
||||
|
||||
// Global SCSS styling
|
||||
$snacks: #b180ff; // Global SCSS styling
|
||||
// @see https://docs.nativescript.org/ui/styling
|
||||
|
||||
Page,
|
||||
.ns-modal {
|
||||
font-family: "Orkney-Regular";
|
||||
.ns-modal,
|
||||
Page {
|
||||
font-family: 'Orkney-Regular';
|
||||
}
|
||||
.orkm {
|
||||
font-family: "Orkney-Medium";
|
||||
font-family: 'Orkney-Medium';
|
||||
}
|
||||
.bx {
|
||||
font-family: "boxicons";
|
||||
font-family: 'boxicons';
|
||||
font-size: 24;
|
||||
vertical-alignment: center;
|
||||
&.small {
|
||||
|
@ -39,38 +35,37 @@ Page,
|
|||
}
|
||||
}
|
||||
.ns-light {
|
||||
Page,
|
||||
ActionBar,
|
||||
ListPicker,
|
||||
Page,
|
||||
SearchBar,
|
||||
Tabs,
|
||||
TabStripItem,
|
||||
ListPicker {
|
||||
Tabs {
|
||||
color: $gray9;
|
||||
background: $gray1;
|
||||
}
|
||||
MDRipple,
|
||||
MDButton {
|
||||
MDButton,
|
||||
MDRipple {
|
||||
ripple-color: rgba($gray6, 0.2);
|
||||
}
|
||||
.hr {
|
||||
border-color: $gray3;
|
||||
}
|
||||
.sd,
|
||||
.fieldLabel {
|
||||
.fieldLabel,
|
||||
.sd {
|
||||
background: $gray1;
|
||||
}
|
||||
.urlCard,
|
||||
.textCard,
|
||||
.overviewItem,
|
||||
.recipeItem {
|
||||
.recipeItem,
|
||||
.textCard,
|
||||
.urlCard {
|
||||
background: white;
|
||||
}
|
||||
TextField.combinationToken {
|
||||
background: $gray3;
|
||||
}
|
||||
|
||||
.sd-item,
|
||||
.sd-group-header,
|
||||
.sd-item,
|
||||
.time .bx {
|
||||
color: $gray8;
|
||||
}
|
||||
|
@ -87,8 +82,8 @@ Page,
|
|||
color: $gray1;
|
||||
background: $gray9;
|
||||
}
|
||||
.instruction,
|
||||
.dayContainer {
|
||||
.dayContainer,
|
||||
.instruction {
|
||||
border-color: $gray9;
|
||||
}
|
||||
MDProgress {
|
||||
|
@ -101,14 +96,13 @@ Page,
|
|||
background: $orange;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-dark {
|
||||
Page,
|
||||
ActionBar,
|
||||
ListPicker,
|
||||
Page,
|
||||
SearchBar,
|
||||
Tabs,
|
||||
TabStripItem,
|
||||
ListPicker {
|
||||
Tabs {
|
||||
color: $gray1;
|
||||
background: $gray9;
|
||||
}
|
||||
|
@ -116,27 +110,26 @@ Page,
|
|||
// tab-background-color: $gray9;
|
||||
// selected-tab-text-color: $gray1;
|
||||
// }
|
||||
MDRipple,
|
||||
MDButton {
|
||||
MDButton,
|
||||
MDRipple {
|
||||
ripple-color: rgba($gray4, 0.1);
|
||||
}
|
||||
|
||||
.hr {
|
||||
border-color: #111;
|
||||
}
|
||||
.sd,
|
||||
.fieldLabel {
|
||||
.fieldLabel,
|
||||
.sd {
|
||||
background: $gray9;
|
||||
}
|
||||
.urlCard,
|
||||
.textCard,
|
||||
.overviewItem,
|
||||
.recipeItem,
|
||||
.textCard,
|
||||
.urlCard,
|
||||
TextField.combinationToken {
|
||||
background: $gray8;
|
||||
}
|
||||
.sd-item,
|
||||
.sd-group-header,
|
||||
.sd-item,
|
||||
.time .bx {
|
||||
color: $gray3;
|
||||
}
|
||||
|
@ -153,8 +146,8 @@ Page,
|
|||
color: $gray9;
|
||||
background: $gray1;
|
||||
}
|
||||
.instruction,
|
||||
.dayContainer {
|
||||
.dayContainer,
|
||||
.instruction {
|
||||
border-color: $gray1;
|
||||
}
|
||||
MDProgress {
|
||||
|
@ -176,7 +169,7 @@ TimePickerField {
|
|||
border-width: 1;
|
||||
font-size: 14;
|
||||
padding: 14 14 13;
|
||||
margin: 8 0 0 0;
|
||||
margin: 8 0 0;
|
||||
border-radius: 4;
|
||||
border-color: $gray6;
|
||||
placeholder-color: $gray6;
|
||||
|
@ -184,8 +177,11 @@ TimePickerField {
|
|||
TextView {
|
||||
line-height: 12;
|
||||
}
|
||||
ListPicker {
|
||||
width: 25%;
|
||||
}
|
||||
SearchBar {
|
||||
font-family: "Orkney-Regular";
|
||||
font-family: 'Orkney-Regular';
|
||||
font-size: 16;
|
||||
text-field-hint-color: $gray6;
|
||||
}
|
||||
|
@ -203,16 +199,15 @@ TabView {
|
|||
.progressContainer {
|
||||
width: 100%;
|
||||
}
|
||||
.text-btn,
|
||||
.group-header,
|
||||
.category,
|
||||
.group-header,
|
||||
.text-btn,
|
||||
MDActivityIndicator {
|
||||
color: $orange;
|
||||
}
|
||||
MDProgress {
|
||||
progress-color: $orange;
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// ActionBar
|
||||
ActionBar {
|
||||
|
@ -260,17 +255,20 @@ ActionBar {
|
|||
padding: 2 16 0 0;
|
||||
font-size: 16;
|
||||
vertical-alignment: center;
|
||||
&.bx{
|
||||
&.bx {
|
||||
padding: 0 0 0 16;
|
||||
}
|
||||
}
|
||||
MDRipple {
|
||||
padding: 0 16;
|
||||
}
|
||||
MDButton.bx {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.sd-group-header {
|
||||
width: 100%;
|
||||
padding: 8;
|
||||
padding: 0 0 8 8;
|
||||
}
|
||||
MDRipple {
|
||||
border-radius: 4;
|
||||
|
@ -313,7 +311,7 @@ MDButton {
|
|||
font-size: 20;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin: 0 0 8;
|
||||
horizontal-alignment: center;
|
||||
.bx {
|
||||
font-size: 24;
|
||||
|
@ -356,8 +354,8 @@ RadListView {
|
|||
border-radius: 4 0 0 4;
|
||||
// prettier-ignore
|
||||
Image {
|
||||
border-radius: 4 0 0 4;
|
||||
}
|
||||
border-radius: 4 0 0 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
.swipe-item {
|
||||
|
@ -404,8 +402,8 @@ RadListView {
|
|||
// VIEW RECIPE
|
||||
.viewRecipe {
|
||||
.category,
|
||||
.time,
|
||||
.ingredient {
|
||||
.ingredient,
|
||||
.time {
|
||||
font-size: 16;
|
||||
}
|
||||
.category {
|
||||
|
@ -413,14 +411,15 @@ RadListView {
|
|||
}
|
||||
.time {
|
||||
margin: 0 8;
|
||||
.bx {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: 22;
|
||||
line-height: 6;
|
||||
}
|
||||
.subTitle {
|
||||
font-size: 18;
|
||||
line-height: 4;
|
||||
}
|
||||
.overviewContainer {
|
||||
margin-top: 12;
|
||||
.overviewItem {
|
||||
|
@ -507,7 +506,7 @@ MDFloatingActionButton {
|
|||
font-size: 14;
|
||||
horizontal-alignment: left;
|
||||
padding: 12;
|
||||
margin: 8 0 0 0;
|
||||
margin: 8 0 0;
|
||||
min-width: 0;
|
||||
}
|
||||
MDButton.closeBtn {
|
||||
|
@ -544,7 +543,7 @@ MDButton.closeBtn {
|
|||
padding: 0 0 0 16;
|
||||
}
|
||||
.recipes {
|
||||
margin: 4 8 4;
|
||||
margin: 4 8;
|
||||
.recipeTitle {
|
||||
font-size: 14;
|
||||
padding: 6 8;
|
||||
|
@ -555,8 +554,8 @@ MDButton.closeBtn {
|
|||
vertical-alignment: top;
|
||||
}
|
||||
}
|
||||
MDRipple,
|
||||
MDButton {
|
||||
MDButton,
|
||||
MDRipple {
|
||||
ripple-color: rgba($gray6, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -612,7 +611,6 @@ MDButton.closeBtn {
|
|||
margin: 0 16 16;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
MDActivityIndicator {
|
||||
width: 24;
|
||||
|
@ -647,7 +645,6 @@ MDActivityIndicator {
|
|||
75% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
@ -656,7 +653,6 @@ MDActivityIndicator {
|
|||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
|
|
|
@ -1,95 +1,71 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<GridLayout rows="*" columns="auto, *">
|
||||
<MDButton
|
||||
variant="text"
|
||||
class="bx"
|
||||
:text="icon.menu"
|
||||
automationText="Back"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" text="About" col="1" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView @scroll="onScroll">
|
||||
<StackLayout class="main-container">
|
||||
<StackLayout
|
||||
horizontalAlignment="center"
|
||||
orientation="horizontal"
|
||||
class="appIconContainer"
|
||||
>
|
||||
<Image src="res://logo" class="appIcon" stretch="aspectFit" />
|
||||
</StackLayout>
|
||||
<StackLayout class="m-8"></StackLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<Label col="0" class="bx" :text="icon.info" />
|
||||
<StackLayout col="1">
|
||||
<Label text="Version" />
|
||||
<Label :text="getVersion" class="info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple
|
||||
colSpan="2"
|
||||
@tap="openURL('https://github.com/vishnuraghavb/enrecipes')"
|
||||
/>
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label
|
||||
verticalAlignment="center"
|
||||
col="1"
|
||||
text="View project on GitHub"
|
||||
/>
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://t.me/enrecipes')" />
|
||||
<Label col="0" class="bx" :text="icon.telegram" />
|
||||
<StackLayout col="1">
|
||||
<Label text="Join the Telegram group" />
|
||||
<Label
|
||||
text="for reporting issues, suggestions and feedback"
|
||||
class="info"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label text="Author" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple
|
||||
colSpan="2"
|
||||
@tap="openURL('https://www.vishnuraghav.com')"
|
||||
/>
|
||||
<Label col="0" class="bx" :text="icon.user" />
|
||||
<Label verticalAlignment="center" col="1" text="Vishnu Raghav B" />
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple
|
||||
colSpan="2"
|
||||
@tap="openURL('https://github.com/vishnuraghavb')"
|
||||
/>
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label verticalAlignment="center" col="1" text="Follow on GitHub" />
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple
|
||||
colSpan="2"
|
||||
@tap="openURL('https://mastodon.social/@vishnuraghavb')"
|
||||
/>
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label verticalAlignment="center" col="1" text="Follow on Mastodon" />
|
||||
</GridLayout>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<GridLayout rows="*" columns="auto, *">
|
||||
<MDButton variant="text" class="bx" :text="icon.menu" automationText="Back" @tap="showDrawer" col="0" />
|
||||
<Label class="title orkm" :text="'About' | L" col="1" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView @scroll="onScroll">
|
||||
<StackLayout class="main-container">
|
||||
<StackLayout horizontalAlignment="center" orientation="horizontal" class="appIconContainer">
|
||||
<Image src="res://logo" class="appIcon" stretch="aspectFit" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
<StackLayout class="m-8"></StackLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<Label col="0" class="bx" :text="icon.info" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'Version' | L" />
|
||||
<Label :text="getVersion" class="info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://github.com/vishnuraghavb/enrecipes')" />
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label verticalAlignment="center" col="1" :text="'View project on GitHub' | L" textWrap="true" />
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://t.me/enrecipes')" />
|
||||
<Label col="0" class="bx" :text="icon.telegram" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'Join the Telegram group' | L" textWrap="true" />
|
||||
<Label :text="'for reporting issues, suggestions and feedback' | L" class="info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
|
||||
<Label :text="'Author' | L" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://www.vishnuraghav.com')" />
|
||||
<Label col="0" class="bx" :text="icon.user" />
|
||||
<Label verticalAlignment="center" col="1" :text="'Vishnu Raghav B' | L" textWrap="true" />
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://github.com/vishnuraghavb')" />
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label verticalAlignment="center" col="1" :text="'Follow on GitHub' | L" textWrap="true" />
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="openURL('https://mastodon.social/@vishnuraghavb')" />
|
||||
<Label col="0" class="bx" :text="icon.link" />
|
||||
<Label verticalAlignment="center" col="1" :text="'Follow on Mastodon' | L" textWrap="true" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application, Utils } from "@nativescript/core"
|
||||
import { mapActions, mapState } from "vuex"
|
||||
import {
|
||||
Application,
|
||||
Utils,
|
||||
Observable
|
||||
} from "@nativescript/core"
|
||||
import {
|
||||
mapActions,
|
||||
mapState
|
||||
} from "vuex"
|
||||
|
||||
import * as utils from "~/shared/utils"
|
||||
|
||||
|
@ -110,7 +86,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(["setCurrentComponentAction"]),
|
||||
onPageLoad() {
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
this.setCurrentComponentAction("About")
|
||||
},
|
||||
// HELPERS
|
||||
|
|
|
@ -1,141 +1,60 @@
|
|||
<template>
|
||||
<Page
|
||||
@loaded="onPageLoad"
|
||||
actionBarHidden="true"
|
||||
:androidStatusBarBackground="appTheme == 'Light' ? '#f1f3f5' : '#212529'"
|
||||
>
|
||||
<RadSideDrawer
|
||||
allowEdgeSwipe="true"
|
||||
showOverNavigation="true"
|
||||
ref="drawer"
|
||||
id="sideDrawer"
|
||||
drawerContentSize="270"
|
||||
gesturesEnabled="true"
|
||||
drawerTransition="SlideInOnTopTransition"
|
||||
>
|
||||
<GridLayout rows="*, auto" columns="*" ~drawerContent class="sd">
|
||||
<StackLayout row="0">
|
||||
<GridLayout
|
||||
rows="48"
|
||||
columns="auto, 24, *"
|
||||
v-for="(item, index) in topmenu"
|
||||
:key="index"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-sd-item': currentComponent === item.component,
|
||||
}"
|
||||
>
|
||||
<MDRipple
|
||||
row="0"
|
||||
colSpan="3"
|
||||
@tap="navigateTo(item.component, false, false)"
|
||||
/>
|
||||
<Label col="0" row="0" class="bx" :text="icon[item.icon]" />
|
||||
<Label col="2" row="0" :text="item.title" />
|
||||
</GridLayout>
|
||||
<StackLayout class="hr m-8"></StackLayout>
|
||||
<GridLayout
|
||||
rows="48"
|
||||
columns="auto, 24, *"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
'selected-sd-item': currentComponent === 'MealPlanner',
|
||||
}"
|
||||
>
|
||||
<MDRipple
|
||||
row="0"
|
||||
colSpan="3"
|
||||
@tap="navigateTo(MealPlanner, true, false)"
|
||||
/>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true" :androidStatusBarBackground="appTheme == 'Light' ? '#f1f3f5' : '#212529'">
|
||||
|
||||
<Label col="0" row="0" class="bx" :text="icon.calendar" />
|
||||
<Label col="2" row="0" text="Meal Planner" />
|
||||
</GridLayout>
|
||||
<StackLayout class="hr m-8"></StackLayout>
|
||||
<GridLayout
|
||||
class="sd-group-header orkm"
|
||||
rows="auto"
|
||||
columns="*, auto"
|
||||
v-if="categoriesWithRecipes.length"
|
||||
>
|
||||
<Label verticalAlignment="center" col="0" text="Categories" />
|
||||
<MDButton
|
||||
variant="text"
|
||||
@tap="toggleCatEdit"
|
||||
col="2"
|
||||
:text="editCategory ? 'DONE' : 'RENAME'"
|
||||
/>
|
||||
</GridLayout>
|
||||
<ScrollView height="100%">
|
||||
<StackLayout>
|
||||
<GridLayout
|
||||
v-for="(item, index) in categoriesWithRecipes"
|
||||
:key="index"
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
<RadSideDrawer allowEdgeSwipe="true" showOverNavigation="true" ref="drawer" id="sideDrawer" drawerContentSize="270" gesturesEnabled="true" drawerTransition="SlideInOnTopTransition">
|
||||
<GridLayout rows="*, auto" columns="*" ~drawerContent class="sd">
|
||||
<StackLayout row="0">
|
||||
<GridLayout rows="48" columns="auto, 24, *" v-for="(item, index) in topmenu" :key="index" class="sd-item orkm" :class="{
|
||||
'selected-sd-item': currentComponent === item.component,
|
||||
}">
|
||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(item.component, item.component, false, false)" />
|
||||
<Label col="0" row="0" class="bx" :text="icon[item.icon]" />
|
||||
<Label col="2" row="0" :text="`${item.title}` | L" />
|
||||
</GridLayout>
|
||||
<StackLayout class="hr" margin="8"></StackLayout>
|
||||
<GridLayout rows="48" columns="auto, 24, *" class="sd-item orkm" :class="{
|
||||
'selected-sd-item': currentComponent === 'MealPlanner',
|
||||
}">
|
||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(MealPlanner, 'MealPlanner', true, false)" />
|
||||
|
||||
<Label col="0" row="0" class="bx" :text="icon.calendar" />
|
||||
<Label col="2" row="0" :text="'Meal Planner' | L" />
|
||||
</GridLayout>
|
||||
<StackLayout class="hr" margin="8"></StackLayout>
|
||||
<GridLayout class="sd-group-header orkm" rows="auto" columns="*, auto" v-if="categoriesWithRecipes.length">
|
||||
<Label verticalAlignment="center" col="0" :text="'Categories' | L" />
|
||||
<MDButton variant="text" @tap="toggleCatEdit" col="2" :text="`${editCategory ? 'DONE' : 'RENAME'}` | L" />
|
||||
</GridLayout>
|
||||
<ScrollView height="100%">
|
||||
<StackLayout>
|
||||
<GridLayout v-for="(item, index) in categoriesWithRecipes" :key="index" class="sd-item orkm" :class="{
|
||||
'selected-sd-item': currentComponent == item,
|
||||
}"
|
||||
columns="auto, *, auto"
|
||||
>
|
||||
<MDRipple
|
||||
row="0"
|
||||
colSpan="3"
|
||||
@tap="navigateTo(item, false, true)"
|
||||
/>
|
||||
<Label
|
||||
col="0"
|
||||
class="bx"
|
||||
:text="icon.label"
|
||||
margin="0 24 0 0"
|
||||
/>
|
||||
<Label col="1" :text="item" />
|
||||
<MDButton
|
||||
variant="text"
|
||||
v-if="editCategory"
|
||||
@tap="renameCategory(item)"
|
||||
col="2"
|
||||
class="bx"
|
||||
:text="icon.edit"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</StackLayout>
|
||||
<StackLayout row="1">
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
<GridLayout
|
||||
class="sd-item orkm"
|
||||
:class="{
|
||||
}" columns="auto, *, auto">
|
||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(item, item, false, true)" />
|
||||
<Label col="0" class="bx" :text="icon.label" margin="0 24 0 0" />
|
||||
<Label col="1" :text="`${item}` | L" />
|
||||
<MDButton variant="text" v-if="editCategory" @tap="renameCategory(item)" col="2" class="bx" :text="icon.edit" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</StackLayout>
|
||||
<StackLayout row="1">
|
||||
<StackLayout class="hr" margin="0 8 8"></StackLayout>
|
||||
<GridLayout class="sd-item orkm" :class="{
|
||||
'selected-sd-item': currentComponent == item.title,
|
||||
}"
|
||||
v-for="(item, index) in bottommenu"
|
||||
:key="index"
|
||||
rows="48"
|
||||
columns="auto, 24, *"
|
||||
>
|
||||
<MDRipple
|
||||
colSpan="3"
|
||||
@tap="navigateTo(item.component, true, false)"
|
||||
/>
|
||||
<Label class="bx" col="0" :text="icon[item.icon]" />
|
||||
<Label col="2" :text="item.title" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<Frame ~mainContent id="main-frame">
|
||||
<!-- Home -->
|
||||
<EnRecipes
|
||||
ref="enrecipes"
|
||||
:filterFavorites="filterFavorites"
|
||||
:filterTrylater="filterTrylater"
|
||||
:selectedCategory="selectedCategory"
|
||||
:closeDrawer="closeDrawer"
|
||||
:hijackGlobalBackEvent="hijackGlobalBackEvent"
|
||||
:releaseGlobalBackEvent="releaseGlobalBackEvent"
|
||||
/>
|
||||
</Frame>
|
||||
</RadSideDrawer>
|
||||
</Page>
|
||||
}" v-for="(item, index) in bottommenu" :key="index" rows="48" columns="auto, 24, *">
|
||||
<MDRipple colSpan="3" @tap="navigateTo(item.component, 'item.title', true, false)" />
|
||||
<Label class="bx" col="0" :text="icon[item.icon]" />
|
||||
<Label col="2" :text="`${item.title}` | L" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<Frame ~mainContent id="main-frame">
|
||||
<EnRecipes ref="enrecipes" :filterFavourites="filterFavourites" :filterTrylater="filterTrylater" :selectedCategory="selectedCategory" :closeDrawer="closeDrawer" :hijackGlobalBackEvent="hijackGlobalBackEvent"
|
||||
:releaseGlobalBackEvent="releaseGlobalBackEvent" />
|
||||
</Frame>
|
||||
</RadSideDrawer>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -143,11 +62,17 @@ import {
|
|||
ApplicationSettings,
|
||||
AndroidApplication,
|
||||
Application,
|
||||
} from "@nativescript/core"
|
||||
Device
|
||||
}
|
||||
from "@nativescript/core"
|
||||
import Theme from "@nativescript/theme"
|
||||
import * as Toast from "nativescript-toast"
|
||||
import * as application from "tns-core-modules/application"
|
||||
import { mapActions, mapState } from "vuex"
|
||||
import {
|
||||
mapActions,
|
||||
mapState
|
||||
}
|
||||
from "vuex"
|
||||
|
||||
import EnRecipes from "./EnRecipes"
|
||||
import MealPlanner from "./MealPlanner"
|
||||
|
@ -160,11 +85,10 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
selectedCategory: null,
|
||||
filterFavorites: false,
|
||||
filterFavourites: false,
|
||||
filterTrylater: false,
|
||||
MealPlanner: MealPlanner,
|
||||
topmenu: [
|
||||
{
|
||||
topmenu: [ {
|
||||
title: "EnRecipes",
|
||||
component: "EnRecipes",
|
||||
icon: "home",
|
||||
|
@ -175,13 +99,12 @@ export default {
|
|||
icon: "trylater",
|
||||
},
|
||||
{
|
||||
title: "Favorites",
|
||||
component: "Favorites",
|
||||
title: "Favourites",
|
||||
component: "Favourites",
|
||||
icon: "heart",
|
||||
},
|
||||
],
|
||||
bottommenu: [
|
||||
{
|
||||
bottommenu: [ {
|
||||
title: "Settings",
|
||||
component: Settings,
|
||||
icon: "cog",
|
||||
|
@ -201,68 +124,68 @@ export default {
|
|||
MealPlanner,
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
...mapState( [
|
||||
"icon",
|
||||
"recipes",
|
||||
"categories",
|
||||
"yieldUnits",
|
||||
"mealPlans",
|
||||
"currentComponent",
|
||||
]),
|
||||
] ),
|
||||
categoriesWithRecipes() {
|
||||
let arr = this.recipes.map((e) => {
|
||||
let arr = this.recipes.map( ( e ) => {
|
||||
return e.category
|
||||
})
|
||||
return [...new Set(arr)]
|
||||
} )
|
||||
return [ ...new Set( arr ) ]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
...mapActions( [
|
||||
"setCurrentComponentAction",
|
||||
"initializeRecipes",
|
||||
"initializeCategories",
|
||||
"initializeYieldUnits",
|
||||
"initializeMealPlans",
|
||||
"renameCategoryAction",
|
||||
]),
|
||||
] ),
|
||||
onPageLoad() {
|
||||
if (this.appTheme === "Light") {
|
||||
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)
|
||||
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR )
|
||||
}
|
||||
},
|
||||
|
||||
// HELPERS
|
||||
toggleCatEdit() {
|
||||
this.editCategory = !this.editCategory
|
||||
if (this.selectedCategory) this.setComponent("EnRecipes")
|
||||
this.filterFavorites = this.filterTrylater = false
|
||||
if ( this.selectedCategory ) this.setCurrentComponentAction( "EnRecipes" )
|
||||
this.filterFavourites = this.filterTrylater = false
|
||||
this.selectedCategory = null
|
||||
this.$refs.enrecipes.updateFilter()
|
||||
},
|
||||
setComponent(comp) {
|
||||
this.setCurrentComponentAction(comp)
|
||||
},
|
||||
renameCategory(category) {
|
||||
renameCategory( category ) {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal( PromptDialog, {
|
||||
props: {
|
||||
title: `Rename category`,
|
||||
text: category,
|
||||
action: "RENAME",
|
||||
},
|
||||
}).then((newCategory) => {
|
||||
} ).then( ( newCategory ) => {
|
||||
this.hijackGlobalBackEvent()
|
||||
if (newCategory.length) {
|
||||
this.renameCategoryAction({ current: category, updated: newCategory })
|
||||
if ( newCategory.length ) {
|
||||
this.renameCategoryAction( {
|
||||
current: category,
|
||||
updated: newCategory
|
||||
} )
|
||||
this.editCategory = false
|
||||
this.navigateTo(newCategory, false, true)
|
||||
this.navigateTo( newCategory, newCategory, false, true )
|
||||
}
|
||||
})
|
||||
} )
|
||||
},
|
||||
setSelectedCategory(e) {
|
||||
setSelectedCategory( e ) {
|
||||
this.selectedCategory = e.item
|
||||
this.closeDrawer()
|
||||
},
|
||||
|
@ -284,67 +207,68 @@ export default {
|
|||
this.globalBackEvent
|
||||
)
|
||||
},
|
||||
globalBackEvent(args) {
|
||||
globalBackEvent( args ) {
|
||||
function preventDefault() {
|
||||
args.cancel = true
|
||||
}
|
||||
let vm = this
|
||||
function isFiltered() {
|
||||
vm.filterFavorites
|
||||
? vm.setComponent("Favorites")
|
||||
: vm.filterTrylater
|
||||
? vm.setComponent("Try Later")
|
||||
: vm.selectedCategory
|
||||
? vm.setComponent(vm.selectedCategory)
|
||||
: vm.setComponent("EnRecipes")
|
||||
}
|
||||
if (this.$refs.drawer && this.$refs.drawer.nativeView.getIsOpen()) {
|
||||
if ( this.$refs.drawer && this.$refs.drawer.nativeView.getIsOpen() ) {
|
||||
preventDefault()
|
||||
this.closeDrawer()
|
||||
this.editCategory = false
|
||||
} else if (
|
||||
["Favorites", "Try Later", this.selectedCategory].includes(
|
||||
}
|
||||
else if (
|
||||
[ "Favourites", "Try Later", this.selectedCategory ].includes(
|
||||
this.currentComponent
|
||||
)
|
||||
) {
|
||||
preventDefault()
|
||||
this.setComponent("EnRecipes")
|
||||
this.filterFavorites = this.filterTrylater = false
|
||||
this.setCurrentComponentAction( "EnRecipes" )
|
||||
this.filterFavourites = this.filterTrylater = false
|
||||
this.selectedCategory = null
|
||||
this.$refs.enrecipes.updateFilter()
|
||||
this.releaseGlobalBackEvent()
|
||||
}
|
||||
},
|
||||
navigateTo(to, isTrueComponent, isCategory) {
|
||||
if (isTrueComponent) {
|
||||
this.$navigateTo(to, {
|
||||
frame: "main-frame",
|
||||
backstackVisible: false,
|
||||
})
|
||||
this.closeDrawer()
|
||||
} else if (!this.editCategory || !isCategory) {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.hijackGlobalBackEvent()
|
||||
this.setComponent(to)
|
||||
this.$navigateBack({ frame: "main-frame", backstackVisible: false })
|
||||
this.filterFavorites = to === "Favorites" ? true : false
|
||||
this.filterTrylater = to === "Try Later" ? true : false
|
||||
this.selectedCategory = isCategory ? to : null
|
||||
this.$refs.enrecipes.updateFilter()
|
||||
navigateTo( to, title, isTrueComponent, isCategory ) {
|
||||
if ( title !== this.currentComponent ) {
|
||||
if ( isTrueComponent ) {
|
||||
this.$navigateTo( to, {
|
||||
frame: "main-frame",
|
||||
backstackVisible: false
|
||||
} )
|
||||
this.closeDrawer()
|
||||
}
|
||||
else if ( !this.editCategory || !isCategory ) {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.hijackGlobalBackEvent()
|
||||
this.setCurrentComponentAction( to )
|
||||
this.$navigateBack( {
|
||||
frame: "main-frame",
|
||||
backstackVisible: false
|
||||
} )
|
||||
this.filterFavourites = to === "Favourites" ? true : false
|
||||
this.filterTrylater = to === "Try Later" ? true : false
|
||||
this.selectedCategory = isCategory ? to : null
|
||||
this.$refs.enrecipes.updateFilter()
|
||||
this.closeDrawer()
|
||||
}
|
||||
this.editCategory = false
|
||||
}
|
||||
else {
|
||||
this.closeDrawer()
|
||||
}
|
||||
this.editCategory = false
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.appTheme = ApplicationSettings.getString("appTheme", "Light")
|
||||
setTimeout((e) => {
|
||||
Theme.setMode(Theme[this.appTheme])
|
||||
}, 10)
|
||||
if (!this.recipes.length) this.initializeRecipes()
|
||||
if (!this.categories.length) this.initializeCategories()
|
||||
if (!this.yieldUnits.length) this.initializeYieldUnits()
|
||||
if (!this.mealPlans.length) this.initializeMealPlans()
|
||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
||||
setTimeout( ( e ) => {
|
||||
Theme.setMode( Theme[ this.appTheme ] )
|
||||
}, 10 )
|
||||
if ( !this.recipes.length ) this.initializeRecipes()
|
||||
if ( !this.categories.length ) this.initializeCategories()
|
||||
if ( !this.yieldUnits.length ) this.initializeYieldUnits()
|
||||
if ( !this.mealPlans.length ) this.initializeMealPlans()
|
||||
console.log( Device.language );
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,246 +1,123 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<!-- Search Actionbar -->
|
||||
<GridLayout
|
||||
v-if="showSearch"
|
||||
columns="auto, *"
|
||||
verticalAlignment="center"
|
||||
>
|
||||
<MDButton
|
||||
class="bx"
|
||||
:text="icon.back"
|
||||
variant="text"
|
||||
automationText="Back"
|
||||
col="0"
|
||||
@tap="closeSearch"
|
||||
/>
|
||||
<SearchBar
|
||||
col="1"
|
||||
hint="Search"
|
||||
v-model="searchQuery"
|
||||
@textChange="updateFilter"
|
||||
@clear="clearSearch"
|
||||
/>
|
||||
</GridLayout>
|
||||
<!-- Home Actionbar -->
|
||||
<GridLayout v-else columns="auto, *, auto, auto">
|
||||
<MDButton
|
||||
class="bx"
|
||||
col="0"
|
||||
variant="text"
|
||||
@tap="showDrawer"
|
||||
:text="icon.menu"
|
||||
automationText="Back"
|
||||
/>
|
||||
<Label class="title orkm" :text="currentComponent" col="1" />
|
||||
<MDButton
|
||||
v-if="recipes.length"
|
||||
class="bx"
|
||||
:text="icon.search"
|
||||
variant="text"
|
||||
col="2"
|
||||
@tap="openSearch"
|
||||
/>
|
||||
<MDButton
|
||||
v-if="recipes.length"
|
||||
class="bx"
|
||||
:text="icon.sort"
|
||||
variant="text"
|
||||
col="3"
|
||||
@tap="sortDialog"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<AbsoluteLayout>
|
||||
<RadListView
|
||||
ref="listView"
|
||||
itemHeight="112"
|
||||
for="recipe in recipes"
|
||||
swipeActions="true"
|
||||
@itemSwipeProgressChanged="onSwiping"
|
||||
@itemSwipeProgressEnded="onSwipeEnded"
|
||||
@scrolled="onScroll"
|
||||
:filteringFunction="filterFunction"
|
||||
:sortingFunction="sortFunction"
|
||||
>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
class="recipeItem"
|
||||
rows="112"
|
||||
columns="112, *"
|
||||
androidElevation="1"
|
||||
>
|
||||
<MDRipple colSpan="2" @tap="viewRecipe(recipe.id)" />
|
||||
<GridLayout class="imageHolder card" rows="112" columns="112">
|
||||
<Image
|
||||
row="0"
|
||||
col="0"
|
||||
v-if="recipe.imageSrc"
|
||||
:src="recipe.imageSrc"
|
||||
stretch="aspectFill"
|
||||
decodeWidth="112"
|
||||
decodeHeight="112"
|
||||
loadMode="async"
|
||||
/>
|
||||
<Label
|
||||
v-else
|
||||
row="0"
|
||||
col="0"
|
||||
horizontalAlignment="center"
|
||||
class="bx"
|
||||
fontSize="56"
|
||||
:text="icon.image"
|
||||
/>
|
||||
</GridLayout>
|
||||
<StackLayout class="recipeInfo" col="1">
|
||||
<Label :text="recipe.category" class="orkm category" />
|
||||
<Label :text="recipe.title" class="orkm title" />
|
||||
<StackLayout class="timeContainer" orientation="horizontal">
|
||||
<Label class="bx small" :text="icon.time" />
|
||||
<Label
|
||||
class="time"
|
||||
:text="
|
||||
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<GridLayout v-if="showSearch" columns="auto, *" verticalAlignment="center">
|
||||
<MDButton class="bx" :text="icon.back" variant="text" automationText="Back" col="0" @tap="closeSearch" />
|
||||
<SearchBar col="1" :hint="'Search' | L" v-model="searchQuery" @textChange="updateFilter" @clear="clearSearch" />
|
||||
</GridLayout>
|
||||
<GridLayout v-else columns="auto, *, auto, auto">
|
||||
<MDButton class="bx" col="0" variant="text" @tap="showDrawer" :text="icon.menu" automationText="Back" />
|
||||
<Label class="title orkm" :text="`${currentComponent}` | L" col="1" />
|
||||
<MDButton v-if="recipes.length" class="bx" :text="icon.search" variant="text" col="2" @tap="openSearch" />
|
||||
<MDButton v-if="recipes.length" class="bx" :text="icon.sort" variant="text" col="3" @tap="sortDialog" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<AbsoluteLayout>
|
||||
<RadListView ref="listView" itemHeight="112" for="recipe in recipes" swipeActions="true" @itemSwipeProgressChanged="onSwiping" @itemSwipeProgressEnded="onSwipeEnded" @scrolled="onScroll" :filteringFunction="filterFunction"
|
||||
:sortingFunction="sortFunction">
|
||||
<v-template>
|
||||
<GridLayout class="recipeItem" rows="112" columns="112, *" androidElevation="1">
|
||||
<MDRipple colSpan="2" @tap="viewRecipe(recipe.id)" />
|
||||
<GridLayout class="imageHolder card" rows="112" columns="112">
|
||||
<Image row="0" col="0" v-if="recipe.imageSrc" :src="recipe.imageSrc" stretch="aspectFill" decodeWidth="112" decodeHeight="112" loadMode="async" />
|
||||
<Label v-else row="0" col="0" horizontalAlignment="center" class="bx" fontSize="56" :text="icon.image" />
|
||||
</GridLayout>
|
||||
<StackLayout class="recipeInfo" col="1">
|
||||
<Label :text="`${recipe.category}` | L" class="orkm category" />
|
||||
<Label :text="recipe.title" class="orkm title" />
|
||||
<StackLayout class="timeContainer" orientation="horizontal">
|
||||
<Label class="bx small" :text="icon.time" />
|
||||
<Label class="time" :text="
|
||||
`${
|
||||
formattedTotalTime(recipe.prepTime, recipe.cookTime).time
|
||||
}`
|
||||
"
|
||||
/>
|
||||
</StackLayout>
|
||||
" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template name="itemswipe">
|
||||
<GridLayout columns="*, auto">
|
||||
<StackLayout id="delete-action" col="1" class="swipe-item right">
|
||||
<Label class="bx" padding="8 0 0 6" :text="icon.trash" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template name="footer">
|
||||
<StackLayout height="80"></StackLayout>
|
||||
</v-template>
|
||||
</RadListView>
|
||||
<GridLayout rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
|
||||
<StackLayout
|
||||
row="1"
|
||||
class="emptyState"
|
||||
v-if="
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template name="itemswipe">
|
||||
<GridLayout columns="*, auto">
|
||||
<StackLayout id="delete-action" col="1" class="swipe-item right">
|
||||
<Label class="bx" padding="8 0 0 6" :text="icon.trash" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template name="footer">
|
||||
<StackLayout height="80"></StackLayout>
|
||||
</v-template>
|
||||
</RadListView>
|
||||
<GridLayout rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
|
||||
<StackLayout row="1" class="emptyState" v-if="
|
||||
!recipes.length &&
|
||||
!filterFavorites &&
|
||||
!filterFavourites &&
|
||||
!filterTrylater &&
|
||||
!selectedCategory
|
||||
"
|
||||
@tap="addRecipe"
|
||||
>
|
||||
<Label class="bx icon" :text="icon.plusCircle" />
|
||||
<Label
|
||||
class="title orkm"
|
||||
text="Start adding your recipes!"
|
||||
textWrap="true"
|
||||
/>
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label text="Use the " />
|
||||
<Label class="bx" :text="icon.plus" />
|
||||
<Label text=" button to add one" />
|
||||
</StackLayout>
|
||||
" @tap="addRecipe">
|
||||
<Label class="bx icon" :text="icon.plusCircle" />
|
||||
<Label class="title orkm" :text="'Start adding your recipes!' | L" textWrap="true" />
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label :text="'Use the plus button to add one' | L" textWrap="true" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
row="1"
|
||||
class="emptyState"
|
||||
v-if="!filteredRecipes.length && filterTrylater && !searchQuery"
|
||||
>
|
||||
<Label class="bx icon" :text="icon.trylaterOutline" textWrap="true" />
|
||||
<Label class="title orkm" text="All done!" textWrap="true" />
|
||||
<Label
|
||||
text="Recipes you mark as try later will be listed here"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && filterTrylater && !searchQuery">
|
||||
<Label class="bx icon" :text="icon.trylaterOutline" textWrap="true" />
|
||||
<Label class="title orkm" :text="'All done!' | L" textWrap="true" />
|
||||
<Label :text="'Recipes you mark as try later will be listed here' | L" textWrap="true" />
|
||||
</StackLayout>
|
||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && filterFavourites && !searchQuery">
|
||||
<Label class="bx icon" :text="icon.heartOutline" textWrap="true" />
|
||||
<Label class="title orkm" :text="'No favourites yet' | L" textWrap="true" />
|
||||
<Label :text="'Recipes you mark as favourite will be listed here' | L" textWrap="true" />
|
||||
</StackLayout>
|
||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && !searchQuery && selectedCategory">
|
||||
<Label class="bx icon" :text="icon.labelOutline" textWrap="true" />
|
||||
<Label class="title orkm" :text="'Category looks empty' | L" textWrap="true" />
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label :text="'Use the plus button to add one' | L" textWrap="true" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
row="1"
|
||||
class="emptyState"
|
||||
v-if="!filteredRecipes.length && filterFavorites && !searchQuery"
|
||||
>
|
||||
<Label class="bx icon" :text="icon.heartOutline" textWrap="true" />
|
||||
<Label class="title orkm" text="No favorites yet" textWrap="true" />
|
||||
<Label
|
||||
text="Recipes you mark as favorite will be listed here"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
row="1"
|
||||
class="emptyState"
|
||||
v-if="!filteredRecipes.length && !searchQuery && selectedCategory"
|
||||
>
|
||||
<Label class="bx icon" :text="icon.labelOutline" textWrap="true" />
|
||||
<Label
|
||||
class="title orkm"
|
||||
text="Category looks empty"
|
||||
textWrap="true"
|
||||
/>
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label text="Use the " textWrap="true" />
|
||||
<Label class="bx" :text="icon.plus" />
|
||||
<Label text=" button to add a recipe" textWrap="true" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
row="1"
|
||||
class="emptyState"
|
||||
v-if="!filteredRecipes.length && searchQuery"
|
||||
>
|
||||
<Label class="bx icon" :text="icon.search" textWrap="true" />
|
||||
<Label class="title orkm" text="No recipes found" textWrap="true" />
|
||||
<Label
|
||||
:text="
|
||||
`Your search "${searchQuery}" did not match any recipes${noResultFor}`
|
||||
"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
||||
<transition name="bounce">
|
||||
<MDFloatingActionButton
|
||||
v-if="showFAB"
|
||||
row="1"
|
||||
col="1"
|
||||
class="bx fab-button"
|
||||
src="res://plus"
|
||||
@tap="addRecipe"
|
||||
/>
|
||||
</transition>
|
||||
</GridLayout>
|
||||
</AbsoluteLayout>
|
||||
</Page>
|
||||
</StackLayout>
|
||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && searchQuery">
|
||||
<Label class="bx icon" :text="icon.search" textWrap="true" />
|
||||
<Label class="title orkm" :text="'No recipes found' | L" textWrap="true" />
|
||||
<Label :text="`${noResultFor}` | L" textWrap="true" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
||||
<transition name="bounce">
|
||||
<MDFloatingActionButton v-if="showFAB" row="1" col="1" class="bx fab-button" src="res://plus" @tap="addRecipe" />
|
||||
</transition>
|
||||
</GridLayout>
|
||||
</AbsoluteLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { AndroidApplication, Utils } from "@nativescript/core"
|
||||
import { mapActions, mapState } from "vuex"
|
||||
|
||||
import EditRecipe from "./EditRecipe.vue"
|
||||
import ViewRecipe from "./ViewRecipe.vue"
|
||||
|
||||
import ActionDialog from "./modal/ActionDialog.vue"
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||
|
||||
import * as utils from "~/shared/utils"
|
||||
|
||||
import {
|
||||
AndroidApplication,
|
||||
Utils,
|
||||
Observable
|
||||
}
|
||||
from "@nativescript/core";
|
||||
import {
|
||||
localize
|
||||
}
|
||||
from "@nativescript/localize"
|
||||
import {
|
||||
mapActions,
|
||||
mapState
|
||||
}
|
||||
from "vuex";
|
||||
import EditRecipe from "./EditRecipe.vue";
|
||||
import ViewRecipe from "./ViewRecipe.vue";
|
||||
import ActionDialog from "./modal/ActionDialog.vue";
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
||||
import * as utils from "~/shared/utils";
|
||||
export default {
|
||||
props: [
|
||||
"filterFavorites",
|
||||
"filterTrylater",
|
||||
"closeDrawer",
|
||||
"selectedCategory",
|
||||
"hijackGlobalBackEvent",
|
||||
"releaseGlobalBackEvent",
|
||||
],
|
||||
props: [ "filterFavourites", "filterTrylater", "closeDrawer", "selectedCategory", "hijackGlobalBackEvent", "releaseGlobalBackEvent" ],
|
||||
components: {
|
||||
EditRecipe,
|
||||
ViewRecipe,
|
||||
ViewRecipe
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -250,245 +127,228 @@ export default {
|
|||
rightAction: false,
|
||||
sortType: "Natural order",
|
||||
deletionDialogActive: false,
|
||||
showFAB: false,
|
||||
}
|
||||
showFAB: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "recipes", "currentComponent"]),
|
||||
...mapState( [ "icon", "recipes", "currentComponent" ] ),
|
||||
filteredRecipes() {
|
||||
if (this.filterFavorites) {
|
||||
return this.recipes.filter(
|
||||
(e) =>
|
||||
e.isFavorite && e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else if (this.filterTrylater) {
|
||||
return this.recipes.filter(
|
||||
(e) => !e.tried && e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else if (this.selectedCategory) {
|
||||
return this.recipes.filter(
|
||||
(e) =>
|
||||
e.category === this.selectedCategory &&
|
||||
e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else {
|
||||
return this.recipes.filter((e) =>
|
||||
e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
if ( this.filterFavourites ) {
|
||||
return this.recipes.filter( e => e.isFavorite && e.title.toLowerCase().includes( this.searchQuery ) );
|
||||
}
|
||||
else if ( this.filterTrylater ) {
|
||||
return this.recipes.filter( e => !e.tried && e.title.toLowerCase().includes( this.searchQuery ) );
|
||||
}
|
||||
else if ( this.selectedCategory ) {
|
||||
return this.recipes.filter( e => e.category === this.selectedCategory && e.title.toLowerCase().includes( this.searchQuery ) );
|
||||
}
|
||||
else {
|
||||
return this.recipes.filter( e => e.title.toLowerCase().includes( this.searchQuery ) );
|
||||
}
|
||||
},
|
||||
noResultFor() {
|
||||
if (this.selectedCategory) return " in this category"
|
||||
if (this.filterFavorites) return " in your favorites"
|
||||
if (this.filterTrylater) return " in your try later list"
|
||||
return ""
|
||||
},
|
||||
if ( this.selectedCategory ) return "Your search did not match any recipes in this category";
|
||||
if ( this.filterFavourites ) return "Your search did not match any recipes in your favourites";
|
||||
if ( this.filterTrylater ) return "Your search did not match any recipes in your try later list";
|
||||
return "Your search did not match any recipes";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setCurrentComponentAction", "deleteRecipeAction"]),
|
||||
onPageLoad() {
|
||||
this.filterFavorites
|
||||
? this.setComponent("Favorites")
|
||||
: this.filterTrylater
|
||||
? this.setComponent("Try Later")
|
||||
: this.selectedCategory
|
||||
? this.setComponent(this.selectedCategory)
|
||||
: this.setComponent("EnRecipes")
|
||||
this.showFAB = true
|
||||
...mapActions( [ "setCurrentComponentAction", "deleteRecipeAction" ] ),
|
||||
onPageLoad( args ) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
this.filterFavourites ? this.setComponent( "Favourites" ) : this.filterTrylater ? this.setComponent( "Try Later" ) : this.selectedCategory ? this.setComponent( this.selectedCategory ) : this.setComponent( "EnRecipes" );
|
||||
this.showFAB = true;
|
||||
},
|
||||
onPageUnload() {
|
||||
this.releaseGlobalBackEvent();
|
||||
},
|
||||
|
||||
// HELPERS
|
||||
showDrawer() {
|
||||
utils.showDrawer()
|
||||
utils.showDrawer();
|
||||
},
|
||||
openSearch() {
|
||||
this.showSearch = true
|
||||
this.showFAB = false
|
||||
this.hijackLocalBackEvent()
|
||||
this.showSearch = true;
|
||||
this.showFAB = false;
|
||||
this.hijackLocalBackEvent();
|
||||
},
|
||||
closeSearch() {
|
||||
if (this.searchQuery) this.updateFilter()
|
||||
this.searchQuery = ""
|
||||
Utils.ad.dismissSoftInput()
|
||||
this.showSearch = false
|
||||
this.showFAB = true
|
||||
this.releaseLocalBackEvent()
|
||||
if ( this.searchQuery ) this.updateFilter();
|
||||
this.searchQuery = "";
|
||||
Utils.ad.dismissSoftInput();
|
||||
this.showSearch = false;
|
||||
this.showFAB = true;
|
||||
this.releaseLocalBackEvent();
|
||||
},
|
||||
setComponent(comp) {
|
||||
this.setCurrentComponentAction(comp)
|
||||
this.hijackGlobalBackEvent()
|
||||
setComponent( comp ) {
|
||||
this.setCurrentComponentAction( comp );
|
||||
this.hijackGlobalBackEvent();
|
||||
},
|
||||
clearSearch() {
|
||||
if (this.searchQuery !== "") {
|
||||
this.updateFilter()
|
||||
if ( this.searchQuery !== "" ) {
|
||||
this.updateFilter();
|
||||
}
|
||||
},
|
||||
formattedTotalTime(prepTime, cookTime) {
|
||||
let t1 = prepTime.split(":")
|
||||
let t2 = cookTime.split(":")
|
||||
let h = parseInt(t1[0]) + parseInt(t2[0])
|
||||
let m = parseInt(t1[1]) + parseInt(t2[1])
|
||||
formattedTotalTime( prepTime, cookTime ) {
|
||||
let t1 = prepTime.split( ":" );
|
||||
let t2 = cookTime.split( ":" );
|
||||
let h = parseInt( t1[ 0 ] ) + parseInt( t2[ 0 ] );
|
||||
let m = parseInt( t1[ 1 ] ) + parseInt( t2[ 1 ] );
|
||||
let hr = localize( 'hr' )
|
||||
let min = localize( 'min' )
|
||||
return {
|
||||
time: h ? (m ? `${h} hr ${m} min` : `${h} hr`) : `${m} min`,
|
||||
duration: `${h}${m}`,
|
||||
}
|
||||
time: h ? ( m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}` ) : `${m} ${min}`,
|
||||
duration: `${h}${m}`
|
||||
};
|
||||
},
|
||||
onScroll(args) {
|
||||
this.viewIsScrolled = args.scrollOffset ? true : false
|
||||
onScroll( args ) {
|
||||
this.viewIsScrolled = args.scrollOffset ? true : false;
|
||||
},
|
||||
|
||||
// NAVIGATION HANDLERS
|
||||
hijackLocalBackEvent() {
|
||||
this.releaseGlobalBackEvent()
|
||||
AndroidApplication.on(
|
||||
AndroidApplication.activityBackPressedEvent,
|
||||
this.searchBackEvent
|
||||
)
|
||||
this.releaseGlobalBackEvent();
|
||||
AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.searchBackEvent );
|
||||
},
|
||||
releaseLocalBackEvent() {
|
||||
AndroidApplication.off(
|
||||
AndroidApplication.activityBackPressedEvent,
|
||||
this.searchBackEvent
|
||||
)
|
||||
this.hijackGlobalBackEvent()
|
||||
AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.searchBackEvent );
|
||||
this.hijackGlobalBackEvent();
|
||||
},
|
||||
searchBackEvent(args) {
|
||||
args.cancel = true
|
||||
this.closeDrawer()
|
||||
this.closeSearch()
|
||||
searchBackEvent( args ) {
|
||||
args.cancel = true;
|
||||
this.closeDrawer();
|
||||
this.closeSearch();
|
||||
},
|
||||
addRecipe() {
|
||||
this.showFAB = false
|
||||
this.releaseGlobalBackEvent()
|
||||
this.$navigateTo(EditRecipe, {
|
||||
this.showFAB = false;
|
||||
this.releaseGlobalBackEvent();
|
||||
this.$navigateTo( EditRecipe, {
|
||||
props: {
|
||||
selectedCategory: this.selectedCategory,
|
||||
filterFavorites: this.filterFavorites,
|
||||
},
|
||||
})
|
||||
filterFavourites: this.filterFavourites
|
||||
}
|
||||
} );
|
||||
},
|
||||
viewRecipe(recipeID) {
|
||||
this.showFAB = false
|
||||
this.$navigateTo(ViewRecipe, {
|
||||
viewRecipe( recipeID ) {
|
||||
this.showFAB = false;
|
||||
this.$navigateTo( ViewRecipe, {
|
||||
props: {
|
||||
filterTrylater: this.filterTrylater,
|
||||
recipeID,
|
||||
recipeID
|
||||
},
|
||||
backstackVisible: false,
|
||||
})
|
||||
backstackVisible: false
|
||||
} );
|
||||
},
|
||||
|
||||
// LIST HANDLERS
|
||||
sortDialog() {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.$showModal(ActionDialog, {
|
||||
this.releaseGlobalBackEvent();
|
||||
this.$showModal( ActionDialog, {
|
||||
props: {
|
||||
title: "Sort by",
|
||||
list: ["Natural order", "Title", "Duration", "Last modified"],
|
||||
height: "192",
|
||||
},
|
||||
}).then((action) => {
|
||||
if (action && action !== "Cancel" && this.sortType !== action) {
|
||||
this.sortType = action
|
||||
this.updateSort()
|
||||
list: [ "Natural order", "Title", "Duration", "Last modified" ],
|
||||
height: "192"
|
||||
}
|
||||
this.hijackGlobalBackEvent()
|
||||
})
|
||||
} ).then( action => {
|
||||
if ( action && action !== "Cancel" && this.sortType !== action ) {
|
||||
this.sortType = action;
|
||||
this.updateSort();
|
||||
}
|
||||
this.hijackGlobalBackEvent();
|
||||
} );
|
||||
},
|
||||
updateSort() {
|
||||
let listView = this.$refs.listView.nativeView
|
||||
listView.sortingFunction = undefined
|
||||
listView.sortingFunction = this.sortFunction
|
||||
let listView = this.$refs.listView.nativeView;
|
||||
listView.sortingFunction = undefined;
|
||||
listView.sortingFunction = this.sortFunction;
|
||||
},
|
||||
sortFunction(item, otherItem) {
|
||||
const titleOrder = item.title
|
||||
.toLowerCase()
|
||||
.localeCompare(otherItem.title.toLowerCase(), "en", {
|
||||
ignorePunctuation: true,
|
||||
})
|
||||
let d1 = this.formattedTotalTime(item.prepTime, item.cookTime).duration
|
||||
let d2 = this.formattedTotalTime(otherItem.prepTime, otherItem.cookTime)
|
||||
.duration
|
||||
let ld1 = new Date(item.lastModified)
|
||||
let ld2 = new Date(otherItem.lastModified)
|
||||
switch (this.sortType) {
|
||||
sortFunction( item, otherItem ) {
|
||||
const titleOrder = item.title.toLowerCase().localeCompare( otherItem.title.toLowerCase(), "en", {
|
||||
ignorePunctuation: true
|
||||
} );
|
||||
let d1 = this.formattedTotalTime( item.prepTime, item.cookTime ).duration;
|
||||
let d2 = this.formattedTotalTime( otherItem.prepTime, otherItem.cookTime ).duration;
|
||||
let ld1 = new Date( item.lastModified );
|
||||
let ld2 = new Date( otherItem.lastModified );
|
||||
switch ( this.sortType ) {
|
||||
case "Title":
|
||||
return titleOrder > 0 ? -1 : titleOrder < 0 ? 1 : 0
|
||||
break
|
||||
return titleOrder > 0 ? -1 : titleOrder < 0 ? 1 : 0;
|
||||
break;
|
||||
case "Duration":
|
||||
return d1 > d2 ? -1 : d1 < d2 ? 1 : 0
|
||||
break
|
||||
return d1 > d2 ? -1 : d1 < d2 ? 1 : 0;
|
||||
break;
|
||||
case "Last modified":
|
||||
return ld1 < ld2 ? -1 : ld1 > ld2 ? 1 : 0
|
||||
break
|
||||
return ld1 < ld2 ? -1 : ld1 > ld2 ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
return 0
|
||||
break
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
},
|
||||
updateFilter() {
|
||||
let listView = this.$refs.listView.nativeView
|
||||
setTimeout((e) => {
|
||||
listView.filteringFunction = undefined
|
||||
listView.filteringFunction = this.filterFunction
|
||||
}, 1)
|
||||
let listView = this.$refs.listView.nativeView;
|
||||
setTimeout( e => {
|
||||
listView.filteringFunction = undefined;
|
||||
listView.filteringFunction = this.filterFunction;
|
||||
}, 1 );
|
||||
},
|
||||
filterFunction(item) {
|
||||
if (this.filterFavorites) {
|
||||
return item.isFavorite
|
||||
? item.title.toLowerCase().includes(this.searchQuery)
|
||||
: false
|
||||
} else if (this.filterTrylater) {
|
||||
return item.tried
|
||||
? false
|
||||
: item.title.toLowerCase().includes(this.searchQuery)
|
||||
} else if (this.selectedCategory) {
|
||||
return item.category === this.selectedCategory
|
||||
? item.title.toLowerCase().includes(this.searchQuery)
|
||||
: false
|
||||
} else {
|
||||
return item.title.toLowerCase().includes(this.searchQuery)
|
||||
filterFunction( item ) {
|
||||
if ( this.filterFavourites ) {
|
||||
return item.isFavorite ? item.title.toLowerCase().includes( this.searchQuery ) : false;
|
||||
}
|
||||
else if ( this.filterTrylater ) {
|
||||
return item.tried ? false : item.title.toLowerCase().includes( this.searchQuery );
|
||||
}
|
||||
else if ( this.selectedCategory ) {
|
||||
return item.category === this.selectedCategory ? item.title.toLowerCase().includes( this.searchQuery ) : false;
|
||||
}
|
||||
else {
|
||||
return item.title.toLowerCase().includes( this.searchQuery );
|
||||
}
|
||||
},
|
||||
|
||||
onSwiping({ data, object }) {
|
||||
const swipeLimits = data.swipeLimits
|
||||
const swipeView = object
|
||||
const rightItem = swipeView.getViewById("delete-action")
|
||||
swipeLimits.right = rightItem.getMeasuredWidth() - 12
|
||||
swipeLimits.threshold = swipeLimits.right - 6
|
||||
if (data.x < -swipeLimits.threshold) {
|
||||
this.rightAction = true
|
||||
swipeView.notifySwipeToExecuteFinished()
|
||||
onSwiping( {
|
||||
data,
|
||||
object
|
||||
} ) {
|
||||
const swipeLimits = data.swipeLimits;
|
||||
const swipeView = object;
|
||||
const rightItem = swipeView.getViewById( "delete-action" );
|
||||
swipeLimits.right = rightItem.getMeasuredWidth() - 12;
|
||||
swipeLimits.threshold = swipeLimits.right - 6;
|
||||
if ( data.x < -swipeLimits.threshold ) {
|
||||
this.rightAction = true;
|
||||
swipeView.notifySwipeToExecuteFinished();
|
||||
}
|
||||
},
|
||||
onSwipeEnded({ index }) {
|
||||
let recipeID = this.recipes[index].id
|
||||
if (this.rightAction && !this.deletionDialogActive)
|
||||
this.deleteRecipe(index, recipeID)
|
||||
this.rightAction = false
|
||||
onSwipeEnded( {
|
||||
index
|
||||
} ) {
|
||||
let recipeID = this.recipes[ index ].id;
|
||||
if ( this.rightAction && !this.deletionDialogActive ) this.deleteRecipe( index, recipeID );
|
||||
this.rightAction = false;
|
||||
},
|
||||
|
||||
// DATA HANDLERS
|
||||
deleteRecipe(index, recipeID) {
|
||||
this.deletionDialogActive = true
|
||||
this.$showModal(ConfirmDialog, {
|
||||
deleteRecipe( index, recipeID ) {
|
||||
this.deletionDialogActive = true;
|
||||
this.$showModal( ConfirmDialog, {
|
||||
props: {
|
||||
title: "Delete recipe",
|
||||
description: `Are you sure you want to delete the recipe "${this.recipes[index].title}"?`,
|
||||
title: localize( "Delete recipe?" ),
|
||||
description: `${localize('Are you sure you want to delete the recipe')} "${this.recipes[index].title}"?`,
|
||||
cancelButtonText: "CANCEL",
|
||||
okButtonText: "DELETE",
|
||||
},
|
||||
}).then((action) => {
|
||||
if (action) {
|
||||
this.deleteRecipeAction({ index, id: recipeID })
|
||||
okButtonText: "DELETE"
|
||||
}
|
||||
this.deletionDialogActive = false
|
||||
})
|
||||
},
|
||||
} ).then( action => {
|
||||
if ( action ) {
|
||||
this.deleteRecipeAction( {
|
||||
index,
|
||||
id: recipeID
|
||||
} );
|
||||
}
|
||||
this.deletionDialogActive = false;
|
||||
} );
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.showFAB = true
|
||||
},
|
||||
}
|
||||
this.showFAB = true;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,90 +1,43 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar flat="true">
|
||||
<GridLayout rows="*" columns="auto, *, auto">
|
||||
<MDButton
|
||||
class="bx left"
|
||||
variant="text"
|
||||
:text="icon.menu"
|
||||
automationText="Back"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" text="Meal Planner" col="1" />
|
||||
<MDButton
|
||||
class="bx left"
|
||||
variant="text"
|
||||
:text="icon.today"
|
||||
automationText="today"
|
||||
@tap="goToToday"
|
||||
col="2"
|
||||
/>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<GridLayout rows="280, *">
|
||||
<RadCalendar
|
||||
:androidElevation="viewIsScrolled ? 4 : 0"
|
||||
class="orkm"
|
||||
row="0"
|
||||
ref="calendar"
|
||||
locale="en-US"
|
||||
@loaded="onCalendarLoad"
|
||||
@dateSelected="onDateSelected"
|
||||
:viewMode="viewMode"
|
||||
:transitionMode="transitionMode"
|
||||
:selectionMode="selectionMode"
|
||||
:eventsViewMode="eventsViewMode"
|
||||
:eventSource="getMealPlans"
|
||||
></RadCalendar>
|
||||
<ScrollView row="1" width="100%" height="100%" @scroll="onScroll">
|
||||
<StackLayout class="dayPlan">
|
||||
<StackLayout
|
||||
v-for="(mealType, index) in mealTimes"
|
||||
:key="'mealType' + index"
|
||||
class="plansContainer"
|
||||
:class="mealType"
|
||||
>
|
||||
<GridLayout columns="*, auto" class="header">
|
||||
<Label col="0" class="periodLabel orkm" :text="mealType" />
|
||||
<MDButton
|
||||
col="1"
|
||||
variant="text"
|
||||
class="bx addMeal"
|
||||
:text="icon.plus"
|
||||
@tap="addRecipe(mealType)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
class="recipes"
|
||||
columns="*, auto"
|
||||
v-for="(recipeID, index) in getRecipes[mealType]"
|
||||
:key="mealType + index"
|
||||
>
|
||||
<MDRipple @tap="viewRecipe(recipeID)" />
|
||||
<Label
|
||||
verticalAlignment="center"
|
||||
class="recipeTitle"
|
||||
col="0"
|
||||
:text="getRecipeTitle(recipeID)"
|
||||
textWrap="true"
|
||||
/>
|
||||
<MDButton
|
||||
variant="text"
|
||||
col="1"
|
||||
class="bx closeBtn"
|
||||
:text="icon.close"
|
||||
@tap="removeRecipe(mealType, recipeID)"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar flat="true">
|
||||
<GridLayout rows="*" columns="auto, *, auto">
|
||||
<MDButton class="bx left" variant="text" :text="icon.menu" automationText="Back" @tap="showDrawer" col="0" />
|
||||
<Label class="title orkm" :text="'Meal Planner' | L" col="1" />
|
||||
<MDButton class="bx left" variant="text" :text="icon.today" automationText="today" @tap="goToToday" col="2" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</ActionBar>
|
||||
<GridLayout rows="280, *">
|
||||
<RadCalendar :androidElevation="viewIsScrolled ? 4 : 0" class="orkm" row="0" ref="calendar" @loaded="onCalendarLoad" @dateSelected="onDateSelected" :viewMode="viewMode" :transitionMode="transitionMode" :selectionMode="selectionMode"
|
||||
:eventsViewMode="eventsViewMode" :eventSource="getMealPlans"></RadCalendar>
|
||||
<ScrollView row="1" width="100%" height="100%" @scroll="onScroll">
|
||||
<StackLayout class="dayPlan">
|
||||
<StackLayout v-for="(mealType, index) in mealTimes" :key="'mealType' + index" class="plansContainer" :class="mealType">
|
||||
<GridLayout columns="*, auto" class="header">
|
||||
<Label col="0" class="periodLabel orkm" :text="mealType | L" />
|
||||
<MDButton col="1" variant="text" class="bx addMeal" :text="icon.plus" @tap="addRecipe(mealType)" />
|
||||
</GridLayout>
|
||||
<GridLayout class="recipes" columns="*, auto" v-for="(recipeID, index) in getRecipes[mealType]" :key="mealType + index">
|
||||
<MDRipple @tap="viewRecipe(recipeID)" />
|
||||
<Label verticalAlignment="center" class="recipeTitle" col="0" :text="getRecipeTitle(recipeID)" textWrap="true" />
|
||||
<MDButton variant="text" col="1" class="bx closeBtn" :text="icon.close" @tap="removeRecipe(mealType, recipeID)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ApplicationSettings, Color, Page } from "@nativescript/core"
|
||||
import {
|
||||
ApplicationSettings,
|
||||
Color,
|
||||
Page,
|
||||
Observable,
|
||||
Device
|
||||
}
|
||||
from "@nativescript/core"
|
||||
import {
|
||||
CalendarViewMode,
|
||||
CalendarTransitionMode,
|
||||
|
@ -96,9 +49,14 @@ import {
|
|||
CalendarCellAlignment,
|
||||
CellStyle,
|
||||
CalendarEventsViewMode,
|
||||
CalendarEvent,
|
||||
} from "nativescript-ui-calendar"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
CalendarEvent
|
||||
}
|
||||
from "nativescript-ui-calendar"
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
}
|
||||
from "vuex"
|
||||
|
||||
import ViewRecipe from "./ViewRecipe.vue"
|
||||
|
||||
|
@ -112,7 +70,7 @@ export default {
|
|||
return {
|
||||
viewIsScrolled: false,
|
||||
appTheme: "Light",
|
||||
mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
|
||||
mealTimes: [ "breakfast", "lunch", "dinner", "snacks" ],
|
||||
eventList: [],
|
||||
selectedDayMealPlans: [],
|
||||
viewMode: CalendarViewMode.Month,
|
||||
|
@ -120,18 +78,18 @@ export default {
|
|||
selectionMode: CalendarSelectionMode.Single,
|
||||
eventsViewMode: CalendarEventsViewMode.None,
|
||||
color: {
|
||||
white: new Color("#ffffff"),
|
||||
gray1: new Color("#f1f3f5"),
|
||||
gray2: new Color("#e9ecef"),
|
||||
gray3: new Color("#dee2e6"),
|
||||
gray4: new Color("#ced4da"),
|
||||
gray5: new Color("#adb5bd"),
|
||||
gray6: new Color("#868e96"),
|
||||
gray7: new Color("#495057"),
|
||||
gray8: new Color("#343a40"),
|
||||
gray9: new Color("#212529"),
|
||||
black: new Color("#111111"),
|
||||
orange: new Color("#ff5200"),
|
||||
white: new Color( "#ffffff" ),
|
||||
gray1: new Color( "#f1f3f5" ),
|
||||
gray2: new Color( "#e9ecef" ),
|
||||
gray3: new Color( "#dee2e6" ),
|
||||
gray4: new Color( "#ced4da" ),
|
||||
gray5: new Color( "#adb5bd" ),
|
||||
gray6: new Color( "#868e96" ),
|
||||
gray7: new Color( "#495057" ),
|
||||
gray8: new Color( "#343a40" ),
|
||||
gray9: new Color( "#212529" ),
|
||||
black: new Color( "#111111" ),
|
||||
orange: new Color( "#ff5200" ),
|
||||
breakfast: "#ffb180",
|
||||
lunch: "#ceff80",
|
||||
dinner: "#80ceff",
|
||||
|
@ -143,45 +101,45 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "recipes", "mealPlans"]),
|
||||
...mapState( [ "icon", "recipes", "mealPlans" ] ),
|
||||
isLightMode() {
|
||||
return this.appTheme === "Light"
|
||||
},
|
||||
monthViewStyle() {
|
||||
const monthViewStyle = new CalendarMonthViewStyle()
|
||||
monthViewStyle.backgroundColor = this.isLightMode
|
||||
? this.color.gray1
|
||||
: this.color.gray9
|
||||
monthViewStyle.backgroundColor = this.isLightMode ?
|
||||
this.color.gray1 :
|
||||
this.color.gray9
|
||||
monthViewStyle.showTitle = true
|
||||
monthViewStyle.showWeekNumbers = false
|
||||
monthViewStyle.showDayNames = true
|
||||
|
||||
const titleCellStyle = new DayCellStyle()
|
||||
titleCellStyle.cellBackgroundColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
titleCellStyle.cellBackgroundColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
titleCellStyle.cellBorderWidth = 1
|
||||
titleCellStyle.cellBorderColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
titleCellStyle.cellBorderColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
titleCellStyle.cellTextSize = 16
|
||||
titleCellStyle.cellTextColor = this.isLightMode
|
||||
? this.color.gray9
|
||||
: this.color.gray1
|
||||
titleCellStyle.cellTextColor = this.isLightMode ?
|
||||
this.color.gray9 :
|
||||
this.color.gray1
|
||||
titleCellStyle.cellTextFontName = this.appFontMedium
|
||||
monthViewStyle.titleCellStyle = titleCellStyle
|
||||
|
||||
const dayNameCellStyle = new CellStyle()
|
||||
dayNameCellStyle.cellBackgroundColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
dayNameCellStyle.cellTextColor = this.isLightMode
|
||||
? this.color.gray9
|
||||
: this.color.gray1
|
||||
dayNameCellStyle.cellBackgroundColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
dayNameCellStyle.cellTextColor = this.isLightMode ?
|
||||
this.color.gray9 :
|
||||
this.color.gray1
|
||||
dayNameCellStyle.cellBorderWidth = 1
|
||||
dayNameCellStyle.cellBorderColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
dayNameCellStyle.cellBorderColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
dayNameCellStyle.cellTextSize = 10
|
||||
dayNameCellStyle.cellAlignment = CalendarCellAlignment.Center
|
||||
dayNameCellStyle.cellTextFontName = this.appFontMedium
|
||||
|
@ -194,46 +152,46 @@ export default {
|
|||
dayCellStyle.eventFontStyle = CalendarFontStyle.Bold
|
||||
dayCellStyle.eventTextSize = 8
|
||||
dayCellStyle.cellTextSize = 16
|
||||
dayCellStyle.cellTextColor = this.isLightMode
|
||||
? this.color.gray9
|
||||
: this.color.gray1
|
||||
dayCellStyle.cellTextColor = this.isLightMode ?
|
||||
this.color.gray9 :
|
||||
this.color.gray1
|
||||
dayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
|
||||
dayCellStyle.cellBackgroundColor = this.isLightMode
|
||||
? this.color.gray1
|
||||
: this.color.gray9
|
||||
dayCellStyle.cellBackgroundColor = this.isLightMode ?
|
||||
this.color.gray1 :
|
||||
this.color.gray9
|
||||
dayCellStyle.cellTextFontName = this.appFontRegular
|
||||
dayCellStyle.cellBorderWidth = 1
|
||||
dayCellStyle.cellBorderColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
dayCellStyle.cellBorderColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
monthViewStyle.dayCellStyle = dayCellStyle
|
||||
|
||||
const todayCellStyle = new DayCellStyle()
|
||||
todayCellStyle.cellBackgroundColor = this.isLightMode
|
||||
? this.color.gray1
|
||||
: this.color.gray9
|
||||
todayCellStyle.cellBackgroundColor = this.isLightMode ?
|
||||
this.color.gray1 :
|
||||
this.color.gray9
|
||||
todayCellStyle.cellTextColor = this.color.orange
|
||||
todayCellStyle.cellBorderWidth = 1
|
||||
todayCellStyle.cellTextFontName = this.appFontMedium
|
||||
todayCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
|
||||
todayCellStyle.cellTextSize = 16
|
||||
todayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
|
||||
todayCellStyle.cellBorderColor = this.isLightMode
|
||||
? this.color.gray2
|
||||
: this.color.black
|
||||
todayCellStyle.cellBorderColor = this.isLightMode ?
|
||||
this.color.gray2 :
|
||||
this.color.black
|
||||
monthViewStyle.todayCellStyle = todayCellStyle
|
||||
|
||||
const selectedCellStyle = new DayCellStyle()
|
||||
selectedCellStyle.eventTextSize = 1
|
||||
selectedCellStyle.cellAlignment = CalendarCellAlignment.Bottom
|
||||
selectedCellStyle.cellBackgroundColor = this.isLightMode
|
||||
? this.color.white
|
||||
: this.color.gray8
|
||||
selectedCellStyle.cellBackgroundColor = this.isLightMode ?
|
||||
this.color.white :
|
||||
this.color.gray8
|
||||
selectedCellStyle.cellBorderWidth = 1
|
||||
selectedCellStyle.cellBorderColor = this.color.orange
|
||||
selectedCellStyle.cellTextColor = this.isLightMode
|
||||
? this.color.gray9
|
||||
: this.color.gray1
|
||||
selectedCellStyle.cellTextColor = this.isLightMode ?
|
||||
this.color.gray9 :
|
||||
this.color.gray1
|
||||
selectedCellStyle.cellTextFontName = this.appFontMedium
|
||||
selectedCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
|
||||
selectedCellStyle.cellTextSize = 16
|
||||
|
@ -242,31 +200,32 @@ export default {
|
|||
return monthViewStyle
|
||||
},
|
||||
getRecipes() {
|
||||
if (this.selectedDayMealPlans.length) {
|
||||
return this.selectedDayMealPlans.reduce((acc, e) => {
|
||||
switch (e.startDate.getHours()) {
|
||||
if ( this.selectedDayMealPlans.length ) {
|
||||
return this.selectedDayMealPlans.reduce( ( acc, e ) => {
|
||||
switch ( e.startDate.getHours() ) {
|
||||
case 0: //breakfast
|
||||
acc["breakfast"] = [...(acc["breakfast"] || []), e.title]
|
||||
acc[ "breakfast" ] = [ ...( acc[ "breakfast" ] || [] ), e.title ]
|
||||
break
|
||||
case 5: //lunch
|
||||
acc["lunch"] = [...(acc["lunch"] || []), e.title]
|
||||
acc[ "lunch" ] = [ ...( acc[ "lunch" ] || [] ), e.title ]
|
||||
break
|
||||
case 10: //dinner
|
||||
acc["dinner"] = [...(acc["dinner"] || []), e.title]
|
||||
acc[ "dinner" ] = [ ...( acc[ "dinner" ] || [] ), e.title ]
|
||||
break
|
||||
case 15: //snacks
|
||||
acc["snacks"] = [...(acc["snacks"] || []), e.title]
|
||||
acc[ "snacks" ] = [ ...( acc[ "snacks" ] || [] ), e.title ]
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
} else return 0
|
||||
}, {} )
|
||||
}
|
||||
else return 0
|
||||
},
|
||||
getMealPlans() {
|
||||
const getDate = (date) => {
|
||||
let d = new Date(date)
|
||||
const getDate = ( date ) => {
|
||||
let d = new Date( date )
|
||||
let result = new Date(
|
||||
d.getFullYear(),
|
||||
d.getMonth(),
|
||||
|
@ -276,40 +235,43 @@ export default {
|
|||
return result
|
||||
}
|
||||
let events = []
|
||||
this.mealPlans.forEach((plan) => {
|
||||
this.mealPlans.forEach( ( plan ) => {
|
||||
let e = new CalendarEvent(
|
||||
plan.title,
|
||||
getDate(plan.startDate),
|
||||
getDate(plan.endDate),
|
||||
getDate( plan.startDate ),
|
||||
getDate( plan.endDate ),
|
||||
false,
|
||||
new Color(plan.eventColor)
|
||||
new Color( plan.eventColor )
|
||||
)
|
||||
events = [...events, e]
|
||||
})
|
||||
events = [ ...events, e ]
|
||||
} )
|
||||
return events
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
...mapActions( [
|
||||
"setCurrentComponentAction",
|
||||
"initializeMealPlans",
|
||||
"addMealPlanAction",
|
||||
"deleteMealPlanAction",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
this.setCurrentComponentAction("MealPlanner")
|
||||
] ),
|
||||
onPageLoad( args ) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
this.setCurrentComponentAction( "MealPlanner" )
|
||||
},
|
||||
onCalendarLoad(args) {
|
||||
onCalendarLoad( args ) {
|
||||
args.object.locale = `${Device.language}-${Device.language.toUpperCase()}`
|
||||
args.object.monthViewStyle = this.monthViewStyle
|
||||
args.object.android
|
||||
.getGestureManager()
|
||||
.setDoubleTapToChangeDisplayMode(false)
|
||||
.setDoubleTapToChangeDisplayMode( false )
|
||||
args.object.android
|
||||
.getGestureManager()
|
||||
.setPinchCloseToChangeDisplayMode(false)
|
||||
if (args.object.selectedDate == null)
|
||||
.setPinchCloseToChangeDisplayMode( false )
|
||||
if ( args.object.selectedDate == null )
|
||||
args.object.selectedDate = new Date()
|
||||
if (args.object.nativeView.getEventAdapter()) {
|
||||
if ( args.object.nativeView.getEventAdapter() ) {
|
||||
args.object.nativeView
|
||||
.getEventAdapter()
|
||||
.getRenderer()
|
||||
|
@ -323,102 +285,102 @@ export default {
|
|||
showDrawer() {
|
||||
utils.showDrawer()
|
||||
},
|
||||
onScroll(args) {
|
||||
onScroll( args ) {
|
||||
this.viewIsScrolled = args.scrollY ? true : false
|
||||
},
|
||||
getDate(index) {
|
||||
getDate( index ) {
|
||||
let date = new Date()
|
||||
date.setDate(date.getDate() + index)
|
||||
date.setDate( date.getDate() + index )
|
||||
return date.getTime()
|
||||
},
|
||||
getDateString(days) {
|
||||
getDateString( days ) {
|
||||
let date = new Date()
|
||||
date.setDate(date.getDate() + days)
|
||||
return date.toDateString().slice(0, -5)
|
||||
date.setDate( date.getDate() + days )
|
||||
return date.toDateString().slice( 0, -5 )
|
||||
},
|
||||
getRecipeTitle(id) {
|
||||
let recipe = this.recipes.filter((e) => e.id === id)[0]
|
||||
getRecipeTitle( id ) {
|
||||
let recipe = this.recipes.filter( ( e ) => e.id === id )[ 0 ]
|
||||
return recipe ? recipe.title : "[Deleted Recipe]"
|
||||
},
|
||||
|
||||
// NAVIGATION HANDLERS
|
||||
viewRecipe(recipeID) {
|
||||
let recipe = this.recipes.filter((e) => e.id === recipeID)[0]
|
||||
if (recipe) {
|
||||
this.$navigateTo(ViewRecipe, {
|
||||
viewRecipe( recipeID ) {
|
||||
let recipe = this.recipes.filter( ( e ) => e.id === recipeID )[ 0 ]
|
||||
if ( recipe ) {
|
||||
this.$navigateTo( ViewRecipe, {
|
||||
props: {
|
||||
filterTrylater: true,
|
||||
recipeID,
|
||||
},
|
||||
backstackVisible: false,
|
||||
})
|
||||
} )
|
||||
}
|
||||
},
|
||||
|
||||
// DATA HANDLERS
|
||||
addRecipe(mealType) {
|
||||
let filteredRecipes = this.recipes.filter((e) =>
|
||||
this.getRecipes[mealType]
|
||||
? !this.getRecipes[mealType].includes(e.id)
|
||||
: true
|
||||
addRecipe( mealType ) {
|
||||
let filteredRecipes = this.recipes.filter( ( e ) =>
|
||||
this.getRecipes[ mealType ] ?
|
||||
!this.getRecipes[ mealType ].includes( e.id ) :
|
||||
true
|
||||
)
|
||||
this.$showModal(ActionDialogWithSearch, {
|
||||
this.$showModal( ActionDialogWithSearch, {
|
||||
props: {
|
||||
title: "Select a recipe",
|
||||
recipes: filteredRecipes,
|
||||
},
|
||||
}).then((recipeID) => {
|
||||
recipeID && this.newEvent(recipeID, mealType)
|
||||
})
|
||||
} ).then( ( recipeID ) => {
|
||||
recipeID && this.newEvent( recipeID, mealType )
|
||||
} )
|
||||
},
|
||||
removeRecipeConfirm(mealType) {
|
||||
return this.$showModal(ConfirmDialog, {
|
||||
removeRecipeConfirm( mealType ) {
|
||||
return this.$showModal( ConfirmDialog, {
|
||||
props: {
|
||||
title: `Remove recipe from ${mealType}`,
|
||||
cancelButtonText: "CANCEL",
|
||||
okButtonText: "REMOVE",
|
||||
},
|
||||
})
|
||||
} )
|
||||
},
|
||||
removeRecipe(mealType, recipeID) {
|
||||
removeRecipe( mealType, recipeID ) {
|
||||
let startHour = {
|
||||
breakfast: 0,
|
||||
lunch: 5,
|
||||
dinner: 10,
|
||||
snacks: 15,
|
||||
}
|
||||
this.removeRecipeConfirm(mealType).then((res) => {
|
||||
if (res) {
|
||||
this.removeRecipeConfirm( mealType ).then( ( res ) => {
|
||||
if ( res ) {
|
||||
let actualMealPlan = this.selectedDayMealPlans.filter(
|
||||
(e) =>
|
||||
e.startDate.getHours() === startHour[mealType] &&
|
||||
e.title === recipeID
|
||||
)[0]
|
||||
( e ) =>
|
||||
e.startDate.getHours() === startHour[ mealType ] &&
|
||||
e.title === recipeID
|
||||
)[ 0 ]
|
||||
let mealPlan = {
|
||||
title: actualMealPlan.title,
|
||||
startDate: actualMealPlan.startDate,
|
||||
}
|
||||
this.deleteMealPlanAction(mealPlan)
|
||||
this.deleteMealPlanAction( mealPlan )
|
||||
this.updateSelectedDatePlans()
|
||||
}
|
||||
})
|
||||
} )
|
||||
},
|
||||
|
||||
// CALENDAR
|
||||
updateSelectedDatePlans() {
|
||||
let date = new Date(this.selectedDate)
|
||||
setTimeout(() => {
|
||||
let date = new Date( this.selectedDate )
|
||||
setTimeout( () => {
|
||||
this.selectedDayMealPlans = this.$refs.calendar.nativeView.getEventsForDate(
|
||||
date
|
||||
)
|
||||
}, 100)
|
||||
}, 100 )
|
||||
},
|
||||
onDateSelected(args) {
|
||||
onDateSelected( args ) {
|
||||
this.selectedDate = args.date
|
||||
this.selectedDayMealPlans = args.object.getEventsForDate(args.date)
|
||||
this.selectedDayMealPlans = args.object.getEventsForDate( args.date )
|
||||
},
|
||||
newEvent(recipeID, mealType) {
|
||||
let date = new Date(this.selectedDate)
|
||||
newEvent( recipeID, mealType ) {
|
||||
let date = new Date( this.selectedDate )
|
||||
const selectedDate = () => {
|
||||
return {
|
||||
y: date.getFullYear(),
|
||||
|
@ -426,45 +388,52 @@ export default {
|
|||
d: date.getDate(),
|
||||
}
|
||||
}
|
||||
let { y, m, d } = selectedDate()
|
||||
let {
|
||||
y,
|
||||
m,
|
||||
d
|
||||
} = selectedDate()
|
||||
let mealTime = {
|
||||
breakfast: {
|
||||
start: new Date(y, m, d, 0),
|
||||
end: new Date(y, m, d, 4),
|
||||
start: new Date( y, m, d, 0 ),
|
||||
end: new Date( y, m, d, 4 ),
|
||||
},
|
||||
lunch: {
|
||||
start: new Date(y, m, d, 5),
|
||||
end: new Date(y, m, d, 9),
|
||||
start: new Date( y, m, d, 5 ),
|
||||
end: new Date( y, m, d, 9 ),
|
||||
},
|
||||
dinner: {
|
||||
start: new Date(y, m, d, 10),
|
||||
end: new Date(y, m, d, 14),
|
||||
start: new Date( y, m, d, 10 ),
|
||||
end: new Date( y, m, d, 14 ),
|
||||
},
|
||||
snacks: {
|
||||
start: new Date(y, m, d, 15),
|
||||
end: new Date(y, m, d, 19),
|
||||
start: new Date( y, m, d, 15 ),
|
||||
end: new Date( y, m, d, 19 ),
|
||||
},
|
||||
}
|
||||
let event = new CalendarEvent(
|
||||
recipeID,
|
||||
mealTime[mealType].start,
|
||||
mealTime[mealType].end,
|
||||
mealTime[ mealType ].start,
|
||||
mealTime[ mealType ].end,
|
||||
false,
|
||||
new Color(this.color[mealType])
|
||||
new Color( this.color[ mealType ] )
|
||||
)
|
||||
this.addMealPlanAction({ event, eventColor: this.color[mealType] })
|
||||
this.addMealPlanAction( {
|
||||
event,
|
||||
eventColor: this.color[ mealType ]
|
||||
} )
|
||||
this.updateSelectedDatePlans()
|
||||
},
|
||||
goToToday() {
|
||||
const date = new Date()
|
||||
this.$refs.calendar.goToDate(date)
|
||||
this.$refs.calendar.goToDate( date )
|
||||
this.$refs.calendar.nativeView.selectedDate = date
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.appTheme = ApplicationSettings.getString("appTheme", "Light")
|
||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
||||
let d = new Date()
|
||||
d.setHours(0, 0, 0)
|
||||
d.setHours( 0, 0, 0 )
|
||||
this.selectedDate = d
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,73 +1,55 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<GridLayout rows="*" columns="auto, *">
|
||||
<MDButton
|
||||
class="bx left"
|
||||
variant="text"
|
||||
:text="icon.menu"
|
||||
automationText="Back"
|
||||
@tap="showDrawer"
|
||||
col="0"
|
||||
/>
|
||||
<Label class="title orkm" text="Settings" col="1" />
|
||||
<Page @loaded="onPageLoad">
|
||||
<ActionBar :androidElevation="viewIsScrolled ? 4 : 0">
|
||||
<GridLayout rows="*" columns="auto, *">
|
||||
<MDButton class="bx left" variant="text" :text="icon.menu" automationText="Back" @tap="showDrawer" col="0" />
|
||||
<Label class="title orkm" :text="'Settings' | L" col="1" />
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView @scroll="onScroll">
|
||||
<StackLayout class="main-container">
|
||||
<Label :text="'Interface' | L" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="selectAppLanguage" />
|
||||
<Label col="0" verticalAlignment="center" class="bx" :text="icon.globe" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'App language' | L" />
|
||||
<Label :text="appLanguage" class="info" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</ActionBar>
|
||||
<ScrollView @scroll="onScroll">
|
||||
<StackLayout class="main-container">
|
||||
<Label text="Interface" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="selectThemes" />
|
||||
<Label
|
||||
col="0"
|
||||
verticalAlignment="center"
|
||||
class="bx"
|
||||
:text="icon.theme"
|
||||
/>
|
||||
<StackLayout col="1">
|
||||
<Label text="Theme" />
|
||||
<Label :text="appTheme" class="info" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
<Label text="Database" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<!-- <MDRipple colSpan="2" @tap="folderPicker" /> -->
|
||||
<MDRipple colSpan="2" @tap="exportCheck" />
|
||||
<Label col="0" class="bx" :text="icon.export" />
|
||||
<StackLayout col="1">
|
||||
<Label text="Export a full backup" />
|
||||
<Label
|
||||
v-if="!backupInProgress"
|
||||
text="Generates a zip file that contains all your data. This file can be imported back."
|
||||
class="info"
|
||||
textWrap="true"
|
||||
/>
|
||||
<GridLayout class="progressContainer" v-else columns="*, 64">
|
||||
<MDProgress
|
||||
col="0"
|
||||
:value="backupProgress"
|
||||
maxValue="100"
|
||||
></MDProgress>
|
||||
<Label col="1" :text="` ${backupProgress}%`" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option"
|
||||
><MDRipple colSpan="2" @tap="importCheck" />
|
||||
<Label col="0" class="bx" :text="icon.import" />
|
||||
<StackLayout col="1">
|
||||
<Label text="Import from backup" />
|
||||
<Label
|
||||
text="Supports full backups exported by this app"
|
||||
class="info"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="selectThemes" />
|
||||
<Label col="0" verticalAlignment="center" class="bx" :text="icon.theme" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'Theme' | L" />
|
||||
<Label :text="`${appTheme}` | L" class="info" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
<Label :text="'Database' | L" class="group-header orkm" />
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="exportCheck" />
|
||||
<Label col="0" class="bx" :text="icon.export" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'Export a full backup' | L" textWrap="true" />
|
||||
<Label v-if="!backupInProgress" :text="'Generates a zip file that contains all your data. This file can be imported back.' | 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}%`" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
<GridLayout columns="auto, *" class="option">
|
||||
<MDRipple colSpan="2" @tap="importCheck" />
|
||||
<Label col="0" class="bx" :text="icon.import" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="'Import from backup' | L" textWrap="true" />
|
||||
<Label :text="'Supports full backups exported by this app' | L" class="info" textWrap="true" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -77,13 +59,28 @@ import {
|
|||
knownFolders,
|
||||
File,
|
||||
Folder,
|
||||
} from "@nativescript/core"
|
||||
Observable,
|
||||
Device
|
||||
}
|
||||
from "@nativescript/core"
|
||||
import * as Permissions from "@nativescript-community/perms"
|
||||
import { Zip } from "@nativescript/zip"
|
||||
import {
|
||||
Zip
|
||||
}
|
||||
from "@nativescript/zip"
|
||||
import * as Toast from "nativescript-toast"
|
||||
import * as Filepicker from "nativescript-plugin-filepicker"
|
||||
import Theme from "@nativescript/theme"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
import {
|
||||
localize,
|
||||
overrideLocale
|
||||
}
|
||||
from "@nativescript/localize"
|
||||
import {
|
||||
mapState,
|
||||
mapActions
|
||||
}
|
||||
from "vuex"
|
||||
|
||||
import ActionDialog from "./modal/ActionDialog.vue"
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||
|
@ -95,145 +92,182 @@ export default {
|
|||
return {
|
||||
viewIsScrolled: false,
|
||||
appTheme: "Light",
|
||||
appLanguage: "English",
|
||||
backupProgress: 0,
|
||||
backupInProgress: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
...mapState( [
|
||||
"icon",
|
||||
"recipes",
|
||||
"userCategories",
|
||||
"userYieldUnits",
|
||||
"mealPlans",
|
||||
"currentComponent",
|
||||
]),
|
||||
"language",
|
||||
] ),
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
...mapActions( [
|
||||
"setCurrentComponentAction",
|
||||
"importCategoriesAction",
|
||||
"importYieldUnitsAction",
|
||||
"importRecipesAction",
|
||||
"importMealPlansAction",
|
||||
]),
|
||||
onPageLoad() {
|
||||
this.setCurrentComponentAction("Settings")
|
||||
] ),
|
||||
onPageLoad( args ) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
this.setCurrentComponentAction( "Settings" )
|
||||
},
|
||||
// HELPERS
|
||||
showDrawer() {
|
||||
utils.showDrawer()
|
||||
},
|
||||
onScroll(args) {
|
||||
onScroll( args ) {
|
||||
this.viewIsScrolled = args.scrollY ? true : false
|
||||
},
|
||||
|
||||
// LANGUAGE SELECTION
|
||||
selectAppLanguage() {
|
||||
let languages = this.language.map( e => e.title )
|
||||
this.$showModal( ActionDialog, {
|
||||
props: {
|
||||
title: "App language",
|
||||
list: [ ...languages ],
|
||||
},
|
||||
} ).then( ( action ) => {
|
||||
if ( action && action !== "Cancel" && this.appLanguage !== action ) {
|
||||
let currentLocale = Device.language.split( '-' )[ 0 ]
|
||||
let locale = this.language.filter( e => e.title === action )[ 0 ].locale
|
||||
if ( currentLocale !== locale ) {
|
||||
this.$showModal( ConfirmDialog, {
|
||||
props: {
|
||||
title: "Restart required",
|
||||
description: localize( "EnRecipes needs to be restarted for the app language to take effect." ),
|
||||
cancelButtonText: "CANCEL",
|
||||
okButtonText: "RESTART",
|
||||
},
|
||||
} ).then( ( result ) => {
|
||||
if ( result ) {
|
||||
this.appLanguage = action
|
||||
ApplicationSettings.setString( "appLanguage", action )
|
||||
|
||||
overrideLocale( locale )
|
||||
setTimeout( ( e ) => utils.restartApp(), 250 )
|
||||
}
|
||||
} )
|
||||
}
|
||||
}
|
||||
} )
|
||||
},
|
||||
// THEME SELECTION
|
||||
selectThemes() {
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal( ActionDialog, {
|
||||
props: {
|
||||
title: "Theme",
|
||||
list: ["Light", "Dark"],
|
||||
list: [ "Light", "Dark" ],
|
||||
height: "96",
|
||||
},
|
||||
}).then((action) => {
|
||||
if (action && action !== "Cancel" && this.appTheme !== action) {
|
||||
this.$showModal(ConfirmDialog, {
|
||||
} ).then( ( action ) => {
|
||||
if ( action && action !== "Cancel" && this.appTheme !== action ) {
|
||||
this.$showModal( ConfirmDialog, {
|
||||
props: {
|
||||
title: "Reload required",
|
||||
description:
|
||||
"EnRecipes needs to be reloaded for the theme change to take effect.",
|
||||
title: "Restart required",
|
||||
description: localize( "EnRecipes needs to be restarted for the theme change to take effect." ),
|
||||
cancelButtonText: "CANCEL",
|
||||
okButtonText: "RELOAD",
|
||||
okButtonText: "RESTART",
|
||||
},
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
} ).then( ( result ) => {
|
||||
if ( result ) {
|
||||
this.appTheme = action
|
||||
ApplicationSettings.setString("appTheme", action)
|
||||
setTimeout((e) => utils.restartApp(), 250)
|
||||
ApplicationSettings.setString( "appTheme", action )
|
||||
setTimeout( ( e ) => utils.restartApp(), 250 )
|
||||
}
|
||||
})
|
||||
} )
|
||||
}
|
||||
})
|
||||
} )
|
||||
},
|
||||
|
||||
// EXPORT HANDLERS
|
||||
exportCheck() {
|
||||
if (!this.recipes.length) {
|
||||
if ( !this.recipes.length ) {
|
||||
Toast.makeText(
|
||||
"Add at least one recipe to perform a backup",
|
||||
localize( "Add at least one recipe to perform a backup" ),
|
||||
"long"
|
||||
).show()
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.permissionCheck(
|
||||
this.permissionConfirmation,
|
||||
"EnRecipes requires storage permission in order to backup your data to this device.",
|
||||
localize( "EnRecipes requires storage permission in order to backup your data to this device." ),
|
||||
this.exportBackup
|
||||
)
|
||||
}
|
||||
},
|
||||
exportBackup() {
|
||||
this.exportFiles("create")
|
||||
this.exportFiles( "create" )
|
||||
let date = new Date()
|
||||
let formattedDate =
|
||||
date.getFullYear() +
|
||||
"-" +
|
||||
("0" + (date.getMonth() + 1)).slice(-2) +
|
||||
( "0" + ( date.getMonth() + 1 ) ).slice( -2 ) +
|
||||
"-" +
|
||||
("0" + date.getDate()).slice(-2) +
|
||||
( "0" + date.getDate() ).slice( -2 ) +
|
||||
"_" +
|
||||
("0" + date.getHours()).slice(-2) +
|
||||
("0" + date.getMinutes()).slice(-2) +
|
||||
("0" + date.getSeconds()).slice(-2)
|
||||
( "0" + date.getHours() ).slice( -2 ) +
|
||||
( "0" + date.getMinutes() ).slice( -2 ) +
|
||||
( "0" + date.getSeconds() ).slice( -2 )
|
||||
const sdDownloadPath = Folder.fromPath(
|
||||
android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
|
||||
).getFolder("Download").path
|
||||
let fromPath = path.join(knownFolders.documents().path, "EnRecipes")
|
||||
).getFolder( "Download" ).path
|
||||
let fromPath = path.join( knownFolders.documents().path, "EnRecipes" )
|
||||
let destPath = path.join(
|
||||
sdDownloadPath,
|
||||
`EnRecipes-Backup_${formattedDate}.zip`
|
||||
)
|
||||
this.backupInProgress = true
|
||||
Zip.zip({
|
||||
Zip.zip( {
|
||||
directory: fromPath,
|
||||
archive: destPath,
|
||||
onProgress: (progress) => {
|
||||
onProgress: ( progress ) => {
|
||||
this.backupProgress = progress
|
||||
},
|
||||
}).then((success) => {
|
||||
} ).then( ( success ) => {
|
||||
Toast.makeText(
|
||||
"Backup file successfully saved to Download folder",
|
||||
"long"
|
||||
).show()
|
||||
this.exportFiles("delete")
|
||||
})
|
||||
this.exportFiles( "delete" )
|
||||
} )
|
||||
},
|
||||
exportFiles(option) {
|
||||
const folder = path.join(knownFolders.documents().path, "EnRecipes")
|
||||
const EnRecipesFile = File.fromPath(path.join(folder, "recipes.json"))
|
||||
exportFiles( option ) {
|
||||
const folder = path.join( knownFolders.documents().path, "EnRecipes" )
|
||||
const EnRecipesFile = File.fromPath( path.join( folder, "recipes.json" ) )
|
||||
let userCategoriesFile, userYieldUnitsFile, mealPlansFile
|
||||
if (this.userCategories.length) {
|
||||
if ( this.userCategories.length ) {
|
||||
userCategoriesFile = File.fromPath(
|
||||
path.join(folder, "userCategories.json")
|
||||
path.join( folder, "userCategories.json" )
|
||||
)
|
||||
}
|
||||
if (this.userYieldUnits.length) {
|
||||
if ( this.userYieldUnits.length ) {
|
||||
userYieldUnitsFile = File.fromPath(
|
||||
path.join(folder, "userYieldUnits.json")
|
||||
path.join( folder, "userYieldUnits.json" )
|
||||
)
|
||||
}
|
||||
if (this.mealPlans.length) {
|
||||
mealPlansFile = File.fromPath(path.join(folder, "mealPlans.json"))
|
||||
if ( this.mealPlans.length ) {
|
||||
mealPlansFile = File.fromPath( path.join( folder, "mealPlans.json" ) )
|
||||
}
|
||||
switch (option) {
|
||||
switch ( option ) {
|
||||
case "create":
|
||||
this.writeDataToFile(EnRecipesFile, this.recipes)
|
||||
this.writeDataToFile( EnRecipesFile, this.recipes )
|
||||
this.userCategories.length &&
|
||||
this.writeDataToFile(userCategoriesFile, this.userCategories)
|
||||
this.writeDataToFile( userCategoriesFile, this.userCategories )
|
||||
this.userYieldUnits.length &&
|
||||
this.writeDataToFile(userYieldUnitsFile, this.userYieldUnits)
|
||||
this.writeDataToFile( userYieldUnitsFile, this.userYieldUnits )
|
||||
this.mealPlans.length &&
|
||||
this.writeDataToFile(mealPlansFile, this.mealPlans)
|
||||
this.writeDataToFile( mealPlansFile, this.mealPlans )
|
||||
break
|
||||
case "delete":
|
||||
EnRecipesFile.remove()
|
||||
|
@ -245,144 +279,159 @@ export default {
|
|||
break
|
||||
}
|
||||
},
|
||||
writeDataToFile(file, data) {
|
||||
file.writeText(JSON.stringify(data))
|
||||
writeDataToFile( file, data ) {
|
||||
file.writeText( JSON.stringify( data ) )
|
||||
},
|
||||
|
||||
// IMPORT HANDLERS
|
||||
importCheck() {
|
||||
this.permissionCheck(
|
||||
this.permissionConfirmation,
|
||||
"EnRecipes requires storage permission in order to import your data from a previous backup.",
|
||||
localize( "EnRecipes requires storage permission in order to import your data from a previous backup." ),
|
||||
this.openFilePicker
|
||||
)
|
||||
},
|
||||
openFilePicker() {
|
||||
Filepicker.create({
|
||||
mode: "single",
|
||||
extensions: ["zip"],
|
||||
})
|
||||
Filepicker.create( {
|
||||
mode: "single",
|
||||
extensions: [ "zip" ],
|
||||
} )
|
||||
.present()
|
||||
.then((selection) => {
|
||||
Toast.makeText("Processing...").show()
|
||||
let zipPath = selection[0]
|
||||
this.validateZipContent(zipPath)
|
||||
})
|
||||
.then( ( selection ) => {
|
||||
Toast.makeText( localize( "Verifying..." ) ).show()
|
||||
let zipPath = selection[ 0 ]
|
||||
this.validateZipContent( zipPath )
|
||||
} )
|
||||
},
|
||||
importDataToDB(data, db, zipPath) {
|
||||
switch (db) {
|
||||
importDataToDB( data, db, zipPath ) {
|
||||
switch ( db ) {
|
||||
case "EnRecipesDB":
|
||||
this.importImages(zipPath)
|
||||
this.importRecipesAction(data)
|
||||
this.importImages( zipPath )
|
||||
this.importRecipesAction( data )
|
||||
break
|
||||
case "userCategoriesDB":
|
||||
this.importCategoriesAction(data)
|
||||
this.importCategoriesAction( data )
|
||||
break
|
||||
case "userYieldUnitsDB":
|
||||
this.importYieldUnitsAction(data)
|
||||
this.importYieldUnitsAction( data )
|
||||
break
|
||||
case "mealPlansDB":
|
||||
this.importMealPlansAction(data)
|
||||
this.importMealPlansAction( data )
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
},
|
||||
isFileDataValid(file) {
|
||||
file.forEach((file, i) => {
|
||||
if (File.exists(file.path)) {
|
||||
File.fromPath(file.path)
|
||||
isFileDataValid( file ) {
|
||||
file.forEach( ( file, i ) => {
|
||||
if ( File.exists( file.path ) ) {
|
||||
File.fromPath( file.path )
|
||||
.readText()
|
||||
.then((data) => {
|
||||
Array.isArray(JSON.parse(data)) &&
|
||||
this.importDataToDB(JSON.parse(data), file.db, file.zipPath)
|
||||
})
|
||||
.then( ( data ) => {
|
||||
Array.isArray( JSON.parse( data ) ) &&
|
||||
this.importDataToDB( JSON.parse( data ), file.db, file.zipPath )
|
||||
} )
|
||||
}
|
||||
})
|
||||
} )
|
||||
},
|
||||
validateZipContent(zipPath) {
|
||||
Zip.unzip({
|
||||
validateZipContent( zipPath ) {
|
||||
Zip.unzip( {
|
||||
archive: zipPath,
|
||||
overwrite: true,
|
||||
}).then((extractedFolderPath) => {
|
||||
} ).then( ( extractedFolderPath ) => {
|
||||
let cacheFolderPath = extractedFolderPath + "/EnRecipes"
|
||||
const EnRecipesFilePath = cacheFolderPath + "/recipes.json"
|
||||
const userCategoriesFilePath = cacheFolderPath + "/userCategories.json"
|
||||
const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json"
|
||||
const mealPlansFilePath = cacheFolderPath + "/mealPlans.json"
|
||||
if (Folder.exists(cacheFolderPath)) {
|
||||
this.isFileDataValid([
|
||||
{
|
||||
if ( Folder.exists( cacheFolderPath ) ) {
|
||||
this.isFileDataValid( [ {
|
||||
zipPath,
|
||||
path: EnRecipesFilePath,
|
||||
db: "EnRecipesDB",
|
||||
},
|
||||
{ zipPath, path: userCategoriesFilePath, db: "userCategoriesDB" },
|
||||
{ zipPath, path: userYieldUnitsFilePath, db: "userYieldUnitsDB" },
|
||||
{ zipPath, path: mealPlansFilePath, db: "mealPlansDB" },
|
||||
])
|
||||
} else {
|
||||
Folder.fromPath(extractedFolderPath).remove()
|
||||
{
|
||||
zipPath,
|
||||
path: userCategoriesFilePath,
|
||||
db: "userCategoriesDB"
|
||||
},
|
||||
{
|
||||
zipPath,
|
||||
path: userYieldUnitsFilePath,
|
||||
db: "userYieldUnitsDB"
|
||||
},
|
||||
{
|
||||
zipPath,
|
||||
path: mealPlansFilePath,
|
||||
db: "mealPlansDB"
|
||||
},
|
||||
] )
|
||||
}
|
||||
else {
|
||||
Folder.fromPath( extractedFolderPath ).remove()
|
||||
Toast.makeText(
|
||||
"Import failed. Backup file is incorrect or corrupt",
|
||||
"long"
|
||||
).show()
|
||||
}
|
||||
if (Folder.exists(cacheFolderPath + "/Images")) {
|
||||
this.importImages(cacheFolderPath + "/Images")
|
||||
if ( Folder.exists( cacheFolderPath + "/Images" ) ) {
|
||||
this.importImages( cacheFolderPath + "/Images" )
|
||||
}
|
||||
})
|
||||
} )
|
||||
},
|
||||
importImages(sourcePath) {
|
||||
importImages( sourcePath ) {
|
||||
let dest = knownFolders.documents().path
|
||||
Zip.unzip({
|
||||
Zip.unzip( {
|
||||
archive: sourcePath,
|
||||
directory: dest,
|
||||
overwrite: true,
|
||||
}).then((res) => {
|
||||
Toast.makeText("Import successful", "long").show()
|
||||
} ).then( ( res ) => {
|
||||
Toast.makeText( localize( "Import successful" ), "long" ).show()
|
||||
this.$navigateBack()
|
||||
})
|
||||
} )
|
||||
},
|
||||
|
||||
// PERMISSIONS HANDLER
|
||||
permissionCheck(confirmation, description, action) {
|
||||
if (!ApplicationSettings.getBoolean("storagePermissionAsked", false)) {
|
||||
confirmation(description).then((e) => {
|
||||
if (e) {
|
||||
Permissions.request("photo").then((res) => {
|
||||
let status = res[Object.keys(res)[0]]
|
||||
if (status === "authorized") action()
|
||||
if (status !== "denied")
|
||||
ApplicationSettings.setBoolean("storagePermissionAsked", true)
|
||||
else Toast.makeText("Permission denied").show()
|
||||
})
|
||||
permissionCheck( confirmation, description, action ) {
|
||||
if ( !ApplicationSettings.getBoolean( "storagePermissionAsked", false ) ) {
|
||||
confirmation( description ).then( ( e ) => {
|
||||
if ( e ) {
|
||||
Permissions.request( "photo" ).then( ( res ) => {
|
||||
let status = res[ Object.keys( res )[ 0 ] ]
|
||||
if ( status === "authorized" ) action()
|
||||
if ( status !== "denied" )
|
||||
ApplicationSettings.setBoolean( "storagePermissionAsked", true )
|
||||
else Toast.makeText( localize( "Permission denied" ) ).show()
|
||||
} )
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Permissions.check("photo").then((res) => {
|
||||
let status = res[Object.keys(res)[0]]
|
||||
if (status !== "authorized") {
|
||||
confirmation(description).then((e) => {
|
||||
} )
|
||||
}
|
||||
else {
|
||||
Permissions.check( "photo" ).then( ( res ) => {
|
||||
let status = res[ Object.keys( res )[ 0 ] ]
|
||||
if ( status !== "authorized" ) {
|
||||
confirmation( description ).then( ( e ) => {
|
||||
e && utils.openAppSettingsPage()
|
||||
})
|
||||
} else action()
|
||||
})
|
||||
} )
|
||||
}
|
||||
else action()
|
||||
} )
|
||||
}
|
||||
},
|
||||
permissionConfirmation(description) {
|
||||
return this.$showModal(ConfirmDialog, {
|
||||
permissionConfirmation( description ) {
|
||||
return this.$showModal( ConfirmDialog, {
|
||||
props: {
|
||||
title: "Grant permission",
|
||||
description,
|
||||
cancelButtonText: "NOT NOW",
|
||||
okButtonText: "CONTINUE",
|
||||
},
|
||||
})
|
||||
} )
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.appTheme = ApplicationSettings.getString("appTheme", "Light")
|
||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
||||
this.appLanguage = ApplicationSettings.getString( "appLanguage", localize( "System default" ) )
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,67 +1,44 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" />
|
||||
<ScrollView width="100%" :height="height ? height : screenHeight - 256">
|
||||
<StackLayout>
|
||||
<MDButton
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
class="actionItem"
|
||||
variant="text"
|
||||
:rippleColor="rippleColor"
|
||||
:text="item"
|
||||
@loaded="onLabelLoaded"
|
||||
@tap="tapAction(item)"
|
||||
/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<GridLayout rows="auto" columns="auto, *, auto" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
v-if="action"
|
||||
col="0"
|
||||
class="action orkm pull-left"
|
||||
:text="action"
|
||||
@tap="$modal.close(action)"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="2"
|
||||
class="action orkm pull-right"
|
||||
text="CANCEL"
|
||||
@tap="$modal.close(false)"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
||||
<ScrollView width="100%" :height="height ? height : screenHeight - 256">
|
||||
<StackLayout>
|
||||
<MDButton v-for="(item, index) in list" :key="index" class="actionItem" variant="text" :rippleColor="rippleColor" :text="`${item}` | L" @loaded="onLabelLoaded" @tap="tapAction(item)" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<GridLayout rows="auto" columns="auto, *, auto" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" variant="text" v-if="action" col="0" class="action orkm pull-left" :text="`${action}` | L" @tap="$modal.close(action)" />
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm pull-right" :text="'CANCEL' | L" @tap="$modal.close(false)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application, Screen } from "@nativescript/core"
|
||||
import {
|
||||
Application,
|
||||
Screen
|
||||
} from "@nativescript/core"
|
||||
export default {
|
||||
props: ["title", "list", "height", "action"],
|
||||
props: [ "title", "list", "height", "action" ],
|
||||
computed: {
|
||||
appTheme() {
|
||||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ? "rgba(134,142,150,0.2)" : "rgba(206,212,218,0.1)"
|
||||
},
|
||||
screenHeight() {
|
||||
return Math.round(Screen.mainScreen.heightDIPs)
|
||||
return Math.round( Screen.mainScreen.heightDIPs )
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
tapAction(item) {
|
||||
this.$modal.close(item)
|
||||
tapAction( item ) {
|
||||
this.$modal.close( item )
|
||||
},
|
||||
onLabelLoaded(args) {
|
||||
args.object.android.setGravity(16)
|
||||
onLabelLoaded( args ) {
|
||||
args.object.android.setGravity( 16 )
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,62 +1,32 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" />
|
||||
<StackLayout
|
||||
v-if="filteredRecipes.length || searchTerm"
|
||||
padding="0 24 24"
|
||||
>
|
||||
<TextField hint="Search" v-model="searchTerm" />
|
||||
</StackLayout>
|
||||
<ScrollView width="100%" :height="height ? height : screenHeight - 320">
|
||||
<StackLayout>
|
||||
<MDButton
|
||||
v-for="(recipe, index) in filteredRecipes"
|
||||
:key="index"
|
||||
class="actionItem"
|
||||
variant="text"
|
||||
:rippleColor="rippleColor"
|
||||
:text="recipe.title"
|
||||
@loaded="onLabelLoaded"
|
||||
@tap="tapAction(recipe)"
|
||||
/>
|
||||
<Label
|
||||
padding="24"
|
||||
lineHeight="6"
|
||||
v-if="!filteredRecipes.length"
|
||||
text="Nothing here! Add some recipes and try again."
|
||||
textAlignment="center"
|
||||
textWrap="true"
|
||||
/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<GridLayout rows="auto" columns="auto, *, auto" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
v-if="action"
|
||||
col="0"
|
||||
class="action orkm pull-left"
|
||||
:text="action"
|
||||
@tap="$modal.close(action)"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="2"
|
||||
class="action orkm pull-right"
|
||||
text="CANCEL"
|
||||
@tap="$modal.close(false)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap='true' />
|
||||
<StackLayout v-if="filteredRecipes.length || searchTerm" padding="0 24 24">
|
||||
<TextField :hint="'Search' | L" v-model="searchTerm" />
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<ScrollView width="100%" :height="height ? height : screenHeight - 320">
|
||||
<StackLayout>
|
||||
<MDButton v-for="(recipe, index) in filteredRecipes" :key="index" class="actionItem" variant="text" :rippleColor="rippleColor" :text="recipe.title" @loaded="onLabelLoaded" @tap="tapAction(recipe)" />
|
||||
<Label padding="24" lineHeight="6" v-if="!filteredRecipes.length" :text="'Nothing here! Add some recipes and try again.' | L" textAlignment="center" textWrap="true" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
<GridLayout rows="auto" columns="auto, *, auto" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" variant="text" v-if="action" col="0" class="action orkm pull-left" :text="`${action}` | L" @tap="$modal.close(action)" />
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm pull-right" :text="'CANCEL' | L" @tap="$modal.close(false)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application, Screen } from "@nativescript/core"
|
||||
import {
|
||||
Application,
|
||||
Screen
|
||||
}
|
||||
from "@nativescript/core"
|
||||
export default {
|
||||
props: ["title", "recipes", "height", "action"],
|
||||
props: [ "title", "recipes", "height", "action" ],
|
||||
data() {
|
||||
return {
|
||||
searchTerm: "",
|
||||
|
@ -67,30 +37,26 @@ export default {
|
|||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ? "rgba(134,142,150,0.2)" : "rgba(206,212,218,0.1)"
|
||||
},
|
||||
screenHeight() {
|
||||
return Math.round(Screen.mainScreen.heightDIPs)
|
||||
return Math.round( Screen.mainScreen.heightDIPs )
|
||||
},
|
||||
filteredRecipes() {
|
||||
return this.recipes
|
||||
.map((e, i) => {
|
||||
return {
|
||||
id: e.id,
|
||||
title: e.title,
|
||||
}
|
||||
})
|
||||
.filter((e) => e.title.includes(this.searchTerm))
|
||||
return this.recipes.map( ( e, i ) => {
|
||||
return {
|
||||
id: e.id,
|
||||
title: e.title,
|
||||
}
|
||||
} ).filter( ( e ) => e.title.includes( this.searchTerm ) )
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
tapAction(recipe) {
|
||||
this.$modal.close(recipe.id)
|
||||
tapAction( recipe ) {
|
||||
this.$modal.close( recipe.id )
|
||||
},
|
||||
onLabelLoaded(args) {
|
||||
args.object.android.setGravity(16)
|
||||
onLabelLoaded( args ) {
|
||||
args.object.android.setGravity( 16 )
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,47 +1,31 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" textWrap="true"/>
|
||||
<Label
|
||||
v-if="description"
|
||||
class="dialogDescription"
|
||||
:text="description"
|
||||
textWrap="true"
|
||||
/>
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="1"
|
||||
class="action orkm"
|
||||
:text="cancelButtonText"
|
||||
@tap="$modal.close(false)"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="2"
|
||||
class="action orkm"
|
||||
:text="okButtonText"
|
||||
@tap="$modal.close(true)"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap="true" />
|
||||
<Label v-if="description" class="dialogDescription" :text="description" textWrap="true" />
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="`${cancelButtonText}` | L" @tap="$modal.close(false)" />
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${okButtonText}` | L" @tap="$modal.close(true)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application } from "@nativescript/core"
|
||||
import {
|
||||
Application
|
||||
}
|
||||
from "@nativescript/core"
|
||||
export default {
|
||||
props: ["title", "description", "cancelButtonText", "okButtonText"],
|
||||
props: [ "title", "description", "cancelButtonText", "okButtonText" ],
|
||||
computed: {
|
||||
appTheme() {
|
||||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ?
|
||||
"rgba(134,142,150,0.2)" :
|
||||
"rgba(206,212,218,0.1)"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,138 +1,73 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" />
|
||||
<StackLayout
|
||||
class="dialogListPicker"
|
||||
orientation="horizontal"
|
||||
horizontalAlignment="center"
|
||||
>
|
||||
<ListPicker
|
||||
ref="hrPicker"
|
||||
:items="hrs"
|
||||
:selectedIndex="hrIndex"
|
||||
@selectedIndexChange="setHrs"
|
||||
></ListPicker>
|
||||
<ListPicker
|
||||
ref="minPicker"
|
||||
:items="mins"
|
||||
:selectedIndex="minIndex"
|
||||
@selectedIndexChange="setMins"
|
||||
></ListPicker>
|
||||
</StackLayout>
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="1"
|
||||
class="action orkm"
|
||||
text="CANCEL"
|
||||
@tap="$modal.close(false)"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="2"
|
||||
class="action orkm"
|
||||
:text="action"
|
||||
@tap="$modal.close(selectedTime)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
||||
<StackLayout class="dialogListPicker" orientation="horizontal" horizontalAlignment="center">
|
||||
<ListPicker ref="hrPicker" :items="hrsList" :selectedIndex="hrIndex" @selectedIndexChange="setHrs"></ListPicker>
|
||||
<ListPicker ref="minPicker" :items="minsList" :selectedIndex="minIndex" @selectedIndexChange="setMins"></ListPicker>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="'CANCEL' | L" @tap="$modal.close(false)" />
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${action}` | L" @tap="$modal.close(selectedTime)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application } from "@nativescript/core"
|
||||
import {
|
||||
Application
|
||||
}
|
||||
from "@nativescript/core"
|
||||
import {
|
||||
localize
|
||||
}
|
||||
from "@nativescript/localize"
|
||||
export default {
|
||||
props: ["title", "selectedHr", "selectedMin", "action"],
|
||||
props: [ "title", "selectedHr", "selectedMin", "action" ],
|
||||
data() {
|
||||
return {
|
||||
hrs: [
|
||||
"0 hr",
|
||||
"1 hr",
|
||||
"2 hr",
|
||||
"3 hr",
|
||||
"4 hr",
|
||||
"5 hr",
|
||||
"6 hr",
|
||||
"7 hr",
|
||||
"8 hr",
|
||||
"9 hr",
|
||||
"10 hr",
|
||||
"11 hr",
|
||||
"12 hr",
|
||||
"13 hr",
|
||||
"14 hr",
|
||||
"15 hr",
|
||||
"16 hr",
|
||||
"17 hr",
|
||||
"18 hr",
|
||||
"19 hr",
|
||||
"20 hr",
|
||||
"21 hr",
|
||||
"22 hr",
|
||||
"23 hr",
|
||||
],
|
||||
mins: [
|
||||
"0 min",
|
||||
"1 min",
|
||||
"2 min",
|
||||
"3 min",
|
||||
"4 min",
|
||||
"5 min",
|
||||
"6 min",
|
||||
"7 min",
|
||||
"8 min",
|
||||
"9 min",
|
||||
"10 min",
|
||||
"15 min",
|
||||
"20 min",
|
||||
"25 min",
|
||||
"30 min",
|
||||
"35 min",
|
||||
"40 min",
|
||||
"45 min",
|
||||
"50 min",
|
||||
"55 min",
|
||||
],
|
||||
hrs: [],
|
||||
mins: [],
|
||||
selectedHrs: "00",
|
||||
selectedMins: "00",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hrsList() {
|
||||
let h = [ ...Array( 24 ).keys() ]
|
||||
this.hrs = h
|
||||
return h.map( e => `${e} ${localize( 'hr' )}` )
|
||||
},
|
||||
minsList() {
|
||||
let m = [ ...new Set( [ ...Array( 11 ).keys(), ...Array.from( Array( 12 ), ( _, x ) => x * 5 ) ] ) ]
|
||||
this.mins = m
|
||||
return m.map( e => `${e} ${localize( 'min' )}` )
|
||||
},
|
||||
hrIndex() {
|
||||
let hr = this.selectedHr
|
||||
if (hr.charAt(0) == "0") hr = hr.slice(-1) + " hr"
|
||||
else hr = hr + " hr"
|
||||
return this.hrs.indexOf(hr)
|
||||
return this.hrs.indexOf( parseInt( this.selectedHr ) )
|
||||
},
|
||||
minIndex() {
|
||||
let min = this.selectedMin
|
||||
if (min.charAt(0) == "0") min = min.slice(-1) + " min"
|
||||
else min = min + " min"
|
||||
return this.mins.indexOf(min)
|
||||
return this.mins.indexOf( parseInt( this.selectedMin ) )
|
||||
},
|
||||
appTheme() {
|
||||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ? "rgba(134,142,150,0.2)" : "rgba(206,212,218,0.1)"
|
||||
},
|
||||
selectedTime() {
|
||||
return this.selectedHrs + ":" + this.selectedMins
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setHrs(args) {
|
||||
let hr = "0" + this.hrs[args.object.selectedIndex]
|
||||
this.selectedHrs = hr.slice(-5).slice(0, -3)
|
||||
setHrs( args ) {
|
||||
let hr = "0" + this.hrs[ args.object.selectedIndex ]
|
||||
this.selectedHrs = hr.slice( -2 )
|
||||
},
|
||||
setMins(args) {
|
||||
let min = "0" + this.mins[args.object.selectedIndex]
|
||||
this.selectedMins = min.slice(-6).slice(0, -4)
|
||||
setMins( args ) {
|
||||
let min = "0" + this.mins[ args.object.selectedIndex ]
|
||||
this.selectedMins = min.slice( -2 )
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,41 +1,30 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" />
|
||||
<StackLayout class="dialogInput">
|
||||
<TextField
|
||||
@loaded="focusField"
|
||||
:hint="hint ? hint : ''"
|
||||
v-model="category"
|
||||
autocapitalizationType="words"
|
||||
/>
|
||||
</StackLayout>
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="1"
|
||||
class="action orkm"
|
||||
text="CANCEL"
|
||||
@tap="$modal.close(false)"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
variant="text"
|
||||
col="2"
|
||||
class="action orkm"
|
||||
:text="action"
|
||||
@tap="$modal.close(category)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap='true' />
|
||||
<StackLayout class="dialogInput">
|
||||
<TextField @loaded="focusField" :hint="hint ? hint : ''" v-model="category" autocapitalizationType="words" />
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="'CANCEL' | L" @tap="$modal.close(false)" />
|
||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${action}` | L" @tap="$modal.close(category)" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application, Utils } from "@nativescript/core"
|
||||
import {
|
||||
Application,
|
||||
Utils
|
||||
}
|
||||
from "@nativescript/core"
|
||||
import {
|
||||
localize
|
||||
}
|
||||
from '@nativescript/localize'
|
||||
export default {
|
||||
props: ["title", "hint", "text", "action"],
|
||||
props: [ "title", "hint", "text", "action" ],
|
||||
data() {
|
||||
return {
|
||||
category: null,
|
||||
|
@ -46,20 +35,18 @@ export default {
|
|||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ? "rgba(134,142,150,0.2)" : "rgba(206,212,218,0.1)"
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
focusField(args) {
|
||||
focusField( args ) {
|
||||
args.object.focus()
|
||||
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1)
|
||||
setTimeout( ( e ) => Utils.ad.showSoftInput( args.object.android ), 1 )
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.text) {
|
||||
this.category = this.text
|
||||
if ( this.text ) {
|
||||
this.category = localize( this.text )
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,45 +1,31 @@
|
|||
<template>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="title" />
|
||||
<GridLayout rows="auto, auto" columns="*" class="actionsContainer">
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
:backgroundColor="backgroundColor"
|
||||
row="0"
|
||||
class="actionIcon"
|
||||
src="res://photo"
|
||||
text="Photo"
|
||||
@tap="$modal.close('photo')"
|
||||
/>
|
||||
<MDButton
|
||||
:rippleColor="rippleColor"
|
||||
:backgroundColor="backgroundColor"
|
||||
row="1"
|
||||
class="actionIcon"
|
||||
src="res://detail"
|
||||
text="Recipe"
|
||||
@tap="$modal.close('recipe')"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
<Page>
|
||||
<StackLayout class="dialogContainer" :class="appTheme">
|
||||
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
||||
<GridLayout rows="auto, auto" columns="*" class="actionsContainer">
|
||||
<MDButton :rippleColor="rippleColor" :backgroundColor="backgroundColor" row="0" class="actionIcon" src="res://photo" :text="'Photo' | L" @tap="$modal.close('photo')" />
|
||||
<MDButton :rippleColor="rippleColor" :backgroundColor="backgroundColor" row="1" class="actionIcon" src="res://detail" :text="'Recipe' | L" @tap="$modal.close('recipe')" />
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Application } from "@nativescript/core"
|
||||
import { mapState } from "vuex"
|
||||
import {
|
||||
Application
|
||||
} from "@nativescript/core"
|
||||
import {
|
||||
mapState
|
||||
} from "vuex"
|
||||
export default {
|
||||
props: ["title"],
|
||||
props: [ "title" ],
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
...mapState( [ "icon" ] ),
|
||||
appTheme() {
|
||||
return Application.systemAppearance()
|
||||
},
|
||||
rippleColor() {
|
||||
return this.appTheme == "light"
|
||||
? "rgba(134,142,150,0.2)"
|
||||
: "rgba(206,212,218,0.1)"
|
||||
return this.appTheme == "light" ? "rgba(134,142,150,0.2)" : "rgba(206,212,218,0.1)"
|
||||
},
|
||||
backgroundColor() {
|
||||
return this.appTheme == "light" ? "#fff" : "#343a40"
|
||||
|
|
206
app/i18n/en.default.json
Normal file
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"app.name": "EnRecipes",
|
||||
"EnRecipes": "EnRecipes",
|
||||
"Try Later": "Try Later",
|
||||
"Favourites": "Favourites",
|
||||
"Meal Planner": "Meal Planner",
|
||||
"Categories": "Categories",
|
||||
"DONE": "DONE",
|
||||
"RENAME": "RENAME",
|
||||
"Settings": "Settings",
|
||||
"About": "About",
|
||||
"Appetizers": "Appetizers",
|
||||
"Barbecue": "Barbecue",
|
||||
"Beverages": "Beverages",
|
||||
"Breads": "Breads",
|
||||
"Breakfast": "Breakfast",
|
||||
"Desserts": "Desserts",
|
||||
"Dinner": "Dinner",
|
||||
"Drinks": "Drinks",
|
||||
"Healthy": "Healthy",
|
||||
"Lunch": "Lunch",
|
||||
"Main dishes": "Main dishes",
|
||||
"Meat": "Meat",
|
||||
"Noodles": "Noodles",
|
||||
"Pasta": "Pasta",
|
||||
"Poultry": "Poultry",
|
||||
"Rice": "Rice",
|
||||
"Salads": "Salads",
|
||||
"Sauces": "Sauces",
|
||||
"Seafood": "Seafood",
|
||||
"Side dishes": "Side dishes",
|
||||
"Snacks": "Snacks",
|
||||
"Soups": "Soups",
|
||||
"Undefined": "Undefined",
|
||||
"Vegan": "Vegan",
|
||||
"Vegetarian": "Vegetarian",
|
||||
"Serving": "Serving",
|
||||
"Piece": "Piece",
|
||||
"Teaspoon": "Teaspoon",
|
||||
"Tablespoon": "Tablespoon",
|
||||
"Fluid Ounce": "Fluid Ounce",
|
||||
"Ounce": "Ounce",
|
||||
"Pound": "Pound",
|
||||
"Gram": "Gram",
|
||||
"Kilogram": "Kilogram",
|
||||
"Cup": "Cup",
|
||||
"Gallon": "Gallon",
|
||||
"Millilitre": "Millilitre",
|
||||
"Litre": "Litre",
|
||||
"Roll": "Roll",
|
||||
"Patty": "Patty",
|
||||
"Loaf": "Loaf",
|
||||
"unit": "unit",
|
||||
"Unit": "Unit",
|
||||
"tsp": "tsp",
|
||||
"dsp": "dsp",
|
||||
"tbsp": "tbsp",
|
||||
"fl oz": "fl oz",
|
||||
"cup": "cup",
|
||||
"pt": "pt",
|
||||
"qt": "qt",
|
||||
"gal": "gal",
|
||||
"ml": "ml",
|
||||
"l": "l",
|
||||
"oz": "oz",
|
||||
"lb": "lb",
|
||||
"mg": "mg",
|
||||
"g": "g",
|
||||
"kg": "kg",
|
||||
"cm": "cm",
|
||||
"in": "in",
|
||||
"leaf": "leaf",
|
||||
"clove": "clove",
|
||||
"piece": "piece",
|
||||
"pinch": "pinch",
|
||||
"drop": "drop",
|
||||
"dozen": "dozen",
|
||||
"stick": "stick",
|
||||
"small": "small",
|
||||
"medium": "medium",
|
||||
"large": "large",
|
||||
"Start adding your recipes!": "Start adding your recipes!",
|
||||
"Use the plus button to add one": "Use the plus button to add one",
|
||||
"Use the pencil button to add some ingredients": "Use the pencil button to add some ingredients",
|
||||
"Use the pencil button to add some instructions": "Use the pencil button to add some instructions",
|
||||
"Use the pencil button to add some combinations": "Use the pencil button to add some combinations",
|
||||
"Use the pencil button to add some notes": "Use the pencil button to add some notes",
|
||||
"All done!": "All done!",
|
||||
"Recipes you mark as try later will be listed here": "Recipes you mark as try later will be listed here",
|
||||
"No favourites yet": "No favourites yet",
|
||||
"Recipes you mark as favourite will be listed here": "Recipes you mark as favourite will be listed here",
|
||||
"Category looks empty": "Category looks empty",
|
||||
"No recipes found": "No recipes found",
|
||||
"Your search did not match any recipes": "Your search did not match any recipes",
|
||||
"Your search did not match any recipes in this category": "Your search did not match any recipes in this category",
|
||||
"Your search did not match any recipes in your favourites": "Your search did not match any recipes in your favourites",
|
||||
"Your search did not match any recipes in your try later list": "Your search did not match any recipes in your try later list",
|
||||
"Interface": "Interface",
|
||||
"App language": "App language",
|
||||
"System default": "System default",
|
||||
"Theme": "Theme",
|
||||
"Light": "Light",
|
||||
"Dark": "Dark",
|
||||
"Database": "Database",
|
||||
"Export a full backup": "Export a full backup",
|
||||
"Generates a zip file that contains all your data. This file can be imported back.": "Generates a zip file that contains all your data. This file can be imported back.",
|
||||
"Import from backup": "Import from backup",
|
||||
"Supports full backups exported by this app": "Supports full backups exported by this app",
|
||||
"Version": "Version",
|
||||
"View project on GitHub": "View project on GitHub",
|
||||
"Join the Telegram group": "Join the Telegram group",
|
||||
"for reporting issues, suggestions and feedback": "for reporting issues, suggestions and feedback",
|
||||
"Author": "Author",
|
||||
"Vishnu Raghav B": "Vishnu Raghav B",
|
||||
"Follow on GitHub": "Follow on GitHub",
|
||||
"Follow on Mastodon": "Follow on Mastodon",
|
||||
"New recipe": "New recipe",
|
||||
"Edit recipe": "Edit recipe",
|
||||
"Title": "Title",
|
||||
"Category": "Category",
|
||||
"Preparation time": "Preparation time",
|
||||
"Cooking time": "Cooking time",
|
||||
"Yield quantity": "Yield quantity",
|
||||
"Yield measured in": "Yield measured in",
|
||||
"Ingredient": "Ingredient",
|
||||
"Ingredients": "Ingredients",
|
||||
"ADD INGREDIENT": "ADD INGREDIENT",
|
||||
"Instruction": "Instruction",
|
||||
"Instructions": "Instructions",
|
||||
"ADD STEP": "ADD STEP",
|
||||
"Combinations": "Combinations",
|
||||
"ADD COMBINATION": "ADD COMBINATION",
|
||||
"Note": "Note",
|
||||
"Notes": "Notes",
|
||||
"ADD NOTE": "ADD NOTE",
|
||||
"Item": "Item",
|
||||
"Step": "Step",
|
||||
"Note": "Note",
|
||||
"Sort by": "Sort by",
|
||||
"Natural order": "Natural order",
|
||||
"Duration": "Duration",
|
||||
"Last modified": "Last modified",
|
||||
"CANCEL": "CANCEL",
|
||||
"REMOVE": "REMOVE",
|
||||
"ADD": "ADD",
|
||||
"Select a recipe": "Select a recipe",
|
||||
"Nothing here! Add some recipes and try again.": "Nothing here! Add some recipes and try again.",
|
||||
"My Healthy Recipe": "My Healthy Recipe",
|
||||
"hr": "hr",
|
||||
"min": "min",
|
||||
"Photo": "Photo",
|
||||
"Recipe": "Recipe",
|
||||
"Overview": "Overview",
|
||||
"Share": "Share",
|
||||
"ADD NEW": "ADD NEW",
|
||||
"SET": "SET",
|
||||
"Restart required": "Restart required",
|
||||
"RESTART": "RESTART",
|
||||
"EnRecipes needs to be restarted for the theme change to take effect.": "EnRecipes needs to be restarted for the theme change to take effect.",
|
||||
"EnRecipes needs to be restarted for the app language to take effect.": "EnRecipes needs to be restarted for the app language to take effect.",
|
||||
"Grant permission": "Grant permission",
|
||||
"EnRecipes requires storage permission in order to import your data from a previous backup.": "EnRecipes requires storage permission in order to import your data from a previous backup.",
|
||||
"NOT NOW": "NOT NOW",
|
||||
"CONTINUE": "CONTINUE",
|
||||
"EnRecipes requires storage permission in order to backup your data to this device.": "EnRecipes requires storage permission in order to backup your data to this device.",
|
||||
"Add at least one recipe to perform a backup": "Add at least one recipe to perform a backup",
|
||||
"Added to Favourites": "Added to Favourites",
|
||||
"Removed from Favourites": "Removed from Favourites",
|
||||
"Added to Try Later": "Added to Try Later",
|
||||
"Removed from Try Later": "Removed from Try Later",
|
||||
"Delete recipe?": "Delete recipe?",
|
||||
"DELETE": "DELETE",
|
||||
"Are you sure you want to delete the recipe": "Are you sure you want to delete the recipe",
|
||||
"Search": "Search",
|
||||
"Rename category": "Rename category",
|
||||
"Unsaved changes": "Unsaved changes",
|
||||
"Are you sure you want to discard unsaved changes to this recipe?": "Are you sure you want to discard unsaved changes to this recipe?",
|
||||
"DISCARD": "DISCARD",
|
||||
"KEEP EDITING": "KEEP EDITING",
|
||||
"Remove ingredient?": "Remove ingredient?",
|
||||
"Remove instruction?": "Remove instruction?",
|
||||
"Remove combination?": "Remove combination?",
|
||||
"Remove note?": "Remove note?",
|
||||
"New yield unit": "New yield unit",
|
||||
"New category": "New category",
|
||||
"Required": "Required",
|
||||
"EnRecipes requires storage permission in order to set recipe photo.": "EnRecipes requires storage permission in order to set recipe photo.",
|
||||
"Recipe photo": "Recipe photo",
|
||||
"REPLACE PHOTO": "REPLACE PHOTO",
|
||||
"Crop photo": "Crop photo",
|
||||
"breakfast": "breakfast",
|
||||
"lunch": "lunch",
|
||||
"dinner": "dinner",
|
||||
"snacks": "snacks",
|
||||
"You tried this recipe:": "You tried this recipe:",
|
||||
"today": "today",
|
||||
"yesterday": "yesterday",
|
||||
"days ago": "days ago",
|
||||
"weeks ago": "weeks ago",
|
||||
"months ago": "months ago",
|
||||
"long time ago": "long time ago",
|
||||
"Verifying...": "Verifying...",
|
||||
"Import successful": "Import successful",
|
||||
"Permission denied": "Permission denied",
|
||||
"Shared via EnRecipes. Get it on Play Store or F-Droid.": "Shared via EnRecipes. Get it on Play Store or F-Droid."
|
||||
}
|
206
app/i18n/ta.json
Normal file
|
@ -0,0 +1,206 @@
|
|||
{
|
||||
"app.name": "என்ரெசிபீஸ்",
|
||||
"EnRecipes": "என்ரெசிபீஸ்",
|
||||
"Try Later": "பின்னர் முயற்சிக்க",
|
||||
"Favourites": "பிடித்தவை",
|
||||
"Meal Planner": "உணவுத் திட்டம்",
|
||||
"Categories": "வகைகள்",
|
||||
"DONE": "முடிந்தது",
|
||||
"RENAME": "மறுபெயரிடு",
|
||||
"Settings": "அமைப்புகள்",
|
||||
"About": "பற்றி",
|
||||
"Appetizers": "பசித்தூண்டி",
|
||||
"Barbecue": "பார்பிக்யூ",
|
||||
"Beverages": "பானங்கள்",
|
||||
"Breads": "ரொட்டிகள்",
|
||||
"Breakfast": "காலை உணவு",
|
||||
"Desserts": "இனிப்புகள்",
|
||||
"Dinner": "இரவு உணவு",
|
||||
"Drinks": "மதுபானம்",
|
||||
"Healthy": "ஆரோக்கியமானவை",
|
||||
"Lunch": "மதிய உணவு",
|
||||
"Main dishes": "முக்கிய உணவுகள்",
|
||||
"Meat": "இறைச்சி",
|
||||
"Noodles": "நூடுல்ஸ்",
|
||||
"Pasta": "பாஸ்தா",
|
||||
"Poultry": "கோழி",
|
||||
"Rice": "சோறு",
|
||||
"Salads": "சாலடுகள்",
|
||||
"Sauces": "சாஸ்கள்",
|
||||
"Seafood": "கடல் உணவு",
|
||||
"Side dishes": "தொடு கறிகள்",
|
||||
"Snacks": "தின்பண்டங்கள்",
|
||||
"Soups": "சூப்கள்",
|
||||
"Undefined": "வரையறுக்கப்படாதவை",
|
||||
"Vegan": "வேகன்",
|
||||
"Vegetarian": "சைவம்",
|
||||
"Serving": "கூறு",
|
||||
"Piece": "துண்டு",
|
||||
"Teaspoon": "டீஸ்பூன்",
|
||||
"Tablespoon": "தேக்கரண்டி",
|
||||
"Fluid Ounce": "திரவ அவுன்ஸ்",
|
||||
"Ounce": "அவுன்ஸ்",
|
||||
"Pound": "பவுண்டு",
|
||||
"Gram": "கிராம்",
|
||||
"Kilogram": "கிலோகிராம்",
|
||||
"Cup": "கோப்பை",
|
||||
"Gallon": "கேலன்",
|
||||
"Millilitre": "மில்லிலிட்டர்",
|
||||
"Litre": "லிட்டர்",
|
||||
"Roll": "ரோல்",
|
||||
"Patty": "வடை",
|
||||
"Loaf": "ரொட்டித் துண்டு",
|
||||
"unit": "அலகு",
|
||||
"Unit": "அலகு",
|
||||
"tsp": "டீஸ்பூன்",
|
||||
"dsp": "இனிப்பு ஸ்பூன்",
|
||||
"tbsp": "தேக்கரண்டி",
|
||||
"fl oz": "திரவ அவுன்ஸ",
|
||||
"cup": "கோப்பை",
|
||||
"pt": "பைண்ட்",
|
||||
"qt": "குவிண்ட்",
|
||||
"gal": "கேலன்",
|
||||
"ml": "மில்லிலிட்டர்",
|
||||
"l": "லிட்டர்",
|
||||
"oz": "அவுன்ஸ்",
|
||||
"lb": "பவுண்டு",
|
||||
"mg": "மில்லிகிராம்",
|
||||
"g": "கிராம்",
|
||||
"kg": "கிலோகிராம்",
|
||||
"cm": "சென்டிமீட்டர்",
|
||||
"in": "அங்குலம்",
|
||||
"leaf": "இலை",
|
||||
"clove": "பல்",
|
||||
"piece": "துண்டு",
|
||||
"pinch": "கிள்ளு",
|
||||
"drop": "துளி",
|
||||
"dozen": "டஜன்",
|
||||
"stick": "குச்சி",
|
||||
"small": "சிறிய",
|
||||
"medium": "நடுத்தர",
|
||||
"large": "பெரிய",
|
||||
"Start adding your recipes!": "உங்கள் சமையல் குறிப்புகளைச் சேர்க்கத் தொடங்குங்கள்!",
|
||||
"Use the plus button to add one": "ஒரு செய்முறையைச் சேர்க்க பிளஸ் பொத்தானைப் பயன்படுத்தவும்",
|
||||
"Use the pencil button to add some ingredients": "தேவையான பொருட்களைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்",
|
||||
"Use the pencil button to add some instructions": "செய்முறைகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்",
|
||||
"Use the pencil button to add some combinations": "சில சேர்க்கைகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்",
|
||||
"Use the pencil button to add some notes": "சில குறிப்புகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்",
|
||||
"All done!": "அனைத்தும் செய்யப்பட்டுள்ளன!",
|
||||
"Recipes you mark as try later will be listed here": "முயற்சிக்க வேண்டும் என நீங்கள் குறிக்கும் சமையல் குறிப்புகள் இங்கே பட்டியலிடப்படும்",
|
||||
"No favourites yet": "இன்னும் பிடித்தவை எதுவும் இல்லை",
|
||||
"Recipes you mark as favourite will be listed here": "நீங்கள் பிடித்ததாகக் குறிக்கும் சமையல் குறிப்புகள் இங்கே பட்டியலிடப்படும்",
|
||||
"Category looks empty": "இந்த பிரிவில் எந்த சமையல் குறிப்புகளும் இல்லை",
|
||||
"No recipes found": "எந்த சமையல் குறிப்புகளும் இல்லை",
|
||||
"Your search did not match any recipes": "உங்கள் தேடல் எந்த சமையல் குறிப்புகளுக்கும் பொருந்தவில்லை",
|
||||
"Your search did not match any recipes in this category": "உங்கள் தேடல் இந்த வகையில் எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லை",
|
||||
"Your search did not match any recipes in your favourites": "உங்கள் தேடல் உங்களுக்கு பிடித்தவற்றில் எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லைை",
|
||||
"Your search did not match any recipes in your try later list": "உங்கள் தேடல் நீங்கள் முயற்சிக்க வேண்டிய பட்டியலில் உள்ள எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லைை",
|
||||
"Interface": "இடைமுகம்",
|
||||
"App language": "பயன்பாட்டு மொழி",
|
||||
"System default": "கணினி இயல்புநிலை",
|
||||
"Theme": "தீம்",
|
||||
"Light": "வெளிச்சம்",
|
||||
"Dark": "இருள்",
|
||||
"Database": "தரவுத்தளம்",
|
||||
"Export a full backup": "முழு காப்புப்பிரதியை ஏற்றுமதி செய்க",
|
||||
"Generates a zip file that contains all your data. This file can be imported back.": "இது உங்கள் எல்லா தரவையும் கொண்ட ஒரு ஜிப் கோப்பை உருவாக்குகிறது. இந்த கோப்பை மீண்டும் இறக்குமதி செய்யலாம்.",
|
||||
"Import from backup": "காப்புப்பிரதியிலிருந்து இறக்குமதி செய்க",
|
||||
"Supports full backups exported by this app": "இந்த பயன்பாட்டின் மூலம் ஏற்றுமதி செய்யப்பட்ட முழு காப்புப்பிரதிகளை ஆதரிக்கும்",
|
||||
"Version": "பதிப்பு",
|
||||
"View project on GitHub": "கிட்ஹப்பில் திட்டத்தைக் காண்க",
|
||||
"Join the Telegram group": "டெலிகிராம் குழுவில் சேரவும்",
|
||||
"for reporting issues, suggestions and feedback": "சிக்கல்கள், பரிந்துரைகள் மற்றும் கருத்துக்களைப் புகாரளிக்க",
|
||||
"Author": "பயன்பாட்டு ஆசிரியர்",
|
||||
"Vishnu Raghav B": "விஷ்ணு ராகவ் .பா",
|
||||
"Follow on GitHub": "கிட்ஹப்பில் அவரைப் பின்தொடரவும்",
|
||||
"Follow on Mastodon": "மஸ்டோடனில் அவரைப் பின்தொடரவும்",
|
||||
"New recipe": "புதிய செய்முறை",
|
||||
"Edit recipe": "செய்முறையைத் திருத்து",
|
||||
"Title": "தலைப்பு",
|
||||
"Category": "வகை",
|
||||
"Preparation time": "தயாரிப்பு நேரம்",
|
||||
"Cooking time": "சமைக்கும் நேரம்",
|
||||
"Yield quantity": "மகசூல் அளவு",
|
||||
"Yield measured in": "மகசூல் அலகு",
|
||||
"Ingredient": "தேவையான பொருள்",
|
||||
"Ingredients": "தேவையான பொருட்கள்",
|
||||
"ADD INGREDIENT": "பொருளைச் சேர்",
|
||||
"Instruction": "செய்முறை",
|
||||
"Instructions": "செய்முறைகள்",
|
||||
"ADD STEP": "செய்முறையைச் சேர்",
|
||||
"Combinations": "சேர்க்கைகள்",
|
||||
"ADD COMBINATION": "சேர்க்கையைச் சேர்",
|
||||
"Note": "குறிப்பு",
|
||||
"Notes": "குறிப்புகள்",
|
||||
"ADD NOTE": "குறிப்பைச் சேர்",
|
||||
"Item": "பொருள்",
|
||||
"Step": "செயஂமுறை",
|
||||
"Note": "குறிப்பு",
|
||||
"Sort by": "வரிசை விதி",
|
||||
"Natural order": "இயற்கை வரிசை",
|
||||
"Duration": "நேரம்",
|
||||
"Last modified": "கடைசியாக மாற்றப்பட்டது",
|
||||
"CANCEL": "ரத்துசெய்",
|
||||
"REMOVE": "அகற்று",
|
||||
"ADD": "சேர்",
|
||||
"Select a recipe": "ஒரு செய்முறையைத் தேர்ந்தெடுக்கவும்",
|
||||
"Nothing here! Add some recipes and try again.": "இங்கு எதுவுமில்லை! சில சமையல் வகைகளைச் சேர்த்து மீண்டும் முயற்சிக்கவும்.",
|
||||
"My Healthy Recipe": "எனது ஆரோக்கியமான செய்முறை",
|
||||
"hr": "மணி",
|
||||
"min": "நிமிடம்",
|
||||
"Photo": "புகைப்படம்",
|
||||
"Recipe": "செய்முறை",
|
||||
"Overview": "கண்ணோட்டம்",
|
||||
"Share": "பகிர்",
|
||||
"ADD NEW": "புதியனவற்றை சேர்",
|
||||
"SET": "அமை",
|
||||
"Restart required": "மறுதொடக்கம் தேவை",
|
||||
"RESTART": "மறுதொடக்கம்",
|
||||
"EnRecipes needs to be restarted for the theme change to take effect.": "தீம் மாற்றம் நடைமுறைக்கு வருவதற்கு என்ரெசிபீஸ் ஐ மீண்டும் தொடங்க வேண்டும்.",
|
||||
"EnRecipes needs to be restarted for the app language to take effect.": "பயன்பாட்டு மொழி நடைமுறைக்கு வருவதற்கு என்ரெசிபீஸ் ஐ மீண்டும் தொடங்க வேண்டும்.",
|
||||
"Grant permission": "அனுமதி வழங்கவும்",
|
||||
"EnRecipes requires storage permission in order to import your data from a previous backup.": "முந்தைய காப்புப்பிரதியிலிருந்து உங்கள் தரவை இறக்குமதி செய்ய என்ரெசிபீஸ்க்கு சேமிப்பு அனுமதி தேவைப்படுகிறது.",
|
||||
"NOT NOW": "இப்போது இல்லை",
|
||||
"CONTINUE": "தொடர்",
|
||||
"EnRecipes requires storage permission in order to backup your data to this device.": "இந்தச் சாதனத்தில் உங்கள் தரவை காப்புப் பிரதி எடுக்க என்ரெசிபீஸ்க்கு சேமிப்பக அனுமதி தேவைப்படுகிறது.",
|
||||
"Add at least one recipe to perform a backup": "காப்புப்பிரதி செய்ய குறைந்தபட்சம் ஒரு செய்முறையாவது சேர்க்கவும்",
|
||||
"Added to Favourites": "பிடித்தவையில் சேர்க்கப்பட்டது",
|
||||
"Removed from Favourites": "பிடித்தவற்றிலிருந்து அகற்றப்பட்டது",
|
||||
"Added to Try Later": "பின்னர் முயற்சிக்க சேர்க்கப்பட்டது",
|
||||
"Removed from Try Later": "பின்னர் முயற்சிப்பதில் இருந்து நீக்கப்பட்டது",
|
||||
"Delete recipe?": "செய்முறையை நீக்கவா?",
|
||||
"DELETE": "நீக்கு",
|
||||
"Are you sure you want to delete the recipe": "இந்த செய்முறையை நீக்க விரும்புகிறீர்களா",
|
||||
"Search": "தேடு",
|
||||
"Rename category": "வகையை மறுபெயரிடுங்கள்",
|
||||
"Unsaved changes": "சேமிக்கப்படாத மாற்றங்கள்",
|
||||
"Are you sure you want to discard unsaved changes to this recipe?": "இந்த செய்முறையில் சேமிக்கப்படாத மாற்றங்களை நிராகரிக்க விரும்புகிறீர்களா?",
|
||||
"DISCARD": "நிராகரி",
|
||||
"KEEP EDITING": "தொடர்ந்து திருத்து",
|
||||
"Remove ingredient?": "பொருளை அகற்றவா?",
|
||||
"Remove instruction?": "செய்முறையை அகற்றவா?",
|
||||
"Remove combination?": "சேர்க்கையை அகற்றவா?",
|
||||
"Remove note?": "குறிப்பை அகற்றவா?",
|
||||
"New yield unit": "புதிய மகசூல் அலகு",
|
||||
"New category": "புதிய வகை",
|
||||
"Required": "தேவையான",
|
||||
"EnRecipes requires storage permission in order to set recipe photo.": "செய்முறை புகைப்படத்தை அமைக்க என்ரெசிபீஸ்க்கு சேமிப்பு அனுமதி தேவை.",
|
||||
"Recipe photo": "செய்முறை புகைப்படம்",
|
||||
"REPLACE PHOTO": "புகைப்படத்தை மாற்றவும்",
|
||||
"Crop photo": "படத்தை வெட்டு",
|
||||
"breakfast": "காலை உணவு",
|
||||
"lunch": "மதிய உணவு",
|
||||
"dinner": "இரவு உணவு",
|
||||
"snacks": "சிற்றிடை உணவு",
|
||||
"You tried this recipe:": "இந்த செய்முறையை முயற்சித்தீர்கள்:",
|
||||
"today": "இன்று",
|
||||
"yesterday": "நேற்று",
|
||||
"days ago": "நாட்களுக்கு முன்பு",
|
||||
"weeks ago": "வாரங்களுக்கு முன்பு",
|
||||
"months ago": "மாதங்களுக்கு முன்பு",
|
||||
"long time ago": "வெகுகாலத்திற்கு முன்பு",
|
||||
"Verifying...": "சரிபார்க்கிறது...",
|
||||
"Import successful": "வெற்றிகரமாக இறக்குமதி செய்யப்பட்டது",
|
||||
"Permission denied": "அனுமதி மறுக்கப்பட்டது",
|
||||
"Shared via EnRecipes. Get it on Play Store or F-Droid.": "என்ரெசிபீஸ் வழியாக பகிரப்பட்டது. அதை ப்ளே ஸ்டோர் அல்லது எஃப்-டிரயோடு இருந்து பெறுங்கள்."
|
||||
}
|
18
app/main.js
|
@ -1,3 +1,16 @@
|
|||
import {
|
||||
localize,
|
||||
androidLaunchEventLocalizationHandler
|
||||
} from '@nativescript/localize'
|
||||
import {
|
||||
on,
|
||||
launchEvent
|
||||
} from '@nativescript/core/application';
|
||||
on(launchEvent, (args) => {
|
||||
if (args.android) {
|
||||
androidLaunchEventLocalizationHandler();
|
||||
}
|
||||
})
|
||||
import Vue from "nativescript-vue"
|
||||
import App from "./components/App"
|
||||
import store from "./store"
|
||||
|
@ -26,7 +39,9 @@ Vue.use(CalendarView)
|
|||
import RadSideDrawer from "nativescript-ui-sidedrawer/vue"
|
||||
Vue.use(RadSideDrawer)
|
||||
|
||||
import { CheckBox } from "@nstudio/nativescript-checkbox"
|
||||
import {
|
||||
CheckBox
|
||||
} from "@nstudio/nativescript-checkbox"
|
||||
Vue.registerElement("CheckBox", () => CheckBox, {
|
||||
model: {
|
||||
prop: "checked",
|
||||
|
@ -35,6 +50,7 @@ Vue.registerElement("CheckBox", () => CheckBox, {
|
|||
})
|
||||
|
||||
Vue.config.silent = TNS_ENV === "production"
|
||||
Vue.filter('L', localize)
|
||||
|
||||
new Vue({
|
||||
store,
|
||||
|
|
|
@ -15,17 +15,22 @@
|
|||
|
||||
android {
|
||||
defaultConfig {
|
||||
versionCode 2
|
||||
versionName '1.0.1'
|
||||
versionCode 3
|
||||
versionName '1.1.2'
|
||||
applicationId 'com.vishnuraghav.enrecipes'
|
||||
minSdkVersion 21
|
||||
generatedDensities = []
|
||||
// ndk {
|
||||
// abiFilters.clear()
|
||||
// abiFilters.addAll(['x86','armeabi-v7a','arm64-v8a'])
|
||||
// }
|
||||
ndk {
|
||||
abiFilters.clear()
|
||||
abiFilters.addAll(['x86','armeabi-v7a','arm64-v8a'])
|
||||
}
|
||||
}
|
||||
aaptOptions {
|
||||
additionalParameters "--no-version-vectors"
|
||||
}
|
||||
// bundle {
|
||||
// language {
|
||||
// enableSplit = false
|
||||
// }
|
||||
// }
|
||||
}
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 687 B |
Before Width: | Height: | Size: 567 B After Width: | Height: | Size: 567 B |
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 197 B |
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 488 B |
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 229 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 198 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 161 B After Width: | Height: | Size: 161 B |
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 363 B |
Before Width: | Height: | Size: 626 B After Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 165 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 969 B After Width: | Height: | Size: 969 B |
Before Width: | Height: | Size: 434 B After Width: | Height: | Size: 434 B |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 797 B |
Before Width: | Height: | Size: 165 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 979 B After Width: | Height: | Size: 979 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 818 B |
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 1,020 B After Width: | Height: | Size: 1,020 B |
208
app/resources/Android/src/main/res/values-ta/strings.xml
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="_Shared_via_EnRecipes__Get_it_on_Play_Store_or_F_Droid__Z2oTOK1">"என்ரெசிபீஸ் வழியாக பகிரப்பட்டது. அதை ப்ளே ஸ்டோர் அல்லது எஃப்-டிரயோடு இருந்து பெறுங்கள்."</string>
|
||||
<string name="_Permission_denied_Z7wlWK">"அனுமதி மறுக்கப்பட்டது"</string>
|
||||
<string name="_Import_successful_2bLM3e">"வெற்றிகரமாக இறக்குமதி செய்யப்பட்டது"</string>
|
||||
<string name="_Verifying____cS102">"சரிபார்க்கிறது..."</string>
|
||||
<string name="_long_time_ago_1nwlFA">"வெகுகாலத்திற்கு முன்பு"</string>
|
||||
<string name="_months_ago_Z1TsskA">"மாதங்களுக்கு முன்பு"</string>
|
||||
<string name="_weeks_ago_Z2sT1GA">"வாரங்களுக்கு முன்பு"</string>
|
||||
<string name="_days_ago_2iCYkm">"நாட்களுக்கு முன்பு"</string>
|
||||
<string name="yesterday">"நேற்று"</string>
|
||||
<string name="today">"இன்று"</string>
|
||||
<string name="_You_tried_this_recipe__ZUJOl3">"இந்த செய்முறையை முயற்சித்தீர்கள்:"</string>
|
||||
<string name="snacks">"சிற்றிடை உணவு"</string>
|
||||
<string name="dinner">"இரவு உணவு"</string>
|
||||
<string name="lunch">"மதிய உணவு"</string>
|
||||
<string name="breakfast">"காலை உணவு"</string>
|
||||
<string name="_Crop_photo_1VL04J">"படத்தை வெட்டு"</string>
|
||||
<string name="_REPLACE_PHOTO_ZLHhwH">"புகைப்படத்தை மாற்றவும்"</string>
|
||||
<string name="_Recipe_photo_eqm9B">"செய்முறை புகைப்படம்"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_set_recipe_photo__23OnNT">"செய்முறை புகைப்படத்தை அமைக்க என்ரெசிபீஸ்க்கு சேமிப்பு அனுமதி தேவை."</string>
|
||||
<string name="Required">"தேவையான"</string>
|
||||
<string name="_New_category_Weg73">"புதிய வகை"</string>
|
||||
<string name="_New_yield_unit_1Oevd2">"புதிய மகசூல் அலகு"</string>
|
||||
<string name="_Remove_note__2wyMVE">"குறிப்பை அகற்றவா?"</string>
|
||||
<string name="_Remove_combination__1dr2LS">"சேர்க்கையை அகற்றவா?"</string>
|
||||
<string name="_Remove_instruction__vkJfi">"செய்முறையை அகற்றவா?"</string>
|
||||
<string name="_Remove_ingredient__2puvMO">"பொருளை அகற்றவா?"</string>
|
||||
<string name="_KEEP_EDITING_1o9uy3">"தொடர்ந்து திருத்து"</string>
|
||||
<string name="DISCARD">"நிராகரி"</string>
|
||||
<string name="_Are_you_sure_you_want_to_discard_unsaved_changes_to_this_recipe__Z1G7sVC">"இந்த செய்முறையில் சேமிக்கப்படாத மாற்றங்களை நிராகரிக்க விரும்புகிறீர்களா?"</string>
|
||||
<string name="_Unsaved_changes_9fqb4">"சேமிக்கப்படாத மாற்றங்கள்"</string>
|
||||
<string name="_Rename_category_Z1WzCco">"வகையை மறுபெயரிடுங்கள்"</string>
|
||||
<string name="Search">"தேடு"</string>
|
||||
<string name="_Are_you_sure_you_want_to_delete_the_recipe_29DH9w">"இந்த செய்முறையை நீக்க விரும்புகிறீர்களா"</string>
|
||||
<string name="DELETE">"நீக்கு"</string>
|
||||
<string name="_Delete_recipe__Z2tMYtE">"செய்முறையை நீக்கவா?"</string>
|
||||
<string name="_Removed_from_Try_Later_1h5Bkp">"பின்னர் முயற்சிப்பதில் இருந்து நீக்கப்பட்டது"</string>
|
||||
<string name="_Added_to_Try_Later_Z1gaF37">"பின்னர் முயற்சிக்க சேர்க்கப்பட்டது"</string>
|
||||
<string name="_Removed_from_Favourites_Z5k7LR">"பிடித்தவற்றிலிருந்து அகற்றப்பட்டது"</string>
|
||||
<string name="_Added_to_Favourites_2mzllO">"பிடித்தவையில் சேர்க்கப்பட்டது"</string>
|
||||
<string name="_Add_at_least_one_recipe_to_perform_a_backup_17xYaH">"காப்புப்பிரதி செய்ய குறைந்தபட்சம் ஒரு செய்முறையாவது சேர்க்கவும்"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_backup_your_data_to_this_device__2cbvIq">"இந்தச் சாதனத்தில் உங்கள் தரவை காப்புப் பிரதி எடுக்க என்ரெசிபீஸ்க்கு சேமிப்பக அனுமதி தேவைப்படுகிறது."</string>
|
||||
<string name="CONTINUE">"தொடர்"</string>
|
||||
<string name="_NOT_NOW_Z1HD7qX">"இப்போது இல்லை"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_import_your_data_from_a_previous_backup__1CKjb7">"முந்தைய காப்புப்பிரதியிலிருந்து உங்கள் தரவை இறக்குமதி செய்ய என்ரெசிபீஸ்க்கு சேமிப்பு அனுமதி தேவைப்படுகிறது."</string>
|
||||
<string name="_Grant_permission_Z1UQBuh">"அனுமதி வழங்கவும்"</string>
|
||||
<string name="_EnRecipes_needs_to_be_restarted_for_the_app_language_to_take_effect__ZWGUtY">"பயன்பாட்டு மொழி நடைமுறைக்கு வருவதற்கு என்ரெசிபீஸ் ஐ மீண்டும் தொடங்க வேண்டும்."</string>
|
||||
<string name="_EnRecipes_needs_to_be_restarted_for_the_theme_change_to_take_effect__2kU319">"தீம் மாற்றம் நடைமுறைக்கு வருவதற்கு என்ரெசிபீஸ் ஐ மீண்டும் தொடங்க வேண்டும்."</string>
|
||||
<string name="RESTART">"மறுதொடக்கம்"</string>
|
||||
<string name="_Restart_required_Z22YINL">"மறுதொடக்கம் தேவை"</string>
|
||||
<string name="SET">"அமை"</string>
|
||||
<string name="_ADD_NEW_Zv8FjM">"புதியனவற்றை சேர்"</string>
|
||||
<string name="Share">"பகிர்"</string>
|
||||
<string name="Overview">"கண்ணோட்டம்"</string>
|
||||
<string name="Recipe">"செய்முறை"</string>
|
||||
<string name="Photo">"புகைப்படம்"</string>
|
||||
<string name="min">"நிமிடம்"</string>
|
||||
<string name="hr">"மணி"</string>
|
||||
<string name="_My_Healthy_Recipe_Z1EqB8f">"எனது ஆரோக்கியமான செய்முறை"</string>
|
||||
<string name="_Nothing_here__Add_some_recipes_and_try_again__Z25A7Q">"இங்கு எதுவுமில்லை! சில சமையல் வகைகளைச் சேர்த்து மீண்டும் முயற்சிக்கவும்."</string>
|
||||
<string name="_Select_a_recipe_2lL8x2">"ஒரு செய்முறையைத் தேர்ந்தெடுக்கவும்"</string>
|
||||
<string name="ADD">"சேர்"</string>
|
||||
<string name="REMOVE">"அகற்று"</string>
|
||||
<string name="CANCEL">"ரத்துசெய்"</string>
|
||||
<string name="_Last_modified_Z1yBAS3">"கடைசியாக மாற்றப்பட்டது"</string>
|
||||
<string name="Duration">"நேரம்"</string>
|
||||
<string name="_Natural_order_Z1O8On5">"இயற்கை வரிசை"</string>
|
||||
<string name="_Sort_by_Zq01TF">"வரிசை விதி"</string>
|
||||
<string name="Step">"செயஂமுறை"</string>
|
||||
<string name="Item">"பொருள்"</string>
|
||||
<string name="_ADD_NOTE_ZyNw1r">"குறிப்பைச் சேர்"</string>
|
||||
<string name="Notes">"குறிப்புகள்"</string>
|
||||
<string name="Note">"குறிப்பு"</string>
|
||||
<string name="_ADD_COMBINATION_2q9HWq">"சேர்க்கையைச் சேர்"</string>
|
||||
<string name="Combinations">"சேர்க்கைகள்"</string>
|
||||
<string name="_ADD_STEP_ZyMPOe">"செய்முறையைச் சேர்"</string>
|
||||
<string name="Instructions">"செய்முறைகள்"</string>
|
||||
<string name="Instruction">"செய்முறை"</string>
|
||||
<string name="_ADD_INGREDIENT_29sSLU">"பொருளைச் சேர்"</string>
|
||||
<string name="Ingredients">"தேவையான பொருட்கள்"</string>
|
||||
<string name="Ingredient">"தேவையான பொருள்"</string>
|
||||
<string name="_Yield_measured_in_2OoRT">"மகசூல் அலகு"</string>
|
||||
<string name="_Yield_quantity_ZHx3jw">"மகசூல் அளவு"</string>
|
||||
<string name="_Cooking_time_2w2fEw">"சமைக்கும் நேரம்"</string>
|
||||
<string name="_Preparation_time_15BfxT">"தயாரிப்பு நேரம்"</string>
|
||||
<string name="Category">"வகை"</string>
|
||||
<string name="Title">"தலைப்பு"</string>
|
||||
<string name="_Edit_recipe_ZPvwDP">"செய்முறையைத் திருத்து"</string>
|
||||
<string name="_New_recipe_Z1Y2YKJ">"புதிய செய்முறை"</string>
|
||||
<string name="_Follow_on_Mastodon_Z1v6e4V">"மஸ்டோடனில் அவரைப் பின்தொடரவும்"</string>
|
||||
<string name="_Follow_on_GitHub_Z1GjptH">"கிட்ஹப்பில் அவரைப் பின்தொடரவும்"</string>
|
||||
<string name="_Vishnu_Raghav_B_1qnRnC">"விஷ்ணு ராகவ் .பா"</string>
|
||||
<string name="Author">"பயன்பாட்டு ஆசிரியர்"</string>
|
||||
<string name="_for_reporting_issues__suggestions_and_feedback_Z1JUmyE">"சிக்கல்கள், பரிந்துரைகள் மற்றும் கருத்துக்களைப் புகாரளிக்க"</string>
|
||||
<string name="_Join_the_Telegram_group_ZAXQgc">"டெலிகிராம் குழுவில் சேரவும்"</string>
|
||||
<string name="_View_project_on_GitHub_1hrJ0U">"கிட்ஹப்பில் திட்டத்தைக் காண்க"</string>
|
||||
<string name="Version">"பதிப்பு"</string>
|
||||
<string name="_Supports_full_backups_exported_by_this_app_ZYs4f2">"இந்த பயன்பாட்டின் மூலம் ஏற்றுமதி செய்யப்பட்ட முழு காப்புப்பிரதிகளை ஆதரிக்கும்"</string>
|
||||
<string name="_Import_from_backup_Z28HsC0">"காப்புப்பிரதியிலிருந்து இறக்குமதி செய்க"</string>
|
||||
<string name="_Generates_a_zip_file_that_contains_all_your_data__This_file_can_be_imported_back__Z19m3xY">"இது உங்கள் எல்லா தரவையும் கொண்ட ஒரு ஜிப் கோப்பை உருவாக்குகிறது. இந்த கோப்பை மீண்டும் இறக்குமதி செய்யலாம்."</string>
|
||||
<string name="_Export_a_full_backup_TJfra">"முழு காப்புப்பிரதியை ஏற்றுமதி செய்க"</string>
|
||||
<string name="Database">"தரவுத்தளம்"</string>
|
||||
<string name="Dark">"இருள்"</string>
|
||||
<string name="Light">"வெளிச்சம்"</string>
|
||||
<string name="Theme">"தீம்"</string>
|
||||
<string name="_System_default_Z1jruVS">"கணினி இயல்புநிலை"</string>
|
||||
<string name="_App_language_DzFsk">"பயன்பாட்டு மொழி"</string>
|
||||
<string name="Interface">"இடைமுகம்"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_your_try_later_list_Z2wWbA1">"உங்கள் தேடல் நீங்கள் முயற்சிக்க வேண்டிய பட்டியலில் உள்ள எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லைை"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_your_favourites_1ylvHN">"உங்கள் தேடல் உங்களுக்கு பிடித்தவற்றில் எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லைை"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_this_category_P7J4V">"உங்கள் தேடல் இந்த வகையில் எந்த சமையல் குறிப்புகளுடன் பொருந்தவில்லை"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_Z1eppHH">"உங்கள் தேடல் எந்த சமையல் குறிப்புகளுக்கும் பொருந்தவில்லை"</string>
|
||||
<string name="_No_recipes_found_Z125IxD">"எந்த சமையல் குறிப்புகளும் இல்லை"</string>
|
||||
<string name="_Category_looks_empty_ZAK5qU">"இந்த பிரிவில் எந்த சமையல் குறிப்புகளும் இல்லை"</string>
|
||||
<string name="_Recipes_you_mark_as_favourite_will_be_listed_here_Z1iIHgY">"நீங்கள் பிடித்ததாகக் குறிக்கும் சமையல் குறிப்புகள் இங்கே பட்டியலிடப்படும்"</string>
|
||||
<string name="_No_favourites_yet_aPSoG">"இன்னும் பிடித்தவை எதுவும் இல்லை"</string>
|
||||
<string name="_Recipes_you_mark_as_try_later_will_be_listed_here_Z1ITwPV">"முயற்சிக்க வேண்டும் என நீங்கள் குறிக்கும் சமையல் குறிப்புகள் இங்கே பட்டியலிடப்படும்"</string>
|
||||
<string name="_All_done__72KYl">"அனைத்தும் செய்யப்பட்டுள்ளன!"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_notes_Z1wyyeb">"சில குறிப்புகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_combinations_6NhFS">"சில சேர்க்கைகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_instructions_ZAi0PH">"செய்முறைகளைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_ingredients_Z1xOX8S">"தேவையான பொருட்களைச் சேர்க்க பென்சில் பொத்தானைப் பயன்படுத்தவும்"</string>
|
||||
<string name="_Use_the_plus_button_to_add_one_1h20ms">"ஒரு செய்முறையைச் சேர்க்க பிளஸ் பொத்தானைப் பயன்படுத்தவும்"</string>
|
||||
<string name="_Start_adding_your_recipes__rwnVV">"உங்கள் சமையல் குறிப்புகளைச் சேர்க்கத் தொடங்குங்கள்!"</string>
|
||||
<string name="large">"பெரிய"</string>
|
||||
<string name="medium">"நடுத்தர"</string>
|
||||
<string name="small">"சிறிய"</string>
|
||||
<string name="stick">"குச்சி"</string>
|
||||
<string name="dozen">"டஜன்"</string>
|
||||
<string name="drop">"துளி"</string>
|
||||
<string name="pinch">"கிள்ளு"</string>
|
||||
<string name="piece">"துண்டு"</string>
|
||||
<string name="clove">"பல்"</string>
|
||||
<string name="leaf">"இலை"</string>
|
||||
<string name="in">"அங்குலம்"</string>
|
||||
<string name="cm">"சென்டிமீட்டர்"</string>
|
||||
<string name="kg">"கிலோகிராம்"</string>
|
||||
<string name="g">"கிராம்"</string>
|
||||
<string name="mg">"மில்லிகிராம்"</string>
|
||||
<string name="lb">"பவுண்டு"</string>
|
||||
<string name="oz">"அவுன்ஸ்"</string>
|
||||
<string name="l">"லிட்டர்"</string>
|
||||
<string name="ml">"மில்லிலிட்டர்"</string>
|
||||
<string name="gal">"கேலன்"</string>
|
||||
<string name="qt">"குவிண்ட்"</string>
|
||||
<string name="pt">"பைண்ட்"</string>
|
||||
<string name="cup">"கோப்பை"</string>
|
||||
<string name="_fl_oz_72kqu">"திரவ அவுன்ஸ"</string>
|
||||
<string name="tbsp">"தேக்கரண்டி"</string>
|
||||
<string name="dsp">"இனிப்பு ஸ்பூன்"</string>
|
||||
<string name="tsp">"டீஸ்பூன்"</string>
|
||||
<string name="Unit">"அலகு"</string>
|
||||
<string name="unit">"அலகு"</string>
|
||||
<string name="Loaf">"ரொட்டித் துண்டு"</string>
|
||||
<string name="Patty">"வடை"</string>
|
||||
<string name="Roll">"ரோல்"</string>
|
||||
<string name="Litre">"லிட்டர்"</string>
|
||||
<string name="Millilitre">"மில்லிலிட்டர்"</string>
|
||||
<string name="Gallon">"கேலன்"</string>
|
||||
<string name="Cup">"கோப்பை"</string>
|
||||
<string name="Kilogram">"கிலோகிராம்"</string>
|
||||
<string name="Gram">"கிராம்"</string>
|
||||
<string name="Pound">"பவுண்டு"</string>
|
||||
<string name="Ounce">"அவுன்ஸ்"</string>
|
||||
<string name="_Fluid_Ounce_bd10L">"திரவ அவுன்ஸ்"</string>
|
||||
<string name="Tablespoon">"தேக்கரண்டி"</string>
|
||||
<string name="Teaspoon">"டீஸ்பூன்"</string>
|
||||
<string name="Piece">"துண்டு"</string>
|
||||
<string name="Serving">"கூறு"</string>
|
||||
<string name="Vegetarian">"சைவம்"</string>
|
||||
<string name="Vegan">"வேகன்"</string>
|
||||
<string name="Undefined">"வரையறுக்கப்படாதவை"</string>
|
||||
<string name="Soups">"சூப்கள்"</string>
|
||||
<string name="Snacks">"தின்பண்டங்கள்"</string>
|
||||
<string name="_Side_dishes_Z1Et4Vg">"தொடு கறிகள்"</string>
|
||||
<string name="Seafood">"கடல் உணவு"</string>
|
||||
<string name="Sauces">"சாஸ்கள்"</string>
|
||||
<string name="Salads">"சாலடுகள்"</string>
|
||||
<string name="Rice">"சோறு"</string>
|
||||
<string name="Poultry">"கோழி"</string>
|
||||
<string name="Pasta">"பாஸ்தா"</string>
|
||||
<string name="Noodles">"நூடுல்ஸ்"</string>
|
||||
<string name="Meat">"இறைச்சி"</string>
|
||||
<string name="_Main_dishes_u6RGQ">"முக்கிய உணவுகள்"</string>
|
||||
<string name="Lunch">"மதிய உணவு"</string>
|
||||
<string name="Healthy">"ஆரோக்கியமானவை"</string>
|
||||
<string name="Drinks">"மதுபானம்"</string>
|
||||
<string name="Dinner">"இரவு உணவு"</string>
|
||||
<string name="Desserts">"இனிப்புகள்"</string>
|
||||
<string name="Breakfast">"காலை உணவு"</string>
|
||||
<string name="Breads">"ரொட்டிகள்"</string>
|
||||
<string name="Beverages">"பானங்கள்"</string>
|
||||
<string name="Barbecue">"பார்பிக்யூ"</string>
|
||||
<string name="Appetizers">"பசித்தூண்டி"</string>
|
||||
<string name="About">"பற்றி"</string>
|
||||
<string name="Settings">"அமைப்புகள்"</string>
|
||||
<string name="RENAME">"மறுபெயரிடு"</string>
|
||||
<string name="DONE">"முடிந்தது"</string>
|
||||
<string name="Categories">"வகைகள்"</string>
|
||||
<string name="_Meal_Planner_2aq4oj">"உணவுத் திட்டம்"</string>
|
||||
<string name="Favourites">"பிடித்தவை"</string>
|
||||
<string name="_Try_Later_If7PG">"பின்னர் முயற்சிக்க"</string>
|
||||
<string name="EnRecipes">"என்ரெசிபீஸ்"</string>
|
||||
<string name="_app_name_1k3Sbz">"என்ரெசிபீஸ்"</string>
|
||||
<string name="app_name">"என்ரெசிபீஸ்"</string>
|
||||
<string name="title_activity_kimera">"என்ரெசிபீஸ்"</string>
|
||||
</resources>
|
208
app/resources/Android/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="_Shared_via_EnRecipes__Get_it_on_Play_Store_or_F_Droid__Z2oTOK1">"Shared via EnRecipes. Get it on Play Store or F-Droid."</string>
|
||||
<string name="_Permission_denied_Z7wlWK">"Permission denied"</string>
|
||||
<string name="_Import_successful_2bLM3e">"Import successful"</string>
|
||||
<string name="_Verifying____cS102">"Verifying..."</string>
|
||||
<string name="_long_time_ago_1nwlFA">"long time ago"</string>
|
||||
<string name="_months_ago_Z1TsskA">"months ago"</string>
|
||||
<string name="_weeks_ago_Z2sT1GA">"weeks ago"</string>
|
||||
<string name="_days_ago_2iCYkm">"days ago"</string>
|
||||
<string name="yesterday">"yesterday"</string>
|
||||
<string name="today">"today"</string>
|
||||
<string name="_You_tried_this_recipe__ZUJOl3">"You tried this recipe:"</string>
|
||||
<string name="snacks">"snacks"</string>
|
||||
<string name="dinner">"dinner"</string>
|
||||
<string name="lunch">"lunch"</string>
|
||||
<string name="breakfast">"breakfast"</string>
|
||||
<string name="_Crop_photo_1VL04J">"Crop photo"</string>
|
||||
<string name="_REPLACE_PHOTO_ZLHhwH">"REPLACE PHOTO"</string>
|
||||
<string name="_Recipe_photo_eqm9B">"Recipe photo"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_set_recipe_photo__23OnNT">"EnRecipes requires storage permission in order to set recipe photo."</string>
|
||||
<string name="Required">"Required"</string>
|
||||
<string name="_New_category_Weg73">"New category"</string>
|
||||
<string name="_New_yield_unit_1Oevd2">"New yield unit"</string>
|
||||
<string name="_Remove_note__2wyMVE">"Remove note?"</string>
|
||||
<string name="_Remove_combination__1dr2LS">"Remove combination?"</string>
|
||||
<string name="_Remove_instruction__vkJfi">"Remove instruction?"</string>
|
||||
<string name="_Remove_ingredient__2puvMO">"Remove ingredient?"</string>
|
||||
<string name="_KEEP_EDITING_1o9uy3">"KEEP EDITING"</string>
|
||||
<string name="DISCARD">"DISCARD"</string>
|
||||
<string name="_Are_you_sure_you_want_to_discard_unsaved_changes_to_this_recipe__Z1G7sVC">"Are you sure you want to discard unsaved changes to this recipe?"</string>
|
||||
<string name="_Unsaved_changes_9fqb4">"Unsaved changes"</string>
|
||||
<string name="_Rename_category_Z1WzCco">"Rename category"</string>
|
||||
<string name="Search">"Search"</string>
|
||||
<string name="_Are_you_sure_you_want_to_delete_the_recipe_29DH9w">"Are you sure you want to delete the recipe"</string>
|
||||
<string name="DELETE">"DELETE"</string>
|
||||
<string name="_Delete_recipe__Z2tMYtE">"Delete recipe?"</string>
|
||||
<string name="_Removed_from_Try_Later_1h5Bkp">"Removed from Try Later"</string>
|
||||
<string name="_Added_to_Try_Later_Z1gaF37">"Added to Try Later"</string>
|
||||
<string name="_Removed_from_Favourites_Z5k7LR">"Removed from Favourites"</string>
|
||||
<string name="_Added_to_Favourites_2mzllO">"Added to Favourites"</string>
|
||||
<string name="_Add_at_least_one_recipe_to_perform_a_backup_17xYaH">"Add at least one recipe to perform a backup"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_backup_your_data_to_this_device__2cbvIq">"EnRecipes requires storage permission in order to backup your data to this device."</string>
|
||||
<string name="CONTINUE">"CONTINUE"</string>
|
||||
<string name="_NOT_NOW_Z1HD7qX">"NOT NOW"</string>
|
||||
<string name="_EnRecipes_requires_storage_permission_in_order_to_import_your_data_from_a_previous_backup__1CKjb7">"EnRecipes requires storage permission in order to import your data from a previous backup."</string>
|
||||
<string name="_Grant_permission_Z1UQBuh">"Grant permission"</string>
|
||||
<string name="_EnRecipes_needs_to_be_restarted_for_the_app_language_to_take_effect__ZWGUtY">"EnRecipes needs to be restarted for the app language to take effect."</string>
|
||||
<string name="_EnRecipes_needs_to_be_restarted_for_the_theme_change_to_take_effect__2kU319">"EnRecipes needs to be restarted for the theme change to take effect."</string>
|
||||
<string name="RESTART">"RESTART"</string>
|
||||
<string name="_Restart_required_Z22YINL">"Restart required"</string>
|
||||
<string name="SET">"SET"</string>
|
||||
<string name="_ADD_NEW_Zv8FjM">"ADD NEW"</string>
|
||||
<string name="Share">"Share"</string>
|
||||
<string name="Overview">"Overview"</string>
|
||||
<string name="Recipe">"Recipe"</string>
|
||||
<string name="Photo">"Photo"</string>
|
||||
<string name="min">"min"</string>
|
||||
<string name="hr">"hr"</string>
|
||||
<string name="_My_Healthy_Recipe_Z1EqB8f">"My Healthy Recipe"</string>
|
||||
<string name="_Nothing_here__Add_some_recipes_and_try_again__Z25A7Q">"Nothing here! Add some recipes and try again."</string>
|
||||
<string name="_Select_a_recipe_2lL8x2">"Select a recipe"</string>
|
||||
<string name="ADD">"ADD"</string>
|
||||
<string name="REMOVE">"REMOVE"</string>
|
||||
<string name="CANCEL">"CANCEL"</string>
|
||||
<string name="_Last_modified_Z1yBAS3">"Last modified"</string>
|
||||
<string name="Duration">"Duration"</string>
|
||||
<string name="_Natural_order_Z1O8On5">"Natural order"</string>
|
||||
<string name="_Sort_by_Zq01TF">"Sort by"</string>
|
||||
<string name="Step">"Step"</string>
|
||||
<string name="Item">"Item"</string>
|
||||
<string name="_ADD_NOTE_ZyNw1r">"ADD NOTE"</string>
|
||||
<string name="Notes">"Notes"</string>
|
||||
<string name="Note">"Note"</string>
|
||||
<string name="_ADD_COMBINATION_2q9HWq">"ADD COMBINATION"</string>
|
||||
<string name="Combinations">"Combinations"</string>
|
||||
<string name="_ADD_STEP_ZyMPOe">"ADD STEP"</string>
|
||||
<string name="Instructions">"Instructions"</string>
|
||||
<string name="Instruction">"Instruction"</string>
|
||||
<string name="_ADD_INGREDIENT_29sSLU">"ADD INGREDIENT"</string>
|
||||
<string name="Ingredients">"Ingredients"</string>
|
||||
<string name="Ingredient">"Ingredient"</string>
|
||||
<string name="_Yield_measured_in_2OoRT">"Yield measured in"</string>
|
||||
<string name="_Yield_quantity_ZHx3jw">"Yield quantity"</string>
|
||||
<string name="_Cooking_time_2w2fEw">"Cooking time"</string>
|
||||
<string name="_Preparation_time_15BfxT">"Preparation time"</string>
|
||||
<string name="Category">"Category"</string>
|
||||
<string name="Title">"Title"</string>
|
||||
<string name="_Edit_recipe_ZPvwDP">"Edit recipe"</string>
|
||||
<string name="_New_recipe_Z1Y2YKJ">"New recipe"</string>
|
||||
<string name="_Follow_on_Mastodon_Z1v6e4V">"Follow on Mastodon"</string>
|
||||
<string name="_Follow_on_GitHub_Z1GjptH">"Follow on GitHub"</string>
|
||||
<string name="_Vishnu_Raghav_B_1qnRnC">"Vishnu Raghav B"</string>
|
||||
<string name="Author">"Author"</string>
|
||||
<string name="_for_reporting_issues__suggestions_and_feedback_Z1JUmyE">"for reporting issues, suggestions and feedback"</string>
|
||||
<string name="_Join_the_Telegram_group_ZAXQgc">"Join the Telegram group"</string>
|
||||
<string name="_View_project_on_GitHub_1hrJ0U">"View project on GitHub"</string>
|
||||
<string name="Version">"Version"</string>
|
||||
<string name="_Supports_full_backups_exported_by_this_app_ZYs4f2">"Supports full backups exported by this app"</string>
|
||||
<string name="_Import_from_backup_Z28HsC0">"Import from backup"</string>
|
||||
<string name="_Generates_a_zip_file_that_contains_all_your_data__This_file_can_be_imported_back__Z19m3xY">"Generates a zip file that contains all your data. This file can be imported back."</string>
|
||||
<string name="_Export_a_full_backup_TJfra">"Export a full backup"</string>
|
||||
<string name="Database">"Database"</string>
|
||||
<string name="Dark">"Dark"</string>
|
||||
<string name="Light">"Light"</string>
|
||||
<string name="Theme">"Theme"</string>
|
||||
<string name="_System_default_Z1jruVS">"System default"</string>
|
||||
<string name="_App_language_DzFsk">"App language"</string>
|
||||
<string name="Interface">"Interface"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_your_try_later_list_Z2wWbA1">"Your search did not match any recipes in your try later list"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_your_favourites_1ylvHN">"Your search did not match any recipes in your favourites"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_in_this_category_P7J4V">"Your search did not match any recipes in this category"</string>
|
||||
<string name="_Your_search_did_not_match_any_recipes_Z1eppHH">"Your search did not match any recipes"</string>
|
||||
<string name="_No_recipes_found_Z125IxD">"No recipes found"</string>
|
||||
<string name="_Category_looks_empty_ZAK5qU">"Category looks empty"</string>
|
||||
<string name="_Recipes_you_mark_as_favourite_will_be_listed_here_Z1iIHgY">"Recipes you mark as favourite will be listed here"</string>
|
||||
<string name="_No_favourites_yet_aPSoG">"No favourites yet"</string>
|
||||
<string name="_Recipes_you_mark_as_try_later_will_be_listed_here_Z1ITwPV">"Recipes you mark as try later will be listed here"</string>
|
||||
<string name="_All_done__72KYl">"All done!"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_notes_Z1wyyeb">"Use the pencil button to add some notes"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_combinations_6NhFS">"Use the pencil button to add some combinations"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_instructions_ZAi0PH">"Use the pencil button to add some instructions"</string>
|
||||
<string name="_Use_the_pencil_button_to_add_some_ingredients_Z1xOX8S">"Use the pencil button to add some ingredients"</string>
|
||||
<string name="_Use_the_plus_button_to_add_one_1h20ms">"Use the plus button to add one"</string>
|
||||
<string name="_Start_adding_your_recipes__rwnVV">"Start adding your recipes!"</string>
|
||||
<string name="large">"large"</string>
|
||||
<string name="medium">"medium"</string>
|
||||
<string name="small">"small"</string>
|
||||
<string name="stick">"stick"</string>
|
||||
<string name="dozen">"dozen"</string>
|
||||
<string name="drop">"drop"</string>
|
||||
<string name="pinch">"pinch"</string>
|
||||
<string name="piece">"piece"</string>
|
||||
<string name="clove">"clove"</string>
|
||||
<string name="leaf">"leaf"</string>
|
||||
<string name="in">"in"</string>
|
||||
<string name="cm">"cm"</string>
|
||||
<string name="kg">"kg"</string>
|
||||
<string name="g">"g"</string>
|
||||
<string name="mg">"mg"</string>
|
||||
<string name="lb">"lb"</string>
|
||||
<string name="oz">"oz"</string>
|
||||
<string name="l">"l"</string>
|
||||
<string name="ml">"ml"</string>
|
||||
<string name="gal">"gal"</string>
|
||||
<string name="qt">"qt"</string>
|
||||
<string name="pt">"pt"</string>
|
||||
<string name="cup">"cup"</string>
|
||||
<string name="_fl_oz_72kqu">"fl oz"</string>
|
||||
<string name="tbsp">"tbsp"</string>
|
||||
<string name="dsp">"dsp"</string>
|
||||
<string name="tsp">"tsp"</string>
|
||||
<string name="Unit">"Unit"</string>
|
||||
<string name="unit">"unit"</string>
|
||||
<string name="Loaf">"Loaf"</string>
|
||||
<string name="Patty">"Patty"</string>
|
||||
<string name="Roll">"Roll"</string>
|
||||
<string name="Litre">"Litre"</string>
|
||||
<string name="Millilitre">"Millilitre"</string>
|
||||
<string name="Gallon">"Gallon"</string>
|
||||
<string name="Cup">"Cup"</string>
|
||||
<string name="Kilogram">"Kilogram"</string>
|
||||
<string name="Gram">"Gram"</string>
|
||||
<string name="Pound">"Pound"</string>
|
||||
<string name="Ounce">"Ounce"</string>
|
||||
<string name="_Fluid_Ounce_bd10L">"Fluid Ounce"</string>
|
||||
<string name="Tablespoon">"Tablespoon"</string>
|
||||
<string name="Teaspoon">"Teaspoon"</string>
|
||||
<string name="Piece">"Piece"</string>
|
||||
<string name="Serving">"Serving"</string>
|
||||
<string name="Vegetarian">"Vegetarian"</string>
|
||||
<string name="Vegan">"Vegan"</string>
|
||||
<string name="Undefined">"Undefined"</string>
|
||||
<string name="Soups">"Soups"</string>
|
||||
<string name="Snacks">"Snacks"</string>
|
||||
<string name="_Side_dishes_Z1Et4Vg">"Side dishes"</string>
|
||||
<string name="Seafood">"Seafood"</string>
|
||||
<string name="Sauces">"Sauces"</string>
|
||||
<string name="Salads">"Salads"</string>
|
||||
<string name="Rice">"Rice"</string>
|
||||
<string name="Poultry">"Poultry"</string>
|
||||
<string name="Pasta">"Pasta"</string>
|
||||
<string name="Noodles">"Noodles"</string>
|
||||
<string name="Meat">"Meat"</string>
|
||||
<string name="_Main_dishes_u6RGQ">"Main dishes"</string>
|
||||
<string name="Lunch">"Lunch"</string>
|
||||
<string name="Healthy">"Healthy"</string>
|
||||
<string name="Drinks">"Drinks"</string>
|
||||
<string name="Dinner">"Dinner"</string>
|
||||
<string name="Desserts">"Desserts"</string>
|
||||
<string name="Breakfast">"Breakfast"</string>
|
||||
<string name="Breads">"Breads"</string>
|
||||
<string name="Beverages">"Beverages"</string>
|
||||
<string name="Barbecue">"Barbecue"</string>
|
||||
<string name="Appetizers">"Appetizers"</string>
|
||||
<string name="About">"About"</string>
|
||||
<string name="Settings">"Settings"</string>
|
||||
<string name="RENAME">"RENAME"</string>
|
||||
<string name="DONE">"DONE"</string>
|
||||
<string name="Categories">"Categories"</string>
|
||||
<string name="_Meal_Planner_2aq4oj">"Meal Planner"</string>
|
||||
<string name="Favourites">"Favourites"</string>
|
||||
<string name="_Try_Later_If7PG">"Try Later"</string>
|
||||
<string name="EnRecipes">"EnRecipes"</string>
|
||||
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
|
||||
<string name="app_name">"EnRecipes"</string>
|
||||
<string name="title_activity_kimera">"EnRecipes"</string>
|
||||
</resources>
|
201
app/store.js
|
@ -1,7 +1,11 @@
|
|||
import Vue from "vue"
|
||||
import Vuex from "vuex"
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
import { getFileAccess } from "@nativescript/core"
|
||||
import {
|
||||
Couchbase
|
||||
} from "nativescript-couchbase-plugin"
|
||||
import {
|
||||
getFileAccess
|
||||
} from "@nativescript/core"
|
||||
const EnRecipesDB = new Couchbase("EnRecipes")
|
||||
const userCategoriesDB = new Couchbase("userCategories")
|
||||
const userYieldUnitsDB = new Couchbase("userYieldUnits")
|
||||
|
@ -11,7 +15,7 @@ Vue.use(Vuex)
|
|||
|
||||
const defaultCategories = [
|
||||
"Appetizers",
|
||||
"BBQ",
|
||||
"Barbecue",
|
||||
"Beverages",
|
||||
"Breads",
|
||||
"Breakfast",
|
||||
|
@ -81,6 +85,7 @@ export default new Vuex.Store({
|
|||
"in",
|
||||
"leaf",
|
||||
"clove",
|
||||
"piece",
|
||||
"pinch",
|
||||
"drop",
|
||||
"dozen",
|
||||
|
@ -135,17 +140,29 @@ export default new Vuex.Store({
|
|||
outline: "\ueb07",
|
||||
calendar: "\uec55",
|
||||
today: "\ue97c",
|
||||
globe: "\uea5a",
|
||||
},
|
||||
currentComponent: "EnRecipes",
|
||||
language: [{
|
||||
locale: 'en',
|
||||
title: 'English'
|
||||
}, {
|
||||
locale: 'ta',
|
||||
title: 'தமிழ்'
|
||||
}, ]
|
||||
},
|
||||
mutations: {
|
||||
initializeRecipes(state) {
|
||||
EnRecipesDB.query({ select: [] }).forEach((recipe) => {
|
||||
EnRecipesDB.query({
|
||||
select: []
|
||||
}).forEach((recipe) => {
|
||||
state.recipes.push(recipe)
|
||||
})
|
||||
},
|
||||
initializeCategories(state) {
|
||||
let isCategoriesStored = userCategoriesDB.query({ select: [] }).length
|
||||
let isCategoriesStored = userCategoriesDB.query({
|
||||
select: []
|
||||
}).length
|
||||
if (isCategoriesStored) {
|
||||
state.userCategories = userCategoriesDB.getDocument(
|
||||
"userCategories"
|
||||
|
@ -155,8 +172,9 @@ export default new Vuex.Store({
|
|||
categoriesWithRecipes.includes(e)
|
||||
)
|
||||
} else {
|
||||
userCategoriesDB.createDocument(
|
||||
{ userCategories: [] },
|
||||
userCategoriesDB.createDocument({
|
||||
userCategories: []
|
||||
},
|
||||
"userCategories"
|
||||
)
|
||||
}
|
||||
|
@ -164,7 +182,9 @@ export default new Vuex.Store({
|
|||
state.categories.sort()
|
||||
},
|
||||
initializeYieldUnits(state) {
|
||||
let isYieldUnitsStored = userYieldUnitsDB.query({ select: [] }).length
|
||||
let isYieldUnitsStored = userYieldUnitsDB.query({
|
||||
select: []
|
||||
}).length
|
||||
if (isYieldUnitsStored) {
|
||||
state.userYieldUnits = userYieldUnitsDB.getDocument(
|
||||
"userYieldUnits"
|
||||
|
@ -174,19 +194,24 @@ export default new Vuex.Store({
|
|||
yieldUnitsWithRecipes.includes(e)
|
||||
)
|
||||
} else {
|
||||
userYieldUnitsDB.createDocument(
|
||||
{ userYieldUnits: [] },
|
||||
userYieldUnitsDB.createDocument({
|
||||
userYieldUnits: []
|
||||
},
|
||||
"userYieldUnits"
|
||||
)
|
||||
}
|
||||
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
|
||||
},
|
||||
initializeMealPlans(state) {
|
||||
let isMealPlansDBStored = mealPlansDB.query({ select: [] }).length
|
||||
let isMealPlansDBStored = mealPlansDB.query({
|
||||
select: []
|
||||
}).length
|
||||
if (isMealPlansDBStored) {
|
||||
state.mealPlans = mealPlansDB.getDocument("mealPlans").mealPlans
|
||||
} else {
|
||||
mealPlansDB.createDocument({ mealPlans: [] }, "mealPlans")
|
||||
mealPlansDB.createDocument({
|
||||
mealPlans: []
|
||||
}, "mealPlans")
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -196,18 +221,23 @@ export default new Vuex.Store({
|
|||
localRecipesIDs = state.recipes.map((e) => e.id)
|
||||
partition = recipes.reduce(
|
||||
(result, recipe, i) => {
|
||||
localRecipesIDs.indexOf(recipe.id) < 0
|
||||
? result[0].push(recipe) // create candidates
|
||||
: result[1].push(recipe) // update candidates
|
||||
localRecipesIDs.indexOf(recipe.id) < 0 ?
|
||||
result[0].push(recipe) // create candidates
|
||||
:
|
||||
result[1].push(recipe) // update candidates
|
||||
return result
|
||||
},
|
||||
[[], []]
|
||||
[
|
||||
[],
|
||||
[]
|
||||
]
|
||||
)
|
||||
if (partition[0].length) createDocuments(partition[0])
|
||||
if (partition[1].length) updateDocuments(partition[1])
|
||||
} else {
|
||||
createDocuments(recipes)
|
||||
}
|
||||
|
||||
function getUpdatedData(data) {
|
||||
return data.map((recipe) => {
|
||||
let r = Object.assign({}, recipe)
|
||||
|
@ -219,6 +249,7 @@ export default new Vuex.Store({
|
|||
return r
|
||||
})
|
||||
}
|
||||
|
||||
function createDocuments(data) {
|
||||
data = getUpdatedData(data)
|
||||
state.recipes = [...state.recipes, ...data]
|
||||
|
@ -226,6 +257,7 @@ export default new Vuex.Store({
|
|||
EnRecipesDB.createDocument(recipe, recipe.id)
|
||||
})
|
||||
}
|
||||
|
||||
function updateDocuments(data) {
|
||||
data = getUpdatedData(data)
|
||||
data.forEach((recipe) => {
|
||||
|
@ -261,9 +293,9 @@ export default new Vuex.Store({
|
|||
importMealPlans(state, mealPlans) {
|
||||
let newMealPlans = mealPlans.filter(
|
||||
(e) =>
|
||||
!state.mealPlans.some(
|
||||
(f) => f.title === e.title && f.startDate === e.startDate
|
||||
)
|
||||
!state.mealPlans.some(
|
||||
(f) => f.title === e.title && f.startDate === e.startDate
|
||||
)
|
||||
)
|
||||
state.mealPlans = [...state.mealPlans, ...newMealPlans]
|
||||
mealPlansDB.updateDocument("mealPlans", {
|
||||
|
@ -271,7 +303,10 @@ export default new Vuex.Store({
|
|||
})
|
||||
},
|
||||
|
||||
addRecipe(state, { id, recipe }) {
|
||||
addRecipe(state, {
|
||||
id,
|
||||
recipe
|
||||
}) {
|
||||
state.recipes.push(recipe)
|
||||
EnRecipesDB.createDocument(recipe, id)
|
||||
},
|
||||
|
@ -296,7 +331,10 @@ export default new Vuex.Store({
|
|||
state.yieldUnits = [...defaultYieldUnits, ...state.userYieldUnits]
|
||||
}
|
||||
},
|
||||
addMealPlan(state, { event, eventColor }) {
|
||||
addMealPlan(state, {
|
||||
event,
|
||||
eventColor
|
||||
}) {
|
||||
state.mealPlans.push({
|
||||
title: event.title,
|
||||
startDate: event.startDate,
|
||||
|
@ -308,7 +346,10 @@ export default new Vuex.Store({
|
|||
})
|
||||
},
|
||||
|
||||
deleteRecipe(state, { index, id }) {
|
||||
deleteRecipe(state, {
|
||||
index,
|
||||
id
|
||||
}) {
|
||||
getFileAccess().deleteFile(state.recipes[index].imageSrc)
|
||||
state.recipes.splice(index, 1)
|
||||
EnRecipesDB.deleteDocument(id)
|
||||
|
@ -319,7 +360,10 @@ export default new Vuex.Store({
|
|||
}
|
||||
})
|
||||
},
|
||||
deleteMealPlan(state, { title, startDate }) {
|
||||
deleteMealPlan(state, {
|
||||
title,
|
||||
startDate
|
||||
}) {
|
||||
let mealPlan = state.mealPlans.filter((e) => {
|
||||
console.log(e.startDate, startDate)
|
||||
let sd = new Date(e.startDate).getTime()
|
||||
|
@ -335,14 +379,22 @@ export default new Vuex.Store({
|
|||
})
|
||||
},
|
||||
|
||||
overwriteRecipe(state, { id, recipe }) {
|
||||
overwriteRecipe(state, {
|
||||
id,
|
||||
recipe
|
||||
}) {
|
||||
let index = state.recipes.indexOf(
|
||||
state.recipes.filter((e) => e.id === id)[0]
|
||||
)
|
||||
Object.assign(state.recipes[index], recipe)
|
||||
EnRecipesDB.updateDocument(id, recipe)
|
||||
},
|
||||
toggleState(state, { id, recipe, key, setDate }) {
|
||||
toggleState(state, {
|
||||
id,
|
||||
recipe,
|
||||
key,
|
||||
setDate
|
||||
}) {
|
||||
let index = state.recipes.indexOf(
|
||||
state.recipes.filter((e) => e.id === id)[0]
|
||||
)
|
||||
|
@ -350,7 +402,10 @@ export default new Vuex.Store({
|
|||
if (setDate) state.recipes[index].lastTried = new Date()
|
||||
EnRecipesDB.updateDocument(id, recipe)
|
||||
},
|
||||
setRecipeAsTried(state, { id, recipe }) {
|
||||
setRecipeAsTried(state, {
|
||||
id,
|
||||
recipe
|
||||
}) {
|
||||
let index = state.recipes.indexOf(
|
||||
state.recipes.filter((e) => e.id === id)[0]
|
||||
)
|
||||
|
@ -362,7 +417,10 @@ export default new Vuex.Store({
|
|||
state.recipes[index].lastTried = new Date()
|
||||
EnRecipesDB.updateDocument(state.recipes[index].id, state.recipes[index])
|
||||
},
|
||||
renameCategory(state, { current, updated }) {
|
||||
renameCategory(state, {
|
||||
current,
|
||||
updated
|
||||
}) {
|
||||
let lowercase = state.categories.map((e) => e.toLowerCase())
|
||||
if (lowercase.indexOf(updated.toLowerCase()) == -1) {
|
||||
state.userCategories.push(updated)
|
||||
|
@ -384,7 +442,10 @@ export default new Vuex.Store({
|
|||
setCurrentComponent(state, comp) {
|
||||
state.currentComponent = comp
|
||||
},
|
||||
unSyncCombinations(state, { id, combinations }) {
|
||||
unSyncCombinations(state, {
|
||||
id,
|
||||
combinations
|
||||
}) {
|
||||
state.recipes.forEach((e, i) => {
|
||||
if (combinations.includes(e.id)) {
|
||||
state.recipes[i].combinations.splice(e.combinations.indexOf(id), 1)
|
||||
|
@ -394,71 +455,113 @@ export default new Vuex.Store({
|
|||
},
|
||||
},
|
||||
actions: {
|
||||
initializeRecipes({ commit }) {
|
||||
initializeRecipes({
|
||||
commit
|
||||
}) {
|
||||
commit("initializeRecipes")
|
||||
},
|
||||
initializeCategories({ commit }) {
|
||||
initializeCategories({
|
||||
commit
|
||||
}) {
|
||||
commit("initializeCategories")
|
||||
},
|
||||
initializeYieldUnits({ commit }) {
|
||||
initializeYieldUnits({
|
||||
commit
|
||||
}) {
|
||||
commit("initializeYieldUnits")
|
||||
},
|
||||
initializeMealPlans({ commit }) {
|
||||
initializeMealPlans({
|
||||
commit
|
||||
}) {
|
||||
commit("initializeMealPlans")
|
||||
},
|
||||
|
||||
importRecipesAction({ commit }, recipes) {
|
||||
importRecipesAction({
|
||||
commit
|
||||
}, recipes) {
|
||||
commit("importRecipes", recipes)
|
||||
},
|
||||
importCategoriesAction({ commit }, categories) {
|
||||
importCategoriesAction({
|
||||
commit
|
||||
}, categories) {
|
||||
commit("importCategories", categories)
|
||||
},
|
||||
importYieldUnitsAction({ commit }, yieldUnits) {
|
||||
importYieldUnitsAction({
|
||||
commit
|
||||
}, yieldUnits) {
|
||||
commit("importYieldUnits", yieldUnits)
|
||||
},
|
||||
importMealPlansAction({ commit }, mealPlans) {
|
||||
importMealPlansAction({
|
||||
commit
|
||||
}, mealPlans) {
|
||||
commit("importMealPlans", mealPlans)
|
||||
},
|
||||
|
||||
addRecipeAction({ commit }, recipe) {
|
||||
addRecipeAction({
|
||||
commit
|
||||
}, recipe) {
|
||||
commit("addRecipe", recipe)
|
||||
},
|
||||
addYieldUnitAction({ commit }, yieldUnit) {
|
||||
addYieldUnitAction({
|
||||
commit
|
||||
}, yieldUnit) {
|
||||
commit("addYieldUnit", yieldUnit)
|
||||
},
|
||||
addCategoryAction({ commit }, category) {
|
||||
addCategoryAction({
|
||||
commit
|
||||
}, category) {
|
||||
commit("addCategory", category)
|
||||
},
|
||||
addMealPlanAction({ commit }, mealPlan) {
|
||||
addMealPlanAction({
|
||||
commit
|
||||
}, mealPlan) {
|
||||
commit("addMealPlan", mealPlan)
|
||||
},
|
||||
|
||||
deleteMealPlanAction({ commit }, mealPlan) {
|
||||
deleteMealPlanAction({
|
||||
commit
|
||||
}, mealPlan) {
|
||||
commit("deleteMealPlan", mealPlan)
|
||||
},
|
||||
deleteRecipeAction({ commit }, recipe) {
|
||||
deleteRecipeAction({
|
||||
commit
|
||||
}, recipe) {
|
||||
commit("deleteRecipe", recipe)
|
||||
},
|
||||
|
||||
overwriteRecipeAction({ commit }, updatedRecipe) {
|
||||
overwriteRecipeAction({
|
||||
commit
|
||||
}, updatedRecipe) {
|
||||
commit("overwriteRecipe", updatedRecipe)
|
||||
},
|
||||
toggleStateAction({ commit }, toggledRecipe) {
|
||||
toggleStateAction({
|
||||
commit
|
||||
}, toggledRecipe) {
|
||||
commit("toggleState", toggledRecipe)
|
||||
},
|
||||
setRecipeAsTriedAction({ commit }, recipe) {
|
||||
setRecipeAsTriedAction({
|
||||
commit
|
||||
}, recipe) {
|
||||
commit("setRecipeAsTried", recipe)
|
||||
},
|
||||
setLastTriedDateAction({ commit }, index) {
|
||||
setLastTriedDateAction({
|
||||
commit
|
||||
}, index) {
|
||||
commit("setLastTriedDate", index)
|
||||
},
|
||||
renameCategoryAction({ commit }, category) {
|
||||
renameCategoryAction({
|
||||
commit
|
||||
}, category) {
|
||||
commit("renameCategory", category)
|
||||
},
|
||||
setCurrentComponentAction({ commit }, comp) {
|
||||
setCurrentComponentAction({
|
||||
commit
|
||||
}, comp) {
|
||||
commit("setCurrentComponent", comp)
|
||||
},
|
||||
unSyncCombinationsAction({ commit }, combinations) {
|
||||
unSyncCombinationsAction({
|
||||
commit
|
||||
}, combinations) {
|
||||
commit("unSyncCombinations", combinations)
|
||||
},
|
||||
},
|
||||
|
|
5
fastlane/metadata/android/en-US/changelogs/3.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
- Fixed several bugs causing app crashes
|
||||
- Minor UI improvements
|
||||
- Application language support
|
||||
- Added Tamil
|
||||
- More languages coming soon!
|
|
@ -5,9 +5,9 @@ EnRecipes is an easy to use, privacy-friendly digital cookbook that lets you cre
|
|||
▸ Add photo, notes and combinations to your recipes
|
||||
▸ Organise your recipes by category
|
||||
▸ Quickly search for your recipes
|
||||
▸ Mark recipes as favorites and add them to your Try Later list
|
||||
▸ Mark recipes as favourites and add them to your Try Later list
|
||||
▸ Scale your recipe ingredients to serve more or less people
|
||||
▸ Get notified of the last time you tried a recipe
|
||||
▸ Get notified of when you last tried a recipe
|
||||
▸ Share your recipe to anyone by any means as a nicely formatted message. You can share the recipe photo too.
|
||||
▸ Create meal plans
|
||||
▸ Import/Export recipes
|
||||
|
@ -16,7 +16,5 @@ EnRecipes is an easy to use, privacy-friendly digital cookbook that lets you cre
|
|||
▸ No internet access is required and never asks for any unwanted permissions
|
||||
▸ 100% free and open-source
|
||||
|
||||
Lots of interesting features on the way...
|
||||
|
||||
<b>Credits</b>
|
||||
This app was written in my free time using NativeScript. I would like to thank all those people who helped me understand the concepts during the process and my special thanks to the NativeScript team and the community.
|
||||
|
|
1
hooks/before-checkForChanges/nativescript-localize.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require("@nativescript/localize/hooks/before-checkForChanges.js");
|
1
hooks/before-watchPatterns/nativescript-localize.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require("@nativescript/localize/hooks/before-watchPatterns.js");
|
|
@ -2,7 +2,7 @@ import { NativeScriptConfig } from "@nativescript/core"
|
|||
|
||||
export default {
|
||||
id: "com.vishnuraghav.enrecipes",
|
||||
appResourcesPath: "app/App_Resources",
|
||||
appResourcesPath: "app/resources",
|
||||
android: {
|
||||
v8Flags: "--expose_gc",
|
||||
markingMode: "none",
|
||||
|
|
80
package-lock.json
generated
|
@ -1131,6 +1131,17 @@
|
|||
"mkdirp": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"@nativescript/localize": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript/localize/-/localize-5.0.2.tgz",
|
||||
"integrity": "sha512-TokwtXhb3oROr3ST0vCsuDHkTl+pi2caNEkTZNTlXXt5lBd4qyLpooo6ua0O7rVZ6VDcFD9rmJU0sPyNJCMvcw==",
|
||||
"requires": {
|
||||
"mkdirp": "^1.0.4",
|
||||
"shorthash": "0.0.2",
|
||||
"simple-plist": "^1.1.0",
|
||||
"sprintf-js": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"@nativescript/social-share": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript/social-share/-/social-share-2.0.1.tgz",
|
||||
|
@ -2032,8 +2043,7 @@
|
|||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
|
@ -2056,6 +2066,11 @@
|
|||
"tryer": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
|
@ -2135,6 +2150,22 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"bplist-creator": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz",
|
||||
"integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==",
|
||||
"requires": {
|
||||
"stream-buffers": "~2.2.0"
|
||||
}
|
||||
},
|
||||
"bplist-parser": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
|
||||
"integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.44"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
|
@ -6220,6 +6251,16 @@
|
|||
"find-up": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"plist": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
|
||||
"integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.2.3",
|
||||
"xmlbuilder": "^9.0.7",
|
||||
"xmldom": "0.1.x"
|
||||
}
|
||||
},
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
|
||||
|
@ -7333,12 +7374,27 @@
|
|||
"rechoir": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"shorthash": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/shorthash/-/shorthash-0.0.2.tgz",
|
||||
"integrity": "sha1-WbJo7sveWQOLMNogK8+93rLEpOs="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||
"dev": true
|
||||
},
|
||||
"simple-plist": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.1.1.tgz",
|
||||
"integrity": "sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg==",
|
||||
"requires": {
|
||||
"bplist-creator": "0.0.8",
|
||||
"bplist-parser": "0.2.0",
|
||||
"plist": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
|
@ -7569,6 +7625,11 @@
|
|||
"extend-shallow": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
|
@ -7641,6 +7702,11 @@
|
|||
"readable-stream": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"stream-buffers": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
|
||||
"integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ="
|
||||
},
|
||||
"stream-each": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
|
||||
|
@ -9082,6 +9148,16 @@
|
|||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
|
||||
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
|
||||
},
|
||||
"xmldom": {
|
||||
"version": "0.1.31",
|
||||
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
|
||||
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"@nativescript-community/ui-material-progress": "^5.0.30",
|
||||
"@nativescript-community/ui-material-ripple": "^5.0.30",
|
||||
"@nativescript/core": "~7.0.0",
|
||||
"@nativescript/localize": "^5.0.2",
|
||||
"@nativescript/social-share": "^2.0.1",
|
||||
"@nativescript/theme": "^3.0.0",
|
||||
"@nativescript/zip": "^5.0.0",
|
||||
|
|