diff --git a/README.md b/README.md
index 3ab56c9b..32dd9e90 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
A simple, offline recipe manager
-EnRecipes is an easy to use, privacy-friendly digital cookbook that lets you create, manage and share your own recipes.
+EnRecipes is an open source, privacy-friendly digital cookbook that lets you create, manage and share your recipes.
-
+
Features - Downloads - Screenshots - Future - Contributors - Credits - License
@@ -18,7 +18,7 @@
- Add photo, notes and combinations to your recipes
- Organise your recipes by cuisine, category and tags
- Mark recipes as Favourites and add them to your Try Later list
-- Quickly search for recipes by name, ingredient or tag
+- Quickly search for recipes by title or ingredient
- Scale your recipe ingredients to serve more or less people
- Get notified of the last time you tried a recipe
- Share your recipe to anyone by any means as a nicely formatted message. You can share the recipe photo too
@@ -26,12 +26,15 @@
- Create meal plans
- Import/Export recipes
- Light & Dark theme
+
+## Highlights
+
+- 100% free and open-source
- No annoying ads or pop-ups
- No internet access is required and never asks for any unwanted permissions
- Private by Design
-- 100% free and open-source
-**Languages supported**: Danish, Dutch, English, German, Portuguese, Russian, Spanish and Tamil
+**Languages supported**: Danish, Dutch, English, French, German, Italian, Norwegian Bokmål,Portuguese, Russian, Spanish and Tamil
Check the [Roadmap](https://github.com/vishnuraghavb/EnRecipes/projects/1) for upcoming features.
@@ -92,8 +95,7 @@ This app was written in my free time using NativeScript-Vue. I would like to tha
### Assets
-- Icon font from [Boxicons](https://boxicons.com/)
-- Logo by [Vishnu Raghav](https://www.vishnuraghav.com/)
+- Icon font and Logo by [Vishnu Raghav](https://www.vishnuraghav.com/)
## License
diff --git a/app/app.scss b/app/app.scss
index 2052cb7f..0d97ac04 100644
--- a/app/app.scss
+++ b/app/app.scss
@@ -1,22 +1,24 @@
// NativeScript core theme
// @see https://docs.nativescript.org/ui/theme
@import "~@nativescript/theme/core"; // Override variables here
-$gray1: #f1f3f5;
-$gray2: #e9ecef;
-$gray3: #dee2e6;
-$gray4: #ced4da;
-$gray5: #adb5bd;
-$gray6: #868e96;
-$gray7: #495057;
-$gray8: #343a40;
-$gray9: #212529;
+$gray0: #fff;
+$gray1: #f0f0f0;
+$gray2: #e0e0e0;
+$gray3: #d1d1d1;
+$gray4: #c2c2c2;
+$gray5: #858585;
+$gray6: #575757;
+$gray7: #393939;
+$gray8: #292929;
+$gray9: #1A1A1A;
+$gray10: #000;
$orange: #ff5200;
-$fabRipple: #ff922b;
+$fabRipple: #ffa94d;
$red: #c92a2a;
-$breakfast: #ff922b;
-$lunch: #94d82d;
-$dinner: #339af0;
-$snacks: #845ef7; // Global SCSS styling
+$breakfast: #ffa94d;
+$lunch: #69db7c;
+$dinner: #4dabf7;
+$snacks: #9775fa; // Global SCSS styling
// @see https://docs.nativescript.org/ui/styling
.ns-modal,
Page {
@@ -25,8 +27,8 @@ Page {
.orkm {
font-family: 'Orkney-Medium';
}
-.bx {
- font-family: 'boxicons';
+.er {
+ font-family: 'enrecipes';
font-size: 24;
vertical-alignment: center;
&.small {
@@ -34,7 +36,11 @@ Page {
font-size: 16;
}
}
+.today {
+ color: $orange;
+}
.ns-light {
+ .count,
ActionBar,
ListPicker,
Page,
@@ -44,45 +50,41 @@ Page {
color: $gray9;
background: $gray1;
}
- MDButton,
- MDRipple {
- ripple-color: rgba($gray6, 0.2);
- }
.hr {
- border-color: $gray3;
+ border-color: $gray2;
}
.fieldLabel,
.sd {
background: $gray1;
}
.combination,
+ .hasPlans,
.overviewItem,
.recipeItem,
- .textCard,
.titleContainer {
- background: white;
+ background: $gray0;
}
- TextField.combinationToken {
- background: $gray3;
- }
- .sd-group-header,
- .sd-item,
- .tag,
- .time .bx {
- color: $gray8;
+ .combinationToken,
+ .note,
+ .tag {
+ background: $gray2;
}
+ .dayName,
.group-info,
- .option .bx,
.option .info {
- color: $gray7;
+ color: $gray6;
+ }
+ .done .count {
+ color: $gray0;
}
.imageHolder {
- color: $gray4;
- background: $gray3;
+ color: $gray3;
+ background: $gray2;
}
- .count,
- .marker,
- .noteCount {
+ .selected {
+ background: $gray2;
+ }
+ .activeDay {
color: $gray1;
background: $gray9;
}
@@ -94,68 +96,70 @@ Page {
progress-background-color: $gray4;
}
MDFloatingActionButton {
- color: white;
+ color: $gray0;
}
.appIconContainer {
background: $orange;
}
+ .emptyState .icon {
+ color: $gray4;
+ }
}
.ns-dark {
+ .count,
ActionBar,
ListPicker,
Page,
SearchBar,
TabStripItem,
Tabs {
- color: $gray1;
+ color: $gray2;
background: $gray9;
}
- MDButton,
- MDRipple {
- ripple-color: rgba($gray4, 0.1);
- }
.hr {
- border-color: #111;
+ border-color: $gray8;
}
.fieldLabel,
.sd {
background: $gray9;
}
.combination,
+ .hasPlans,
.overviewItem,
.recipeItem,
- .textCard,
- .titleContainer,
- TextField.combinationToken {
+ .titleContainer {
background: $gray8;
}
- .sd-group-header,
- .sd-item,
- .tag,
- .time .bx {
- color: $gray3;
+ .combinationToken,
+ .note,
+ .tag {
+ background: $gray10;
}
+ .dayName,
.group-info,
- .option .bx,
.option .info {
color: $gray5;
}
- .imageHolder {
- color: $gray8;
- background: #111;
+ .done .count {
+ color: $gray10;
}
- .count,
- .marker,
- .noteCount {
+ .imageHolder {
color: $gray9;
- background: $gray1;
+ background: $gray10;
+ }
+ .selected {
+ background: $gray6;
+ }
+ .activeDay {
+ color: $gray9;
+ background: $gray2;
}
.dayContainer,
.instruction {
- border-color: $gray1;
+ border-color: $gray2;
}
MDProgress {
- progress-background-color: $gray6;
+ progress-background-color: $gray5;
}
MDFloatingActionButton {
color: $gray9;
@@ -163,6 +167,9 @@ Page {
.appIconContainer {
background: $orange;
}
+ .emptyState .icon {
+ color: $gray6;
+ }
}
// -----------------------------
// Elements
@@ -175,8 +182,8 @@ TimePickerField {
padding: 13 12;
margin: 8 0 0;
border-radius: 4;
- border-color: $gray6;
- placeholder-color: $gray6;
+ border-color: $gray5;
+ placeholder-color: $gray5;
}
TextView {
line-height: 12;
@@ -187,10 +194,10 @@ ListPicker {
SearchBar {
font-family: 'Orkney-Regular';
font-size: 14;
- text-field-hint-color: $gray6;
+ text-field-hint-color: $gray5;
}
TabView {
- tab-text-color: $gray6;
+ tab-text-color: $gray5;
}
.inputField {
margin-bottom: 8;
@@ -203,6 +210,9 @@ TabView {
.progressContainer {
width: 100%;
}
+.hr {
+ padding: 0;
+}
// .category,
// .group-header,
.text-btn,
@@ -214,7 +224,7 @@ MDProgress {
}
Switch {
background-color: $orange;
- off-background-color: $gray6;
+ off-background-color: $gray5;
}
// -----------------------------
// ActionBar
@@ -226,7 +236,7 @@ ActionBar {
padding: 0;
margin: 0;
}
- MDButton.bx {
+ MDButton.er {
padding: 0;
margin: 0;
}
@@ -245,11 +255,14 @@ ActionBar {
border-radius: 4;
height: 48;
vertical-alignment: center;
- .bx {
+ .er {
font-size: 24;
margin: 0 24 0 0;
}
- &.selected-sd-item {
+ &.selected .er {
+ color: $orange;
+ }
+ &.selected {
color: $orange;
background: rgba($orange, 0.1);
MDRipple {
@@ -261,14 +274,14 @@ ActionBar {
padding: 2 16 0 0;
font-size: 14;
vertical-alignment: center;
- &.bx {
+ &.er {
padding: 0 0 0 16;
}
}
MDRipple {
padding: 0 16;
}
- MDButton.bx {
+ MDButton.er {
margin: 0;
}
.recipeCount {
@@ -280,8 +293,8 @@ ActionBar {
}
.sd-group-header {
width: 100%;
- padding: 0 0 8 8;
- MDButton.bx {
+ padding: 0 0 0 8;
+ MDButton.er {
margin: 0;
}
.filterPath {
@@ -300,7 +313,7 @@ MDButton {
padding: 8;
min-width: 0;
min-height: 0;
- &.bx {
+ &.er {
padding: 0;
width: 48;
height: 48;
@@ -308,6 +321,10 @@ MDButton {
border-radius: 99;
}
}
+MDButton,
+MDRipple {
+ ripple-color: rgba($gray5, 0.2);
+}
// -----------------------------
// HOME
.emptyStateContainer {
@@ -323,7 +340,6 @@ MDButton {
.icon {
font-size: 64;
text-align: center;
- color: $gray5;
margin-bottom: 16;
}
.logo {
@@ -335,7 +351,7 @@ MDButton {
text-align: center;
padding: 0;
horizontal-alignment: center;
- .bx {
+ .er {
font-size: 24;
vertical-alignment: center;
}
@@ -356,12 +372,21 @@ MDButton {
}
// -----------------------------
// Recipe Items
-RadListView {
- margin: 0 0 128;
+ListView {
font-size: 14;
}
-.recipeItem {
- margin: 4 8;
+.recipeContainer {
+ padding: 0;
+}
+.firstItem {
+ padding: 12 0 0;
+}
+.lastItem {
+ padding: 0 0 84;
+}
+.layout1 {
+ padding: 0;
+ margin: 4 16;
border-radius: 4;
.recipeInfo {
margin: 0;
@@ -384,20 +409,46 @@ RadListView {
}
}
}
+.layout2 {
+ padding: 0;
+ margin: 4;
+ border-radius: 4;
+ .imageHolder {
+ vertical-alignment: center;
+ &.card {
+ border-radius: 4 4 0 0;
+ // prettier-ignore
+ Image {
+ border-radius: 4 4 0 0;
+ }
+ }
+ }
+ .recipeInfo {
+ margin: 0;
+ padding: 8;
+ .attr,
+ .category {
+ font-size: 10;
+ padding: 0;
+ margin: 0;
+ }
+ .title {
+ margin: 0;
+ padding: 2 0;
+ }
+ }
+ .tagsContainer {
+ padding: 4 0 0;
+ }
+}
.tagsContainer {
padding: 2 0 0;
- .collapsedTagsCount {
- font-size: 10;
- padding: 1 0 0 2;
- }
.tag {
font-size: 10;
- padding: 0 4;
+ padding: 1 4;
margin: 0 4 0 0;
line-height: 0;
- border-radius: 4;
- border-width: 1;
- border-color: $gray6;
+ border-radius: 2;
}
}
.imageHolder {
@@ -435,7 +486,7 @@ RadListView {
.option {
font-size: 14;
line-height: 6;
- .bx {
+ .er {
margin: 11 24 11 16;
}
.info {
@@ -481,32 +532,34 @@ RadListView {
padding: 0 12;
}
.ratingContainer {
- margin: 14 8 6;
- .rating {
- margin-right: 8;
- color: $orange;
- }
+ margin: 16 8 8;
}
- .subTitle {
- font-size: 14;
- line-height: 6;
+ .rate,
+ .rated {
+ padding: 0 8 0 0;
+ }
+ .rate {
+ color: $gray5;
+ }
+ .rated {
+ color: $orange;
}
.tagsContainer {
- padding: 18 12 0;
+ padding: 0;
+ margin: 12 12 0;
.tag {
- padding: 1 6;
+ padding: 2 6;
margin: 0 8 8 0;
}
}
.overviewContainer {
- margin: 12 0 24;
+ margin: 8 8 12;
.overviewItem {
border-radius: 4;
margin: 4;
android-elevation: 1;
- .bx {
+ .er {
padding: 16 0 0 16;
- color: $gray6;
horizontal-alignment: left;
}
.itemCount {
@@ -515,23 +568,16 @@ RadListView {
}
}
}
- .ingredient {
- font-family: 'Orkney-Regular';
- margin: 0 0 0 4;
- color: blue;
- }
- .red {
- color: red;
- }
.count {
width: 24;
height: 24;
- padding-top: 4%;
margin: 0 0 0 8;
text-align: center;
vertical-alignment: top;
horizontal-alignment: center;
border-radius: 99;
+ border-width: 2;
+ border-color: $gray5;
}
.instruction {
font-size: 14;
@@ -539,12 +585,21 @@ RadListView {
padding: 2 0 24 35;
margin: 0 0 0 19;
border-width: 0 0 0 2;
+ border-color: $gray5;
}
.instruction.noBorder {
border-color: transparent;
}
+ .done .count {
+ background: $orange;
+ border-color: $orange;
+ }
+ .done .instruction {
+ opacity: 0.4;
+ text-decoration: line-through;
+ }
.combination {
- margin: 0 8 8;
+ margin: 0 16 8;
border-radius: 4;
font-size: 14;
.combinationTitle {
@@ -553,21 +608,12 @@ RadListView {
line-height: 6;
}
}
- .noteCount {
- width: 24;
- height: 24;
- padding-top: 4%;
- margin: 0 0 0 8;
- text-align: center;
- vertical-alignment: top;
- horizontal-alignment: center;
- clip-path: polygon(4% 12%, 12% 4%, 75% 4%, 96% 25%, 96% 88%, 88% 96%, 12% 96%, 4% 88%,);
- }
.note {
font-size: 14;
line-height: 6;
- padding: 2 0 24 37;
- margin: 0 0 0 19;
+ padding: 14 16;
+ margin: 0 0 8;
+ border-radius: 4;
}
}
// -----------------------------
@@ -596,20 +642,47 @@ MDFloatingActionButton {
margin: 8 0 0;
min-width: 0;
}
-MDButton.closeBtn {
- margin: 16 0 0;
+MDButton.x {
+ margin: 8 0 0;
width: 32;
height: 32;
min-width: 0;
- vertical-alignment: top;
+ vertical-alignment: center;
}
// -----------------------------
// MEAL PLANNER
+.calendar {
+ padding: 0 8;
+ .navBtn {
+ horizontal-alignment: center;
+ margin: 0;
+ }
+ .monthName {
+ text-align: center;
+ vertical-alignment: center;
+ font-size: 18;
+ padding: 24 0;
+ }
+ .dayName {
+ padding: 8 4;
+ font-size: 12;
+ text-align: center;
+ }
+ .day {
+ font-size: 14;
+ margin: 4;
+ width: 32;
+ height: 32;
+ // horizontal-alignment: center;
+ border-radius: 99;
+ text-align: center;
+ }
+}
.dayPlan {
- padding: 0 0 88;
+ padding: 0 8 88;
width: 100%;
.plansContainer {
- margin: 16 8 0 16;
+ margin: 16 0 0 8;
padding: 0;
border-left-width: 8;
&.breakfast {
@@ -634,7 +707,7 @@ MDButton.closeBtn {
margin: 0 8;
.titleContainer {
border-radius: 4;
- margin: 0 8 8;
+ margin: 0 0 8 8;
}
.recipeTitle {
font-size: 14;
@@ -642,13 +715,9 @@ MDButton.closeBtn {
line-height: 6;
}
}
- .closeBtn {
- margin: 8 0;
- vertical-alignment: top;
- }
- MDButton,
- MDRipple {
- ripple-color: rgba($gray6, 0.2);
+ .x {
+ margin: 8 0 16 8;
+ vertical-alignment: center;
}
}
}
@@ -661,16 +730,13 @@ MDButton.closeBtn {
background: $gray1;
font-size: 14;
&.dark {
- color: $gray1;
+ color: $gray2;
background: $gray9;
}
.dialogIcon {
text-align: center;
padding: 32;
font-size: 48;
- &.flip {
- transform: scaleX(-1);
- }
}
.dialogTitle {
line-height: 6;
@@ -704,7 +770,7 @@ MDButton.closeBtn {
margin: 0 16 16;
android-elevation: 1;
text-align: center;
- .bx {
+ .er {
padding: 16 0 0;
}
.item {
@@ -776,30 +842,3 @@ MDActivityIndicator {
opacity: 0;
}
}
-.dolly-enter-active {
- animation-name: dolly;
- animation-duration: 1s;
- animation-delay: 0.25s;
- animation-fill-mode: forwards;
- animation-timing-function: ease-in-out;
-}
-.dolly-leave-active {
- opacity: 0;
-}
-@keyframes dolly {
- 0% {
- transform: rotate(20deg);
- }
- 25% {
- transform: rotate(-20deg);
- }
- 50% {
- transform: rotate(10deg);
- }
- 75% {
- transform: rotate(-10deg);
- }
- 100% {
- transform: rotate(0deg);
- }
-}
diff --git a/app/components/App.vue b/app/components/App.vue
index e696d08f..5f3f595c 100644
--- a/app/components/App.vue
+++ b/app/components/App.vue
@@ -1,27 +1,28 @@
-GroceryListcui
-
-
-
+
+
+
+
+
-
+
-
+
@@ -34,28 +35,35 @@ GroceryListcui
-
+
-
-
+
+
+
+
+
+ -->
-
+
@@ -63,11 +71,9 @@ GroceryListcui
+ :hijackGlobalBackEvent="hijackGlobalBackEvent" :releaseGlobalBackEvent="releaseGlobalBackEvent" @backToHome="backToHome" :showDrawer="showDrawer" @selectModeOn="selectModeOn" />
-
+
@@ -92,6 +98,7 @@ import {
}
from "vuex"
import EnRecipes from "./EnRecipes"
+import ViewRecipe from "./ViewRecipe"
import MealPlanner from "./MealPlanner"
import GroceryList from "./GroceryList"
import Settings from "./Settings"
@@ -116,18 +123,21 @@ export default {
}, {
title: "trylater",
component: "Try Later",
- icon: "trylater",
+ icon: "try",
}, {
title: "favourites",
component: "Favourites",
- icon: "heart",
+ icon: "fav",
}, ],
appTheme: "Light",
setFilter: true,
+ gestures: true,
+ drawer: null,
}
},
components: {
EnRecipes,
+ ViewRecipe,
MealPlanner,
GroceryList,
Settings
@@ -184,6 +194,10 @@ export default {
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR )
}
},
+ drawerLoad( args ) {
+ this.drawer = args.object
+ },
+
// HELPERS
setRecipeFilter( item ) {
this.setFilter = this.filterFavourites = this.filterTrylater = false
@@ -204,13 +218,8 @@ export default {
this.closeDrawer()
}
this.setFilter = true
- }, 200 )
-
- clearTimeout( filterTimer )
- filterTimer = setTimeout( e => {
- this.setCurrentComponentAction( "Filtered recipes" )
- this.$refs.enrecipes.updateFilter()
- }, 750 )
+ }, 250 )
+ this.setCurrentComponentAction( "Filtered recipes" )
},
previousRecipeFilter() {
if ( this.selectedCategory ) {
@@ -222,11 +231,12 @@ export default {
this.selectedCuisine = null
this.setCurrentComponentAction( "EnRecipes" )
}
- clearTimeout( filterTimer )
- filterTimer = setTimeout( e => this.$refs.enrecipes.updateFilter(), 750 )
+ },
+ showDrawer() {
+ this.drawer.open()
},
closeDrawer() {
- this.$refs.drawer.nativeView.closeDrawer()
+ this.drawer.close()
},
getRecipeCount( arg ) {
let count = ''
@@ -267,6 +277,9 @@ export default {
}
return count
},
+ selectModeOn( bool ) {
+ this.gestures = bool
+ },
// NAVIGATION HANDLERS
hijackGlobalBackEvent() {
AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.globalBackEvent )
@@ -275,17 +288,13 @@ export default {
AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.globalBackEvent )
},
globalBackEvent( args ) {
- function preventDefault() {
+ if ( this.drawer && this.drawer.isOpened() ) {
args.cancel = true
- }
- if ( this.$refs.drawer && this.$refs.drawer.nativeView.getIsOpen() ) {
- preventDefault()
this.closeDrawer()
} else if (
[ "Favourites", "Try Later", "Filtered recipes" ].includes( this.currentComponent ) ) {
- preventDefault()
+ args.cancel = true
this.backToHome()
- this.releaseGlobalBackEvent()
}
},
backToHome() {
@@ -293,34 +302,29 @@ export default {
this.filterFavourites = this.filterTrylater = false
this.selectedTag = this.selectedCategory = this.selectedCuisine = null
this.selectedFilterType = "cuisine"
- this.$refs.enrecipes.updateFilter()
},
navigateTo( to, title, isTrueComponent ) {
if ( title !== this.currentComponent ) {
if ( isTrueComponent ) {
this.$navigateTo( to, {
- frame: "main-frame",
- backstackVisible: false
+ backstackVisible: true
} )
this.closeDrawer()
} else {
- this.releaseGlobalBackEvent()
- this.hijackGlobalBackEvent()
this.setCurrentComponentAction( to )
this.$navigateBack( {
frame: "main-frame",
backstackVisible: false
} )
- this.filterFavourites = to === "Favourites" ? true : false
- this.filterTrylater = to === "Try Later" ? true : false
- this.$refs.enrecipes.updateFilter()
+ this.filterFavourites = to === "Favourites"
+ this.filterTrylater = to === "Try Later"
this.closeDrawer()
+ this.selectedTag = this.selectedCategory = this.selectedCuisine = null
+ this.selectedFilterType = "cuisine"
}
} else {
this.closeDrawer()
}
- this.selectedTag = this.selectedCategory = this.selectedCuisine = null
- this.selectedFilterType = "cuisine"
},
},
created() {
diff --git a/app/components/EditRecipe.vue b/app/components/EditRecipe.vue
index a72abcc2..dd95ba33 100644
--- a/app/components/EditRecipe.vue
+++ b/app/components/EditRecipe.vue
@@ -1,22 +1,22 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -81,7 +81,7 @@
-
+
@@ -90,7 +90,7 @@
-
+
@@ -99,7 +99,7 @@
-
+
@@ -108,7 +108,7 @@
-
+
@@ -164,7 +164,6 @@ export default {
data() {
return {
title: "newRec",
- viewIsScrolled: false,
recipeContent: {
imageSrc: null,
title: undefined,
@@ -188,7 +187,7 @@ export default {
lastTried: null,
lastModified: null,
created: null,
- inCart: false,
+ inBag: false,
},
tempRecipeContent: {},
tags: undefined,
@@ -301,9 +300,6 @@ export default {
}
} )
},
- onScroll( args ) {
- this.viewIsScrolled = args.scrollY ? true : false
- },
// DATA LIST
showCuisine( focus ) {
this.modalOpen = true
@@ -398,7 +394,7 @@ export default {
list: this.yieldUnits,
stretch: true,
action: "aNBtn",
- helpIcon: 'dish',
+ helpIcon: 'yield',
},
} ).then( ( action ) => {
if ( action == "aNBtn" ) {
@@ -406,7 +402,7 @@ export default {
props: {
title: "nwYiU",
action: "aBtn",
- helpIcon: 'dish',
+ helpIcon: 'yield',
},
} ).then( ( item ) => {
this.hijackBackEvent()
@@ -439,7 +435,7 @@ export default {
title: "Difficulty level",
list: this.difficultyLevels,
stretch: false,
- helpIcon: 'meter',
+ helpIcon: 'diff',
},
} ).then( ( action ) => {
if ( action ) {
@@ -462,7 +458,7 @@ export default {
list: this.units,
stretch: true,
action: "aNBtn",
- helpIcon: 'ruler',
+ helpIcon: 'unit',
},
} ).then( ( action ) => {
if ( action == "aNBtn" ) {
@@ -470,7 +466,7 @@ export default {
props: {
title: "newUnit",
action: "aBtn",
- helpIcon: 'ruler',
+ helpIcon: 'unit',
},
} ).then( ( item ) => {
this.hijackBackEvent()
@@ -528,7 +524,7 @@ export default {
description: localize( "disc" ),
cancelButtonText: "disBtn",
okButtonText: "kEdit",
- helpIcon: 'error',
+ helpIcon: 'alert',
bgColor: '#c92a2a',
},
} ).then( ( action ) => {
@@ -565,8 +561,8 @@ export default {
title: "recPic",
cancelButtonText: "rBtn",
okButtonText: "repBtn",
- helpIcon: 'image',
- bgColor: '#adb5bd',
+ helpIcon: 'img',
+ bgColor: '#858585',
},
} ).then( ( action ) => {
this.blockModal = false
@@ -622,11 +618,11 @@ export default {
},
imagePicker() {
ApplicationSettings.setBoolean( "storagePermissionAsked", true )
- this.cacheImagePath = path.join( knownFolders.temp().path, `${this.getRandomID()}.jpg` )
Filepicker.create( {
mode: "single",
extensions: [ "png", "jpeg", "jpg" ],
} ).present().then( ( selection ) => {
+ this.cacheImagePath = path.join( knownFolders.temp().path, `${this.getRandomID()}.jpg` )
let imgPath = selection[ 0 ]
ImageSource.fromFile( imgPath ).then( ( image ) => {
ImageCropper.prototype.show( image, {
@@ -636,8 +632,8 @@ export default {
hideBottomControls: true,
toolbarTitle: localize( "cPic" ),
statusBarColor: "#ff5200",
- toolbarTextColor: this.appTheme == "light" ? "#212529" : "#f1f3f5",
- toolbarColor: this.appTheme == "light" ? "#f1f3f5" : "#212529",
+ toolbarTextColor: this.appTheme == "light" ? "#1A1A1A" : "#e0e0e0",
+ toolbarColor: this.appTheme == "light" ? "#e0e0e0" : "#1A1A1A",
cropFrameColor: "#ff5200",
} ).then( ( cropped ) => {
cropped.image.saveToFile( this.cacheImagePath, "jpg", 75 )
@@ -666,10 +662,10 @@ export default {
return snackbar
.action( {
message,
- textColor: this.appTheme == "light" ? "#f1f3f5" : "#212529",
+ textColor: this.appTheme == "light" ? "#fff" : "#292929",
actionTextColor: '#ff5200',
- backgroundColor: this.appTheme == "light" ? "#212529" : "#f1f3f5",
- actionText: 'Undo',
+ backgroundColor: this.appTheme == "light" ? "#292929" : "#fff",
+ actionText: localize('undo'),
hideDelay: 5000
} )
},
@@ -739,7 +735,7 @@ export default {
props: {
title: "selRec",
recipes: filteredRecipes,
- helpIcon: 'outline',
+ helpIcon: 'comb',
},
} ).then( ( res ) => {
this.hijackBackEvent()
@@ -754,7 +750,6 @@ export default {
this.unSyncCombinations.push( id )
this.undoDeletion( `${this.$options.filters.L('rmCmb')}` ).then( res => {
if ( res.command === 'action' ) {
- console.log( this.recipeContent.combinations, index, id );
this.recipeContent.combinations.splice( index, 0, id )
}
} )
diff --git a/app/components/EnRecipes.vue b/app/components/EnRecipes.vue
index 23f6ee07..d7b382cc 100644
--- a/app/components/EnRecipes.vue
+++ b/app/components/EnRecipes.vue
@@ -1,96 +1,117 @@
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
@@ -105,6 +126,9 @@ import {
Utils,
Observable,
Device,
+ ObservableArray,
+ GestureTypes,
+ Screen
}
from "@nativescript/core";
import {
@@ -131,14 +155,13 @@ import EditRecipe from "./EditRecipe.vue";
import ViewRecipe from "./ViewRecipe.vue";
import ActionDialog from "./modal/ActionDialog.vue";
import ConfirmDialog from "./modal/ConfirmDialog.vue";
-import * as utils from "~/shared/utils";
let lastTime = 0;
let lastShake = 0;
let lastForce = 0;
let shakeCount = 0;
let typingTimer;
export default {
- props: [ "filterFavourites", "filterTrylater", "closeDrawer", "selectedCategory", "selectedCuisine", "selectedTag", "hijackGlobalBackEvent", "releaseGlobalBackEvent" ],
+ props: [ "filterFavourites", "filterTrylater", "closeDrawer", "showDrawer", "selectedCategory", "selectedCuisine", "selectedTag", "hijackGlobalBackEvent", "releaseGlobalBackEvent" ],
components: {
EditRecipe,
ViewRecipe
@@ -146,12 +169,16 @@ export default {
data() {
return {
searchQuery: "",
- viewIsScrolled: false,
showSearch: false,
rightAction: false,
deletionDialogActive: false,
showFAB: false,
filterDone: true,
+ selection: [],
+ selectMode: false,
+ recipeList: [],
+ // listView: null,
+ layout: 1,
};
},
computed: {
@@ -164,21 +191,21 @@ export default {
function getIngredients( e ) {
return e.ingredients.map( f => f.item.toLowerCase() ).join().includes( vm.searchQuery );
}
- if ( this.filterDone ) {
- if ( this.filterFavourites ) {
- return this.recipes.filter( e => e.isFavorite && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) )
- } else if ( this.filterTrylater ) {
- return this.recipes.filter( e => !e.tried && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) )
- } else if ( this.selectedCuisine ) {
- return this.recipes.filter( e => {
- return this.recipeFilter( e ) && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) )
- } )
- } else {
- return this.recipes.filter( e => e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) )
- }
+ // if ( this.filterDone ) {
+ if ( this.filterFavourites ) {
+ return this.recipes.filter( e => e.isFavorite && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) ).sort( this.sortFunction )
+ } else if ( this.filterTrylater ) {
+ return this.recipes.filter( e => !e.tried && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ) ).sort( this.sortFunction )
+ } else if ( this.selectedCuisine ) {
+ return this.recipes.filter( e => {
+ return this.recipeFilter( e ) && ( e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) )
+ } ).sort( this.sortFunction )
} else {
- return "A";
+ return this.recipes.filter( e => e.title.toLowerCase().includes( this.searchQuery ) || getIngredients( e ) ).sort( this.sortFunction )
}
+ // } else {
+ // return 0;
+ // }
},
noResultFor() {
if ( this.filterFavourites ) return "noRecsInFavs";
@@ -186,35 +213,60 @@ export default {
if ( this.selectedCuisine ) return "noRecsInFtr";
return "noRecs";
},
+ screenWidth() {
+ return Screen.mainScreen.widthDIPs
+ },
+ imgWidth() {
+ return Screen.mainScreen.widthDIPs / 2 - 20
+ },
+
},
methods: {
- ...mapActions( [ "setCurrentComponentAction", "setSortTypeAction", "deleteRecipeAction" ] ),
+ ...mapActions( [ "setCurrentComponentAction", "setSortTypeAction", "deleteRecipeAction", "deleteRecipesAction" ] ),
onPageLoad( args ) {
const page = args.object;
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.showFAB = true;
+ this.filterFavourites ? this.setComponent( "Favourites" ) : this.filterTrylater ? this.setComponent( "Try Later" ) : this.selectedCuisine ? this.setComponent( "Filtered recipes" ) : this.setComponent( "EnRecipes" )
+ if ( !this.selectMode ) this.showFAB = true
if ( this.shakeEnabled ) startAccelerometerUpdates( data => this.onSensorData( data ) )
- if ( this.showSearch )
+ if ( this.showSearch || this.selectMode )
this.hijackLocalBackEvent()
-
+ this.showDrawer()
+ this.closeDrawer()
},
onPageUnload() {
if ( this.shakeEnabled ) stopAccelerometerUpdates();
this.releaseGlobalBackEvent();
this.releaseLocalBackEvent();
},
- // HELPERS
- showDrawer() {
- utils.showDrawer();
+ listViewLoad( args ) {
+ let e = args.object.android
+ e.setSelector( new android.graphics.drawable.StateListDrawable() )
+ e.setDivider( null );
+ e.setDividerHeight( 1 );
},
+ // switchLayout() {
+ // if ( this.layout == 2 ) this.layout = 1
+ // else this.layout++
+ // },
+ getLayout() {
+ switch ( this.layout ) {
+ case 1:
+ return 'one';
+ case 2:
+ return 'two';
+ case 3:
+ return 'three';
+ }
+ },
+
+ // HELPERS
openSearch() {
this.showSearch = true;
this.showFAB = false;
this.hijackLocalBackEvent();
},
closeSearch() {
- if ( this.searchQuery ) this.updateFilter();
this.searchQuery = "";
Utils.ad.dismissSoftInput();
this.showSearch = false;
@@ -226,9 +278,13 @@ export default {
this.hijackGlobalBackEvent();
},
clearSearch() {
- if ( this.searchQuery !== "" ) {
- this.updateFilter();
- }
+ this.searchQuery = ""
+ },
+ updateList( value ) {
+ clearTimeout( typingTimer )
+ typingTimer = setTimeout( e => {
+ this.searchQuery = value
+ }, 750 )
},
formattedTotalTime( prepTime, cookTime ) {
let t1 = prepTime.split( ":" );
@@ -238,14 +294,12 @@ export default {
let h = parseInt( t1[ 0 ] ) + parseInt( t2[ 0 ] ) + Math.floor( minutes / 60 );
let hr = localize( 'hr' )
let min = localize( 'min' )
+ let mins = h * 60 + m
return {
time: h ? ( m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}` ) : `${m} ${min}`,
- duration: `${h}${m}`
+ duration: `${mins}`
};
},
- onScroll( args ) {
- this.viewIsScrolled = args.scrollOffset ? true : false;
- },
randomRecipeID() { // TODO: show only from selected filter
let min = 0
let max = this.filteredRecipes.length - 1
@@ -266,17 +320,86 @@ export default {
searchAll() {
this.$emit( "backToHome" )
},
+ sortFunction( a, b ) {
+ const titleOrder = a.title.toLowerCase().localeCompare( b.title.toLowerCase(), Device.language, {
+ ignorePunctuation: true
+ } );
+ let d1 = this.formattedTotalTime( a.prepTime, a.cookTime ).duration;
+ let d2 = this.formattedTotalTime( b.prepTime, b.cookTime ).duration;
+ let ld1 = new Date( a.lastModified );
+ let ld2 = new Date( b.lastModified );
+ let cd1 = new Date( a.created );
+ let cd2 = new Date( b.created );
+ let r1 = a.rating
+ let r2 = b.rating
+
+ function difficultyLevel( l ) {
+ switch ( l ) {
+ case "Easy":
+ return 1;
+ case "Moderate":
+ return 2;
+ case "Challenging":
+ return 3;
+ }
+ }
+ let dl1 = difficultyLevel( a.difficulty )
+ let dl2 = difficultyLevel( b.difficulty )
+ switch ( this.sortType ) {
+ case "Title":
+ return titleOrder > 0 ? 1 : titleOrder < 0 ? -1 : 0;
+ break;
+ case "Quickest first":
+ return d1 > d2 ? 1 : d1 < d2 ? -1 : 0;
+ break;
+ case "Slowest first":
+ return d1 > d2 ? -1 : d1 < d2 ? 1 : 0;
+ break;
+ case "Rating":
+ return r1 > r2 ? -1 : r1 < r2 ? 1 : 0;
+ break;
+ case "Difficulty level":
+ return dl1 > dl2 ? 1 : dl1 < dl2 ? -1 : 0;
+ break;
+ case "Last updated":
+ return ld1 < ld2 ? 1 : ld1 > ld2 ? -1 : 0;
+ break;
+ case "Newest first":
+ return cd1 < cd2 ? 1 : cd1 > cd2 ? -1 : 0;
+ break;
+ case "Oldest first":
+ return cd1 < cd2 ? -1 : cd1 > cd2 ? 1 : 0;
+ break;
+ }
+ },
+ isFirstItem( id ) {
+ let length = this.filteredRecipes.length
+ return id == this.filteredRecipes[ 0 ].id ? 'firstItem' : id == this.filteredRecipes[ length - 1 ].id ? 'lastItem' : ''
+ },
+ isLastItem( id ) {
+ let length = this.filteredRecipes.length
+ // let lastIsOdd = ( length - 1 ) % 2 == 0
+ // if ( this.filteredRecipes.length > 1 ) {
+ // if ( id == this.filteredRecipes[ length - 2 ].id ) {
+ // if ( !lastIsOdd ) return 'lastItem'
+ // }
+ // }
+ if ( id == this.filteredRecipes[ length - 1 ].id ) return 'lastItem'
+ },
+
// NAVIGATION HANDLERS
hijackLocalBackEvent() {
this.releaseGlobalBackEvent();
- AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.searchBackEvent );
+ AndroidApplication.on( AndroidApplication.activityBackPressedEvent, this.localBackEvent );
},
releaseLocalBackEvent() {
- AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.searchBackEvent );
+ AndroidApplication.off( AndroidApplication.activityBackPressedEvent, this.localBackEvent );
this.hijackGlobalBackEvent();
},
- searchBackEvent( args ) {
+ localBackEvent( args ) {
args.cancel = true;
+ if ( this.selectMode )
+ this.clearSelection()
this.closeDrawer();
this.closeSearch();
},
@@ -313,6 +436,7 @@ export default {
backstackVisible: false
} );
},
+
// LIST HANDLERS
sortDialog() {
this.releaseGlobalBackEvent();
@@ -322,7 +446,7 @@ export default {
list: [ "Title", "Quickest first", "Slowest first", "Rating", "Difficulty level", "Last updated", "Newest first", "Oldest first" ],
stretch: false,
helpIcon: 'sort',
- bgColor: '#adb5bd',
+ bgColor: '#858585',
}
} ).then( action => {
if ( action && action !== "Cancel" && this.sortType !== action ) {
@@ -333,135 +457,89 @@ export default {
this.hijackGlobalBackEvent();
} );
},
- updateSort() {
- let listView = this.$refs.listView.nativeView;
- listView.sortingFunction = undefined;
- listView.sortingFunction = this.sortFunction;
- },
- sortFunction( item, otherItem ) {
- const titleOrder = item.title.toLowerCase().localeCompare( otherItem.title.toLowerCase(), Device.language, {
- ignorePunctuation: true
- } );
- let d1 = this.formattedTotalTime( item.prepTime, item.cookTime ).duration;
- let d2 = this.formattedTotalTime( otherItem.prepTime, otherItem.cookTime ).duration;
- let ld1 = new Date( item.lastModified );
- let ld2 = new Date( otherItem.lastModified );
- let cd1 = new Date( item.created );
- let cd2 = new Date( otherItem.created );
- let r1 = item.rating
- let r2 = otherItem.rating
- function difficultyLevel( level ) {
- switch ( level ) {
- case "Easy":
- return 1;
- case "Moderate":
- return 2;
- case "Challenging":
- return 3;
- }
- }
- let dl1 = difficultyLevel( item.difficulty )
- let dl2 = difficultyLevel( otherItem.difficulty )
- switch ( this.sortType ) {
- case "Title":
- return titleOrder > 0 ? -1 : titleOrder < 0 ? 1 : 0;
- break;
- case "Quickest first":
- return d1 > d2 ? -1 : d1 < d2 ? 1 : 0;
- break;
- case "Slowest first":
- return d1 > d2 ? 1 : d1 < d2 ? -1 : 0;
- break;
- case "Rating":
- return r1 > r2 ? 1 : r1 < r2 ? -1 : 0;
- break;
- case "Difficulty level":
- return dl1 > dl2 ? -1 : dl1 < dl2 ? 1 : 0;
- break;
- case "Last updated":
- return ld1 < ld2 ? -1 : ld1 > ld2 ? 1 : 0;
- break;
- case "Newest first":
- return cd1 < cd2 ? -1 : cd1 > cd2 ? 1 : 0;
- break;
- case "Oldest first":
- return cd1 < cd2 ? 1 : cd1 > cd2 ? -1 : 0;
- break;
- }
- },
- callUpdateFilter() {
- clearTimeout( typingTimer )
- this.filterDone = false
- typingTimer = setTimeout( e => {
- this.updateFilter()
- }, 750 )
- },
- updateFilter() {
- let listView = this.$refs.listView.nativeView;
- setTimeout( e => {
- listView.filteringFunction = undefined;
- listView.filteringFunction = this.filterFunction;
- }, 1 );
- this.filterDone = true
- },
- filterFunction( e ) {
- let ingredients = e.ingredients.map( e => e.item.toLowerCase() ).join().includes( this.searchQuery )
- if ( this.filterFavourites ) {
- return e.isFavorite ? e.title.toLowerCase().includes( this.searchQuery ) || ingredients : false;
- } else if ( this.filterTrylater ) {
- return e.tried ? false : e.title.toLowerCase().includes( this.searchQuery ) || ingredients
- } else if ( this.selectedCuisine ) {
- return this.recipeFilter( e ) ? e.title.toLowerCase().includes( this.searchQuery ) || ingredients : false;
- } else {
- return e.title.toLowerCase().includes( this.searchQuery ) || ingredients
- }
- },
- onSwiping( {
- data,
- object
- } ) {
- const swipeLimits = data.swipeLimits;
- const swipeView = object;
- const rightItem = swipeView.getViewById( "delete-action" );
- swipeLimits.right = rightItem.getMeasuredWidth() - 8;
- swipeLimits.threshold = swipeLimits.right - 4;
- if ( data.x < -swipeLimits.threshold ) {
- this.rightAction = true;
- swipeView.notifySwipeToExecuteFinished();
- }
- },
- onSwipeEnded( {
- index
- } ) {
- let recipeID = this.recipes[ index ].id;
- if ( this.rightAction && !this.deletionDialogActive ) this.deleteRecipe( index, recipeID );
- this.rightAction = false;
- },
// DATA HANDLERS
- deleteRecipe( index, recipeID ) {
+ addToSelection( args, id ) {
+ this.showFAB = false
+ if ( !this.selectMode )
+ this.hijackLocalBackEvent()
+ this.selectMode = true
+ this.$emit( "selectModeOn", false )
+ let item = args.object
+ if ( item.className === "selected" ) {
+ item.className = ""
+ this.selection.splice( this.selection.indexOf( id ), 1 )
+ this.recipeList.splice( this.selection.indexOf( id ), 1 )
+ } else {
+ item.className = "selected"
+ this.selection.push( id )
+ this.recipeList.push( item )
+ }
+ if ( !this.selection.length )
+ this.clearSelection()
+
+ },
+ clearSelection() {
+ this.selectMode = false
+ this.$emit( "selectModeOn", true )
+ this.selection = []
+ this.recipeList.forEach( e => e.className = "" )
+ this.releaseLocalBackEvent()
+ this.showFAB = true
+ },
+ deleteSelection() {
+ this.selection.length === 1 ?
+ this.deleteRecipe( this.selection[ 0 ] ) :
+ this.deleteRecipes( this.selection )
+ },
+ exportSelection() {},
+ deleteRecipe( id ) {
this.deletionDialogActive = true;
+ let index = this.recipes.findIndex( e => e.id === id )
this.$showModal( ConfirmDialog, {
props: {
title: localize( "conf" ),
description: `${localize('delRecInfo')} "${this.recipes[index].title}"`,
cancelButtonText: "cBtn",
okButtonText: "dBtn",
- helpIcon: 'trash',
+ helpIcon: 'del',
bgColor: '#c92a2a',
}
} ).then( action => {
if ( action ) {
this.deleteRecipeAction( {
index,
- id: recipeID
+ id
} );
if ( !this.filteredRecipes.length )
this.$emit( 'backToHome' )
+ this.clearSelection()
}
this.deletionDialogActive = false;
} );
},
+ deleteRecipes( idsArr ) {
+ this.deletionDialogActive = true;
+ this.$showModal( ConfirmDialog, {
+ props: {
+ title: localize( "conf" ),
+ description: `${localize('delRecsInfo')} ${this.selection.length} ${localize('recs')}`,
+ cancelButtonText: "cBtn",
+ okButtonText: "dBtn",
+ helpIcon: 'del',
+ bgColor: '#c92a2a',
+ }
+ } ).then( action => {
+ if ( action ) {
+ this.deleteRecipesAction( idsArr );
+ if ( !this.filteredRecipes.length )
+ this.$emit( 'backToHome' )
+ this.clearSelection()
+ }
+ this.deletionDialogActive = false;
+ } );
+ },
+
// SHAKE DETECTOR
onSensorData( {
x,
@@ -500,7 +578,7 @@ export default {
},
},
mounted() {
- this.showFAB = true;
+ this.showFAB = true
}
-};
+}
diff --git a/app/components/GroceryList.vue b/app/components/GroceryList.vue
index 7ba25990..16636499 100644
--- a/app/components/GroceryList.vue
+++ b/app/components/GroceryList.vue
@@ -2,9 +2,9 @@
-
+
-
+
@@ -32,11 +32,9 @@ import {
}
from "vuex"
import ConfirmDialog from "./modal/ConfirmDialog.vue"
-import * as utils from "~/shared/utils"
export default {
data() {
return {
- viewIsScrolled: false,
appTheme: "Light",
}
},
@@ -55,12 +53,6 @@ export default {
this.setCurrentComponentAction( "GroceryList" )
},
// HELPERS
- showDrawer() {
- utils.showDrawer()
- },
- onScroll( args ) {
- this.viewIsScrolled = args.scrollY ? true : false
- },
// NAVIGATION HANDLERS
viewRecipe( recipeID ) {
@@ -80,9 +72,9 @@ export default {
return snackbar
.action( {
message,
- textColor: this.appTheme == "Light" ? "#f1f3f5" : "#212529",
+ textColor: this.appTheme == "Light" ? "#fff" : "#292929",
actionTextColor: '#ff5200',
- backgroundColor: this.appTheme == "Light" ? "#212529" : "#f1f3f5",
+ backgroundColor: this.appTheme == "Light" ? "#292929" : "#fff",
actionText: 'Undo',
hideDelay: 5000
} )
diff --git a/app/components/MealPlanner.vue b/app/components/MealPlanner.vue
index 3e710c00..dce58ec3 100644
--- a/app/components/MealPlanner.vue
+++ b/app/components/MealPlanner.vue
@@ -1,59 +1,52 @@
-
-
-
+
+
+
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
diff --git a/app/components/Settings.vue b/app/components/Settings.vue
index 90710ca6..39d9e9e3 100644
--- a/app/components/Settings.vue
+++ b/app/components/Settings.vue
@@ -1,17 +1,17 @@
-
+
-
+
-
+
-
+
@@ -19,7 +19,7 @@
-
+
@@ -28,18 +28,18 @@
-
+
-
+
-
+
@@ -51,7 +51,7 @@
-
+
@@ -61,67 +61,72 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
-
+
+
+
+
+
+
@@ -165,7 +170,6 @@ import * as utils from "~/shared/utils"
export default {
data() {
return {
- viewIsScrolled: false,
appTheme: "Light",
appLanguage: "English",
backupProgress: 0,
@@ -187,12 +191,6 @@ export default {
this.setCurrentComponentAction( "Settings" )
},
// HELPERS
- showDrawer() {
- utils.showDrawer()
- },
- onScroll( args ) {
- this.viewIsScrolled = args.scrollY ? true : false
- },
openURL( url ) {
Utils.openUrl( url )
},
@@ -204,7 +202,7 @@ export default {
title: "lang",
list: [ ...languages ],
stretch: true,
- helpIcon: 'globe',
+ helpIcon: 'lang',
},
} ).then( ( action ) => {
if ( action && action !== "Cancel" && this.appLanguage !== action ) {
@@ -217,7 +215,7 @@ export default {
description: localize( "nLangInfo" ),
cancelButtonText: "cBtn",
okButtonText: "rst",
- helpIcon: 'restart',
+ helpIcon: 'res',
bgColor: '#ff5200',
},
} ).then( ( result ) => {
@@ -249,7 +247,7 @@ export default {
description: localize( "nThmInfo" ),
cancelButtonText: "cBtn",
okButtonText: "rst",
- helpIcon: 'restart',
+ helpIcon: 'res',
bgColor: '#ff5200',
},
} ).then( ( result ) => {
@@ -420,7 +418,7 @@ export default {
title: "impFail",
description,
okButtonText: "OK",
- helpIcon: 'error',
+ helpIcon: 'alert',
bgColor: '#c92a2a',
},
} )
@@ -504,8 +502,8 @@ export default {
title: "impSuc",
description: `${found} ${localize('recF')}${ importedNote}${existsNote}${updatedNote}`,
okButtonText: "OK",
- helpIcon: 'success',
- bgColor: '#94d82d',
+ helpIcon: 'succ',
+ bgColor: '#69db7c',
},
} )
},
diff --git a/app/components/ViewRecipe.vue b/app/components/ViewRecipe.vue
index f5690155..cc409e51 100644
--- a/app/components/ViewRecipe.vue
+++ b/app/components/ViewRecipe.vue
@@ -2,20 +2,20 @@
-
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -33,17 +33,17 @@
-
+
-
+
-
+
@@ -55,7 +55,7 @@
-
+
-
+
-
+
-
+
+
-
+
-
+
@@ -120,7 +120,8 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -178,10 +179,9 @@
-
-
+
@@ -202,6 +202,7 @@ import {
GridLayout,
ItemSpec,
Observable,
+ GestureTypes
}
from "@nativescript/core"
import {
@@ -236,11 +237,11 @@ export default {
showFab: false,
selectedTabIndex: 0,
currentRecipeID: this.recipeID,
- viewIsScrolled: false,
- isScrolled: [ false, false, false, false, false, false ],
hideActionBar: false,
overviewTab: null,
checks: [],
+ checkboxes: [],
+ steps: [],
}
},
computed: {
@@ -254,6 +255,9 @@ export default {
isLightMode() {
return Application.systemAppearance() === "light"
},
+ checkPadding() {
+ return `${Math.round( 20 * Utils.layout.getDisplayDensity() )},0,0,0`;
+ },
},
methods: {
...mapActions( [ "toggleStateAction", "setCurrentComponentAction", "overwriteRecipeAction", "setRecipeAsTriedAction", "setRatingAction", "toggleCartAction" ] ),
@@ -265,19 +269,20 @@ export default {
this.setCurrentComponentAction( "ViewRecipe" )
}, 500 )
this.showFab = true
- this.yieldMultiplier = this.recipe.yield.quantity
+ if ( this.yieldMultiplier == this.recipe.yield.quantity ) this.yieldMultiplier = this.recipe.yield.quantity
this.keepScreenOn( true )
this.syncCombinations()
},
onPageUnload() {
- feedback.hide()
this.keepScreenOn( false )
+ feedback.hide()
},
overviewLoaded( args ) {
this.overviewTab = args
},
+
// HELPERS
- niceDates( time ) {
+ niceDate( time ) {
let lastTried = new Date( time ).getTime()
let now = new Date().getTime()
let midnight = new Date().setHours( 0, 0, 0, 0 )
@@ -294,14 +299,13 @@ export default {
},
selectedIndexChange( args ) {
this.selectedTabIndex = args.object.selectedIndex
- this.viewIsScrolled = this.isScrolled[ this.selectedTabIndex ]
},
showLastTried() {
feedback.show( {
- title: `${localize('triedInfo')} ${this.niceDates(
+ title: `${localize('triedInfo')} ${this.niceDate(
this.recipe.lastTried
)}`,
- titleColor: new Color( `${this.isLightMode ? "#f1f3f5" : "#212529"}` ),
+ titleColor: new Color( `${this.isLightMode ? "#fff" : "#1A1A1A"}` ),
backgroundColor: new Color( "#ff5200" ),
} )
},
@@ -352,12 +356,32 @@ export default {
},
checkChange( args, index ) {
let check = args.object
+ this.checkboxes.push( check )
this.checks[ index ] = !this.checks[ index ]
},
- // NAVIGATION HANDLERS
- onScroll( args ) {
- this.viewIsScrolled = this.isScrolled[ this.selectedTabIndex ] = args.scrollY > 8 ? true : false
+ stepDone( args ) {
+ let a = args.object
+ this.steps.push( a )
+ if ( a.className !== "done" ) a.className = "done"
+ else a.className = ""
},
+ centerLabel( args ) {
+ args.object.android.setGravity( 17 )
+ },
+ clearChecks() {
+ this.checkboxes.forEach( e => {
+ if ( e.checked ) e.checked = false
+ } )
+ this.checkboxes = []
+ },
+ clearSteps() {
+ this.steps.forEach( e => {
+ if ( e.className === "done" ) e.className = ""
+ } )
+ this.steps = []
+ },
+
+ // NAVIGATION HANDLERS
editRecipe() {
this.showFab = false
this.busy = true
@@ -372,6 +396,9 @@ export default {
},
viewCombination( combination ) {
this.recipe = this.recipes.filter( ( e ) => e.id === combination )[ 0 ]
+ this.recipe.ingredients.forEach( e => this.checks.push( false ) )
+ this.clearChecks()
+ this.clearSteps()
this.currentRecipeID = combination
this.syncCombinations()
this.selectedTabIndex = 0
@@ -379,6 +406,7 @@ export default {
setTimeout(
( e ) => this.recipe.tried && this.recipe.lastTried && this.showLastTried(), 500 )
},
+
// SHARE ACTION
shareHandler() {
if ( this.recipe.imageSrc ) {
@@ -450,6 +478,7 @@ export default {
shareContent += sharenote
SocialShare.shareText( shareContent, "Share recipe using" )
},
+
// DATA HANDLERS
toggle( key, setDate ) {
this.toggleStateAction( {
@@ -475,8 +504,7 @@ export default {
this.$navigateBack()
},
setRating( rating ) {
- if ( rating !== this.recipe.rating ) {
-
+ if ( rating !== this.recipe.rating || rating === 1 ) {
this.setRatingAction( {
id: this.currentRecipeID,
recipe: this.recipe,
@@ -484,9 +512,10 @@ export default {
} )
}
},
+
// SHOPPINGLIST
toggleCart() {
- if ( !this.recipe.inCart ) {
+ if ( !this.recipe.inBag ) {
} else {
@@ -496,19 +525,16 @@ export default {
recipe: this.recipe,
} )
},
+
// NOTES
createNote( note, i ) {
const vm = this
let regex = /(https?:\/\/[^\s]+)/g
const grid = new GridLayout()
- const firstCol = new ItemSpec( 1, "auto" )
- const secondCol = new ItemSpec( 1, "star" )
- const label1 = new Label()
- const label2 = new Label()
- label1.class = "note"
- label1.textWrap = true
- label2.class = "noteCount orkm"
- label2.text = i + 1
+ const firstCol = new ItemSpec( 1, "star" )
+ const label = new Label()
+ label.class = "note"
+ label.textWrap = true
let formattedString = new FormattedString()
let textArray = note.split( regex )
@@ -526,14 +552,10 @@ export default {
textArray.forEach( ( text ) => {
createSpan( text, regex.test( text ) )
} )
- label1.formattedText = formattedString
- grid.addChild( label1 )
- grid.addChild( label2 )
- GridLayout.setColumn( label1, 0 )
- GridLayout.setColumn( label2, 0 )
- GridLayout.setColumnSpan( label1, 2 )
+ label.formattedText = formattedString
+ grid.addChild( label )
+ GridLayout.setColumn( label, 0 )
grid.addColumn( firstCol )
- grid.addColumn( secondCol )
return grid
},
createNotes( args ) {
@@ -547,10 +569,11 @@ export default {
},
created() {
this.recipe = this.recipes.filter( ( e ) => e.id === this.currentRecipeID )[ 0 ]
- this.checks = this.recipe.ingredients.map( e => true )
+ this.recipe.ingredients.forEach( e => this.checks.push( false ) )
},
mounted() {
this.showFab = true
+ this.yieldMultiplier = this.recipe.yield.quantity
setTimeout(
( e ) => this.recipe.tried && this.recipe.lastTried && this.showLastTried(), 500 )
},
diff --git a/app/components/modal/ActionDialog.vue b/app/components/modal/ActionDialog.vue
index f589710b..1429da6e 100644
--- a/app/components/modal/ActionDialog.vue
+++ b/app/components/modal/ActionDialog.vue
@@ -1,12 +1,12 @@
-
+
-
+
@@ -19,7 +19,8 @@