replaced mdripple
This commit is contained in:
parent
89f8557521
commit
2b8627959b
12
app/app.scss
12
app/app.scss
|
@ -1,6 +1,6 @@
|
||||||
// NativeScript core theme
|
// NativeScript core theme
|
||||||
// @see https://docs.nativescript.org/ui/theme
|
// @see https://docs.nativescript.org/ui/theme
|
||||||
@import "~@nativescript/theme/core"; // Override variables here
|
@import '~@nativescript/theme/core'; // Override variables here
|
||||||
$gray0: #fff;
|
$gray0: #fff;
|
||||||
$gray1: #f0f0f0;
|
$gray1: #f0f0f0;
|
||||||
$gray2: #e0e0e0;
|
$gray2: #e0e0e0;
|
||||||
|
@ -10,7 +10,7 @@ $gray5: #858585;
|
||||||
$gray6: #575757;
|
$gray6: #575757;
|
||||||
$gray7: #393939;
|
$gray7: #393939;
|
||||||
$gray8: #292929;
|
$gray8: #292929;
|
||||||
$gray9: #1A1A1A;
|
$gray9: #1a1a1a;
|
||||||
$gray10: #000;
|
$gray10: #000;
|
||||||
$orange: #ff5200;
|
$orange: #ff5200;
|
||||||
$fabRipple: #ffa94d;
|
$fabRipple: #ffa94d;
|
||||||
|
@ -265,7 +265,7 @@ ActionBar {
|
||||||
&.selected {
|
&.selected {
|
||||||
color: $orange;
|
color: $orange;
|
||||||
background: rgba($orange, 0.1);
|
background: rgba($orange, 0.1);
|
||||||
MDRipple {
|
.mdr {
|
||||||
ripple-color: transparent;
|
ripple-color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ ActionBar {
|
||||||
padding: 0 0 0 16;
|
padding: 0 0 0 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MDRipple {
|
.mdr {
|
||||||
padding: 0 16;
|
padding: 0 16;
|
||||||
}
|
}
|
||||||
MDButton.er {
|
MDButton.er {
|
||||||
|
@ -306,7 +306,7 @@ ActionBar {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 8;
|
margin: 8;
|
||||||
}
|
}
|
||||||
MDRipple {
|
.mdr {
|
||||||
border-radius: 4;
|
border-radius: 4;
|
||||||
}
|
}
|
||||||
MDButton {
|
MDButton {
|
||||||
|
@ -322,7 +322,7 @@ MDButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MDButton,
|
MDButton,
|
||||||
MDRipple {
|
.mdr {
|
||||||
ripple-color: rgba($gray5, 0.2);
|
ripple-color: rgba($gray5, 0.2);
|
||||||
}
|
}
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
|
@ -1,32 +1,83 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true" :androidStatusBarBackground="appTheme == 'Light' ? '#f0f0f0' : '#1A1A1A'">
|
<Page
|
||||||
|
@loaded="onPageLoad"
|
||||||
<Drawer @loaded="drawerLoad" :gestureEnabled="gestures" leftSwipeDistance="128">
|
actionBarHidden="true"
|
||||||
|
:androidStatusBarBackground="appTheme == 'Light' ? '#f0f0f0' : '#1A1A1A'"
|
||||||
|
>
|
||||||
|
<Drawer
|
||||||
|
@loaded="drawerLoad"
|
||||||
|
:gestureEnabled="gestures"
|
||||||
|
leftSwipeDistance="128"
|
||||||
|
>
|
||||||
<GridLayout ~leftDrawer rows="*, auto" columns="*" width="280" class="sd">
|
<GridLayout ~leftDrawer rows="*, auto" columns="*" width="280" class="sd">
|
||||||
<StackLayout row="0">
|
<StackLayout row="0">
|
||||||
<GridLayout rows="48" columns="auto, *, auto" v-for="(item, index) in topmenu" :key="index" class="sd-item orkm" :class="{
|
<GridLayout
|
||||||
'selected': currentComponent === item.component,
|
rows="48"
|
||||||
}">
|
columns="auto, *, auto"
|
||||||
<MDRipple colSpan="3" @tap="navigateTo(item.component, item.component, false)" />
|
v-for="(item, index) in topmenu"
|
||||||
|
:key="index"
|
||||||
|
class="sd-item orkm mdr"
|
||||||
|
:class="{
|
||||||
|
selected: currentComponent === item.component,
|
||||||
|
}"
|
||||||
|
@tap="navigateTo(item.component, item.component, false)"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon[item.icon]" />
|
<Label col="0" class="er" :text="icon[item.icon]" />
|
||||||
<Label col="1" :text="`${item.title}` | L" />
|
<Label col="1" :text="`${item.title}` | L" />
|
||||||
<Label class="recipeCount" v-if="getRecipeCount(item.title)" :text="getRecipeCount(item.title)" col="2" />
|
<Label
|
||||||
|
class="recipeCount"
|
||||||
|
v-if="getRecipeCount(item.title)"
|
||||||
|
:text="getRecipeCount(item.title)"
|
||||||
|
col="2"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout class="sd-group-header orkm" rows="auto" columns="*, auto" v-if="cuisinesWithRecipes.length">
|
<GridLayout
|
||||||
<Label class="filterPath" verticalAlignment="center" col="0" :text="getCurrentPath | L" textWrap='true' />
|
class="sd-group-header orkm"
|
||||||
<MDButton :visibility="selectedCuisine?'visible':'hidden'" variant="text" @tap="previousRecipeFilter" class="er" col="2" :text="icon.back" />
|
rows="auto"
|
||||||
|
columns="*, auto"
|
||||||
|
v-if="cuisinesWithRecipes.length"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
class="filterPath"
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="0"
|
||||||
|
:text="getCurrentPath | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
:visibility="selectedCuisine ? 'visible' : 'hidden'"
|
||||||
|
variant="text"
|
||||||
|
@tap="previousRecipeFilter"
|
||||||
|
class="er"
|
||||||
|
col="2"
|
||||||
|
:text="icon.back"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<ScrollView height="100%">
|
<ScrollView height="100%">
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<GridLayout v-for="(item, index) in getRecipeList" :key="index" class="sd-item orkm" :class="{
|
<GridLayout
|
||||||
'selected': selectedTag == item,
|
v-for="(item, index) in getRecipeList"
|
||||||
}" columns="auto, *, auto">
|
:key="index"
|
||||||
<MDRipple colSpan="3" @tap="setFilter && setRecipeFilter(item)" />
|
class="sd-item orkm mdr"
|
||||||
|
:class="{
|
||||||
|
selected: selectedTag == item,
|
||||||
|
}"
|
||||||
|
columns="auto, *, auto"
|
||||||
|
@tap="setFilter && setRecipeFilter(item)"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon[selectedFilterType]" />
|
<Label col="0" class="er" :text="icon[selectedFilterType]" />
|
||||||
<Label col="1" :text="`${item}` | L" />
|
<Label col="1" :text="`${item}` | L" />
|
||||||
<Label class="recipeCount" :text="getRecipeCount(item)" col="2" />
|
<Label
|
||||||
|
class="recipeCount"
|
||||||
|
:text="getRecipeCount(item)"
|
||||||
|
col="2"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout v-if="selectedFilterType =='tag' && !tagsWithRecipes.length" columns="*" rows="*">
|
<GridLayout
|
||||||
|
v-if="selectedFilterType == 'tag' && !tagsWithRecipes.length"
|
||||||
|
columns="*"
|
||||||
|
rows="*"
|
||||||
|
>
|
||||||
<Label class="noTags" :text="'noTs' | L" textWrap="true" />
|
<Label class="noTags" :text="'noTs' | L" textWrap="true" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
@ -34,44 +85,75 @@
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout row="1">
|
<StackLayout row="1">
|
||||||
<StackLayout class="hr" margin="0 8 8"></StackLayout>
|
<StackLayout class="hr" margin="0 8 8"></StackLayout>
|
||||||
<GridLayout rows="48" columns="auto, *" class="sd-item orkm" :class="{
|
<GridLayout
|
||||||
'selected': currentComponent == 'MealPlanner',
|
rows="48"
|
||||||
}">
|
columns="auto, *"
|
||||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(MealPlanner, 'MealPlanner', true)" />
|
class="sd-item orkm mdr"
|
||||||
|
:class="{
|
||||||
|
selected: currentComponent == 'MealPlanner',
|
||||||
|
}"
|
||||||
|
@tap="navigateTo(MealPlanner, 'MealPlanner', true)"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.cal" />
|
<Label col="0" class="er" :text="icon.cal" />
|
||||||
<Label col="2" :text="'planner' | L" />
|
<Label col="2" :text="'planner' | L" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
<!-- <GridLayout rows="48" columns="auto, *" class="sd-item orkm" :class="{
|
<!-- <GridLayout
|
||||||
'selected': currentComponent == 'GroceryList',
|
rows="48"
|
||||||
}">
|
columns="auto, *"
|
||||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(GroceryList, 'GroceryList', true)" />
|
class="sd-item orkm mdr"
|
||||||
|
:class="{
|
||||||
|
selected: currentComponent == 'GroceryList',
|
||||||
|
}"
|
||||||
|
@tap="navigateTo(GroceryList, 'GroceryList', true)"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.bag" />
|
<Label col="0" class="er" :text="icon.bag" />
|
||||||
<Label col="2" :text="'grocery' | L" />
|
<Label col="2" :text="'grocery' | L" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout rows="48" columns="auto, *" class="sd-item orkm" :class="{
|
<GridLayout
|
||||||
'selected': currentComponent == 'GroceryList',
|
rows="48"
|
||||||
}">
|
columns="auto, *"
|
||||||
<MDRipple row="0" colSpan="3" @tap="navigateTo(GroceryList, 'GroceryList', true)" />
|
class="sd-item orkm mdr"
|
||||||
|
:class="{
|
||||||
|
selected: currentComponent == 'GroceryList',
|
||||||
|
}"
|
||||||
|
@tap="navigateTo(GroceryList, 'GroceryList', true)"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.price" />
|
<Label col="0" class="er" :text="icon.price" />
|
||||||
<Label col="2" :text="'Price List' | L" />
|
<Label col="2" :text="'Price List' | L" />
|
||||||
</GridLayout> -->
|
</GridLayout> -->
|
||||||
|
|
||||||
<StackLayout class="hr" margin="8"></StackLayout>
|
<StackLayout class="hr" margin="8"></StackLayout>
|
||||||
|
|
||||||
<GridLayout class="sd-item orkm" :class="{
|
<GridLayout
|
||||||
'selected': currentComponent == 'Settings',
|
class="sd-item orkm mdr"
|
||||||
}" rows="48" columns="auto, *">
|
:class="{
|
||||||
<MDRipple colSpan="3" @tap="navigateTo(Settings, 'Settings', true)" />
|
selected: currentComponent == 'Settings',
|
||||||
|
}"
|
||||||
|
rows="48"
|
||||||
|
columns="auto, *"
|
||||||
|
@tap="navigateTo(Settings, 'Settings', true)"
|
||||||
|
>
|
||||||
<Label class="er" col="0" :text="icon.cog" />
|
<Label class="er" col="0" :text="icon.cog" />
|
||||||
<Label col="2" :text="'Settings' | L" />
|
<Label col="2" :text="'Settings' | L" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Frame ~mainContent id="main-frame">
|
<Frame ~mainContent id="main-frame">
|
||||||
<EnRecipes ref="enrecipes" :filterFavourites="filterFavourites" :filterTrylater="filterTrylater" :selectedCuisine="selectedCuisine" :selectedCategory="selectedCategory" :selectedTag="selectedTag" :closeDrawer="closeDrawer"
|
<EnRecipes
|
||||||
:hijackGlobalBackEvent="hijackGlobalBackEvent" :releaseGlobalBackEvent="releaseGlobalBackEvent" @backToHome="backToHome" :showDrawer="showDrawer" @selectModeOn="selectModeOn" />
|
ref="enrecipes"
|
||||||
|
:filterFavourites="filterFavourites"
|
||||||
|
:filterTrylater="filterTrylater"
|
||||||
|
:selectedCuisine="selectedCuisine"
|
||||||
|
:selectedCategory="selectedCategory"
|
||||||
|
:selectedTag="selectedTag"
|
||||||
|
:closeDrawer="closeDrawer"
|
||||||
|
:hijackGlobalBackEvent="hijackGlobalBackEvent"
|
||||||
|
:releaseGlobalBackEvent="releaseGlobalBackEvent"
|
||||||
|
@backToHome="backToHome"
|
||||||
|
:showDrawer="showDrawer"
|
||||||
|
@selectModeOn="selectModeOn"
|
||||||
|
/>
|
||||||
</Frame>
|
</Frame>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -82,24 +164,16 @@ import {
|
||||||
ApplicationSettings,
|
ApplicationSettings,
|
||||||
AndroidApplication,
|
AndroidApplication,
|
||||||
Application,
|
Application,
|
||||||
}
|
} from "@nativescript/core";
|
||||||
from "@nativescript/core"
|
import Theme from "@nativescript/theme";
|
||||||
import Theme from "@nativescript/theme"
|
import { localize } from "@nativescript/localize";
|
||||||
import {
|
import { mapActions, mapState } from "vuex";
|
||||||
localize
|
import EnRecipes from "./EnRecipes";
|
||||||
}
|
import ViewRecipe from "./ViewRecipe";
|
||||||
from "@nativescript/localize"
|
import MealPlanner from "./MealPlanner";
|
||||||
import {
|
import GroceryList from "./GroceryList";
|
||||||
mapActions,
|
import Settings from "./Settings";
|
||||||
mapState
|
import PromptDialog from "./modal/PromptDialog";
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
import EnRecipes from "./EnRecipes"
|
|
||||||
import ViewRecipe from "./ViewRecipe"
|
|
||||||
import MealPlanner from "./MealPlanner"
|
|
||||||
import GroceryList from "./GroceryList"
|
|
||||||
import Settings from "./Settings"
|
|
||||||
import PromptDialog from "./modal/PromptDialog"
|
|
||||||
let filterTimer;
|
let filterTimer;
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
@ -107,232 +181,316 @@ export default {
|
||||||
selectedCuisine: null,
|
selectedCuisine: null,
|
||||||
selectedCategory: null,
|
selectedCategory: null,
|
||||||
selectedTag: null,
|
selectedTag: null,
|
||||||
selectedFilterType: 'cuisine',
|
selectedFilterType: "cuisine",
|
||||||
filterFavourites: false,
|
filterFavourites: false,
|
||||||
filterTrylater: false,
|
filterTrylater: false,
|
||||||
MealPlanner: MealPlanner,
|
MealPlanner: MealPlanner,
|
||||||
GroceryList: GroceryList,
|
GroceryList: GroceryList,
|
||||||
Settings: Settings,
|
Settings: Settings,
|
||||||
topmenu: [ {
|
topmenu: [
|
||||||
|
{
|
||||||
title: "EnRecipes",
|
title: "EnRecipes",
|
||||||
component: "EnRecipes",
|
component: "EnRecipes",
|
||||||
icon: "home",
|
icon: "home",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: "trylater",
|
title: "trylater",
|
||||||
component: "Try Later",
|
component: "Try Later",
|
||||||
icon: "try",
|
icon: "try",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
title: "favourites",
|
title: "favourites",
|
||||||
component: "Favourites",
|
component: "Favourites",
|
||||||
icon: "fav",
|
icon: "fav",
|
||||||
}, ],
|
},
|
||||||
|
],
|
||||||
appTheme: "Light",
|
appTheme: "Light",
|
||||||
setFilter: true,
|
setFilter: true,
|
||||||
gestures: true,
|
gestures: true,
|
||||||
drawer: null,
|
drawer: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
EnRecipes,
|
EnRecipes,
|
||||||
ViewRecipe,
|
ViewRecipe,
|
||||||
MealPlanner,
|
MealPlanner,
|
||||||
GroceryList,
|
GroceryList,
|
||||||
Settings
|
Settings,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState( [ "icon", "recipes", "cuisines", "categories", "yieldUnits", "mealPlans", "currentComponent" ] ),
|
...mapState([
|
||||||
|
"icon",
|
||||||
|
"recipes",
|
||||||
|
"cuisines",
|
||||||
|
"categories",
|
||||||
|
"yieldUnits",
|
||||||
|
"mealPlans",
|
||||||
|
"currentComponent",
|
||||||
|
]),
|
||||||
getCurrentPath() {
|
getCurrentPath() {
|
||||||
let path = "/"
|
let path = "/";
|
||||||
if ( this.selectedCuisine ) path += localize( this.selectedCuisine )
|
if (this.selectedCuisine) path += localize(this.selectedCuisine);
|
||||||
else path = "cuis"
|
else path = "cuis";
|
||||||
if ( this.selectedCategory ) path += "/" + localize( this.selectedCategory )
|
if (this.selectedCategory) path += "/" + localize(this.selectedCategory);
|
||||||
if ( this.selectedTag ) path += "/" + localize( this.selectedTag )
|
if (this.selectedTag) path += "/" + localize(this.selectedTag);
|
||||||
return path;
|
return path;
|
||||||
},
|
},
|
||||||
getRecipeList() {
|
getRecipeList() {
|
||||||
switch (this.selectedFilterType) {
|
switch (this.selectedFilterType) {
|
||||||
case 'cuisine':
|
case "cuisine":
|
||||||
return this.cuisinesWithRecipes
|
return this.cuisinesWithRecipes;
|
||||||
break;
|
break;
|
||||||
case 'category':
|
case "category":
|
||||||
return this.categoriesWithRecipes
|
return this.categoriesWithRecipes;
|
||||||
break;
|
break;
|
||||||
case 'tag':
|
case "tag":
|
||||||
return this.tagsWithRecipes
|
return this.tagsWithRecipes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cuisinesWithRecipes() {
|
cuisinesWithRecipes() {
|
||||||
let arr = this.recipes.map( ( e ) => e.cuisine ).sort()
|
let arr = this.recipes.map((e) => e.cuisine).sort();
|
||||||
return arr.length ? [ "allCuis", ...new Set( arr ) ] : []
|
return arr.length ? ["allCuis", ...new Set(arr)] : [];
|
||||||
},
|
},
|
||||||
categoriesWithRecipes() {
|
categoriesWithRecipes() {
|
||||||
let arr = this.recipes.map( e => ( this.selectedCuisine === "allCuis" || e.cuisine === this.selectedCuisine ) && e.category ).filter( e => e ).sort()
|
let arr = this.recipes
|
||||||
return arr.length ? [ "allCats", ...new Set( arr ) ] : []
|
.map(
|
||||||
|
(e) =>
|
||||||
|
(this.selectedCuisine === "allCuis" ||
|
||||||
|
e.cuisine === this.selectedCuisine) &&
|
||||||
|
e.category
|
||||||
|
)
|
||||||
|
.filter((e) => e)
|
||||||
|
.sort();
|
||||||
|
return arr.length ? ["allCats", ...new Set(arr)] : [];
|
||||||
},
|
},
|
||||||
tagsWithRecipes() {
|
tagsWithRecipes() {
|
||||||
let arr = this.recipes.map( e => {
|
let arr = this.recipes
|
||||||
if ( this.selectedCuisine === "allCuis" && this.selectedCategory === "allCats" && e.tags.length ) return e.tags;
|
.map((e) => {
|
||||||
else if ( this.selectedCuisine === "allCuis" && e.category === this.selectedCategory && e.tags.length ) return e.tags;
|
if (
|
||||||
else if ( this.selectedCategory === "allCats" && e.cuisine === this.selectedCuisine && e.tags.length ) return e.tags;
|
this.selectedCuisine === "allCuis" &&
|
||||||
else if ( e.category === this.selectedCategory && e.cuisine === this.selectedCuisine && e.tags.length ) return e.tags;
|
this.selectedCategory === "allCats" &&
|
||||||
} ).flat().filter( e => e ).sort()
|
e.tags.length
|
||||||
let showAllTags = this.selectedCuisine === "allCuis" && this.selectedCategory === "allCats"
|
)
|
||||||
return arr.length ? [ !showAllTags && "allTs", ...new Set( arr ) ].filter( e => e ) : []
|
return e.tags;
|
||||||
|
else if (
|
||||||
|
this.selectedCuisine === "allCuis" &&
|
||||||
|
e.category === this.selectedCategory &&
|
||||||
|
e.tags.length
|
||||||
|
)
|
||||||
|
return e.tags;
|
||||||
|
else if (
|
||||||
|
this.selectedCategory === "allCats" &&
|
||||||
|
e.cuisine === this.selectedCuisine &&
|
||||||
|
e.tags.length
|
||||||
|
)
|
||||||
|
return e.tags;
|
||||||
|
else if (
|
||||||
|
e.category === this.selectedCategory &&
|
||||||
|
e.cuisine === this.selectedCuisine &&
|
||||||
|
e.tags.length
|
||||||
|
)
|
||||||
|
return e.tags;
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
.filter((e) => e)
|
||||||
|
.sort();
|
||||||
|
let showAllTags =
|
||||||
|
this.selectedCuisine === "allCuis" &&
|
||||||
|
this.selectedCategory === "allCats";
|
||||||
|
return arr.length
|
||||||
|
? [!showAllTags && "allTs", ...new Set(arr)].filter((e) => e)
|
||||||
|
: [];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions( [ "setCurrentComponentAction", "initializeListItems", "initializeRecipes", "initializeMealPlans", "setShakeAction" ] ),
|
...mapActions([
|
||||||
|
"setCurrentComponentAction",
|
||||||
|
"initializeListItems",
|
||||||
|
"initializeRecipes",
|
||||||
|
"initializeMealPlans",
|
||||||
|
"setShakeAction",
|
||||||
|
]),
|
||||||
onPageLoad() {
|
onPageLoad() {
|
||||||
if (this.appTheme === "Light") {
|
if (this.appTheme === "Light") {
|
||||||
const View = android.view.View
|
const View = android.view.View;
|
||||||
const window = Application.android.startActivity.getWindow()
|
const window = Application.android.startActivity.getWindow();
|
||||||
const decorView = window.getDecorView()
|
const decorView = window.getDecorView();
|
||||||
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR )
|
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
drawerLoad(args) {
|
drawerLoad(args) {
|
||||||
this.drawer = args.object
|
this.drawer = args.object;
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
setRecipeFilter(item) {
|
setRecipeFilter(item) {
|
||||||
this.setFilter = this.filterFavourites = this.filterTrylater = false
|
this.setFilter = this.filterFavourites = this.filterTrylater = false;
|
||||||
this.$navigateBack({
|
this.$navigateBack({
|
||||||
frame: "main-frame",
|
frame: "main-frame",
|
||||||
backstackVisible: false
|
backstackVisible: false,
|
||||||
} )
|
});
|
||||||
setTimeout( e => {
|
setTimeout((e) => {
|
||||||
if (this.selectedCuisine == null) {
|
if (this.selectedCuisine == null) {
|
||||||
this.selectedCuisine = item
|
this.selectedCuisine = item;
|
||||||
this.selectedFilterType = 'category'
|
this.selectedFilterType = "category";
|
||||||
} else if (this.selectedCategory == null) {
|
} else if (this.selectedCategory == null) {
|
||||||
this.selectedCategory = item
|
this.selectedCategory = item;
|
||||||
this.selectedFilterType = 'tag'
|
this.selectedFilterType = "tag";
|
||||||
if ( !this.tagsWithRecipes.length ) this.closeDrawer()
|
if (!this.tagsWithRecipes.length) this.closeDrawer();
|
||||||
} else {
|
} else {
|
||||||
this.selectedTag = item;
|
this.selectedTag = item;
|
||||||
this.closeDrawer()
|
this.closeDrawer();
|
||||||
}
|
}
|
||||||
this.setFilter = true
|
this.setFilter = true;
|
||||||
}, 250 )
|
}, 250);
|
||||||
this.setCurrentComponentAction( "Filtered recipes" )
|
this.setCurrentComponentAction("Filtered recipes");
|
||||||
},
|
},
|
||||||
previousRecipeFilter() {
|
previousRecipeFilter() {
|
||||||
if (this.selectedCategory) {
|
if (this.selectedCategory) {
|
||||||
this.selectedFilterType = 'category'
|
this.selectedFilterType = "category";
|
||||||
this.selectedTag = this.selectedCategory = null
|
this.selectedTag = this.selectedCategory = null;
|
||||||
this.setCurrentComponentAction( "Filtered recipes" )
|
this.setCurrentComponentAction("Filtered recipes");
|
||||||
} else {
|
} else {
|
||||||
this.selectedFilterType = 'cuisine'
|
this.selectedFilterType = "cuisine";
|
||||||
this.selectedCuisine = null
|
this.selectedCuisine = null;
|
||||||
this.setCurrentComponentAction( "EnRecipes" )
|
this.setCurrentComponentAction("EnRecipes");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showDrawer() {
|
showDrawer() {
|
||||||
this.drawer.open()
|
this.drawer.open();
|
||||||
},
|
},
|
||||||
closeDrawer() {
|
closeDrawer() {
|
||||||
this.drawer.close()
|
this.drawer.close();
|
||||||
},
|
},
|
||||||
getRecipeCount(arg) {
|
getRecipeCount(arg) {
|
||||||
let count = ''
|
let count = "";
|
||||||
switch (arg) {
|
switch (arg) {
|
||||||
case 'EnRecipes':
|
case "EnRecipes":
|
||||||
count = this.recipes.length
|
count = this.recipes.length;
|
||||||
break;
|
break;
|
||||||
case 'trylater':
|
case "trylater":
|
||||||
count = this.recipes.filter( e => !e.tried ).length
|
count = this.recipes.filter((e) => !e.tried).length;
|
||||||
break;
|
break;
|
||||||
case 'favourites':
|
case "favourites":
|
||||||
count = this.recipes.filter( e => e.isFavorite ).length
|
count = this.recipes.filter((e) => e.isFavorite).length;
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
switch (this.selectedFilterType) {
|
switch (this.selectedFilterType) {
|
||||||
case 'cuisine':
|
case "cuisine":
|
||||||
count = this.recipes.filter( e => arg === "allCuis" ? e.cuisine : e.cuisine === arg ).length
|
count = this.recipes.filter((e) =>
|
||||||
|
arg === "allCuis" ? e.cuisine : e.cuisine === arg
|
||||||
|
).length;
|
||||||
break;
|
break;
|
||||||
case 'category':
|
case "category":
|
||||||
count = this.recipes.filter( e => this.selectedCuisine === "allCuis" ? arg === "allCats" ? e.category : e.category === arg : arg === "allCats" ? e.cuisine === this.selectedCuisine && e.category : e.cuisine === this
|
count = this.recipes.filter((e) =>
|
||||||
.selectedCuisine && e.category === arg ).length
|
this.selectedCuisine === "allCuis"
|
||||||
|
? arg === "allCats"
|
||||||
|
? e.category
|
||||||
|
: e.category === arg
|
||||||
|
: arg === "allCats"
|
||||||
|
? e.cuisine === this.selectedCuisine && e.category
|
||||||
|
: e.cuisine === this.selectedCuisine && e.category === arg
|
||||||
|
).length;
|
||||||
break;
|
break;
|
||||||
case 'tag':
|
case "tag":
|
||||||
count = this.recipes.filter( e => {
|
count = this.recipes.filter((e) => {
|
||||||
if ( this.selectedCuisine === "allCuis" && this.selectedCategory === "allCats" ) {
|
if (
|
||||||
return e.tags.includes( arg ) || arg === "allTs"
|
this.selectedCuisine === "allCuis" &&
|
||||||
} else if ( this.selectedCuisine === "allCuis" && e.category === this.selectedCategory ) {
|
this.selectedCategory === "allCats"
|
||||||
return e.tags.includes( arg ) || arg === "allTs"
|
) {
|
||||||
} else if ( this.selectedCategory === "allCats" && e.cuisine === this.selectedCuisine ) {
|
return e.tags.includes(arg) || arg === "allTs";
|
||||||
return e.tags.includes( arg ) || arg === "allTs"
|
} else if (
|
||||||
} else if ( e.category === this.selectedCategory && e.cuisine === this.selectedCuisine ) {
|
this.selectedCuisine === "allCuis" &&
|
||||||
return e.tags.includes( arg ) || arg === "allTs"
|
e.category === this.selectedCategory
|
||||||
|
) {
|
||||||
|
return e.tags.includes(arg) || arg === "allTs";
|
||||||
|
} else if (
|
||||||
|
this.selectedCategory === "allCats" &&
|
||||||
|
e.cuisine === this.selectedCuisine
|
||||||
|
) {
|
||||||
|
return e.tags.includes(arg) || arg === "allTs";
|
||||||
|
} else if (
|
||||||
|
e.category === this.selectedCategory &&
|
||||||
|
e.cuisine === this.selectedCuisine
|
||||||
|
) {
|
||||||
|
return e.tags.includes(arg) || arg === "allTs";
|
||||||
}
|
}
|
||||||
} ).length
|
}).length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count
|
return count;
|
||||||
},
|
},
|
||||||
selectModeOn(bool) {
|
selectModeOn(bool) {
|
||||||
this.gestures = bool
|
this.gestures = bool;
|
||||||
},
|
},
|
||||||
// NAVIGATION HANDLERS
|
// NAVIGATION HANDLERS
|
||||||
hijackGlobalBackEvent() {
|
hijackGlobalBackEvent() {
|
||||||
AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.globalBackEvent )
|
AndroidApplication.on(
|
||||||
|
AndroidApplication.activityBackPressedEvent,
|
||||||
|
this.globalBackEvent
|
||||||
|
);
|
||||||
},
|
},
|
||||||
releaseGlobalBackEvent() {
|
releaseGlobalBackEvent() {
|
||||||
AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.globalBackEvent )
|
AndroidApplication.off(
|
||||||
|
AndroidApplication.activityBackPressedEvent,
|
||||||
|
this.globalBackEvent
|
||||||
|
);
|
||||||
},
|
},
|
||||||
globalBackEvent(args) {
|
globalBackEvent(args) {
|
||||||
if (this.drawer && this.drawer.isOpened()) {
|
if (this.drawer && this.drawer.isOpened()) {
|
||||||
args.cancel = true
|
args.cancel = true;
|
||||||
this.closeDrawer()
|
this.closeDrawer();
|
||||||
} else if (
|
} else if (
|
||||||
[ "Favourites", "Try Later", "Filtered recipes" ].includes( this.currentComponent ) ) {
|
["Favourites", "Try Later", "Filtered recipes"].includes(
|
||||||
args.cancel = true
|
this.currentComponent
|
||||||
this.backToHome()
|
)
|
||||||
|
) {
|
||||||
|
args.cancel = true;
|
||||||
|
this.backToHome();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
backToHome() {
|
backToHome() {
|
||||||
this.setCurrentComponentAction( "EnRecipes" )
|
this.setCurrentComponentAction("EnRecipes");
|
||||||
this.filterFavourites = this.filterTrylater = false
|
this.filterFavourites = this.filterTrylater = false;
|
||||||
this.selectedTag = this.selectedCategory = this.selectedCuisine = null
|
this.selectedTag = this.selectedCategory = this.selectedCuisine = null;
|
||||||
this.selectedFilterType = "cuisine"
|
this.selectedFilterType = "cuisine";
|
||||||
},
|
},
|
||||||
navigateTo(to, title, isTrueComponent) {
|
navigateTo(to, title, isTrueComponent) {
|
||||||
if (title !== this.currentComponent) {
|
if (title !== this.currentComponent) {
|
||||||
if (isTrueComponent) {
|
if (isTrueComponent) {
|
||||||
this.$navigateTo(to, {
|
this.$navigateTo(to, {
|
||||||
backstackVisible: true
|
backstackVisible: true,
|
||||||
} )
|
});
|
||||||
this.closeDrawer()
|
this.closeDrawer();
|
||||||
} else {
|
} else {
|
||||||
this.setCurrentComponentAction( to )
|
this.setCurrentComponentAction(to);
|
||||||
this.$navigateBack({
|
this.$navigateBack({
|
||||||
frame: "main-frame",
|
frame: "main-frame",
|
||||||
backstackVisible: false
|
backstackVisible: false,
|
||||||
} )
|
});
|
||||||
this.filterFavourites = to === "Favourites"
|
this.filterFavourites = to === "Favourites";
|
||||||
this.filterTrylater = to === "Try Later"
|
this.filterTrylater = to === "Try Later";
|
||||||
this.closeDrawer()
|
this.closeDrawer();
|
||||||
this.selectedTag = this.selectedCategory = this.selectedCuisine = null
|
this.selectedTag = this.selectedCategory = this.selectedCuisine = null;
|
||||||
this.selectedFilterType = "cuisine"
|
this.selectedFilterType = "cuisine";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.closeDrawer()
|
this.closeDrawer();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
||||||
setTimeout((e) => {
|
setTimeout((e) => {
|
||||||
Theme.setMode( Theme[ this.appTheme ] )
|
Theme.setMode(Theme[this.appTheme]);
|
||||||
}, 10 )
|
}, 10);
|
||||||
if ( !this.recipes.length ) this.initializeRecipes()
|
if (!this.recipes.length) this.initializeRecipes();
|
||||||
this.initializeListItems()
|
this.initializeListItems();
|
||||||
if ( !this.mealPlans.length ) this.initializeMealPlans()
|
if (!this.mealPlans.length) this.initializeMealPlans();
|
||||||
this.setShakeAction( ApplicationSettings.getBoolean( "shakeEnabled", true ) )
|
this.setShakeAction(ApplicationSettings.getBoolean("shakeEnabled", true));
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,66 +1,218 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
|
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
|
||||||
<ActionBar androidElevation="1">
|
<ActionBar androidElevation="1">
|
||||||
<GridLayout v-if="showSearch" columns="auto, *" verticalAlignment="center">
|
<GridLayout
|
||||||
<MDButton class="er" :text="icon.back" variant="text" automationText="Back" col="0" @tap="closeSearch" />
|
v-if="showSearch"
|
||||||
<SearchBar col="1" :hint="'ser' | L" @textChange="updateList($event.value)" @clear="clearSearch" />
|
columns="auto, *"
|
||||||
|
verticalAlignment="center"
|
||||||
|
>
|
||||||
|
<MDButton
|
||||||
|
class="er"
|
||||||
|
:text="icon.back"
|
||||||
|
variant="text"
|
||||||
|
automationText="Back"
|
||||||
|
col="0"
|
||||||
|
@tap="closeSearch"
|
||||||
|
/>
|
||||||
|
<SearchBar
|
||||||
|
col="1"
|
||||||
|
:hint="'ser' | L"
|
||||||
|
@textChange="updateList($event.value)"
|
||||||
|
@clear="clearSearch"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout v-else columns="auto, *, auto, auto, auto">
|
<GridLayout v-else columns="auto, *, auto, auto, auto">
|
||||||
<MDButton class="er" col="0" variant="text" @tap="selectMode ? clearSelection() : showDrawer()" :text="selectMode ? icon.x : icon.menu" />
|
<MDButton
|
||||||
<Label v-if="selectMode" class="title orkm" :text="`${selection.length} ${$options.filters.L('sltd')}`" col="1" />
|
class="er"
|
||||||
<Label v-else class="title orkm" :text="`${currentComponent}` | L" col="1" />
|
col="0"
|
||||||
|
variant="text"
|
||||||
|
@tap="selectMode ? clearSelection() : showDrawer()"
|
||||||
|
:text="selectMode ? icon.x : icon.menu"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
v-if="selectMode"
|
||||||
|
class="title orkm"
|
||||||
|
:text="`${selection.length} ${$options.filters.L('sltd')}`"
|
||||||
|
col="1"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
v-else
|
||||||
|
class="title orkm"
|
||||||
|
:text="`${currentComponent}` | L"
|
||||||
|
col="1"
|
||||||
|
/>
|
||||||
<!-- <MDButton v-if="recipes.length" class="er" :text="layout== 1 ? icon.l1 : layout==2 ? icon.l2 : icon.l3" variant="text" col="2" @tap="switchLayout" /> -->
|
<!-- <MDButton v-if="recipes.length" class="er" :text="layout== 1 ? icon.l1 : layout==2 ? icon.l2 : icon.l3" variant="text" col="2" @tap="switchLayout" /> -->
|
||||||
<MDButton v-if="recipes.length && !selectMode" class="er" :text="selectMode ? icon.export : icon.sear" variant="text" col="3" @tap="selectMode ? exportSelection() : openSearch()" />
|
<MDButton
|
||||||
<MDButton v-if="recipes.length" class="er" :text="selectMode ? icon.del : icon.sort" variant="text" col="4" @tap="selectMode ? deleteSelection() : sortDialog()" />
|
v-if="recipes.length && !selectMode"
|
||||||
|
class="er"
|
||||||
|
:text="selectMode ? icon.export : icon.sear"
|
||||||
|
variant="text"
|
||||||
|
col="3"
|
||||||
|
@tap="selectMode ? exportSelection() : openSearch()"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
v-if="recipes.length"
|
||||||
|
class="er"
|
||||||
|
:text="selectMode ? icon.del : icon.sort"
|
||||||
|
variant="text"
|
||||||
|
col="4"
|
||||||
|
@tap="selectMode ? deleteSelection() : sortDialog()"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<AbsoluteLayout>
|
<AbsoluteLayout>
|
||||||
<ListView width="100%" height="100%" for="recipe in filteredRecipes" @loaded="listViewLoad" :itemTemplateSelector="getLayout">
|
<ListView
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
for="recipe in filteredRecipes"
|
||||||
|
@loaded="listViewLoad"
|
||||||
|
:itemTemplateSelector="getLayout"
|
||||||
|
>
|
||||||
<v-template key="one">
|
<v-template key="one">
|
||||||
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
||||||
<GridLayout class="recipeItem layout1" rows="104" columns="104, *" androidElevation="1">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" ref="recipe" @longPress="selectMode? viewRecipe(recipe.id) : addToSelection($event, recipe.id)" @tap="selectMode? addToSelection($event, recipe.id) : viewRecipe(recipe.id)" />
|
class="recipeItem layout1 mdr"
|
||||||
|
rows="104"
|
||||||
|
columns="104, *"
|
||||||
|
androidElevation="1"
|
||||||
|
ref="recipe"
|
||||||
|
@longPress="
|
||||||
|
selectMode
|
||||||
|
? viewRecipe(recipe.id)
|
||||||
|
: addToSelection($event, recipe.id)
|
||||||
|
"
|
||||||
|
@tap="
|
||||||
|
selectMode
|
||||||
|
? addToSelection($event, recipe.id)
|
||||||
|
: viewRecipe(recipe.id)
|
||||||
|
"
|
||||||
|
>
|
||||||
<GridLayout class="imageHolder card" rows="104" columns="104">
|
<GridLayout class="imageHolder card" rows="104" columns="104">
|
||||||
<Image row="0" col="0" v-if="recipe.imageSrc" :src="recipe.imageSrc" stretch="aspectFill" decodeWidth="104" decodeHeight="104" loadMode="async" />
|
<Image
|
||||||
<Label v-else row="0" col="0" horizontalAlignment="center" class="er" fontSize="56" :text="icon.img" />
|
row="0"
|
||||||
|
col="0"
|
||||||
|
v-if="recipe.imageSrc"
|
||||||
|
:src="recipe.imageSrc"
|
||||||
|
stretch="aspectFill"
|
||||||
|
decodeWidth="104"
|
||||||
|
decodeHeight="104"
|
||||||
|
loadMode="async"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
v-else
|
||||||
|
row="0"
|
||||||
|
col="0"
|
||||||
|
horizontalAlignment="center"
|
||||||
|
class="er"
|
||||||
|
fontSize="56"
|
||||||
|
:text="icon.img"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout class="recipeInfo" col="1">
|
<StackLayout class="recipeInfo" col="1">
|
||||||
<Label :text="`${$options.filters.L(recipe.cuisine)} • ${$options.filters.L(recipe.category)}`" class="category" />
|
<Label
|
||||||
|
:text="`${$options.filters.L(
|
||||||
|
recipe.cuisine
|
||||||
|
)} • ${$options.filters.L(recipe.category)}`"
|
||||||
|
class="category"
|
||||||
|
/>
|
||||||
<Label :text="recipe.title" class="orkm title" />
|
<Label :text="recipe.title" class="orkm title" />
|
||||||
<GridLayout columns="*" rows="auto, *, auto">
|
<GridLayout columns="*" rows="auto, *, auto">
|
||||||
<StackLayout class="attrContainer" orientation="horizontal" row="0">
|
<StackLayout
|
||||||
|
class="attrContainer"
|
||||||
|
orientation="horizontal"
|
||||||
|
row="0"
|
||||||
|
>
|
||||||
<Label class="er small" :text="icon.star" />
|
<Label class="er small" :text="icon.star" />
|
||||||
<Label class="attr" :text="recipe.rating" />
|
<Label class="attr" :text="recipe.rating" />
|
||||||
<Label class="er small" :text="icon.diff" />
|
<Label class="er small" :text="icon.diff" />
|
||||||
<Label class="attr" :text="`${recipe.difficulty}` | L" />
|
<Label class="attr" :text="`${recipe.difficulty}` | L" />
|
||||||
<Label class="er small" :text="icon.time" />
|
<Label class="er small" :text="icon.time" />
|
||||||
<Label class="attr" :text="
|
<Label
|
||||||
`${
|
class="attr"
|
||||||
formattedTotalTime(recipe.prepTime, recipe.cookTime).time
|
:text="`${
|
||||||
}`
|
formattedTotalTime(recipe.prepTime, recipe.cookTime)
|
||||||
" />
|
.time
|
||||||
|
}`"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout class="tagsContainer" orientation="horizontal" row="2">
|
<StackLayout
|
||||||
<Label v-for="(tag, index) in recipe.tags" :key="index" class="tag" :text="tag" />
|
class="tagsContainer"
|
||||||
|
orientation="horizontal"
|
||||||
|
row="2"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
v-for="(tag, index) in recipe.tags"
|
||||||
|
:key="index"
|
||||||
|
class="tag"
|
||||||
|
:text="tag"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
|
|
||||||
<!-- <v-template key="two">
|
<!-- <v-template key="two">
|
||||||
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
||||||
<GridLayout class="recipeItem layout2" rows="auto, auto" columns="*" androidElevation="1">
|
<GridLayout
|
||||||
<MDRipple rowSpan="2" ref="recipe" @longPress="selectMode? viewRecipe(recipe.id) : addToSelection($event, recipe.id)" @tap="selectMode? addToSelection($event, recipe.id) : viewRecipe(recipe.id)" />
|
class="recipeItem layout2 mdr"
|
||||||
|
rows="auto, auto"
|
||||||
|
columns="*"
|
||||||
|
androidElevation="1"
|
||||||
|
ref="recipe"
|
||||||
|
@longPress="
|
||||||
|
selectMode
|
||||||
|
? viewRecipe(recipe.id)
|
||||||
|
: addToSelection($event, recipe.id)
|
||||||
|
"
|
||||||
|
@tap="
|
||||||
|
selectMode
|
||||||
|
? addToSelection($event, recipe.id)
|
||||||
|
: viewRecipe(recipe.id)
|
||||||
|
"
|
||||||
|
>
|
||||||
<GridLayout class="imageHolder card" :rows="imgWidth" columns="*">
|
<GridLayout class="imageHolder card" :rows="imgWidth" columns="*">
|
||||||
<Image row="0" col="0" v-if="recipe.imageSrc" :src="recipe.imageSrc" stretch="aspectFill" :decodeWidth="imgWidth" :decodeHeight="imgWidth" loadMode="async" />
|
<Image
|
||||||
<Label v-else row="0" col="0" horizontalAlignment="center" class="er" :fontSize="imgWidth / 2" :text="icon.img" />
|
row="0"
|
||||||
|
col="0"
|
||||||
|
v-if="recipe.imageSrc"
|
||||||
|
:src="recipe.imageSrc"
|
||||||
|
stretch="aspectFill"
|
||||||
|
:decodeWidth="imgWidth"
|
||||||
|
:decodeHeight="imgWidth"
|
||||||
|
loadMode="async"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
v-else
|
||||||
|
row="0"
|
||||||
|
col="0"
|
||||||
|
horizontalAlignment="center"
|
||||||
|
class="er"
|
||||||
|
:fontSize="imgWidth / 2"
|
||||||
|
:text="icon.img"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout class="recipeInfo" row="1">
|
<StackLayout class="recipeInfo" row="1">
|
||||||
<Label :text="`${$options.filters.L(recipe.cuisine)} • ${$options.filters.L(recipe.category)}`" class="category" />
|
<Label
|
||||||
|
:text="`${$options.filters.L(
|
||||||
|
recipe.cuisine
|
||||||
|
)} • ${$options.filters.L(recipe.category)}`"
|
||||||
|
class="category"
|
||||||
|
/>
|
||||||
<Label :text="recipe.title" class="orkm title" />
|
<Label :text="recipe.title" class="orkm title" />
|
||||||
<StackLayout class="tagsContainer" orientation="horizontal" row="2">
|
<StackLayout
|
||||||
<Label v-for="(tag, index) in recipe.tags" :key="index" v-if="tag" class="tag" :text="tag" />
|
class="tagsContainer"
|
||||||
|
orientation="horizontal"
|
||||||
|
row="2"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
v-for="(tag, index) in recipe.tags"
|
||||||
|
:key="index"
|
||||||
|
v-if="tag"
|
||||||
|
class="tag"
|
||||||
|
:text="tag"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
@ -68,13 +220,39 @@
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template key="three">
|
<v-template key="three">
|
||||||
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
<GridLayout class="recipeContainer" :class="isFirstItem(recipe.id)">
|
||||||
<GridLayout class="recipeItem layout1" rows="auto" columns="*" androidElevation="1">
|
<GridLayout
|
||||||
<MDRipple ref="recipe" @longPress="selectMode? viewRecipe(recipe.id) : addToSelection($event, recipe.id)" @tap="selectMode? addToSelection($event, recipe.id) : viewRecipe(recipe.id)" />
|
class="recipeItem layout1 mdr"
|
||||||
|
rows="auto"
|
||||||
|
columns="*"
|
||||||
|
androidElevation="1"
|
||||||
|
ref="recipe"
|
||||||
|
@longPress="
|
||||||
|
selectMode
|
||||||
|
? viewRecipe(recipe.id)
|
||||||
|
: addToSelection($event, recipe.id)
|
||||||
|
"
|
||||||
|
@tap="
|
||||||
|
selectMode
|
||||||
|
? addToSelection($event, recipe.id)
|
||||||
|
: viewRecipe(recipe.id)
|
||||||
|
"
|
||||||
|
>
|
||||||
<StackLayout class="recipeInfo">
|
<StackLayout class="recipeInfo">
|
||||||
<Label :text="`${$options.filters.L(recipe.cuisine)} • ${$options.filters.L(recipe.category)}`" class="category" />
|
<Label
|
||||||
|
:text="`${$options.filters.L(
|
||||||
|
recipe.cuisine
|
||||||
|
)} • ${$options.filters.L(recipe.category)}`"
|
||||||
|
class="category"
|
||||||
|
/>
|
||||||
<Label :text="recipe.title" class="orkm title" />
|
<Label :text="recipe.title" class="orkm title" />
|
||||||
<StackLayout class="tagsContainer" orientation="horizontal">
|
<StackLayout class="tagsContainer" orientation="horizontal">
|
||||||
<Label v-for="(tag, index) in recipe.tags" :key="index" v-if="tag" class="tag" :text="tag" />
|
<Label
|
||||||
|
v-for="(tag, index) in recipe.tags"
|
||||||
|
:key="index"
|
||||||
|
v-if="tag"
|
||||||
|
class="tag"
|
||||||
|
:text="tag"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
@ -82,36 +260,66 @@
|
||||||
</v-template> -->
|
</v-template> -->
|
||||||
</ListView>
|
</ListView>
|
||||||
<GridLayout rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
|
<GridLayout rows="*, auto, *, 88" columns="*" class="emptyStateContainer">
|
||||||
<StackLayout row="1" class="emptyState" v-if="
|
<StackLayout
|
||||||
!recipes.length &&
|
row="1"
|
||||||
!filterFavourites &&
|
class="emptyState"
|
||||||
!filterTrylater
|
v-if="!recipes.length && !filterFavourites && !filterTrylater"
|
||||||
" @tap="addRecipe">
|
@tap="addRecipe"
|
||||||
|
>
|
||||||
<Label class="er icon" :text="icon.plusc" />
|
<Label class="er icon" :text="icon.plusc" />
|
||||||
<Label class="title orkm" :text="'strAdd' | L" textWrap="true" />
|
<Label class="title orkm" :text="'strAdd' | L" textWrap="true" />
|
||||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||||
<Label :text="'plsAdd' | L" textWrap="true" />
|
<Label :text="'plsAdd' | L" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && filterTrylater && !searchQuery">
|
<StackLayout
|
||||||
|
row="1"
|
||||||
|
class="emptyState"
|
||||||
|
v-if="!filteredRecipes.length && filterTrylater && !searchQuery"
|
||||||
|
>
|
||||||
<Label class="er icon" :text="icon.try" textWrap="true" />
|
<Label class="er icon" :text="icon.try" textWrap="true" />
|
||||||
<Label class="title orkm" :text="'aD' | L" textWrap="true" />
|
<Label class="title orkm" :text="'aD' | L" textWrap="true" />
|
||||||
<Label :text="'tLInfo' | L" textWrap="true" />
|
<Label :text="'tLInfo' | L" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && filterFavourites && !searchQuery">
|
<StackLayout
|
||||||
|
row="1"
|
||||||
|
class="emptyState"
|
||||||
|
v-if="!filteredRecipes.length && filterFavourites && !searchQuery"
|
||||||
|
>
|
||||||
<Label class="er icon" :text="icon.fav" textWrap="true" />
|
<Label class="er icon" :text="icon.fav" textWrap="true" />
|
||||||
<Label class="title orkm" :text="'noFavs' | L" textWrap="true" />
|
<Label class="title orkm" :text="'noFavs' | L" textWrap="true" />
|
||||||
<Label :text="'fsList' | L" textWrap="true" />
|
<Label :text="'fsList' | L" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout row="1" class="emptyState" v-if="!filteredRecipes.length && searchQuery">
|
<StackLayout
|
||||||
|
row="1"
|
||||||
|
class="emptyState"
|
||||||
|
v-if="!filteredRecipes.length && searchQuery"
|
||||||
|
>
|
||||||
<Label class="er icon" :text="icon.noresult" textWrap="true" />
|
<Label class="er icon" :text="icon.noresult" textWrap="true" />
|
||||||
<Label class="title orkm" :text="`${noResultFor}` | L" textWrap="true" />
|
<Label
|
||||||
<MDButton v-if="filterFavourites || filterTrylater || selectedCuisine" variant="text" class="searchAll orkm" :text="'trySer' | L" @tap="searchAll" />
|
class="title orkm"
|
||||||
|
:text="`${noResultFor}` | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
v-if="filterFavourites || filterTrylater || selectedCuisine"
|
||||||
|
variant="text"
|
||||||
|
class="searchAll orkm"
|
||||||
|
:text="'trySer' | L"
|
||||||
|
@tap="searchAll"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
<GridLayout id="btnFabContainer" rows="*, auto" columns="*, auto">
|
||||||
<transition name="bounce">
|
<transition name="bounce">
|
||||||
<MDFloatingActionButton v-if="showFAB" row="1" col="1" class="er fab-button" src="res://plus" @tap="addRecipe" />
|
<MDFloatingActionButton
|
||||||
|
v-if="showFAB"
|
||||||
|
row="1"
|
||||||
|
col="1"
|
||||||
|
class="er fab-button"
|
||||||
|
src="res://plus"
|
||||||
|
@tap="addRecipe"
|
||||||
|
/>
|
||||||
</transition>
|
</transition>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</AbsoluteLayout>
|
</AbsoluteLayout>
|
||||||
|
@ -124,29 +332,17 @@ import {
|
||||||
Utils,
|
Utils,
|
||||||
Observable,
|
Observable,
|
||||||
Device,
|
Device,
|
||||||
Screen
|
Screen,
|
||||||
}
|
} from "@nativescript/core";
|
||||||
from "@nativescript/core";
|
import { localize } from "@nativescript/localize";
|
||||||
import {
|
import { time } from "tns-core-modules/profiling";
|
||||||
localize
|
|
||||||
}
|
|
||||||
from "@nativescript/localize"
|
|
||||||
import {
|
|
||||||
time
|
|
||||||
} from "tns-core-modules/profiling"
|
|
||||||
import {
|
import {
|
||||||
startAccelerometerUpdates,
|
startAccelerometerUpdates,
|
||||||
stopAccelerometerUpdates,
|
stopAccelerometerUpdates,
|
||||||
} from "nativescript-accelerometer"
|
} from "nativescript-accelerometer";
|
||||||
import {
|
import { Vibrate } from "nativescript-vibrate";
|
||||||
Vibrate
|
|
||||||
} from 'nativescript-vibrate';
|
|
||||||
let vibrator = new Vibrate();
|
let vibrator = new Vibrate();
|
||||||
import {
|
import { mapActions, mapState } from "vuex";
|
||||||
mapActions,
|
|
||||||
mapState
|
|
||||||
}
|
|
||||||
from "vuex";
|
|
||||||
import EditRecipe from "./EditRecipe.vue";
|
import EditRecipe from "./EditRecipe.vue";
|
||||||
import ViewRecipe from "./ViewRecipe.vue";
|
import ViewRecipe from "./ViewRecipe.vue";
|
||||||
import ActionDialog from "./modal/ActionDialog.vue";
|
import ActionDialog from "./modal/ActionDialog.vue";
|
||||||
|
@ -157,10 +353,20 @@ let lastForce = 0;
|
||||||
let shakeCount = 0;
|
let shakeCount = 0;
|
||||||
let typingTimer;
|
let typingTimer;
|
||||||
export default {
|
export default {
|
||||||
props: [ "filterFavourites", "filterTrylater", "closeDrawer", "showDrawer", "selectedCategory", "selectedCuisine", "selectedTag", "hijackGlobalBackEvent", "releaseGlobalBackEvent" ],
|
props: [
|
||||||
|
"filterFavourites",
|
||||||
|
"filterTrylater",
|
||||||
|
"closeDrawer",
|
||||||
|
"showDrawer",
|
||||||
|
"selectedCategory",
|
||||||
|
"selectedCuisine",
|
||||||
|
"selectedTag",
|
||||||
|
"hijackGlobalBackEvent",
|
||||||
|
"releaseGlobalBackEvent",
|
||||||
|
],
|
||||||
components: {
|
components: {
|
||||||
EditRecipe,
|
EditRecipe,
|
||||||
ViewRecipe
|
ViewRecipe,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -178,26 +384,63 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState( [ "sortType", "icon", "recipes", "currentComponent", "shakeEnabled" ] ),
|
...mapState([
|
||||||
|
"sortType",
|
||||||
|
"icon",
|
||||||
|
"recipes",
|
||||||
|
"currentComponent",
|
||||||
|
"shakeEnabled",
|
||||||
|
]),
|
||||||
filteredRecipes() {
|
filteredRecipes() {
|
||||||
let ingredients = this.recipes.map( e => e.ingredients.map( f => f.item.toLowerCase() ).join() ).join()
|
let ingredients = this.recipes
|
||||||
|
.map((e) => e.ingredients.map((f) => f.item.toLowerCase()).join())
|
||||||
|
.join();
|
||||||
|
|
||||||
let vm = this
|
let vm = this;
|
||||||
|
|
||||||
function getIngredients(e) {
|
function getIngredients(e) {
|
||||||
return e.ingredients.map( f => f.item.toLowerCase() ).join().includes( vm.searchQuery );
|
return e.ingredients
|
||||||
|
.map((f) => f.item.toLowerCase())
|
||||||
|
.join()
|
||||||
|
.includes(vm.searchQuery);
|
||||||
}
|
}
|
||||||
// if ( this.filterDone ) {
|
// if ( this.filterDone ) {
|
||||||
if (this.filterFavourites) {
|
if (this.filterFavourites) {
|
||||||
return this.recipes.filter( e => e.isFavorite && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) ).sort( this.sortFunction )
|
return this.recipes
|
||||||
|
.filter(
|
||||||
|
(e) =>
|
||||||
|
e.isFavorite &&
|
||||||
|
(e.title.toLowerCase().includes(this.searchQuery) ||
|
||||||
|
getIngredients(e))
|
||||||
|
)
|
||||||
|
.sort(this.sortFunction);
|
||||||
} else if (this.filterTrylater) {
|
} else if (this.filterTrylater) {
|
||||||
return this.recipes.filter( e => !e.tried && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) ).sort( this.sortFunction )
|
return this.recipes
|
||||||
|
.filter(
|
||||||
|
(e) =>
|
||||||
|
!e.tried &&
|
||||||
|
(e.title.toLowerCase().includes(this.searchQuery) ||
|
||||||
|
getIngredients(e))
|
||||||
|
)
|
||||||
|
.sort(this.sortFunction);
|
||||||
} else if (this.selectedCuisine) {
|
} else if (this.selectedCuisine) {
|
||||||
return this.recipes.filter( e => {
|
return this.recipes
|
||||||
return this.recipeFilter( e ) && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) )
|
.filter((e) => {
|
||||||
} ).sort( this.sortFunction )
|
return (
|
||||||
|
this.recipeFilter(e) &&
|
||||||
|
(e.title.toLowerCase().includes(this.searchQuery) ||
|
||||||
|
getIngredients(e))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.sort(this.sortFunction);
|
||||||
} else {
|
} else {
|
||||||
return this.recipes.filter( e => e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ).sort( this.sortFunction )
|
return this.recipes
|
||||||
|
.filter(
|
||||||
|
(e) =>
|
||||||
|
e.title.toLowerCase().includes(this.searchQuery) ||
|
||||||
|
getIngredients(e)
|
||||||
|
)
|
||||||
|
.sort(this.sortFunction);
|
||||||
}
|
}
|
||||||
// } else {
|
// } else {
|
||||||
// return 0;
|
// return 0;
|
||||||
|
@ -210,25 +453,35 @@ export default {
|
||||||
return "noRecs";
|
return "noRecs";
|
||||||
},
|
},
|
||||||
screenWidth() {
|
screenWidth() {
|
||||||
return Screen.mainScreen.widthDIPs
|
return Screen.mainScreen.widthDIPs;
|
||||||
},
|
},
|
||||||
imgWidth() {
|
imgWidth() {
|
||||||
return Screen.mainScreen.widthDIPs / 2 - 20
|
return Screen.mainScreen.widthDIPs / 2 - 20;
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions( [ "setCurrentComponentAction", "setSortTypeAction", "deleteRecipeAction", "deleteRecipesAction" ] ),
|
...mapActions([
|
||||||
|
"setCurrentComponentAction",
|
||||||
|
"setSortTypeAction",
|
||||||
|
"deleteRecipeAction",
|
||||||
|
"deleteRecipesAction",
|
||||||
|
]),
|
||||||
onPageLoad(args) {
|
onPageLoad(args) {
|
||||||
const page = args.object;
|
const page = args.object;
|
||||||
page.bindingContext = new Observable();
|
page.bindingContext = new Observable();
|
||||||
this.filterFavourites ? this.setComponent( "Favourites" ) : this.filterTrylater ? this.setComponent( "Try Later" ) : this.selectedCuisine ? this.setComponent( "Filtered recipes" ) : this.setComponent( "EnRecipes" )
|
this.filterFavourites
|
||||||
if ( !this.selectMode ) this.showFAB = true
|
? this.setComponent("Favourites")
|
||||||
if ( this.shakeEnabled ) startAccelerometerUpdates( data => this.onSensorData( data ) )
|
: this.filterTrylater
|
||||||
if ( this.showSearch || this.selectMode )
|
? this.setComponent("Try Later")
|
||||||
this.hijackLocalBackEvent()
|
: this.selectedCuisine
|
||||||
this.showDrawer()
|
? this.setComponent("Filtered recipes")
|
||||||
this.closeDrawer()
|
: this.setComponent("EnRecipes");
|
||||||
|
if (!this.selectMode) this.showFAB = true;
|
||||||
|
if (this.shakeEnabled)
|
||||||
|
startAccelerometerUpdates((data) => this.onSensorData(data));
|
||||||
|
if (this.showSearch || this.selectMode) this.hijackLocalBackEvent();
|
||||||
|
this.showDrawer();
|
||||||
|
this.closeDrawer();
|
||||||
},
|
},
|
||||||
onPageUnload() {
|
onPageUnload() {
|
||||||
if (this.shakeEnabled) stopAccelerometerUpdates();
|
if (this.shakeEnabled) stopAccelerometerUpdates();
|
||||||
|
@ -236,8 +489,8 @@ export default {
|
||||||
this.releaseLocalBackEvent();
|
this.releaseLocalBackEvent();
|
||||||
},
|
},
|
||||||
listViewLoad(args) {
|
listViewLoad(args) {
|
||||||
let e = args.object.android
|
let e = args.object.android;
|
||||||
e.setSelector( new android.graphics.drawable.StateListDrawable() )
|
e.setSelector(new android.graphics.drawable.StateListDrawable());
|
||||||
e.setDivider(null);
|
e.setDivider(null);
|
||||||
e.setDividerHeight(1);
|
e.setDividerHeight(1);
|
||||||
},
|
},
|
||||||
|
@ -248,11 +501,11 @@ export default {
|
||||||
getLayout() {
|
getLayout() {
|
||||||
switch (this.layout) {
|
switch (this.layout) {
|
||||||
case 1:
|
case 1:
|
||||||
return 'one';
|
return "one";
|
||||||
case 2:
|
case 2:
|
||||||
return 'two';
|
return "two";
|
||||||
case 3:
|
case 3:
|
||||||
return 'three';
|
return "three";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -274,51 +527,58 @@ export default {
|
||||||
this.hijackGlobalBackEvent();
|
this.hijackGlobalBackEvent();
|
||||||
},
|
},
|
||||||
clearSearch() {
|
clearSearch() {
|
||||||
this.searchQuery = ""
|
this.searchQuery = "";
|
||||||
},
|
},
|
||||||
updateList(value) {
|
updateList(value) {
|
||||||
clearTimeout( typingTimer )
|
clearTimeout(typingTimer);
|
||||||
typingTimer = setTimeout( e => {
|
typingTimer = setTimeout((e) => {
|
||||||
this.searchQuery = value
|
this.searchQuery = value;
|
||||||
}, 750 )
|
}, 750);
|
||||||
},
|
},
|
||||||
formattedTotalTime(prepTime, cookTime) {
|
formattedTotalTime(prepTime, cookTime) {
|
||||||
let t1 = prepTime.split(":");
|
let t1 = prepTime.split(":");
|
||||||
let t2 = cookTime.split(":");
|
let t2 = cookTime.split(":");
|
||||||
let minutes = parseInt( t1[ 1 ] ) + parseInt( t2[ 1 ] )
|
let minutes = parseInt(t1[1]) + parseInt(t2[1]);
|
||||||
let m = minutes % 60
|
let m = minutes % 60;
|
||||||
let h = parseInt(t1[0]) + parseInt(t2[0]) + Math.floor(minutes / 60);
|
let h = parseInt(t1[0]) + parseInt(t2[0]) + Math.floor(minutes / 60);
|
||||||
let hr = localize( 'hr' )
|
let hr = localize("hr");
|
||||||
let min = localize( 'min' )
|
let min = localize("min");
|
||||||
let mins = h * 60 + m
|
let mins = h * 60 + m;
|
||||||
return {
|
return {
|
||||||
time: h ? (m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}`) : `${m} ${min}`,
|
time: h ? (m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}`) : `${m} ${min}`,
|
||||||
duration: `${mins}`
|
duration: `${mins}`,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
randomRecipeID() { // TODO: show only from selected filter
|
randomRecipeID() {
|
||||||
let min = 0
|
// TODO: show only from selected filter
|
||||||
let max = this.filteredRecipes.length - 1
|
let min = 0;
|
||||||
let randomIndex = Math.round( Math.random() * ( max - min ) )
|
let max = this.filteredRecipes.length - 1;
|
||||||
return this.filteredRecipes[ randomIndex ].id
|
let randomIndex = Math.round(Math.random() * (max - min));
|
||||||
|
return this.filteredRecipes[randomIndex].id;
|
||||||
},
|
},
|
||||||
recipeFilter(e) {
|
recipeFilter(e) {
|
||||||
let cuisineMatched = e.cuisine === this.selectedCuisine
|
let cuisineMatched = e.cuisine === this.selectedCuisine;
|
||||||
let allCuisines = /allCuis/.test( this.selectedCuisine )
|
let allCuisines = /allCuis/.test(this.selectedCuisine);
|
||||||
let categoryMatched = e.category === this.selectedCategory
|
let categoryMatched = e.category === this.selectedCategory;
|
||||||
let allCategories = /allCats/.test( this.selectedCategory )
|
let allCategories = /allCats/.test(this.selectedCategory);
|
||||||
let tagMatched = e.tags.includes( this.selectedTag )
|
let tagMatched = e.tags.includes(this.selectedTag);
|
||||||
let allTags = /allTs/.test( this.selectedTag )
|
let allTags = /allTs/.test(this.selectedTag);
|
||||||
let cuisine = cuisineMatched || allCuisines
|
let cuisine = cuisineMatched || allCuisines;
|
||||||
|
|
||||||
return this.selectedTag && !allTags ? ( categoryMatched || allCategories ) && cuisine && tagMatched : this.selectedCategory && !allCategories ? cuisine && categoryMatched : cuisine
|
return this.selectedTag && !allTags
|
||||||
|
? (categoryMatched || allCategories) && cuisine && tagMatched
|
||||||
|
: this.selectedCategory && !allCategories
|
||||||
|
? cuisine && categoryMatched
|
||||||
|
: cuisine;
|
||||||
},
|
},
|
||||||
searchAll() {
|
searchAll() {
|
||||||
this.$emit( "backToHome" )
|
this.$emit("backToHome");
|
||||||
},
|
},
|
||||||
sortFunction(a, b) {
|
sortFunction(a, b) {
|
||||||
const titleOrder = a.title.toLowerCase().localeCompare( b.title.toLowerCase(), Device.language, {
|
const titleOrder = a.title
|
||||||
ignorePunctuation: true
|
.toLowerCase()
|
||||||
|
.localeCompare(b.title.toLowerCase(), Device.language, {
|
||||||
|
ignorePunctuation: true,
|
||||||
});
|
});
|
||||||
let d1 = this.formattedTotalTime(a.prepTime, a.cookTime).duration;
|
let d1 = this.formattedTotalTime(a.prepTime, a.cookTime).duration;
|
||||||
let d2 = this.formattedTotalTime(b.prepTime, b.cookTime).duration;
|
let d2 = this.formattedTotalTime(b.prepTime, b.cookTime).duration;
|
||||||
|
@ -326,8 +586,8 @@ export default {
|
||||||
let ld2 = new Date(b.lastModified);
|
let ld2 = new Date(b.lastModified);
|
||||||
let cd1 = new Date(a.created);
|
let cd1 = new Date(a.created);
|
||||||
let cd2 = new Date(b.created);
|
let cd2 = new Date(b.created);
|
||||||
let r1 = a.rating
|
let r1 = a.rating;
|
||||||
let r2 = b.rating
|
let r2 = b.rating;
|
||||||
|
|
||||||
function difficultyLevel(l) {
|
function difficultyLevel(l) {
|
||||||
switch (l) {
|
switch (l) {
|
||||||
|
@ -339,8 +599,8 @@ export default {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dl1 = difficultyLevel( a.difficulty )
|
let dl1 = difficultyLevel(a.difficulty);
|
||||||
let dl2 = difficultyLevel( b.difficulty )
|
let dl2 = difficultyLevel(b.difficulty);
|
||||||
switch (this.sortType) {
|
switch (this.sortType) {
|
||||||
case "Title":
|
case "Title":
|
||||||
return titleOrder > 0 ? 1 : titleOrder < 0 ? -1 : 0;
|
return titleOrder > 0 ? 1 : titleOrder < 0 ? -1 : 0;
|
||||||
|
@ -369,33 +629,42 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isFirstItem(id) {
|
isFirstItem(id) {
|
||||||
let length = this.filteredRecipes.length
|
let length = this.filteredRecipes.length;
|
||||||
return id == this.filteredRecipes[ 0 ].id ? 'firstItem' : id == this.filteredRecipes[ length - 1 ].id ? 'lastItem' : ''
|
return id == this.filteredRecipes[0].id
|
||||||
|
? "firstItem"
|
||||||
|
: id == this.filteredRecipes[length - 1].id
|
||||||
|
? "lastItem"
|
||||||
|
: "";
|
||||||
},
|
},
|
||||||
isLastItem(id) {
|
isLastItem(id) {
|
||||||
let length = this.filteredRecipes.length
|
let length = this.filteredRecipes.length;
|
||||||
// let lastIsOdd = ( length - 1 ) % 2 == 0
|
// let lastIsOdd = ( length - 1 ) % 2 == 0
|
||||||
// if ( this.filteredRecipes.length > 1 ) {
|
// if ( this.filteredRecipes.length > 1 ) {
|
||||||
// if ( id == this.filteredRecipes[ length - 2 ].id ) {
|
// if ( id == this.filteredRecipes[ length - 2 ].id ) {
|
||||||
// if ( !lastIsOdd ) return 'lastItem'
|
// if ( !lastIsOdd ) return 'lastItem'
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if ( id == this.filteredRecipes[ length - 1 ].id ) return 'lastItem'
|
if (id == this.filteredRecipes[length - 1].id) return "lastItem";
|
||||||
},
|
},
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
// NAVIGATION HANDLERS
|
||||||
hijackLocalBackEvent() {
|
hijackLocalBackEvent() {
|
||||||
this.releaseGlobalBackEvent();
|
this.releaseGlobalBackEvent();
|
||||||
AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.localBackEvent );
|
AndroidApplication.on(
|
||||||
|
AndroidApplication.activityBackPressedEvent,
|
||||||
|
this.localBackEvent
|
||||||
|
);
|
||||||
},
|
},
|
||||||
releaseLocalBackEvent() {
|
releaseLocalBackEvent() {
|
||||||
AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.localBackEvent );
|
AndroidApplication.off(
|
||||||
|
AndroidApplication.activityBackPressedEvent,
|
||||||
|
this.localBackEvent
|
||||||
|
);
|
||||||
this.hijackGlobalBackEvent();
|
this.hijackGlobalBackEvent();
|
||||||
},
|
},
|
||||||
localBackEvent(args) {
|
localBackEvent(args) {
|
||||||
args.cancel = true;
|
args.cancel = true;
|
||||||
if ( this.selectMode )
|
if (this.selectMode) this.clearSelection();
|
||||||
this.clearSelection()
|
|
||||||
this.closeDrawer();
|
this.closeDrawer();
|
||||||
this.closeSearch();
|
this.closeSearch();
|
||||||
},
|
},
|
||||||
|
@ -409,7 +678,7 @@ export default {
|
||||||
selectedTag: this.selectedTag,
|
selectedTag: this.selectedTag,
|
||||||
filterFavourites: this.filterFavourites,
|
filterFavourites: this.filterFavourites,
|
||||||
filterTrylater: this.filterTrylater,
|
filterTrylater: this.filterTrylater,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
viewRecipe(recipeID) {
|
viewRecipe(recipeID) {
|
||||||
|
@ -417,9 +686,9 @@ export default {
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
props: {
|
props: {
|
||||||
filterTrylater: this.filterTrylater,
|
filterTrylater: this.filterTrylater,
|
||||||
recipeID
|
recipeID,
|
||||||
},
|
},
|
||||||
backstackVisible: false
|
backstackVisible: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
viewRandomRecipe() {
|
viewRandomRecipe() {
|
||||||
|
@ -427,9 +696,9 @@ export default {
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
props: {
|
props: {
|
||||||
filterTrylater: false,
|
filterTrylater: false,
|
||||||
recipeID: this.randomRecipeID()
|
recipeID: this.randomRecipeID(),
|
||||||
},
|
},
|
||||||
backstackVisible: false
|
backstackVisible: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -439,15 +708,24 @@ export default {
|
||||||
this.$showModal(ActionDialog, {
|
this.$showModal(ActionDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: "srt",
|
title: "srt",
|
||||||
list: [ "Title", "Quickest first", "Slowest first", "Rating", "Difficulty level", "Last updated", "Newest first", "Oldest first" ],
|
list: [
|
||||||
|
"Title",
|
||||||
|
"Quickest first",
|
||||||
|
"Slowest first",
|
||||||
|
"Rating",
|
||||||
|
"Difficulty level",
|
||||||
|
"Last updated",
|
||||||
|
"Newest first",
|
||||||
|
"Oldest first",
|
||||||
|
],
|
||||||
stretch: false,
|
stretch: false,
|
||||||
helpIcon: 'sort',
|
helpIcon: "sort",
|
||||||
bgColor: '#858585',
|
bgColor: "#858585",
|
||||||
}
|
},
|
||||||
} ).then( action => {
|
}).then((action) => {
|
||||||
if (action && action !== "Cancel" && this.sortType !== action) {
|
if (action && action !== "Cancel" && this.sortType !== action) {
|
||||||
this.setSortTypeAction( action )
|
this.setSortTypeAction(action);
|
||||||
ApplicationSettings.setString( "sortType", action )
|
ApplicationSettings.setString("sortType", action);
|
||||||
this.updateSort();
|
this.updateSort();
|
||||||
}
|
}
|
||||||
this.hijackGlobalBackEvent();
|
this.hijackGlobalBackEvent();
|
||||||
|
@ -456,60 +734,58 @@ export default {
|
||||||
|
|
||||||
// DATA HANDLERS
|
// DATA HANDLERS
|
||||||
addToSelection(args, id) {
|
addToSelection(args, id) {
|
||||||
this.showFAB = false
|
this.showFAB = false;
|
||||||
if ( !this.selectMode )
|
if (!this.selectMode) this.hijackLocalBackEvent();
|
||||||
this.hijackLocalBackEvent()
|
this.selectMode = true;
|
||||||
this.selectMode = true
|
this.$emit("selectModeOn", false);
|
||||||
this.$emit( "selectModeOn", false )
|
let item = args.object;
|
||||||
let item = args.object
|
|
||||||
if (item.className === "selected") {
|
if (item.className === "selected") {
|
||||||
item.className = ""
|
item.className = "";
|
||||||
this.selection.splice( this.selection.indexOf( id ), 1 )
|
this.selection.splice(this.selection.indexOf(id), 1);
|
||||||
this.recipeList.splice( this.selection.indexOf( id ), 1 )
|
this.recipeList.splice(this.selection.indexOf(id), 1);
|
||||||
} else {
|
} else {
|
||||||
item.className = "selected"
|
item.className = "selected";
|
||||||
this.selection.push( id )
|
this.selection.push(id);
|
||||||
this.recipeList.push( item )
|
this.recipeList.push(item);
|
||||||
}
|
}
|
||||||
if ( !this.selection.length )
|
if (!this.selection.length) this.clearSelection();
|
||||||
this.clearSelection()
|
|
||||||
|
|
||||||
},
|
},
|
||||||
clearSelection() {
|
clearSelection() {
|
||||||
this.selectMode = false
|
this.selectMode = false;
|
||||||
this.$emit( "selectModeOn", true )
|
this.$emit("selectModeOn", true);
|
||||||
this.selection = []
|
this.selection = [];
|
||||||
this.recipeList.forEach( e => e.className = "" )
|
this.recipeList.forEach((e) => (e.className = ""));
|
||||||
this.releaseLocalBackEvent()
|
this.releaseLocalBackEvent();
|
||||||
this.showFAB = true
|
this.showFAB = true;
|
||||||
},
|
},
|
||||||
deleteSelection() {
|
deleteSelection() {
|
||||||
this.selection.length === 1 ?
|
this.selection.length === 1
|
||||||
this.deleteRecipe( this.selection[ 0 ] ) :
|
? this.deleteRecipe(this.selection[0])
|
||||||
this.deleteRecipes( this.selection )
|
: this.deleteRecipes(this.selection);
|
||||||
},
|
},
|
||||||
exportSelection() {},
|
exportSelection() {},
|
||||||
deleteRecipe(id) {
|
deleteRecipe(id) {
|
||||||
this.deletionDialogActive = true;
|
this.deletionDialogActive = true;
|
||||||
let index = this.recipes.findIndex( e => e.id === id )
|
let index = this.recipes.findIndex((e) => e.id === id);
|
||||||
this.$showModal(ConfirmDialog, {
|
this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: localize("conf"),
|
title: localize("conf"),
|
||||||
description: `${localize('delRecInfo')} "${this.recipes[index].title}"`,
|
description: `${localize("delRecInfo")} "${
|
||||||
|
this.recipes[index].title
|
||||||
|
}"`,
|
||||||
cancelButtonText: "cBtn",
|
cancelButtonText: "cBtn",
|
||||||
okButtonText: "dBtn",
|
okButtonText: "dBtn",
|
||||||
helpIcon: 'del',
|
helpIcon: "del",
|
||||||
bgColor: '#c92a2a',
|
bgColor: "#c92a2a",
|
||||||
}
|
},
|
||||||
} ).then( action => {
|
}).then((action) => {
|
||||||
if (action) {
|
if (action) {
|
||||||
this.deleteRecipeAction({
|
this.deleteRecipeAction({
|
||||||
index,
|
index,
|
||||||
id
|
id,
|
||||||
});
|
});
|
||||||
if ( !this.filteredRecipes.length )
|
if (!this.filteredRecipes.length) this.$emit("backToHome");
|
||||||
this.$emit( 'backToHome' )
|
this.clearSelection();
|
||||||
this.clearSelection()
|
|
||||||
}
|
}
|
||||||
this.deletionDialogActive = false;
|
this.deletionDialogActive = false;
|
||||||
});
|
});
|
||||||
|
@ -519,52 +795,51 @@ export default {
|
||||||
this.$showModal(ConfirmDialog, {
|
this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: localize("conf"),
|
title: localize("conf"),
|
||||||
description: `${localize('delRecsInfo')} ${this.selection.length} ${localize('recs')}`,
|
description: `${localize("delRecsInfo")} ${
|
||||||
|
this.selection.length
|
||||||
|
} ${localize("recs")}`,
|
||||||
cancelButtonText: "cBtn",
|
cancelButtonText: "cBtn",
|
||||||
okButtonText: "dBtn",
|
okButtonText: "dBtn",
|
||||||
helpIcon: 'del',
|
helpIcon: "del",
|
||||||
bgColor: '#c92a2a',
|
bgColor: "#c92a2a",
|
||||||
}
|
},
|
||||||
} ).then( action => {
|
}).then((action) => {
|
||||||
if (action) {
|
if (action) {
|
||||||
this.deleteRecipesAction(idsArr);
|
this.deleteRecipesAction(idsArr);
|
||||||
if ( !this.filteredRecipes.length )
|
if (!this.filteredRecipes.length) this.$emit("backToHome");
|
||||||
this.$emit( 'backToHome' )
|
this.clearSelection();
|
||||||
this.clearSelection()
|
|
||||||
}
|
}
|
||||||
this.deletionDialogActive = false;
|
this.deletionDialogActive = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// SHAKE DETECTOR
|
// SHAKE DETECTOR
|
||||||
onSensorData( {
|
onSensorData({ x, y, z }) {
|
||||||
x,
|
x = x.toFixed(2);
|
||||||
y,
|
y = y.toFixed(2);
|
||||||
z
|
z = z.toFixed(2);
|
||||||
} ) {
|
|
||||||
x = x.toFixed( 2 )
|
|
||||||
y = y.toFixed( 2 )
|
|
||||||
z = z.toFixed( 2 )
|
|
||||||
const FORCE_THRESHOLD = 1;
|
const FORCE_THRESHOLD = 1;
|
||||||
const TIME_THRESHOLD = 150;
|
const TIME_THRESHOLD = 150;
|
||||||
const SHAKE_TIMEOUT = 600;
|
const SHAKE_TIMEOUT = 600;
|
||||||
const SHAKE_THROTTLE = 600;
|
const SHAKE_THROTTLE = 600;
|
||||||
const SHAKE_COUNT = 3;
|
const SHAKE_COUNT = 3;
|
||||||
const now = time()
|
const now = time();
|
||||||
if ( ( now - lastForce ) > SHAKE_TIMEOUT ) {
|
if (now - lastForce > SHAKE_TIMEOUT) {
|
||||||
shakeCount = 0;
|
shakeCount = 0;
|
||||||
}
|
}
|
||||||
let timeDelta = now - lastTime;
|
let timeDelta = now - lastTime;
|
||||||
if (timeDelta > TIME_THRESHOLD) {
|
if (timeDelta > TIME_THRESHOLD) {
|
||||||
let forceVector = Math.abs( Math.sqrt( Math.pow( x, 2 ) + Math.pow( y, 2 ) + Math.pow( z, 2 ) ) - 1 );
|
let forceVector = Math.abs(
|
||||||
|
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)) - 1
|
||||||
|
);
|
||||||
if (forceVector > FORCE_THRESHOLD) {
|
if (forceVector > FORCE_THRESHOLD) {
|
||||||
shakeCount++;
|
shakeCount++;
|
||||||
if ( ( shakeCount >= SHAKE_COUNT ) && ( now - lastShake > SHAKE_THROTTLE ) ) {
|
if (shakeCount >= SHAKE_COUNT && now - lastShake > SHAKE_THROTTLE) {
|
||||||
lastShake = now;
|
lastShake = now;
|
||||||
shakeCount = 0;
|
shakeCount = 0;
|
||||||
if (this.filteredRecipes.length) {
|
if (this.filteredRecipes.length) {
|
||||||
vibrator.vibrate( 100 )
|
vibrator.vibrate(100);
|
||||||
this.viewRandomRecipe()
|
this.viewRandomRecipe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastForce = now;
|
lastForce = now;
|
||||||
|
@ -574,7 +849,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.showFAB = true
|
this.showFAB = true;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,57 +2,57 @@
|
||||||
<Page @loaded="onPageLoad">
|
<Page @loaded="onPageLoad">
|
||||||
<ActionBar flat="true">
|
<ActionBar flat="true">
|
||||||
<GridLayout rows="*" columns="auto, *, auto">
|
<GridLayout rows="*" columns="auto, *, auto">
|
||||||
<MDButton class="er left" variant="text" :text="icon.back" automationText="Back" @tap="$navigateBack()" col="0" />
|
<MDButton
|
||||||
|
class="er left"
|
||||||
|
variant="text"
|
||||||
|
:text="icon.back"
|
||||||
|
automationText="Back"
|
||||||
|
@tap="$navigateBack()"
|
||||||
|
col="0"
|
||||||
|
/>
|
||||||
<Label class="title orkm" :text="'grocery' | L" col="1" />
|
<Label class="title orkm" :text="'grocery' | L" col="1" />
|
||||||
<MDButton class="er left" variant="text" :text="icon.today" automationText="today" col="2" />
|
<MDButton
|
||||||
|
class="er left"
|
||||||
|
variant="text"
|
||||||
|
:text="icon.today"
|
||||||
|
automationText="today"
|
||||||
|
col="2"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<GridLayout columns="" rows="">
|
<GridLayout columns="" rows=""> </GridLayout>
|
||||||
|
|
||||||
</GridLayout>
|
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { ApplicationSettings, Observable } from "@nativescript/core";
|
||||||
ApplicationSettings,
|
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
|
||||||
Observable,
|
|
||||||
}
|
|
||||||
from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
SnackBar
|
|
||||||
} from '@nativescript-community/ui-material-snackbar';
|
|
||||||
const snackbar = new SnackBar();
|
const snackbar = new SnackBar();
|
||||||
import {
|
import { mapState, mapActions } from "vuex";
|
||||||
mapState,
|
|
||||||
mapActions
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
appTheme: "Light",
|
appTheme: "Light",
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes", "mealPlans"]),
|
...mapState(["icon", "recipes", "mealPlans"]),
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme === "Light"
|
return this.appTheme === "Light";
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["setCurrentComponentAction"]),
|
...mapActions(["setCurrentComponentAction"]),
|
||||||
onPageLoad(args) {
|
onPageLoad(args) {
|
||||||
const page = args.object;
|
const page = args.object;
|
||||||
page.bindingContext = new Observable();
|
page.bindingContext = new Observable();
|
||||||
this.setCurrentComponentAction( "GroceryList" )
|
this.setCurrentComponentAction("GroceryList");
|
||||||
},
|
},
|
||||||
// HELPERS
|
// HELPERS
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
// NAVIGATION HANDLERS
|
||||||
viewRecipe(recipeID) {
|
viewRecipe(recipeID) {
|
||||||
let recipe = this.recipes.filter( ( e ) => e.id === recipeID )[ 0 ]
|
let recipe = this.recipes.filter((e) => e.id === recipeID)[0];
|
||||||
if (recipe) {
|
if (recipe) {
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
props: {
|
props: {
|
||||||
|
@ -60,24 +60,23 @@ export default {
|
||||||
recipeID,
|
recipeID,
|
||||||
},
|
},
|
||||||
backstackVisible: false,
|
backstackVisible: false,
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// DATA HANDLERS
|
// DATA HANDLERS
|
||||||
undoRemove(message) {
|
undoRemove(message) {
|
||||||
return snackbar
|
return snackbar.action({
|
||||||
.action( {
|
|
||||||
message,
|
message,
|
||||||
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
|
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
|
||||||
actionTextColor: '#ff5200',
|
actionTextColor: "#ff5200",
|
||||||
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
|
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
|
||||||
actionText: 'Undo',
|
actionText: "Undo",
|
||||||
hideDelay: 5000
|
hideDelay: 5000,
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,35 +2,140 @@
|
||||||
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
|
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
|
||||||
<ActionBar androidElevation="1">
|
<ActionBar androidElevation="1">
|
||||||
<GridLayout rows="*" columns="auto, *, auto, auto">
|
<GridLayout rows="*" columns="auto, *, auto, auto">
|
||||||
<MDButton class="er" variant="text" :text="icon.back" automationText="Back" @tap="$navigateBack()" col="0" />
|
<MDButton
|
||||||
|
class="er"
|
||||||
|
variant="text"
|
||||||
|
:text="icon.back"
|
||||||
|
automationText="Back"
|
||||||
|
@tap="$navigateBack()"
|
||||||
|
col="0"
|
||||||
|
/>
|
||||||
<Label class="title orkm" :text="'planner' | L" col="1" />
|
<Label class="title orkm" :text="'planner' | L" col="1" />
|
||||||
<MDButton class="er" variant="text" :text="icon.tod" automationText="today" @tap="goToToday" col="2" />
|
<MDButton
|
||||||
<MDButton class="er" variant="text" :text="edit ? icon.done : icon.edit" automationText="edit" @tap="edit = !edit" col="3" />
|
class="er"
|
||||||
|
variant="text"
|
||||||
|
:text="icon.tod"
|
||||||
|
automationText="today"
|
||||||
|
@tap="goToToday"
|
||||||
|
col="2"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
class="er"
|
||||||
|
variant="text"
|
||||||
|
:text="edit ? icon.done : icon.edit"
|
||||||
|
automationText="edit"
|
||||||
|
@tap="edit = !edit"
|
||||||
|
col="3"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<ScrollView width="100%" height="100%">
|
<ScrollView width="100%" height="100%">
|
||||||
<GridLayout rows="auto, *">
|
<GridLayout rows="auto, *">
|
||||||
<GridLayout class="calendar" width="100%" row="0" columns="*, *, *, *, *, *, *" rows="auto, auto, auto, auto, auto, auto, auto, auto">
|
<GridLayout
|
||||||
<MDButton variant="text" class="er navBtn" col="0" :text="icon.left" @tap="prevMonth" />
|
class="calendar"
|
||||||
<Label class="monthName" col="1" colSpan="5" :text="$options.filters.L(mNames[month]) + ' ' + year" />
|
width="100%"
|
||||||
<MDButton variant="text" class="er navBtn" col="6" :text="icon.right" @tap="nextMonth" />
|
row="0"
|
||||||
<Label class="dayName" row="1" :col="i" v-for="(d,i) in dNames" :key="d" :text="$options.filters.L(d)" />
|
columns="*, *, *, *, *, *, *"
|
||||||
<Label @loaded="centerLabel" class="day orkm" :androidElevation="hasPlans(d) ? 1 : 0" :class="{'today': isToday(d), 'activeDay': isActive(d),'hasPlans': hasPlans(d)}" :row="getrow(i)" :col="i % 7" v-for="(d, i) in getCal" :key="i"
|
rows="auto, auto, auto, auto, auto, auto, auto, auto"
|
||||||
:text="d ? d : null" @tap="setToday(d)" />
|
>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
class="er navBtn"
|
||||||
|
col="0"
|
||||||
|
:text="icon.left"
|
||||||
|
@tap="prevMonth"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
class="monthName"
|
||||||
|
col="1"
|
||||||
|
colSpan="5"
|
||||||
|
:text="$options.filters.L(mNames[month]) + ' ' + year"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
class="er navBtn"
|
||||||
|
col="6"
|
||||||
|
:text="icon.right"
|
||||||
|
@tap="nextMonth"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
class="dayName"
|
||||||
|
row="1"
|
||||||
|
:col="i"
|
||||||
|
v-for="(d, i) in dNames"
|
||||||
|
:key="d"
|
||||||
|
:text="$options.filters.L(d)"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
@loaded="centerLabel"
|
||||||
|
class="day orkm"
|
||||||
|
:androidElevation="hasPlans(d) ? 1 : 0"
|
||||||
|
:class="{
|
||||||
|
today: isToday(d),
|
||||||
|
activeDay: isActive(d),
|
||||||
|
hasPlans: hasPlans(d),
|
||||||
|
}"
|
||||||
|
:row="getrow(i)"
|
||||||
|
:col="i % 7"
|
||||||
|
v-for="(d, i) in getCal"
|
||||||
|
:key="i"
|
||||||
|
:text="d ? d : null"
|
||||||
|
@tap="setToday(d)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout row="1" class="dayPlan">
|
<StackLayout row="1" class="dayPlan">
|
||||||
<StackLayout class="hr" margin="16 0 0"></StackLayout>
|
<StackLayout class="hr" margin="16 0 0"></StackLayout>
|
||||||
<StackLayout v-for="(mealType, index) in mealTimes" :key="'mealType' + index" class="plansContainer" :class="mealType">
|
<StackLayout
|
||||||
|
v-for="(mealType, index) in mealTimes"
|
||||||
|
:key="'mealType' + index"
|
||||||
|
class="plansContainer"
|
||||||
|
:class="mealType"
|
||||||
|
>
|
||||||
<GridLayout columns="auto, auto" class="header">
|
<GridLayout columns="auto, auto" class="header">
|
||||||
<Label col="0" @tap="edit = true" class="periodLabel orkm" :text="mealType | L" />
|
<Label
|
||||||
<MDButton :visibility="edit ? 'visible' : 'hidden'" col="1" variant="text" class="er" :text="icon.plus" @tap="addRecipe(mealType)" />
|
col="0"
|
||||||
|
@tap="edit = true"
|
||||||
|
class="periodLabel orkm"
|
||||||
|
:text="mealType | L"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
:visibility="edit ? 'visible' : 'hidden'"
|
||||||
|
col="1"
|
||||||
|
variant="text"
|
||||||
|
class="er"
|
||||||
|
:text="icon.plus"
|
||||||
|
@tap="addRecipe(mealType)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout class="recipe" :paddingTop="index == 0?8:0" :columns="`*, ${edit ? 'auto' : 0}`" v-for="(recipeID, index) in getRecipes[mealType]" :key="mealType + index">
|
<GridLayout
|
||||||
<GridLayout androidElevation="1" col="0" columns="*" class="titleContainer">
|
class="recipe"
|
||||||
<MDRipple class="recipeRipple" @tap="viewRecipe(recipeID)" />
|
:paddingTop="index == 0 ? 8 : 0"
|
||||||
<Label verticalAlignment="center" class="recipeTitle" :text="getRecipeTitle(recipeID)" textWrap="true" />
|
:columns="`*, ${edit ? 'auto' : 0}`"
|
||||||
|
v-for="(recipeID, index) in getRecipes[mealType]"
|
||||||
|
:key="mealType + index"
|
||||||
|
>
|
||||||
|
<GridLayout
|
||||||
|
androidElevation="1"
|
||||||
|
col="0"
|
||||||
|
columns="*"
|
||||||
|
class="titleContainer mdr"
|
||||||
|
@tap="viewRecipe(recipeID)"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="recipeTitle"
|
||||||
|
:text="getRecipeTitle(recipeID)"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<MDButton :visibility="edit ? 'visible' : 'hidden'" variant="text" col="1" class="er x" :text="icon.x" @tap="removeRecipe(recipeID, mealType)" />
|
<MDButton
|
||||||
|
:visibility="edit ? 'visible' : 'hidden'"
|
||||||
|
variant="text"
|
||||||
|
col="1"
|
||||||
|
class="er x"
|
||||||
|
:text="icon.x"
|
||||||
|
@tap="removeRecipe(recipeID, mealType)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
@ -45,148 +150,162 @@ import {
|
||||||
Page,
|
Page,
|
||||||
Observable,
|
Observable,
|
||||||
GestureTypes,
|
GestureTypes,
|
||||||
}
|
} from "@nativescript/core";
|
||||||
from "@nativescript/core"
|
import { SnackBar } from "@nativescript-community/ui-material-snackbar";
|
||||||
import {
|
|
||||||
SnackBar
|
|
||||||
} from '@nativescript-community/ui-material-snackbar';
|
|
||||||
const snackbar = new SnackBar();
|
const snackbar = new SnackBar();
|
||||||
import {
|
import { mapState, mapActions } from "vuex";
|
||||||
mapState,
|
import ViewRecipe from "./ViewRecipe.vue";
|
||||||
mapActions
|
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
|
||||||
}
|
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
||||||
from "vuex"
|
|
||||||
import ViewRecipe from "./ViewRecipe.vue"
|
|
||||||
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue"
|
|
||||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
appTheme: "Light",
|
appTheme: "Light",
|
||||||
mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
|
mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
|
||||||
dNames: [ 'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT' ],
|
dNames: ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"],
|
||||||
year: 2021,
|
year: 2021,
|
||||||
mNames: [ "January", "February", "March", "April", "May", "June",
|
mNames: [
|
||||||
"July", "August", "September", "October", "November", "December"
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December",
|
||||||
],
|
],
|
||||||
month: 0,
|
month: 0,
|
||||||
today: null,
|
today: null,
|
||||||
edit: false,
|
edit: false,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes", "mealPlans"]),
|
...mapState(["icon", "recipes", "mealPlans"]),
|
||||||
todaysTime() {
|
todaysTime() {
|
||||||
return new Date( this.year, this.month, this.today, 0 ).getTime()
|
return new Date(this.year, this.month, this.today, 0).getTime();
|
||||||
},
|
},
|
||||||
getRecipes() {
|
getRecipes() {
|
||||||
if (this.mealPlans.length) {
|
if (this.mealPlans.length) {
|
||||||
return this.mealPlans.reduce((acc, e) => {
|
return this.mealPlans.reduce((acc, e) => {
|
||||||
if (e.date == this.todaysTime) {
|
if (e.date == this.todaysTime) {
|
||||||
acc[ e.type ] = [ ...( acc[ e.type ] || [] ), e.title ]
|
acc[e.type] = [...(acc[e.type] || []), e.title];
|
||||||
}
|
}
|
||||||
return acc
|
return acc;
|
||||||
}, {} )
|
}, {});
|
||||||
} else return 0
|
} else return 0;
|
||||||
},
|
},
|
||||||
getCal() {
|
getCal() {
|
||||||
let y = this.year
|
let y = this.year;
|
||||||
let m = this.month
|
let m = this.month;
|
||||||
let t = this.today
|
let t = this.today;
|
||||||
let d = new Date( y, m, t )
|
let d = new Date(y, m, t);
|
||||||
let ds = new Date( y, m + 1, 0 ).getDate()
|
let ds = new Date(y, m + 1, 0).getDate();
|
||||||
let fd = new Date( y, m, 1 ).getDay()
|
let fd = new Date(y, m, 1).getDay();
|
||||||
let days = new Array( fd ).fill( 0 )
|
let days = new Array(fd).fill(0);
|
||||||
for (let i = 1; i <= ds; i++) {
|
for (let i = 1; i <= ds; i++) {
|
||||||
days.push( i )
|
days.push(i);
|
||||||
}
|
}
|
||||||
return days;
|
return days;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions( [ "setCurrentComponentAction", "addMealPlanAction", "deleteMealPlanAction", ] ),
|
...mapActions([
|
||||||
|
"setCurrentComponentAction",
|
||||||
|
"addMealPlanAction",
|
||||||
|
"deleteMealPlanAction",
|
||||||
|
]),
|
||||||
onPageLoad(args) {
|
onPageLoad(args) {
|
||||||
const page = args.object;
|
const page = args.object;
|
||||||
page.bindingContext = new Observable();
|
page.bindingContext = new Observable();
|
||||||
this.setCurrentComponentAction( "MealPlanner" )
|
this.setCurrentComponentAction("MealPlanner");
|
||||||
if ( !this.today || this.today === new Date().getDate() ) this.goToToday()
|
if (!this.today || this.today === new Date().getDate()) this.goToToday();
|
||||||
},
|
},
|
||||||
onPageUnload(args) {
|
onPageUnload(args) {
|
||||||
snackbar.dismiss()
|
snackbar.dismiss();
|
||||||
},
|
},
|
||||||
// HELPERS
|
// HELPERS
|
||||||
getrow(i) {
|
getrow(i) {
|
||||||
return Math.floor(2 + i / 7);
|
return Math.floor(2 + i / 7);
|
||||||
},
|
},
|
||||||
getDate(index) {
|
getDate(index) {
|
||||||
let date = new Date()
|
let date = new Date();
|
||||||
date.setDate( date.getDate() + index )
|
date.setDate(date.getDate() + index);
|
||||||
return date.getTime()
|
return date.getTime();
|
||||||
},
|
},
|
||||||
getRecipeTitle(id) {
|
getRecipeTitle(id) {
|
||||||
let recipe = this.recipes.filter( ( e ) => e.id === id )[ 0 ]
|
let recipe = this.recipes.filter((e) => e.id === id)[0];
|
||||||
return recipe ? recipe.title : `[ ${this.$options.filters.L('resNF')} ]`
|
return recipe ? recipe.title : `[ ${this.$options.filters.L("resNF")} ]`;
|
||||||
},
|
},
|
||||||
centerLabel(args) {
|
centerLabel(args) {
|
||||||
args.object.android.setGravity( 17 )
|
args.object.android.setGravity(17);
|
||||||
},
|
},
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
// NAVIGATION HANDLERS
|
||||||
viewRecipe(recipeID) {
|
viewRecipe(recipeID) {
|
||||||
let recipe = this.recipes.filter( ( e ) => e.id === recipeID )[ 0 ]
|
let recipe = this.recipes.filter((e) => e.id === recipeID)[0];
|
||||||
if (recipe) {
|
if (recipe) {
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
props: {
|
props: {
|
||||||
filterTrylater: true,
|
filterTrylater: true,
|
||||||
recipeID,
|
recipeID,
|
||||||
},
|
},
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// CALENDAR
|
// CALENDAR
|
||||||
prevMonth() {
|
prevMonth() {
|
||||||
if (this.month == 0) {
|
if (this.month == 0) {
|
||||||
this.year--
|
this.year--;
|
||||||
this.month = 11
|
this.month = 11;
|
||||||
} else this.month--
|
} else this.month--;
|
||||||
},
|
},
|
||||||
nextMonth() {
|
nextMonth() {
|
||||||
if (this.month == 11) {
|
if (this.month == 11) {
|
||||||
this.year++
|
this.year++;
|
||||||
this.month = 0
|
this.month = 0;
|
||||||
} else this.month++
|
} else this.month++;
|
||||||
},
|
},
|
||||||
goToToday() {
|
goToToday() {
|
||||||
let d = new Date()
|
let d = new Date();
|
||||||
this.year = d.getFullYear()
|
this.year = d.getFullYear();
|
||||||
this.month = d.getMonth()
|
this.month = d.getMonth();
|
||||||
this.today = d.getDate()
|
this.today = d.getDate();
|
||||||
},
|
},
|
||||||
isToday(date) {
|
isToday(date) {
|
||||||
let d = new Date()
|
let d = new Date();
|
||||||
return this.year == d.getFullYear() && this.month == d.getMonth() && date == d.getDate()
|
return (
|
||||||
|
this.year == d.getFullYear() &&
|
||||||
|
this.month == d.getMonth() &&
|
||||||
|
date == d.getDate()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
isActive(date) {
|
isActive(date) {
|
||||||
return this.today == date
|
return this.today == date;
|
||||||
},
|
},
|
||||||
hasPlans(date) {
|
hasPlans(date) {
|
||||||
let d = new Date( this.year, this.month, date, 0 ).getTime()
|
let d = new Date(this.year, this.month, date, 0).getTime();
|
||||||
return this.mealPlans.filter( e => e.date == d ).length
|
return this.mealPlans.filter((e) => e.date == d).length;
|
||||||
},
|
},
|
||||||
setToday(date) {
|
setToday(date) {
|
||||||
if ( date ) this.today = date
|
if (date) this.today = date;
|
||||||
},
|
},
|
||||||
newMealPlan(title, date, type, index) {
|
newMealPlan(title, date, type, index) {
|
||||||
this.addMealPlanAction({
|
this.addMealPlanAction({
|
||||||
title,
|
title,
|
||||||
date: date ? date : this.todaysTime,
|
date: date ? date : this.todaysTime,
|
||||||
type,
|
type,
|
||||||
index
|
index,
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
// DATA HANDLERS
|
// DATA HANDLERS
|
||||||
addRecipe(type) {
|
addRecipe(type) {
|
||||||
let filteredRecipes = this.recipes.filter( ( e ) => this.getRecipes[ type ] ? !this.getRecipes[ type ].includes( e.id ) : true )
|
let filteredRecipes = this.recipes.filter((e) =>
|
||||||
|
this.getRecipes[type] ? !this.getRecipes[type].includes(e.id) : true
|
||||||
|
);
|
||||||
this.$showModal(ActionDialogWithSearch, {
|
this.$showModal(ActionDialogWithSearch, {
|
||||||
props: {
|
props: {
|
||||||
title: "selRec",
|
title: "selRec",
|
||||||
|
@ -194,40 +313,40 @@ export default {
|
||||||
helpIcon: "cal",
|
helpIcon: "cal",
|
||||||
},
|
},
|
||||||
}).then((title) => {
|
}).then((title) => {
|
||||||
title && this.newMealPlan( title, null, type, null )
|
title && this.newMealPlan(title, null, type, null);
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
removeRecipe(title, type) {
|
removeRecipe(title, type) {
|
||||||
let date = this.todaysTime
|
let date = this.todaysTime;
|
||||||
let index = this.mealPlans.findIndex( e => e.title === title && e.type === type && e.date === date )
|
let index = this.mealPlans.findIndex(
|
||||||
|
(e) => e.title === title && e.type === type && e.date === date
|
||||||
|
);
|
||||||
let mealPlan = {
|
let mealPlan = {
|
||||||
title,
|
title,
|
||||||
date,
|
date,
|
||||||
type,
|
type,
|
||||||
index
|
index,
|
||||||
|
};
|
||||||
|
this.deleteMealPlanAction(mealPlan);
|
||||||
|
this.undoRemove(`${this.$options.filters.L("recRm")}`).then((res) => {
|
||||||
|
if (res.command === "action") {
|
||||||
|
this.newMealPlan(title, date, type, index);
|
||||||
}
|
}
|
||||||
this.deleteMealPlanAction( mealPlan )
|
});
|
||||||
this.undoRemove( `${this.$options.filters.L('recRm')}` ).then( res => {
|
|
||||||
if ( res.command === 'action' ) {
|
|
||||||
this.newMealPlan( title, date, type, index )
|
|
||||||
}
|
|
||||||
} )
|
|
||||||
},
|
},
|
||||||
undoRemove(message) {
|
undoRemove(message) {
|
||||||
return snackbar
|
return snackbar.action({
|
||||||
.action( {
|
|
||||||
message,
|
message,
|
||||||
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
|
textColor: this.appTheme == "Light" ? "#fff" : "#292929",
|
||||||
actionTextColor: '#ff5200',
|
actionTextColor: "#ff5200",
|
||||||
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
|
backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
|
||||||
actionText: 'Undo',
|
actionText: "Undo",
|
||||||
hideDelay: 5000
|
hideDelay: 5000,
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,24 +2,43 @@
|
||||||
<Page @loaded="onPageLoad">
|
<Page @loaded="onPageLoad">
|
||||||
<ActionBar androidElevation="1">
|
<ActionBar androidElevation="1">
|
||||||
<GridLayout rows="*" columns="auto, *">
|
<GridLayout rows="*" columns="auto, *">
|
||||||
<MDButton class="er left" variant="text" :text="icon.back" automationText="Back" @tap="$navigateBack()" col="0" />
|
<MDButton
|
||||||
|
class="er left"
|
||||||
|
variant="text"
|
||||||
|
:text="icon.back"
|
||||||
|
automationText="Back"
|
||||||
|
@tap="$navigateBack()"
|
||||||
|
col="0"
|
||||||
|
/>
|
||||||
<Label class="title orkm" :text="'Settings' | L" col="1" />
|
<Label class="title orkm" :text="'Settings' | L" col="1" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<StackLayout class="main-container">
|
<StackLayout class="main-container">
|
||||||
<Label :text="'intf' | L" class="group-header orkm" />
|
<Label :text="'intf' | L" class="group-header orkm" />
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="selectAppLanguage" />
|
columns="auto, *"
|
||||||
<Label col="0" verticalAlignment="center" class="er" :text="icon.lang" />
|
class="option mdr"
|
||||||
|
@tap="selectAppLanguage"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
col="0"
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="er"
|
||||||
|
:text="icon.lang"
|
||||||
|
/>
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'lang' | L" />
|
<Label :text="'lang' | L" />
|
||||||
<Label :text="appLanguage" class="info" />
|
<Label :text="appLanguage" class="info" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout columns="auto, *" class="option mdr" @tap="selectThemes">
|
||||||
<MDRipple colSpan="2" @tap="selectThemes" />
|
<Label
|
||||||
<Label col="0" verticalAlignment="center" class="er" :text="icon.theme" />
|
col="0"
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="er"
|
||||||
|
:text="icon.theme"
|
||||||
|
/>
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'Theme' | L" />
|
<Label :text="'Theme' | L" />
|
||||||
<Label :text="`${appTheme}` | L" class="info" />
|
<Label :text="`${appTheme}` | L" class="info" />
|
||||||
|
@ -28,29 +47,47 @@
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<Label :text="'opts' | L" class="group-header orkm" />
|
<Label :text="'opts' | L" class="group-header orkm" />
|
||||||
<GridLayout columns="auto, *, auto" class="option">
|
<GridLayout columns="auto, *, auto" class="option">
|
||||||
<Label col="0" verticalAlignment="center" class="er" :text="icon.shuf" />
|
<Label
|
||||||
|
col="0"
|
||||||
|
verticalAlignment="center"
|
||||||
|
class="er"
|
||||||
|
:text="icon.shuf"
|
||||||
|
/>
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'sVw' | L" textWrap="true" />
|
<Label :text="'sVw' | L" textWrap="true" />
|
||||||
<Label :text="`sVwInfo` | L" class="info" textWrap="true" />
|
<Label :text="`sVwInfo` | L" class="info" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<Switch :color="shakeEnabled ? '#ff5200' : '#858585'" verticalAlignment="center" col="2" :checked="shakeEnabled" @checkedChange="toggleShake" />
|
<Switch
|
||||||
|
:color="shakeEnabled ? '#ff5200' : '#858585'"
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="2"
|
||||||
|
:checked="shakeEnabled"
|
||||||
|
@checkedChange="toggleShake"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<Label :text="'db' | L" class="group-header orkm" />
|
<Label :text="'db' | L" class="group-header orkm" />
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout columns="auto, *" class="option mdr" @tap="exportCheck">
|
||||||
<MDRipple colSpan="2" @tap="exportCheck" />
|
|
||||||
<Label col="0" class="er" :text="icon.exp" />
|
<Label col="0" class="er" :text="icon.exp" />
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'expBu' | L" textWrap="true" />
|
<Label :text="'expBu' | L" textWrap="true" />
|
||||||
<Label v-if="!backupInProgress" :text="'buInfo' | L" class="info" textWrap="true" />
|
<Label
|
||||||
|
v-if="!backupInProgress"
|
||||||
|
:text="'buInfo' | L"
|
||||||
|
class="info"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
<GridLayout class="progressContainer" v-else columns="*, 64">
|
<GridLayout class="progressContainer" v-else columns="*, 64">
|
||||||
<MDProgress col="0" :value="backupProgress" maxValue="100"></MDProgress>
|
<MDProgress
|
||||||
|
col="0"
|
||||||
|
:value="backupProgress"
|
||||||
|
maxValue="100"
|
||||||
|
></MDProgress>
|
||||||
<Label col="1" :text="` ${backupProgress}%`" />
|
<Label col="1" :text="` ${backupProgress}%`" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout columns="auto, *" class="option mdr" @tap="importCheck">
|
||||||
<MDRipple colSpan="2" @tap="importCheck" />
|
|
||||||
<Label col="0" class="er" :text="icon.imp" />
|
<Label col="0" class="er" :text="icon.imp" />
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'impBu' | L" textWrap="true" />
|
<Label :text="'impBu' | L" textWrap="true" />
|
||||||
|
@ -59,48 +96,107 @@
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<Label :text="'rest' | L" class="group-header orkm" />
|
<Label :text="'rest' | L" class="group-header orkm" />
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="resetListItems('cuisines')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="resetListItems('cuisines')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.reset" />
|
<Label col="0" class="er" :text="icon.reset" />
|
||||||
<Label col="1" verticalAlignment="center" :text="'restCuiL' | L" textWrap="true" />
|
<Label
|
||||||
|
col="1"
|
||||||
|
verticalAlignment="center"
|
||||||
|
:text="'restCuiL' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="resetListItems('categories')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="resetListItems('categories')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.reset" />
|
<Label col="0" class="er" :text="icon.reset" />
|
||||||
<Label col="1" verticalAlignment="center" :text="'restCatL' | L" textWrap="true" />
|
<Label
|
||||||
|
col="1"
|
||||||
|
verticalAlignment="center"
|
||||||
|
:text="'restCatL' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="resetListItems('yieldUnits')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="resetListItems('yieldUnits')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.reset" />
|
<Label col="0" class="er" :text="icon.reset" />
|
||||||
<Label col="1" verticalAlignment="center" :text="'restYUL' | L" textWrap="true" />
|
<Label
|
||||||
|
col="1"
|
||||||
|
verticalAlignment="center"
|
||||||
|
:text="'restYUL' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="resetListItems('units')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="resetListItems('units')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.reset" />
|
<Label col="0" class="er" :text="icon.reset" />
|
||||||
<Label col="1" verticalAlignment="center" :text="'restUL' | L" textWrap="true" />
|
<Label
|
||||||
|
col="1"
|
||||||
|
verticalAlignment="center"
|
||||||
|
:text="'restUL' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Label class="group-info" :text="'restInfo' | L" textWrap="true" />
|
<Label class="group-info" :text="'restInfo' | L" textWrap="true" />
|
||||||
|
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<Label :text="'help' | L" class="group-header orkm" />
|
<Label :text="'help' | L" class="group-header orkm" />
|
||||||
|
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://t.me/enrecipes')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="openURL('https://t.me/enrecipes')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.tg" />
|
<Label col="0" class="er" :text="icon.tg" />
|
||||||
<StackLayout col="1">
|
<StackLayout col="1">
|
||||||
<Label :text="'joinTG' | L" textWrap="true" />
|
<Label :text="'joinTG' | L" textWrap="true" />
|
||||||
<Label :text="'tgInfo' | L" class="info" textWrap="true" />
|
<Label :text="'tgInfo' | L" class="info" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://github.com/vishnuraghavb/EnRecipes/wiki/User-Guide')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="
|
||||||
|
openURL(
|
||||||
|
'https://github.com/vishnuraghavb/EnRecipes/wiki/User-Guide'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.help" />
|
<Label col="0" class="er" :text="icon.help" />
|
||||||
<Label verticalAlignment="center" col="1" :text="'guide' | L" textWrap="true" />
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="1"
|
||||||
|
:text="'guide' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="
|
||||||
|
openURL(
|
||||||
|
'https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.priv" />
|
<Label col="0" class="er" :text="icon.priv" />
|
||||||
<Label verticalAlignment="center" col="1" :text="'priv' | L" textWrap="true" />
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="1"
|
||||||
|
:text="'priv' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<StackLayout class="hr m-10"></StackLayout>
|
<StackLayout class="hr m-10"></StackLayout>
|
||||||
<Label :text="'About' | L" class="group-header orkm" />
|
<Label :text="'About' | L" class="group-header orkm" />
|
||||||
|
@ -112,20 +208,48 @@
|
||||||
<Label :text="getVersion" class="info" textWrap="true" />
|
<Label :text="getVersion" class="info" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://github.com/vishnuraghavb/enrecipes')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="openURL('https://github.com/vishnuraghavb/enrecipes')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.gh" />
|
<Label col="0" class="er" :text="icon.gh" />
|
||||||
<Label verticalAlignment="center" col="1" :text="'gh' | L" textWrap="true" />
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="1"
|
||||||
|
:text="'gh' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://www.vishnuraghav.com/donate')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="openURL('https://www.vishnuraghav.com/donate')"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.don" />
|
<Label col="0" class="er" :text="icon.don" />
|
||||||
<Label verticalAlignment="center" col="1" :text="'donate' | L" textWrap="true" />
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="1"
|
||||||
|
:text="'donate' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout columns="auto, *" class="option">
|
<GridLayout
|
||||||
<MDRipple colSpan="2" @tap="openURL('https://hosted.weblate.org/projects/enrecipes/app-translations')" />
|
columns="auto, *"
|
||||||
|
class="option mdr"
|
||||||
|
@tap="
|
||||||
|
openURL(
|
||||||
|
'https://hosted.weblate.org/projects/enrecipes/app-translations'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
<Label col="0" class="er" :text="icon.trans" />
|
<Label col="0" class="er" :text="icon.trans" />
|
||||||
<Label verticalAlignment="center" col="1" :text="'trnsl' | L" textWrap="true" />
|
<Label
|
||||||
|
verticalAlignment="center"
|
||||||
|
col="1"
|
||||||
|
:text="'trnsl' | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Label class="group-info" :text="'appInfo' | L" textWrap="true" />
|
<Label class="group-info" :text="'appInfo' | L" textWrap="true" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
@ -143,30 +267,18 @@ import {
|
||||||
File,
|
File,
|
||||||
Folder,
|
Folder,
|
||||||
Observable,
|
Observable,
|
||||||
Device
|
Device,
|
||||||
}
|
} from "@nativescript/core";
|
||||||
from "@nativescript/core"
|
import * as Permissions from "@nativescript-community/perms";
|
||||||
import * as Permissions from "@nativescript-community/perms"
|
import { Zip } from "@nativescript/zip";
|
||||||
import {
|
import * as Toast from "nativescript-toast";
|
||||||
Zip
|
import * as Filepicker from "nativescript-plugin-filepicker";
|
||||||
}
|
import Theme from "@nativescript/theme";
|
||||||
from "@nativescript/zip"
|
import { localize, overrideLocale } from "@nativescript/localize";
|
||||||
import * as Toast from "nativescript-toast"
|
import { mapState, mapActions } from "vuex";
|
||||||
import * as Filepicker from "nativescript-plugin-filepicker"
|
import ActionDialog from "./modal/ActionDialog.vue";
|
||||||
import Theme from "@nativescript/theme"
|
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
||||||
import {
|
import * as utils from "~/shared/utils";
|
||||||
localize,
|
|
||||||
overrideLocale
|
|
||||||
}
|
|
||||||
from "@nativescript/localize"
|
|
||||||
import {
|
|
||||||
mapState,
|
|
||||||
mapActions
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
import ActionDialog from "./modal/ActionDialog.vue"
|
|
||||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
|
||||||
import * as utils from "~/shared/utils"
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -174,40 +286,62 @@ export default {
|
||||||
appLanguage: "English",
|
appLanguage: "English",
|
||||||
backupProgress: 0,
|
backupProgress: 0,
|
||||||
backupInProgress: false,
|
backupInProgress: false,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState( [ "icon", "recipes", "cuisines", "categories", "yieldUnits", "units", "mealPlans", "currentComponent", "language", "shakeEnabled", "importSummary" ] ),
|
...mapState([
|
||||||
|
"icon",
|
||||||
|
"recipes",
|
||||||
|
"cuisines",
|
||||||
|
"categories",
|
||||||
|
"yieldUnits",
|
||||||
|
"units",
|
||||||
|
"mealPlans",
|
||||||
|
"currentComponent",
|
||||||
|
"language",
|
||||||
|
"shakeEnabled",
|
||||||
|
"importSummary",
|
||||||
|
]),
|
||||||
getVersion() {
|
getVersion() {
|
||||||
let ctx = Application.android.context
|
let ctx = Application.android.context;
|
||||||
return ctx.getPackageManager().getPackageInfo( ctx.getPackageName(), 0 ).versionName
|
return ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0)
|
||||||
|
.versionName;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions( [ "setCurrentComponentAction", "importListItemsAction", "importRecipesAction", "importMealPlansAction", "resetListItemsAction", "setShakeAction", "unlinkBrokenImages" ] ),
|
...mapActions([
|
||||||
|
"setCurrentComponentAction",
|
||||||
|
"importListItemsAction",
|
||||||
|
"importRecipesAction",
|
||||||
|
"importMealPlansAction",
|
||||||
|
"resetListItemsAction",
|
||||||
|
"setShakeAction",
|
||||||
|
"unlinkBrokenImages",
|
||||||
|
]),
|
||||||
onPageLoad(args) {
|
onPageLoad(args) {
|
||||||
const page = args.object;
|
const page = args.object;
|
||||||
page.bindingContext = new Observable();
|
page.bindingContext = new Observable();
|
||||||
this.setCurrentComponentAction( "Settings" )
|
this.setCurrentComponentAction("Settings");
|
||||||
},
|
},
|
||||||
// HELPERS
|
// HELPERS
|
||||||
openURL(url) {
|
openURL(url) {
|
||||||
Utils.openUrl( url )
|
Utils.openUrl(url);
|
||||||
},
|
},
|
||||||
// LANGUAGE SELECTION
|
// LANGUAGE SELECTION
|
||||||
selectAppLanguage() {
|
selectAppLanguage() {
|
||||||
let languages = this.language.map( e => e.title )
|
let languages = this.language.map((e) => e.title);
|
||||||
this.$showModal(ActionDialog, {
|
this.$showModal(ActionDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: "lang",
|
title: "lang",
|
||||||
list: [...languages],
|
list: [...languages],
|
||||||
stretch: true,
|
stretch: true,
|
||||||
helpIcon: 'lang',
|
helpIcon: "lang",
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action && action !== "Cancel" && this.appLanguage !== action) {
|
if (action && action !== "Cancel" && this.appLanguage !== action) {
|
||||||
let currentLocale = Device.language.split( '-' )[ 0 ]
|
let currentLocale = Device.language.split("-")[0];
|
||||||
let locale = this.language.filter( e => e.title === action )[ 0 ].locale
|
let locale = this.language.filter((e) => e.title === action)[0]
|
||||||
|
.locale;
|
||||||
if (currentLocale !== locale) {
|
if (currentLocale !== locale) {
|
||||||
this.$showModal(ConfirmDialog, {
|
this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
|
@ -215,20 +349,20 @@ export default {
|
||||||
description: localize("nLangInfo"),
|
description: localize("nLangInfo"),
|
||||||
cancelButtonText: "cBtn",
|
cancelButtonText: "cBtn",
|
||||||
okButtonText: "rst",
|
okButtonText: "rst",
|
||||||
helpIcon: 'res',
|
helpIcon: "res",
|
||||||
bgColor: '#ff5200',
|
bgColor: "#ff5200",
|
||||||
},
|
},
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.appLanguage = action
|
this.appLanguage = action;
|
||||||
ApplicationSettings.setString( "appLanguage", action )
|
ApplicationSettings.setString("appLanguage", action);
|
||||||
overrideLocale( locale )
|
overrideLocale(locale);
|
||||||
setTimeout( utils.restartApp, 250 )
|
setTimeout(utils.restartApp, 250);
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
// THEME SELECTION
|
// THEME SELECTION
|
||||||
selectThemes() {
|
selectThemes() {
|
||||||
|
@ -237,7 +371,7 @@ export default {
|
||||||
title: "Theme",
|
title: "Theme",
|
||||||
list: ["Light", "Dark"],
|
list: ["Light", "Dark"],
|
||||||
stretch: false,
|
stretch: false,
|
||||||
helpIcon: 'theme',
|
helpIcon: "theme",
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action && action !== "Cancel" && this.appTheme !== action) {
|
if (action && action !== "Cancel" && this.appTheme !== action) {
|
||||||
|
@ -247,169 +381,224 @@ export default {
|
||||||
description: localize("nThmInfo"),
|
description: localize("nThmInfo"),
|
||||||
cancelButtonText: "cBtn",
|
cancelButtonText: "cBtn",
|
||||||
okButtonText: "rst",
|
okButtonText: "rst",
|
||||||
helpIcon: 'res',
|
helpIcon: "res",
|
||||||
bgColor: '#ff5200',
|
bgColor: "#ff5200",
|
||||||
},
|
},
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.appTheme = action
|
this.appTheme = action;
|
||||||
ApplicationSettings.setString( "appTheme", action )
|
ApplicationSettings.setString("appTheme", action);
|
||||||
setTimeout( utils.restartApp, 250 )
|
setTimeout(utils.restartApp, 250);
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
// SHAKE VIEW RANDOM RECIPE
|
// SHAKE VIEW RANDOM RECIPE
|
||||||
toggleShake(args) {
|
toggleShake(args) {
|
||||||
let checked = args.object.checked
|
let checked = args.object.checked;
|
||||||
// let checked = !this.shakeEnabled
|
// let checked = !this.shakeEnabled
|
||||||
ApplicationSettings.setBoolean( 'shakeEnabled', checked )
|
ApplicationSettings.setBoolean("shakeEnabled", checked);
|
||||||
this.setShakeAction( checked )
|
this.setShakeAction(checked);
|
||||||
},
|
},
|
||||||
// EXPORT HANDLERS
|
// EXPORT HANDLERS
|
||||||
exportCheck() {
|
exportCheck() {
|
||||||
if (!this.recipes.length) {
|
if (!this.recipes.length) {
|
||||||
Toast.makeText( localize( "aFBu" ) ).show()
|
Toast.makeText(localize("aFBu")).show();
|
||||||
} else {
|
} else {
|
||||||
this.permissionCheck( this.permissionConfirmation, localize( "reqAcc" ), this.exportBackup )
|
this.permissionCheck(
|
||||||
|
this.permissionConfirmation,
|
||||||
|
localize("reqAcc"),
|
||||||
|
this.exportBackup
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
exportBackup() {
|
exportBackup() {
|
||||||
this.exportFiles( "create" )
|
this.exportFiles("create");
|
||||||
let date = new Date()
|
let date = new Date();
|
||||||
let formattedDate = date.getFullYear() + "-" + ( "0" + ( date.getMonth() + 1 ) ).slice( -2 ) + "-" + ( "0" + date.getDate() ).slice( -2 ) + "_" + ( "0" + date.getHours() ).slice( -2 ) + ( "0" + date.getMinutes() ).slice( -2 ) + ( "0" + date
|
let formattedDate =
|
||||||
.getSeconds() ).slice( -2 )
|
date.getFullYear() +
|
||||||
const sdDownloadPath = Folder.fromPath( android.os.Environment.getExternalStorageDirectory().getAbsolutePath() ).getFolder( "Download" ).path
|
"-" +
|
||||||
let fromPath = path.join( knownFolders.documents().path, "EnRecipes" )
|
("0" + (date.getMonth() + 1)).slice(-2) +
|
||||||
let destPath = path.join( sdDownloadPath, `EnRecipes-Backup_${formattedDate}.zip` )
|
"-" +
|
||||||
this.backupInProgress = true
|
("0" + date.getDate()).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");
|
||||||
|
let destPath = path.join(
|
||||||
|
sdDownloadPath,
|
||||||
|
`EnRecipes-Backup_${formattedDate}.zip`
|
||||||
|
);
|
||||||
|
this.backupInProgress = true;
|
||||||
Zip.zip({
|
Zip.zip({
|
||||||
directory: fromPath,
|
directory: fromPath,
|
||||||
archive: destPath,
|
archive: destPath,
|
||||||
onProgress: (progress) => {
|
onProgress: (progress) => {
|
||||||
this.backupProgress = progress
|
this.backupProgress = progress;
|
||||||
},
|
},
|
||||||
}).then((success) => {
|
}).then((success) => {
|
||||||
Toast.makeText( "Backup file successfully saved to Download folder", "long" ).show()
|
Toast.makeText(
|
||||||
this.exportFiles( "delete" )
|
"Backup file successfully saved to Download folder",
|
||||||
setTimeout( e => this.backupInProgress = false, 3000 )
|
"long"
|
||||||
} )
|
).show();
|
||||||
|
this.exportFiles("delete");
|
||||||
|
setTimeout((e) => (this.backupInProgress = false), 3000);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
exportFiles(option) {
|
exportFiles(option) {
|
||||||
const folder = path.join( knownFolders.documents().path, "EnRecipes" )
|
const folder = path.join(knownFolders.documents().path, "EnRecipes");
|
||||||
const EnRecipesFile = File.fromPath( path.join( folder, "recipes.json" ) )
|
const EnRecipesFile = File.fromPath(path.join(folder, "recipes.json"));
|
||||||
let userCuisinesFile, userCategoriesFile, userYieldUnitsFile, userUnitsFile, mealPlansFile
|
let userCuisinesFile,
|
||||||
if ( this.cuisines.length ) userCuisinesFile = File.fromPath( path.join( folder, "userCuisines.json" ) )
|
userCategoriesFile,
|
||||||
if ( this.categories.length ) userCategoriesFile = File.fromPath( path.join( folder, "userCategories.json" ) )
|
userYieldUnitsFile,
|
||||||
if ( this.yieldUnits.length ) userYieldUnitsFile = File.fromPath( path.join( folder, "userYieldUnits.json" ) )
|
userUnitsFile,
|
||||||
if ( this.units.length ) userUnitsFile = File.fromPath( path.join( folder, "userUnits.json" ) )
|
mealPlansFile;
|
||||||
if ( this.mealPlans.length ) mealPlansFile = File.fromPath( path.join( folder, "mealPlans.json" ) )
|
if (this.cuisines.length)
|
||||||
|
userCuisinesFile = File.fromPath(
|
||||||
|
path.join(folder, "userCuisines.json")
|
||||||
|
);
|
||||||
|
if (this.categories.length)
|
||||||
|
userCategoriesFile = File.fromPath(
|
||||||
|
path.join(folder, "userCategories.json")
|
||||||
|
);
|
||||||
|
if (this.yieldUnits.length)
|
||||||
|
userYieldUnitsFile = File.fromPath(
|
||||||
|
path.join(folder, "userYieldUnits.json")
|
||||||
|
);
|
||||||
|
if (this.units.length)
|
||||||
|
userUnitsFile = File.fromPath(path.join(folder, "userUnits.json"));
|
||||||
|
if (this.mealPlans.length)
|
||||||
|
mealPlansFile = File.fromPath(path.join(folder, "mealPlans.json"));
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case "create":
|
case "create":
|
||||||
this.writeDataToFile( EnRecipesFile, this.recipes )
|
this.writeDataToFile(EnRecipesFile, this.recipes);
|
||||||
this.cuisines.length && this.writeDataToFile( userCuisinesFile, this.cuisines )
|
this.cuisines.length &&
|
||||||
this.categories.length && this.writeDataToFile( userCategoriesFile, this.categories )
|
this.writeDataToFile(userCuisinesFile, this.cuisines);
|
||||||
this.yieldUnits.length && this.writeDataToFile( userYieldUnitsFile, this.yieldUnits )
|
this.categories.length &&
|
||||||
this.units.length && this.writeDataToFile( userUnitsFile, this.units )
|
this.writeDataToFile(userCategoriesFile, this.categories);
|
||||||
this.mealPlans.length && this.writeDataToFile( mealPlansFile, this.mealPlans )
|
this.yieldUnits.length &&
|
||||||
break
|
this.writeDataToFile(userYieldUnitsFile, this.yieldUnits);
|
||||||
|
this.units.length && this.writeDataToFile(userUnitsFile, this.units);
|
||||||
|
this.mealPlans.length &&
|
||||||
|
this.writeDataToFile(mealPlansFile, this.mealPlans);
|
||||||
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
EnRecipesFile.remove()
|
EnRecipesFile.remove();
|
||||||
this.cuisines.length && userCuisinesFile.remove()
|
this.cuisines.length && userCuisinesFile.remove();
|
||||||
this.categories.length && userCategoriesFile.remove()
|
this.categories.length && userCategoriesFile.remove();
|
||||||
this.yieldUnits.length && userYieldUnitsFile.remove()
|
this.yieldUnits.length && userYieldUnitsFile.remove();
|
||||||
this.units.length && userUnitsFile.remove()
|
this.units.length && userUnitsFile.remove();
|
||||||
this.mealPlans.length && mealPlansFile.remove()
|
this.mealPlans.length && mealPlansFile.remove();
|
||||||
break
|
break;
|
||||||
default:
|
default:
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
writeDataToFile(file, data) {
|
writeDataToFile(file, data) {
|
||||||
file.writeText( JSON.stringify( data ) )
|
file.writeText(JSON.stringify(data));
|
||||||
},
|
},
|
||||||
// IMPORT HANDLERS
|
// IMPORT HANDLERS
|
||||||
importCheck() {
|
importCheck() {
|
||||||
this.permissionCheck( this.permissionConfirmation, localize( "reqAcc" ), this.openFilePicker )
|
this.permissionCheck(
|
||||||
|
this.permissionConfirmation,
|
||||||
|
localize("reqAcc"),
|
||||||
|
this.openFilePicker
|
||||||
|
);
|
||||||
},
|
},
|
||||||
openFilePicker() {
|
openFilePicker() {
|
||||||
Filepicker.create({
|
Filepicker.create({
|
||||||
mode: "single",
|
mode: "single",
|
||||||
extensions: ["zip"],
|
extensions: ["zip"],
|
||||||
} ).present().then( ( selection ) => {
|
|
||||||
Toast.makeText( localize( "vrfy" ) + '...' ).show()
|
|
||||||
let zipPath = selection[ 0 ]
|
|
||||||
this.validateZipContent( zipPath )
|
|
||||||
})
|
})
|
||||||
|
.present()
|
||||||
|
.then((selection) => {
|
||||||
|
Toast.makeText(localize("vrfy") + "...").show();
|
||||||
|
let zipPath = selection[0];
|
||||||
|
this.validateZipContent(zipPath);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
importDataToDB(data, db, zipPath) {
|
importDataToDB(data, db, zipPath) {
|
||||||
switch (db) {
|
switch (db) {
|
||||||
case "EnRecipesDB":
|
case "EnRecipesDB":
|
||||||
this.importImages( zipPath )
|
this.importImages(zipPath);
|
||||||
this.importRecipesAction( data )
|
this.importRecipesAction(data);
|
||||||
break
|
break;
|
||||||
case "userCuisinesDB":
|
case "userCuisinesDB":
|
||||||
this.importListItemsAction({
|
this.importListItemsAction({
|
||||||
data,
|
data,
|
||||||
listName: "cuisines",
|
listName: "cuisines",
|
||||||
} )
|
});
|
||||||
break
|
break;
|
||||||
case "userCategoriesDB":
|
case "userCategoriesDB":
|
||||||
this.importListItemsAction({
|
this.importListItemsAction({
|
||||||
data,
|
data,
|
||||||
listName: "categories",
|
listName: "categories",
|
||||||
} )
|
});
|
||||||
break
|
break;
|
||||||
case "userYieldUnitsDB":
|
case "userYieldUnitsDB":
|
||||||
this.importListItemsAction({
|
this.importListItemsAction({
|
||||||
data,
|
data,
|
||||||
listName: "yieldUnits",
|
listName: "yieldUnits",
|
||||||
} )
|
});
|
||||||
break
|
break;
|
||||||
case "userUnitsDB":
|
case "userUnitsDB":
|
||||||
this.importListItemsAction({
|
this.importListItemsAction({
|
||||||
data,
|
data,
|
||||||
listName: "units",
|
listName: "units",
|
||||||
} )
|
});
|
||||||
break
|
break;
|
||||||
case "mealPlansDB":
|
case "mealPlansDB":
|
||||||
this.importMealPlansAction( data )
|
this.importMealPlansAction(data);
|
||||||
break
|
break;
|
||||||
default:
|
default:
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hasValidJSON(data) {
|
hasValidJSON(data) {
|
||||||
try {
|
try {
|
||||||
JSON.parse( data ) && Array.isArray( JSON.parse( data ) )
|
JSON.parse(data) && Array.isArray(JSON.parse(data));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
isFileDataValid(file) {
|
isFileDataValid(file) {
|
||||||
const files = file.filter( e => File.exists( e.path ) )
|
const files = file.filter((e) => File.exists(e.path));
|
||||||
if (files.length) {
|
if (files.length) {
|
||||||
let isValid = files.map( e => false )
|
let isValid = files.map((e) => false);
|
||||||
files.forEach((file, i) => {
|
files.forEach((file, i) => {
|
||||||
File.fromPath( file.path ).readText().then( ( data ) => {
|
File.fromPath(file.path)
|
||||||
isValid[ i ] = this.hasValidJSON( data )
|
.readText()
|
||||||
|
.then((data) => {
|
||||||
|
isValid[i] = this.hasValidJSON(data);
|
||||||
if (!isValid[i]) {
|
if (!isValid[i]) {
|
||||||
this.failedImport( `${localize("buMod")}\n\n${localize("invFile")}: ${file.file}` )
|
this.failedImport(
|
||||||
|
`${localize("buMod")}\n\n${localize("invFile")}: ${file.file}`
|
||||||
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( isValid.every( e => e === true ) ) {
|
if (isValid.every((e) => e === true)) {
|
||||||
files.forEach((file, i) => {
|
files.forEach((file, i) => {
|
||||||
File.fromPath( file.path ).readText().then( ( data ) => {
|
File.fromPath(file.path)
|
||||||
this.importDataToDB( JSON.parse( data ), file.db, file.zipPath )
|
.readText()
|
||||||
} )
|
.then((data) => {
|
||||||
} )
|
this.importDataToDB(
|
||||||
|
JSON.parse(data),
|
||||||
|
file.db,
|
||||||
|
file.zipPath
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
} )
|
});
|
||||||
} else {
|
} else {
|
||||||
this.failedImport( localize( "buEmp" ) )
|
this.failedImport(localize("buEmp"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
failedImport(description) {
|
failedImport(description) {
|
||||||
|
@ -418,94 +607,99 @@ export default {
|
||||||
title: "impFail",
|
title: "impFail",
|
||||||
description,
|
description,
|
||||||
okButtonText: "OK",
|
okButtonText: "OK",
|
||||||
helpIcon: 'alert',
|
helpIcon: "alert",
|
||||||
bgColor: '#c92a2a',
|
bgColor: "#c92a2a",
|
||||||
},
|
},
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
validateZipContent(zipPath) {
|
validateZipContent(zipPath) {
|
||||||
Zip.unzip({
|
Zip.unzip({
|
||||||
archive: zipPath,
|
archive: zipPath,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
}).then((extractedFolderPath) => {
|
}).then((extractedFolderPath) => {
|
||||||
let cacheFolderPath = extractedFolderPath + "/EnRecipes"
|
let cacheFolderPath = extractedFolderPath + "/EnRecipes";
|
||||||
const EnRecipesFilePath = cacheFolderPath + "/recipes.json"
|
const EnRecipesFilePath = cacheFolderPath + "/recipes.json";
|
||||||
const userCuisinesFilePath = cacheFolderPath + "/userCuisines.json"
|
const userCuisinesFilePath = cacheFolderPath + "/userCuisines.json";
|
||||||
const userCategoriesFilePath = cacheFolderPath + "/userCategories.json"
|
const userCategoriesFilePath = cacheFolderPath + "/userCategories.json";
|
||||||
const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json"
|
const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json";
|
||||||
const userUnitsFilePath = cacheFolderPath + "/userUnits.json"
|
const userUnitsFilePath = cacheFolderPath + "/userUnits.json";
|
||||||
const mealPlansFilePath = cacheFolderPath + "/mealPlans.json"
|
const mealPlansFilePath = cacheFolderPath + "/mealPlans.json";
|
||||||
if (Folder.exists(cacheFolderPath)) {
|
if (Folder.exists(cacheFolderPath)) {
|
||||||
this.isFileDataValid( [ {
|
this.isFileDataValid([
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: EnRecipesFilePath,
|
path: EnRecipesFilePath,
|
||||||
db: "EnRecipesDB",
|
db: "EnRecipesDB",
|
||||||
file: "recipes.json"
|
file: "recipes.json",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: userCuisinesFilePath,
|
path: userCuisinesFilePath,
|
||||||
db: "userCuisinesDB",
|
db: "userCuisinesDB",
|
||||||
file: "userCuisines.json"
|
file: "userCuisines.json",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: userCategoriesFilePath,
|
path: userCategoriesFilePath,
|
||||||
db: "userCategoriesDB",
|
db: "userCategoriesDB",
|
||||||
file: "userCategories.json"
|
file: "userCategories.json",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: userYieldUnitsFilePath,
|
path: userYieldUnitsFilePath,
|
||||||
db: "userYieldUnitsDB",
|
db: "userYieldUnitsDB",
|
||||||
file: "userYieldUnits.json"
|
file: "userYieldUnits.json",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: userUnitsFilePath,
|
path: userUnitsFilePath,
|
||||||
db: "userUnitsDB",
|
db: "userUnitsDB",
|
||||||
file: "userUnits.json"
|
file: "userUnits.json",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
zipPath,
|
zipPath,
|
||||||
path: mealPlansFilePath,
|
path: mealPlansFilePath,
|
||||||
db: "mealPlansDB",
|
db: "mealPlansDB",
|
||||||
file: "mealPlans.json"
|
file: "mealPlans.json",
|
||||||
}, ] )
|
},
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
Folder.fromPath( extractedFolderPath ).remove()
|
Folder.fromPath(extractedFolderPath).remove();
|
||||||
this.failedImport( localize( "buInc" ) )
|
this.failedImport(localize("buInc"));
|
||||||
}
|
}
|
||||||
if (Folder.exists(cacheFolderPath + "/Images")) {
|
if (Folder.exists(cacheFolderPath + "/Images")) {
|
||||||
this.importImages( cacheFolderPath + "/Images" )
|
this.importImages(cacheFolderPath + "/Images");
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
importImages(sourcePath) {
|
importImages(sourcePath) {
|
||||||
let dest = knownFolders.documents().path
|
let dest = knownFolders.documents().path;
|
||||||
Zip.unzip({
|
Zip.unzip({
|
||||||
archive: sourcePath,
|
archive: sourcePath,
|
||||||
directory: dest,
|
directory: dest,
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
this.showImportSummary()
|
this.showImportSummary();
|
||||||
this.unlinkBrokenImages()
|
this.unlinkBrokenImages();
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
showImportSummary() {
|
showImportSummary() {
|
||||||
let {
|
let { found, imported, updated } = this.importSummary;
|
||||||
found,
|
let exists = Math.abs(found - imported - updated) + updated;
|
||||||
imported,
|
let importedNote = `\n${imported} ${localize("recI")}`;
|
||||||
updated
|
let existsNote = `\n${exists} ${localize("recE")}`;
|
||||||
} = this.importSummary
|
let updatedNote = `\n${updated} ${localize("recU")}`;
|
||||||
let exists = Math.abs( found - imported - updated ) + updated
|
|
||||||
let importedNote = `\n${imported} ${localize('recI')}`
|
|
||||||
let existsNote = `\n${exists} ${localize('recE')}`
|
|
||||||
let updatedNote = `\n${updated} ${localize('recU')}`
|
|
||||||
this.$showModal(ConfirmDialog, {
|
this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: "impSuc",
|
title: "impSuc",
|
||||||
description: `${found} ${localize('recF')}${ importedNote}${existsNote}${updatedNote}`,
|
description: `${found} ${localize(
|
||||||
|
"recF"
|
||||||
|
)}${importedNote}${existsNote}${updatedNote}`,
|
||||||
okButtonText: "OK",
|
okButtonText: "OK",
|
||||||
helpIcon: 'succ',
|
helpIcon: "succ",
|
||||||
bgColor: '#69db7c',
|
bgColor: "#69db7c",
|
||||||
},
|
},
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
// PERMISSIONS HANDLER
|
// PERMISSIONS HANDLER
|
||||||
permissionCheck(confirmation, description, action) {
|
permissionCheck(confirmation, description, action) {
|
||||||
|
@ -513,22 +707,23 @@ export default {
|
||||||
confirmation(description).then((e) => {
|
confirmation(description).then((e) => {
|
||||||
if (e) {
|
if (e) {
|
||||||
Permissions.request("photo").then((res) => {
|
Permissions.request("photo").then((res) => {
|
||||||
let status = res[ Object.keys( res )[ 0 ] ]
|
let status = res[Object.keys(res)[0]];
|
||||||
if ( status === "authorized" ) action()
|
if (status === "authorized") action();
|
||||||
if ( status !== "denied" ) ApplicationSettings.setBoolean( "storagePermissionAsked", true )
|
if (status !== "denied")
|
||||||
else Toast.makeText( localize( "dend" ) ).show()
|
ApplicationSettings.setBoolean("storagePermissionAsked", true);
|
||||||
} )
|
else Toast.makeText(localize("dend")).show();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} )
|
});
|
||||||
} else {
|
} else {
|
||||||
Permissions.check("photo").then((res) => {
|
Permissions.check("photo").then((res) => {
|
||||||
let status = res[ Object.keys( res )[ 0 ] ]
|
let status = res[Object.keys(res)[0]];
|
||||||
if (status !== "authorized") {
|
if (status !== "authorized") {
|
||||||
confirmation(description).then((e) => {
|
confirmation(description).then((e) => {
|
||||||
e && utils.openAppSettingsPage()
|
e && utils.openAppSettingsPage();
|
||||||
} )
|
});
|
||||||
} else action()
|
} else action();
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permissionConfirmation(description) {
|
permissionConfirmation(description) {
|
||||||
|
@ -538,21 +733,23 @@ export default {
|
||||||
description,
|
description,
|
||||||
cancelButtonText: "nNBtn",
|
cancelButtonText: "nNBtn",
|
||||||
okButtonText: "conBtn",
|
okButtonText: "conBtn",
|
||||||
helpIcon: 'folder',
|
helpIcon: "folder",
|
||||||
bgColor: '#ff5200',
|
bgColor: "#ff5200",
|
||||||
},
|
},
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
// RESET
|
// RESET
|
||||||
resetListItems(listName) {
|
resetListItems(listName) {
|
||||||
this.resetListItemsAction( listName )
|
this.resetListItemsAction(listName);
|
||||||
Toast.makeText( localize( "restDone" ) ).show()
|
Toast.makeText(localize("restDone")).show();
|
||||||
}
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
|
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
||||||
this.appLanguage = ApplicationSettings.getString( "appLanguage", localize( "sysDef" ) )
|
this.appLanguage = ApplicationSettings.getString(
|
||||||
|
"appLanguage",
|
||||||
|
localize("sysDef")
|
||||||
|
);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,115 +1,144 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<GridLayout columns="*" :rows="`auto, auto, ${stretch? '*':'auto'}, auto`" class="dialogContainer" :class="appTheme">
|
<GridLayout
|
||||||
<Label row="0" class="er dialogIcon" backgroundColor="#858585" :color="iconColor" :text="icon[helpIcon]" />
|
columns="*"
|
||||||
|
:rows="`auto, auto, ${stretch ? '*' : 'auto'}, auto`"
|
||||||
|
class="dialogContainer"
|
||||||
|
:class="appTheme"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
row="0"
|
||||||
|
class="er dialogIcon"
|
||||||
|
backgroundColor="#858585"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon[helpIcon]"
|
||||||
|
/>
|
||||||
<Label row="1" class="dialogTitle orkm" :text="`${title}` | L" />
|
<Label row="1" class="dialogTitle orkm" :text="`${title}` | L" />
|
||||||
<ScrollView row="2" width="100%">
|
<ScrollView row="2" width="100%">
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<MDButton v-for="(item, index) in newList" :key="index" class="actionItem" :class="{'orkm':title==='srt' && sortType=== item}" :color="title==='srt' && sortType=== item ? '#ff5200':''" variant="text" :rippleColor="rippleColor"
|
<MDButton
|
||||||
:text="`${localized(item)}${title==='srt' && sortType=== item ? '*':''}`" @loaded="centerLabel" @tap="tapAction(item)" @longPress="removeItem(index)" />
|
v-for="(item, index) in newList"
|
||||||
|
:key="index"
|
||||||
|
class="actionItem"
|
||||||
|
:class="{ orkm: title === 'srt' && sortType === item }"
|
||||||
|
:color="title === 'srt' && sortType === item ? '#ff5200' : ''"
|
||||||
|
variant="text"
|
||||||
|
:text="`${localized(item)}${
|
||||||
|
title === 'srt' && sortType === item ? '*' : ''
|
||||||
|
}`"
|
||||||
|
@loaded="centerLabel"
|
||||||
|
@tap="tapAction(item)"
|
||||||
|
@longPress="removeItem(index)"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<GridLayout row="3" rows="auto" columns="auto, *, auto" class="actionsContainer">
|
<GridLayout
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" v-if="action" col="0" class="action orkm pull-left" :text="`${action}` | L" @tap="$modal.close(action)" />
|
row="3"
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm pull-right" :text="'cBtn' | L" @tap="$modal.close(false)" />
|
rows="auto"
|
||||||
|
columns="auto, *, auto"
|
||||||
|
class="actionsContainer"
|
||||||
|
>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
v-if="action"
|
||||||
|
col="0"
|
||||||
|
class="action orkm pull-left"
|
||||||
|
:text="`${action}` | L"
|
||||||
|
@tap="$modal.close(action)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm pull-right"
|
||||||
|
:text="'cBtn' | L"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application, Color } from "@nativescript/core";
|
||||||
Application,
|
import * as Toast from "nativescript-toast";
|
||||||
Color
|
import { localize } from "@nativescript/localize";
|
||||||
} from "@nativescript/core"
|
import { mapState, mapActions } from "vuex";
|
||||||
import * as Toast from "nativescript-toast"
|
import ConfirmDialog from "./ConfirmDialog.vue";
|
||||||
import {
|
|
||||||
localize
|
|
||||||
}
|
|
||||||
from "@nativescript/localize"
|
|
||||||
import {
|
|
||||||
mapState,
|
|
||||||
mapActions
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
import ConfirmDialog from "./ConfirmDialog.vue"
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "list", "stretch", "action", "helpIcon"],
|
props: ["title", "list", "stretch", "action", "helpIcon"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
newList: this.list,
|
newList: this.list,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState( [ "sortType", 'icon' ] ),
|
...mapState(["sortType", "icon"]),
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["removeListItemAction"]),
|
...mapActions(["removeListItemAction"]),
|
||||||
localized(item) {
|
localized(item) {
|
||||||
if ( this.title !== 'lang' )
|
if (this.title !== "lang") return localize(item);
|
||||||
return localize( item )
|
else return item;
|
||||||
else
|
|
||||||
return item
|
|
||||||
},
|
},
|
||||||
tapAction(item) {
|
tapAction(item) {
|
||||||
this.$modal.close( item )
|
this.$modal.close(item);
|
||||||
},
|
},
|
||||||
centerLabel(args) {
|
centerLabel(args) {
|
||||||
args.object.android.setGravity( 16 )
|
args.object.android.setGravity(16);
|
||||||
},
|
},
|
||||||
deletionConfirmation(type, description) {
|
deletionConfirmation(type, description) {
|
||||||
return this.$showModal(ConfirmDialog, {
|
return this.$showModal(ConfirmDialog, {
|
||||||
props: {
|
props: {
|
||||||
title: 'conf',
|
title: "conf",
|
||||||
description,
|
description,
|
||||||
cancelButtonText: "cBtn",
|
cancelButtonText: "cBtn",
|
||||||
okButtonText: "rBtn",
|
okButtonText: "rBtn",
|
||||||
helpIcon: 'err',
|
helpIcon: "err",
|
||||||
bgColor: '#c92a2a',
|
bgColor: "#c92a2a",
|
||||||
},
|
},
|
||||||
} )
|
});
|
||||||
},
|
},
|
||||||
removeItem(index) {
|
removeItem(index) {
|
||||||
let item = this.newList[ index ]
|
let item = this.newList[index];
|
||||||
let vm = this
|
let vm = this;
|
||||||
|
|
||||||
function removeListItem(type, listName, desc) {
|
function removeListItem(type, listName, desc) {
|
||||||
vm.deletionConfirmation( type, `${localize(desc)} "${localize(item)}"\n\n${localize('rmLIInfo')}` ).then( action => {
|
vm.deletionConfirmation(
|
||||||
|
type,
|
||||||
|
`${localize(desc)} "${localize(item)}"\n\n${localize("rmLIInfo")}`
|
||||||
|
).then((action) => {
|
||||||
if (action != null && action)
|
if (action != null && action)
|
||||||
vm.removeListItemAction({
|
vm.removeListItemAction({
|
||||||
item,
|
item,
|
||||||
listName
|
listName,
|
||||||
} )
|
});
|
||||||
} )
|
});
|
||||||
}
|
}
|
||||||
switch (this.title) {
|
switch (this.title) {
|
||||||
case "cui":
|
case "cui":
|
||||||
removeListItem( 'cuisine', "cuisines", "rmCuiInfo" )
|
removeListItem("cuisine", "cuisines", "rmCuiInfo");
|
||||||
break;
|
break;
|
||||||
case "cat":
|
case "cat":
|
||||||
removeListItem( "category", "categories", "rmCatInfo" )
|
removeListItem("category", "categories", "rmCatInfo");
|
||||||
break;
|
break;
|
||||||
case "yieldU":
|
case "yieldU":
|
||||||
removeListItem( "yield unit", "yieldUnits", "rmYUInfo" )
|
removeListItem("yield unit", "yieldUnits", "rmYUInfo");
|
||||||
break;
|
break;
|
||||||
case "Unit":
|
case "Unit":
|
||||||
removeListItem( "unit", "units", "rmUInfo" )
|
removeListItem("unit", "units", "rmUInfo");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,81 +1,139 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<GridLayout columns="*" rows="auto, auto, auto, *, auto" class="dialogContainer" :class="appTheme">
|
<GridLayout
|
||||||
<Label row="0" class="er dialogIcon" backgroundColor="#858585" :color="iconColor" :text="icon[helpIcon]" />
|
columns="*"
|
||||||
<Label row="1" class="dialogTitle orkm" :text="`${title}` | L" textWrap='true' />
|
rows="auto, auto, auto, *, auto"
|
||||||
<StackLayout row="2" v-if="filteredRecipes.length || searchQuery" padding="0 24 24">
|
class="dialogContainer"
|
||||||
|
:class="appTheme"
|
||||||
|
>
|
||||||
|
<Label
|
||||||
|
row="0"
|
||||||
|
class="er dialogIcon"
|
||||||
|
backgroundColor="#858585"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon[helpIcon]"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
row="1"
|
||||||
|
class="dialogTitle orkm"
|
||||||
|
:text="`${title}` | L"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<StackLayout
|
||||||
|
row="2"
|
||||||
|
v-if="filteredRecipes.length || searchQuery"
|
||||||
|
padding="0 24 24"
|
||||||
|
>
|
||||||
<TextField :hint="'Search' | L" v-model="searchQuery" />
|
<TextField :hint="'Search' | L" v-model="searchQuery" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<ScrollView row="3" width="100%" :height="height ? height : ''">
|
<ScrollView row="3" width="100%" :height="height ? height : ''">
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<MDButton v-for="(recipe, index) in filteredRecipes" :key="index" class="actionItem" variant="text" :rippleColor="rippleColor" :text="recipe.title" @loaded="centerLabel" @tap="tapAction(recipe)" />
|
<MDButton
|
||||||
<Label padding="24" lineHeight="6" v-if="!filteredRecipes.length && !searchQuery" :text="'recListEmp' | L" textAlignment="center" textWrap="true" />
|
v-for="(recipe, index) in filteredRecipes"
|
||||||
<Label padding="24" lineHeight="6" v-if="!filteredRecipes.length && searchQuery" :text="'noRecs' | L" textAlignment="center" textWrap="true" />
|
:key="index"
|
||||||
|
class="actionItem"
|
||||||
|
variant="text"
|
||||||
|
:text="recipe.title"
|
||||||
|
@loaded="centerLabel"
|
||||||
|
@tap="tapAction(recipe)"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
padding="24"
|
||||||
|
lineHeight="6"
|
||||||
|
v-if="!filteredRecipes.length && !searchQuery"
|
||||||
|
:text="'recListEmp' | L"
|
||||||
|
textAlignment="center"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
padding="24"
|
||||||
|
lineHeight="6"
|
||||||
|
v-if="!filteredRecipes.length && searchQuery"
|
||||||
|
:text="'noRecs' | L"
|
||||||
|
textAlignment="center"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<GridLayout row="4" rows="auto" columns="auto, *, auto" class="actionsContainer">
|
<GridLayout
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" v-if="action" col="0" class="action orkm pull-left" :text="`${action}` | L" @tap="$modal.close(action)" />
|
row="4"
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm pull-right" :text="'CANCEL' | L" @tap="$modal.close(false)" />
|
rows="auto"
|
||||||
|
columns="auto, *, auto"
|
||||||
|
class="actionsContainer"
|
||||||
|
>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
v-if="action"
|
||||||
|
col="0"
|
||||||
|
class="action orkm pull-left"
|
||||||
|
:text="`${action}` | L"
|
||||||
|
@tap="$modal.close(action)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm pull-right"
|
||||||
|
:text="'CANCEL' | L"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application } from "@nativescript/core";
|
||||||
Application
|
import { mapState } from "vuex";
|
||||||
}
|
|
||||||
from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
mapState
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "recipes", "height", "action", "helpIcon"],
|
props: ["title", "recipes", "height", "action", "helpIcon"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchQuery: "",
|
searchQuery: "",
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState( [ 'icon' ] ),
|
...mapState(["icon"]),
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
filteredRecipes() {
|
filteredRecipes() {
|
||||||
return this.recipes.map( ( e, i ) => {
|
return this.recipes
|
||||||
|
.map((e, i) => {
|
||||||
return {
|
return {
|
||||||
id: e.id,
|
id: e.id,
|
||||||
title: e.title,
|
title: e.title,
|
||||||
cuisine: e.cuisine,
|
cuisine: e.cuisine,
|
||||||
category: e.category,
|
category: e.category,
|
||||||
tags: e.tags.map( e => e.toLowerCase() ).join(),
|
tags: e.tags.map((e) => e.toLowerCase()).join(),
|
||||||
ingredients: e.ingredients.map( e => e.item.toLowerCase() ).join(),
|
ingredients: e.ingredients.map((e) => e.item.toLowerCase()).join(),
|
||||||
}
|
};
|
||||||
} ).filter( ( e ) => this.recipeFilter( e ) )
|
})
|
||||||
|
.filter((e) => this.recipeFilter(e));
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
tapAction(recipe) {
|
tapAction(recipe) {
|
||||||
this.$modal.close( recipe.id )
|
this.$modal.close(recipe.id);
|
||||||
},
|
},
|
||||||
centerLabel(args) {
|
centerLabel(args) {
|
||||||
args.object.android.setGravity( 16 )
|
args.object.android.setGravity(16);
|
||||||
},
|
},
|
||||||
recipeFilter(e) {
|
recipeFilter(e) {
|
||||||
let searchQuery = this.searchQuery.toLowerCase()
|
let searchQuery = this.searchQuery.toLowerCase();
|
||||||
return e.title.includes( searchQuery ) || e.cuisine.includes( searchQuery ) || e.category.includes( searchQuery ) || e.tags.includes( searchQuery ) || e.ingredients.includes( searchQuery )
|
return (
|
||||||
|
e.title.includes(searchQuery) ||
|
||||||
|
e.cuisine.includes(searchQuery) ||
|
||||||
|
e.category.includes(searchQuery) ||
|
||||||
|
e.tags.includes(searchQuery) ||
|
||||||
|
e.ingredients.includes(searchQuery)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,42 +1,63 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<StackLayout class="dialogContainer" :class="appTheme">
|
<StackLayout class="dialogContainer" :class="appTheme">
|
||||||
<Label class="er dialogIcon" :backgroundColor="bgColor" :color="iconColor" :text="icon[helpIcon]" />
|
<Label
|
||||||
|
class="er dialogIcon"
|
||||||
|
:backgroundColor="bgColor"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon[helpIcon]"
|
||||||
|
/>
|
||||||
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap="true" />
|
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap="true" />
|
||||||
<Label v-if="description" class="dialogDescription" :text="description" textWrap="true" />
|
<Label
|
||||||
|
v-if="description"
|
||||||
|
class="dialogDescription"
|
||||||
|
:text="description"
|
||||||
|
textWrap="true"
|
||||||
|
/>
|
||||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||||
<MDButton v-if="cancelButtonText" :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="`${cancelButtonText}` | L" @tap="$modal.close(false)" />
|
<MDButton
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${okButtonText}` | L" @tap="$modal.close(true)" />
|
v-if="cancelButtonText"
|
||||||
|
variant="text"
|
||||||
|
col="1"
|
||||||
|
class="action orkm"
|
||||||
|
:text="`${cancelButtonText}` | L"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm"
|
||||||
|
:text="`${okButtonText}` | L"
|
||||||
|
@tap="$modal.close(true)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application } from "@nativescript/core";
|
||||||
Application
|
import { mapState } from "vuex";
|
||||||
}
|
|
||||||
from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
mapState
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
export default {
|
export default {
|
||||||
props: [ "title", "description", "cancelButtonText", "okButtonText", "helpIcon", "bgColor" ],
|
props: [
|
||||||
|
"title",
|
||||||
|
"description",
|
||||||
|
"cancelButtonText",
|
||||||
|
"okButtonText",
|
||||||
|
"helpIcon",
|
||||||
|
"bgColor",
|
||||||
|
],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon"]),
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,33 +1,55 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<StackLayout class="dialogContainer" :class="appTheme">
|
<StackLayout class="dialogContainer" :class="appTheme">
|
||||||
<Label class="er dialogIcon" backgroundColor="#858585" :color="iconColor" :text="icon.time" />
|
<Label
|
||||||
|
class="er dialogIcon"
|
||||||
|
backgroundColor="#858585"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon.time"
|
||||||
|
/>
|
||||||
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
||||||
<StackLayout class="dialogListPicker" orientation="horizontal" horizontalAlignment="center">
|
<StackLayout
|
||||||
<ListPicker ref="hrPicker" :items="hrsList" :selectedIndex="hrIndex" @selectedIndexChange="setHrs"></ListPicker>
|
class="dialogListPicker"
|
||||||
<ListPicker ref="minPicker" :items="minsList" :selectedIndex="minIndex" @selectedIndexChange="setMins"></ListPicker>
|
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>
|
</StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="'cBtn' | L" @tap="$modal.close(false)" />
|
<MDButton
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${action}` | L" @tap="$modal.close(selectedTime)" />
|
variant="text"
|
||||||
|
col="1"
|
||||||
|
class="action orkm"
|
||||||
|
:text="'cBtn' | L"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm"
|
||||||
|
:text="`${action}` | L"
|
||||||
|
@tap="$modal.close(selectedTime)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application } from "@nativescript/core";
|
||||||
Application
|
import { mapState } from "vuex";
|
||||||
}
|
import { localize } from "@nativescript/localize";
|
||||||
from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
mapState
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
import {
|
|
||||||
localize
|
|
||||||
}
|
|
||||||
from "@nativescript/localize"
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "selectedHr", "selectedMin", "action"],
|
props: ["title", "selectedHr", "selectedMin", "action"],
|
||||||
data() {
|
data() {
|
||||||
|
@ -36,51 +58,53 @@ export default {
|
||||||
mins: [],
|
mins: [],
|
||||||
selectedHrs: "00",
|
selectedHrs: "00",
|
||||||
selectedMins: "00",
|
selectedMins: "00",
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon"]),
|
||||||
hrsList() {
|
hrsList() {
|
||||||
let h = [ ...Array( 24 ).keys() ]
|
let h = [...Array(24).keys()];
|
||||||
this.hrs = h
|
this.hrs = h;
|
||||||
return h.map( e => `${e} ${localize( 'hr' )}` )
|
return h.map((e) => `${e} ${localize("hr")}`);
|
||||||
},
|
},
|
||||||
minsList() {
|
minsList() {
|
||||||
let m = [ ...new Set( [ ...Array( 11 ).keys(), ...Array.from( Array( 12 ), ( _, x ) => x * 5 ) ] ) ]
|
let m = [
|
||||||
this.mins = m
|
...new Set([
|
||||||
return m.map( e => `${e} ${localize( 'min' )}` )
|
...Array(11).keys(),
|
||||||
|
...Array.from(Array(12), (_, x) => x * 5),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
this.mins = m;
|
||||||
|
return m.map((e) => `${e} ${localize("min")}`);
|
||||||
},
|
},
|
||||||
hrIndex() {
|
hrIndex() {
|
||||||
return this.hrs.indexOf( parseInt( this.selectedHr ) )
|
return this.hrs.indexOf(parseInt(this.selectedHr));
|
||||||
},
|
},
|
||||||
minIndex() {
|
minIndex() {
|
||||||
return this.mins.indexOf( parseInt( this.selectedMin ) )
|
return this.mins.indexOf(parseInt(this.selectedMin));
|
||||||
},
|
},
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
selectedTime() {
|
selectedTime() {
|
||||||
return this.selectedHrs + ":" + this.selectedMins
|
return this.selectedHrs + ":" + this.selectedMins;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setHrs(args) {
|
setHrs(args) {
|
||||||
let hr = "0" + this.hrs[ args.object.selectedIndex ]
|
let hr = "0" + this.hrs[args.object.selectedIndex];
|
||||||
this.selectedHrs = hr.slice( -2 )
|
this.selectedHrs = hr.slice(-2);
|
||||||
},
|
},
|
||||||
setMins(args) {
|
setMins(args) {
|
||||||
let min = "0" + this.mins[ args.object.selectedIndex ]
|
let min = "0" + this.mins[args.object.selectedIndex];
|
||||||
this.selectedMins = min.slice( -2 )
|
this.selectedMins = min.slice(-2);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,65 +1,75 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<StackLayout class="dialogContainer" :class="appTheme">
|
<StackLayout class="dialogContainer" :class="appTheme">
|
||||||
<Label class="er dialogIcon" backgroundColor="#858585" :color="iconColor" :text="icon[helpIcon]" />
|
<Label
|
||||||
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap='true' />
|
class="er dialogIcon"
|
||||||
|
backgroundColor="#858585"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon[helpIcon]"
|
||||||
|
/>
|
||||||
|
<Label class="dialogTitle orkm" :text="`${title}` | L" textWrap="true" />
|
||||||
<StackLayout class="dialogInput">
|
<StackLayout class="dialogInput">
|
||||||
<TextField @loaded="focusField" :hint="hint ? hint : ''" v-model="category" autocapitalizationType="words" @returnPress="$modal.close(category)" />
|
<TextField
|
||||||
|
@loaded="focusField"
|
||||||
|
:hint="hint ? hint : ''"
|
||||||
|
v-model="category"
|
||||||
|
autocapitalizationType="words"
|
||||||
|
@returnPress="$modal.close(category)"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
<GridLayout rows="auto" columns="*, auto, auto" class="actionsContainer">
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="'cBtn' | L" @tap="$modal.close(false)" />
|
<MDButton
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="2" class="action orkm" :text="`${action}` | L" @tap="$modal.close(category)" />
|
variant="text"
|
||||||
|
col="1"
|
||||||
|
class="action orkm"
|
||||||
|
:text="'cBtn' | L"
|
||||||
|
@tap="$modal.close(false)"
|
||||||
|
/>
|
||||||
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="2"
|
||||||
|
class="action orkm"
|
||||||
|
:text="`${action}` | L"
|
||||||
|
@tap="$modal.close(category)"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application, Utils } from "@nativescript/core";
|
||||||
Application,
|
import { localize } from "@nativescript/localize";
|
||||||
Utils
|
import { mapState } from "vuex";
|
||||||
}
|
|
||||||
from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
localize
|
|
||||||
}
|
|
||||||
from '@nativescript/localize'
|
|
||||||
import {
|
|
||||||
mapState
|
|
||||||
}
|
|
||||||
from "vuex"
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "hint", "text", "action", "helpIcon"],
|
props: ["title", "hint", "text", "action", "helpIcon"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
category: null,
|
category: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon"]),
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
focusField(args) {
|
focusField(args) {
|
||||||
args.object.focus()
|
args.object.focus();
|
||||||
setTimeout( ( e ) => Utils.ad.showSoftInput( args.object.android ), 1 )
|
setTimeout((e) => Utils.ad.showSoftInput(args.object.android), 1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.text) {
|
if (this.text) {
|
||||||
this.category = localize( this.text )
|
this.category = localize(this.text);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,59 +1,80 @@
|
||||||
<template>
|
<template>
|
||||||
<Page>
|
<Page>
|
||||||
<StackLayout class="dialogContainer" :class="appTheme">
|
<StackLayout class="dialogContainer" :class="appTheme">
|
||||||
<Label class="er dialogIcon" backgroundColor="#858585" :color="iconColor" :text="icon[helpIcon]" />
|
<Label
|
||||||
|
class="er dialogIcon"
|
||||||
|
backgroundColor="#858585"
|
||||||
|
:color="iconColor"
|
||||||
|
:text="icon[helpIcon]"
|
||||||
|
/>
|
||||||
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
<Label class="dialogTitle orkm" :text="`${title}` | L" />
|
||||||
<GridLayout rows="auto, auto, auto" columns="*" class="actionsContainer">
|
<GridLayout rows="auto, auto, auto" columns="*" class="actionsContainer">
|
||||||
|
<GridLayout
|
||||||
<GridLayout class="shareItem" :backgroundColor="bgColor" row="0" columns="*" rows="auto, auto">
|
class="shareItem mdr"
|
||||||
<MDRipple :rippleColor="rippleColor" rowSpan="2" @tap="$modal.close('photo')" />
|
:backgroundColor="bgColor"
|
||||||
|
row="0"
|
||||||
|
columns="*"
|
||||||
|
rows="auto, auto"
|
||||||
|
@tap="$modal.close('photo')"
|
||||||
|
>
|
||||||
<Label row="0" class="er" :text="icon.img" />
|
<Label row="0" class="er" :text="icon.img" />
|
||||||
<Label row="1" class="item" :text="'pht' | L" textWrap="true" />
|
<Label row="1" class="item" :text="'pht' | L" textWrap="true" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout class="shareItem" :backgroundColor="bgColor" row="1" columns="*" rows="auto, auto">
|
<GridLayout
|
||||||
<MDRipple :rippleColor="rippleColor" rowSpan="2" @tap="$modal.close('recipe')" />
|
class="shareItem mdr"
|
||||||
|
:backgroundColor="bgColor"
|
||||||
|
row="1"
|
||||||
|
columns="*"
|
||||||
|
rows="auto, auto"
|
||||||
|
@tap="$modal.close('recipe')"
|
||||||
|
>
|
||||||
<Label row="0" class="er" :text="icon.text" />
|
<Label row="0" class="er" :text="icon.text" />
|
||||||
<Label row="1" class="item" :text="'rec' | L" textWrap="true" />
|
<Label row="1" class="item" :text="'rec' | L" textWrap="true" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<!-- <GridLayout class="shareItem" :backgroundColor="bgColor" row="2" columns="*" rows="auto, auto">
|
<!-- <GridLayout
|
||||||
<MDRipple :rippleColor="rippleColor" rowSpan="2" @tap="$modal.close('file')" />
|
class="shareItem mdr"
|
||||||
|
:backgroundColor="bgColor"
|
||||||
|
row="2"
|
||||||
|
columns="*"
|
||||||
|
rows="auto, auto"
|
||||||
|
@tap="$modal.close('file')"
|
||||||
|
>
|
||||||
<Label row="0" class="er" :text="icon.zip" />
|
<Label row="0" class="er" :text="icon.zip" />
|
||||||
<Label row="1" class="item" :text="'fil' | L" textWrap="true" />
|
<Label row="1" class="item" :text="'fil' | L" textWrap="true" />
|
||||||
</GridLayout> -->
|
</GridLayout> -->
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout rows="auto" columns="*, auto" class="actionsContainer">
|
<GridLayout rows="auto" columns="*, auto" class="actionsContainer">
|
||||||
<MDButton :rippleColor="rippleColor" variant="text" col="1" class="action orkm" :text="'cBtn' | L" @tap="$modal.close()" />
|
<MDButton
|
||||||
|
variant="text"
|
||||||
|
col="1"
|
||||||
|
class="action orkm mdr"
|
||||||
|
:text="'cBtn' | L"
|
||||||
|
@tap="$modal.close()"
|
||||||
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Application } from "@nativescript/core";
|
||||||
Application
|
import { mapState } from "vuex";
|
||||||
} from "@nativescript/core"
|
|
||||||
import {
|
|
||||||
mapState
|
|
||||||
} from "vuex"
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "helpIcon"],
|
props: ["title", "helpIcon"],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon"]),
|
||||||
appTheme() {
|
appTheme() {
|
||||||
return Application.systemAppearance()
|
return Application.systemAppearance();
|
||||||
},
|
},
|
||||||
isLightMode() {
|
isLightMode() {
|
||||||
return this.appTheme == "light"
|
return this.appTheme == "light";
|
||||||
},
|
|
||||||
rippleColor() {
|
|
||||||
return "rgba(133,133,133,0.2)"
|
|
||||||
},
|
},
|
||||||
iconColor() {
|
iconColor() {
|
||||||
return this.isLightMode ? "#f0f0f0" : "#1A1A1A"
|
return this.isLightMode ? "#f0f0f0" : "#1A1A1A";
|
||||||
},
|
},
|
||||||
bgColor() {
|
bgColor() {
|
||||||
return this.isLightMode ? "#fff" : "#292929"
|
return this.isLightMode ? "#fff" : "#292929";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
55
app/main.js
55
app/main.js
|
@ -1,51 +1,54 @@
|
||||||
import {localize, androidLaunchEventLocalizationHandler} from '@nativescript/localize'
|
import {
|
||||||
import {on, launchEvent} from '@nativescript/core/application';
|
localize,
|
||||||
|
androidLaunchEventLocalizationHandler,
|
||||||
|
} from '@nativescript/localize'
|
||||||
|
import { on, launchEvent } from '@nativescript/core/application'
|
||||||
on(launchEvent, (args) => {
|
on(launchEvent, (args) => {
|
||||||
if (args.android) {
|
if (args.android) {
|
||||||
androidLaunchEventLocalizationHandler();
|
androidLaunchEventLocalizationHandler()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
import Vue from "nativescript-vue"
|
import Vue from 'nativescript-vue'
|
||||||
import App from "./components/App"
|
import App from './components/App'
|
||||||
import store from "./store"
|
import store from './store'
|
||||||
|
|
||||||
import {install} from '@nativescript-community/ui-drawer';
|
import { installMixins } from '@nativescript-community/ui-material-core'
|
||||||
install();
|
installMixins()
|
||||||
|
|
||||||
import DrawerPlugin from '@nativescript-community/ui-drawer/vue';
|
import { install } from '@nativescript-community/ui-drawer'
|
||||||
Vue.use(DrawerPlugin);
|
install()
|
||||||
|
|
||||||
// import CollectionView from '@nativescript-community/ui-collectionview/vue';
|
import DrawerPlugin from '@nativescript-community/ui-drawer/vue'
|
||||||
// Vue.use(CollectionView);
|
Vue.use(DrawerPlugin)
|
||||||
|
|
||||||
import ButtonPlugin from "@nativescript-community/ui-material-button/vue"
|
import CollectionView from '@nativescript-community/ui-collectionview/vue';
|
||||||
|
Vue.use(CollectionView);
|
||||||
|
|
||||||
|
import ButtonPlugin from '@nativescript-community/ui-material-button/vue'
|
||||||
Vue.use(ButtonPlugin)
|
Vue.use(ButtonPlugin)
|
||||||
|
|
||||||
import ActivityIndicatorPlugin from "@nativescript-community/ui-material-activityindicator/vue"
|
import ActivityIndicatorPlugin from '@nativescript-community/ui-material-activityindicator/vue'
|
||||||
Vue.use(ActivityIndicatorPlugin)
|
Vue.use(ActivityIndicatorPlugin)
|
||||||
|
|
||||||
import RipplePlugin from "@nativescript-community/ui-material-ripple/vue"
|
import FloatingActionButtonPlugin from '@nativescript-community/ui-material-floatingactionbutton/vue'
|
||||||
Vue.use(RipplePlugin)
|
|
||||||
|
|
||||||
import FloatingActionButtonPlugin from "@nativescript-community/ui-material-floatingactionbutton/vue"
|
|
||||||
Vue.use(FloatingActionButtonPlugin)
|
Vue.use(FloatingActionButtonPlugin)
|
||||||
|
|
||||||
import ProgressPlugin from "@nativescript-community/ui-material-progress/vue"
|
import ProgressPlugin from '@nativescript-community/ui-material-progress/vue'
|
||||||
Vue.use(ProgressPlugin)
|
Vue.use(ProgressPlugin)
|
||||||
|
|
||||||
import {CheckBox} from "@nstudio/nativescript-checkbox"
|
import { CheckBox } from '@nstudio/nativescript-checkbox'
|
||||||
Vue.registerElement("CheckBox", () => CheckBox, {
|
Vue.registerElement('CheckBox', () => CheckBox, {
|
||||||
model: {
|
model: {
|
||||||
prop: "checked",
|
prop: 'checked',
|
||||||
event: "checkedChange"
|
event: 'checkedChange',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
Vue.config.silent = TNS_ENV === "production"
|
Vue.config.silent = TNS_ENV === 'production'
|
||||||
|
|
||||||
Vue.filter('L', localize)
|
Vue.filter('L', localize)
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
store,
|
store,
|
||||||
render: h => h("frame", [h(App)])
|
render: (h) => h('frame', [h(App)]),
|
||||||
}).$start()
|
}).$start()
|
||||||
|
|
15399
package-lock.json
generated
15399
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -7,12 +7,12 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nativescript-community/gesturehandler": "^0.1.36",
|
"@nativescript-community/gesturehandler": "^0.1.36",
|
||||||
"@nativescript-community/perms": "^2.1.4",
|
"@nativescript-community/perms": "^2.1.4",
|
||||||
|
"@nativescript-community/ui-collectionview": "^4.0.24",
|
||||||
"@nativescript-community/ui-drawer": "0.0.22",
|
"@nativescript-community/ui-drawer": "0.0.22",
|
||||||
"@nativescript-community/ui-material-activityindicator": "^5.1.16",
|
"@nativescript-community/ui-material-activityindicator": "^5.1.16",
|
||||||
"@nativescript-community/ui-material-button": "^5.1.16",
|
"@nativescript-community/ui-material-button": "^5.1.16",
|
||||||
"@nativescript-community/ui-material-floatingactionbutton": "^5.1.16",
|
"@nativescript-community/ui-material-floatingactionbutton": "^5.1.16",
|
||||||
"@nativescript-community/ui-material-progress": "^5.1.16",
|
"@nativescript-community/ui-material-progress": "^5.1.16",
|
||||||
"@nativescript-community/ui-material-ripple": "^5.1.16",
|
|
||||||
"@nativescript-community/ui-material-snackbar": "^5.1.16",
|
"@nativescript-community/ui-material-snackbar": "^5.1.16",
|
||||||
"@nativescript/core": "~7.0.0",
|
"@nativescript/core": "~7.0.0",
|
||||||
"@nativescript/localize": "^5.0.2",
|
"@nativescript/localize": "^5.0.2",
|
||||||
|
|
Loading…
Reference in a new issue