v2.0.0 50% ready
|
@ -6,4 +6,4 @@ Here are some important resources:
|
||||||
|
|
||||||
- The [roadmap](https://github.com/vishnuraghavb/EnRecipes/projects/1) will tell you whats the future of EnRecipes. Your feedback and suggestions are very important to make EnRecipes the best. If you have an idea to improve EnRecipes, [do let me know](https://github.com/vishnuraghavb/EnRecipes#having-issues-suggestions-and-feedback). I'm always open to ideas ;)
|
- The [roadmap](https://github.com/vishnuraghavb/EnRecipes/projects/1) will tell you whats the future of EnRecipes. Your feedback and suggestions are very important to make EnRecipes the best. If you have an idea to improve EnRecipes, [do let me know](https://github.com/vishnuraghavb/EnRecipes#having-issues-suggestions-and-feedback). I'm always open to ideas ;)
|
||||||
- You can help [translate EnRecipes using Weblate](https://hosted.weblate.org/engage/enrecipes/) into the language of your choice. See [translation instructions](https://github.com/vishnuraghavb/EnRecipes/wiki/Translation-Instructions) in the wiki for more information.
|
- You can help [translate EnRecipes using Weblate](https://hosted.weblate.org/engage/enrecipes/) into the language of your choice. See [translation instructions](https://github.com/vishnuraghavb/EnRecipes/wiki/Translation-Instructions) in the wiki for more information.
|
||||||
- Bugs, suggestions or feedback? You can [create an issue here](https://github.com/vishnuraghavb/EnRecipes/issues) or [join the Telegram group](http://t.me/enrecipes)(quicker replies) or contact me at apps@vishnuraghav.com
|
- Bugs, suggestions or feedback? You can [create an issue here](https://github.com/vishnuraghavb/EnRecipes/issues) or [join the Telegram group](http://t.me/enrecipes) (quicker replies) or contact me at apps@vishnuraghav.com
|
||||||
|
|
11
README.md
|
@ -6,7 +6,7 @@
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/license-GPL%20v3-blue"></a> <a href="https://github.com/vishnuraghavb/EnRecipes/releases" alt="Release version"><img src="https://img.shields.io/github/v/release/vishnuraghavb/EnRecipes?color=ff5200"/></a> <a href="https://hosted.weblate.org/engage/enrecipes/">
|
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/license-GPL%20v3-blue"></a> <a href="https://github.com/vishnuraghavb/EnRecipes/releases" alt="Release version"><img src="https://img.shields.io/github/v/release/vishnuraghavb/EnRecipes?color=ff5200"/></a> <a href="https://hosted.weblate.org/engage/enrecipes/">
|
||||||
<img src="https://hosted.weblate.org/widgets/enrecipes/-/app-translations/svg-badge.svg" alt="Translation status" /></a>
|
<img src="https://hosted.weblate.org/widgets/enrecipes/-/app-translations/svg-badge.svg" alt="Translation status" /></a>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://play.google.com/store/apps/details?id=com.vishnuraghav.enrecipes"><img src="assets/Images/google-play-badge.png" height="80"/></a><a href="https://apt.izzysoft.de/fdroid/index/apk/com.vishnuraghav.enrecipes"><img src="assets/Images/IzzyOnDroid.png" height="80"/></a><br>You can also get the <a href="https://github.com/vishnuraghavb/EnRecipes/releases/latest">latest release on GitHub</a>
|
<a href="https://play.google.com/store/apps/details?id=com.vishnuraghav.EnRecipes"><img src="assets/Images/google-play-badge.png" height="80"/></a><a href="https://apt.izzysoft.de/fdroid/index/apk/com.vishnuraghav.EnRecipes"><img src="assets/Images/IzzyOnDroid.png" height="80"/></a><br>You can also get the <a href="https://github.com/vishnuraghavb/EnRecipes/releases/latest">latest release on GitHub</a>
|
||||||
</p>
|
</p>
|
||||||
<h2 align="center">Enjoying EnRecipes?</h2>
|
<h2 align="center">Enjoying EnRecipes?</h2>
|
||||||
<p align="center">Please consider making a small donation to help fund the project. Developing an application, especially one that is open source and completely free, takes a lot of time and effort.
|
<p align="center">Please consider making a small donation to help fund the project. Developing an application, especially one that is open source and completely free, takes a lot of time and effort.
|
||||||
|
@ -28,16 +28,17 @@
|
||||||
- Scale your recipe ingredients to serve more or less people
|
- Scale your recipe ingredients to serve more or less people
|
||||||
- Get notified of the last time you tried a recipe
|
- 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.
|
- Share your recipe to anyone by any means as a nicely formatted message. You can share the recipe photo too.
|
||||||
- Shake device to view random recipe
|
- Shake your device to view a random recipe
|
||||||
- Create meal plans
|
- Create meal plans
|
||||||
- Import/Export recipes
|
- Set cooking timers
|
||||||
- Light, Dark and Black themes
|
- You can Import or Export your data
|
||||||
|
- Has Light, Dark and Black themes
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
|
|
||||||
- 100% free and open-source
|
- 100% free and open-source
|
||||||
- Private by Design
|
- Private by Design
|
||||||
- No permissions required
|
- No special permissions required
|
||||||
- No annoying ads or pop-ups
|
- No annoying ads or pop-ups
|
||||||
|
|
||||||
**Languages being translated**:
|
**Languages being translated**:
|
||||||
|
|
191
app/app.scss
|
@ -1,3 +1,4 @@
|
||||||
|
// Colours
|
||||||
$gray0: #f8f9fa;
|
$gray0: #f8f9fa;
|
||||||
$gray1: #f1f3f5;
|
$gray1: #f1f3f5;
|
||||||
$gray2: #e9ecef;
|
$gray2: #e9ecef;
|
||||||
|
@ -11,21 +12,29 @@ $gray9: #212529;
|
||||||
$gray10: #000000;
|
$gray10: #000000;
|
||||||
$orange: #ff5200;
|
$orange: #ff5200;
|
||||||
|
|
||||||
|
// FontSizes based on Minor Third
|
||||||
|
$t1: 25;
|
||||||
|
$t2: 21;
|
||||||
|
$t3: 17;
|
||||||
|
$t4: 14;
|
||||||
|
$t5: 12; // Base size
|
||||||
|
$t6: 10;
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
font-family: 'Inter-Medium';
|
font-family: 'Inter-Medium', sans-serif;
|
||||||
font-size: 14;
|
font-size: $t4;
|
||||||
}
|
}
|
||||||
.ico {
|
.ico {
|
||||||
font-family: 'enrecipes';
|
font-family: 'enrecipes';
|
||||||
font-size: 24;
|
font-size: 24;
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
&.sm {
|
&.sm {
|
||||||
font-size: 16;
|
font-size: $t3;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tb {
|
.tb {
|
||||||
font-family: 'Inter-Bold';
|
font-family: 'Inter-Bold', sans-serif;
|
||||||
}
|
}
|
||||||
.tac {
|
.tac {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -36,7 +45,7 @@ Page {
|
||||||
.pageTitle {
|
.pageTitle {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
font-size: 25;
|
font-size: $t1;
|
||||||
padding: 16 16 24;
|
padding: 16 16 24;
|
||||||
}
|
}
|
||||||
.Light {
|
.Light {
|
||||||
|
@ -60,7 +69,6 @@ Page {
|
||||||
background: $gray0;
|
background: $gray0;
|
||||||
}
|
}
|
||||||
.fieldLabel,
|
.fieldLabel,
|
||||||
.dayName,
|
|
||||||
.sub {
|
.sub {
|
||||||
color: $gray6;
|
color: $gray6;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +106,6 @@ Page {
|
||||||
background: $gray8;
|
background: $gray8;
|
||||||
}
|
}
|
||||||
.fieldLabel,
|
.fieldLabel,
|
||||||
.dayName,
|
|
||||||
.sub {
|
.sub {
|
||||||
color: $gray5;
|
color: $gray5;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +143,6 @@ Page {
|
||||||
background: $gray9;
|
background: $gray9;
|
||||||
}
|
}
|
||||||
.fieldLabel,
|
.fieldLabel,
|
||||||
.dayName,
|
|
||||||
.sub {
|
.sub {
|
||||||
color: $gray6;
|
color: $gray6;
|
||||||
}
|
}
|
||||||
|
@ -169,14 +175,13 @@ TextView {
|
||||||
line-height: 4;
|
line-height: 4;
|
||||||
}
|
}
|
||||||
#searchBar {
|
#searchBar {
|
||||||
padding-left: 0;
|
padding: 13 12;
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
.inputField {
|
.inputField {
|
||||||
margin-bottom: 24;
|
margin-bottom: 24;
|
||||||
}
|
}
|
||||||
.fieldLabel {
|
.fieldLabel {
|
||||||
font-size: 12;
|
font-size: $t5;
|
||||||
}
|
}
|
||||||
.progressContainer {
|
.progressContainer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -198,25 +203,28 @@ button {
|
||||||
border-radius: 12;
|
border-radius: 12;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
&:active {
|
|
||||||
@extend .fade;
|
|
||||||
}
|
|
||||||
&.ico {
|
&.ico {
|
||||||
width: 48;
|
width: 48;
|
||||||
height: 48;
|
height: 48;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
&:active {
|
||||||
|
@extend .fade;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.text {
|
&.text {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
color: $orange;
|
color: $orange;
|
||||||
|
&:active {
|
||||||
|
@extend .fade;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.big {
|
&.big {
|
||||||
margin-top: 8;
|
margin-top: 8;
|
||||||
padding: 16 0;
|
padding: 16 0;
|
||||||
}
|
}
|
||||||
&.sm {
|
&.sm {
|
||||||
font-size: 12;
|
font-size: $t5;
|
||||||
padding: 12;
|
padding: 12;
|
||||||
}
|
}
|
||||||
&.min {
|
&.min {
|
||||||
|
@ -224,10 +232,16 @@ button {
|
||||||
height: 40;
|
height: 40;
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
}
|
}
|
||||||
|
&.fb:active {
|
||||||
|
@extend .fade;
|
||||||
|
}
|
||||||
&.rate {
|
&.rate {
|
||||||
margin: 0 4 0 0;
|
margin: 0 4 0 0;
|
||||||
width: 32;
|
width: 32;
|
||||||
height: 32;
|
height: 32;
|
||||||
|
&:active {
|
||||||
|
@extend .fade;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActivityIndicator {
|
ActivityIndicator {
|
||||||
|
@ -246,14 +260,15 @@ ActivityIndicator {
|
||||||
.value {
|
.value {
|
||||||
padding: 0 0 0 8;
|
padding: 0 0 0 8;
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
&.rtl {
|
&.r {
|
||||||
padding: 0 8 0 0;
|
padding: 0 8 0 0;
|
||||||
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.select {
|
}
|
||||||
|
.select {
|
||||||
color: $orange;
|
color: $orange;
|
||||||
@extend .hl;
|
@extend .hl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.emptyState {
|
.emptyState {
|
||||||
padding: 16 16 8;
|
padding: 16 16 8;
|
||||||
|
@ -262,7 +277,7 @@ ActivityIndicator {
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
font-size: 17;
|
font-size: $t3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,22 +287,18 @@ ActivityIndicator {
|
||||||
padding: 8 16;
|
padding: 8 16;
|
||||||
.recipeInfo {
|
.recipeInfo {
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
padding: 0 0 4 8;
|
padding: 0 8 4;
|
||||||
&.rtl {
|
|
||||||
transform: none;
|
|
||||||
padding: 0 8 4 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
padding: 0 0 4;
|
padding: 0 0 4;
|
||||||
}
|
}
|
||||||
.attr {
|
}
|
||||||
font-size: 10;
|
.attrs {
|
||||||
padding: 0 6 1 2;
|
orientation: horizontal;
|
||||||
&.rtl {
|
}
|
||||||
padding: 0 2 1 6;
|
.attr {
|
||||||
}
|
font-size: $t6;
|
||||||
}
|
padding: 1 4;
|
||||||
}
|
}
|
||||||
.simple .recipeInfo {
|
.simple .recipeInfo {
|
||||||
padding: 8 0;
|
padding: 8 0;
|
||||||
|
@ -343,20 +354,24 @@ ActivityIndicator {
|
||||||
.group-info {
|
.group-info {
|
||||||
padding: 16 16 16 72;
|
padding: 16 16 16 72;
|
||||||
line-height: 4;
|
line-height: 4;
|
||||||
|
&.r {
|
||||||
|
padding: 16 72 16 16;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.options {
|
.options {
|
||||||
.option {
|
.option {
|
||||||
vertical-align: center;
|
vertical-align: center;
|
||||||
padding: 14 12;
|
padding: 14 16;
|
||||||
.ico {
|
.ico {
|
||||||
margin: 0 24 0 12;
|
width: 40;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.info,
|
.info {
|
||||||
.sub {
|
padding: 0 16;
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
}
|
}
|
||||||
.sub {
|
.sub {
|
||||||
font-size: 12;
|
font-size: $t5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,7 +386,7 @@ ActivityIndicator {
|
||||||
horizontal-alignment: center;
|
horizontal-alignment: center;
|
||||||
}
|
}
|
||||||
.name {
|
.name {
|
||||||
font-size: 21;
|
font-size: $t2;
|
||||||
}
|
}
|
||||||
.info {
|
.info {
|
||||||
padding: 8 16 24;
|
padding: 8 16 24;
|
||||||
|
@ -394,9 +409,8 @@ ActivityIndicator {
|
||||||
}
|
}
|
||||||
.attribute {
|
.attribute {
|
||||||
margin: 8 16;
|
margin: 8 16;
|
||||||
.title {
|
.sub {
|
||||||
margin-right: 8;
|
font-size: $t5;
|
||||||
font-size: 12;
|
|
||||||
}
|
}
|
||||||
.value {
|
.value {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
|
@ -416,7 +430,7 @@ ActivityIndicator {
|
||||||
padding: 0 16;
|
padding: 0 16;
|
||||||
.count {
|
.count {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
font-size: 17;
|
font-size: $t3;
|
||||||
}
|
}
|
||||||
.value {
|
.value {
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
|
@ -443,7 +457,7 @@ ActivityIndicator {
|
||||||
}
|
}
|
||||||
.dateInfo {
|
.dateInfo {
|
||||||
padding: 32 16 16;
|
padding: 32 16 16;
|
||||||
font-size: 12;
|
font-size: $t5;
|
||||||
line-height: 4;
|
line-height: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,10 +473,12 @@ ActivityIndicator {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
vertical-align: center;
|
vertical-align: center;
|
||||||
|
margin: 0 12;
|
||||||
line-height: 4;
|
line-height: 4;
|
||||||
}
|
}
|
||||||
.msg {
|
.msg {
|
||||||
padding: 14 16;
|
padding: 14 16;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
.fab {
|
.fab {
|
||||||
margin-left: 8;
|
margin-left: 8;
|
||||||
|
@ -471,21 +487,21 @@ ActivityIndicator {
|
||||||
margin: 8 8 0;
|
margin: 8 8 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.sidebar {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
.toolbar {
|
.toolbar {
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
padding: 4;
|
padding: 4;
|
||||||
margin: 0 0 52;
|
margin: 0 0 52;
|
||||||
horizontal-alignment: left;
|
|
||||||
.tool {
|
.tool {
|
||||||
padding: 0 12;
|
padding: 0 8;
|
||||||
label {
|
label {
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
}
|
}
|
||||||
|
.value,
|
||||||
.ico {
|
.ico {
|
||||||
padding: 0 8 0 0;
|
padding: 0 4;
|
||||||
&.rtl {
|
|
||||||
padding: 0 0 0 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,7 +515,7 @@ ActivityIndicator {
|
||||||
.sectionTitle {
|
.sectionTitle {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
font-size: 21;
|
font-size: $t2;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 32 0 16;
|
margin: 32 0 16;
|
||||||
}
|
}
|
||||||
|
@ -509,49 +525,51 @@ ActivityIndicator {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.countdown {
|
.countdown {
|
||||||
font-size: 17;
|
font-size: $t3;
|
||||||
color: $orange;
|
color: $orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// MealPlanner
|
// MealPlanner
|
||||||
.calendar {
|
.monthSwitcher {
|
||||||
padding: 0 8;
|
padding: 0 16;
|
||||||
.navBtn {
|
.month {
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.monthName {
|
|
||||||
text-align: center;
|
|
||||||
vertical-alignment: center;
|
vertical-alignment: center;
|
||||||
font-size: 17;
|
|
||||||
}
|
|
||||||
.dayName {
|
|
||||||
margin: 8 0;
|
|
||||||
font-size: 12;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
font-size: $t3;
|
||||||
.day {
|
|
||||||
border-radius: 12;
|
|
||||||
}
|
|
||||||
.hasPlans {
|
|
||||||
color: $orange;
|
|
||||||
}
|
|
||||||
.activeDay {
|
|
||||||
@extend .hl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dayPlan {
|
.calendar {
|
||||||
padding: 16 16 80;
|
padding: 0 16;
|
||||||
width: 100%;
|
.dayName {
|
||||||
.periodLabel {
|
vertical-alignment: center;
|
||||||
font-size: 17;
|
text-align: center;
|
||||||
text-transform: capitalize;
|
font-size: $t5;
|
||||||
vertical-align: center;
|
|
||||||
}
|
}
|
||||||
.recipeTitle {
|
.accent.sub {
|
||||||
@extend .tw;
|
color: rgba($orange, 0.5);
|
||||||
padding: 16 8;
|
}
|
||||||
line-height: 4;
|
}
|
||||||
|
.plans {
|
||||||
|
padding: 8 16 80;
|
||||||
|
width: 100%;
|
||||||
|
.date {
|
||||||
|
font-size: $t2;
|
||||||
|
padding: 16 0;
|
||||||
|
}
|
||||||
|
.plan {
|
||||||
|
padding: 8 0;
|
||||||
|
}
|
||||||
|
.meal {
|
||||||
|
font-size: $t3;
|
||||||
|
padding: 8 0;
|
||||||
|
}
|
||||||
|
.planContent {
|
||||||
|
min-height: 48;
|
||||||
|
padding: 8;
|
||||||
|
}
|
||||||
|
.attr {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +584,7 @@ ActivityIndicator {
|
||||||
@extend .tb;
|
@extend .tb;
|
||||||
@extend .tw;
|
@extend .tw;
|
||||||
padding: 16;
|
padding: 16;
|
||||||
font-size: 21;
|
font-size: $t2;
|
||||||
}
|
}
|
||||||
.input {
|
.input {
|
||||||
padding: 0 16 8;
|
padding: 0 16 8;
|
||||||
|
@ -581,13 +599,12 @@ ActivityIndicator {
|
||||||
margin: 16 0;
|
margin: 16 0;
|
||||||
}
|
}
|
||||||
.listItem {
|
.listItem {
|
||||||
@extend .tw;
|
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
line-height: 4;
|
line-height: 4;
|
||||||
padding: 13 16;
|
padding: 13 16;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.shareItem {
|
.shareItem {
|
||||||
border-radius: 12;
|
border-radius: 12;
|
||||||
|
@ -649,10 +666,10 @@ ActivityIndicator {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
.rtl {
|
.f {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
.clickable {
|
.accent {
|
||||||
color: $orange;
|
color: $orange;
|
||||||
}
|
}
|
||||||
.hal {
|
.hal {
|
||||||
|
|
|
@ -1,53 +1,55 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" @unloaded="pgUnload" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="*">
|
<GridLayout rows="*, auto" columns="*">
|
||||||
<ScrollView
|
<ScrollView
|
||||||
@scroll="onScroll($event)"
|
@scroll="svScroll($event)"
|
||||||
rowSpan="2"
|
rowSpan="2"
|
||||||
scrollBarIndicatorVisible="false"
|
scrollBarIndicatorVisible="false"
|
||||||
>
|
>
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, auto, 8">
|
<RGridLayout :rtl="RTL" rows="auto" columns="*, auto, 12">
|
||||||
<Label class="pageTitle" :text="'timer' | L" />
|
<RLabel class="pageTitle" :text="'timer' | L" />
|
||||||
<Button
|
<Button col="1" class="ico" :text="icon.cog" @tap="navigateTo" />
|
||||||
col="1"
|
</RGridLayout>
|
||||||
class="ico"
|
|
||||||
:text="icon.cog"
|
|
||||||
@tap="$navigateTo(CTSettings)"
|
|
||||||
/>
|
|
||||||
</GridLayout>
|
|
||||||
<Timer
|
<Timer
|
||||||
v-for="(timer, i) in activeTimers"
|
v-for="timer in activeTimers"
|
||||||
:key="timer.id"
|
:key="timer.id + key"
|
||||||
:timer="timer"
|
:timer="timer"
|
||||||
:timerIndex="i"
|
|
||||||
:formattedTime="formattedTime"
|
:formattedTime="formattedTime"
|
||||||
:removeTimer="removeTimer"
|
:removeTimer="removeTimer"
|
||||||
:addToPreset="addToPreset"
|
|
||||||
:togglePause="togglePause"
|
:togglePause="togglePause"
|
||||||
:fireTimer="fireTimer"
|
:timerAlert="timerAlert"
|
||||||
|
:showToast="showToast"
|
||||||
/>
|
/>
|
||||||
<StackLayout class="listSpace"> </StackLayout>
|
<StackLayout class="listSpace"> </StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<GridLayout
|
<GridLayout v-if="!activeTimers.length" rows="*, auto">
|
||||||
|
<StackLayout row="1" class="emptyState">
|
||||||
|
<RLabel class="title" :text="'ccwt' | L" />
|
||||||
|
<RLabel :text="'plsAdd' | L" />
|
||||||
|
</StackLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
row="1"
|
row="1"
|
||||||
@loaded="onAppBarLoad"
|
@loaded="abLoad"
|
||||||
class="appbar"
|
class="appbar"
|
||||||
:hidden="showUndo"
|
:hidden="showUndo"
|
||||||
columns="auto, *, auto"
|
columns="auto, *, auto"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico rtl" :text="icon.back" @tap="navigateBack" />
|
||||||
<Button class="ico fab" :text="icon.plus" @tap="addTimer" col="2" />
|
<Button class="ico fab" :text="icon.plus" @tap="addTimer" col="2" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<SnackBar
|
<SnackBar
|
||||||
:hidden="!showUndo || toast"
|
:hidden="!showUndo || toast"
|
||||||
:count="countdown"
|
:count="countdown"
|
||||||
:msg="snackMsg"
|
:msg="snackMsg"
|
||||||
:undo="undoDel"
|
:undo="undoDel"
|
||||||
:action="hideBar"
|
:action="hideBar"
|
||||||
|
:onload="sbLoad"
|
||||||
/>
|
/>
|
||||||
<Toast :toast="toast" :action="hideBar" />
|
<Toast :onload="tbLoad" :toast="toast" :action="hideBar" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -58,13 +60,17 @@ import {
|
||||||
Observable,
|
Observable,
|
||||||
CoreTypes,
|
CoreTypes,
|
||||||
Application,
|
Application,
|
||||||
ApplicationSettings,
|
|
||||||
AndroidApplication,
|
|
||||||
Utils,
|
Utils,
|
||||||
Device,
|
Device,
|
||||||
|
Frame,
|
||||||
} from "@nativescript/core";
|
} from "@nativescript/core";
|
||||||
|
import {
|
||||||
|
getNumber,
|
||||||
|
setNumber,
|
||||||
|
remove,
|
||||||
|
} from "@nativescript/core/application-settings";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
|
import EnRecipes from "./EnRecipes.vue";
|
||||||
import Action from "./modals/Action.vue";
|
import Action from "./modals/Action.vue";
|
||||||
import CTSettings from "./settings/CTSettings.vue";
|
import CTSettings from "./settings/CTSettings.vue";
|
||||||
import TimePickerHMS from "./modals/TimePickerHMS.vue";
|
import TimePickerHMS from "./modals/TimePickerHMS.vue";
|
||||||
|
@ -72,13 +78,10 @@ import TimerReminder from "./modals/TimerReminder.vue";
|
||||||
import Timer from "./sub/Timer.vue";
|
import Timer from "./sub/Timer.vue";
|
||||||
import Toast from "./sub/Toast.vue";
|
import Toast from "./sub/Toast.vue";
|
||||||
import SnackBar from "./sub/SnackBar.vue";
|
import SnackBar from "./sub/SnackBar.vue";
|
||||||
|
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
import { EventBus } from "~/main";
|
import { EvtBus } from "~/main";
|
||||||
let undoTimer,
|
let barTimer;
|
||||||
firingTimers = [];
|
declare const com, android: any;
|
||||||
declare const com: any;
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Timer, Toast, SnackBar },
|
components: { Timer, Toast, SnackBar },
|
||||||
props: ["recipeID"],
|
props: ["recipeID"],
|
||||||
|
@ -86,43 +89,62 @@ export default {
|
||||||
return {
|
return {
|
||||||
scrollPos: 1,
|
scrollPos: 1,
|
||||||
appbar: null,
|
appbar: null,
|
||||||
|
toastbar: null,
|
||||||
|
snackbar: null,
|
||||||
|
scrollView: null,
|
||||||
countdown: 5,
|
countdown: 5,
|
||||||
snackMsg: null,
|
snackMsg: null,
|
||||||
showUndo: false,
|
showUndo: 0,
|
||||||
undo: false,
|
undo: 0,
|
||||||
CTSettings: CTSettings,
|
|
||||||
toast: null,
|
toast: null,
|
||||||
|
key: 99,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
"icon",
|
"icon",
|
||||||
"recipes",
|
"recipes",
|
||||||
"currentComponent",
|
|
||||||
"timerSound",
|
"timerSound",
|
||||||
"timerVibrate",
|
"timerVibrate",
|
||||||
"timerDelay",
|
|
||||||
"timerPresets",
|
"timerPresets",
|
||||||
"activeTimers",
|
"activeTimers",
|
||||||
|
"FGService",
|
||||||
|
"RTL",
|
||||||
]),
|
]),
|
||||||
|
hasBackStack() {
|
||||||
|
return Frame.topmost().backStack.length;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions([
|
||||||
"setComponent",
|
|
||||||
"addActiveTimer",
|
"addActiveTimer",
|
||||||
"removeActiveTimer",
|
"removeActiveTimer",
|
||||||
"clearTimerInterval",
|
"clearTimerInterval",
|
||||||
"addTimerPreset",
|
"addTimerPreset",
|
||||||
"updateActiveTimer",
|
"updateActiveTimer",
|
||||||
|
"setFGService",
|
||||||
]),
|
]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
this.setComponent("CookingTimer");
|
if (this.activeTimers.filter((e: any) => e.done).length)
|
||||||
|
this.openReminder();
|
||||||
|
this.keepScreenOnCountUp();
|
||||||
|
setNumber("isTimer", 1);
|
||||||
},
|
},
|
||||||
onAppBarLoad({ object }) {
|
pgUnload() {
|
||||||
|
utils.keepScreenOn(0);
|
||||||
|
},
|
||||||
|
abLoad({ object }) {
|
||||||
this.appbar = object;
|
this.appbar = object;
|
||||||
},
|
},
|
||||||
onScroll(args) {
|
tbLoad({ object }) {
|
||||||
|
this.toastbar = object;
|
||||||
|
},
|
||||||
|
sbLoad({ object }) {
|
||||||
|
this.snackbar = object;
|
||||||
|
},
|
||||||
|
svScroll(args) {
|
||||||
|
this.scrollView = args.object;
|
||||||
let scrollUp;
|
let scrollUp;
|
||||||
let y = args.scrollY;
|
let y = args.scrollY;
|
||||||
if (y) {
|
if (y) {
|
||||||
|
@ -132,18 +154,19 @@ export default {
|
||||||
if (!scrollUp && ab == 0) {
|
if (!scrollUp && ab == 0) {
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 64 },
|
translate: { x: 0, y: 64 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
} else if (scrollUp && ab == 64) {
|
} else if (scrollUp && ab == 64) {
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 0 },
|
translate: { x: 0, y: 0 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
getRecipeTitle(id) {
|
getRecipeTitle(id) {
|
||||||
let recipe = this.recipes.filter((e) => e.id === id)[0];
|
let recipe = this.recipes.filter((e) => e.id === id)[0];
|
||||||
|
@ -168,81 +191,111 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// NOTIFICATION HANDLERS
|
// NOTIFICATION HANDLERS
|
||||||
notifyTimers() {
|
timerInfo() {
|
||||||
let activeCount = this.activeTimers.length;
|
let activeCount = this.activeTimers.length;
|
||||||
let pausedCount = this.activeTimers.filter((e) => e.isPaused).length;
|
let pausedCount = this.activeTimers.filter((e) => e.isPaused).length;
|
||||||
let ongoingCount = activeCount - pausedCount;
|
let ongoingCount = activeCount - pausedCount;
|
||||||
console.log("notifying");
|
this.foregroundService(activeCount);
|
||||||
|
function show() {
|
||||||
utils.TimerNotif.show({
|
utils.TimerNotif.show({
|
||||||
bID: "bringToFront",
|
bID: "info",
|
||||||
cID: "cti",
|
cID: "cti",
|
||||||
cName: "Cooking Timer info",
|
cName: "Cooking Timer info",
|
||||||
description: `${ongoingCount} ongoing, ${pausedCount} paused`,
|
description: localize("oAP", ongoingCount + "", pausedCount),
|
||||||
nID: 777,
|
nID: 6,
|
||||||
priority: -2,
|
priority: -2,
|
||||||
sound: null,
|
sound: null,
|
||||||
title: localize("timer"),
|
title: localize("timer"),
|
||||||
});
|
});
|
||||||
if (activeCount <= 0) this.foregroundService(false);
|
}
|
||||||
|
if (this.FGService)
|
||||||
|
setTimeout(() => this.activeTimers.length && show(), 250);
|
||||||
|
this.keepScreenOnCountUp();
|
||||||
|
utils.wakeLock(ongoingCount);
|
||||||
},
|
},
|
||||||
fireTimer(timer) {
|
timerAlert() {
|
||||||
console.log("firing");
|
let title, description, bID;
|
||||||
let description = timer.recipeID
|
let firedTimers = this.activeTimers.filter((e) => e.done);
|
||||||
? " - " + this.getRecipeTitle(timer.recipeID)
|
let timer = firedTimers[0];
|
||||||
: "";
|
if (firedTimers.length > 1) {
|
||||||
let title = timer.label;
|
title = localize("texp", firedTimers.length);
|
||||||
let time = this.formattedTime(timer.time);
|
description = localize("ttv");
|
||||||
let bID = "timer" + timer.id;
|
bID = "alerts";
|
||||||
|
} else if (firedTimers.length == 1) {
|
||||||
|
title =
|
||||||
|
timer.label +
|
||||||
|
(timer.recipeID ? " - " + this.getRecipeTitle(timer.recipeID) : "");
|
||||||
|
description = this.formattedTime(timer.time);
|
||||||
|
bID = "timer" + timer.id;
|
||||||
|
} else {
|
||||||
|
utils.TimerNotif.clear(7);
|
||||||
|
return;
|
||||||
|
}
|
||||||
utils.TimerNotif.show({
|
utils.TimerNotif.show({
|
||||||
actions: true,
|
actions: 1,
|
||||||
bID,
|
bID,
|
||||||
cID: "cta",
|
cID: "cta",
|
||||||
cName: "Cooking Timer alerts",
|
cName: "Cooking Timer alerts",
|
||||||
description: time,
|
description,
|
||||||
nID: timer.id,
|
multi: firedTimers.length > 1,
|
||||||
|
nID: 7,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
sound: this.timerSound.uri,
|
sound: this.timerSound.uri,
|
||||||
title: title + description,
|
title,
|
||||||
vibrate: this.timerVibrate,
|
vibrate: this.timerVibrate,
|
||||||
});
|
});
|
||||||
|
if (firedTimers.length == 1) {
|
||||||
Application.android.registerBroadcastReceiver(bID, (ctx, intent) => {
|
Application.android.registerBroadcastReceiver(bID, (ctx, intent) => {
|
||||||
let action = intent.getStringExtra("action");
|
EvtBus.$emit(bID, intent.getStringExtra("action"));
|
||||||
console.log(action, "firing");
|
Application.android.unregisterBroadcastReceiver(bID);
|
||||||
EventBus.$emit(bID, action);
|
|
||||||
});
|
});
|
||||||
firingTimers.push(timer);
|
} else {
|
||||||
// if (firingTimers.length == 1) {
|
Application.android.unregisterBroadcastReceiver(bID);
|
||||||
// this.$showModal(TimerReminder, {
|
Application.android.registerBroadcastReceiver(bID, (ctx, intent) => {
|
||||||
// fullscreen: true,
|
if (intent.getStringExtra("action") == "dismissAll") {
|
||||||
// props: {
|
firedTimers.forEach((t) => this.removeTimer(t.id, 1));
|
||||||
// timers: firingTimers,
|
Application.android.unregisterBroadcastReceiver(bID);
|
||||||
// stop: this.stopFiringTimers,
|
}
|
||||||
// formattedTime: this.formattedTime,
|
});
|
||||||
// },
|
}
|
||||||
// });
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
stopFiringTimers() {
|
openReminder() {
|
||||||
firingTimers.forEach((e) => utils.TimerNotif.clear(e.id));
|
this.clearTimerInterval();
|
||||||
firingTimers = [];
|
this.$showModal(TimerReminder, {
|
||||||
|
fullscreen: true,
|
||||||
|
props: {
|
||||||
|
formattedTime: this.formattedTime,
|
||||||
|
removeTimer: this.removeTimer,
|
||||||
|
togglePause: this.togglePause,
|
||||||
|
timerAlert: this.timerAlert,
|
||||||
|
showToast: this.showToast,
|
||||||
},
|
},
|
||||||
openReminder() {},
|
}).then(() => {
|
||||||
foregroundService(bool) {
|
this.clearTimerInterval();
|
||||||
|
this.key = Math.floor(Math.random() * 900) + 100;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
foregroundService(n) {
|
||||||
const ctx = Utils.ad.getApplicationContext();
|
const ctx = Utils.ad.getApplicationContext();
|
||||||
const intent = new android.content.Intent(
|
const intent = new android.content.Intent(
|
||||||
ctx,
|
ctx,
|
||||||
com.tns.ForegroundService.class
|
com.tns.ForegroundService.class
|
||||||
);
|
);
|
||||||
if (bool)
|
if (n && !this.FGService) {
|
||||||
parseInt(Device.sdkVersion) < 26
|
parseInt(Device.sdkVersion) < 26
|
||||||
? ctx.startService(intent)
|
? ctx.startService(intent)
|
||||||
: ctx.startForegroundService(intent);
|
: ctx.startForegroundService(intent);
|
||||||
else ctx.stopService(intent);
|
this.setFGService(1);
|
||||||
|
setNumber("FGService", 1);
|
||||||
|
} else if (!this.activeTimers.length) {
|
||||||
|
ctx.stopService(intent);
|
||||||
|
this.setFGService(0);
|
||||||
|
setNumber("FGService", 0);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// DATA HANDLERS
|
// DATA HANDLERS
|
||||||
addTimer() {
|
addTimer() {
|
||||||
this.foregroundService(true);
|
|
||||||
this.$showModal(TimePickerHMS, {
|
this.$showModal(TimePickerHMS, {
|
||||||
props: {
|
props: {
|
||||||
title: "ntmr",
|
title: "ntmr",
|
||||||
|
@ -258,7 +311,7 @@ export default {
|
||||||
);
|
);
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "tmrPrsts",
|
title: "prsts",
|
||||||
list,
|
list,
|
||||||
},
|
},
|
||||||
}).then((preset) => {
|
}).then((preset) => {
|
||||||
|
@ -266,128 +319,155 @@ export default {
|
||||||
let timer = JSON.parse(
|
let timer = JSON.parse(
|
||||||
JSON.stringify(this.timerPresets[list.indexOf(preset)])
|
JSON.stringify(this.timerPresets[list.indexOf(preset)])
|
||||||
);
|
);
|
||||||
timer.id = this.getRandomID();
|
timer.id = utils.getRandomID(1);
|
||||||
|
timer.recipeID = this.recipeID;
|
||||||
|
timer.timerInt = timer.isPaused = 0;
|
||||||
|
timer.preset = timer.mode = 1;
|
||||||
this.addActiveTimer({
|
this.addActiveTimer({
|
||||||
timer,
|
timer,
|
||||||
index: this.activeTimers.length,
|
i: this.activeTimers.length,
|
||||||
});
|
});
|
||||||
this.notifyTimers();
|
this.timerInfo();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (res.time != "00:00:00") {
|
let mode = res.time != "00:00:00" ? 1 : 0;
|
||||||
this.addActiveTimer({
|
this.addActiveTimer({
|
||||||
timer: {
|
timer: {
|
||||||
id: this.getRandomID(),
|
id: utils.getRandomID(1),
|
||||||
label: res.label,
|
label: res.label,
|
||||||
recipeID: this.recipeID,
|
recipeID: this.recipeID,
|
||||||
time: res.time,
|
time: res.time,
|
||||||
timerInterval: null,
|
timerInt: 0,
|
||||||
isPaused: false,
|
isPaused: 0,
|
||||||
preset: 0,
|
preset: 0,
|
||||||
|
done: 0,
|
||||||
|
mode,
|
||||||
},
|
},
|
||||||
index: this.activeTimers.length,
|
i: this.activeTimers.length,
|
||||||
});
|
});
|
||||||
this.notifyTimers();
|
this.timerInfo();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
removeTimer(id, index, noUndo) {
|
removeTimer(id, noUndo) {
|
||||||
let temp = this.activeTimers[index];
|
let i = this.activeTimers.findIndex((e) => e.id == id);
|
||||||
this.removeActiveTimer(index);
|
let temp = this.activeTimers[i];
|
||||||
utils.TimerNotif.clear(id);
|
clearInterval(temp.timerInt);
|
||||||
|
temp.timerInt = 0;
|
||||||
|
this.removeActiveTimer(i);
|
||||||
|
let secs = [getNumber(`${temp.id}c`, 0), getNumber(`${temp.id}d`, 0)];
|
||||||
|
function removeSettings() {
|
||||||
|
remove(`${temp.id}c`);
|
||||||
|
remove(`${temp.id}d`);
|
||||||
|
}
|
||||||
|
removeSettings();
|
||||||
if (!noUndo) {
|
if (!noUndo) {
|
||||||
this.showUndoBar("tmrClr")
|
this.showUndoBar("tmrRm")
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.foregroundService(true);
|
setNumber(`${temp.id}c`, secs[0]),
|
||||||
|
setNumber(`${temp.id}d`, secs[1]),
|
||||||
this.addActiveTimer({
|
this.addActiveTimer({
|
||||||
timer: temp,
|
timer: temp,
|
||||||
index,
|
i,
|
||||||
});
|
});
|
||||||
this.notifyTimers();
|
this.timerInfo();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => removeSettings());
|
||||||
ApplicationSettings.remove(`${temp.id}progress`);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this.notifyTimers();
|
this.timerAlert();
|
||||||
|
this.timerInfo();
|
||||||
},
|
},
|
||||||
addToPreset(timer) {
|
togglePause(timer, n) {
|
||||||
timer = JSON.parse(JSON.stringify(timer));
|
timer.isPaused =
|
||||||
timer.recipeID = timer.timerInterval = null;
|
typeof n === "number" ? n : (!timer.isPaused as boolean | 0);
|
||||||
timer.preset = 1;
|
|
||||||
this.addTimerPreset(timer);
|
|
||||||
this.showToast("aTPrst");
|
|
||||||
},
|
|
||||||
togglePause(timer, bool) {
|
|
||||||
if (typeof bool === "boolean") timer.isPaused = bool;
|
|
||||||
else timer.isPaused = !timer.isPaused;
|
|
||||||
this.updateActiveTimer(timer);
|
this.updateActiveTimer(timer);
|
||||||
this.notifyTimers();
|
n ? 0 : this.timerInfo();
|
||||||
},
|
},
|
||||||
showToast(data) {
|
showToast(data) {
|
||||||
|
this.animateBar(this.snackbar, 0);
|
||||||
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
|
this.showUndo = 0;
|
||||||
this.toast = localize(data);
|
this.toast = localize(data);
|
||||||
utils.timer(5, (val) => {
|
this.animateBar(this.toastbar, 1);
|
||||||
if (!val) this.toast = val;
|
let a = 5;
|
||||||
|
clearInterval(barTimer);
|
||||||
|
barTimer = setInterval(() => a-- < 1 && this.hideBar(), 1000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showUndoBar(message) {
|
showUndoBar(message) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
clearTimeout(undoTimer);
|
this.animateBar(this.toastbar, 0);
|
||||||
this.showUndo = true;
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
|
this.toast = null;
|
||||||
|
this.showUndo = 1;
|
||||||
this.snackMsg = message;
|
this.snackMsg = message;
|
||||||
this.countdown = 5;
|
this.countdown = 5;
|
||||||
|
this.animateBar(this.snackbar, 1).then(() => {
|
||||||
let a = 5;
|
let a = 5;
|
||||||
undoTimer = setInterval(() => {
|
clearInterval(barTimer);
|
||||||
|
barTimer = setInterval(() => {
|
||||||
if (this.undo) {
|
if (this.undo) {
|
||||||
this.showUndo = this.undo = false;
|
this.hideBar();
|
||||||
clearTimeout(undoTimer);
|
resolve(1);
|
||||||
resolve(true);
|
|
||||||
}
|
}
|
||||||
this.countdown = Math.round((a -= 0.1));
|
this.countdown = Math.round((a -= 0.1));
|
||||||
if (this.countdown < 1) {
|
if (this.countdown < 1) {
|
||||||
this.showUndo = false;
|
this.hideBar();
|
||||||
clearTimeout(undoTimer);
|
reject(1);
|
||||||
reject(true);
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
hideBar({ object }) {
|
hideBar() {
|
||||||
this.appbar.translateY = 64;
|
clearInterval(barTimer);
|
||||||
object
|
this.animateBar(this.toast ? this.toastbar : this.snackbar, 0).then(
|
||||||
.animate({
|
() => {
|
||||||
opacity: 0,
|
this.showUndo = this.undo = 0;
|
||||||
translate: { x: 0, y: 64 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.showUndo = false;
|
|
||||||
this.toast = null;
|
this.toast = null;
|
||||||
this.appbar.animate({
|
this.animateBar(this.appbar, 1);
|
||||||
translate: { x: 0, y: 0 },
|
}
|
||||||
duration: 250,
|
);
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
|
||||||
object.opacity = 1;
|
|
||||||
object.translateY = 0;
|
|
||||||
clearTimeout(undoTimer);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
undoDel() {
|
undoDel() {
|
||||||
this.undo = true;
|
this.undo = 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
//NAVIGATION HANDLERS
|
||||||
|
navigateTo() {
|
||||||
|
this.$navigateTo(CTSettings, {
|
||||||
|
transition: {
|
||||||
|
name: this.RTL ? "slideRight" : "slide",
|
||||||
|
duration: 200,
|
||||||
|
curve: "easeOut",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
navigateBack() {
|
||||||
|
setNumber("isTimer", 0);
|
||||||
|
this.hasBackStack
|
||||||
|
? this.$navigateBack()
|
||||||
|
: this.$navigateTo(EnRecipes, {
|
||||||
|
clearHistory: true,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
getRandomID() {
|
keepScreenOnCountUp() {
|
||||||
return Math.floor(Math.random() * 9000000000) + 1000000000;
|
utils.keepScreenOn(
|
||||||
|
this.activeTimers.filter((e: any) => !e.isPaused).length
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.clearTimerInterval();
|
this.clearTimerInterval();
|
||||||
|
this.recipeID && this.addTimer();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
setNumber("isTimer", 0);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" @unloaded="onPageUnload" actionBarHidden="true">
|
<Page @loaded="pgLoad" @unloaded="onPageUnload" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<GridLayout rows="*, auto" columns="auto, *, auto">
|
||||||
<ScrollView
|
<ScrollView rowSpan="2" colSpan="3" @scroll="!showUndo && svLoad($event)">
|
||||||
rowSpan="2"
|
|
||||||
colSpan="2"
|
|
||||||
@scroll="!showUndo && onScroll($event)"
|
|
||||||
>
|
|
||||||
<StackLayout padding="0 16 72">
|
<StackLayout padding="0 16 72">
|
||||||
<Label class="pageTitle" padding="16 0" :text="`${title}` | L" />
|
<RLabel class="pageTitle" padding="16 0 24" :text="`${title}` | L" />
|
||||||
<Image
|
<Image
|
||||||
margin="8 0 32"
|
margin="0 0 32"
|
||||||
v-if="recipe.image"
|
v-if="recipe.image"
|
||||||
:src="recipe.image"
|
:src="recipe.image"
|
||||||
stretch="aspectFit"
|
stretch="aspectFit"
|
||||||
|
@ -20,7 +16,7 @@
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
margin="8 0 32"
|
margin="0 0 32"
|
||||||
class="ico imgHolder"
|
class="ico imgHolder"
|
||||||
fontSize="128"
|
fontSize="128"
|
||||||
:width="screenWidth - 32"
|
:width="screenWidth - 32"
|
||||||
|
@ -37,30 +33,33 @@
|
||||||
@loaded="setInputTypeText($event, 'words')"
|
@loaded="setInputTypeText($event, 'words')"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout columns="*, 8, *">
|
<RGridLayout :rtl="RTL" class="" columns="*, 8, *">
|
||||||
<StackLayout class="inputField">
|
<StackLayout class="inputField">
|
||||||
<Label class="fieldLabel" :text="'cui' | L" />
|
<Label class="fieldLabel" :text="'cui' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
:text="recipe.cuisine | L"
|
:text="recipe.cuisine | L"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && showCuisine(true)"
|
@focus="!modalOpen && showCuisine(1)"
|
||||||
@tap="showCuisine(false)"
|
@tap="showCuisine(0)"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout class="inputField" col="2">
|
<StackLayout class="inputField" col="2">
|
||||||
<Label class="fieldLabel" :text="'cat' | L" />
|
<Label class="fieldLabel" :text="'cat' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
ref="category"
|
ref="category"
|
||||||
:text="recipe.category | L"
|
:text="recipe.category | L"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && showCategories(true)"
|
@focus="!modalOpen && showCategories(1)"
|
||||||
@tap="showCategories(false)"
|
@tap="showCategories(0)"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<StackLayout class="inputField">
|
<StackLayout class="inputField">
|
||||||
<Label class="fieldLabel" :text="'ts' | L" />
|
<Label class="fieldLabel" :text="'ts' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
:hint="'tsInfo' | L"
|
:hint="'tsInfo' | L"
|
||||||
autocapitalizationType="words"
|
autocapitalizationType="words"
|
||||||
ref="tags"
|
ref="tags"
|
||||||
|
@ -69,31 +68,34 @@
|
||||||
returnKeyType="next"
|
returnKeyType="next"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout columns="*, 8, *">
|
<RGridLayout :rtl="RTL" columns="*, 8, *">
|
||||||
<StackLayout class="inputField">
|
<StackLayout class="inputField">
|
||||||
<Label class="fieldLabel" :text="'prepT' | L" />
|
<Label class="fieldLabel" :text="'prepT' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
:text="timeRequired('prepTime')"
|
:text="timeRequired('prepTime')"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && setTimeRequired(true, 'prepTime')"
|
@focus="!modalOpen && setTimeRequired(1, 'prepTime')"
|
||||||
@tap="setTimeRequired(false, 'prepTime')"
|
@tap="setTimeRequired(0, 'prepTime')"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout class="inputField" col="2">
|
<StackLayout class="inputField" col="2">
|
||||||
<Label class="fieldLabel" :text="'cookT' | L" />
|
<Label class="fieldLabel" :text="'cookT' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
ref="cookTime"
|
ref="cookTime"
|
||||||
:text="timeRequired('cookTime')"
|
:text="timeRequired('cookTime')"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && setTimeRequired(true, 'cookTime')"
|
@focus="!modalOpen && setTimeRequired(1, 'cookTime')"
|
||||||
@tap="setTimeRequired(false, 'cookTime')"
|
@tap="setTimeRequired(0, 'cookTime')"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<GridLayout columns="*, 8, *">
|
<RGridLayout :rtl="RTL" columns="*, 8, *">
|
||||||
<StackLayout class="inputField">
|
<StackLayout class="inputField">
|
||||||
<Label class="fieldLabel" :text="'yieldQ' | L" />
|
<Label class="fieldLabel" :text="'yieldQ' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
ref="yieldQuantity"
|
ref="yieldQuantity"
|
||||||
v-model="recipe.yieldQuantity"
|
v-model="recipe.yieldQuantity"
|
||||||
hint="1"
|
hint="1"
|
||||||
|
@ -104,22 +106,24 @@
|
||||||
<StackLayout class="inputField" col="2">
|
<StackLayout class="inputField" col="2">
|
||||||
<Label class="fieldLabel" :text="'yieldU' | L" />
|
<Label class="fieldLabel" :text="'yieldU' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
:text="`${recipe.yieldUnit}` | L"
|
:text="`${recipe.yieldUnit}` | L"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && showYieldUnits(true)"
|
@focus="!modalOpen && showYieldUnits(1)"
|
||||||
@tap="showYieldUnits(false)"
|
@tap="showYieldUnits(0)"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<GridLayout columns="*, 8, *">
|
<GridLayout columns="*, 8, *">
|
||||||
<StackLayout class="inputField">
|
<StackLayout class="inputField" :col="RTL ? 2 : 0">
|
||||||
<Label class="fieldLabel" :text="'Difficulty level' | L" />
|
<Label class="fieldLabel" :text="'Difficulty level' | L" />
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
ref="difficultyLevel"
|
ref="difficultyLevel"
|
||||||
:text="`${recipe.difficulty}` | L"
|
:text="`${recipe.difficulty}` | L"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && showDifficultyLevel(true)"
|
@focus="!modalOpen && showDifficultyLevel(1)"
|
||||||
@tap="showDifficultyLevel(false)"
|
@tap="showDifficultyLevel(0)"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
|
@ -128,7 +132,8 @@
|
||||||
:text="getTitleCount('ings', 'ingredients')"
|
:text="getTitleCount('ings', 'ingredients')"
|
||||||
class="sectionTitle"
|
class="sectionTitle"
|
||||||
/>
|
/>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="auto,8,auto,8,*,auto"
|
columns="auto,8,auto,8,*,auto"
|
||||||
v-for="(ingredient, index) in recipe.ingredients"
|
v-for="(ingredient, index) in recipe.ingredients"
|
||||||
:key="'ing' + index"
|
:key="'ing' + index"
|
||||||
|
@ -147,8 +152,8 @@
|
||||||
col="2"
|
col="2"
|
||||||
:text="`${recipe.ingredients[index].unit}` | L"
|
:text="`${recipe.ingredients[index].unit}` | L"
|
||||||
editable="false"
|
editable="false"
|
||||||
@focus="!modalOpen && showUnits($event, true, index)"
|
@focus="!modalOpen && showUnits($event, 1, index)"
|
||||||
@tap="showUnits($event, false, index)"
|
@tap="showUnits($event, 0, index)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -163,13 +168,14 @@
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="5"
|
col="5"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeIngredient(index)"
|
@tap="removeIngredient(index)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<Button
|
<Button
|
||||||
class="text big"
|
class="text big hal"
|
||||||
|
:class="{ r: RTL }"
|
||||||
:text="'aIngBtn' | L"
|
:text="'aIngBtn' | L"
|
||||||
@tap="addIngredient()"
|
@tap="addIngredient()"
|
||||||
/>
|
/>
|
||||||
|
@ -178,7 +184,8 @@
|
||||||
:text="getTitleCount('inss', 'instructions')"
|
:text="getTitleCount('inss', 'instructions')"
|
||||||
class="sectionTitle"
|
class="sectionTitle"
|
||||||
/>
|
/>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="*,auto"
|
columns="*,auto"
|
||||||
v-for="(instruction, index) in recipe.instructions"
|
v-for="(instruction, index) in recipe.instructions"
|
||||||
:key="'ins' + index"
|
:key="'ins' + index"
|
||||||
|
@ -190,13 +197,14 @@
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="1"
|
col="1"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeInstruction(index)"
|
@tap="removeInstruction(index)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<Button
|
<Button
|
||||||
class="text big"
|
class="text big hal"
|
||||||
|
:class="{ r: RTL }"
|
||||||
:text="'aStpBtn' | L"
|
:text="'aStpBtn' | L"
|
||||||
@tap="addInstruction"
|
@tap="addInstruction"
|
||||||
/>
|
/>
|
||||||
|
@ -205,32 +213,36 @@
|
||||||
:text="getTitleCount('cmbs', 'combinations')"
|
:text="getTitleCount('cmbs', 'combinations')"
|
||||||
class="sectionTitle"
|
class="sectionTitle"
|
||||||
/>
|
/>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="*,auto"
|
columns="*,auto"
|
||||||
v-for="(combination, index) in recipe.combinations"
|
v-for="(combination, index) in recipe.combinations"
|
||||||
:key="'cmbs' + index"
|
:key="'cmbs' + index"
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
class="combField"
|
class="combField"
|
||||||
:text="getCombinationTitle(combination)"
|
:text="getCombinationTitle(combination)"
|
||||||
editable="false"
|
editable="false"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="1"
|
col="1"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeCombination(combination)"
|
@tap="removeCombination(combination)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<Button
|
<Button
|
||||||
class="text big"
|
class="text big hal"
|
||||||
|
:class="{ r: RTL }"
|
||||||
:text="'addCmbBtn' | L"
|
:text="'addCmbBtn' | L"
|
||||||
@tap="showCombinations"
|
@tap="showCombinations"
|
||||||
/>
|
/>
|
||||||
<!-- NOTES -->
|
<!-- NOTES -->
|
||||||
<Label :text="getTitleCount('nos', 'notes')" class="sectionTitle" />
|
<Label :text="getTitleCount('nos', 'notes')" class="sectionTitle" />
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
columns="*,auto"
|
:rtl="RTL"
|
||||||
|
columns="*, auto"
|
||||||
v-for="(note, index) in recipe.notes"
|
v-for="(note, index) in recipe.notes"
|
||||||
:key="'nos' + index"
|
:key="'nos' + index"
|
||||||
>
|
>
|
||||||
|
@ -241,52 +253,53 @@
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="1"
|
col="1"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeNote(index)"
|
@tap="removeNote(index)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<Button class="text big" :text="'aNoBtn' | L" @tap="addNote" />
|
<Button
|
||||||
|
class="text big hal"
|
||||||
|
:class="{ r: RTL }"
|
||||||
|
:text="'aNoBtn' | L"
|
||||||
|
@tap="addNote"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL && hasChanges"
|
||||||
row="1"
|
row="1"
|
||||||
@loaded="onAppBarLoad"
|
@loaded="abLoad"
|
||||||
:hidden="showUndo"
|
:hidden="showUndo"
|
||||||
class="appbar"
|
class="appbar"
|
||||||
:colSpan="hasChanges ? 2 : 1"
|
:col="RTL ? (hasChanges ? 0 : 2) : 0"
|
||||||
|
:colSpan="hasChanges ? 3 : 1"
|
||||||
columns="auto, *, auto"
|
columns="auto, *, auto"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="navigateBack" />
|
<Button
|
||||||
|
class="ico"
|
||||||
|
:class="{ f: RTL }"
|
||||||
|
:text="icon.back"
|
||||||
|
@tap="navigateBack(0)"
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-if="hasChanges && !saving"
|
v-if="hasChanges && !saving"
|
||||||
class="ico fab"
|
class="ico fab"
|
||||||
:text="icon.save"
|
:text="icon.save"
|
||||||
col="2"
|
col="2"
|
||||||
@tap="saveOperation()"
|
@tap="saveOperation"
|
||||||
/>
|
/>
|
||||||
<ActivityIndicator col="2" v-if="saving" :busy="saving" />
|
<ActivityIndicator col="2" v-if="saving" :busy="saving" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<SnackBar
|
<SnackBar
|
||||||
:hidden="!showUndo"
|
:hidden="!showUndo"
|
||||||
colSpan="2"
|
colSpan="2"
|
||||||
:count="countdown"
|
:count="countdown"
|
||||||
:msg="snackMsg"
|
:msg="snackMsg"
|
||||||
:undo="undoDel"
|
:undo="undoDel"
|
||||||
:action="hideUndoBar"
|
:action="hideBar"
|
||||||
|
:onload="sbLoad"
|
||||||
/>
|
/>
|
||||||
<!-- <GridLayout
|
|
||||||
row="1"
|
|
||||||
class="appbar snackBar"
|
|
||||||
:hidden="!showUndo"
|
|
||||||
colSpan="2"
|
|
||||||
columns="auto, *, auto"
|
|
||||||
@swipe="hideUndoBar"
|
|
||||||
>
|
|
||||||
<Button :text="countdown" class="ico countdown tb" />
|
|
||||||
<Label class="title" col="1" :text="snackMsg | L" />
|
|
||||||
<Button class="ico fab" :text="icon.undo" @tap="undoDel" col="3" />
|
|
||||||
</GridLayout> -->
|
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -294,7 +307,6 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
AndroidApplication,
|
AndroidApplication,
|
||||||
ApplicationSettings,
|
|
||||||
File,
|
File,
|
||||||
getFileAccess,
|
getFileAccess,
|
||||||
ImageSource,
|
ImageSource,
|
||||||
|
@ -304,10 +316,15 @@ import {
|
||||||
Utils,
|
Utils,
|
||||||
Observable,
|
Observable,
|
||||||
CoreTypes,
|
CoreTypes,
|
||||||
|
Frame,
|
||||||
|
Application,
|
||||||
|
GridLayout,
|
||||||
} from "@nativescript/core";
|
} from "@nativescript/core";
|
||||||
|
import { getString, setString } from "@nativescript/core/application-settings";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
import { ImageCropper } from "nativescript-imagecropper";
|
import { ImageCropper } from "nativescript-imagecropper";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
|
import EnRecipes from "./EnRecipes.vue";
|
||||||
import Action from "./modals/Action";
|
import Action from "./modals/Action";
|
||||||
import ActionWithSearch from "./modals/ActionWithSearch";
|
import ActionWithSearch from "./modals/ActionWithSearch";
|
||||||
import Confirm from "./modals/Confirm";
|
import Confirm from "./modals/Confirm";
|
||||||
|
@ -315,22 +332,17 @@ import Prompt from "./modals/Prompt";
|
||||||
import TimePickerHM from "./modals/TimePickerHM";
|
import TimePickerHM from "./modals/TimePickerHM";
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
import SnackBar from "./sub/SnackBar";
|
import SnackBar from "./sub/SnackBar";
|
||||||
let undoTimer;
|
let barTimer;
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SnackBar,
|
SnackBar,
|
||||||
},
|
},
|
||||||
props: [
|
props: ["recipeID", "filterFavourites", "filterTrylater", "dupRecipe"],
|
||||||
"recipeID",
|
|
||||||
"filterFavourites",
|
|
||||||
"filterTrylater",
|
|
||||||
"navigationFromView",
|
|
||||||
],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: "newRec",
|
title: "newRec",
|
||||||
recipe: {
|
recipe: {
|
||||||
id: this.recipeID ? this.recipeID : this.getRandomID(),
|
id: this.recipeID || utils.getRandomID(0),
|
||||||
image: null,
|
image: null,
|
||||||
title: null,
|
title: null,
|
||||||
cuisine: "Undefined",
|
cuisine: "Undefined",
|
||||||
|
@ -354,18 +366,18 @@ export default {
|
||||||
},
|
},
|
||||||
tempRecipe: {},
|
tempRecipe: {},
|
||||||
tags: undefined,
|
tags: undefined,
|
||||||
modalOpen: false,
|
modalOpen: 0,
|
||||||
// newRecipeID: null,
|
saving: 0,
|
||||||
saving: false,
|
|
||||||
cacheImagePath: null,
|
cacheImagePath: null,
|
||||||
unSyncCombinations: [],
|
unSyncCombinations: [],
|
||||||
difficultyLevels: ["Easy", "Moderate", "Challenging"],
|
difficultyLevels: ["Easy", "Moderate", "Challenging"],
|
||||||
appbar: null,
|
appbar: null,
|
||||||
|
snackbar: null,
|
||||||
scrollPos: 1,
|
scrollPos: 1,
|
||||||
countdown: 5,
|
countdown: 5,
|
||||||
snackMsg: null,
|
snackMsg: null,
|
||||||
showUndo: false,
|
showUndo: 0,
|
||||||
undo: false,
|
undo: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -376,37 +388,42 @@ export default {
|
||||||
"recipes",
|
"recipes",
|
||||||
"cuisines",
|
"cuisines",
|
||||||
"categories",
|
"categories",
|
||||||
"currentComponent",
|
"selCuisine",
|
||||||
"selectedCuisine",
|
"selCategory",
|
||||||
"selectedCategory",
|
"selTag",
|
||||||
"selectedTag",
|
"theme",
|
||||||
"appTheme",
|
"RTL",
|
||||||
]),
|
]),
|
||||||
screenWidth() {
|
screenWidth() {
|
||||||
return Screen.mainScreen.widthDIPs;
|
return Screen.mainScreen.widthDIPs;
|
||||||
},
|
},
|
||||||
hasChanges() {
|
hasChanges() {
|
||||||
return JSON.stringify(this.recipe) !== JSON.stringify(this.tempRecipe);
|
return JSON.stringify(this.recipe) != JSON.stringify(this.tempRecipe);
|
||||||
|
},
|
||||||
|
hasBackStack() {
|
||||||
|
return Frame.topmost().backStack.length;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions([
|
||||||
"setComponent",
|
|
||||||
"addRecipeAction",
|
"addRecipeAction",
|
||||||
"addListItemAction",
|
"addListItemAction",
|
||||||
"unSyncCombinationsAction",
|
"unSyncCombinationsAction",
|
||||||
]),
|
]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
this.hijackBackEvent();
|
this.hijackBackEvent();
|
||||||
},
|
},
|
||||||
onPageUnload() {
|
onPageUnload() {
|
||||||
this.releaseBackEvent();
|
this.releaseBackEvent();
|
||||||
},
|
},
|
||||||
onAppBarLoad({ object }) {
|
abLoad(args) {
|
||||||
this.appbar = object;
|
this.appbar = args.object;
|
||||||
},
|
},
|
||||||
onScroll(args) {
|
sbLoad({ object }) {
|
||||||
|
this.snackbar = object;
|
||||||
|
},
|
||||||
|
svLoad(args) {
|
||||||
let scrollUp;
|
let scrollUp;
|
||||||
let y = args.scrollY;
|
let y = args.scrollY;
|
||||||
if (y) {
|
if (y) {
|
||||||
|
@ -416,14 +433,14 @@ export default {
|
||||||
if (!scrollUp && ab == 0) {
|
if (!scrollUp && ab == 0) {
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 64 },
|
translate: { x: 0, y: 64 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
} else if (scrollUp && ab == 64) {
|
} else if (scrollUp && ab == 64) {
|
||||||
Utils.ad.dismissSoftInput();
|
Utils.ad.dismissSoftInput();
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 0 },
|
translate: { x: 0, y: 0 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -432,16 +449,16 @@ export default {
|
||||||
|
|
||||||
// PHOTO HANDLERS
|
// PHOTO HANDLERS
|
||||||
imageHandler() {
|
imageHandler() {
|
||||||
this.clearEmptyFields(true);
|
this.clearEmptyFields(1);
|
||||||
if (this.recipe.image) {
|
if (this.recipe.image) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "recPic",
|
title: "recPic",
|
||||||
list: ["aap", "rp"],
|
list: ["aap", "rp"],
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "aap":
|
case "aap":
|
||||||
this.imagePicker();
|
this.imagePicker();
|
||||||
|
@ -454,12 +471,12 @@ export default {
|
||||||
} else this.imagePicker();
|
} else this.imagePicker();
|
||||||
},
|
},
|
||||||
imagePicker() {
|
imagePicker() {
|
||||||
let aT = this.appTheme;
|
let aT = this.theme;
|
||||||
utils.getRecipePhoto().then((uri) => {
|
utils.getRecipePhoto().then((uri) => {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
this.cacheImagePath = path.join(
|
this.cacheImagePath = path.join(
|
||||||
knownFolders.temp().path,
|
knownFolders.temp().path,
|
||||||
`${this.getRandomID()}.jpg`
|
`${utils.getRandomID(0)}.jpg`
|
||||||
);
|
);
|
||||||
utils.copyPhotoToCache(uri, this.cacheImagePath).then((imgPath) => {
|
utils.copyPhotoToCache(uri, this.cacheImagePath).then((imgPath) => {
|
||||||
if (imgPath) {
|
if (imgPath) {
|
||||||
|
@ -495,15 +512,27 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
createDupImage() {
|
||||||
|
if (this.recipe.image) {
|
||||||
|
let cachePath = path.join(
|
||||||
|
knownFolders.temp().path,
|
||||||
|
`${utils.getRandomID(0)}.jpg`
|
||||||
|
);
|
||||||
|
utils.copyPhotoToCache(this.recipe.image, cachePath).then((imgPath) => {
|
||||||
|
if (imgPath) this.recipe.image = imgPath;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// DATA LIST
|
// DATA LIST
|
||||||
showCuisine(focus) {
|
showCuisine(focus) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "cui",
|
title: "cui",
|
||||||
list: this.cuisines,
|
list: this.cuisines,
|
||||||
action: "aNBtn",
|
action: "aNBtn",
|
||||||
|
selected: this.recipe.cuisine,
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action == "aNBtn") {
|
if (action == "aNBtn") {
|
||||||
|
@ -513,21 +542,21 @@ export default {
|
||||||
action: "aBtn",
|
action: "aBtn",
|
||||||
},
|
},
|
||||||
}).then((item) => {
|
}).then((item) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (item.length) {
|
if (item.length) {
|
||||||
this.recipe.cuisine = item;
|
this.recipe.cuisine = item;
|
||||||
this.addListItemAction({
|
this.addListItemAction({
|
||||||
item,
|
item,
|
||||||
listName: "cuisines",
|
listName: "cuisines",
|
||||||
});
|
});
|
||||||
if (focus) this.autoFocusField("category", false);
|
if (focus) this.autoFocusField("category", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action) {
|
if (action) {
|
||||||
this.recipe.cuisine = action;
|
this.recipe.cuisine = action;
|
||||||
if (focus) this.autoFocusField("category", false);
|
if (focus) this.autoFocusField("category", 0);
|
||||||
} else
|
} else
|
||||||
this.cuisines.includes(this.recipe.cuisine)
|
this.cuisines.includes(this.recipe.cuisine)
|
||||||
? mull
|
? mull
|
||||||
|
@ -536,12 +565,13 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showCategories(focus) {
|
showCategories(focus) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "cat",
|
title: "cat",
|
||||||
list: this.categories,
|
list: this.categories,
|
||||||
action: "aNBtn",
|
action: "aNBtn",
|
||||||
|
selected: this.recipe.category,
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action == "aNBtn") {
|
if (action == "aNBtn") {
|
||||||
|
@ -551,21 +581,21 @@ export default {
|
||||||
action: "aBtn",
|
action: "aBtn",
|
||||||
},
|
},
|
||||||
}).then((item) => {
|
}).then((item) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (item.length) {
|
if (item.length) {
|
||||||
this.recipe.category = item;
|
this.recipe.category = item;
|
||||||
this.addListItemAction({
|
this.addListItemAction({
|
||||||
item,
|
item,
|
||||||
listName: "categories",
|
listName: "categories",
|
||||||
});
|
});
|
||||||
if (focus) this.autoFocusField("tags", true);
|
if (focus) this.autoFocusField("tags", 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action) {
|
if (action) {
|
||||||
this.recipe.category = action;
|
this.recipe.category = action;
|
||||||
if (focus) this.autoFocusField("tags", true);
|
if (focus) this.autoFocusField("tags", 1);
|
||||||
} else
|
} else
|
||||||
this.categories.includes(this.recipe.category)
|
this.categories.includes(this.recipe.category)
|
||||||
? mull
|
? mull
|
||||||
|
@ -574,12 +604,13 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showYieldUnits(focus) {
|
showYieldUnits(focus) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "yieldU",
|
title: "yieldU",
|
||||||
list: this.yieldUnits,
|
list: this.yieldUnits,
|
||||||
action: "aNBtn",
|
action: "aNBtn",
|
||||||
|
selected: this.recipe.yieldUnit,
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action == "aNBtn") {
|
if (action == "aNBtn") {
|
||||||
|
@ -589,21 +620,21 @@ export default {
|
||||||
action: "aBtn",
|
action: "aBtn",
|
||||||
},
|
},
|
||||||
}).then((item) => {
|
}).then((item) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (item.length) {
|
if (item.length) {
|
||||||
this.recipe.yieldUnit = item;
|
this.recipe.yieldUnit = item;
|
||||||
this.addListItemAction({
|
this.addListItemAction({
|
||||||
item,
|
item,
|
||||||
listName: "yieldUnits",
|
listName: "yieldUnits",
|
||||||
});
|
});
|
||||||
if (focus) this.autoFocusField("difficultyLevel", false);
|
if (focus) this.autoFocusField("difficultyLevel", 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action) {
|
if (action) {
|
||||||
this.recipe.yieldUnit = action;
|
this.recipe.yieldUnit = action;
|
||||||
if (focus) this.autoFocusField("difficultyLevel", false);
|
if (focus) this.autoFocusField("difficultyLevel", 0);
|
||||||
} else
|
} else
|
||||||
this.yieldUnits.includes(this.recipe.yieldUnit)
|
this.yieldUnits.includes(this.recipe.yieldUnit)
|
||||||
? mull
|
? mull
|
||||||
|
@ -612,14 +643,15 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showDifficultyLevel(focus) {
|
showDifficultyLevel(focus) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "Difficulty level",
|
title: "Difficulty level",
|
||||||
list: this.difficultyLevels,
|
list: this.difficultyLevels,
|
||||||
|
selected: this.recipe.difficulty,
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action) {
|
if (action) {
|
||||||
this.recipe.difficulty = action;
|
this.recipe.difficulty = action;
|
||||||
if (focus) this.addIngredient();
|
if (focus) this.addIngredient();
|
||||||
|
@ -630,12 +662,13 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showUnits(e, focus, index) {
|
showUnits(e, focus, index) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "Unit",
|
title: "Unit",
|
||||||
list: this.units,
|
list: this.units,
|
||||||
action: "aNBtn",
|
action: "aNBtn",
|
||||||
|
selected: this.recipe.ingredients[index].unit,
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (action == "aNBtn") {
|
if (action == "aNBtn") {
|
||||||
|
@ -645,7 +678,7 @@ export default {
|
||||||
action: "aBtn",
|
action: "aBtn",
|
||||||
},
|
},
|
||||||
}).then((item) => {
|
}).then((item) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (item.length) {
|
if (item.length) {
|
||||||
this.recipe.ingredients[index].unit = item;
|
this.recipe.ingredients[index].unit = item;
|
||||||
this.addListItemAction({
|
this.addListItemAction({
|
||||||
|
@ -657,7 +690,7 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action) {
|
if (action) {
|
||||||
this.recipe.ingredients[index].unit = action;
|
this.recipe.ingredients[index].unit = action;
|
||||||
if (focus && this.recipe.ingredients.length - 1 === index)
|
if (focus && this.recipe.ingredients.length - 1 === index)
|
||||||
|
@ -668,7 +701,7 @@ export default {
|
||||||
},
|
},
|
||||||
showCombinations() {
|
showCombinations() {
|
||||||
Utils.ad.dismissSoftInput();
|
Utils.ad.dismissSoftInput();
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
let existingCombinations = [...this.recipe.combinations, this.recipe.id];
|
let existingCombinations = [...this.recipe.combinations, this.recipe.id];
|
||||||
let filteredRecipes = this.recipes.filter(
|
let filteredRecipes = this.recipes.filter(
|
||||||
(e) => !existingCombinations.includes(e.id)
|
(e) => !existingCombinations.includes(e.id)
|
||||||
|
@ -679,7 +712,7 @@ export default {
|
||||||
recipes: filteredRecipes,
|
recipes: filteredRecipes,
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (res) this.recipe.combinations.push(res);
|
if (res) this.recipe.combinations.push(res);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -697,7 +730,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
removeIngredient(index) {
|
removeIngredient(index) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
if (this.recipe.ingredients[index].item.length) {
|
if (this.recipe.ingredients[index].item.length) {
|
||||||
let item = this.recipe.ingredients[index];
|
let item = this.recipe.ingredients[index];
|
||||||
this.recipe.ingredients.splice(index, 1);
|
this.recipe.ingredients.splice(index, 1);
|
||||||
|
@ -707,7 +740,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.recipe.ingredients.splice(index, 1);
|
this.recipe.ingredients.splice(index, 1);
|
||||||
}
|
}
|
||||||
setTimeout(() => (this.modalOpen = false), 200);
|
setTimeout(() => (this.modalOpen = 0), 200);
|
||||||
},
|
},
|
||||||
addInstruction() {
|
addInstruction() {
|
||||||
this.recipe.instructions.push("");
|
this.recipe.instructions.push("");
|
||||||
|
@ -759,17 +792,17 @@ export default {
|
||||||
clearEmpty("notes");
|
clearEmpty("notes");
|
||||||
},
|
},
|
||||||
saveOperation() {
|
saveOperation() {
|
||||||
this.saving = this.modalOpen = true;
|
this.saving = this.modalOpen = 1;
|
||||||
this.clearEmptyFields();
|
this.clearEmptyFields();
|
||||||
this.recipe.lastModified = new Date().getTime();
|
this.recipe.lastModified = new Date().getTime();
|
||||||
ApplicationSettings.setString("previousCuisine", this.recipe.cuisine);
|
setString("previousCuisine", this.recipe.cuisine);
|
||||||
ApplicationSettings.setString("previousCategory", this.recipe.category);
|
setString("previousCategory", this.recipe.category);
|
||||||
ApplicationSettings.setString("previousYieldUnit", this.recipe.yieldUnit);
|
setString("previousYieldUnit", this.recipe.yieldUnit);
|
||||||
if (this.cacheImagePath) {
|
if (this.cacheImagePath) {
|
||||||
let recipeImage = path.join(
|
let recipeImage = path.join(
|
||||||
knownFolders.documents().getFolder("EnRecipes").getFolder("Images")
|
knownFolders.documents().getFolder("EnRecipes").getFolder("Images")
|
||||||
.path,
|
.path,
|
||||||
`${this.getRandomID()}.jpg`
|
`${utils.getRandomID(0)}.jpg`
|
||||||
);
|
);
|
||||||
let binarySource = File.fromPath(this.cacheImagePath).readSync();
|
let binarySource = File.fromPath(this.cacheImagePath).readSync();
|
||||||
File.fromPath(recipeImage).writeSync(binarySource);
|
File.fromPath(recipeImage).writeSync(binarySource);
|
||||||
|
@ -794,57 +827,49 @@ export default {
|
||||||
},
|
},
|
||||||
saveRecipe() {
|
saveRecipe() {
|
||||||
this.addRecipeAction(this.recipe);
|
this.addRecipeAction(this.recipe);
|
||||||
setTimeout(() => (this.saving = false), 100);
|
this.saving = 0;
|
||||||
this.$navigateBack();
|
this.dupRecipe
|
||||||
|
? this.$navigateTo(EnRecipes, {
|
||||||
|
clearHistory: true,
|
||||||
|
animated: false,
|
||||||
|
})
|
||||||
|
: this.goBackAction(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
// UNDO OPERATION
|
// UNDO OPERATION
|
||||||
showUndoBar(message) {
|
showUndoBar(message) {
|
||||||
|
clearInterval(barTimer);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.showUndo = true;
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
this.appbar.translateY = 0;
|
this.showUndo = 1;
|
||||||
this.snackMsg = message;
|
this.snackMsg = message;
|
||||||
this.countdown = 5;
|
this.countdown = 5;
|
||||||
|
this.animateBar(this.snackbar, 1).then(() => {
|
||||||
let a = 5;
|
let a = 5;
|
||||||
clearTimeout(undoTimer);
|
barTimer = setInterval(() => {
|
||||||
undoTimer = setInterval(() => {
|
|
||||||
if (this.undo) {
|
if (this.undo) {
|
||||||
this.showUndo = this.undo = false;
|
this.hideBar();
|
||||||
clearTimeout(undoTimer);
|
resolve(1);
|
||||||
resolve(true);
|
|
||||||
}
|
}
|
||||||
this.countdown = Math.round((a -= 0.1));
|
this.countdown = Math.round((a -= 0.1));
|
||||||
if (this.countdown < 1) {
|
if (this.countdown < 1) {
|
||||||
this.showUndo = false;
|
this.hideBar();
|
||||||
clearTimeout(undoTimer);
|
reject(1);
|
||||||
reject(true);
|
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
},
|
|
||||||
hideUndoBar({ object }) {
|
|
||||||
object
|
|
||||||
.animate({
|
|
||||||
opacity: 0,
|
|
||||||
translate: { x: 0, y: 64 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.showUndo = false;
|
|
||||||
this.appbar.translateY = 64;
|
|
||||||
this.appbar.animate({
|
|
||||||
translate: { x: 0, y: 0 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
});
|
||||||
object.opacity = 1;
|
});
|
||||||
object.translateY = 0;
|
},
|
||||||
clearTimeout(undoTimer);
|
hideBar() {
|
||||||
|
clearInterval(barTimer);
|
||||||
|
this.animateBar(this.snackbar, 0).then(() => {
|
||||||
|
this.showUndo = this.undo = 0;
|
||||||
|
this.animateBar(this.appbar, 1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
undoDel() {
|
undoDel() {
|
||||||
this.undo = true;
|
this.undo = 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
|
@ -891,29 +916,30 @@ export default {
|
||||||
},
|
},
|
||||||
focusField(args, type) {
|
focusField(args, type) {
|
||||||
if (type) this.setInputTypeText(args, type);
|
if (type) this.setInputTypeText(args, type);
|
||||||
|
else this.setGravity(args);
|
||||||
if (!args.object.text) {
|
if (!args.object.text) {
|
||||||
args.object.focus();
|
args.object.focus();
|
||||||
setTimeout(() => Utils.ad.showSoftInput(args.object.android), 100);
|
setTimeout(() => Utils.ad.showSoftInput(args.object.android), 100);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setInputTypeText(args, type) {
|
setInputTypeText({ object }, type) {
|
||||||
let field = args.object;
|
this.setGravity(object);
|
||||||
let common =
|
let common =
|
||||||
android.text.InputType.TYPE_CLASS_TEXT |
|
android.text.InputType.TYPE_CLASS_TEXT |
|
||||||
android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
|
android.text.InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "words":
|
case "words":
|
||||||
field.android.setInputType(
|
object.android.setInputType(
|
||||||
android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS | common
|
android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS | common
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "sentence":
|
case "sentence":
|
||||||
field.android.setInputType(
|
object.android.setInputType(
|
||||||
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | common
|
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | common
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "multiLine":
|
case "multiLine":
|
||||||
field.android.setInputType(
|
object.android.setInputType(
|
||||||
android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE |
|
android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE |
|
||||||
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
|
android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
|
||||||
common
|
common
|
||||||
|
@ -921,37 +947,28 @@ export default {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getRandomID() {
|
|
||||||
let res = "";
|
|
||||||
let chars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
res += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
setTimeRequired(focus, time) {
|
setTimeRequired(focus, time) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
let t = this.recipe[time].split(":");
|
let t = this.recipe[time].split(":");
|
||||||
let hr = t[0];
|
let hr = t[0];
|
||||||
let min = t[1];
|
let min = t[1];
|
||||||
this.$showModal(TimePickerHM, {
|
this.$showModal(TimePickerHM, {
|
||||||
props: {
|
props: {
|
||||||
title: `${time == "prepTime" ? "prepT" : "cookT"}`,
|
title: `${time == "prepTime" ? "prepT" : "cookT"}`,
|
||||||
action: "SET",
|
|
||||||
selectedHr: hr,
|
selectedHr: hr,
|
||||||
selectedMin: min,
|
selectedMin: min,
|
||||||
},
|
},
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (result) {
|
if (result) {
|
||||||
this.recipe[time] = result;
|
this.recipe[time] = result;
|
||||||
if (focus) {
|
if (focus) {
|
||||||
switch (time) {
|
switch (time) {
|
||||||
case "prepTime":
|
case "prepTime":
|
||||||
this.autoFocusField("cookTime", false);
|
this.autoFocusField("cookTime", 0);
|
||||||
break;
|
break;
|
||||||
case "cookTime":
|
case "cookTime":
|
||||||
this.autoFocusField("yieldQuantity", true);
|
this.autoFocusField("yieldQuantity", 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,12 +997,22 @@ export default {
|
||||||
backEvent(args) {
|
backEvent(args) {
|
||||||
if (!this.modalOpen) {
|
if (!this.modalOpen) {
|
||||||
args.cancel = true;
|
args.cancel = true;
|
||||||
this.navigateBack();
|
this.navigateBack(1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
navigateBack() {
|
goBackAction(exit) {
|
||||||
|
this.hasBackStack || this.recipeID
|
||||||
|
? this.$navigateBack()
|
||||||
|
: exit
|
||||||
|
? Application.android.foregroundActivity.finish()
|
||||||
|
: this.$navigateTo(EnRecipes, {
|
||||||
|
clearHistory: true,
|
||||||
|
animated: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
navigateBack(hwb) {
|
||||||
if (this.hasChanges) {
|
if (this.hasChanges) {
|
||||||
this.modalOpen = true;
|
this.modalOpen = 1;
|
||||||
this.$showModal(Confirm, {
|
this.$showModal(Confirm, {
|
||||||
props: {
|
props: {
|
||||||
title: "unsaved",
|
title: "unsaved",
|
||||||
|
@ -994,46 +1021,47 @@ export default {
|
||||||
okButtonText: "kEdit",
|
okButtonText: "kEdit",
|
||||||
},
|
},
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
this.modalOpen = false;
|
this.modalOpen = 0;
|
||||||
if (action != null && !action) this.$navigateBack();
|
if (action != null && !action) {
|
||||||
|
this.goBackAction(1);
|
||||||
|
knownFolders.temp().clear();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else this.$navigateBack();
|
} else this.goBackAction(hwb);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
setTimeout(() => {
|
this.title = this.recipeID || this.dupRecipe ? "editRec" : "newRec";
|
||||||
this.setComponent("EditRecipe");
|
|
||||||
}, 500);
|
|
||||||
this.title = this.recipeID ? "editRec" : "newRec";
|
|
||||||
if (this.recipeID) {
|
if (this.recipeID) {
|
||||||
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0];
|
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0];
|
||||||
Object.assign(this.recipe, JSON.parse(JSON.stringify(recipe)));
|
Object.assign(this.recipe, JSON.parse(JSON.stringify(recipe)));
|
||||||
Object.assign(this.tempRecipe, JSON.parse(JSON.stringify(this.recipe)));
|
Object.assign(this.tempRecipe, JSON.parse(JSON.stringify(this.recipe)));
|
||||||
if (this.recipe.tags.length) this.joinTags();
|
if (this.recipe.tags.length) this.joinTags();
|
||||||
|
} else if (this.dupRecipe) {
|
||||||
|
this.recipe = Object.assign({}, this.dupRecipe);
|
||||||
|
this.recipe.tried = 1;
|
||||||
|
this.recipe.lastTried = 0;
|
||||||
|
this.createDupImage();
|
||||||
} else {
|
} else {
|
||||||
this.recipe.cuisine = this.selectedCuisine
|
this.recipe.cuisine = this.selCuisine
|
||||||
? /all/.test(this.selectedCuisine)
|
? /all/.test(this.selCuisine)
|
||||||
? "Undefined"
|
? "Undefined"
|
||||||
: this.selectedCuisine
|
: this.selCuisine
|
||||||
: ApplicationSettings.getString("previousCuisine", "Undefined");
|
: getString("previousCuisine", "Undefined");
|
||||||
this.recipe.category = this.selectedCategory
|
this.recipe.category = this.selCategory
|
||||||
? /all/.test(this.selectedCategory)
|
? /all/.test(this.selCategory)
|
||||||
? "Undefined"
|
? "Undefined"
|
||||||
: this.selectedCategory
|
: this.selCategory
|
||||||
: ApplicationSettings.getString("previousCategory", "Undefined");
|
: getString("previousCategory", "Undefined");
|
||||||
if (this.selectedTag && !/all/.test(this.selectedTag)) {
|
if (this.selTag && !/all/.test(this.selTag)) {
|
||||||
this.tags = this.selectedTag;
|
this.tags = this.selTag;
|
||||||
this.splitTags();
|
this.splitTags();
|
||||||
}
|
}
|
||||||
this.recipe.yieldUnit = ApplicationSettings.getString(
|
this.recipe.yieldUnit = getString("previousYieldUnit", "Serving");
|
||||||
"previousYieldUnit",
|
if (this.filterFavourites) this.recipe.favorite = 1;
|
||||||
"Serving"
|
if (this.filterTrylater) this.recipe.tried = 0;
|
||||||
);
|
|
||||||
if (this.filterFavourites) this.recipe.favorite = true;
|
|
||||||
if (this.filterTrylater) this.recipe.tried = false;
|
|
||||||
this.recipe.created = new Date().getTime();
|
this.recipe.created = new Date().getTime();
|
||||||
Object.assign(this.tempRecipe, JSON.parse(JSON.stringify(this.recipe)));
|
this.tempRecipe = Object.assign({}, this.recipe);
|
||||||
// this.newRecipeID = this.getRandomID();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
<template>
|
|
||||||
<Page @loaded="onPageLoad">
|
|
||||||
<ActionBar flat="true">
|
|
||||||
<GridLayout rows="*" columns="auto, *, auto">
|
|
||||||
<Button class="ico left" :text="icon.back" @tap="$navigateBack()" />
|
|
||||||
<Label class="title tb" :text="'grocery' | L" col="1" />
|
|
||||||
<Button class="ico left" :text="icon.today" col="2" />
|
|
||||||
</GridLayout>
|
|
||||||
</ActionBar>
|
|
||||||
<GridLayout columns="" rows=""> </GridLayout>
|
|
||||||
</Page>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ApplicationSettings, Observable } from "@nativescript/core";
|
|
||||||
import { mapState, mapActions } from "vuex";
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
appTheme: "Light",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(["icon", "recipes", "mealPlans"]),
|
|
||||||
isLightMode() {
|
|
||||||
return this.appTheme === "Light";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapActions(["setComponent"]),
|
|
||||||
onPageLoad({ object }) {
|
|
||||||
object.bindingContext = new Observable();
|
|
||||||
this.setComponent("GroceryList");
|
|
||||||
},
|
|
||||||
// HELPERS
|
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
|
||||||
viewRecipe(recipeID) {
|
|
||||||
let recipe = this.recipes.filter((e) => e.id === recipeID)[0];
|
|
||||||
if (recipe) {
|
|
||||||
this.$navigateTo(ViewRecipe, {
|
|
||||||
props: {
|
|
||||||
filterTrylater: true,
|
|
||||||
recipeID,
|
|
||||||
},
|
|
||||||
backstackVisible: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// DATA HANDLERS
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
|
@ -1,112 +1,146 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="pgLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="*">
|
<GridLayout rows="*, auto, 72" columns="*">
|
||||||
<ScrollView
|
<ScrollView
|
||||||
@scroll="!edit && svLoad($event)"
|
@scroll="!edit && svScroll($event)"
|
||||||
rowSpan="2"
|
rowSpan="3"
|
||||||
scrollBarIndicatorVisible="false"
|
scrollBarIndicatorVisible="false"
|
||||||
>
|
>
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, auto, 8">
|
<RGridLayout :rtl="RTL" columns="*, auto, 12">
|
||||||
<Label class="pageTitle" :text="'planner' | L" />
|
<Label class="pageTitle a" :text="'planner' | L" />
|
||||||
<Button
|
<Button col="1" class="ico" :text="icon.cog" @tap="navigateTo" />
|
||||||
|
</RGridLayout>
|
||||||
|
<GridLayout class="monthSwitcher" columns="auto, *, auto">
|
||||||
|
<Button class="ico min" :text="icon.left" @tap="navigate(0)" />
|
||||||
|
<Label
|
||||||
|
class="month"
|
||||||
|
@touch="mYPicker"
|
||||||
col="1"
|
col="1"
|
||||||
class="ico"
|
:text="formattedDate(0)"
|
||||||
:text="icon.cog"
|
/>
|
||||||
@tap="$navigateTo(MPSettings)"
|
<Button
|
||||||
|
class="ico min"
|
||||||
|
col="2"
|
||||||
|
:text="icon.right"
|
||||||
|
@tap="navigate(1)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
class="calendar"
|
class="calendar"
|
||||||
columns="*, *, *, *, *, *, *"
|
columns="*, *, *, *, *, *, *"
|
||||||
rows="auto, auto, auto, auto, auto, auto, auto, auto"
|
:rows="calRows"
|
||||||
>
|
>
|
||||||
<Button class="ico navBtn" :text="icon.left" @tap="prevMonth" />
|
|
||||||
<Label
|
<Label
|
||||||
class="monthName"
|
class="dayName sub rtl"
|
||||||
@touch="touchMonthYearPicker"
|
:class="{ f: RTL }"
|
||||||
col="1"
|
|
||||||
colSpan="5"
|
|
||||||
:text="$options.filters.L(mNames[month]) + ' ' + year"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
class="ico navBtn"
|
|
||||||
col="6"
|
|
||||||
:text="icon.right"
|
|
||||||
@tap="nextMonth"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
class="dayName"
|
|
||||||
row="1"
|
|
||||||
:col="i"
|
:col="i"
|
||||||
v-for="(d, i) in getDayNames"
|
v-for="(d, i) in getDayNames"
|
||||||
:key="d"
|
:key="d + i"
|
||||||
:text="d | L"
|
:text="d | L"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
class="min day"
|
v-for="(cal, i) in getCal"
|
||||||
:class="{
|
:key="i"
|
||||||
tb: isToday(d),
|
|
||||||
activeDay: isActive(d),
|
|
||||||
hasPlans: hasPlans(d),
|
|
||||||
}"
|
|
||||||
:row="getrow(i)"
|
:row="getrow(i)"
|
||||||
:col="i % 7"
|
:col="i % 7"
|
||||||
v-for="(d, i) in getCal"
|
:class="dayClasses(cal)"
|
||||||
:key="i"
|
:text="cal.ld"
|
||||||
:text="d ? d : null"
|
@tap="setDate(cal)"
|
||||||
@tap="setToday(d)"
|
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<StackLayout class="dayPlan">
|
<StackLayout class="plans">
|
||||||
<StackLayout
|
<RLabel
|
||||||
v-for="(mealType, index) in mealTimesWithRecipes"
|
v-if="plannerView != 'd' && mealPlans.length"
|
||||||
:key="'mealType' + index"
|
class="date tb"
|
||||||
>
|
:text="formattedDate(1)"
|
||||||
<GridLayout columns="auto, auto">
|
textWrap="true"
|
||||||
|
/>
|
||||||
|
<StackLayout v-for="(meal, i) in mealTypes" :key="'meal' + i">
|
||||||
<Label
|
<Label
|
||||||
class="periodLabel tb"
|
:hidden="!getRecipes[meal]"
|
||||||
:class="mealType"
|
class="meal tb"
|
||||||
:text="mealType | L"
|
:class="[meal]"
|
||||||
|
:text="meal | L"
|
||||||
/>
|
/>
|
||||||
<Button
|
<RGridLayout
|
||||||
:visibility="edit ? 'visible' : 'hidden'"
|
:rtl="RTL"
|
||||||
col="1"
|
v-for="(plan, i) in getRecipes[meal]"
|
||||||
class="ico"
|
:key="meal + i"
|
||||||
:text="icon.plus"
|
class="plan"
|
||||||
@tap="addRecipe(mealType)"
|
columns="*, auto"
|
||||||
/>
|
|
||||||
</GridLayout>
|
|
||||||
<GridLayout
|
|
||||||
:columns="`*, ${edit ? 'auto' : 0}`"
|
|
||||||
v-for="(recipeID, index) in getRecipes[mealType]"
|
|
||||||
:key="mealType + index"
|
|
||||||
>
|
>
|
||||||
<Button
|
<RGridLayout
|
||||||
class="recipeTitle"
|
:rtl="RTL"
|
||||||
:text="getRecipeTitle(recipeID)"
|
class="rtl"
|
||||||
@tap="viewRecipe(recipeID)"
|
:hidden="!plan.recipeID"
|
||||||
|
:columns="noImg ? '*' : '48, *'"
|
||||||
|
@touch="touchRecipe"
|
||||||
|
@tap="viewRecipe(plan.id)"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
class="imgHolder"
|
||||||
|
verticalAlignment="middle"
|
||||||
|
v-if="!noImg && getRecipeImage(plan.recipeID)"
|
||||||
|
:src="getRecipeImage(plan.recipeID)"
|
||||||
|
stretch="none"
|
||||||
|
decodeWidth="48"
|
||||||
|
decodeHeight="48"
|
||||||
|
loadMode="async"
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
v-else-if="!noImg && !getRecipeImage(plan.recipeID)"
|
||||||
|
verticalAlignment="middle"
|
||||||
|
class="ico imgHolder"
|
||||||
|
@loaded="centerLabel($event, 17)"
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
fontSize="24"
|
||||||
|
:text="icon.img"
|
||||||
|
/>
|
||||||
|
<StackLayout class="planContent" col="1">
|
||||||
|
<RLabel
|
||||||
|
class="title"
|
||||||
|
:text="getRecipeTitle(plan.recipeID)"
|
||||||
|
/>
|
||||||
|
<RLabel class="attr" :text="getYield(plan.id)" />
|
||||||
|
</StackLayout>
|
||||||
|
</RGridLayout>
|
||||||
|
<Label
|
||||||
|
class="planContent tw"
|
||||||
|
@loaded="centerLabel($event, 16)"
|
||||||
|
:hidden="!plan.note"
|
||||||
|
:text="plan.note"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
:visibility="edit ? 'visible' : 'hidden'"
|
:hidden="!edit"
|
||||||
col="1"
|
col="1"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeRecipe(mealType, recipeID)"
|
@tap="removeRecipe(plan.id)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<GridLayout
|
<GridLayout rowSpan="2" rows="*, auto" v-if="!mealPlans.length">
|
||||||
row="1"
|
<StackLayout row="1" class="emptyState">
|
||||||
|
<RLabel class="title" :text="'ehwmp' | L" />
|
||||||
|
<RLabel :text="'plsCrt' | L" />
|
||||||
|
</StackLayout>
|
||||||
|
</GridLayout>
|
||||||
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
|
row="2"
|
||||||
@loaded="abLoad"
|
@loaded="abLoad"
|
||||||
class="appbar"
|
class="appbar"
|
||||||
:hidden="showUndo"
|
:hidden="showUndo"
|
||||||
columns="auto, *, auto, auto"
|
columns="auto, *, auto, auto, auto"
|
||||||
|
@swipe="stSwipe"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico rtl" :text="icon.back" @tap="navigateBack" />
|
||||||
<Button
|
<Button
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="icon.tod"
|
:text="icon.tod"
|
||||||
|
@ -115,13 +149,22 @@
|
||||||
col="2"
|
col="2"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
class="ico fab"
|
:hidden="!hasRecipes"
|
||||||
|
class="ico"
|
||||||
:text="edit ? icon.done : icon.edit"
|
:text="edit ? icon.done : icon.edit"
|
||||||
@tap="toggleEditMode"
|
@tap="toggleEditMode"
|
||||||
col="3"
|
col="3"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
<!-- <Button
|
||||||
|
class="ico"
|
||||||
|
:text="hasRecipes ? (edit ? icon.done : icon.edit) : icon.madd"
|
||||||
|
@tap="hasRecipes ? toggleEditMode() : randomMealPlan()"
|
||||||
|
col="3"
|
||||||
|
/> -->
|
||||||
|
<Button class="ico fab" :text="icon.plus" @tap="addMealPlan" col="4" />
|
||||||
|
</RGridLayout>
|
||||||
<SnackBar
|
<SnackBar
|
||||||
|
row="2"
|
||||||
:hidden="!showUndo"
|
:hidden="!showUndo"
|
||||||
:count="countdown"
|
:count="countdown"
|
||||||
:msg="snackMsg"
|
:msg="snackMsg"
|
||||||
|
@ -133,14 +176,21 @@
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { Observable, CoreTypes } from "@nativescript/core";
|
import { Frame, Observable, CoreTypes, Screen } from "@nativescript/core";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
import ViewRecipe from "./ViewRecipe";
|
import ViewRecipe from "./ViewRecipe.vue";
|
||||||
import MPSettings from "./settings/MPSettings";
|
import EditRecipe from "./EditRecipe.vue";
|
||||||
import ActionWithSearch from "./modals/ActionWithSearch";
|
import EnRecipes from "./EnRecipes.vue";
|
||||||
import MonthYearPicker from "./modals/MonthYearPicker";
|
import MPSettings from "./settings/MPSettings.vue";
|
||||||
import SnackBar from "./sub/SnackBar";
|
import Action from "./modals/Action.vue";
|
||||||
|
import ActionWithSearch from "./modals/ActionWithSearch.vue";
|
||||||
|
import Prompt from "./modals/Prompt.vue";
|
||||||
|
import DMYPicker from "./modals/DMYPicker.vue";
|
||||||
|
import SnackBar from "./sub/SnackBar.vue";
|
||||||
|
import * as utils from "~/shared/utils";
|
||||||
|
const Intl = require("nativescript-intl");
|
||||||
|
import { localize } from "@nativescript/localize";
|
||||||
let barTimer;
|
let barTimer;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -149,10 +199,9 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
|
mealTypes: ["breakfast", "lunch", "dinner", "snacks"],
|
||||||
dNames: ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"],
|
|
||||||
year: 2021,
|
year: 2021,
|
||||||
mNames: [
|
monthNames: [
|
||||||
"January",
|
"January",
|
||||||
"February",
|
"February",
|
||||||
"March",
|
"March",
|
||||||
|
@ -168,20 +217,27 @@ export default {
|
||||||
],
|
],
|
||||||
month: 0,
|
month: 0,
|
||||||
date: null,
|
date: null,
|
||||||
edit: false,
|
edit: 0,
|
||||||
scrollPos: 1,
|
scrollPos: 1,
|
||||||
appbar: null,
|
appbar: null,
|
||||||
snackbar: null,
|
snackbar: null,
|
||||||
countdown: 5,
|
countdown: 5,
|
||||||
snackMsg: null,
|
snackMsg: null,
|
||||||
showUndo: false,
|
showUndo: 0,
|
||||||
undo: false,
|
undo: 0,
|
||||||
MPSettings: MPSettings,
|
|
||||||
temp: 0,
|
temp: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes", "mealPlans", "mondayFirst"]),
|
...mapState([
|
||||||
|
"icon",
|
||||||
|
"recipes",
|
||||||
|
"layout",
|
||||||
|
"mealPlans",
|
||||||
|
"mondayFirst",
|
||||||
|
"RTL",
|
||||||
|
"plannerView",
|
||||||
|
]),
|
||||||
todaysTime() {
|
todaysTime() {
|
||||||
return new Date(this.year, this.month, this.date, 0).getTime();
|
return new Date(this.year, this.month, this.date, 0).getTime();
|
||||||
},
|
},
|
||||||
|
@ -189,33 +245,58 @@ export default {
|
||||||
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.mealType] = [...(acc[e.mealType] || []), e];
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
} else return 0;
|
} else return {};
|
||||||
|
},
|
||||||
|
calRows() {
|
||||||
|
let h = (Screen.mainScreen.widthDIPs - 32) / 8;
|
||||||
|
let pv = this.plannerView;
|
||||||
|
return pv != "d" ? `${h}, `.repeat(pv == "wk" ? 1 : 6) + h : 0;
|
||||||
},
|
},
|
||||||
getDayNames() {
|
getDayNames() {
|
||||||
let dNames = [...this.dNames];
|
let dNames =
|
||||||
if (!this.mondayFirst) dNames.unshift(dNames.pop());
|
this.plannerView != "d" &&
|
||||||
|
this.getCal.slice(0, 7).map((d) => {
|
||||||
|
let date = new Date(d.y, d.m, d.d);
|
||||||
|
return new Intl.DateTimeFormat(null, {
|
||||||
|
weekday: "short",
|
||||||
|
}).format(date);
|
||||||
|
});
|
||||||
return dNames;
|
return dNames;
|
||||||
},
|
},
|
||||||
getCal() {
|
getCal() {
|
||||||
let y = this.year;
|
const getDays = (s, e) => {
|
||||||
let m = this.month;
|
let a = [];
|
||||||
let ds = new Date(y, m + 1, 0).getDate();
|
for (
|
||||||
let fd = new Date(y, m, 1).getDay();
|
let d = new Date(s);
|
||||||
let ld = new Date(y, m, ds).getDay();
|
d <= new Date(e);
|
||||||
if (this.mondayFirst) fd -= 1;
|
d.setDate(d.getDate() + 1)
|
||||||
let days = new Array(fd).fill(0);
|
) {
|
||||||
// let prevDays = Array.from(
|
a.push({
|
||||||
// { length: fd },
|
d: d.getDate(),
|
||||||
// (e, k) => k + new Date(!m ? y - 1 : y, m, 0).getDate() - fd + 1
|
ld: this.getLocaleN(d.getDate()),
|
||||||
// );
|
m: d.getMonth(),
|
||||||
// let days = prevDays;
|
y: d.getFullYear(),
|
||||||
for (let i = 1; i <= ds; i++) days.push(i);
|
});
|
||||||
// for (let i = 1; i <= 6 - ld; i++) days.push(i);
|
}
|
||||||
return days;
|
return a;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pv = this.plannerView;
|
||||||
|
let date = new Date(
|
||||||
|
this.year,
|
||||||
|
this.month,
|
||||||
|
pv == "mnth" ? 1 : this.date - this.mondayFirst
|
||||||
|
);
|
||||||
|
return pv != "d"
|
||||||
|
? getDays(
|
||||||
|
date.setDate(date.getDate() - date.getDay() + this.mondayFirst),
|
||||||
|
date.setDate(date.getDate() + (pv == "mnth" ? 41 : 6))
|
||||||
|
)
|
||||||
|
: 0;
|
||||||
},
|
},
|
||||||
isExactlyToday() {
|
isExactlyToday() {
|
||||||
let d = new Date();
|
let d = new Date();
|
||||||
|
@ -225,22 +306,24 @@ export default {
|
||||||
this.date == d.getDate()
|
this.date == d.getDate()
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
mealTimesWithRecipes() {
|
hasRecipes() {
|
||||||
return this.mealTimes.filter(
|
return this.mealTypes.filter(
|
||||||
(e) => (this.getRecipes[e] && this.getRecipes[e].length) || this.edit
|
(e) => this.getRecipes[e] && this.getRecipes[e].length
|
||||||
);
|
).length;
|
||||||
|
},
|
||||||
|
noImg() {
|
||||||
|
return /simple|minimal/.test(this.layout);
|
||||||
|
},
|
||||||
|
noAttr() {
|
||||||
|
return /minimal/.test(this.layout);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions(["addMealPlanAction", "deleteMealPlanAction"]),
|
||||||
"setComponent",
|
|
||||||
"addMealPlanAction",
|
|
||||||
"deleteMealPlanAction",
|
|
||||||
]),
|
|
||||||
pgLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
this.setComponent("MealPlanner");
|
|
||||||
if (!this.date || this.date === new Date().getDate()) this.goToToday();
|
if (!this.date || this.date === new Date().getDate()) this.goToToday();
|
||||||
|
this.showBar();
|
||||||
},
|
},
|
||||||
abLoad({ object }) {
|
abLoad({ object }) {
|
||||||
this.appbar = object;
|
this.appbar = object;
|
||||||
|
@ -248,7 +331,7 @@ export default {
|
||||||
sbLoad({ object }) {
|
sbLoad({ object }) {
|
||||||
this.snackbar = object;
|
this.snackbar = object;
|
||||||
},
|
},
|
||||||
svLoad(args) {
|
svScroll(args) {
|
||||||
let scrollUp;
|
let scrollUp;
|
||||||
let y = args.scrollY;
|
let y = args.scrollY;
|
||||||
if (y) {
|
if (y) {
|
||||||
|
@ -258,96 +341,143 @@ export default {
|
||||||
if (!scrollUp && ab == 0) {
|
if (!scrollUp && ab == 0) {
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 64 },
|
translate: { x: 0, y: 64 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
} else if (scrollUp && ab == 64) {
|
} else if (scrollUp && ab == 64) {
|
||||||
this.appbar.animate({
|
this.appbar.animate({
|
||||||
translate: { x: 0, y: 0 },
|
translate: { x: 0, y: 0 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// HELPERS
|
|
||||||
showAppBar() {
|
// Helpers
|
||||||
this.appbar.translateY = 0;
|
centerLabel({ object }, n) {
|
||||||
|
object.android.setGravity(n);
|
||||||
|
},
|
||||||
|
showBar() {
|
||||||
|
// this.appbar.translateY = 0;
|
||||||
|
this.appbar.animate({
|
||||||
|
translate: { x: 0, y: 0 },
|
||||||
|
duration: 200,
|
||||||
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
getrow(i) {
|
getrow(i) {
|
||||||
return Math.floor(2 + i / 7);
|
return Math.floor(1 + 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();
|
||||||
},
|
},
|
||||||
|
getRecipeImage(id) {
|
||||||
|
let r = this.recipes.filter((e) => e.id === id)[0];
|
||||||
|
return r && r.image;
|
||||||
|
},
|
||||||
getRecipeTitle(id) {
|
getRecipeTitle(id) {
|
||||||
let recipe = this.recipes.filter((e) => e.id === id)[0];
|
let r = this.recipes.filter((e) => e.id === id)[0];
|
||||||
return recipe ? recipe.title : `[ ${this.$options.filters.L("resNF")} ]`;
|
return r ? r.title : `[${this.$options.filters.L("resNF")}]`;
|
||||||
|
},
|
||||||
|
getRecipeTotalTime(id) {
|
||||||
|
let r = this.recipes.filter((e) => e.id === id)[0];
|
||||||
|
return r ? this.totalTime(r.prepTime, r.cookTime).time : "00:00";
|
||||||
|
},
|
||||||
|
getYield(id) {
|
||||||
|
let mp = this.mealPlans.filter((e) => e.id == id)[0];
|
||||||
|
let r = this.recipes.filter((e) => e.id === mp.recipeID)[0];
|
||||||
|
return r ? `${this.getLocaleN(mp.quantity)} ${localize(r.yieldUnit)}` : 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
// NavigationHandlers
|
||||||
viewRecipe(recipeID) {
|
viewRecipe(id) {
|
||||||
let recipe = this.recipes.filter((e) => e.id === recipeID)[0];
|
let mp = this.mealPlans.filter((e) => e.id == id)[0];
|
||||||
if (recipe) {
|
let r = this.recipes.filter((e) => e.id === mp.recipeID)[0];
|
||||||
|
if (r) {
|
||||||
this.$navigateTo(ViewRecipe, {
|
this.$navigateTo(ViewRecipe, {
|
||||||
props: {
|
props: {
|
||||||
filterTrylater: true,
|
filterTrylater: 1,
|
||||||
recipeID,
|
recipeID: r.id,
|
||||||
|
yieldQuantity: mp.quantity,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
navigateTo() {
|
||||||
// CALENDAR
|
this.$navigateTo(MPSettings, {
|
||||||
prevMonth() {
|
transition: {
|
||||||
if (this.month == 0) {
|
name: this.RTL ? "slideRight" : "slide",
|
||||||
this.year--;
|
duration: 200,
|
||||||
this.month = 11;
|
curve: "easeOut",
|
||||||
} else this.month--;
|
|
||||||
this.showAppBar();
|
|
||||||
},
|
},
|
||||||
nextMonth() {
|
});
|
||||||
if (this.month == 11) {
|
},
|
||||||
this.year++;
|
navigateBack() {
|
||||||
this.month = 0;
|
Frame.topmost().backStack.length
|
||||||
} else this.month++;
|
? this.$navigateBack()
|
||||||
this.showAppBar();
|
: this.$navigateTo(EnRecipes, {
|
||||||
|
clearHistory: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Calendar
|
||||||
|
navigate(dir) {
|
||||||
|
if (this.RTL) dir = !dir;
|
||||||
|
let pv = this.plannerView;
|
||||||
|
let date = new Date(this.year, this.month, this.date);
|
||||||
|
let sd =
|
||||||
|
pv == "mnth"
|
||||||
|
? new Date(this.year, this.month + (dir ? 1 : 0), 0).getDate()
|
||||||
|
: pv == "wk"
|
||||||
|
? 7
|
||||||
|
: 1;
|
||||||
|
date.setDate(date.getDate() + (dir ? sd : -sd));
|
||||||
|
this.date = date.getDate();
|
||||||
|
this.month = date.getMonth();
|
||||||
|
this.year = date.getFullYear();
|
||||||
|
this.showBar();
|
||||||
},
|
},
|
||||||
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.date = d.getDate();
|
this.date = d.getDate();
|
||||||
this.showAppBar();
|
|
||||||
},
|
},
|
||||||
isToday(date) {
|
dayClasses({ d, m }) {
|
||||||
let d = new Date();
|
let classes = "min ";
|
||||||
return (
|
let dt1 = new Date();
|
||||||
this.year == d.getFullYear() &&
|
let dt2 = new Date(this.year, m, d, 0).getTime();
|
||||||
this.month == d.getMonth() &&
|
if (
|
||||||
date == d.getDate()
|
this.year == dt1.getFullYear() &&
|
||||||
);
|
this.month == dt1.getMonth() &&
|
||||||
|
m == dt1.getMonth() &&
|
||||||
|
d == dt1.getDate()
|
||||||
|
)
|
||||||
|
classes += "tb ";
|
||||||
|
classes += this.date == d && this.month == m ? "hl " : "fb ";
|
||||||
|
if (!!this.mealPlans.filter((e) => e.date == dt2).length)
|
||||||
|
classes += "accent ";
|
||||||
|
if (this.month != m) classes += "sub";
|
||||||
|
return classes;
|
||||||
},
|
},
|
||||||
isActive(date) {
|
setDate({ d, m, y }) {
|
||||||
return this.date == date;
|
this.year = y;
|
||||||
},
|
this.month = m;
|
||||||
hasPlans(date) {
|
this.date = d;
|
||||||
let d = new Date(this.year, this.month, date, 0).getTime();
|
this.showBar();
|
||||||
return this.mealPlans.filter((e) => e.date == d).length;
|
|
||||||
},
|
|
||||||
setToday(date) {
|
|
||||||
if (date) this.date = date;
|
|
||||||
},
|
},
|
||||||
toggleEditMode() {
|
toggleEditMode() {
|
||||||
this.edit = !this.edit;
|
this.edit = !this.edit;
|
||||||
},
|
},
|
||||||
openMonthYearPicker() {
|
openMonthYearPicker() {
|
||||||
this.$showModal(MonthYearPicker, {
|
this.$showModal(DMYPicker, {
|
||||||
props: {
|
props: {
|
||||||
title: "gtD",
|
title: "gtD",
|
||||||
monthNames: this.mNames,
|
monthNames: this.monthNames,
|
||||||
|
currentD: this.date,
|
||||||
currentM: this.month,
|
currentM: this.month,
|
||||||
currentY: this.year,
|
currentY: this.year,
|
||||||
},
|
},
|
||||||
|
@ -355,69 +485,140 @@ export default {
|
||||||
if (res) {
|
if (res) {
|
||||||
this.month = res.month;
|
this.month = res.month;
|
||||||
this.year = res.year;
|
this.year = res.year;
|
||||||
|
this.date = res.date;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
stSwipe({ direction }) {
|
||||||
|
let date = new Date(this.year, this.month, this.date);
|
||||||
|
if (direction == 1) date.setDate(date.getDate() - 1);
|
||||||
|
else if (direction == 2) date.setDate(date.getDate() + 1);
|
||||||
|
this.date = date.getDate();
|
||||||
|
this.month = date.getMonth();
|
||||||
|
this.year = date.getFullYear();
|
||||||
|
},
|
||||||
|
randomMealPlan() {},
|
||||||
|
|
||||||
// DATA HANDLERS
|
// DataHandlers
|
||||||
newMealPlan({ date, type, title, index, inDB }) {
|
newMealPlan({ plan, index, inDB }) {
|
||||||
this.addMealPlanAction({
|
this.addMealPlanAction({
|
||||||
date: date ? date : this.todaysTime,
|
plan,
|
||||||
type,
|
|
||||||
title,
|
|
||||||
index,
|
index,
|
||||||
inDB,
|
inDB,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
addRecipe(type) {
|
addMealPlan() {
|
||||||
let filteredRecipes = this.recipes.filter((e) =>
|
this.$showModal(Action, {
|
||||||
this.getRecipes[type] ? !this.getRecipes[type].includes(e.id) : true
|
props: {
|
||||||
|
title: "add",
|
||||||
|
list: ["rec", "no"],
|
||||||
|
},
|
||||||
|
}).then((type) => {
|
||||||
|
if (type) {
|
||||||
|
this.$showModal(Action, {
|
||||||
|
props: {
|
||||||
|
title: "selMT",
|
||||||
|
list: ["breakfast", "lunch", "dinner", "snacks"],
|
||||||
|
},
|
||||||
|
}).then((mealType) => {
|
||||||
|
if (mealType) {
|
||||||
|
if (type == "rec") {
|
||||||
|
let recipes = this.recipes.filter((e) =>
|
||||||
|
this.getRecipes[mealType]
|
||||||
|
? this.getRecipes[mealType].every((f) => f.recipeID != e.id)
|
||||||
|
: 1
|
||||||
);
|
);
|
||||||
this.$showModal(ActionWithSearch, {
|
this.$showModal(ActionWithSearch, {
|
||||||
props: {
|
props: {
|
||||||
title: "selRec",
|
title: "selRec",
|
||||||
recipes: filteredRecipes,
|
recipes,
|
||||||
|
action: "aNBtn",
|
||||||
},
|
},
|
||||||
}).then(
|
}).then((res) => {
|
||||||
(title) =>
|
if (res == "aNBtn") {
|
||||||
title &&
|
this.$navigateTo(EditRecipe, {
|
||||||
this.newMealPlan({ date: 0, type, title, index: null, inDB: true })
|
animated: false,
|
||||||
);
|
});
|
||||||
|
} else if (res) {
|
||||||
|
let r = this.recipes.filter((e) => e.id == res)[0];
|
||||||
|
this.$showModal(Prompt, {
|
||||||
|
props: {
|
||||||
|
title: `${localize("req", localize(r.yieldUnit))}`,
|
||||||
|
placeholder: Math.abs(parseFloat(r.yieldQuantity)),
|
||||||
|
action: "SET",
|
||||||
|
},
|
||||||
|
}).then((quantity) => {
|
||||||
|
if (quantity) {
|
||||||
|
let plan = {
|
||||||
|
id: utils.getRandomID(),
|
||||||
|
date: this.todaysTime,
|
||||||
|
mealType,
|
||||||
|
recipeID: res,
|
||||||
|
quantity,
|
||||||
|
note: null,
|
||||||
|
};
|
||||||
|
this.newMealPlan({
|
||||||
|
plan,
|
||||||
|
index: null,
|
||||||
|
inDB: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (type == "no") {
|
||||||
|
this.$showModal(Prompt, {
|
||||||
|
props: {
|
||||||
|
title: "no",
|
||||||
|
type: "view",
|
||||||
|
action: "ADD",
|
||||||
|
},
|
||||||
|
}).then((note) => {
|
||||||
|
if (note) {
|
||||||
|
let plan = {
|
||||||
|
id: utils.getRandomID(),
|
||||||
|
date: this.todaysTime,
|
||||||
|
mealType,
|
||||||
|
recipeID: null,
|
||||||
|
quantity: null,
|
||||||
|
note,
|
||||||
|
};
|
||||||
|
this.newMealPlan({
|
||||||
|
plan,
|
||||||
|
index: null,
|
||||||
|
inDB: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
deleteTempFromDB() {
|
deleteTempFromDB() {
|
||||||
if (this.temp) {
|
if (this.temp) {
|
||||||
this.temp.inDB = 1;
|
let { plan, index } = this.temp;
|
||||||
this.deleteMealPlanAction(this.temp);
|
this.deleteMealPlanAction({ id: plan.id, index, inDB: 1 });
|
||||||
this.temp = 0;
|
this.temp = 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeRecipe(type, title) {
|
removeRecipe(id) {
|
||||||
this.deleteTempFromDB();
|
this.deleteTempFromDB();
|
||||||
let date = this.todaysTime;
|
let index = this.mealPlans.findIndex((e) => e.id == id);
|
||||||
let index = this.mealPlans.findIndex(
|
let plan = this.mealPlans.filter((e) => e.id == id)[0];
|
||||||
(e) => e.date == date && e.type == type && e.title == title
|
this.temp = { plan, index };
|
||||||
);
|
this.deleteMealPlanAction({ id, index });
|
||||||
let mealPlan = {
|
this.showUndoBar(plan.note ? "rmN" : "recRm")
|
||||||
date,
|
.then(() => this.newMealPlan({ plan, index }))
|
||||||
type,
|
|
||||||
title,
|
|
||||||
index,
|
|
||||||
};
|
|
||||||
let temp;
|
|
||||||
this.temp = temp = mealPlan;
|
|
||||||
this.deleteMealPlanAction(mealPlan);
|
|
||||||
this.showUndoBar("recRm")
|
|
||||||
.then(() => this.newMealPlan({ date, type, title, index }))
|
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
temp.inDB = 1;
|
this.deleteMealPlanAction({ id, index, inDB: 1 });
|
||||||
console.log("deleting inDB after catch: ", temp);
|
|
||||||
this.deleteMealPlanAction(temp);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showUndoBar(message) {
|
showUndoBar(message) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.animateBar(this.appbar, 0).then(() => {
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
this.showUndo = true;
|
this.showUndo = 1;
|
||||||
this.snackMsg = message;
|
this.snackMsg = message;
|
||||||
this.countdown = 5;
|
this.countdown = 5;
|
||||||
this.animateBar(this.snackbar, 1).then(() => {
|
this.animateBar(this.snackbar, 1).then(() => {
|
||||||
|
@ -426,12 +627,12 @@ export default {
|
||||||
barTimer = setInterval(() => {
|
barTimer = setInterval(() => {
|
||||||
if (this.undo) {
|
if (this.undo) {
|
||||||
this.hideBar();
|
this.hideBar();
|
||||||
resolve(true);
|
resolve(1);
|
||||||
}
|
}
|
||||||
this.countdown = Math.round((a -= 0.1));
|
this.countdown = Math.round((a -= 0.1));
|
||||||
if (this.countdown < 1) {
|
if (this.countdown < 1) {
|
||||||
this.hideBar();
|
this.hideBar();
|
||||||
reject(true);
|
reject(1);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
@ -440,22 +641,76 @@ export default {
|
||||||
},
|
},
|
||||||
hideBar() {
|
hideBar() {
|
||||||
clearInterval(barTimer);
|
clearInterval(barTimer);
|
||||||
|
this.deleteTempFromDB();
|
||||||
this.animateBar(this.snackbar, 0).then(() => {
|
this.animateBar(this.snackbar, 0).then(() => {
|
||||||
this.showUndo = this.undo = false;
|
this.showUndo = this.undo = 0;
|
||||||
this.animateBar(this.appbar, 1);
|
this.animateBar(this.appbar, 1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
undoDel() {
|
undoDel() {
|
||||||
this.undo = true;
|
this.undo = 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
//HELPERS
|
// Helpers
|
||||||
touchMonthYearPicker({ object, action }) {
|
formattedDate(v) {
|
||||||
object.className = action.match(/down|move/)
|
let d = new Date(this.year, this.month, this.date, 0, 0, 0);
|
||||||
? "monthName fade"
|
let today = new Date();
|
||||||
: "monthName";
|
let myToday = new Date(
|
||||||
|
today.getFullYear(),
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDate(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
let tdy = myToday.getTime();
|
||||||
|
let ystr = myToday.setDate(today.getDate() - 1);
|
||||||
|
let tmrw = myToday.setDate(today.getDate() + 1);
|
||||||
|
let options: {
|
||||||
|
year?: string;
|
||||||
|
month?: string;
|
||||||
|
weekday?: string;
|
||||||
|
day?: string;
|
||||||
|
} = {};
|
||||||
|
if (v) {
|
||||||
|
options.weekday = "long";
|
||||||
|
options.day = "numeric";
|
||||||
|
options.month = "long";
|
||||||
|
} else {
|
||||||
|
options.year = "numeric";
|
||||||
|
options.month = "long";
|
||||||
|
}
|
||||||
|
if (this.plannerView == "d") {
|
||||||
|
options.weekday = "long";
|
||||||
|
options.day = "numeric";
|
||||||
|
options.month = "short";
|
||||||
|
}
|
||||||
|
let date = new Intl.DateTimeFormat(null, options).format(d);
|
||||||
|
let val;
|
||||||
|
switch (d.getTime()) {
|
||||||
|
case ystr:
|
||||||
|
val = "ystr";
|
||||||
|
break;
|
||||||
|
case tdy:
|
||||||
|
val = "tdy";
|
||||||
|
break;
|
||||||
|
case tmrw:
|
||||||
|
val = "tmrw";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
? [ystr, tdy, tmrw].some((e) => e == d.getTime())
|
||||||
|
? localize(val)
|
||||||
|
: date
|
||||||
|
: date;
|
||||||
|
},
|
||||||
|
mYPicker({ object, action }) {
|
||||||
|
object.className = action.match(/down|move/) ? "month fade" : "month";
|
||||||
if (action == "up") this.openMonthYearPicker();
|
if (action == "up") this.openMonthYearPicker();
|
||||||
},
|
},
|
||||||
|
touchRecipe({ object, action }) {
|
||||||
|
object.className = action.match(/down|move/) ? "fade" : "";
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" @unloaded="onPageUnload" actionBarHidden="true">
|
<Page @loaded="pgLoad" @unloaded="onPageUnload" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="*">
|
<GridLayout rows="*, auto, auto" columns="auto, *, auto">
|
||||||
<DockLayout stretchLastChild="true" rowSpan="2">
|
<DockLayout stretchLastChild="true" rowSpan="3" colSpan="3">
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
dock="top"
|
dock="top"
|
||||||
rows="auto,auto"
|
rows="auto,auto"
|
||||||
columns="*, auto"
|
columns="*, auto"
|
||||||
paddingBottom="24"
|
paddingBottom="24"
|
||||||
>
|
>
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<Label class="pageTitle" paddingBottom="8" :text="recipe.title" />
|
<RLabel class="pageTitle" paddingBottom="8" :text="recipe.title" />
|
||||||
<StackLayout marginLeft="12" orientation="horizontal">
|
<StackLayout
|
||||||
|
:class="{ f: RTL }"
|
||||||
|
margin="0 12"
|
||||||
|
orientation="horizontal"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
class="ico rate"
|
class="ico rate"
|
||||||
:class="{ rated: recipe.rating >= n }"
|
:class="{ rated: recipe.rating >= n }"
|
||||||
|
@ -34,72 +39,82 @@
|
||||||
decodeHeight="96"
|
decodeHeight="96"
|
||||||
@tap="viewPhoto"
|
@tap="viewPhoto"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<AbsoluteLayout dock="bottom">
|
<AbsoluteLayout dock="bottom">
|
||||||
<ScrollView
|
<ScrollView
|
||||||
dock="bottom"
|
dock="bottom"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
@loaded="onScrollLoad"
|
@loaded="onScrollLoad"
|
||||||
@scroll="onScroll($event)"
|
@scroll="svScroll($event)"
|
||||||
>
|
>
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, *">
|
<RGridLayout :rtl="RTL" rows="auto" columns="*, *">
|
||||||
<StackLayout class="attribute">
|
<StackLayout class="attribute">
|
||||||
<Label class="title sub" :text="'cui' | L" />
|
<RLabel class="sub" :text="'cui' | L" />
|
||||||
<Label class="value" :text="recipe.cuisine | L" />
|
<RLabel class="value" :text="recipe.cuisine | L" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout class="attribute" col="1">
|
<StackLayout class="attribute" col="1">
|
||||||
<Label class="title sub" :text="'cat' | L" />
|
<RLabel class="sub" :text="'cat' | L" />
|
||||||
<Label class="value" :text="recipe.category | L" />
|
<RLabel class="value" :text="recipe.category | L" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<StackLayout :hidden="!recipe.tags.length" class="attribute">
|
<StackLayout
|
||||||
<Label class="title sub" :text="'ts' | L" />
|
:hidden="!recipe.tags.length"
|
||||||
<Label class="value" :text="getTags(recipe.tags)" />
|
class="attribute hal"
|
||||||
|
:class="{ r: RTL }"
|
||||||
|
>
|
||||||
|
<RLabel class="sub" :text="'ts' | L" />
|
||||||
|
<RLabel class="value" :text="getTags(recipe.tags)" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout rows="auto" columns="*, *">
|
<RGridLayout :rtl="RTL" rows="auto" columns="*, *">
|
||||||
<StackLayout
|
<StackLayout
|
||||||
class="attribute"
|
class="attribute"
|
||||||
:hidden="!hasTime(recipe.prepTime)"
|
:hidden="!hasTime(recipe.prepTime)"
|
||||||
>
|
>
|
||||||
<Label class="title sub" :text="'prepT' | L" />
|
<RLabel class="sub" :text="'prepT' | L" />
|
||||||
<Label class="value" :text="formattedTime(recipe.prepTime)" />
|
<RLabel
|
||||||
|
class="value"
|
||||||
|
:text="formattedTime(recipe.prepTime)"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout
|
<StackLayout
|
||||||
:col="hasTime(recipe.prepTime) ? 1 : 0"
|
:col="hasTime(recipe.prepTime) ? 1 : 0"
|
||||||
class="attribute"
|
class="attribute"
|
||||||
:hidden="!hasTime(recipe.cookTime)"
|
:hidden="!hasTime(recipe.cookTime)"
|
||||||
>
|
>
|
||||||
<Label class="title sub" :text="'cookT' | L" />
|
<RLabel class="title sub" :text="'cookT' | L" />
|
||||||
<Label class="value" :text="formattedTime(recipe.cookTime)" />
|
<RLabel
|
||||||
|
class="value"
|
||||||
|
:text="formattedTime(recipe.cookTime)"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<GridLayout rows="auto" columns="*, *">
|
<RGridLayout :rtl="RTL" rows="auto" columns="*, *">
|
||||||
<StackLayout class="attribute">
|
<StackLayout class="attribute">
|
||||||
<Label class="title sub" :text="'yld' | L" />
|
<RLabel class="title sub" :text="'yld' | L" />
|
||||||
<Label
|
<RLabel
|
||||||
@touch="touchYield"
|
@touch="touchYield"
|
||||||
class="value clickable"
|
class="value accent"
|
||||||
horizontalAlignment="left"
|
|
||||||
:text="`${tempYieldQuantity} ${$options.filters.L(
|
:text="`${tempYieldQuantity} ${$options.filters.L(
|
||||||
recipe.yieldUnit
|
recipe.yieldUnit
|
||||||
)}`"
|
)}`"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout class="attribute" col="1">
|
<StackLayout class="attribute" col="1">
|
||||||
<Label class="title sub" :text="'Difficulty level' | L" />
|
<RLabel class="title sub" :text="'Difficulty level' | L" />
|
||||||
<Label class="value" :text="recipe.difficulty | L" />
|
<RLabel class="value" :text="recipe.difficulty | L" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<StackLayout @loaded="onIngsLoad">
|
<StackLayout @loaded="onIngsLoad">
|
||||||
<Label
|
<RLabel
|
||||||
padding="0 16"
|
padding="0 16"
|
||||||
class="sectionTitle"
|
class="sectionTitle"
|
||||||
:hidden="!recipe.ingredients.length"
|
:hidden="!recipe.ingredients.length"
|
||||||
:text="getTitleCount('ings', 'ingredients')"
|
:text="getTitleCount('ings', 'ingredients')"
|
||||||
/>
|
/>
|
||||||
<StackLayout
|
<RStackLayout
|
||||||
|
:rtl="RTL"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
v-for="(item, index) in recipe.ingredients"
|
v-for="(item, index) in recipe.ingredients"
|
||||||
:key="index + 'ing'"
|
:key="index + 'ing'"
|
||||||
|
@ -107,39 +122,29 @@
|
||||||
@touch="touchIngredient($event, index)"
|
@touch="touchIngredient($event, index)"
|
||||||
>
|
>
|
||||||
<Button class="ico min" :text="icon.uncheck" />
|
<Button class="ico min" :text="icon.uncheck" />
|
||||||
<Label
|
<RLabel class="value tw" :text="getIngredientItem(item)" />
|
||||||
class="value tw"
|
</RStackLayout>
|
||||||
:text="`${
|
|
||||||
roundedQuantity(item.quantity)
|
|
||||||
? roundedQuantity(item.quantity) + ' '
|
|
||||||
: ''
|
|
||||||
}${
|
|
||||||
roundedQuantity(item.quantity)
|
|
||||||
? $options.filters.L(item.unit) + ' '
|
|
||||||
: ''
|
|
||||||
}${item.item}`"
|
|
||||||
/>
|
|
||||||
</StackLayout>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout @loaded="onInsLoad">
|
<StackLayout @loaded="onInsLoad">
|
||||||
<Label
|
<RLabel
|
||||||
padding="0 16"
|
padding="0 16"
|
||||||
:hidden="!recipe.instructions.length"
|
:hidden="!recipe.instructions.length"
|
||||||
class="sectionTitle"
|
class="sectionTitle"
|
||||||
:text="getTitleCount('inss', 'instructions')"
|
:text="getTitleCount('inss', 'instructions')"
|
||||||
/>
|
/>
|
||||||
<StackLayout
|
<RStackLayout
|
||||||
|
:rtl="RTL"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
@touch="touchInstruction"
|
@touch="touchInstruction"
|
||||||
v-for="(instruction, index) in recipe.instructions"
|
v-for="(instruction, index) in recipe.instructions"
|
||||||
:key="index + 'ins'"
|
:key="index + 'ins'"
|
||||||
class="instruction"
|
class="instruction"
|
||||||
>
|
>
|
||||||
<Button class="count ico min" :text="index + 1" />
|
<Button class="count ico min" :text="getLocaleN(index + 1)" />
|
||||||
<Label class="value tw" :text="instruction" />
|
<RLabel class="value tw" :text="instruction" />
|
||||||
|
</RStackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
<RLabel
|
||||||
<Label
|
|
||||||
@loaded="onCmbLoad"
|
@loaded="onCmbLoad"
|
||||||
padding="0 16"
|
padding="0 16"
|
||||||
:hidden="!recipe.combinations.length"
|
:hidden="!recipe.combinations.length"
|
||||||
|
@ -153,7 +158,7 @@
|
||||||
:text="getCombinationTitle(combination)"
|
:text="getCombinationTitle(combination)"
|
||||||
@tap="viewCombination(combination)"
|
@tap="viewCombination(combination)"
|
||||||
/>
|
/>
|
||||||
<Label
|
<RLabel
|
||||||
@loaded="onNosTLoad"
|
@loaded="onNosTLoad"
|
||||||
padding="0 16"
|
padding="0 16"
|
||||||
:hidden="!recipe.notes.length"
|
:hidden="!recipe.notes.length"
|
||||||
|
@ -161,17 +166,10 @@
|
||||||
:text="getTitleCount('nos', 'notes')"
|
:text="getTitleCount('nos', 'notes')"
|
||||||
/>
|
/>
|
||||||
<StackLayout @loaded="onNosLoad" padding="0 16"> </StackLayout>
|
<StackLayout @loaded="onNosLoad" padding="0 16"> </StackLayout>
|
||||||
<Label
|
<Label class="dateInfo sub tw" :text="getDates().uc" />
|
||||||
class="dateInfo sub tw"
|
|
||||||
:text="`${$options.filters.L('Last updated')}: ${formattedDate(
|
|
||||||
recipe.lastModified
|
|
||||||
)}\n${$options.filters.L('Created')}: ${formattedDate(
|
|
||||||
recipe.created
|
|
||||||
)}`"
|
|
||||||
/>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Label
|
<RLabel
|
||||||
@loaded="onStickyLoad"
|
@loaded="onStickyLoad"
|
||||||
class="sectionTitle sticky"
|
class="sectionTitle sticky"
|
||||||
:hidden="!stickyTitle"
|
:hidden="!stickyTitle"
|
||||||
|
@ -181,61 +179,85 @@
|
||||||
</DockLayout>
|
</DockLayout>
|
||||||
<GridLayout
|
<GridLayout
|
||||||
row="1"
|
row="1"
|
||||||
@loaded="onAppBarLoad"
|
@loaded="sbload"
|
||||||
class="appbar"
|
class="appbar sidebar"
|
||||||
v-show="!toast"
|
:col="RTL ? 0 : 2"
|
||||||
columns="auto, *, auto, auto, auto, auto, auto"
|
rows="auto, auto, auto"
|
||||||
>
|
>
|
||||||
|
<Button class="ico" :text="icon.timer" @tap="openCookingTimer" />
|
||||||
<Button
|
<Button
|
||||||
|
row="1"
|
||||||
|
:hidden="busyDup"
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="photoOpen ? icon.x : icon.back"
|
:class="{ f: RTL }"
|
||||||
@tap="navigateBack"
|
:text="icon.dup"
|
||||||
|
@tap="duplicateRecipe"
|
||||||
/>
|
/>
|
||||||
|
<ActivityIndicator row="1" :hidden="!busyDup" :busy="busyDup" />
|
||||||
|
<Button
|
||||||
|
:hidden="!hasPrinterSupport"
|
||||||
|
row="2"
|
||||||
|
class="ico"
|
||||||
|
:text="icon.print"
|
||||||
|
@tap="printView"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
|
row="2"
|
||||||
|
colSpan="3"
|
||||||
|
@loaded="abLoad"
|
||||||
|
class="appbar"
|
||||||
|
:hidden="toast"
|
||||||
|
columns="auto, *, auto, auto, auto, auto"
|
||||||
|
@touch="() => null"
|
||||||
|
>
|
||||||
|
<Button class="ico rtl" :text="icon.back" @tap="$navigateBack()" />
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
class="ico"
|
|
||||||
:text="icon.timer"
|
|
||||||
@tap="openCookingTimer"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
col="3"
|
|
||||||
v-if="!filterTrylater"
|
v-if="!filterTrylater"
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="recipe.tried ? icon.try : icon.tried"
|
:text="recipe.tried ? icon.try : icon.tried"
|
||||||
@tap="toggle('tried')"
|
@tap="toggle('tried')"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="3"
|
col="2"
|
||||||
v-else
|
v-else
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="icon.done"
|
:text="icon.done"
|
||||||
@tap="toggle('tried', true)"
|
@tap="toggle('tried', 1)"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="4"
|
col="3"
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="recipe.favorite ? icon.faved : icon.fav"
|
:text="recipe.favorite ? icon.faved : icon.fav"
|
||||||
@tap="toggle('favorite')"
|
@tap="toggle('favorite')"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="5"
|
col="4"
|
||||||
v-if="!busy"
|
:hidden="busyEdit"
|
||||||
class="ico"
|
class="ico"
|
||||||
:text="icon.edit"
|
:text="icon.edit"
|
||||||
@tap="editRecipe"
|
@tap="editRecipe"
|
||||||
/>
|
/>
|
||||||
<ActivityIndicator col="5" v-else :busy="busy" />
|
<ActivityIndicator col="4" :hidden="!busyEdit" :busy="busyEdit" />
|
||||||
<Button
|
<Button
|
||||||
col="6"
|
col="5"
|
||||||
class="ico fab"
|
class="ico fab"
|
||||||
:text="icon.share"
|
:text="icon.share"
|
||||||
@tap="shareHandler"
|
@tap="shareHandler"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
<Toast :toast="toast" :action="hideLastTried" />
|
<Toast
|
||||||
<AbsoluteLayout rowSpan="2">
|
row="2"
|
||||||
|
colSpan="3"
|
||||||
|
:onload="tbLoad"
|
||||||
|
:toast="toast"
|
||||||
|
:action="hideBar"
|
||||||
|
/>
|
||||||
|
<AbsoluteLayout rowSpan="3" colSpan="3">
|
||||||
<Image
|
<Image
|
||||||
@tap="({ object }) => (object.cancel = true)"
|
@tap="closePhoto"
|
||||||
backgroundColor="black"
|
backgroundColor="black"
|
||||||
stretch="aspectFit"
|
stretch="aspectFit"
|
||||||
@loaded="onImgViewLoad"
|
@loaded="onImgViewLoad"
|
||||||
|
@ -243,6 +265,7 @@
|
||||||
class="photoviewer"
|
class="photoviewer"
|
||||||
/>
|
/>
|
||||||
</AbsoluteLayout>
|
</AbsoluteLayout>
|
||||||
|
<WebView @loaded="wvLoad" hidden />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -255,13 +278,13 @@ import {
|
||||||
Utils,
|
Utils,
|
||||||
Span,
|
Span,
|
||||||
FormattedString,
|
FormattedString,
|
||||||
Label,
|
|
||||||
Observable,
|
Observable,
|
||||||
Screen,
|
Screen,
|
||||||
CoreTypes,
|
CoreTypes,
|
||||||
|
WebView,
|
||||||
} from "@nativescript/core";
|
} from "@nativescript/core";
|
||||||
|
import { RLabel } from "~/rtl-ui";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
const intl = require("nativescript-intl");
|
|
||||||
import { mapActions, mapState } from "vuex";
|
import { mapActions, mapState } from "vuex";
|
||||||
import CookingTimer from "./CookingTimer.vue";
|
import CookingTimer from "./CookingTimer.vue";
|
||||||
import EditRecipe from "./EditRecipe.vue";
|
import EditRecipe from "./EditRecipe.vue";
|
||||||
|
@ -269,17 +292,24 @@ import Action from "./modals/Action.vue";
|
||||||
import Toast from "./sub/Toast.vue";
|
import Toast from "./sub/Toast.vue";
|
||||||
import Prompt from "./modals/Prompt.vue";
|
import Prompt from "./modals/Prompt.vue";
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
|
const Intl = require("nativescript-intl");
|
||||||
|
let barTimer;
|
||||||
|
declare const android: any;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Toast },
|
components: { Toast },
|
||||||
props: ["filterTrylater", "recipeID"],
|
props: ["filterTrylater", "recipeID", "yieldQuantity"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
busy: false,
|
busyEdit: 0,
|
||||||
|
busyDup: 0,
|
||||||
yieldMultiplier: 1,
|
yieldMultiplier: 1,
|
||||||
recipe: null,
|
recipe: null,
|
||||||
currentRecipeID: this.recipeID,
|
currentRecipeID: this.recipeID,
|
||||||
scrollview: null,
|
scrollview: null,
|
||||||
appbar: null,
|
appbar: null,
|
||||||
|
sidebar: null,
|
||||||
|
toastbar: null,
|
||||||
ingcon: null,
|
ingcon: null,
|
||||||
inscon: null,
|
inscon: null,
|
||||||
cmbcon: null,
|
cmbcon: null,
|
||||||
|
@ -290,13 +320,15 @@ export default {
|
||||||
checked: 0,
|
checked: 0,
|
||||||
stepsDid: 0,
|
stepsDid: 0,
|
||||||
toast: null,
|
toast: null,
|
||||||
photoOpen: false,
|
photoOpen: 0,
|
||||||
showTitleArr: [false, false, false, false],
|
showTitleArr: [0, 0, 0, 0],
|
||||||
sticky: null,
|
sticky: null,
|
||||||
|
view: null,
|
||||||
|
wv: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes"]),
|
...mapState(["icon", "recipes", "RTL"]),
|
||||||
tempYieldQuantity() {
|
tempYieldQuantity() {
|
||||||
return Math.abs(this.yieldMultiplier) > 0
|
return Math.abs(this.yieldMultiplier) > 0
|
||||||
? Math.abs(parseFloat(this.yieldMultiplier))
|
? Math.abs(parseFloat(this.yieldMultiplier))
|
||||||
|
@ -320,29 +352,38 @@ export default {
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
},
|
},
|
||||||
|
hasPrinterSupport() {
|
||||||
|
return utils.Printer.isSupported();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions(["toggleStateAction", "setRatingAction", "toggleCartAction"]),
|
||||||
"toggleStateAction",
|
pgLoad({ object }) {
|
||||||
"setComponent",
|
this.busyDup = this.busyEdit = this.photoOpen = 0;
|
||||||
"setRatingAction",
|
|
||||||
"toggleCartAction",
|
|
||||||
]),
|
|
||||||
onPageLoad({ object }) {
|
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
this.busy = this.photoOpen = false;
|
|
||||||
this.setComponent("ViewRecipe");
|
|
||||||
if (this.yieldMultiplier == this.recipe.yieldQuantity)
|
if (this.yieldMultiplier == this.recipe.yieldQuantity)
|
||||||
this.yieldMultiplier = this.recipe.yieldQuantity;
|
this.yieldMultiplier = this.recipe.yieldQuantity;
|
||||||
this.keepScreenOn(true);
|
utils.keepScreenOn(1);
|
||||||
this.syncCombinations();
|
this.syncCombinations();
|
||||||
|
this.view = object.page.getViewById("printview");
|
||||||
},
|
},
|
||||||
onPageUnload() {
|
onPageUnload() {
|
||||||
this.keepScreenOn(false);
|
utils.keepScreenOn(0);
|
||||||
},
|
},
|
||||||
onAppBarLoad({ object }) {
|
sbload({ object }) {
|
||||||
|
this.sidebar = object;
|
||||||
|
},
|
||||||
|
abLoad({ object }) {
|
||||||
this.appbar = object;
|
this.appbar = object;
|
||||||
},
|
},
|
||||||
|
tbLoad({ object }) {
|
||||||
|
this.toastbar = object;
|
||||||
|
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
|
||||||
|
},
|
||||||
|
wvLoad({ object }) {
|
||||||
|
this.wv = object;
|
||||||
|
utils.updateLocale();
|
||||||
|
},
|
||||||
onIngsLoad({ object }) {
|
onIngsLoad({ object }) {
|
||||||
this.ingcon = object;
|
this.ingcon = object;
|
||||||
},
|
},
|
||||||
|
@ -366,24 +407,22 @@ export default {
|
||||||
this.imgView = object;
|
this.imgView = object;
|
||||||
this.imgView.visibility = "collapsed";
|
this.imgView.visibility = "collapsed";
|
||||||
this.imgView.top = 24;
|
this.imgView.top = 24;
|
||||||
this.imgView.left = Screen.mainScreen.widthDIPs - 112;
|
this.imgView.left = this.RTL ? 16 : Screen.mainScreen.widthDIPs - 112;
|
||||||
},
|
},
|
||||||
onStickyLoad({ object }) {
|
onStickyLoad({ object }) {
|
||||||
this.sticky = object;
|
this.sticky = object;
|
||||||
},
|
},
|
||||||
fixTitle({ object }, swipeUp: boolean): void {
|
fixTitle(object, swipeUp: boolean): void {
|
||||||
let ingL = this.recipe.ingredients.length;
|
let ingL = this.recipe.ingredients.length;
|
||||||
let insL = this.recipe.instructions.length;
|
let insL = this.recipe.instructions.length;
|
||||||
let cmbL = this.recipe.combinations.length;
|
let cmbL = this.recipe.combinations.length;
|
||||||
let notL = this.recipe.notes.length;
|
let notL = this.recipe.notes.length;
|
||||||
|
|
||||||
const isTop = (label): boolean => {
|
const isTop = (label): boolean => {
|
||||||
let pos = label.getLocationRelativeTo(object).y;
|
let pos = label.getLocationRelativeTo(object).y;
|
||||||
return label === this.cmbcon || label === this.notesT
|
return label === this.cmbcon || label === this.notesT
|
||||||
? pos < 0
|
? pos < 0
|
||||||
: pos + 32 < 0;
|
: pos + 32 < 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setVisibleTitle = (n: number): void => {
|
const setVisibleTitle = (n: number): void => {
|
||||||
let arr = [ingL, insL, cmbL, notL];
|
let arr = [ingL, insL, cmbL, notL];
|
||||||
this.showTitleArr = Array.from(
|
this.showTitleArr = Array.from(
|
||||||
|
@ -391,7 +430,6 @@ export default {
|
||||||
(v, i) => (v = arr[i] ? i < n : false)
|
(v, i) => (v = arr[i] ? i < n : false)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (swipeUp) {
|
if (swipeUp) {
|
||||||
if (ingL && !this.showTitleArr[0] && isTop(this.ingcon))
|
if (ingL && !this.showTitleArr[0] && isTop(this.ingcon))
|
||||||
setVisibleTitle(1);
|
setVisibleTitle(1);
|
||||||
|
@ -412,45 +450,71 @@ export default {
|
||||||
setVisibleTitle(0);
|
setVisibleTitle(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onScroll(args) {
|
svScroll({ object, scrollY }) {
|
||||||
let swipeUp: boolean;
|
let swipeUp: boolean;
|
||||||
let y = args.scrollY;
|
let y = scrollY;
|
||||||
if (y) {
|
if (y) {
|
||||||
swipeUp = y > this.scrollPos;
|
swipeUp = y > this.scrollPos;
|
||||||
this.scrollPos = Math.abs(y);
|
this.scrollPos = Math.abs(y);
|
||||||
this.fixTitle(args, swipeUp);
|
this.fixTitle(object, swipeUp);
|
||||||
if (!this.toast) {
|
if (!this.toast) {
|
||||||
let ab = this.appbar.translateY;
|
let ab = this.appbar.translateY;
|
||||||
if (swipeUp && ab == 0)
|
if (swipeUp && ab == 0) this.hideBars();
|
||||||
this.appbar.animate({
|
else if (!swipeUp && ab == 64) this.showBars();
|
||||||
translate: { x: 0, y: 64 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
|
||||||
else if (!swipeUp && ab == 64)
|
|
||||||
this.appbar.animate({
|
|
||||||
translate: { x: 0, y: 0 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// HELPERS
|
showBars() {
|
||||||
|
this.appbar.animate({
|
||||||
|
translate: { x: 0, y: 0 },
|
||||||
|
duration: 200,
|
||||||
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
|
});
|
||||||
|
this.sidebar.animate({
|
||||||
|
translate: { x: 0, y: 0 },
|
||||||
|
duration: 200,
|
||||||
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hideBars() {
|
||||||
|
this.appbar.animate({
|
||||||
|
translate: { x: 0, y: 64 },
|
||||||
|
duration: 200,
|
||||||
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
|
});
|
||||||
|
this.sidebar.animate({
|
||||||
|
translate: { x: this.RTL ? -64 : 64, y: 0 },
|
||||||
|
duration: 200,
|
||||||
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helpers
|
||||||
getTitleCount(title, type) {
|
getTitleCount(title, type) {
|
||||||
let count = this.recipe[type].length;
|
let c = this.recipe[type].length;
|
||||||
let selected = null;
|
let s = null;
|
||||||
switch (title) {
|
switch (title) {
|
||||||
case "ings":
|
case "ings":
|
||||||
selected = this.checked;
|
s = this.checked;
|
||||||
break;
|
break;
|
||||||
case "inss":
|
case "inss":
|
||||||
selected = this.stepsDid;
|
s = this.stepsDid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let text = selected ? ` (${selected}/${count})` : ` (${count})`;
|
c = this.getLocaleN(c);
|
||||||
|
s = s && this.getLocaleN(s);
|
||||||
|
let text = s ? ` (${s}/${c})` : ` (${c})`;
|
||||||
return localize(title) + text;
|
return localize(title) + text;
|
||||||
},
|
},
|
||||||
|
getIngredientItem(item) {
|
||||||
|
return `${
|
||||||
|
this.roundedQuantity(item.quantity)
|
||||||
|
? this.roundedQuantity(item.quantity) + " "
|
||||||
|
: ""
|
||||||
|
}${this.roundedQuantity(item.quantity) ? localize(item.unit) + " " : ""}${
|
||||||
|
item.item
|
||||||
|
}`;
|
||||||
|
},
|
||||||
changeYield() {
|
changeYield() {
|
||||||
this.$showModal(Prompt, {
|
this.$showModal(Prompt, {
|
||||||
props: {
|
props: {
|
||||||
|
@ -485,30 +549,24 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
showLastTried() {
|
showLastTried() {
|
||||||
this.toast = localize("triedInfo", this.niceDate(this.recipe.lastTried));
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
utils.timer(10, (val) => {
|
this.toast = localize(
|
||||||
if (!val) this.toast = val;
|
"triedInfo",
|
||||||
|
this.niceDate(this.recipe.lastTried)
|
||||||
|
);
|
||||||
|
this.animateBar(this.toastbar, 1);
|
||||||
|
let a = 10;
|
||||||
|
clearInterval(barTimer);
|
||||||
|
barTimer = setInterval(() => a-- < 1 && this.hideBar(), 1000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hideLastTried({ object }) {
|
hideBar() {
|
||||||
object
|
clearInterval(barTimer);
|
||||||
.animate({
|
this.animateBar(this.toastbar, 0).then(() => {
|
||||||
opacity: 0,
|
|
||||||
translate: { x: 0, y: 64 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.showUndo = false;
|
|
||||||
this.appbar.translateY = 64;
|
|
||||||
this.appbar.animate({
|
|
||||||
translate: { x: 0, y: 0 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
|
||||||
object.opacity = 1;
|
|
||||||
object.translateY = 0;
|
|
||||||
this.toast = null;
|
this.toast = null;
|
||||||
|
this.photoOpen
|
||||||
|
? (this.appbar.opacity = 1)
|
||||||
|
: this.animateBar(this.appbar, 1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// getMeasure(value: number, unit: string) {
|
// getMeasure(value: number, unit: string) {
|
||||||
|
@ -560,14 +618,6 @@ export default {
|
||||||
) / 100
|
) / 100
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
keepScreenOn(boolean) {
|
|
||||||
let activity =
|
|
||||||
Application.android.foregroundActivity ||
|
|
||||||
Application.android.startActivity;
|
|
||||||
let window = activity.getWindow();
|
|
||||||
let flag = android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
|
||||||
boolean ? window.addFlags(flag) : window.clearFlags(flag);
|
|
||||||
},
|
|
||||||
formattedTime(time) {
|
formattedTime(time) {
|
||||||
let t = time.split(":");
|
let t = time.split(":");
|
||||||
let h = parseInt(t[0]);
|
let h = parseInt(t[0]);
|
||||||
|
@ -577,15 +627,13 @@ export default {
|
||||||
return h ? (m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}`) : `${m} ${min}`;
|
return h ? (m ? `${h} ${hr} ${m} ${min}` : `${h} ${hr}`) : `${m} ${min}`;
|
||||||
},
|
},
|
||||||
formattedDate(date) {
|
formattedDate(date) {
|
||||||
let d = new Date(date);
|
return new Intl.DateTimeFormat(null, {
|
||||||
var dateFormat = new intl.DateTimeFormat(null, {
|
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "long",
|
month: "long",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
hour: "numeric",
|
hour: "numeric",
|
||||||
minute: "numeric",
|
minute: "numeric",
|
||||||
}).format(d);
|
}).format(new Date(date));
|
||||||
return `${dateFormat}`;
|
|
||||||
},
|
},
|
||||||
isValidURL(string) {
|
isValidURL(string) {
|
||||||
let pattern = new RegExp("^https?|^www", "ig");
|
let pattern = new RegExp("^https?|^www", "ig");
|
||||||
|
@ -654,26 +702,38 @@ export default {
|
||||||
this.inscon.getChildAt(i).className = "instruction";
|
this.inscon.getChildAt(i).className = "instruction";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getDates() {
|
||||||
|
let u = `${localize("Last updated")}: ${this.formattedDate(
|
||||||
|
this.recipe.lastModified
|
||||||
|
)}`;
|
||||||
|
let c = `${localize("Created")}: ${this.formattedDate(
|
||||||
|
this.recipe.created
|
||||||
|
)}`;
|
||||||
|
return {
|
||||||
|
u,
|
||||||
|
c,
|
||||||
|
uc: u + "\n" + c,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
// NAVIGATION HANDLERS
|
// NavigationHandlers
|
||||||
editRecipe() {
|
editRecipe() {
|
||||||
this.busy = true;
|
this.busyEdit = 1;
|
||||||
this.$navigateTo(EditRecipe, {
|
this.$navigateTo(EditRecipe, {
|
||||||
props: {
|
props: {
|
||||||
navigationFromView: true,
|
|
||||||
filterTrylater: this.filterTrylater,
|
filterTrylater: this.filterTrylater,
|
||||||
recipeID: this.currentRecipeID,
|
recipeID: this.currentRecipeID,
|
||||||
},
|
},
|
||||||
// backstackVisible: false,
|
animated: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
viewCombination(combination) {
|
viewCombination(combination) {
|
||||||
this.scrollview.scrollToVerticalOffset(0, true);
|
this.scrollview.scrollToVerticalOffset(0, true);
|
||||||
this.recipe = this.recipes.filter((e) => e.id === combination)[0];
|
this.recipe = this.recipes.filter((e) => e.id === combination)[0];
|
||||||
this.showTitleArr = new Array(4).fill(false);
|
this.showTitleArr = new Array(4).fill(0);
|
||||||
this.clearChecks();
|
this.clearChecks();
|
||||||
this.clearSteps();
|
this.clearSteps();
|
||||||
this.recipe.ingredients.forEach(() => this.checks.push(false));
|
this.recipe.ingredients.forEach(() => this.checks.push(0));
|
||||||
this.currentRecipeID = combination;
|
this.currentRecipeID = combination;
|
||||||
this.syncCombinations();
|
this.syncCombinations();
|
||||||
this.createNotes();
|
this.createNotes();
|
||||||
|
@ -681,7 +741,7 @@ export default {
|
||||||
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
|
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
|
||||||
},
|
},
|
||||||
|
|
||||||
// SHARE ACTION
|
// ShareAction
|
||||||
shareHandler() {
|
shareHandler() {
|
||||||
if (this.recipe.image) {
|
if (this.recipe.image) {
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
|
@ -696,7 +756,7 @@ export default {
|
||||||
break;
|
break;
|
||||||
case "pht":
|
case "pht":
|
||||||
ImageSource.fromFile(this.recipe.image).then((res) =>
|
ImageSource.fromFile(this.recipe.image).then((res) =>
|
||||||
utils.shareImage(res, localize("srpu"))
|
utils.shareImage(res, localize("srpu"), this.recipe.title)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -769,7 +829,7 @@ export default {
|
||||||
utils.shareText(shareContent, localize("sru"));
|
utils.shareText(shareContent, localize("sru"));
|
||||||
},
|
},
|
||||||
|
|
||||||
// DATA HANDLERS
|
// DataHandlers
|
||||||
toggle(key: string, setDate: boolean) {
|
toggle(key: string, setDate: boolean) {
|
||||||
this.toggleStateAction({
|
this.toggleStateAction({
|
||||||
id: this.currentRecipeID,
|
id: this.currentRecipeID,
|
||||||
|
@ -787,7 +847,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// SHOPPINGLIST
|
// ShoppingList
|
||||||
toggleCart() {
|
toggleCart() {
|
||||||
if (!this.recipe.inBag) {
|
if (!this.recipe.inBag) {
|
||||||
} else {
|
} else {
|
||||||
|
@ -797,10 +857,10 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// NOTES
|
// Notes
|
||||||
createNote(note) {
|
createNote(note) {
|
||||||
let regex = /(https?:\/\/[^\s]+)/g;
|
let regex = /(https?:\/\/[^\s]+)/g;
|
||||||
const lbl = new Label();
|
const lbl = new RLabel();
|
||||||
lbl.className = "note";
|
lbl.className = "note";
|
||||||
lbl.textWrap = true;
|
lbl.textWrap = true;
|
||||||
let fString = new FormattedString();
|
let fString = new FormattedString();
|
||||||
|
@ -851,7 +911,8 @@ export default {
|
||||||
} else this.$navigateBack();
|
} else this.$navigateBack();
|
||||||
},
|
},
|
||||||
viewPhoto() {
|
viewPhoto() {
|
||||||
this.photoOpen = true;
|
this.hideBars();
|
||||||
|
this.photoOpen = 1;
|
||||||
this.hijackBackEvent();
|
this.hijackBackEvent();
|
||||||
let pv = this.imgView;
|
let pv = this.imgView;
|
||||||
pv.visibility = "visible";
|
pv.visibility = "visible";
|
||||||
|
@ -865,16 +926,16 @@ export default {
|
||||||
pv.animate({
|
pv.animate({
|
||||||
width: sw,
|
width: sw,
|
||||||
height: sw,
|
height: sw,
|
||||||
translate: { x: 112 - sw, y: (sh - sw) / 3 },
|
translate: { x: this.RTL ? -16 : 112 - sw, y: (sh - sw) / 3 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then(() =>
|
.then(() =>
|
||||||
pv.animate({
|
pv.animate({
|
||||||
height: sh,
|
height: sh,
|
||||||
translate: { x: -sw + 112, y: -((sh - sw) / 6) },
|
translate: { x: this.RTL ? -16 : 112 - sw, y: -((sh - sw) / 6) },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -886,8 +947,8 @@ export default {
|
||||||
pv.animate({
|
pv.animate({
|
||||||
width: sw,
|
width: sw,
|
||||||
height: sw,
|
height: sw,
|
||||||
translate: { x: 112 - sw, y: (sh - sw) / 3 },
|
translate: { x: this.RTL ? -16 : 112 - sw, y: (sh - sw) / 3 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
|
@ -895,7 +956,7 @@ export default {
|
||||||
width: 96,
|
width: 96,
|
||||||
height: 96,
|
height: 96,
|
||||||
translate: { x: 0, y: 0 },
|
translate: { x: 0, y: 0 },
|
||||||
duration: 250,
|
duration: 200,
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
curve: CoreTypes.AnimationCurve.ease,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -907,37 +968,162 @@ export default {
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
pv.visibility = "collapsed";
|
pv.visibility = "collapsed";
|
||||||
this.photoOpen = false;
|
this.photoOpen = 0;
|
||||||
this.releaseBackEvent();
|
this.releaseBackEvent();
|
||||||
|
this.showBars();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
navigateBack() {
|
|
||||||
this.photoOpen ? this.closePhoto() : this.$navigateBack();
|
|
||||||
},
|
|
||||||
|
|
||||||
//TIMERS
|
// Timers
|
||||||
openCookingTimer() {
|
openCookingTimer() {
|
||||||
this.$navigateTo(CookingTimer, {
|
this.$navigateTo(CookingTimer, {
|
||||||
props: {
|
props: {
|
||||||
recipeID: this.recipe.id,
|
recipeID: this.recipe.id,
|
||||||
},
|
},
|
||||||
|
animated: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//HELPERS
|
|
||||||
|
//DuplicateRecipe
|
||||||
|
duplicateRecipe() {
|
||||||
|
this.busyDup = 1;
|
||||||
|
let dupRecipe = Object.assign({}, this.recipe);
|
||||||
|
dupRecipe.id = utils.getRandomID(0);
|
||||||
|
dupRecipe.title = dupRecipe.title + " " + localize("cpy");
|
||||||
|
this.$navigateTo(EditRecipe, {
|
||||||
|
props: {
|
||||||
|
dupRecipe,
|
||||||
|
},
|
||||||
|
animated: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Print
|
||||||
|
prepareHTML() {
|
||||||
|
let r = this.recipe;
|
||||||
|
const head = `<head><meta charset=UTF-8><meta content="IE=edge"http-equiv=X-UA-Compatible><meta content="width=device-width,initial-scale=1"name=viewport><title>EnRecipes - Recipe for Print</title><style>a,body,div,html,img,ol,p,span,ul{border:0;font-size:100%;font:inherit;margin:0;padding:0;vertical-align:baseline}@font-face{font-family:Inter-Medium;src:url(../app/fonts/Inter-Medium.otf)}@font-face{font-family:Inter-Bold;src:url(../app/fonts/Inter-Bold.otf)}body{font-family:Inter-Medium,sans-serif;line-height:1.5;max-width:45rem;padding:1.5rem}body>p{padding:.5rem 0}.attr>div>p:last-child,h1,h2{font-family:Inter-Bold,sans-serif}#header{display:grid;grid-column-gap:2rem;grid-template-columns:1fr auto;margin-bottom:2.5rem;width:100%}img{border-radius:1rem;height:8rem;object-fit:cover;width:8rem}h1{font-size:2.25rem;line-height:1.25;margin:0;padding-bottom:1rem}svg{width:2rem;height:2rem;padding:0 .5rem 0 0}h2{margin:2rem 0 1rem}.attr{display:grid;grid-column-gap:2rem;grid-template-columns:1fr 1fr;margin-top:1rem}.attr>div>p:first-child{font-size:.9rem;opacity:.5}ol,ul{padding:0 1.5rem}li{padding:.5rem}a{color:inherit}.sub{font-size:.9rem;margin-top:2rem;opacity:.5}</style></head>`;
|
||||||
|
const getStarRating = () => {
|
||||||
|
let rate = `<svg width="100%" height="100%" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><path d="M10.756 2.826 8.419 7.98l-5.624.63c-.533.06-.982.425-1.147.935-.166.51-.018 1.07.378 1.431l4.179 3.816-1.138 5.543c-.108.525.101 1.065.535 1.38.434.315 1.012.348 1.478.083L12 19.002l4.92 2.796c.466.265 1.044.232 1.478-.083.434-.315.643-.855.535-1.38l-1.138-5.543 4.179-3.816c.396-.361.544-.921.378-1.431-.165-.51-.614-.875-1.147-.935l-5.624-.63-2.337-5.154c-.221-.489-.708-.802-1.244-.802s-1.023.313-1.244.802z"/></svg>`;
|
||||||
|
let unrate = `<svg width="100%" height="100%" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><path d="M10.756 2.826 8.419 7.98l-5.624.63c-.533.06-.982.425-1.147.935-.166.51-.018 1.07.378 1.431l4.179 3.816-1.138 5.543c-.108.525.101 1.065.535 1.38.434.315 1.012.348 1.478.083L12 19.002l4.92 2.796c.466.265 1.044.232 1.478-.083.434-.315.643-.855.535-1.38l-1.138-5.543 4.179-3.816c.396-.361.544-.921.378-1.431-.165-.51-.614-.875-1.147-.935l-5.624-.63-2.337-5.154c-.221-.489-.708-.802-1.244-.802s-1.023.313-1.244.802zM12 4.925l1.994 4.398c.146.321.45.542.8.581l4.799.538-3.567 3.256c-.26.237-.376.594-.305.94l.972 4.73-4.199-2.386c-.306-.174-.682-.174-.988.0l-4.199 2.386.972-4.73c.071-.346-.045-.703-.305-.94l-3.567-3.256 4.799-.538c.35-.039.654-.26.8-.581L12 4.925z"/></svg>`;
|
||||||
|
return rate.repeat(r.rating) + unrate.repeat(5 - r.rating);
|
||||||
|
};
|
||||||
|
const img = r.image ? `<img src="${r.image}" alt="${r.title}" />` : "";
|
||||||
|
const getIngs = () => {
|
||||||
|
let ing = [];
|
||||||
|
r.ingredients.forEach((e) => {
|
||||||
|
ing.push(`<li>${this.getIngredientItem(e)}</li>`);
|
||||||
|
});
|
||||||
|
return ing.join("");
|
||||||
|
};
|
||||||
|
const getIns = () => {
|
||||||
|
let ins = [];
|
||||||
|
r.instructions.forEach((e) => {
|
||||||
|
ins.push(`<li>${e}</li>`);
|
||||||
|
});
|
||||||
|
return ins.join("");
|
||||||
|
};
|
||||||
|
const getCmbs = () => {
|
||||||
|
let cmb = [];
|
||||||
|
r.combinations.forEach((e) => {
|
||||||
|
cmb.push(`<p>${this.getCombinationTitle(e)}</p>`);
|
||||||
|
});
|
||||||
|
return cmb.join("");
|
||||||
|
};
|
||||||
|
const getNotes = () => {
|
||||||
|
let regex = /(https?:\/\/[^\s]+)/g;
|
||||||
|
let n = [];
|
||||||
|
const createSpan = (val, isUrl) => {
|
||||||
|
return isUrl
|
||||||
|
? `<a href="${val}" target="_blank" rel="noopener noreferrer">${val}</a>`
|
||||||
|
: val;
|
||||||
|
};
|
||||||
|
r.notes.forEach((e) => {
|
||||||
|
let arr = e.split(regex);
|
||||||
|
let single = [];
|
||||||
|
arr.forEach((f) => {
|
||||||
|
single.push(createSpan(f, regex.test(f)));
|
||||||
|
});
|
||||||
|
n.push(`<p>${single.join("")}</p>`);
|
||||||
|
});
|
||||||
|
return n.join("");
|
||||||
|
};
|
||||||
|
return `<html dir="${
|
||||||
|
this.RTL ? "rtl" : "ltr"
|
||||||
|
}">${head}<body><div id=header><div class=title><h1>${
|
||||||
|
r.title
|
||||||
|
}</h1><div class=rating>${getStarRating()}</div></div>${img}</div><div class=attr><div><p>${localize(
|
||||||
|
"cui"
|
||||||
|
)}<p>${r.cuisine}</div><div><p>${localize("cat")}<p>${
|
||||||
|
r.category
|
||||||
|
}</div></div>${
|
||||||
|
r.tags.length
|
||||||
|
? `<div class=attr><div style="grid-column:span 2"><p>${localize(
|
||||||
|
"ts"
|
||||||
|
)}<p>${this.getTags(r.tags)}</div></div>`
|
||||||
|
: ""
|
||||||
|
} ${
|
||||||
|
this.hasTime(r.prepTime) || this.hasTime(r.cookTime)
|
||||||
|
? `<div class=attr>${
|
||||||
|
this.hasTime(r.prepTime)
|
||||||
|
? `<div><p>${localize("prepT")}<p>${this.formattedTime(
|
||||||
|
r.prepTime
|
||||||
|
)}</div>`
|
||||||
|
: ""
|
||||||
|
} ${
|
||||||
|
this.hasTime(r.cookTime)
|
||||||
|
? `<div><p>${localize("cookT")}<p>${this.formattedTime(
|
||||||
|
r.cookTime
|
||||||
|
)}</div>`
|
||||||
|
: ""
|
||||||
|
}</div>`
|
||||||
|
: ""
|
||||||
|
}<div class=attr><div><p>${localize("yld")}<p>${
|
||||||
|
this.tempYieldQuantity
|
||||||
|
} ${localize(r.yieldUnit)}</div><div><p>${localize(
|
||||||
|
"Difficulty level"
|
||||||
|
)}<p>${r.difficulty}</div></div>${
|
||||||
|
r.ingredients.length
|
||||||
|
? `<h2>${this.getTitleCount("ings", "ingredients")}</h2>`
|
||||||
|
: ""
|
||||||
|
}<ul>${getIngs()}</ul>${
|
||||||
|
r.instructions.length
|
||||||
|
? `<h2>${this.getTitleCount("inss", "instructions")}</h2>`
|
||||||
|
: ""
|
||||||
|
}<ol>${getIns()}</ol>${
|
||||||
|
r.combinations.length
|
||||||
|
? `<h2>${this.getTitleCount("cmbs", "combinations")}</h2>`
|
||||||
|
: ""
|
||||||
|
} ${getCmbs()} ${
|
||||||
|
r.notes.length ? `<h2>${this.getTitleCount("nos", "notes")}</h2>` : ""
|
||||||
|
} ${getNotes()}<div class=sub><p>${this.getDates().u}<p>${
|
||||||
|
this.getDates().c
|
||||||
|
}</div>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
},
|
||||||
|
printView() {
|
||||||
|
let wv = this.wv as WebView;
|
||||||
|
const fileName = `${this.recipe.title} - ${localize("EnRecipes")}`;
|
||||||
|
wv.src = this.prepareHTML();
|
||||||
|
wv.once("loadFinished", () =>
|
||||||
|
utils.Printer.print(wv, fileName).then(() => (wv.src = null))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helpers
|
||||||
touchYield({ object, action }) {
|
touchYield({ object, action }) {
|
||||||
object.className = action.match(/down|move/)
|
object.className = action.match(/down|move/)
|
||||||
? "value clickable fade"
|
? "value accent fade"
|
||||||
: "value clickable";
|
: "value accent";
|
||||||
if (action == "up") this.changeYield();
|
if (action == "up") this.changeYield();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.recipe = this.recipes.filter((e) => e.id === this.currentRecipeID)[0];
|
this.recipe = this.recipes.filter((e) => e.id === this.currentRecipeID)[0];
|
||||||
this.recipe.ingredients.forEach((e) => this.checks.push(false));
|
this.recipe.ingredients.forEach((e) => this.checks.push(0));
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.yieldMultiplier = this.recipe.yieldQuantity;
|
this.yieldMultiplier = this.yieldQuantity || this.recipe.yieldQuantity;
|
||||||
this.recipe.tried && this.recipe.lastTried && this.showLastTried();
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout
|
<GridLayout
|
||||||
columns="*"
|
columns="*"
|
||||||
:rows="`auto, auto, ${stretch ? '*' : 'auto'}, auto`"
|
:rows="`auto, auto, ${stretch ? '*' : 'auto'}, auto`"
|
||||||
class="modal"
|
class="modal"
|
||||||
>
|
>
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<ListView
|
<ListView
|
||||||
rowHeight="48"
|
rowHeight="48"
|
||||||
row="2"
|
row="2"
|
||||||
|
@ -17,10 +17,9 @@
|
||||||
:height="stretch ? '100%' : listHeight"
|
:height="stretch ? '100%' : listHeight"
|
||||||
>
|
>
|
||||||
<v-template>
|
<v-template>
|
||||||
<Label
|
<RLabel
|
||||||
class="listItem"
|
class="listItem"
|
||||||
:class="{ tb: title === 'srt' && sortType === item }"
|
:class="{ select: item == selected || $index == selected }"
|
||||||
:color="title === 'srt' && sortType === item ? '#ff5200' : ''"
|
|
||||||
:text="`${localized(item)}`"
|
:text="`${localized(item)}`"
|
||||||
@touch="touch"
|
@touch="touch"
|
||||||
@tap="tapAction(item)"
|
@tap="tapAction(item)"
|
||||||
|
@ -28,9 +27,9 @@
|
||||||
/>
|
/>
|
||||||
</v-template>
|
</v-template>
|
||||||
</ListView>
|
</ListView>
|
||||||
<GridLayout row="3" columns="auto, *, auto" class="actions">
|
<RGridLayout :rtl="RTL" row="3" columns="auto, *, auto" class="actions">
|
||||||
<Button
|
<Button
|
||||||
v-if="action"
|
:hidden="!action"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="action | L"
|
:text="action | L"
|
||||||
@tap="$modal.close(action)"
|
@tap="$modal.close(action)"
|
||||||
|
@ -39,9 +38,9 @@
|
||||||
col="2"
|
col="2"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="'cBtn' | L"
|
:text="'cBtn' | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -54,7 +53,7 @@ import Confirm from "./Confirm.vue";
|
||||||
|
|
||||||
interface IData {
|
interface IData {
|
||||||
newList: unknown[];
|
newList: unknown[];
|
||||||
stretch: boolean;
|
stretch: number;
|
||||||
listHeight: number;
|
listHeight: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,26 +71,30 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
selected: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data(): IData {
|
data(): IData {
|
||||||
return {
|
return {
|
||||||
newList: this.list,
|
newList: this.list,
|
||||||
stretch: false,
|
stretch: 0,
|
||||||
listHeight: 0,
|
listHeight: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["sortType", "icon", "appTheme"]),
|
...mapState(["sortType", "icon", "theme", "RTL"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["removeListItemAction"]),
|
...mapActions(["removeListItemAction", "deleteTimerPreset"]),
|
||||||
localized(item: string): string {
|
localized(item: string): string {
|
||||||
return this.title !== "lang" ? localize(item) : item;
|
return this.title !== "lang" ? localize(item) : item;
|
||||||
},
|
},
|
||||||
tapAction(item: string): void {
|
tapAction(item: string): void {
|
||||||
this.$modal.close(item);
|
this.$modal.close(item);
|
||||||
},
|
},
|
||||||
deletionConfirmation(description: string): void {
|
removeConfirmation(description: string): void {
|
||||||
return this.$showModal(Confirm, {
|
return this.$showModal(Confirm, {
|
||||||
props: {
|
props: {
|
||||||
title: "conf",
|
title: "conf",
|
||||||
|
@ -101,13 +104,24 @@ export default {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
deletionConfirmation(description: string): void {
|
||||||
|
return this.$showModal(Confirm, {
|
||||||
|
props: {
|
||||||
|
title: "conf",
|
||||||
|
description,
|
||||||
|
cancelButtonText: "cBtn",
|
||||||
|
okButtonText: "dBtn",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
removeItem(item: string): void {
|
removeItem(item: string): void {
|
||||||
let vm = this;
|
let vm = this;
|
||||||
|
let index = this.newList.findIndex((e) => e === item);
|
||||||
let localizedItem = `"${localize(item)}"`;
|
let localizedItem = `"${localize(item)}"`;
|
||||||
function removeListItem(listName: string, desc: string): void {
|
function removeListItem(listName: string, desc: string): void {
|
||||||
vm.deletionConfirmation(`${localize(desc, localizedItem)}`).then(
|
vm.removeConfirmation(`${localize(desc, localizedItem)}`).then(
|
||||||
(action: boolean) => {
|
(action: boolean) => {
|
||||||
if (action != null && action)
|
if (action)
|
||||||
vm.removeListItemAction({
|
vm.removeListItemAction({
|
||||||
item,
|
item,
|
||||||
listName,
|
listName,
|
||||||
|
@ -115,6 +129,16 @@ export default {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
function deleteTimerPreset(): void {
|
||||||
|
vm.deletionConfirmation(`${localize("delPrst", `"${item}"`)}`).then(
|
||||||
|
(action: boolean) => {
|
||||||
|
if (action) {
|
||||||
|
vm.deleteTimerPreset(index);
|
||||||
|
vm.newList.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
switch (this.title) {
|
switch (this.title) {
|
||||||
case "cui":
|
case "cui":
|
||||||
removeListItem("cuisines", "rmCuiInfo");
|
removeListItem("cuisines", "rmCuiInfo");
|
||||||
|
@ -128,12 +152,18 @@ export default {
|
||||||
case "Unit":
|
case "Unit":
|
||||||
removeListItem("units", "rmUInfo");
|
removeListItem("units", "rmUInfo");
|
||||||
break;
|
break;
|
||||||
|
case "prsts":
|
||||||
|
deleteTimerPreset();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
touch({ object, action }): void {
|
touch({ object, action }): void {
|
||||||
|
let classes = object.className;
|
||||||
object.className = action.match(/down|move/)
|
object.className = action.match(/down|move/)
|
||||||
? "listItem fade"
|
? !classes.includes("fade")
|
||||||
: "listItem";
|
? classes + " fade"
|
||||||
|
: classes
|
||||||
|
: classes.replace(/ fade/g, "");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -145,7 +175,7 @@ export default {
|
||||||
if (modalHeight < usableHeight) {
|
if (modalHeight < usableHeight) {
|
||||||
this.listHeight = listHeight;
|
this.listHeight = listHeight;
|
||||||
} else {
|
} else {
|
||||||
this.stretch = true;
|
this.stretch = 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,20 +2,25 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout columns="*" rows="auto, auto, *, auto" class="modal">
|
<GridLayout columns="*" rows="auto, auto, *, auto" class="modal">
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<StackLayout
|
<StackLayout
|
||||||
row="1"
|
row="1"
|
||||||
v-if="filteredRecipes.length || searchQuery"
|
:hidden="!filteredRecipes.length && !searchQuery"
|
||||||
class="input"
|
class="input"
|
||||||
>
|
>
|
||||||
<TextField class="modalInput" :hint="'ser' | L" v-model="searchQuery" />
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
|
class="modalInput"
|
||||||
|
:hint="'ser' | L"
|
||||||
|
v-model="searchQuery"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<ListView row="2" for="recipe in filteredRecipes">
|
<ListView row="2" for="recipe in filteredRecipes">
|
||||||
<v-template>
|
<v-template>
|
||||||
<Label
|
<RLabel
|
||||||
class="listItem"
|
class="listItem"
|
||||||
:text="recipe.title"
|
:text="recipe.title"
|
||||||
@touch="touch($event, recipe)"
|
@touch="touch($event, recipe)"
|
||||||
|
@ -25,18 +30,18 @@
|
||||||
<Label
|
<Label
|
||||||
row="2"
|
row="2"
|
||||||
class="noResInfo"
|
class="noResInfo"
|
||||||
v-if="!filteredRecipes.length && !searchQuery"
|
:hidden="recipes.length"
|
||||||
:text="'recListEmp' | L"
|
:text="'recListEmp' | L"
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
row="2"
|
row="2"
|
||||||
class="noResInfo"
|
class="noResInfo"
|
||||||
v-if="!filteredRecipes.length && searchQuery"
|
:hidden="filteredRecipes.length || !searchQuery"
|
||||||
:text="'noRecs' | L"
|
:text="'noRecs' | L"
|
||||||
/>
|
/>
|
||||||
<GridLayout row="3" columns="auto, *, auto" class="actions">
|
<RGridLayout :rtl="RTL" row="3" columns="auto, *, auto" class="actions">
|
||||||
<Button
|
<Button
|
||||||
v-if="action"
|
:hidden="!action"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="action | L"
|
:text="action | L"
|
||||||
@tap="$modal.close(action)"
|
@tap="$modal.close(action)"
|
||||||
|
@ -45,9 +50,9 @@
|
||||||
col="2"
|
col="2"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="'cBtn' | L"
|
:text="'cBtn' | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -62,7 +67,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "appTheme"]),
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
filteredRecipes() {
|
filteredRecipes() {
|
||||||
return this.recipes
|
return this.recipes
|
||||||
.map((e, i) => {
|
.map((e, i) => {
|
||||||
|
@ -82,8 +87,8 @@ export default {
|
||||||
tapAction(recipe) {
|
tapAction(recipe) {
|
||||||
this.$modal.close(recipe.id);
|
this.$modal.close(recipe.id);
|
||||||
},
|
},
|
||||||
centerLabel(args) {
|
centerLabel({ object }) {
|
||||||
args.object.android.setGravity(16);
|
object.android.setGravity(16);
|
||||||
},
|
},
|
||||||
recipeFilter(e) {
|
recipeFilter(e) {
|
||||||
let searchQuery = this.searchQuery.toLowerCase();
|
let searchQuery = this.searchQuery.toLowerCase();
|
||||||
|
@ -98,7 +103,7 @@ export default {
|
||||||
touch({ object, action }, recipe) {
|
touch({ object, action }, recipe) {
|
||||||
object.className = action.match(/down|move/)
|
object.className = action.match(/down|move/)
|
||||||
? "listItem fade"
|
? "listItem fade"
|
||||||
: "listItem";
|
: "listItem ";
|
||||||
if (action == "up") this.tapAction(recipe);
|
if (action == "up") this.tapAction(recipe);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,31 +2,31 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout rows="auto, auto, auto" class="modal">
|
<GridLayout rows="auto, auto, auto" class="modal">
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<Label
|
<Label
|
||||||
row="1"
|
row="1"
|
||||||
v-if="description"
|
v-if="description"
|
||||||
class="description tw"
|
class="description tw"
|
||||||
:text="description"
|
:text="description"
|
||||||
/>
|
/>
|
||||||
<GridLayout row="2" columns="*, auto, auto" class="actions">
|
<RGridLayout :rtl="RTL" row="2" columns="*, auto, auto" class="actions">
|
||||||
<Button
|
<Button
|
||||||
v-if="cancelButtonText"
|
v-if="cancelButtonText"
|
||||||
col="1"
|
col="1"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="cancelButtonText | L"
|
:text="cancelButtonText | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="okButtonText | L"
|
:text="okButtonText | L"
|
||||||
@tap="$modal.close(true)"
|
@tap="$modal.close(1)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -53,7 +53,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "appTheme"]),
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
108
app/components/modals/DMYPicker.vue
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<template>
|
||||||
|
<Page
|
||||||
|
@loaded="transparentPage"
|
||||||
|
backgroundColor="transparent"
|
||||||
|
:class="theme"
|
||||||
|
>
|
||||||
|
<GridLayout rows="auto, auto, auto" class="modal">
|
||||||
|
<RLabel class="title" :text="title | L" />
|
||||||
|
<RStackLayout
|
||||||
|
:rtl="RTL"
|
||||||
|
row="1"
|
||||||
|
orientation="horizontal"
|
||||||
|
horizontalAlignment="center"
|
||||||
|
>
|
||||||
|
<ListPicker
|
||||||
|
@loaded="onLPLoad"
|
||||||
|
:items="days"
|
||||||
|
:selectedIndex="dIndex"
|
||||||
|
@selectedIndexChange="setD"
|
||||||
|
></ListPicker>
|
||||||
|
<ListPicker
|
||||||
|
@loaded="onLPLoad"
|
||||||
|
:items="months"
|
||||||
|
:selectedIndex="currentM"
|
||||||
|
@selectedIndexChange="setM"
|
||||||
|
></ListPicker>
|
||||||
|
<ListPicker
|
||||||
|
:items="years"
|
||||||
|
:selectedIndex="yIndex"
|
||||||
|
@selectedIndexChange="setY"
|
||||||
|
></ListPicker>
|
||||||
|
</RStackLayout>
|
||||||
|
<RGridLayout :rtl="RTL" row="2" columns="*, auto, auto" class="actions">
|
||||||
|
<Button
|
||||||
|
col="1"
|
||||||
|
class="text sm"
|
||||||
|
:text="'cBtn' | L"
|
||||||
|
@tap="$modal.close(0)"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
col="2"
|
||||||
|
class="text sm"
|
||||||
|
:text="'SET' | L"
|
||||||
|
@tap="$modal.close(selected)"
|
||||||
|
/>
|
||||||
|
</RGridLayout>
|
||||||
|
</GridLayout>
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import { localize } from "@nativescript/localize";
|
||||||
|
export default {
|
||||||
|
props: ["title", "monthNames", "currentD", "currentM", "currentY"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedD: 0,
|
||||||
|
selectedM: 0,
|
||||||
|
selectedY: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
|
days() {
|
||||||
|
let ld = new Date(this.selectedY, this.selectedM + 1, 0).getDate();
|
||||||
|
return Array.from({ length: ld }, (v, i) => i + 1);
|
||||||
|
},
|
||||||
|
dIndex() {
|
||||||
|
return this.days.indexOf(this.selectedD || this.currentD);
|
||||||
|
},
|
||||||
|
months() {
|
||||||
|
return this.monthNames.map((e) => localize(e));
|
||||||
|
},
|
||||||
|
years() {
|
||||||
|
let min = 1900;
|
||||||
|
let max = min + 200;
|
||||||
|
let years = [];
|
||||||
|
for (let i = min; i <= max; i++) years.push(i);
|
||||||
|
return years;
|
||||||
|
},
|
||||||
|
yIndex() {
|
||||||
|
return this.years.indexOf(this.currentY);
|
||||||
|
},
|
||||||
|
selected() {
|
||||||
|
return {
|
||||||
|
date: this.selectedD,
|
||||||
|
month: this.selectedM,
|
||||||
|
year: this.selectedY,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onLPLoad({ object }) {
|
||||||
|
object.android.setWrapSelectorWheel(true);
|
||||||
|
},
|
||||||
|
setD(args) {
|
||||||
|
this.selectedD = args.object.selectedIndex + 1;
|
||||||
|
},
|
||||||
|
setM(args) {
|
||||||
|
this.selectedM = args.object.selectedIndex;
|
||||||
|
},
|
||||||
|
setY(args) {
|
||||||
|
this.selectedY = this.years[args.object.selectedIndex];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,28 +1,32 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" backgroundColor="transparent" :class="appTheme">
|
<Page @loaded="pgLoad" backgroundColor="transparent" :class="theme">
|
||||||
<GridLayout rows="auto, auto, *, auto" columns="*" class="modal">
|
<GridLayout rows="auto, auto, *, auto" columns="*" class="modal">
|
||||||
<Label class="title" :text="`fltr` | L" />
|
<RLabel class="title a" :text="`fltr` | L" />
|
||||||
<ScrollView orientation="horizontal" row="1" @loaded="onScrollLoad">
|
<ScrollView orientation="horizontal" row="1" @loaded="onScrollLoad">
|
||||||
<StackLayout class="filters" orientation="horizontal">
|
<RStackLayout :rtl="RTL" class="filters" orientation="horizontal">
|
||||||
<GridLayout
|
<GridLayout
|
||||||
rows="48"
|
rows="48"
|
||||||
columns="auto, auto"
|
columns="auto, auto"
|
||||||
class="segment"
|
class="segment rtl"
|
||||||
v-for="(item, index) in pathList"
|
v-for="(item, index) in pathList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{
|
:class="{ select: filterType === item.type }"
|
||||||
select: filterType === item.type,
|
|
||||||
}"
|
|
||||||
@touch="touchSelector($event, item.type)"
|
@touch="touchSelector($event, item.type)"
|
||||||
>
|
>
|
||||||
<Label class="ico" :text="icon[item.type]" />
|
<Label class="ico" :text="icon[item.type]" />
|
||||||
<Label v-if="item.title" class="value" :text="item.title" col="1" />
|
|
||||||
</GridLayout>
|
|
||||||
</StackLayout>
|
|
||||||
</ScrollView>
|
|
||||||
<ListView row="2" class="options-list" for="item in filterList">
|
|
||||||
<v-template>
|
|
||||||
<Label
|
<Label
|
||||||
|
:hidden="!item.title"
|
||||||
|
class="value"
|
||||||
|
:class="{ r: RTL }"
|
||||||
|
:text="item.title"
|
||||||
|
col="1"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
</RStackLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<ListView row="2" class="options" for="item in filterList">
|
||||||
|
<v-template>
|
||||||
|
<RLabel
|
||||||
class="listItem"
|
class="listItem"
|
||||||
verticalAlignment="center"
|
verticalAlignment="center"
|
||||||
col="1"
|
col="1"
|
||||||
|
@ -31,7 +35,12 @@
|
||||||
/>
|
/>
|
||||||
</v-template>
|
</v-template>
|
||||||
</ListView>
|
</ListView>
|
||||||
<GridLayout row="3" columns="auto, *, auto, auto" class="actions">
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
|
row="3"
|
||||||
|
columns="auto, *, auto, auto"
|
||||||
|
class="actions"
|
||||||
|
>
|
||||||
<Button class="text sm" :text="'rest' | L" @tap="resetFilter" />
|
<Button class="text sm" :text="'rest' | L" @tap="resetFilter" />
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
|
@ -45,7 +54,7 @@
|
||||||
:text="'apply' | L"
|
:text="'apply' | L"
|
||||||
@tap="applyFilter"
|
@tap="applyFilter"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -61,7 +70,7 @@ export default {
|
||||||
localCuisine: null,
|
localCuisine: null,
|
||||||
localCategory: null,
|
localCategory: null,
|
||||||
localTag: null,
|
localTag: null,
|
||||||
reset: false,
|
reset: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -70,10 +79,11 @@ export default {
|
||||||
"recipes",
|
"recipes",
|
||||||
"cuisines",
|
"cuisines",
|
||||||
"categories",
|
"categories",
|
||||||
"selectedCuisine",
|
"selCuisine",
|
||||||
"selectedCategory",
|
"selCategory",
|
||||||
"selectedTag",
|
"selTag",
|
||||||
"appTheme",
|
"theme",
|
||||||
|
"RTL",
|
||||||
]),
|
]),
|
||||||
pathList() {
|
pathList() {
|
||||||
let arr = [
|
let arr = [
|
||||||
|
@ -163,18 +173,12 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions([
|
...mapActions(["setCuisine", "setCategory", "setTag", "clearFilter"]),
|
||||||
"setComponent",
|
pgLoad(args) {
|
||||||
"setCuisine",
|
|
||||||
"setCategory",
|
|
||||||
"setTag",
|
|
||||||
"clearFilter",
|
|
||||||
]),
|
|
||||||
onPageLoad(args) {
|
|
||||||
this.transparentPage(args);
|
this.transparentPage(args);
|
||||||
this.localCuisine = this.selectedCuisine;
|
this.localCuisine = this.selCuisine;
|
||||||
this.localCategory = this.selectedCategory;
|
this.localCategory = this.selCategory;
|
||||||
this.localTag = this.selectedTag;
|
this.localTag = this.selTag;
|
||||||
if (this.localCuisine) this.filterType = "category";
|
if (this.localCuisine) this.filterType = "category";
|
||||||
if (this.localCategory && this.localTag) this.filterType = "tag";
|
if (this.localCategory && this.localTag) this.filterType = "tag";
|
||||||
this.scrollToRight();
|
this.scrollToRight();
|
||||||
|
@ -198,14 +202,14 @@ export default {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() =>
|
() =>
|
||||||
this.scrollview.scrollToHorizontalOffset(
|
this.scrollview.scrollToHorizontalOffset(
|
||||||
this.scrollview.scrollableWidth,
|
this.RTL ? 0 : this.scrollview.scrollableWidth,
|
||||||
true
|
true
|
||||||
),
|
),
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
setRecipeFilter(item) {
|
setRecipeFilter(item) {
|
||||||
this.reset = false;
|
this.reset = 0;
|
||||||
switch (this.filterType) {
|
switch (this.filterType) {
|
||||||
case "cuisine":
|
case "cuisine":
|
||||||
this.localCuisine = item;
|
this.localCuisine = item;
|
||||||
|
@ -225,27 +229,26 @@ export default {
|
||||||
this.setCuisine(this.localCuisine);
|
this.setCuisine(this.localCuisine);
|
||||||
this.setCategory(this.localCategory);
|
this.setCategory(this.localCategory);
|
||||||
this.setTag(this.localTag);
|
this.setTag(this.localTag);
|
||||||
this.filterFavourites = this.filterTrylater = false;
|
this.filterFavourites = this.filterTrylater = 0;
|
||||||
if (this.reset) this.setComponent("EnRecipes");
|
this.$modal.close(this.reset);
|
||||||
else this.setComponent("Filtered recipes");
|
|
||||||
this.$modal.close();
|
|
||||||
},
|
},
|
||||||
resetFilter() {
|
resetFilter() {
|
||||||
this.filterType = "cuisine";
|
this.filterType = "cuisine";
|
||||||
this.localCuisine = this.localCategory = this.localTag = null;
|
this.localCuisine = this.localCategory = this.localTag = null;
|
||||||
this.reset = true;
|
this.reset = 1;
|
||||||
},
|
},
|
||||||
touch({ object, action }, item) {
|
touch({ object, action }, item) {
|
||||||
object.className = action.match(/down|move/)
|
object.className = action.match(/down|move/)
|
||||||
? "listItem fade"
|
? "listItem fade"
|
||||||
: "listItem";
|
: "listItem ";
|
||||||
if (action == "up") this.setRecipeFilter(item);
|
if (action == "up") this.setRecipeFilter(item);
|
||||||
},
|
},
|
||||||
touchSelector({ object, action }, type) {
|
touchSelector({ object, action }, type) {
|
||||||
let selected = this.filterType == type;
|
let selected = this.filterType == type;
|
||||||
|
let classes = `segment ${this.RTL ? "rtl" : ""} `;
|
||||||
object.className = action.match(/down|move/)
|
object.className = action.match(/down|move/)
|
||||||
? `segment ${selected ? "select" : "fade"}`
|
? `${classes}${selected ? "select" : "fade"}`
|
||||||
: `segment ${selected && "select"}`;
|
: `${classes}${selected && "select"}`;
|
||||||
if (action == "up") this.setFilterType(type);
|
if (action == "up") this.setFilterType(type);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,24 +2,35 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout rows="auto, auto, auto" class="modal">
|
<GridLayout rows="auto, auto, auto" class="modal">
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<StackLayout row="1" class="input">
|
<StackLayout row="1" class="input">
|
||||||
|
<TextView
|
||||||
|
v-if="type == 'view'"
|
||||||
|
autocorrect="true"
|
||||||
|
autocapitalizationType="sentences"
|
||||||
|
class="modalInput"
|
||||||
|
@loaded="focusField"
|
||||||
|
v-model="text"
|
||||||
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
|
autocapitalizationType="sentences"
|
||||||
|
autocorrect="true"
|
||||||
|
v-else
|
||||||
class="modalInput"
|
class="modalInput"
|
||||||
@loaded="focusField"
|
@loaded="focusField"
|
||||||
v-model="text"
|
v-model="text"
|
||||||
@returnPress="$modal.close(text)"
|
@returnPress="$modal.close(text)"
|
||||||
/>
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<GridLayout row="2" columns="*, auto, auto" class="actions">
|
<RGridLayout :rtl="RTL" row="2" columns="*, auto, auto" class="actions">
|
||||||
<Button
|
<Button
|
||||||
col="1"
|
col="1"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="'cBtn' | L"
|
:text="'cBtn' | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
|
@ -27,7 +38,7 @@
|
||||||
:text="action | L"
|
:text="action | L"
|
||||||
@tap="$modal.close(text)"
|
@tap="$modal.close(text)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -37,20 +48,23 @@ import { Utils } from "@nativescript/core";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "hint", "placeholder", "action"],
|
props: ["title", "type", "hint", "placeholder", "action"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
text: null,
|
text: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "appTheme"]),
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
focusField({ object }) {
|
focusField({ object }) {
|
||||||
|
this.setGravity(object);
|
||||||
let a = this.placeholder;
|
let a = this.placeholder;
|
||||||
typeof a == "number"
|
typeof a == "number"
|
||||||
? (object.keyboardType = "number")
|
? (object.keyboardType = "number")
|
||||||
|
: this.type
|
||||||
|
? ""
|
||||||
: (object.autocapitalizationType = "words");
|
: (object.autocapitalizationType = "words");
|
||||||
object.hint = this.hint;
|
object.hint = this.hint;
|
||||||
object.focus();
|
object.focus();
|
||||||
|
|
|
@ -2,45 +2,43 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout rows="auto, auto, auto" class="modal">
|
<GridLayout rows="auto, auto, auto" class="modal">
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<StackLayout
|
<RStackLayout
|
||||||
|
:rtl="RTL"
|
||||||
row="1"
|
row="1"
|
||||||
class="dialogListPicker"
|
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
horizontalAlignment="center"
|
horizontalAlignment="center"
|
||||||
>
|
>
|
||||||
<ListPicker
|
<ListPicker
|
||||||
@loaded="onLPLoad"
|
@loaded="onLPLoad"
|
||||||
ref="hrPicker"
|
|
||||||
:items="hrsList"
|
:items="hrsList"
|
||||||
:selectedIndex="hrIndex"
|
:selectedIndex="hrIndex"
|
||||||
@selectedIndexChange="setHrs"
|
@selectedIndexChange="setHrs"
|
||||||
></ListPicker>
|
></ListPicker>
|
||||||
<ListPicker
|
<ListPicker
|
||||||
@loaded="onLPLoad"
|
@loaded="onLPLoad"
|
||||||
ref="minPicker"
|
|
||||||
:items="minsList"
|
:items="minsList"
|
||||||
:selectedIndex="minIndex"
|
:selectedIndex="minIndex"
|
||||||
@selectedIndexChange="setMins"
|
@selectedIndexChange="setMins"
|
||||||
></ListPicker>
|
></ListPicker>
|
||||||
</StackLayout>
|
</RStackLayout>
|
||||||
<GridLayout row="2" columns="*, auto, auto" class="actions">
|
<RGridLayout :rtl="RTL" row="2" columns="*, auto, auto" class="actions">
|
||||||
<Button
|
<Button
|
||||||
col="1"
|
col="1"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="'cBtn' | L"
|
:text="'cBtn' | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="action | L"
|
:text="'SET' | L"
|
||||||
@tap="$modal.close(selectedTime)"
|
@tap="$modal.close(selectedTime)"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -49,7 +47,7 @@
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "selectedHr", "selectedMin", "action"],
|
props: ["title", "selectedHr", "selectedMin"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
hrs: [],
|
hrs: [],
|
||||||
|
@ -59,7 +57,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "appTheme"]),
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
hrsList() {
|
hrsList() {
|
||||||
let h = [...Array(24).keys()];
|
let h = [...Array(24).keys()];
|
||||||
this.hrs = h;
|
this.hrs = h;
|
||||||
|
|
|
@ -2,20 +2,25 @@
|
||||||
<Page
|
<Page
|
||||||
@loaded="transparentPage"
|
@loaded="transparentPage"
|
||||||
backgroundColor="transparent"
|
backgroundColor="transparent"
|
||||||
:class="appTheme"
|
:class="theme"
|
||||||
>
|
>
|
||||||
<GridLayout rows="auto, auto, auto" class="modal">
|
<GridLayout rows="auto, auto, auto" class="modal">
|
||||||
<Label class="title" :text="title | L" />
|
<RLabel class="title" :text="title | L" />
|
||||||
<StackLayout row="1">
|
<StackLayout row="1">
|
||||||
<StackLayout class="input">
|
<StackLayout class="input">
|
||||||
<TextField
|
<TextField
|
||||||
|
@loaded="setGravity"
|
||||||
class="modalInput"
|
class="modalInput"
|
||||||
v-model="setLabel"
|
v-model="setLabel"
|
||||||
:hint="label"
|
:hint="label"
|
||||||
autocapitalizationType="words"
|
autocapitalizationType="words"
|
||||||
|
autocorrect="true"
|
||||||
/></StackLayout>
|
/></StackLayout>
|
||||||
<!-- @loaded="focusField" -->
|
<RStackLayout
|
||||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
:rtl="RTL"
|
||||||
|
orientation="horizontal"
|
||||||
|
horizontalAlignment="center"
|
||||||
|
>
|
||||||
<ListPicker
|
<ListPicker
|
||||||
@loaded="onLPLoad"
|
@loaded="onLPLoad"
|
||||||
:items="hrsList"
|
:items="hrsList"
|
||||||
|
@ -31,10 +36,15 @@
|
||||||
:items="secsList"
|
:items="secsList"
|
||||||
@selectedIndexChange="setSec"
|
@selectedIndexChange="setSec"
|
||||||
></ListPicker>
|
></ListPicker>
|
||||||
</StackLayout>
|
</RStackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
||||||
<GridLayout row="2" columns="auto, *, auto, auto" class="actions">
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
|
row="2"
|
||||||
|
columns="auto, *, auto, auto"
|
||||||
|
class="actions r"
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
v-if="showPreset"
|
v-if="showPreset"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
|
@ -45,10 +55,10 @@
|
||||||
col="2"
|
col="2"
|
||||||
class="text sm"
|
class="text sm"
|
||||||
:text="'cBtn' | L"
|
:text="'cBtn' | L"
|
||||||
@tap="$modal.close(false)"
|
@tap="$modal.close(0)"
|
||||||
/>
|
/>
|
||||||
<Button col="3" class="text sm" :text="action | L" @tap="sendRespose" />
|
<Button col="3" class="text sm" :text="action | L" @tap="sendRespose" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
@ -71,7 +81,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "appTheme"]),
|
...mapState(["icon", "theme", "RTL"]),
|
||||||
hrsList() {
|
hrsList() {
|
||||||
let h = [...Array(24).keys()];
|
let h = [...Array(24).keys()];
|
||||||
this.hrs = h;
|
this.hrs = h;
|
||||||
|
|
114
app/components/modals/TimerReminder.vue
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
<template>
|
||||||
|
<Page @loaded="pgLoad" :class="theme" backgroundColor="#ff5200">
|
||||||
|
<GridLayout rows="*, *">
|
||||||
|
<Button
|
||||||
|
class="ico fab"
|
||||||
|
fontSize="128"
|
||||||
|
:width="screenWidth"
|
||||||
|
:height="screenWidth"
|
||||||
|
:text="icon.timer"
|
||||||
|
/>
|
||||||
|
<GridLayout row="1" rows="*, auto" columns="*, auto, *">
|
||||||
|
<ScrollView :class="theme" rowSpan="2" colSpan="3">
|
||||||
|
<StackLayout paddingTop="8">
|
||||||
|
<Timer
|
||||||
|
v-for="timer in timers"
|
||||||
|
:key="timer.id"
|
||||||
|
:timer="timer"
|
||||||
|
:formattedTime="formattedTime"
|
||||||
|
:removeTimer="removeTimer"
|
||||||
|
:togglePause="togglePause"
|
||||||
|
:timerAlert="timerAlert"
|
||||||
|
:showToast="showToast"
|
||||||
|
/>
|
||||||
|
<StackLayout class="listSpace"> </StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</ScrollView>
|
||||||
|
<GridLayout col="1" row="1" class="appbar">
|
||||||
|
<Button
|
||||||
|
class="ico fab"
|
||||||
|
margin="0"
|
||||||
|
:text="icon.x"
|
||||||
|
@tap="removeTimers"
|
||||||
|
col="1"
|
||||||
|
/>
|
||||||
|
</GridLayout>
|
||||||
|
</GridLayout>
|
||||||
|
</GridLayout>
|
||||||
|
</Page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Application, Screen, Device, Color, Utils } from "@nativescript/core";
|
||||||
|
import Timer from "../sub/Timer.vue";
|
||||||
|
import * as utils from "~/shared/utils";
|
||||||
|
import { mapState, mapActions } from "vuex";
|
||||||
|
const windowMgr = android.view.WindowManager;
|
||||||
|
const View = android.view.View as any;
|
||||||
|
const ViewGroup = android.view.ViewGroup;
|
||||||
|
export default {
|
||||||
|
components: { Timer },
|
||||||
|
props: [
|
||||||
|
"formattedTime",
|
||||||
|
"removeTimer",
|
||||||
|
"togglePause",
|
||||||
|
"timerAlert",
|
||||||
|
"showToast",
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
...mapState(["icon", "theme", "activeTimers"]),
|
||||||
|
screenWidth() {
|
||||||
|
return Screen.mainScreen.widthDIPs;
|
||||||
|
},
|
||||||
|
timers() {
|
||||||
|
let timers = this.activeTimers.filter((e) => e.done);
|
||||||
|
if (!timers.length) {
|
||||||
|
this.$modal.close(1);
|
||||||
|
this.isScreenLocked && this.turnOffScreen();
|
||||||
|
}
|
||||||
|
return timers;
|
||||||
|
},
|
||||||
|
sdkv() {
|
||||||
|
return parseInt(Device.sdkVersion);
|
||||||
|
},
|
||||||
|
isScreenLocked() {
|
||||||
|
const keyguardMgr = Utils.ad
|
||||||
|
.getApplicationContext()
|
||||||
|
.getSystemService(android.content.Context.KEYGUARD_SERVICE);
|
||||||
|
return this.sdkv > 21
|
||||||
|
? keyguardMgr.isDeviceLocked()
|
||||||
|
: keyguardMgr.isKeyguardLocked();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(["clearTimerInterval"]),
|
||||||
|
pgLoad({ object }) {
|
||||||
|
let dialog = object._dialogFragment.getDialog();
|
||||||
|
let dialogWindow = dialog.getWindow();
|
||||||
|
let decorView = dialogWindow.getDecorView();
|
||||||
|
dialog.setCancelable(false);
|
||||||
|
if (this.isScreenLocked) {
|
||||||
|
const flags =
|
||||||
|
windowMgr.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||||
|
windowMgr.LayoutParams.FLAG_TURN_SCREEN_ON |
|
||||||
|
windowMgr.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
dialogWindow.addFlags(flags);
|
||||||
|
}
|
||||||
|
utils.setBarColors(dialogWindow, decorView, this.theme);
|
||||||
|
dialogWindow.setStatusBarColor(new Color("#ff5200").android);
|
||||||
|
},
|
||||||
|
removeTimers() {
|
||||||
|
this.timers.forEach((timer) => this.removeTimer(timer.id, 1));
|
||||||
|
this.isScreenLocked && this.turnOffScreen();
|
||||||
|
},
|
||||||
|
turnOffScreen() {
|
||||||
|
const window = Application.android.startActivity.getWindow();
|
||||||
|
const flags =
|
||||||
|
windowMgr.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||||
|
windowMgr.LayoutParams.FLAG_TURN_SCREEN_ON |
|
||||||
|
windowMgr.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
window.clearFlags(flags);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,12 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<ListView
|
<ListView rowSpan="2" colSpan="2" class="options" for="item in items">
|
||||||
rowSpan="2"
|
|
||||||
colSpan="2"
|
|
||||||
class="options-list"
|
|
||||||
for="item in items"
|
|
||||||
>
|
|
||||||
<v-template if="$index == 0">
|
<v-template if="$index == 0">
|
||||||
<Label class="pageTitle" :text="'About' | L" />
|
<Label class="pageTitle" :text="'About' | L" />
|
||||||
</v-template>
|
</v-template>
|
||||||
|
@ -23,20 +18,26 @@
|
||||||
<StackLayout class="listSpace"> </StackLayout>
|
<StackLayout class="listSpace"> </StackLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template>
|
<v-template>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
class="option"
|
class="option"
|
||||||
@touch="touch($event, item.url)"
|
@touch="touch($event, item.url)"
|
||||||
>
|
>
|
||||||
<Label class="ico" :text="icon[item.icon]" />
|
<Label
|
||||||
<Label col="1" :text="item.title | L" />
|
class="ico"
|
||||||
</GridLayout>
|
:class="{ rtl: /help|don/.test(item.icon) }"
|
||||||
|
:text="icon[item.icon]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Label col="1" class="info" :text="item.title | L" />
|
||||||
|
</RGridLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
</ListView>
|
</ListView>
|
||||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
<GridLayout row="1" class="appbar rtl" rows="*" columns="auto, *">
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ import { mapState } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon", "RTL"]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
{},
|
{},
|
||||||
|
@ -69,8 +70,7 @@ export default {
|
||||||
{
|
{
|
||||||
icon: "priv",
|
icon: "priv",
|
||||||
title: "priv",
|
title: "priv",
|
||||||
url:
|
url: "https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md",
|
||||||
"https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "don",
|
icon: "don",
|
||||||
|
@ -95,7 +95,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
},
|
},
|
||||||
// HELPERS
|
// HELPERS
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="Settings" :items="items" :action="navigateTo" />
|
<OptionsList title="Settings" :items="items" :action="navigateTo" />
|
||||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
<GridLayout row="1" class="appbar rtl" rows="*" columns="auto, *">
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Observable } from "@nativescript/core";
|
import { Observable } from "@nativescript/core";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import Interface from "./Interface.vue";
|
import Interface from "./Interface.vue";
|
||||||
import Options from "./Options.vue";
|
import Options from "./Options.vue";
|
||||||
import Database from "./Database.vue";
|
import Database from "./Database.vue";
|
||||||
|
@ -27,30 +27,35 @@ export default {
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "interface",
|
icon: "interface",
|
||||||
|
rtl: 0,
|
||||||
title: "intf",
|
title: "intf",
|
||||||
data: Interface,
|
data: Interface,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "opts",
|
icon: "opts",
|
||||||
|
rtl: 1,
|
||||||
title: "opts",
|
title: "opts",
|
||||||
data: Options,
|
data: Options,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "db",
|
icon: "db",
|
||||||
|
rtl: 0,
|
||||||
title: "db",
|
title: "db",
|
||||||
data: Database,
|
data: Database,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "reset",
|
icon: "reset",
|
||||||
|
rtl: 1,
|
||||||
title: "rest",
|
title: "rest",
|
||||||
data: Reset,
|
data: Reset,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "info",
|
icon: "info",
|
||||||
|
rtl: 0,
|
||||||
title: "About",
|
title: "About",
|
||||||
data: About,
|
data: About,
|
||||||
},
|
},
|
||||||
|
@ -59,22 +64,16 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon", "RTL"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["setComponent"]),
|
pgLoad({ object }) {
|
||||||
onPageLoad({ object }) {
|
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
this.setComponent("Settings");
|
|
||||||
},
|
},
|
||||||
// HELPERS
|
// HELPERS
|
||||||
navigateTo(view) {
|
navigateTo(view) {
|
||||||
this.$navigateTo(view, {
|
this.$navigateTo(view, {
|
||||||
transition: {
|
animated: false,
|
||||||
name: "slide",
|
|
||||||
duration: 200,
|
|
||||||
curve: "easeOut",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="Settings" :items="items" />
|
<OptionsList title="Settings" :items="items" />
|
||||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
<GridLayout row="1" class="appbar rtl" rows="*" columns="auto, *">
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Observable, Device, Application, Utils } from "@nativescript/core";
|
import {
|
||||||
|
Observable,
|
||||||
|
Device,
|
||||||
|
Application,
|
||||||
|
ApplicationSettings,
|
||||||
|
Utils,
|
||||||
|
} from "@nativescript/core";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
import OptionsList from "../sub/OptionsList";
|
import OptionsList from "../sub/OptionsList";
|
||||||
|
@ -20,12 +26,13 @@ import * as utils from "~/shared/utils";
|
||||||
export default {
|
export default {
|
||||||
components: { OptionsList },
|
components: { OptionsList },
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "timerDelay", "timerSound", "timerVibrate"]),
|
...mapState(["icon", "timerDelay", "timerSound", "timerVibrate", "RTL"]),
|
||||||
items() {
|
items() {
|
||||||
let options = [
|
let options = [
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "sound",
|
icon: "sound",
|
||||||
|
rtl: 0,
|
||||||
title: "tmrSnd",
|
title: "tmrSnd",
|
||||||
subTitle: this.timerSound.title,
|
subTitle: this.timerSound.title,
|
||||||
action: this.showSoundsList,
|
action: this.showSoundsList,
|
||||||
|
@ -33,8 +40,9 @@ export default {
|
||||||
{
|
{
|
||||||
type: "switch",
|
type: "switch",
|
||||||
icon: "vibrate",
|
icon: "vibrate",
|
||||||
|
rtl: 0,
|
||||||
title: "tmrvbrt",
|
title: "tmrvbrt",
|
||||||
checked: this.timerVibrate,
|
checked: !!this.timerVibrate,
|
||||||
action: this.toggleTimerVibrate,
|
action: this.toggleTimerVibrate,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -42,6 +50,7 @@ export default {
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "sound",
|
icon: "sound",
|
||||||
|
rtl: 0,
|
||||||
title: "notifSetg",
|
title: "notifSetg",
|
||||||
subTitle: null,
|
subTitle: null,
|
||||||
action: this.openNotificationChannelSettings,
|
action: this.openNotificationChannelSettings,
|
||||||
|
@ -53,39 +62,50 @@ export default {
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "delay",
|
icon: "delay",
|
||||||
|
rtl: 0,
|
||||||
title: "dlyDur",
|
title: "dlyDur",
|
||||||
subTitle: this.timerDelay,
|
subTitle:
|
||||||
|
this.delayList[
|
||||||
|
this.delayList.findIndex((e) => e.n == this.timerDelay)
|
||||||
|
].l,
|
||||||
action: this.showDelayList,
|
action: this.showDelayList,
|
||||||
},
|
},
|
||||||
...list,
|
...list,
|
||||||
{},
|
{},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
delayList() {
|
||||||
methods: {
|
return [
|
||||||
...mapActions([
|
|
||||||
"setTimerDelay",
|
|
||||||
"setTimerSound",
|
|
||||||
"setTimerVibrate",
|
|
||||||
"setComponent",
|
|
||||||
]),
|
|
||||||
onPageLoad({ object }) {
|
|
||||||
object.bindingContext = new Observable();
|
|
||||||
this.setComponent("CTSettings");
|
|
||||||
},
|
|
||||||
showDelayList() {
|
|
||||||
let list = [
|
|
||||||
...Array.from(Array(4), (_, x) => x + 1),
|
...Array.from(Array(4), (_, x) => x + 1),
|
||||||
...Array.from(Array(6), (_, x) => (x + 1) * 5),
|
...Array.from(Array(6), (_, x) => (x + 1) * 5),
|
||||||
].map(
|
].map((e) => {
|
||||||
(e, i) => `${e} ${i == 0 ? localize("minute") : localize("minutes")}`
|
return {
|
||||||
);
|
l: `${this.getLocaleN(e)} ${localize(e > 1 ? "minutes" : "minute")}`,
|
||||||
|
n: e,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(["setTimerDelay", "setTimerSound", "setTimerVibrate"]),
|
||||||
|
pgLoad({ object }) {
|
||||||
|
object.bindingContext = new Observable();
|
||||||
|
ApplicationSettings.setNumber("isTimer", 2);
|
||||||
|
},
|
||||||
|
showDelayList() {
|
||||||
this.$showModal(Action, {
|
this.$showModal(Action, {
|
||||||
props: {
|
props: {
|
||||||
title: "dlyDur",
|
title: "dlyDur",
|
||||||
list,
|
list: this.delayList.map((e) => e.l),
|
||||||
|
selected: this.delayList.findIndex((e) => e.n == this.timerDelay),
|
||||||
},
|
},
|
||||||
}).then((dur) => dur && this.setTimerDelay(dur));
|
}).then(
|
||||||
|
(res) =>
|
||||||
|
res &&
|
||||||
|
this.setTimerDelay(
|
||||||
|
this.delayList[this.delayList.findIndex((e) => e.l == res)].n
|
||||||
|
)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
showSoundsList() {
|
showSoundsList() {
|
||||||
let getTones = utils.getTones();
|
let getTones = utils.getTones();
|
||||||
|
@ -102,7 +122,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
toggleTimerVibrate() {
|
toggleTimerVibrate() {
|
||||||
this.setTimerVibrate(!this.timerVibrate);
|
this.setTimerVibrate(!this.timerVibrate | 0);
|
||||||
},
|
},
|
||||||
openNotificationChannelSettings() {
|
openNotificationChannelSettings() {
|
||||||
const ctx = Application.android.context;
|
const ctx = Application.android.context;
|
||||||
|
|
|
@ -1,28 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="db" :items="items" />
|
<OptionsList title="db" :items="items" />
|
||||||
<GridLayout
|
<GridLayout
|
||||||
v-show="!toast && !progress"
|
:hidden="toast || progress"
|
||||||
|
@loaded="abLoad"
|
||||||
row="1"
|
row="1"
|
||||||
class="appbar"
|
class="appbar rtl"
|
||||||
rows="*"
|
rows="*"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Toast :toast="toast" :action="hideToast" />
|
<Toast :onload="tbLoad" :toast="toast" :action="hideBar" />
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
v-show="progress"
|
v-show="progress"
|
||||||
row="1"
|
row="1"
|
||||||
colSpan="2"
|
colSpan="2"
|
||||||
class="appbar snackBar"
|
class="appbar snackBar rtl"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
>
|
>
|
||||||
<ActivityIndicator :busy="progress ? true : false" />
|
<ActivityIndicator :busy="!!progress" />
|
||||||
<Label col="1" class="title" :text="progress" textWrap="true" />
|
<RLabel col="1" class="title" :text="progress" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -50,9 +52,11 @@ export default {
|
||||||
components: { OptionsList, Toast },
|
components: { OptionsList, Toast },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
backupFolder: null,
|
backupFolder: 0,
|
||||||
progress: null,
|
progress: 0,
|
||||||
toast: null,
|
toast: 0,
|
||||||
|
appbar: 0,
|
||||||
|
toastbar: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -65,6 +69,7 @@ export default {
|
||||||
"units",
|
"units",
|
||||||
"mealPlans",
|
"mealPlans",
|
||||||
"importSummary",
|
"importSummary",
|
||||||
|
"RTL",
|
||||||
]),
|
]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
|
@ -101,13 +106,15 @@ export default {
|
||||||
"importRecipesFromDB",
|
"importRecipesFromDB",
|
||||||
"importMealPlansFromJSON",
|
"importMealPlansFromJSON",
|
||||||
"importMealPlansFromDB",
|
"importMealPlansFromDB",
|
||||||
|
"importTimerPresets",
|
||||||
"unlinkBrokenImages",
|
"unlinkBrokenImages",
|
||||||
"clearImportSummary",
|
"clearImportSummary",
|
||||||
]),
|
]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
const ContentResolver = Application.android.nativeApp.getContentResolver();
|
const ContentResolver =
|
||||||
this.backupFolder = ApplicationSettings.getString("backupFolder");
|
Application.android.nativeApp.getContentResolver();
|
||||||
|
this.backupFolder = ApplicationSettings.getString("backupFolder", null);
|
||||||
if (
|
if (
|
||||||
!this.backupFolder ||
|
!this.backupFolder ||
|
||||||
ContentResolver.getPersistedUriPermissions().isEmpty()
|
ContentResolver.getPersistedUriPermissions().isEmpty()
|
||||||
|
@ -115,22 +122,33 @@ export default {
|
||||||
this.backupFolder = null;
|
this.backupFolder = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// BACKUP FOLDER PICKER
|
abLoad({ object }) {
|
||||||
|
this.appbar = object;
|
||||||
|
},
|
||||||
|
tbLoad({ object }) {
|
||||||
|
this.toastbar = object;
|
||||||
|
},
|
||||||
|
|
||||||
|
// BackupFolderPicker
|
||||||
setBackupFolder(startExport) {
|
setBackupFolder(startExport) {
|
||||||
const ContentResolver = Application.android.nativeApp.getContentResolver();
|
const ContentResolver =
|
||||||
|
Application.android.nativeApp.getContentResolver();
|
||||||
const FLAGS =
|
const FLAGS =
|
||||||
android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION |
|
android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION |
|
||||||
android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
||||||
utils.getBackupFolder().then((uri) => {
|
utils.getBackupFolder().then((uri) => {
|
||||||
|
console.log(uri.toString());
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
if (this.backupFolder)
|
// ReleaseExistingPermissions
|
||||||
|
|
||||||
|
if (this.backupFolder && this.backupFolder != uri.toString())
|
||||||
ContentResolver.releasePersistableUriPermission(
|
ContentResolver.releasePersistableUriPermission(
|
||||||
new android.net.Uri.parse(this.backupFolder),
|
new android.net.Uri.parse(this.backupFolder),
|
||||||
FLAGS
|
FLAGS
|
||||||
);
|
);
|
||||||
this.backupFolder = uri.toString();
|
this.backupFolder = uri.toString();
|
||||||
ApplicationSettings.setString("backupFolder", this.backupFolder);
|
ApplicationSettings.setString("backupFolder", this.backupFolder);
|
||||||
// PERSIST PERMISSIONS
|
// PersistPermissions
|
||||||
ContentResolver.takePersistableUriPermission(uri, FLAGS);
|
ContentResolver.takePersistableUriPermission(uri, FLAGS);
|
||||||
if (startExport && this.backupFolder) {
|
if (startExport && this.backupFolder) {
|
||||||
this.exportBackup();
|
this.exportBackup();
|
||||||
|
@ -141,18 +159,15 @@ export default {
|
||||||
|
|
||||||
// EXPORT HANDLERS
|
// EXPORT HANDLERS
|
||||||
exportCheck() {
|
exportCheck() {
|
||||||
const ContentResolver = Application.android.nativeApp.getContentResolver();
|
const ContentResolver =
|
||||||
if (!this.recipes.length) {
|
Application.android.nativeApp.getContentResolver();
|
||||||
this.toast = localize("aFBu");
|
if (!this.recipes.length) this.showToast(localize("aFBu"));
|
||||||
utils.timer(5, (val) => {
|
else {
|
||||||
if (!val) this.toast = val;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if (
|
if (
|
||||||
!this.backupFolder ||
|
!this.backupFolder ||
|
||||||
ContentResolver.getPersistedUriPermissions().isEmpty()
|
ContentResolver.getPersistedUriPermissions().isEmpty()
|
||||||
) {
|
) {
|
||||||
this.setBackupFolder(true);
|
this.setBackupFolder(1);
|
||||||
} else this.exportBackup();
|
} else this.exportBackup();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -182,7 +197,7 @@ export default {
|
||||||
console.log("Backup error: ", err);
|
console.log("Backup error: ", err);
|
||||||
this.progress = null;
|
this.progress = null;
|
||||||
this.releaseBackEvent();
|
this.releaseBackEvent();
|
||||||
this.setBackupFolder(true);
|
this.setBackupFolder(1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
showExportSummary(filename) {
|
showExportSummary(filename) {
|
||||||
|
@ -248,6 +263,8 @@ export default {
|
||||||
importImages();
|
importImages();
|
||||||
} else if (File.exists(recipes)) {
|
} else if (File.exists(recipes)) {
|
||||||
// IMPORT FROM JSON FILES
|
// IMPORT FROM JSON FILES
|
||||||
|
console.log("import from json");
|
||||||
|
|
||||||
this.isFileDataValid([
|
this.isFileDataValid([
|
||||||
{
|
{
|
||||||
path: recipes,
|
path: recipes,
|
||||||
|
@ -285,9 +302,10 @@ export default {
|
||||||
} else this.failedImport(localize("buInc"));
|
} else this.failedImport(localize("buInc"));
|
||||||
},
|
},
|
||||||
isFileDataValid(file) {
|
isFileDataValid(file) {
|
||||||
|
console.log("isFileDataValid");
|
||||||
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(() => false);
|
let isValid = files.map(() => 0);
|
||||||
files.forEach((file, i) => {
|
files.forEach((file, i) => {
|
||||||
File.fromPath(file.path)
|
File.fromPath(file.path)
|
||||||
.readText()
|
.readText()
|
||||||
|
@ -299,7 +317,7 @@ export default {
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (isValid.every((e) => e === true)) {
|
if (isValid.every((e) => e === 1)) {
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
File.fromPath(file.path)
|
File.fromPath(file.path)
|
||||||
.readText()
|
.readText()
|
||||||
|
@ -328,9 +346,9 @@ export default {
|
||||||
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 0;
|
||||||
}
|
}
|
||||||
return true;
|
return 1;
|
||||||
},
|
},
|
||||||
extractData(recipesDB) {
|
extractData(recipesDB) {
|
||||||
const db = openOrCreate(recipesDB);
|
const db = openOrCreate(recipesDB);
|
||||||
|
@ -356,8 +374,14 @@ export default {
|
||||||
db.select(`SELECT * FROM mealPlans`).then((res) =>
|
db.select(`SELECT * FROM mealPlans`).then((res) =>
|
||||||
this.importMealPlansFromDB(res)
|
this.importMealPlansFromDB(res)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Import timerPresets
|
||||||
|
db.select(`SELECT * FROM timerPresets`).then((res) =>
|
||||||
|
this.importTimerPresets(res)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
importData(data, db) {
|
importData(data, db) {
|
||||||
|
console.log("importing");
|
||||||
switch (db) {
|
switch (db) {
|
||||||
case "recipes":
|
case "recipes":
|
||||||
this.importRecipesFromJSON(data);
|
this.importRecipesFromJSON(data);
|
||||||
|
@ -405,7 +429,6 @@ export default {
|
||||||
File.fromPath(entity._path).remove();
|
File.fromPath(entity._path).remove();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.showImportSummary();
|
this.showImportSummary();
|
||||||
this.unlinkBrokenImages();
|
this.unlinkBrokenImages();
|
||||||
}
|
}
|
||||||
|
@ -447,9 +470,19 @@ export default {
|
||||||
args.cancel = true;
|
args.cancel = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// TOAST
|
||||||
hideToast() {
|
showToast(data) {
|
||||||
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
|
this.toast = data;
|
||||||
|
this.animateBar(this.toastbar, 1);
|
||||||
|
utils.timer(5, (val) => !val && this.hideBar());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hideBar() {
|
||||||
|
this.animateBar(this.toastbar, 0).then(() => {
|
||||||
this.toast = null;
|
this.toast = null;
|
||||||
|
this.animateBar(this.appbar, 1);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="pgLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<RGridLayout :isRtl="RTL" rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="intf" :items="items" />
|
<OptionsList title="intf" :items="items" />
|
||||||
<GridLayout
|
<GridLayout row="1" class="appbar rtl" rows="*" columns="auto, *">
|
||||||
:isRtl="RTL"
|
|
||||||
row="1"
|
|
||||||
class="appbar"
|
|
||||||
rows="*"
|
|
||||||
columns="auto, *"
|
|
||||||
>
|
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</RGridLayout>
|
</RGridLayout>
|
||||||
|
@ -16,18 +10,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { ApplicationSettings, Observable, Frame } from "@nativescript/core";
|
||||||
ApplicationSettings,
|
|
||||||
Observable,
|
|
||||||
Device,
|
|
||||||
Frame,
|
|
||||||
} from "@nativescript/core";
|
|
||||||
import { localize } from "@nativescript/localize";
|
|
||||||
import Action from "../modals/Action";
|
import Action from "../modals/Action";
|
||||||
import Confirm from "../modals/Confirm";
|
|
||||||
import OptionsList from "../sub/OptionsList";
|
import OptionsList from "../sub/OptionsList";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
|
import { localize } from "@nativescript/localize";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { OptionsList },
|
components: { OptionsList },
|
||||||
|
@ -37,29 +25,34 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "language", "appTheme", "layout", "RTL"]),
|
...mapState(["icon", "language", "theme", "layout", "RTL"]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "lang",
|
icon: "lang",
|
||||||
|
rtl: 0,
|
||||||
title: "lang",
|
title: "lang",
|
||||||
subTitle: this.applang,
|
subTitle: localize(this.applang),
|
||||||
action: this.setAppLang,
|
action: this.setAppLang,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "theme",
|
icon: "theme",
|
||||||
|
rtl: 0,
|
||||||
title: "Theme",
|
title: "Theme",
|
||||||
subTitle: ApplicationSettings.getString("appTheme", "sysDef"),
|
subTitle: localize(
|
||||||
|
ApplicationSettings.getString("theme", "sysDef")
|
||||||
|
),
|
||||||
action: this.selectThemes,
|
action: this.selectThemes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "layout",
|
icon: "layout",
|
||||||
|
rtl: 1,
|
||||||
title: "listVM",
|
title: "listVM",
|
||||||
subTitle: this.layout,
|
subTitle: localize(this.layout),
|
||||||
action: this.setLayoutMode,
|
action: this.setLayoutMode,
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
|
@ -93,6 +86,7 @@ export default {
|
||||||
ApplicationSettings.setString("appLocale", locale);
|
ApplicationSettings.setString("appLocale", locale);
|
||||||
utils.updateLocale();
|
utils.updateLocale();
|
||||||
this.setRTL();
|
this.setRTL();
|
||||||
|
Frame.reloadPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -107,9 +101,9 @@ export default {
|
||||||
}).then((action) => {
|
}).then((action) => {
|
||||||
if (
|
if (
|
||||||
action &&
|
action &&
|
||||||
(ApplicationSettings.getString("appTheme") != this.appTheme
|
(ApplicationSettings.getString("theme") != this.theme
|
||||||
? 1
|
? 1
|
||||||
: this.appTheme != action)
|
: this.theme != action)
|
||||||
) {
|
) {
|
||||||
this.setTheme(action);
|
this.setTheme(action);
|
||||||
Frame.reloadPage();
|
Frame.reloadPage();
|
||||||
|
|
|
@ -1,44 +1,80 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="Settings" :items="items" />
|
<OptionsList title="Settings" :items="items" />
|
||||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
<GridLayout row="1" class="appbar rtl" rows="*" columns="auto, *">
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Observable } from "@nativescript/core";
|
import { Observable } from "@nativescript/core";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
|
import Action from "../modals/Action";
|
||||||
import OptionsList from "../sub/OptionsList";
|
import OptionsList from "../sub/OptionsList";
|
||||||
|
import { localize } from "@nativescript/localize";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { OptionsList },
|
components: { OptionsList },
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "mondayFirst"]),
|
...mapState(["icon", "mondayFirst", "RTL", "plannerView", "planDeletion"]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
{},
|
{},
|
||||||
|
{
|
||||||
|
type: "list",
|
||||||
|
icon: "calv",
|
||||||
|
title: "calVM",
|
||||||
|
subTitle: localize(this.plannerView),
|
||||||
|
action: this.selectPlannerView,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "switch",
|
type: "switch",
|
||||||
icon: "week",
|
icon: "week",
|
||||||
title: "swm",
|
title: "swm",
|
||||||
checked: this.mondayFirst,
|
checked: !!this.mondayFirst,
|
||||||
action: this.toggleFirstDay,
|
action: this.toggleFirstDay,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "list",
|
||||||
|
icon: "mpd",
|
||||||
|
title: "admp",
|
||||||
|
subTitle: localize(this.planDeletion),
|
||||||
|
action: this.selectDeletionTime,
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["setFirstDay"]),
|
...mapActions(["setFirstDay", "setPlannerView", "setPlanDeletion"]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
},
|
},
|
||||||
toggleFirstDay() {
|
toggleFirstDay() {
|
||||||
this.setFirstDay(!this.mondayFirst);
|
this.setFirstDay(!this.mondayFirst | 0);
|
||||||
|
},
|
||||||
|
selectPlannerView() {
|
||||||
|
this.$showModal(Action, {
|
||||||
|
props: {
|
||||||
|
title: "calVM",
|
||||||
|
list: ["mnth", "wk", "d"],
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
if (res && this.plannerView != res) this.setPlannerView(res);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectDeletionTime() {
|
||||||
|
this.$showModal(Action, {
|
||||||
|
props: {
|
||||||
|
title: "admp",
|
||||||
|
list: ["otay", "otam", "otaw", "nvr"],
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
if (res && this.planDeletion != res) this.setPlanDeletion(res);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="opts" :items="items" />
|
<OptionsList title="opts" :items="items" />
|
||||||
<GridLayout
|
<GridLayout
|
||||||
v-show="!toast"
|
:hidden="toast"
|
||||||
|
@loaded="abLoad"
|
||||||
row="1"
|
row="1"
|
||||||
class="appbar"
|
class="appbar rtl"
|
||||||
rows="*"
|
rows="*"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Toast :toast="toast" :action="(toast = null)" />
|
<Toast :onload="tbLoad" :toast="toast" :action="hideBar" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -28,11 +29,13 @@ export default {
|
||||||
components: { OptionsList, Toast },
|
components: { OptionsList, Toast },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
appbar: null,
|
||||||
|
toastbar: null,
|
||||||
toast: null,
|
toast: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "shakeEnabled"]),
|
...mapState(["icon", "shake", "RTL"]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
{},
|
{},
|
||||||
|
@ -40,8 +43,8 @@ export default {
|
||||||
type: "switch",
|
type: "switch",
|
||||||
icon: "shuf",
|
icon: "shuf",
|
||||||
title: "sVw",
|
title: "sVw",
|
||||||
subTitle: "sVwInfo",
|
subTitle: localize("sVwInfo"),
|
||||||
checked: this.shakeEnabled,
|
checked: !!this.shake,
|
||||||
action: this.toggleShake,
|
action: this.toggleShake,
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
|
@ -50,19 +53,35 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["setShake"]),
|
...mapActions(["setShake"]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
},
|
},
|
||||||
|
abLoad({ object }) {
|
||||||
|
this.appbar = object;
|
||||||
|
},
|
||||||
|
tbLoad({ object }) {
|
||||||
|
this.toastbar = object;
|
||||||
|
},
|
||||||
|
|
||||||
// SHAKE VIEW RANDOM RECIPE
|
// SHAKE VIEW RANDOM RECIPE
|
||||||
toggleShake() {
|
toggleShake() {
|
||||||
let checked = this.shakeEnabled;
|
let checked = this.shake;
|
||||||
if (checked && !utils.hasAccelerometer()) {
|
if (checked && !utils.hasAccelerometer())
|
||||||
this.toast = localize("noAccSensor");
|
this.showToast(localize("noAccSensor"));
|
||||||
utils.timer(5, (val) => {
|
else this.setShake(!checked | 0);
|
||||||
if (!val) this.toast = val;
|
},
|
||||||
|
showToast(data) {
|
||||||
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
|
this.toast = data;
|
||||||
|
this.animateBar(this.toastbar, 1);
|
||||||
|
utils.timer(5, (val) => !val && this.hideBar());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hideBar() {
|
||||||
|
this.animateBar(this.toastbar, 0).then(() => {
|
||||||
|
this.toast = null;
|
||||||
|
this.animateBar(this.appbar, 1);
|
||||||
});
|
});
|
||||||
} else this.setShake(!checked);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,108 +1,107 @@
|
||||||
<template>
|
<template>
|
||||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
<Page @loaded="pgLoad" actionBarHidden="true">
|
||||||
<GridLayout rows="*, auto" columns="auto, *">
|
<RGridLayout :rtl="RTL" rows="*, auto" columns="auto, *">
|
||||||
<OptionsList title="rest" :items="items" :action="resetListItems" />
|
<OptionsList title="rest" :items="items" :action="resetListItems" />
|
||||||
<GridLayout
|
<GridLayout
|
||||||
:hidden="toast"
|
:hidden="toast"
|
||||||
row="1"
|
row="1"
|
||||||
class="appbar"
|
class="appbar rtl"
|
||||||
@loaded="onAppBarLoad"
|
@loaded="abLoad"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
>
|
>
|
||||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
<Toast :toast="toast" :action="hideToast" />
|
<Toast :onload="tbLoad" :toast="toast" :action="hideToast" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Observable, CoreTypes } from "@nativescript/core";
|
import { Observable } from "@nativescript/core";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
import OptionsList from "../sub/OptionsList";
|
import OptionsList from "../sub/OptionsList";
|
||||||
import Toast from "../sub/Toast";
|
import Toast from "../sub/Toast";
|
||||||
|
let barTimer;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { OptionsList, Toast },
|
components: { OptionsList, Toast },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
toast: null,
|
toast: 0,
|
||||||
appbar: null,
|
appbar: 0,
|
||||||
|
toastbar: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon", "RTL"]),
|
||||||
items() {
|
items() {
|
||||||
return [
|
return [
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "reset",
|
icon: "reset",
|
||||||
|
rtl: 1,
|
||||||
title: "restCuiL",
|
title: "restCuiL",
|
||||||
data: "cuisines",
|
data: "cuisines",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "reset",
|
icon: "reset",
|
||||||
|
rtl: 1,
|
||||||
title: "restCatL",
|
title: "restCatL",
|
||||||
data: "categories",
|
data: "categories",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "reset",
|
icon: "reset",
|
||||||
|
rtl: 1,
|
||||||
title: "restYUL",
|
title: "restYUL",
|
||||||
data: "yieldUnits",
|
data: "yieldUnits",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
icon: "reset",
|
icon: "reset",
|
||||||
|
rtl: 1,
|
||||||
title: "restUL",
|
title: "restUL",
|
||||||
data: "units",
|
data: "units",
|
||||||
},
|
},
|
||||||
{},
|
{
|
||||||
|
type: "info",
|
||||||
|
title: "restInfo",
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["resetListItemsAction"]),
|
...mapActions(["resetListItemsAction"]),
|
||||||
onPageLoad({ object }) {
|
pgLoad({ object }) {
|
||||||
object.bindingContext = new Observable();
|
object.bindingContext = new Observable();
|
||||||
},
|
},
|
||||||
onAppBarLoad({ object }) {
|
abLoad({ object }) {
|
||||||
this.appbar = object;
|
this.appbar = object;
|
||||||
},
|
},
|
||||||
|
tbLoad({ object }) {
|
||||||
|
this.toastbar = object;
|
||||||
|
},
|
||||||
// RESET
|
// RESET
|
||||||
resetListItems(listName) {
|
resetListItems(listName) {
|
||||||
this.resetListItemsAction(listName);
|
this.resetListItemsAction(listName);
|
||||||
this.showToast();
|
this.showToast();
|
||||||
},
|
},
|
||||||
showToast() {
|
showToast() {
|
||||||
|
this.animateBar(this.appbar, 0).then(() => {
|
||||||
this.toast = localize("restDone");
|
this.toast = localize("restDone");
|
||||||
utils.timer(5, (val) => {
|
this.animateBar(this.toastbar, 1);
|
||||||
if (!val) this.toast = val;
|
|
||||||
});
|
});
|
||||||
|
utils.timer(5, (val) => !val && this.hideToast());
|
||||||
},
|
},
|
||||||
hideToast({ object }) {
|
hideToast() {
|
||||||
this.appbar.translateY = 64;
|
this.animateBar(this.toastbar, 0).then(() => {
|
||||||
object
|
|
||||||
.animate({
|
|
||||||
opacity: 0,
|
|
||||||
translate: { x: 0, y: 64 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.showUndo = false;
|
|
||||||
this.toast = null;
|
this.toast = null;
|
||||||
this.appbar.animate({
|
this.animateBar(this.appbar, 1);
|
||||||
translate: { x: 0, y: 0 },
|
|
||||||
duration: 250,
|
|
||||||
curve: CoreTypes.AnimationCurve.ease,
|
|
||||||
});
|
|
||||||
object.opacity = 1;
|
|
||||||
object.translateY = 0;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,42 +1,57 @@
|
||||||
<template>
|
<template>
|
||||||
<ListView colSpan="2" rowSpan="2" class="options-list" for="item in items">
|
<ListView colSpan="2" rowSpan="2" class="options" for="item in items">
|
||||||
<v-template if="$index == 0">
|
<v-template if="$index == 0">
|
||||||
<Label class="pageTitle" :text="title | L" />
|
<Label class="pageTitle" :text="title | L" />
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template if="item.type == 'switch'">
|
<v-template if="item.type == 'switch'">
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="auto, *, auto"
|
columns="auto, *, auto"
|
||||||
class="option"
|
class="option"
|
||||||
@touch="touch($event, item.data, item.action)"
|
@touch="touch($event, item.data, item.action)"
|
||||||
>
|
>
|
||||||
<Label class="ico" :text="icon[item.icon]" />
|
<Label class="ico rtl" :text="icon[item.icon]" />
|
||||||
<StackLayout col="1" verticalAlignment="center">
|
<StackLayout col="1" class="info">
|
||||||
<Label :text="item.title | L" class="info" />
|
<RLabel :text="item.title | L" class="tw" />
|
||||||
<Label v-if="item.subTitle" :text="item.subTitle | L" class="sub" />
|
<RLabel
|
||||||
|
v-if="item.subTitle"
|
||||||
|
:text="item.subTitle | L"
|
||||||
|
class="sub tw"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<Switch
|
<Switch
|
||||||
|
@loaded="swLoad"
|
||||||
isUserInteractionEnabled="false"
|
isUserInteractionEnabled="false"
|
||||||
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
||||||
col="2"
|
col="2"
|
||||||
:checked="item.checked"
|
:checked="item.checked"
|
||||||
/>
|
/>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template if="item.type == 'list'">
|
<v-template if="item.type == 'list'">
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
columns="auto, *"
|
columns="auto, *"
|
||||||
class="option"
|
class="option"
|
||||||
@touch="touch($event, item.data, item.action)"
|
@touch="touch($event, item.data, item.action)"
|
||||||
>
|
>
|
||||||
<Label class="ico" :text="icon[item.icon]" />
|
<Label class="ico" :class="{ rtl: item.rtl }" :text="icon[item.icon]" />
|
||||||
<StackLayout col="1">
|
<StackLayout col="1" class="info">
|
||||||
<Label :text="item.title | L" class="info" />
|
<RLabel :text="item.title | L" class="tw" />
|
||||||
<Label v-if="item.subTitle" :text="item.subTitle" class="sub" />
|
<RLabel
|
||||||
|
:hidden="!item.subTitle"
|
||||||
|
:text="item.subTitle"
|
||||||
|
class="sub tw"
|
||||||
|
/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template if="item.type == 'info'">
|
<v-template if="item.type == 'info'">
|
||||||
<Label class="group-info sub tw" :text="item.title | L" />
|
<Label
|
||||||
|
class="group-info sub tw"
|
||||||
|
:class="{ r: RTL }"
|
||||||
|
:text="item.title | L"
|
||||||
|
/>
|
||||||
</v-template>
|
</v-template>
|
||||||
<v-template>
|
<v-template>
|
||||||
<StackLayout class="listSpace"> </StackLayout>
|
<StackLayout class="listSpace"> </StackLayout>
|
||||||
|
@ -46,13 +61,19 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
|
import * as utils from "~/shared/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "items", "action"],
|
props: ["title", "items", "action"],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon", "RTL"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
swLoad({ object }) {
|
||||||
|
object.android.setRotation(
|
||||||
|
this.RTL && utils.sysRTL() ? 0 : this.RTL || utils.sysRTL() ? 180 : 0
|
||||||
|
);
|
||||||
|
},
|
||||||
touch({ object, action }, data, localAction) {
|
touch({ object, action }, data, localAction) {
|
||||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||||
if (action == "up") localAction ? localAction(data) : this.action(data);
|
if (action == "up") localAction ? localAction(data) : this.action(data);
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
row="1"
|
row="1"
|
||||||
class="appbar snackBar"
|
class="appbar snackBar"
|
||||||
columns="auto, *, auto"
|
columns="auto, *, auto"
|
||||||
@swipe="action"
|
@swipe="action"
|
||||||
|
@loaded="onload"
|
||||||
>
|
>
|
||||||
<Button :text="count" class="ico countdown tb" />
|
<Button @tap="action" :text="count" class="ico countdown tb" />
|
||||||
<Label class="title" col="1" :text="msg | L" />
|
<RLabel @tap="action" class="title" col="1" :text="msg | L" />
|
||||||
<Button class="ico fab" :text="icon.undo" @tap="undo" col="3" />
|
<Button class="ico fab rtl" :text="icon.undo" @tap="undo" col="3" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["count", "msg", "undo", "action"],
|
props: ["count", "msg", "undo", "action", "onload"],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon"]),
|
...mapState(["icon", "RTL"]),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
|
@ -1,193 +1,280 @@
|
||||||
<template>
|
<template>
|
||||||
<GridLayout
|
<RGridLayout
|
||||||
|
:rtl="RTL"
|
||||||
rows="auto, auto"
|
rows="auto, auto"
|
||||||
columns="auto, *, auto, auto, auto"
|
columns="auto, *, auto, auto, auto"
|
||||||
class="singleTimer"
|
class="timer"
|
||||||
>
|
>
|
||||||
<!-- :class="{ blink: done }" -->
|
|
||||||
<Button
|
<Button
|
||||||
class="ico"
|
class="ico min rtl"
|
||||||
:text="done ? icon.ring : timer.isPaused ? icon.start : icon.pause"
|
:text="done ? icon.ring : timer.isPaused ? icon.start : icon.pause"
|
||||||
@tap="!done && toggleProgress()"
|
@tap="!done && toggleProgress()"
|
||||||
/>
|
/>
|
||||||
<StackLayout col="1" class="info" :colSpan="timer.isPaused ? 1 : 2">
|
<StackLayout
|
||||||
<Label :text="timer.label" class="tb title tw" />
|
col="1"
|
||||||
<Label
|
class="info"
|
||||||
@touch="!timer.recipeID && touch($event)"
|
:colSpan="timer.isPaused || !timer.preset ? 1 : 2"
|
||||||
|
>
|
||||||
|
<RLabel :text="timer.label" class="tb title tw a" />
|
||||||
|
<RLabel
|
||||||
|
:hidden="!timer.recipeID && done"
|
||||||
|
@touch="!done && touch($event)"
|
||||||
:text="getRecipeTitle"
|
:text="getRecipeTitle"
|
||||||
class="recipeTitle"
|
class="a"
|
||||||
:class="timer.recipeID ? 'sub' : 'clickable'"
|
:class="timer.recipeID ? 'sub' : 'accent'"
|
||||||
|
/>
|
||||||
|
<RLabel
|
||||||
|
:text="
|
||||||
|
progress == 0
|
||||||
|
? countUp
|
||||||
|
? getCount
|
||||||
|
: formattedTime(timer.time)
|
||||||
|
: getCount
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<Label :text="formattedTime(timer.time)" />
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<Button
|
<Button
|
||||||
col="2"
|
col="2"
|
||||||
class="ico"
|
class="ico rtl"
|
||||||
:hidden="(!timer.isPaused || progress == 0) && !done"
|
:hidden="(!timer.isPaused && timer.preset) || done || countUp"
|
||||||
:text="icon.reset"
|
:text="isReset || timer.preset ? icon.reset : icon.addTo"
|
||||||
@tap="resetTimer"
|
@tap="isReset || timer.preset ? resetTimer() : addPreset()"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="3"
|
col="3"
|
||||||
class="ico"
|
class="ico"
|
||||||
:hidden="timer.preset && !done"
|
@tap="countUp ? addPreset() : addDelay()"
|
||||||
@tap="done ? delay() : addPreset()"
|
:text="countUp ? icon.addTo : icon.delay"
|
||||||
:text="done ? icon.delay : icon.addTo"
|
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
col="4"
|
col="4"
|
||||||
class="ico x"
|
class="ico min"
|
||||||
:text="icon.x"
|
:text="icon.x"
|
||||||
@tap="removeTimerItem(timerIndex, false)"
|
@tap="removeTimer(timer.id, done)"
|
||||||
/>
|
/>
|
||||||
<Progress row="1" colSpan="5" :value="progress" />
|
<Progress @loaded="pLoaded" row="1" colSpan="5" />
|
||||||
</GridLayout>
|
</RGridLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ApplicationSettings, Application } from "@nativescript/core";
|
import { ApplicationSettings } from "@nativescript/core";
|
||||||
import { localize } from "@nativescript/localize";
|
import { localize } from "@nativescript/localize";
|
||||||
import { mapState, mapActions } from "vuex";
|
import { mapState, mapActions } from "vuex";
|
||||||
import ActionWithSearch from "../modals/ActionWithSearch";
|
import ActionWithSearch from "../modals/ActionWithSearch";
|
||||||
|
import ViewRecipe from "../ViewRecipe";
|
||||||
import * as utils from "~/shared/utils";
|
import * as utils from "~/shared/utils";
|
||||||
import { EventBus } from "~/main";
|
import { EvtBus } from "~/main";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
"timer",
|
"timer",
|
||||||
"timerIndex",
|
|
||||||
"formattedTime",
|
"formattedTime",
|
||||||
"removeTimer",
|
"removeTimer",
|
||||||
"addToPreset",
|
|
||||||
"togglePause",
|
"togglePause",
|
||||||
"fireTimer",
|
"timerAlert",
|
||||||
|
"showToast",
|
||||||
],
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
pBar: 0,
|
||||||
|
count: 0,
|
||||||
|
delay: 0,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
timerInt: this.timer.timerInterval,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["icon", "recipes", "timerDelay"]),
|
...mapState(["icon", "recipes", "timerDelay", "timerPresets", "RTL"]),
|
||||||
getRecipeTitle() {
|
getRecipeTitle() {
|
||||||
let { recipeID } = this.timer;
|
let { recipeID } = this.timer;
|
||||||
if (recipeID) {
|
if (recipeID) {
|
||||||
let recipe = this.recipes.filter(
|
let recipe = this.recipes.filter((e) => e.id == this.timer.recipeID)[0];
|
||||||
(e) => e.id === this.timer.recipeID
|
if (recipe) return recipe.title;
|
||||||
)[0];
|
else {
|
||||||
return recipe
|
this.timer.recipeID = null;
|
||||||
? recipe.title
|
return localize("fwr");
|
||||||
: `[ ${this.$options.filters.L("resNF")} ]`;
|
}
|
||||||
} else return localize("fwr");
|
} else return localize("fwr");
|
||||||
},
|
},
|
||||||
done() {
|
done() {
|
||||||
return this.progress >= 100;
|
return this.timer.done;
|
||||||
},
|
},
|
||||||
getTimeInSec() {
|
countUp() {
|
||||||
|
return this.timer.mode == 0;
|
||||||
|
},
|
||||||
|
isReset() {
|
||||||
|
return this.timer.isPaused && this.progress != 0;
|
||||||
|
},
|
||||||
|
getTotalTime() {
|
||||||
|
return this.delay + this.actualTime;
|
||||||
|
},
|
||||||
|
actualTime() {
|
||||||
let t = this.timer.time.split(":");
|
let t = this.timer.time.split(":");
|
||||||
return +t[0] * 60 * 60 + +t[1] * 60 + +t[2];
|
return +t[0] * 60 * 60 + +t[1] * 60 + +t[2];
|
||||||
},
|
},
|
||||||
|
getCount() {
|
||||||
|
let c = this.count;
|
||||||
|
let s = Math.abs(c);
|
||||||
|
return (
|
||||||
|
(c < 0 ? "-" : "") +
|
||||||
|
new Date(s * 1000)
|
||||||
|
.toISOString()
|
||||||
|
.slice(
|
||||||
|
s < 10
|
||||||
|
? 18
|
||||||
|
: s < 60
|
||||||
|
? 17
|
||||||
|
: s < 600
|
||||||
|
? 15
|
||||||
|
: s < 3600
|
||||||
|
? 14
|
||||||
|
: s < 36000
|
||||||
|
? 12
|
||||||
|
: s < 86400
|
||||||
|
? 11
|
||||||
|
: 0,
|
||||||
|
19
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(["removeActiveTimer", "updateActiveTimer", "addTimerPreset"]),
|
...mapActions([
|
||||||
|
"removeActiveTimer",
|
||||||
|
"addTimerPreset",
|
||||||
|
"deleteTimerPreset",
|
||||||
|
"sortActiveTimers",
|
||||||
|
]),
|
||||||
|
pLoaded({ object }) {
|
||||||
|
this.pBar = object.android;
|
||||||
|
this.pBar.setRotation(
|
||||||
|
this.RTL && utils.sysRTL() ? 0 : this.RTL || utils.sysRTL() ? 180 : 0
|
||||||
|
);
|
||||||
|
this.initTimer();
|
||||||
|
},
|
||||||
|
viewRecipe(recipeID) {
|
||||||
|
this.$navigateTo(ViewRecipe, {
|
||||||
|
props: {
|
||||||
|
recipeID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
attachRecipe() {
|
attachRecipe() {
|
||||||
this.$showModal(ActionWithSearch, {
|
this.$showModal(ActionWithSearch, {
|
||||||
props: {
|
props: {
|
||||||
title: "selRec",
|
title: "selRec",
|
||||||
recipes: this.recipes,
|
recipes: this.recipes,
|
||||||
|
action: "aNBtn",
|
||||||
},
|
},
|
||||||
}).then((recipeID) => {
|
}).then((res) => {
|
||||||
|
if (res == "aNBtn") {
|
||||||
|
this.$navigateTo(EditRecipe, {
|
||||||
|
animated: false,
|
||||||
|
});
|
||||||
|
} else if (res) {
|
||||||
let timer = this.timer;
|
let timer = this.timer;
|
||||||
timer.recipeID = recipeID;
|
timer.recipeID = res;
|
||||||
this.updateActiveTimer(timer);
|
this.sortActiveTimers();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setProgress(progress, delay) {
|
setNum(type, val) {
|
||||||
this.progress = progress;
|
ApplicationSettings.setNumber(`${this.timer.id}${type}`, val);
|
||||||
let timer = this.timer;
|
},
|
||||||
if (progress <= 100 && !timer.timerInterval) {
|
setProgress() {
|
||||||
timer.timerInterval = setInterval(() => {
|
this.progress = 100 - (this.count / this.getTotalTime) * 100;
|
||||||
|
this.pBar.setProgress(this.progress, true);
|
||||||
|
},
|
||||||
|
initTimer() {
|
||||||
|
this.resetInterval();
|
||||||
|
this.setProgress();
|
||||||
|
!this.timer.isPaused && this.pBar.setIndeterminate(this.countUp);
|
||||||
|
if (this.progress < 100 || !this.timer.timerInt) {
|
||||||
|
this.timer.timerInt = setInterval(() => {
|
||||||
if (!this.timer.isPaused) {
|
if (!this.timer.isPaused) {
|
||||||
this.progress += 100 / (delay + this.getTimeInSec);
|
this.setNum("c", this.countUp ? this.count++ : --this.count);
|
||||||
ApplicationSettings.setNumber(
|
this.setProgress();
|
||||||
`${this.timer.id}progress`,
|
} else this.resetInterval();
|
||||||
this.progress
|
if (this.progress >= 100 && this.count >= 0) {
|
||||||
);
|
this.timer.done = 1;
|
||||||
}
|
this.timerAlert();
|
||||||
if (this.progress >= 100) {
|
|
||||||
if (progress < 100) this.fireTimer(timer);
|
|
||||||
clearInterval(timer.timerInterval);
|
|
||||||
ApplicationSettings.remove(`${this.timer.id}delay`);
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
this.updateActiveTimer(timer);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetInterval() {
|
resetInterval() {
|
||||||
let timer = this.timer;
|
clearInterval(this.timer.timerInt);
|
||||||
clearInterval(this.timer.timerInterval);
|
this.timer.timerInt = 0;
|
||||||
timer.timerInterval = null;
|
this.pBar.setIndeterminate(false);
|
||||||
this.updateActiveTimer(timer);
|
|
||||||
},
|
},
|
||||||
resetTimer() {
|
resetTimer() {
|
||||||
this.resetInterval();
|
this.count = this.actualTime;
|
||||||
this.togglePause(this.timer, true);
|
this.progress = this.delay = this.timer.done = 0;
|
||||||
ApplicationSettings.remove(`${this.timer.id}delay`);
|
ApplicationSettings.remove(`${this.timer.id}d`);
|
||||||
this.setProgress(0, 0);
|
this.setNum("c", this.count);
|
||||||
ApplicationSettings.setNumber(`${this.timer.id}progress`, 0);
|
this.toggleProgress(1);
|
||||||
this.clearNotification();
|
this.pBar.setProgress(0, true);
|
||||||
},
|
},
|
||||||
clearNotification() {
|
toggleProgress(n) {
|
||||||
Application.android.unregisterBroadcastReceiver("timer" + this.timer.id);
|
this.togglePause(this.timer, n);
|
||||||
utils.TimerNotif.clear(this.timer.id);
|
this.timer.isPaused ? this.resetInterval() : this.initTimer();
|
||||||
},
|
|
||||||
toggleProgress(bool) {
|
|
||||||
this.togglePause(this.timer, bool);
|
|
||||||
this.timer.isPaused
|
|
||||||
? this.resetInterval()
|
|
||||||
: this.setProgress(
|
|
||||||
ApplicationSettings.getNumber(`${this.timer.id}progress`, 0),
|
|
||||||
ApplicationSettings.getNumber(`${this.timer.id}delay`, 0)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
removeTimerItem(index, noUndo) {
|
|
||||||
this.resetInterval();
|
|
||||||
this.removeTimer(this.timer.id, index, noUndo);
|
|
||||||
},
|
},
|
||||||
addPreset() {
|
addPreset() {
|
||||||
|
let exist = this.timerPresets.some((e) => e.id == this.timer.id);
|
||||||
this.timer.preset = 1;
|
this.timer.preset = 1;
|
||||||
this.addToPreset(this.timer);
|
if (this.countUp) {
|
||||||
|
this.timer.time = new Date(this.count * 1000)
|
||||||
|
.toISOString()
|
||||||
|
.substr(11, 8);
|
||||||
|
}
|
||||||
|
let timer = JSON.parse(JSON.stringify(this.timer));
|
||||||
|
let { recipeID, timerInt, isPaused, preset, done, mode, ...presetTimer } =
|
||||||
|
timer;
|
||||||
|
this.addTimerPreset(presetTimer);
|
||||||
|
exist ? this.showToast("prstTU") : this.showToast("aTPrst");
|
||||||
},
|
},
|
||||||
delay() {
|
addDelay() {
|
||||||
let delayInS = this.timerDelay.split(" ")[0] * 60;
|
this.timer.done = 0;
|
||||||
ApplicationSettings.setNumber(`${this.timer.id}delay`, delayInS);
|
let td = this.timerDelay;
|
||||||
let progress = (100 / delayInS) * this.getTimeInSec;
|
let delayDur =
|
||||||
|
this.getLocaleN(td) + " " + localize(td > 1 ? "minutes" : "minute");
|
||||||
|
this.showToast(localize("wDBy", this.timer.label, delayDur));
|
||||||
|
let delay = td * 60;
|
||||||
|
if (this.done) this.delay = delay;
|
||||||
|
else this.delay += delay;
|
||||||
|
if (this.count >= 0) this.count += delay;
|
||||||
|
else this.count = this.delay;
|
||||||
|
this.setNum("d", this.delay);
|
||||||
|
this.setNum("c", this.count);
|
||||||
this.resetInterval();
|
this.resetInterval();
|
||||||
this.setProgress(progress, delayInS);
|
this.initTimer();
|
||||||
this.clearNotification();
|
this.timerAlert();
|
||||||
},
|
},
|
||||||
|
|
||||||
// HELPERS
|
// HELPERS
|
||||||
touch({ object, action }) {
|
touch({ object, action }) {
|
||||||
object.className = action.match(/down|move/)
|
let classes = object.className;
|
||||||
? "recipeTitle clickable fade"
|
classes = action.match(/down|move/)
|
||||||
: "recipeTitle clickable";
|
? !classes.includes("fade")
|
||||||
|
? classes + " fade"
|
||||||
|
: classes
|
||||||
|
: classes.replace(/ fade/g, "");
|
||||||
if (action == "up") this.attachRecipe();
|
if (action == "up") this.attachRecipe();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
created() {
|
||||||
this.setProgress(
|
this.delay = ApplicationSettings.getNumber(`${this.timer.id}d`, 0);
|
||||||
ApplicationSettings.getNumber(`${this.timer.id}progress`, 0),
|
this.count = ApplicationSettings.getNumber(
|
||||||
ApplicationSettings.getNumber(`${this.timer.id}delay`, 0)
|
`${this.timer.id}c`,
|
||||||
|
this.actualTime
|
||||||
);
|
);
|
||||||
EventBus.$on("timer" + this.timer.id, (e) => {
|
let bID = "timer" + this.timer.id;
|
||||||
|
EvtBus.$off(bID);
|
||||||
|
EvtBus.$on(bID, (e) => {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case "stop":
|
|
||||||
this.resetTimer();
|
|
||||||
break;
|
|
||||||
case "delay":
|
case "delay":
|
||||||
this.delay();
|
this.addDelay();
|
||||||
|
break;
|
||||||
|
case "dismiss":
|
||||||
|
this.removeTimer(this.timer.id, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<GridLayout
|
<GridLayout
|
||||||
v-show="toast"
|
:hidden="!toast"
|
||||||
row="1"
|
row="1"
|
||||||
colSpan="2"
|
colSpan="2"
|
||||||
class="appbar snackBar"
|
class="appbar snackBar"
|
||||||
columns="*"
|
columns="*"
|
||||||
@swipe="action"
|
@swipe="action"
|
||||||
|
@tap="action"
|
||||||
|
@loaded="onload"
|
||||||
>
|
>
|
||||||
<FlexboxLayout minHeight="48" alignItems="center">
|
<StackLayout minHeight="48">
|
||||||
<Label class="title msg" :text="toast" />
|
<RLabel class="title msg" :text="toast" />
|
||||||
</FlexboxLayout>
|
</StackLayout>
|
||||||
</GridLayout>
|
</GridLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["toast", "action"],
|
props: ["toast", "action", "onload"],
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
|
@ -290,13 +290,13 @@
|
||||||
"yld": "Ergebnis",
|
"yld": "Ergebnis",
|
||||||
"buto": "Gesichert in %s",
|
"buto": "Gesichert in %s",
|
||||||
"sysDefB": "Systemstandard + schwarz",
|
"sysDefB": "Systemstandard + schwarz",
|
||||||
"tmr": "Eieruhr %s",
|
"tmr": "Kurzzeitwecker %s",
|
||||||
"strtBtn": "START",
|
"strtBtn": "START",
|
||||||
"ntmr": "Neue Eieruhr",
|
"ntmr": "Neuer Kurzzeitwecker",
|
||||||
"timer": "Eieruhr",
|
"timer": "Kurzzeitwecker",
|
||||||
"sec": "s",
|
"sec": "s",
|
||||||
"tmrvbrt": "Eieruhrvibration",
|
"tmrvbrt": "Kurzzeitweckervibration",
|
||||||
"tmrSnd": "Eieruhrton",
|
"tmrSnd": "Kurzzeitweckerton",
|
||||||
"aTPrst": "Zu Voreinstellungen hinzugefügt",
|
"aTPrst": "Zu Voreinstellungen hinzugefügt",
|
||||||
"fwr": "für welches Rezept?",
|
"fwr": "für welches Rezept?",
|
||||||
"prstBtn": "Voreinstellungen",
|
"prstBtn": "Voreinstellungen",
|
||||||
|
@ -308,17 +308,17 @@
|
||||||
"minute": "Minute",
|
"minute": "Minute",
|
||||||
"dlyDur": "Verzögerungsdauer",
|
"dlyDur": "Verzögerungsdauer",
|
||||||
"delay": "Verzögerung",
|
"delay": "Verzögerung",
|
||||||
"tmrRm": "Eieruhr entfernt",
|
"tmrRm": "Kurzzeitwecker entfernt",
|
||||||
"notifSetg": "Benachrichtigungseinstellungen",
|
"notifSetg": "Benachrichtigungseinstellungen",
|
||||||
"delPrst": "Du bist dabei, %s aus den Voreinstellungen zu löschen",
|
"delPrst": "Du bist dabei, %s aus den Voreinstellungen zu löschen",
|
||||||
"prsts": "Voreinstellungen",
|
"prsts": "Voreinstellungen",
|
||||||
"ttv": "Zum Anzeigen tippen",
|
"ttv": "Zum Anzeigen tippen",
|
||||||
"dismissAll": "Alle Eieruhren verwerfen",
|
"dismissAll": "Alle Kurzzeitwecker verwerfen",
|
||||||
"dismiss": "Verwerfen",
|
"dismiss": "Verwerfen",
|
||||||
"texp": "%s Eieruhren abgelaufen",
|
"texp": "%s Kurzzeitwecker abgelaufen",
|
||||||
"wDBy": "%1$s wurde um %2$s verzögert",
|
"wDBy": "%1$s wurde um %2$s verzögert",
|
||||||
"prstTU": "Voreingestellte Zeit aktualisiert",
|
"prstTU": "Voreingestellte Zeit aktualisiert",
|
||||||
"ccwt": "Koche selbstbewusst mit Eieruhren!",
|
"ccwt": "Koche selbstbewusst mit Kurzzeitweckern!",
|
||||||
"gtD": "Zu Datum gehen",
|
"gtD": "Zu Datum gehen",
|
||||||
"random": "Zufällig",
|
"random": "Zufällig",
|
||||||
"oAP": "%1$s laufend, %2$s angehalten",
|
"oAP": "%1$s laufend, %2$s angehalten",
|
||||||
|
@ -333,5 +333,16 @@
|
||||||
"tue": "Dienstag",
|
"tue": "Dienstag",
|
||||||
"mon": "Montag",
|
"mon": "Montag",
|
||||||
"sun": "Sonntag",
|
"sun": "Sonntag",
|
||||||
"calVM": "Modus der Kalenderansicht"
|
"calVM": "Modus der Kalenderansicht",
|
||||||
|
"d": "Tag",
|
||||||
|
"wk": "Woche",
|
||||||
|
"mnth": "Monat",
|
||||||
|
"nvr": "Nie",
|
||||||
|
"otaw": "Älter als eine Woche",
|
||||||
|
"otam": "Älter als ein Monat",
|
||||||
|
"otay": "Älter als ein Jahr",
|
||||||
|
"admp": "Mahlzeitenpläne automatisch löschen",
|
||||||
|
"plsCrt": "Verwende die Plus-Taste, um einen zu erstellen",
|
||||||
|
"ehwmp": "Iss gesund mit Essensplänen!",
|
||||||
|
"selMT": "Mahlzeitentyp auswählen"
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,5 +336,14 @@
|
||||||
"cpy": "copy",
|
"cpy": "copy",
|
||||||
"tdy": "Today",
|
"tdy": "Today",
|
||||||
"tmrw": "Tomorrow",
|
"tmrw": "Tomorrow",
|
||||||
"ystr": "Yesterday"
|
"ystr": "Yesterday",
|
||||||
|
"selMT": "Select meal type",
|
||||||
|
"ehwmp": "Eat healthy with meal plans!",
|
||||||
|
"plsCrt": "Use the plus button to create one",
|
||||||
|
"admp": "Auto-delete meal plans",
|
||||||
|
"otay": "Older than a year",
|
||||||
|
"otam": "Older than a month",
|
||||||
|
"otaw": "Older than a week",
|
||||||
|
"nvr": "Never",
|
||||||
|
"add": "Add"
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,5 +333,16 @@
|
||||||
"mon": "Monday",
|
"mon": "Monday",
|
||||||
"sun": "Sunday",
|
"sun": "Sunday",
|
||||||
"calVM": "Calendar view mode",
|
"calVM": "Calendar view mode",
|
||||||
"oAP": "%1$s ongoing, %2$s paused"
|
"oAP": "%1$s ongoing, %2$s paused",
|
||||||
|
"d": "Day",
|
||||||
|
"wk": "Week",
|
||||||
|
"mnth": "Month",
|
||||||
|
"nvr": "Never",
|
||||||
|
"otaw": "Older than a week",
|
||||||
|
"otam": "Older than a month",
|
||||||
|
"otay": "Older than a year",
|
||||||
|
"admp": "Auto delete meal plans",
|
||||||
|
"plsCrt": "Use the plus button to create one",
|
||||||
|
"ehwmp": "Eat healthy with meal plans!",
|
||||||
|
"selMT": "Select meal type"
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,5 +333,16 @@
|
||||||
"mon": "Monday",
|
"mon": "Monday",
|
||||||
"sun": "Sunday",
|
"sun": "Sunday",
|
||||||
"calVM": "Calendar view mode",
|
"calVM": "Calendar view mode",
|
||||||
"oAP": "%1$s ongoing, %2$s paused"
|
"oAP": "%1$s ongoing, %2$s paused",
|
||||||
|
"d": "Day",
|
||||||
|
"wk": "Week",
|
||||||
|
"mnth": "Month",
|
||||||
|
"nvr": "Never",
|
||||||
|
"otaw": "Older than a week",
|
||||||
|
"otam": "Older than a month",
|
||||||
|
"otay": "Older than a year",
|
||||||
|
"admp": "Auto delete meal plans",
|
||||||
|
"plsCrt": "Use the plus button to create one",
|
||||||
|
"ehwmp": "Eat healthy with meal plans!",
|
||||||
|
"selMT": "Select meal type"
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,14 +312,6 @@
|
||||||
"tmrRm": "Temporizador eliminado",
|
"tmrRm": "Temporizador eliminado",
|
||||||
"delPrst": "Está a punto de eliminar %s de los preajustes",
|
"delPrst": "Está a punto de eliminar %s de los preajustes",
|
||||||
"prsts": "Preselecciones",
|
"prsts": "Preselecciones",
|
||||||
"ttv": "Toca para ver",
|
|
||||||
"dismissAll": "Descartar todos los temporizadores",
|
|
||||||
"dismiss": "Descartar",
|
|
||||||
"texp": "%s temporizadores expirados",
|
|
||||||
"random": "Aleatorio",
|
|
||||||
"ystr": "Ayer",
|
|
||||||
"tmrw": "Mañana",
|
|
||||||
"tdy": "Hoy",
|
|
||||||
"cpy": "copia",
|
"cpy": "copia",
|
||||||
"sat": "sábado",
|
"sat": "sábado",
|
||||||
"fri": "viernes",
|
"fri": "viernes",
|
||||||
|
@ -328,9 +320,10 @@
|
||||||
"tue": "martes",
|
"tue": "martes",
|
||||||
"mon": "lunes",
|
"mon": "lunes",
|
||||||
"sun": "domingo",
|
"sun": "domingo",
|
||||||
"calVM": "Modo de vista del calendario",
|
"d": "Día",
|
||||||
"oAP": "%1$s en curso, %2$s en pausa",
|
"wk": "Semana",
|
||||||
"prstTU": "Hora preestablecida actualizada",
|
"mnth": "Mes",
|
||||||
"ccwt": "¡Cocine con confianza con los temporizadores!",
|
"ystr": "Ayer",
|
||||||
"gtD": "Ir a la fecha"
|
"tmrw": "Mañana",
|
||||||
|
"tdy": "Hoy"
|
||||||
}
|
}
|
||||||
|
|
343
app/i18n/fi.json
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
{
|
||||||
|
"aap": "Liitä valokuva",
|
||||||
|
"About": "Tietoja",
|
||||||
|
"aBtn": "LISÄÄ",
|
||||||
|
"aD": "Valmista!",
|
||||||
|
"addCmbBtn": "LISÄÄ YHDISTELMÄ",
|
||||||
|
"aFBu": "Lisää resepti varmuuskopioinnin suorittamiseen",
|
||||||
|
"aIngBtn": "LISÄÄ AINESOSA",
|
||||||
|
"allCats": "Kaikki luokat",
|
||||||
|
"allCuis": "Kaikki keittiöt",
|
||||||
|
"allTs": "Kaikki tunnisteet",
|
||||||
|
"American": "amerikkalainen",
|
||||||
|
"aNBtn": "LISÄÄ UUSI",
|
||||||
|
"aNoBtn": "LISÄÄ HUOMAUTUS",
|
||||||
|
"app.name": "EnRecipes",
|
||||||
|
"appCrd": "Jaettu EnRecipesin kautta. Lataa se F-Droidista, IzzyOnDroidista tai Play Storesta.",
|
||||||
|
"Appetizers": "Alkupalat",
|
||||||
|
"appInfo": "EnRecipes on avoimen lähdekoodin, yksityisyyden suojaa kunnioittava digitaalinen keittokirja, jonka avulla voit luoda, hallita ja jakaa reseptejäsi",
|
||||||
|
"apply": "KÄYTÄ",
|
||||||
|
"appRst": "Sovelluksen uudelleenkäynnistys vaaditaan",
|
||||||
|
"April": "huhtikuu",
|
||||||
|
"aStpBtn": "",
|
||||||
|
"August": "elokuu",
|
||||||
|
"Barbecue": "Grilli",
|
||||||
|
"Beverages": "Juomat",
|
||||||
|
"Black": "Musta",
|
||||||
|
"Brazilian": "brasilialainen",
|
||||||
|
"Breads": "Leivät",
|
||||||
|
"breakfast": "Aamiainen",
|
||||||
|
"British": "brittiläinen",
|
||||||
|
"buEmp": "Varmuuskopiotiedosto on tyhjä",
|
||||||
|
"buFol": "Varmuuskopioiden hakemisto",
|
||||||
|
"buInc": "Virheellinen tai vioittunut varmuuskopiotiedosto",
|
||||||
|
"buInfo": "Luo ZIP-tiedoston, joka sisältää kaikki tiedot, jotka voidaan tuoda takaisin",
|
||||||
|
"buMod": "Varmuuskopiotiedostoa muutettiin muualla",
|
||||||
|
"cat": "Luokka",
|
||||||
|
"cBtn": "PERUUTA",
|
||||||
|
"Challenging": "Haastava",
|
||||||
|
"Chinese": "kiinalainen",
|
||||||
|
"clove": "kynsi",
|
||||||
|
"cm": "cm",
|
||||||
|
"cmbs": "Yhdistelmät",
|
||||||
|
"conBtn": "JATKA",
|
||||||
|
"conf": "Vahvista",
|
||||||
|
"cookT": "Kypsennysaika",
|
||||||
|
"cPic": "Rajaa kuva",
|
||||||
|
"Created": "Luotu",
|
||||||
|
"cui": "Keittiö",
|
||||||
|
"cup": "cup",
|
||||||
|
"Cup": "Kuppi",
|
||||||
|
"dAgo": "%s päivää sitten",
|
||||||
|
"Danish": "tanskalainen",
|
||||||
|
"Dark": "Tumma",
|
||||||
|
"db": "Tietokanta",
|
||||||
|
"dBtn": "POISTA",
|
||||||
|
"December": "joulukuu",
|
||||||
|
"delRecInfo": "Olet poistamassa reseptiä %s pysyvästi",
|
||||||
|
"delRecsInfo": "Olet poistamassa %s pysyvästi",
|
||||||
|
"Desserts": "Jälkiruoat",
|
||||||
|
"detailed": "Yksityiskohtainen",
|
||||||
|
"Difficulty level": "Vaikeustaso",
|
||||||
|
"dinner": "Illallinen",
|
||||||
|
"disBtn": "HYLKÄÄ",
|
||||||
|
"disc": "Tässä reseptissä on tallentamattomia muutoksia. Mitä haluaisit tehdä?",
|
||||||
|
"donate": "Lahjoita",
|
||||||
|
"dozen": "tusina",
|
||||||
|
"drop": "",
|
||||||
|
"dsp": "",
|
||||||
|
"Easy": "Helppo",
|
||||||
|
"editRec": "Muokkaa resepti",
|
||||||
|
"Egyptian": "egyptiläinen",
|
||||||
|
"English": "englantilainen",
|
||||||
|
"EnRecipes": "EnRecipes",
|
||||||
|
"expBu": "Vie koko varmuuskopio",
|
||||||
|
"expip": "Vienti käynnissä",
|
||||||
|
"expSuc": "",
|
||||||
|
"favourites": "",
|
||||||
|
"February": "helmikuu",
|
||||||
|
"Filipino": "",
|
||||||
|
"Filtered recipes": "Suodatetut reseptit",
|
||||||
|
"fl oz": "",
|
||||||
|
"fltr": "",
|
||||||
|
"Fluid Ounce": "",
|
||||||
|
"French": "ranskalainen",
|
||||||
|
"FRI": "pe",
|
||||||
|
"fsList": "Suosikkireseptisi on lueteltu täällä",
|
||||||
|
"g": "g",
|
||||||
|
"gal": "",
|
||||||
|
"Gallon": "",
|
||||||
|
"German": "saksalainen",
|
||||||
|
"gh": "Näytä GitHub:ssa",
|
||||||
|
"Gram": "gramma",
|
||||||
|
"Greek": "kreikkalainen",
|
||||||
|
"grid": "",
|
||||||
|
"grocery": "Ostoslista",
|
||||||
|
"guide": "Käyttöopas",
|
||||||
|
"Healthy": "Terveellinen",
|
||||||
|
"hr": "t.",
|
||||||
|
"impBu": "Tuo tietoja",
|
||||||
|
"impFail": "Tuonti epäonnistui",
|
||||||
|
"impInfo": "Tukee tämän sovelluksen viemiä täydellisiä varmuuskopioita",
|
||||||
|
"impip": "Tuonti käynnissä",
|
||||||
|
"impSuc": "Tuonti onnistui",
|
||||||
|
"in": "",
|
||||||
|
"Indian": "intialainen",
|
||||||
|
"ings": "Ainekset",
|
||||||
|
"inss": "Ohjeet",
|
||||||
|
"intf": "Käyttöliittymä",
|
||||||
|
"invFile": "Virheellinen tiedosto",
|
||||||
|
"Irish": "irlantilainen",
|
||||||
|
"it": "",
|
||||||
|
"Italian": "",
|
||||||
|
"Jamaican": "",
|
||||||
|
"January": "tammikuu",
|
||||||
|
"Japanese": "japanilainen",
|
||||||
|
"Jewish": "juutalainen",
|
||||||
|
"joinTG": "",
|
||||||
|
"July": "heinäkuu",
|
||||||
|
"June": "kesäkuu",
|
||||||
|
"kEdit": "",
|
||||||
|
"Kenyan": "",
|
||||||
|
"kg": "kg",
|
||||||
|
"Kilogram": "kilogramma",
|
||||||
|
"Korean": "korealainen",
|
||||||
|
"l": "l",
|
||||||
|
"lang": "Kieli",
|
||||||
|
"large": "",
|
||||||
|
"Last updated": "",
|
||||||
|
"lb": "",
|
||||||
|
"leaf": "",
|
||||||
|
"Light": "",
|
||||||
|
"listVM": "",
|
||||||
|
"Litre": "",
|
||||||
|
"Loaf": "",
|
||||||
|
"ltAgo": "",
|
||||||
|
"lunch": "",
|
||||||
|
"mAgo": "",
|
||||||
|
"Main dishes": "",
|
||||||
|
"March": "",
|
||||||
|
"May": "",
|
||||||
|
"Meat": "",
|
||||||
|
"medium": "",
|
||||||
|
"Mexican": "",
|
||||||
|
"mg": "",
|
||||||
|
"Millilitre": "",
|
||||||
|
"min": "",
|
||||||
|
"minimal": "",
|
||||||
|
"ml": "",
|
||||||
|
"Moderate": "",
|
||||||
|
"MON": "",
|
||||||
|
"newCui": "",
|
||||||
|
"Newest first": "",
|
||||||
|
"newRec": "",
|
||||||
|
"newUnit": "",
|
||||||
|
"Nigerian": "",
|
||||||
|
"nLangInfo": "",
|
||||||
|
"nNBtn": "",
|
||||||
|
"no": "",
|
||||||
|
"noAccSensor": "",
|
||||||
|
"noFavs": "",
|
||||||
|
"Noodles": "",
|
||||||
|
"noRecs": "Hakua vastaavia reseptejä ei ole",
|
||||||
|
"noRecsInL": "",
|
||||||
|
"nos": "",
|
||||||
|
"November": "marraskuu",
|
||||||
|
"nwCat": "Uusi luokka",
|
||||||
|
"nwYiU": "",
|
||||||
|
"October": "lokakuu",
|
||||||
|
"OK": "OK",
|
||||||
|
"Oldest first": "",
|
||||||
|
"opts": "Valinnat",
|
||||||
|
"Ounce": "",
|
||||||
|
"oz": "",
|
||||||
|
"Pasta": "",
|
||||||
|
"Patty": "",
|
||||||
|
"photogrid": "",
|
||||||
|
"pht": "Reseptivalokuva",
|
||||||
|
"piece": "pala",
|
||||||
|
"Piece": "Pala",
|
||||||
|
"pinch": "",
|
||||||
|
"planner": "Ateriasuunnittelija",
|
||||||
|
"plsAdd": "Lisää resepti pluspainikkeella",
|
||||||
|
"Portuguese": "portugalilainen",
|
||||||
|
"Poultry": "",
|
||||||
|
"Pound": "",
|
||||||
|
"prepT": "Valmisteluaika",
|
||||||
|
"priv": "Tietosuojakäytäntö",
|
||||||
|
"pt": "",
|
||||||
|
"qt": "",
|
||||||
|
"Quickest first": "",
|
||||||
|
"Rating": "",
|
||||||
|
"rBtn": "POISTA",
|
||||||
|
"rec": "Resepti",
|
||||||
|
"recE": "On jo olemassa:",
|
||||||
|
"recF": "löydettyä reseptiä",
|
||||||
|
"recI": "",
|
||||||
|
"recListEmp": "",
|
||||||
|
"recPic": "Reseptivalokuva",
|
||||||
|
"recRm": "Resepti poistettu",
|
||||||
|
"recs": "reseptiä",
|
||||||
|
"recTitle": "Minun terveellinen reseptini",
|
||||||
|
"recU": "Päivitetty:",
|
||||||
|
"req": "",
|
||||||
|
"resNF": "",
|
||||||
|
"rest": "Nollaa",
|
||||||
|
"restCatL": "",
|
||||||
|
"restCuiL": "",
|
||||||
|
"restDone": "",
|
||||||
|
"restInfo": "",
|
||||||
|
"restUL": "",
|
||||||
|
"restYUL": "",
|
||||||
|
"Rice": "Riisi",
|
||||||
|
"rmCatInfo": "Olet poistamassa %s luokkaluettelosta",
|
||||||
|
"rmCmb": "Yhdistelmä poistettu",
|
||||||
|
"rmCuiInfo": "",
|
||||||
|
"rmIng": "Ainesosa poistettu",
|
||||||
|
"rmIns": "Ohje poistettu",
|
||||||
|
"rmN": "Huomautus poistettu",
|
||||||
|
"rmUInfo": "",
|
||||||
|
"rmYUInfo": "",
|
||||||
|
"Roll": "",
|
||||||
|
"rp": "Poista valokuva",
|
||||||
|
"rst": "UUDELLEENKÄYNNISTÄ",
|
||||||
|
"Russian": "venäläinen",
|
||||||
|
"Salads": "Salaatit",
|
||||||
|
"SAT": "la",
|
||||||
|
"Sauces": "Kastikkeet",
|
||||||
|
"Scottish": "skotlantilainen",
|
||||||
|
"Seafood": "",
|
||||||
|
"selRec": "",
|
||||||
|
"September": "",
|
||||||
|
"ser": "Etsi",
|
||||||
|
"Serving": "",
|
||||||
|
"SET": "ASETA",
|
||||||
|
"Settings": "Asetukset",
|
||||||
|
"shr": "Jaa",
|
||||||
|
"Side dishes": "",
|
||||||
|
"simple": "",
|
||||||
|
"Slowest first": "",
|
||||||
|
"sltd": "",
|
||||||
|
"small": "",
|
||||||
|
"snacks": "",
|
||||||
|
"Soups": "Keitot",
|
||||||
|
"Spanish": "espanjalainen",
|
||||||
|
"Sri Lankan": "srilankalainen",
|
||||||
|
"srpu": "Jaa reseptikuva käyttämällä…",
|
||||||
|
"srt": "Järjestä",
|
||||||
|
"sru": "Jaa resepti käyttämällä…",
|
||||||
|
"stars": "",
|
||||||
|
"stick": "",
|
||||||
|
"stp": "",
|
||||||
|
"strAdd": "",
|
||||||
|
"SUN": "su",
|
||||||
|
"sVw": "Ravista nähdäksesi satunnainen resepti",
|
||||||
|
"sVwInfo": "Auttaa sinua valitsemaan, mitä valmistaa, kun et osaa päättää",
|
||||||
|
"Swedish": "ruotsalainen",
|
||||||
|
"swm": "Aloita viikko maanantaina",
|
||||||
|
"sysDef": "Järjestelmän oletus",
|
||||||
|
"Tablespoon": "",
|
||||||
|
"tbsp": "",
|
||||||
|
"Teaspoon": "",
|
||||||
|
"Thai": "thaimaalainen",
|
||||||
|
"Theme": "Teema",
|
||||||
|
"THU": "to",
|
||||||
|
"title": "Otsikko",
|
||||||
|
"tLInfo": "Reseptit, joita haluat kokeilla myöhemmin, on lueteltu täällä",
|
||||||
|
"today": "tänään",
|
||||||
|
"triedInfo": "Kokeilit tätä reseptiä %s",
|
||||||
|
"trnsl": "Käännä",
|
||||||
|
"trylater": "",
|
||||||
|
"trySer": "ETSI KAIKISTA RESEPTEISTÄ?",
|
||||||
|
"ts": "Tunnisteet",
|
||||||
|
"tsInfo": "",
|
||||||
|
"tsp": "",
|
||||||
|
"TUE": "ti",
|
||||||
|
"Turkish": "",
|
||||||
|
"Undefined": "Määrittelemätön",
|
||||||
|
"unit": "",
|
||||||
|
"Unit": "",
|
||||||
|
"unsaved": "",
|
||||||
|
"untRec": "",
|
||||||
|
"Vegan": "Vegaani",
|
||||||
|
"Vegetarian": "Kasvissyöjä",
|
||||||
|
"Vietnamese": "vietnamilainen",
|
||||||
|
"wAgo": "%s viikkoa sitten",
|
||||||
|
"WED": "ke",
|
||||||
|
"yesterday": "eilen",
|
||||||
|
"yieldQ": "",
|
||||||
|
"yieldU": "",
|
||||||
|
"yld": "",
|
||||||
|
"buto": "",
|
||||||
|
"sysDefB": "Järjestelmän oletusarvo + Musta",
|
||||||
|
"tmr": "Ajastin %s",
|
||||||
|
"stop": "Pysäytä",
|
||||||
|
"ntmr": "Uusi ajastin",
|
||||||
|
"timer": "Keittoajastin",
|
||||||
|
"tmrSnd": "Ajastinääni",
|
||||||
|
"aTPrst": "Lisätty esiasetuksiin",
|
||||||
|
"fwr": "mitä reseptiä varten?",
|
||||||
|
"prstBtn": "ESIASETUKSET",
|
||||||
|
"sec": "s",
|
||||||
|
"dlyDur": "Viiveen kesto",
|
||||||
|
"seconds": "sekuntia",
|
||||||
|
"hours": "tuntia",
|
||||||
|
"minutes": "minuuttia",
|
||||||
|
"hour": "tunti",
|
||||||
|
"minute": "minuutti",
|
||||||
|
"prsts": "Esiasetukset",
|
||||||
|
"texp": "%s ajastinta on vanhentunut",
|
||||||
|
"tmrRm": "Ajastin poistettu",
|
||||||
|
"ccwt": "Keitä luottavaisesti ajastimien avulla!",
|
||||||
|
"gtD": "Siirry päivämäärään",
|
||||||
|
"random": "Satunnainen",
|
||||||
|
"notifSetg": "Ilmoitusasetukset",
|
||||||
|
"prstTU": "Esiasetettu aika päivitetty",
|
||||||
|
"ttv": "Napauta nähdäksesi",
|
||||||
|
"dismissAll": "Hylkää kaikki ajastimet",
|
||||||
|
"dismiss": "Hylkää",
|
||||||
|
"d": "Päivä",
|
||||||
|
"wk": "Viikko",
|
||||||
|
"mnth": "Kuukausi",
|
||||||
|
"ystr": "Eilen",
|
||||||
|
"tmrw": "Huomenna",
|
||||||
|
"tdy": "Tänään",
|
||||||
|
"cpy": "kopio",
|
||||||
|
"sat": "lauantai",
|
||||||
|
"fri": "perjantai",
|
||||||
|
"thu": "torstai",
|
||||||
|
"wed": "keskiviikko",
|
||||||
|
"tue": "tiistai",
|
||||||
|
"mon": "maanantai",
|
||||||
|
"sun": "sunnuntai",
|
||||||
|
"calVM": "Kalenterinäkymätila",
|
||||||
|
"oAP": "%1$s käynnissä, %2$s keskeytetty",
|
||||||
|
"ehwmp": "Syö terveellisesti ateriasuunnitelmien avulla!",
|
||||||
|
"selMT": "Valitse ateriatyyppi",
|
||||||
|
"plsCrt": "Käytä plus-painiketta luodaksesi yhden",
|
||||||
|
"nvr": "Ei koskaan",
|
||||||
|
"otaw": "Viikon jälkeen",
|
||||||
|
"otam": "Kuukauden jälkeen",
|
||||||
|
"otay": "Vuoden jälkeen",
|
||||||
|
"admp": "Poista ateriasuunnitelmat automaattisesti"
|
||||||
|
}
|
|
@ -323,7 +323,7 @@
|
||||||
"random": "Aléatoire",
|
"random": "Aléatoire",
|
||||||
"ystr": "Hier",
|
"ystr": "Hier",
|
||||||
"tmrw": "Demain",
|
"tmrw": "Demain",
|
||||||
"tdy": "Oggi",
|
"tdy": "Aujourd’hui",
|
||||||
"cpy": "copie",
|
"cpy": "copie",
|
||||||
"sat": "samedi",
|
"sat": "samedi",
|
||||||
"fri": "vendredi",
|
"fri": "vendredi",
|
||||||
|
@ -332,6 +332,17 @@
|
||||||
"tue": "mardi",
|
"tue": "mardi",
|
||||||
"mon": "lundi",
|
"mon": "lundi",
|
||||||
"sun": "dimanche",
|
"sun": "dimanche",
|
||||||
|
"d": "Jour",
|
||||||
|
"wk": "Semaine",
|
||||||
|
"mnth": "Mois",
|
||||||
"calVM": "Mode d’affichage du calendrier",
|
"calVM": "Mode d’affichage du calendrier",
|
||||||
"oAP": "%1$s en cours, %2$s en pause"
|
"oAP": "%1$s en cours, %2$s en pause",
|
||||||
|
"otaw": "Après une semaine",
|
||||||
|
"otam": "Après un mois",
|
||||||
|
"otay": "Après un an",
|
||||||
|
"admp": "Supprimer automatiquement les planifications de repas",
|
||||||
|
"nvr": "Jamais",
|
||||||
|
"plsCrt": "Utilisez le bouton plus pour en créer une",
|
||||||
|
"ehwmp": "Mangez sainement grâce aux planifications de repas !",
|
||||||
|
"selMT": "Sélectionnez le type de repas"
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,9 +321,9 @@
|
||||||
"ccwt": "Cuisinez avec confiance avec des minuteries!",
|
"ccwt": "Cuisinez avec confiance avec des minuteries!",
|
||||||
"gtD": "Aller à la date",
|
"gtD": "Aller à la date",
|
||||||
"random": "Aléatoire",
|
"random": "Aléatoire",
|
||||||
"tdy": "Aujourd’hui",
|
|
||||||
"ystr": "Hier",
|
"ystr": "Hier",
|
||||||
"tmrw": "Demain",
|
"tmrw": "Demain",
|
||||||
|
"tdy": "Aujourd’hui",
|
||||||
"cpy": "copie",
|
"cpy": "copie",
|
||||||
"sat": "samedi",
|
"sat": "samedi",
|
||||||
"fri": "vendredi",
|
"fri": "vendredi",
|
||||||
|
@ -332,6 +332,17 @@
|
||||||
"tue": "mardi",
|
"tue": "mardi",
|
||||||
"mon": "lundi",
|
"mon": "lundi",
|
||||||
"sun": "dimanche",
|
"sun": "dimanche",
|
||||||
|
"d": "Jour",
|
||||||
|
"wk": "Semaine",
|
||||||
|
"mnth": "Mois",
|
||||||
"calVM": "Mode d’affichage du calendrier",
|
"calVM": "Mode d’affichage du calendrier",
|
||||||
"oAP": "%1$s en cours, %2$s en pause"
|
"oAP": "%1$s en cours, %2$s en pause",
|
||||||
|
"otaw": "Après une semaine",
|
||||||
|
"otam": "Après un mois",
|
||||||
|
"otay": "Après un an",
|
||||||
|
"admp": "Supprimer automatiquement les planifications de repas",
|
||||||
|
"nvr": "Jamais",
|
||||||
|
"plsCrt": "Utilisez le bouton plus pour en créer une",
|
||||||
|
"ehwmp": "Mangez sainement grâce aux planifications de repas!",
|
||||||
|
"selMT": "Sélectionnez le type de repas"
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@
|
||||||
"random": "Aléatoire",
|
"random": "Aléatoire",
|
||||||
"ystr": "Hier",
|
"ystr": "Hier",
|
||||||
"tmrw": "Demain",
|
"tmrw": "Demain",
|
||||||
"tdy": "Oggi",
|
"tdy": "Aujourd’hui",
|
||||||
"cpy": "copie",
|
"cpy": "copie",
|
||||||
"sat": "samedi",
|
"sat": "samedi",
|
||||||
"fri": "vendredi",
|
"fri": "vendredi",
|
||||||
|
@ -332,6 +332,17 @@
|
||||||
"tue": "mardi",
|
"tue": "mardi",
|
||||||
"mon": "lundi",
|
"mon": "lundi",
|
||||||
"sun": "dimanche",
|
"sun": "dimanche",
|
||||||
|
"d": "Jour",
|
||||||
|
"wk": "Semaine",
|
||||||
|
"mnth": "Mois",
|
||||||
"calVM": "Mode d’affichage du calendrier",
|
"calVM": "Mode d’affichage du calendrier",
|
||||||
"oAP": "%1$s en cours, %2$s en pause"
|
"oAP": "%1$s en cours, %2$s en pause",
|
||||||
|
"nvr": "Jamais",
|
||||||
|
"otaw": "Après une semaine",
|
||||||
|
"otam": "Après un mois",
|
||||||
|
"otay": "Après un an",
|
||||||
|
"admp": "Supprimer automatiquement les planifications de repas",
|
||||||
|
"plsCrt": "Utilisez le bouton plus pour en créer une",
|
||||||
|
"ehwmp": "Mangez sainement grâce aux planifications de repas!",
|
||||||
|
"selMT": "Sélectionnez le type de repas"
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,9 +321,9 @@
|
||||||
"ccwt": "Cuisinez avec confiance avec des minuteries !",
|
"ccwt": "Cuisinez avec confiance avec des minuteries !",
|
||||||
"gtD": "Aller à la date",
|
"gtD": "Aller à la date",
|
||||||
"random": "Aléatoire",
|
"random": "Aléatoire",
|
||||||
"tdy": "Aujourd’hui",
|
|
||||||
"ystr": "Hier",
|
"ystr": "Hier",
|
||||||
"tmrw": "Demain",
|
"tmrw": "Demain",
|
||||||
|
"tdy": "Aujourd’hui",
|
||||||
"cpy": "copie",
|
"cpy": "copie",
|
||||||
"sat": "samedi",
|
"sat": "samedi",
|
||||||
"fri": "vendredi",
|
"fri": "vendredi",
|
||||||
|
@ -332,6 +332,17 @@
|
||||||
"tue": "mardi",
|
"tue": "mardi",
|
||||||
"mon": "lundi",
|
"mon": "lundi",
|
||||||
"sun": "dimanche",
|
"sun": "dimanche",
|
||||||
|
"d": "Jour",
|
||||||
|
"wk": "Semaine",
|
||||||
|
"mnth": "Mois",
|
||||||
"calVM": "Mode d’affichage du calendrier",
|
"calVM": "Mode d’affichage du calendrier",
|
||||||
"oAP": "%1$s en cours, %2$s en pause"
|
"oAP": "%1$s en cours, %2$s en pause",
|
||||||
|
"otaw": "Après une semaine",
|
||||||
|
"otam": "Après un mois",
|
||||||
|
"otay": "Après un an",
|
||||||
|
"admp": "Supprimer automatiquement les planifications de repas",
|
||||||
|
"nvr": "Jamais",
|
||||||
|
"plsCrt": "Utilisez le bouton plus pour en créer une",
|
||||||
|
"ehwmp": "Mangez sainement grâce aux planifications de repas !",
|
||||||
|
"selMT": "Sélectionnez le type de repas"
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,6 +332,17 @@
|
||||||
"tue": "martedì",
|
"tue": "martedì",
|
||||||
"mon": "lunedì",
|
"mon": "lunedì",
|
||||||
"sun": "domenica",
|
"sun": "domenica",
|
||||||
|
"d": "Giorno",
|
||||||
|
"wk": "Settimana",
|
||||||
|
"mnth": "Mese",
|
||||||
"calVM": "Modalità di visualizzazione calendario",
|
"calVM": "Modalità di visualizzazione calendario",
|
||||||
"oAP": "%1$s in corso, %2$s in pausa"
|
"oAP": "%1$s in corso, %2$s in pausa",
|
||||||
|
"otaw": "Dopo una settimana",
|
||||||
|
"otam": "Dopo un mese",
|
||||||
|
"otay": "Dopo un anno",
|
||||||
|
"nvr": "Mai",
|
||||||
|
"admp": "Elimina automaticamente i piani pasto",
|
||||||
|
"plsCrt": "Usa il pulsante più per crearne uno",
|
||||||
|
"ehwmp": "Mangia sano con i piani dei pasti!",
|
||||||
|
"selMT": "Seleziona il tipo di pasto"
|
||||||
}
|
}
|
||||||
|
|
293
app/i18n/ja.json
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
{
|
||||||
|
"aap": "写真を添付",
|
||||||
|
"About": "アプリについて",
|
||||||
|
"aBtn": "追加",
|
||||||
|
"aD": "完了しました!",
|
||||||
|
"addCmbBtn": "組合せを追加",
|
||||||
|
"aFBu": "バックアップするにはレシピを登録してください",
|
||||||
|
"aIngBtn": "材料を追加",
|
||||||
|
"allCats": "全てのカテゴリー",
|
||||||
|
"allCuis": "全てのジャンル",
|
||||||
|
"allTs": "全てのタグ",
|
||||||
|
"American": "アメリカ料理",
|
||||||
|
"aNBtn": "新しく追加",
|
||||||
|
"aNoBtn": "メモを追加",
|
||||||
|
"app.name": "EnRecipes",
|
||||||
|
"appCrd": "EnRecipesから共有されました。F-DroidかIzzyOnDroidかPlayストアからダウンロード出来ます。",
|
||||||
|
"Appetizers": "前菜",
|
||||||
|
"appInfo": "EnRecipesはレシピを作成・管理・共有することができる、オープンソースでプライバシーに配慮したデジタル料理本です",
|
||||||
|
"apply": "適用する",
|
||||||
|
"appRst": "アプリの再起動が必要",
|
||||||
|
"April": "4月",
|
||||||
|
"aStpBtn": "手順を追加",
|
||||||
|
"August": "8月",
|
||||||
|
"Barbecue": "キャンプ料理",
|
||||||
|
"Beverages": "飲物",
|
||||||
|
"Black": "黒",
|
||||||
|
"Brazilian": "ブラジル料理",
|
||||||
|
"Breads": "パン",
|
||||||
|
"breakfast": "朝食",
|
||||||
|
"British": "イギリス料理",
|
||||||
|
"buEmp": "バックアップファイルが空です",
|
||||||
|
"buFol": "バックアップフォルダー",
|
||||||
|
"buInc": "バックアップファイルが壊れています",
|
||||||
|
"buInfo": "全てのデータを復元するためのZIPファイルを生成します",
|
||||||
|
"buMod": "バックアップファイルが一部修正されています",
|
||||||
|
"cat": "カテゴリー",
|
||||||
|
"cBtn": "キャンセル",
|
||||||
|
"Challenging": "難しい",
|
||||||
|
"Chinese": "中華料理",
|
||||||
|
"clove": "クローブ",
|
||||||
|
"cm": "cm",
|
||||||
|
"cmbs": "組合せ",
|
||||||
|
"conBtn": "続ける",
|
||||||
|
"conf": "確認",
|
||||||
|
"cookT": "調理時間",
|
||||||
|
"cPic": "写真を切り抜く",
|
||||||
|
"Created": "作成日時",
|
||||||
|
"cui": "ジャンル",
|
||||||
|
"cup": "カップ",
|
||||||
|
"Cup": "カップ",
|
||||||
|
"dAgo": "%s 日前",
|
||||||
|
"Danish": "デンマーク料理",
|
||||||
|
"Dark": "ダーク",
|
||||||
|
"db": "データベース",
|
||||||
|
"dBtn": "削除",
|
||||||
|
"December": "12月",
|
||||||
|
"delRecInfo": "レシピ %s を削除しようとしています",
|
||||||
|
"delRecsInfo": "%s 件のレシピを削除しようとしています",
|
||||||
|
"Desserts": "デザート",
|
||||||
|
"detailed": "詳細",
|
||||||
|
"Difficulty level": "難易度",
|
||||||
|
"dinner": "夕食",
|
||||||
|
"disBtn": "破棄",
|
||||||
|
"disc": "レシピの変更が保存されていません。どうしますか?",
|
||||||
|
"donate": "寄付する",
|
||||||
|
"dozen": "ダース",
|
||||||
|
"drop": "滴",
|
||||||
|
"dsp": "デザート用スプーン",
|
||||||
|
"Easy": "簡単",
|
||||||
|
"editRec": "レシピを編集する",
|
||||||
|
"Egyptian": "エジプト料理",
|
||||||
|
"English": "イングランド料理",
|
||||||
|
"EnRecipes": "EnRecipes",
|
||||||
|
"expBu": "バックアップをエクスポート",
|
||||||
|
"expip": "エクスポートを実行中",
|
||||||
|
"expSuc": "エクスポートに成功",
|
||||||
|
"favourites": "お気に入り",
|
||||||
|
"February": "2月",
|
||||||
|
"Filipino": "フィリピン料理",
|
||||||
|
"Filtered recipes": "絞り込み結果",
|
||||||
|
"fl oz": "液量オンス",
|
||||||
|
"fltr": "絞り込み",
|
||||||
|
"Fluid Ounce": "液量オンス",
|
||||||
|
"French": "フランス料理",
|
||||||
|
"FRI": "金",
|
||||||
|
"fsList": "お気に入りのレシピはここに表示されます",
|
||||||
|
"g": "g",
|
||||||
|
"gal": "ガロン",
|
||||||
|
"Gallon": "ガロン",
|
||||||
|
"German": "ドイツ料理",
|
||||||
|
"gh": "GitHubで見る",
|
||||||
|
"Gram": "グラム",
|
||||||
|
"Greek": "ギリシャ料理",
|
||||||
|
"grid": "グリッド",
|
||||||
|
"grocery": "食材のリスト",
|
||||||
|
"guide": "ユーザーガイド",
|
||||||
|
"Healthy": "ヘルシー",
|
||||||
|
"hr": "時間",
|
||||||
|
"impBu": "データをインポート",
|
||||||
|
"impFail": "インポートに失敗",
|
||||||
|
"impInfo": "アプリからエクスポートしたフルバックアップに対応しています",
|
||||||
|
"impip": "インポートを実行中",
|
||||||
|
"impSuc": "インポートに成功",
|
||||||
|
"Indian": "インド料理",
|
||||||
|
"ings": "材料",
|
||||||
|
"inss": "作り方",
|
||||||
|
"intf": "インターフェイス",
|
||||||
|
"invFile": "無効なファイルです",
|
||||||
|
"Irish": "アイルランド料理",
|
||||||
|
"Italian": "イタリア料理",
|
||||||
|
"Jamaican": "ジャマイカ料理",
|
||||||
|
"January": "1月",
|
||||||
|
"Japanese": "和食",
|
||||||
|
"Jewish": "ユダヤ料理",
|
||||||
|
"joinTG": "Telegramグループに参加",
|
||||||
|
"July": "7月",
|
||||||
|
"June": "6月",
|
||||||
|
"kEdit": "編集を続ける",
|
||||||
|
"Kenyan": "ケニア料理",
|
||||||
|
"kg": "kg",
|
||||||
|
"Kilogram": "キログラム",
|
||||||
|
"Korean": "韓国料理",
|
||||||
|
"l": "リットル",
|
||||||
|
"lang": "言語",
|
||||||
|
"Last updated": "最終更新",
|
||||||
|
"leaf": "枚",
|
||||||
|
"Light": "ライト",
|
||||||
|
"listVM": "一覧の表示方法",
|
||||||
|
"Litre": "リットル",
|
||||||
|
"Loaf": "ローフ",
|
||||||
|
"ltAgo": "ずっと前",
|
||||||
|
"lunch": "昼食",
|
||||||
|
"mAgo": "%s か月前",
|
||||||
|
"Main dishes": "主菜",
|
||||||
|
"March": "3月",
|
||||||
|
"May": "5月",
|
||||||
|
"Meat": "肉料理",
|
||||||
|
"Mexican": "メキシコ料理",
|
||||||
|
"mg": "mg",
|
||||||
|
"Millilitre": "ミリリットル",
|
||||||
|
"min": "分",
|
||||||
|
"minimal": "最小",
|
||||||
|
"ml": "ml",
|
||||||
|
"Moderate": "普通",
|
||||||
|
"MON": "月",
|
||||||
|
"newCui": "新しいジャンル",
|
||||||
|
"Newest first": "新しい順",
|
||||||
|
"newRec": "新しいレシピ",
|
||||||
|
"newUnit": "新しい単位",
|
||||||
|
"Nigerian": "ナイジェリア料理",
|
||||||
|
"nLangInfo": "新しい言語を使用するためにEnRecipesを再起動",
|
||||||
|
"no": "メモ",
|
||||||
|
"noAccSensor": "加速度センサーが無効です",
|
||||||
|
"noFavs": "お気に入りはまだありません",
|
||||||
|
"Noodles": "麺",
|
||||||
|
"noRecs": "検索に一致するレシピがありません",
|
||||||
|
"noRecsInL": "検索に一致するレシピが見つかりませんでした",
|
||||||
|
"nos": "メモ",
|
||||||
|
"November": "11月",
|
||||||
|
"nwCat": "新しいカテゴリー",
|
||||||
|
"nwYiU": "新しい仕上がり単位",
|
||||||
|
"October": "10月",
|
||||||
|
"OK": "OK",
|
||||||
|
"Oldest first": "古いもの順",
|
||||||
|
"opts": "オプション",
|
||||||
|
"Ounce": "オンス",
|
||||||
|
"Pasta": "パスタ",
|
||||||
|
"Patty": "パティ",
|
||||||
|
"photogrid": "写真グリッド",
|
||||||
|
"pht": "レシピの写真",
|
||||||
|
"piece": "片",
|
||||||
|
"Piece": "片",
|
||||||
|
"planner": "献立プラン",
|
||||||
|
"plsAdd": "プラスボタンを押して追加します",
|
||||||
|
"Portuguese": "ポルトガル料理",
|
||||||
|
"Poultry": "チキン料理",
|
||||||
|
"Pound": "ポンド",
|
||||||
|
"prepT": "準備時間",
|
||||||
|
"priv": "プライバシーポリシー",
|
||||||
|
"pt": "少々",
|
||||||
|
"qt": "クォート",
|
||||||
|
"Quickest first": "速いもの順",
|
||||||
|
"Rating": "評価",
|
||||||
|
"rBtn": "削除",
|
||||||
|
"rec": "レシピ",
|
||||||
|
"recE": "既に存在します:",
|
||||||
|
"recF": "件のレシピが見つかりました",
|
||||||
|
"recI": "インポートしました:",
|
||||||
|
"recListEmp": "まだ何もありません!レシピを追加してもう一度試してください",
|
||||||
|
"recPic": "レシピの写真",
|
||||||
|
"recRm": "レシピを削除しました",
|
||||||
|
"recs": "レシピ",
|
||||||
|
"recTitle": "私の健康レシピ",
|
||||||
|
"recU": "アップデート:",
|
||||||
|
"req": "%s が必要",
|
||||||
|
"resNF": "レシピが見つかりません",
|
||||||
|
"rest": "リセット",
|
||||||
|
"restCatL": "カテゴリーリストをリセット",
|
||||||
|
"restCuiL": "ジャンルのリストをリセット",
|
||||||
|
"restDone": "リセットが完了しました",
|
||||||
|
"restInfo": "リストをリセットすると、作成した項目が削除され、既定の項目を復元します。既にあるレシピには影響しません。",
|
||||||
|
"restUL": "単位のリストをリセットする",
|
||||||
|
"restYUL": "仕上がり分量の単位のリストをリセットする",
|
||||||
|
"Rice": "お米料理",
|
||||||
|
"rmCatInfo": "カテゴリーのリストから %s を削除しようとしています",
|
||||||
|
"rmCmb": "組合せが削除されました",
|
||||||
|
"rmCuiInfo": "ジャンルのリストから %s を削除しようとしています",
|
||||||
|
"rmIng": "材料を削除しました",
|
||||||
|
"rmIns": "作り方を削除しました",
|
||||||
|
"rmN": "メモが削除されました",
|
||||||
|
"rmUInfo": "単位のリストから %s を削除しようとしています",
|
||||||
|
"rmYUInfo": "仕上がり分量の単位のリストから %s を削除しようとしています",
|
||||||
|
"Roll": "ロール",
|
||||||
|
"rp": "写真を削除",
|
||||||
|
"rst": "再起動",
|
||||||
|
"Russian": "ロシア料理",
|
||||||
|
"Salads": "サラダ",
|
||||||
|
"SAT": "土",
|
||||||
|
"Sauces": "ソース",
|
||||||
|
"Scottish": "スコットランド料理",
|
||||||
|
"Seafood": "シーフード",
|
||||||
|
"selRec": "レシピを選択",
|
||||||
|
"September": "9月",
|
||||||
|
"ser": "検索",
|
||||||
|
"Serving": "人前",
|
||||||
|
"SET": "設定",
|
||||||
|
"Settings": "設定",
|
||||||
|
"shr": "共有",
|
||||||
|
"Side dishes": "副菜",
|
||||||
|
"simple": "シンプル",
|
||||||
|
"Slowest first": "遅い順",
|
||||||
|
"sltd": "選択",
|
||||||
|
"snacks": "軽食",
|
||||||
|
"Soups": "スープ",
|
||||||
|
"Spanish": "スペイン料理",
|
||||||
|
"Sri Lankan": "スリランカ料理",
|
||||||
|
"srpu": "レシピの写真を共有...",
|
||||||
|
"srt": "並び替え",
|
||||||
|
"sru": "レシピを共有...",
|
||||||
|
"stars": "星評価",
|
||||||
|
"stp": "作り方",
|
||||||
|
"strAdd": "レシピを追加しましょう!",
|
||||||
|
"SUN": "日",
|
||||||
|
"sVw": "振ってランダムなレシピを表示",
|
||||||
|
"sVwInfo": "何を作るか決められないときに使います",
|
||||||
|
"Swedish": "スウェーデン料理",
|
||||||
|
"swm": "月曜始まりにする",
|
||||||
|
"sysDef": "システム既定",
|
||||||
|
"Tablespoon": "大さじ",
|
||||||
|
"tbsp": "大さじ",
|
||||||
|
"Teaspoon": "小さじ",
|
||||||
|
"Thai": "タイ料理",
|
||||||
|
"Theme": "テーマ",
|
||||||
|
"THU": "木",
|
||||||
|
"title": "タイトル",
|
||||||
|
"tLInfo": "あとで試したいレシピはここに並びます",
|
||||||
|
"today": "今日",
|
||||||
|
"triedInfo": "に作りました",
|
||||||
|
"trnsl": "翻訳",
|
||||||
|
"trylater": "あとで作る",
|
||||||
|
"trySer": "全てのレシピを検索しますか?",
|
||||||
|
"ts": "タグ",
|
||||||
|
"tsInfo": "スペースで区切ってください",
|
||||||
|
"tsp": "小さじ",
|
||||||
|
"TUE": "火",
|
||||||
|
"Turkish": "トルコ料理",
|
||||||
|
"unit": "個",
|
||||||
|
"Unit": "単位",
|
||||||
|
"unsaved": "未保存の変更",
|
||||||
|
"untRec": "無題のレシピ",
|
||||||
|
"Vegan": "ビーガン",
|
||||||
|
"Vegetarian": "ベジタリアン",
|
||||||
|
"Vietnamese": "ベトナム料理",
|
||||||
|
"wAgo": "%s 週前",
|
||||||
|
"WED": "水",
|
||||||
|
"yesterday": "昨日",
|
||||||
|
"yieldQ": "仕上がり分量",
|
||||||
|
"yieldU": "仕上がり分量の単位",
|
||||||
|
"yld": "仕上がり分量",
|
||||||
|
"buto": "%s としてバックアップしました",
|
||||||
|
"sysDefB": "システム既定+黒",
|
||||||
|
"in": "中の",
|
||||||
|
"Undefined": "未定義",
|
||||||
|
"nNBtn": "あとで",
|
||||||
|
"stick": "スティック",
|
||||||
|
"pinch": "ピンチ",
|
||||||
|
"oz": "オンス",
|
||||||
|
"lb": "ポンド",
|
||||||
|
"it": "材料",
|
||||||
|
"small": "小",
|
||||||
|
"large": "大",
|
||||||
|
"medium": "中"
|
||||||
|
}
|
293
app/i18n/ml.json
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
{
|
||||||
|
"aap": "ഒരു ഫോട്ടോ അറ്റാച്ചുചെയ്യുക",
|
||||||
|
"About": "കുറിച്ച്",
|
||||||
|
"aBtn": "ചേർക്കുക",
|
||||||
|
"aD": "എല്ലാം ചെയ്തു!",
|
||||||
|
"addCmbBtn": "സംയോജനം ചേർക്കുക",
|
||||||
|
"aFBu": "ഒരു ബാക്കപ്പ് നടത്താൻ ഒരു പാചകക്കുറിപ്പ് ചേർക്കുക",
|
||||||
|
"aIngBtn": "ചേരുവ ചേർക്കുക",
|
||||||
|
"allCats": "എല്ലാ വിഭാഗങ്ങളും",
|
||||||
|
"allCuis": "എല്ലാ പാചകരീതികളും",
|
||||||
|
"allTs": "എല്ലാ ടാഗുകളും",
|
||||||
|
"American": "അമേരിക്കൻ",
|
||||||
|
"aNBtn": "പുതിയത് ചേർക്കുക",
|
||||||
|
"aNoBtn": "കുറിപ്പ് ചേര്ക്കുക",
|
||||||
|
"app.name": "ൻന്റെസിപിഎസ്",
|
||||||
|
"appCrd": "എന്റെരെസിപീസ് വഴി പങ്കിട്ടു. എഫ്-ആൻഡ്രോയിഡ്, ഇസിഓൺഡ്രോയിഡ് അല്ലെങ്കിൽ പ്ലേ സ്റ്റോറിൽ ഇത് നേടുക.",
|
||||||
|
"Appetizers": "വിശപ്പ്",
|
||||||
|
"appInfo": "നിങ്ങളുടെ പാചകക്കുറിപ്പുകൾ സൃഷ്ടിക്കാനും നിയന്ത്രിക്കാനും പങ്കിടാനും അനുവദിക്കുന്ന ഒരു ഓപ്പൺ സോഴ്സ്, സ്വകാര്യത കേന്ദ്രീകരിച്ച ഡിജിറ്റൽ പാചകപുസ്തകമാണ് എന്റെരെസിപീസ്",
|
||||||
|
"apply": "പ്രയോഗിക്കുക",
|
||||||
|
"appRst": "അപ്ലിക്കേഷൻ പുനരാരംഭിക്കൽ ആവശ്യമാണ്",
|
||||||
|
"April": "ഏപ്രിൽ",
|
||||||
|
"aStpBtn": "നിർദ്ദേശം ചേർക്കുക",
|
||||||
|
"August": "ഓഗസ്റ്റ്",
|
||||||
|
"Barbecue": "ബാർബിക്യൂ",
|
||||||
|
"Beverages": "പാനീയങ്ങൾ",
|
||||||
|
"Black": "കറുപ്പ്",
|
||||||
|
"Brazilian": "ബ്രസീലിയൻ",
|
||||||
|
"Breads": "ബ്രെഡുകൾ",
|
||||||
|
"breakfast": "പ്രഭാതഭക്ഷണം",
|
||||||
|
"British": "ബ്രിട്ടീഷ്",
|
||||||
|
"buEmp": "ബാക്കപ്പ് ഫയൽ ശൂന്യമാണ്",
|
||||||
|
"buFol": "ബാക്കപ്പ് ഫോൾഡർ",
|
||||||
|
"buInc": "കേടായ അല്ലെങ്കിൽ കേടായ ബാക്കപ്പ് ഫയൽ",
|
||||||
|
"buInfo": "തിരികെ ഇറക്കുമതി ചെയ്യാൻ കഴിയുന്ന നിങ്ങളുടെ എല്ലാ ഡാറ്റയും അടങ്ങിയ ഒരു ZIP ഫയൽ സൃഷ്ടിക്കുന്നു",
|
||||||
|
"buMod": "ബാക്കപ്പ് ഫയൽ മറ്റെവിടെയെങ്കിലും പരിഷ്ക്കരിച്ചു",
|
||||||
|
"cat": "വിഭാഗം",
|
||||||
|
"cBtn": "റദ്ദാക്കുക",
|
||||||
|
"Challenging": "വെല്ലുവിളിനിറഞ്ഞ",
|
||||||
|
"Chinese": "ചൈനീസ്",
|
||||||
|
"clove": "ഗ്രാമ്പൂ",
|
||||||
|
"cm": "സെന്റിമീറ്റർ",
|
||||||
|
"cmbs": "സംയോജനങ്ങൾ",
|
||||||
|
"conBtn": "തുടരുക",
|
||||||
|
"conf": "സ്ഥിരീകരിക്കുക",
|
||||||
|
"cookT": "പാചക സമയം",
|
||||||
|
"cPic": "ഫോട്ടോ എഡിറ്റുചെയ്യുക",
|
||||||
|
"Created": "സൃഷ്ടിച്ചു",
|
||||||
|
"cui": "പാചകരീതി",
|
||||||
|
"cup": "കപ്പ്",
|
||||||
|
"Cup": "കപ്പ്",
|
||||||
|
"dAgo": "%s ദിവസം മുമ്പ്",
|
||||||
|
"Danish": "ഡാനിഷ്",
|
||||||
|
"Dark": "ഇരുണ്ടത്",
|
||||||
|
"db": "ഡാറ്റാബേസ്",
|
||||||
|
"dBtn": "ഇല്ലാതാക്കുക",
|
||||||
|
"December": "ഡിസംബർ",
|
||||||
|
"delRecInfo": "%s പാചകക്കുറിപ്പ് നിങ്ങൾ ശാശ്വതമായി ഇല്ലാതാക്കാൻ പോകുന്നു",
|
||||||
|
"delRecsInfo": "നിങ്ങൾ %s ശാശ്വതമായി ഇല്ലാതാക്കാൻ പോകുന്നു",
|
||||||
|
"Desserts": "മധുരപലഹാരങ്ങൾ",
|
||||||
|
"detailed": "വിശദമായ",
|
||||||
|
"Difficulty level": "വൈഷമ്യ നില",
|
||||||
|
"dinner": "അത്താഴം",
|
||||||
|
"disBtn": "നിരസിക്കുക",
|
||||||
|
"disc": "ഈ പാചകക്കുറിപ്പിൽ സംരക്ഷിക്കാത്ത മാറ്റങ്ങളുണ്ട്. നിങ്ങൾ എന്താണ് ചെയ്യാൻ ആഗ്രഹിക്കുന്നത്?",
|
||||||
|
"donate": "സംഭാവനചെയ്യുക",
|
||||||
|
"dozen": "ഡസൻ",
|
||||||
|
"drop": "തുള്ളി",
|
||||||
|
"dsp": "ഡെസേർട്ട് സ്പൂൺ",
|
||||||
|
"Easy": "എളുപ്പമാണ്",
|
||||||
|
"editRec": "പാചകക്കുറിപ്പ് എഡിറ്റുചെയ്യുക",
|
||||||
|
"Egyptian": "ഈജിപ്ഷ്യൻ",
|
||||||
|
"English": "ഇംഗ്ലീഷ്",
|
||||||
|
"EnRecipes": "ൻന്റെസിപിഎസ്",
|
||||||
|
"expBu": "പൂർണ്ണ ബാക്കപ്പ് എക്സ്പോർട്ടുചെയ്യുക",
|
||||||
|
"expip": "കയറ്റുമതി പുരോഗതിയിലാണ്",
|
||||||
|
"expSuc": "കയറ്റുമതി വിജയം",
|
||||||
|
"favourites": "പ്രിയങ്കരങ്ങൾ",
|
||||||
|
"February": "ഫെബ്രുവരി",
|
||||||
|
"Filipino": "ഫിലിപ്പിനോ",
|
||||||
|
"Filtered recipes": "ഫിൽട്ടർ ചെയ്ത പാചകക്കുറിപ്പുകൾ",
|
||||||
|
"fl oz": "ഫ്ലൂയിഡ് un ൺസ്",
|
||||||
|
"fltr": "ഫിൽട്ടർ ചെയ്യുക",
|
||||||
|
"Fluid Ounce": "ഫ്ലൂയിഡ് un ൺസ്",
|
||||||
|
"French": "ഫ്രഞ്ച്",
|
||||||
|
"FRI": "വെള്ളി",
|
||||||
|
"fsList": "നിങ്ങളുടെ പ്രിയപ്പെട്ട പാചകക്കുറിപ്പുകൾ ഇവിടെ പട്ടികപ്പെടുത്തിയിട്ടുണ്ട്",
|
||||||
|
"g": "ഗ്രാം",
|
||||||
|
"gal": "ഗാലൺ",
|
||||||
|
"Gallon": "ഗാലൺ",
|
||||||
|
"German": "ജർമ്മൻ",
|
||||||
|
"gh": "GitHub- ൽ കാണുക",
|
||||||
|
"Gram": "ഗ്രാം",
|
||||||
|
"Greek": "ഗ്രീക്ക്",
|
||||||
|
"grid": "ഗ്രിഡ്",
|
||||||
|
"grocery": "പലചരക്ക് പട്ടിക",
|
||||||
|
"guide": "ഉപയോക്തൃ ഗൈഡ്",
|
||||||
|
"Healthy": "ആരോഗ്യമുള്ള",
|
||||||
|
"hr": "മണിക്കൂർ",
|
||||||
|
"impBu": "ഡാറ്റ ഇറക്കുമതി ചെയ്യുക",
|
||||||
|
"impFail": "ഇറക്കുമതി പരാജയപ്പെട്ടു",
|
||||||
|
"impInfo": "ഈ അപ്ലിക്കേഷൻ എക്സ്പോർട്ടുചെയ്ത പൂർണ്ണ ബാക്കപ്പുകൾ പിന്തുണയ്ക്കുന്നു",
|
||||||
|
"impip": "ഇറക്കുമതി പുരോഗതിയിലാണ്",
|
||||||
|
"impSuc": "ഇറക്കുമതി വിജയം",
|
||||||
|
"in": "ഇഞ്ച്",
|
||||||
|
"Indian": "ഇന്ത്യൻ",
|
||||||
|
"ings": "ചേരുവകൾ",
|
||||||
|
"inss": "നിർദ്ദേശങ്ങൾ",
|
||||||
|
"intf": "ഇന്റർഫേസ്",
|
||||||
|
"invFile": "അസാധുവായ ഫയൽ",
|
||||||
|
"Irish": "ഐറിഷ്",
|
||||||
|
"it": "ഇനം",
|
||||||
|
"Italian": "ഇറ്റാലിയൻ",
|
||||||
|
"Jamaican": "ജമൈക്കൻ",
|
||||||
|
"January": "ജനുവരി",
|
||||||
|
"Japanese": "ജാപ്പനീസ്",
|
||||||
|
"Jewish": "ജൂതൻ",
|
||||||
|
"joinTG": "ടെലിഗ്രാം ഗ്രൂപ്പിൽ ചേരുക",
|
||||||
|
"July": "ജൂലൈ",
|
||||||
|
"June": "ജൂൺ",
|
||||||
|
"kEdit": "എഡിറ്റിംഗ് തുടരുക",
|
||||||
|
"Kenyan": "കെനിയൻ",
|
||||||
|
"kg": "കി. ഗ്രാം",
|
||||||
|
"Kilogram": "കിലോഗ്രാം",
|
||||||
|
"Korean": "കൊറിയൻ",
|
||||||
|
"l": "ലിറ്റർ",
|
||||||
|
"lang": "ഭാഷ",
|
||||||
|
"large": "വലുത്",
|
||||||
|
"Last updated": "അവസാനമായി പുതുക്കിയത്",
|
||||||
|
"lb": "പൗണ്ട്",
|
||||||
|
"leaf": "ഇല",
|
||||||
|
"Light": "പ്രകാശം",
|
||||||
|
"listVM": "പട്ടിക കാഴ്ച മോഡ്",
|
||||||
|
"Litre": "ലിറ്റർ",
|
||||||
|
"Loaf": "അപ്പം",
|
||||||
|
"ltAgo": "വളരെക്കാലം മുമ്പ്",
|
||||||
|
"lunch": "ഉച്ചഭക്ഷണം",
|
||||||
|
"mAgo": "%s മാസം മുമ്പ്",
|
||||||
|
"Main dishes": "പ്രധാന വിഭവങ്ങൾ",
|
||||||
|
"March": "മാർച്ച്",
|
||||||
|
"May": "മെയ്",
|
||||||
|
"Meat": "മാംസം",
|
||||||
|
"medium": "ഇടത്തരം",
|
||||||
|
"Mexican": "മെക്സിക്കൻ",
|
||||||
|
"mg": "മില്ലിഗ്രാം",
|
||||||
|
"Millilitre": "മില്ലിലിറ്റർ",
|
||||||
|
"min": "മിനിറ്റ്",
|
||||||
|
"minimal": "കുറഞ്ഞത്",
|
||||||
|
"ml": "മില്ലി",
|
||||||
|
"Moderate": "മിതത്വം",
|
||||||
|
"MON": "തിങ്കൾ",
|
||||||
|
"newCui": "പുതിയ പാചകരീതി",
|
||||||
|
"Newest first": "ആദ്യത്തെ പുതിയത്",
|
||||||
|
"newRec": "പുതിയ പാചകക്കുറിപ്പ്",
|
||||||
|
"newUnit": "പുതിയ യൂണിറ്റ്",
|
||||||
|
"Nigerian": "നൈജീരിയൻ",
|
||||||
|
"nLangInfo": "പുതിയ ഭാഷ ഉപയോഗിക്കുന്നതിന് എന്റെരെസിപീസ് പുനരാരംഭിക്കുക",
|
||||||
|
"nNBtn": "ഇപ്പോൾ വേണ്ട",
|
||||||
|
"no": "കുറിപ്പ്",
|
||||||
|
"noAccSensor": "ആക്സിലറോമീറ്റർ സെൻസർ പ്രവർത്തനരഹിതമാക്കി അല്ലെങ്കിൽ പ്രവർത്തിക്കുന്നില്ല",
|
||||||
|
"noFavs": "ഇതുവരെ പ്രിയപ്പെട്ട പാചകക്കുറിപ്പുകളൊന്നുമില്ല",
|
||||||
|
"Noodles": "നൂഡിൽസ്",
|
||||||
|
"noRecs": "പാചകക്കുറിപ്പുകളൊന്നും നിങ്ങളുടെ തിരയലുമായി പൊരുത്തപ്പെടുന്നില്ല",
|
||||||
|
"noRecsInL": "ഇവിടെയുള്ള പാചകങ്ങളൊന്നും നിങ്ങളുടെ തിരയലുമായി പൊരുത്തപ്പെടുന്നില്ല",
|
||||||
|
"nos": "കുറിപ്പുകൾ",
|
||||||
|
"November": "നവംബർ",
|
||||||
|
"nwCat": "പുതിയ വിഭാഗം",
|
||||||
|
"nwYiU": "പുതിയ വിളവ് യൂണിറ്റ്",
|
||||||
|
"October": "ഒക്ടോബർ",
|
||||||
|
"OK": "ശരി",
|
||||||
|
"Oldest first": "ആദ്യം പഴയത്",
|
||||||
|
"opts": "ഓപ്ഷനുകൾ",
|
||||||
|
"Ounce": "Un ൺസ്",
|
||||||
|
"oz": "oun ൺസ്",
|
||||||
|
"Pasta": "പാസ്ത",
|
||||||
|
"Patty": "പാറ്റി",
|
||||||
|
"photogrid": "ഫോട്ടോ ഗ്രിഡ്",
|
||||||
|
"pht": "പാചകക്കുറിപ്പ് ഫോട്ടോ",
|
||||||
|
"piece": "കഷണം",
|
||||||
|
"Piece": "പീസ്",
|
||||||
|
"pinch": "നുള്ള്",
|
||||||
|
"planner": "ഭക്ഷണ പ്ലാനർ",
|
||||||
|
"plsAdd": "ഒരെണ്ണം ചേർക്കാൻ പ്ലസ് ബട്ടൺ ഉപയോഗിക്കുക",
|
||||||
|
"Portuguese": "പോർച്ചുഗീസ്",
|
||||||
|
"Poultry": "കോഴി",
|
||||||
|
"Pound": "പൗണ്ട്",
|
||||||
|
"prepT": "തയ്യാറാക്കൽ സമയം",
|
||||||
|
"priv": "സ്വകാര്യതാ നയം",
|
||||||
|
"pt": "പിന്റ്",
|
||||||
|
"qt": "ക്വാർട്ട്",
|
||||||
|
"Quickest first": "ആദ്യ വേഗത്തിലുള്ളത്",
|
||||||
|
"Rating": "റേറ്റിംഗ്",
|
||||||
|
"rBtn": "നീക്കംചെയ്യുക",
|
||||||
|
"rec": "പാചകക്കുറിപ്പ്",
|
||||||
|
"recE": "നിലവിലുള്ളത്:",
|
||||||
|
"recF": "പാചകക്കുറിപ്പുകൾ കണ്ടെത്തി",
|
||||||
|
"recI": "ഇറക്കുമതി ചെയ്തത്:",
|
||||||
|
"recListEmp": "ഇവിടെ ഒന്നുമില്ല! കുറച്ച് പാചകക്കുറിപ്പുകൾ ചേർത്ത് വീണ്ടും ശ്രമിക്കുക",
|
||||||
|
"recPic": "പാചകക്കുറിപ്പ് ഫോട്ടോ",
|
||||||
|
"recRm": "പാചകക്കുറിപ്പ് നീക്കംചെയ്തു",
|
||||||
|
"recs": "പാചകക്കുറിപ്പുകൾ",
|
||||||
|
"recTitle": "എന്റെ ആരോഗ്യകരമായ പാചകക്കുറിപ്പ്",
|
||||||
|
"recU": "അപ്ഡേറ്റുചെയ്തത്:",
|
||||||
|
"req": "ആവശ്യമായ %s",
|
||||||
|
"resNF": "പാചകക്കുറിപ്പ് കണ്ടെത്തിയില്ല",
|
||||||
|
"rest": "പുനഃക്രമീകരിക്കുക",
|
||||||
|
"restCatL": "വിഭാഗ ലിസ്റ്റ് പുന .സജ്ജമാക്കുക",
|
||||||
|
"restCuiL": "പാചകരീതി പട്ടിക പുന .സജ്ജമാക്കുക",
|
||||||
|
"restDone": "പുന .സജ്ജീകരണം പൂർത്തിയായി",
|
||||||
|
"restInfo": "ഒരു ലിസ്റ്റ് പുന .സജ്ജമാക്കുന്നത് ഉപയോക്താവ് സൃഷ്ടിച്ച എൻട്രികൾ ഇല്ലാതാക്കുകയും സ്ഥിരസ്ഥിതി എൻട്രികൾ പുന restore സ്ഥാപിക്കുകയും ചെയ്യും. നിലവിലുള്ള പാചകത്തെ ബാധിക്കില്ല.",
|
||||||
|
"restUL": "യൂണിറ്റ് ലിസ്റ്റ് പുന .സജ്ജമാക്കുക",
|
||||||
|
"restYUL": "വിളവ് യൂണിറ്റ് ലിസ്റ്റ് പുന .സജ്ജമാക്കുക",
|
||||||
|
"Rice": "അരി",
|
||||||
|
"rmCatInfo": "നിങ്ങൾ കാറ്റഗറി ലിസ്റ്റിൽ നിന്ന് %s നീക്കംചെയ്യാൻ പോകുന്നു",
|
||||||
|
"rmCmb": "കോമ്പിനേഷൻ നീക്കംചെയ്തു",
|
||||||
|
"rmCuiInfo": "നിങ്ങൾ പാചക പട്ടികയിൽ നിന്ന് %s നീക്കംചെയ്യാൻ പോകുന്നു",
|
||||||
|
"rmIng": "ചേരുവ നീക്കംചെയ്തു",
|
||||||
|
"rmIns": "നിർദ്ദേശം നീക്കംചെയ്തു",
|
||||||
|
"rmN": "കുറിപ്പ് നീക്കംചെയ്തു",
|
||||||
|
"rmUInfo": "നിങ്ങൾ %s യെ യൂണിറ്റ് പട്ടികയിൽ നിന്ന് നീക്കംചെയ്യാൻ പോവുകയാണ്",
|
||||||
|
"rmYUInfo": "വിളവ് യൂണിറ്റ് പട്ടികയിൽ നിന്ന് നിങ്ങൾ %s നീക്കംചെയ്യാൻ പോകുന്നു",
|
||||||
|
"Roll": "റോൾ",
|
||||||
|
"rp": "ഫോട്ടോ നീക്കംചെയ്യുക",
|
||||||
|
"rst": "പുനരാരംഭിക്കുക",
|
||||||
|
"Russian": "റഷ്യൻ",
|
||||||
|
"Salads": "സലാഡുകൾ",
|
||||||
|
"SAT": "ശനി",
|
||||||
|
"Sauces": "സോസുകൾ",
|
||||||
|
"Scottish": "സ്കോട്ടിഷ്",
|
||||||
|
"Seafood": "കടൽ ഭക്ഷണം",
|
||||||
|
"selRec": "പാചകക്കുറിപ്പ് തിരഞ്ഞെടുക്കുക",
|
||||||
|
"September": "സെപ്റ്റംബർ",
|
||||||
|
"ser": "തിരയുക",
|
||||||
|
"Serving": "സേവിക്കുന്നു",
|
||||||
|
"SET": "സെറ്റ്",
|
||||||
|
"Settings": "ക്രമീകരണങ്ങൾ",
|
||||||
|
"shr": "പങ്കിടുക",
|
||||||
|
"Side dishes": "സൈഡ് വിഭവങ്ങൾ",
|
||||||
|
"simple": "ലളിതം",
|
||||||
|
"Slowest first": "ആദ്യ വേഗത",
|
||||||
|
"sltd": "തിരഞ്ഞെടുത്തു",
|
||||||
|
"small": "ചെറുത്",
|
||||||
|
"snacks": "ലഘുഭക്ഷണങ്ങൾ",
|
||||||
|
"Soups": "സൂപ്പ്",
|
||||||
|
"Spanish": "സ്പാനിഷ്",
|
||||||
|
"Sri Lankan": "ശ്രീലങ്കൻ",
|
||||||
|
"srpu": "പാചകക്കുറിപ്പ് ഫോട്ടോ പങ്കിടുക...",
|
||||||
|
"srt": "അടുക്കുക",
|
||||||
|
"sru": "പാചകക്കുറിപ്പ് പങ്കിടുക...",
|
||||||
|
"stars": "നക്ഷത്ര റേറ്റിംഗ്",
|
||||||
|
"stick": "വടി",
|
||||||
|
"stp": "ഘട്ടം",
|
||||||
|
"strAdd": "നിങ്ങളുടെ പാചകക്കുറിപ്പുകൾ ചേർക്കാൻ ആരംഭിക്കുക!",
|
||||||
|
"SUN": "ഞായ",
|
||||||
|
"sVw": "ക്രമരഹിതമായ പാചകക്കുറിപ്പ് കാണാൻ കുലുക്കുക",
|
||||||
|
"sVwInfo": "നിങ്ങൾക്ക് തീരുമാനിക്കാൻ കഴിയാത്തപ്പോൾ എന്താണ് പാചകം ചെയ്യേണ്ടതെന്ന് തിരഞ്ഞെടുക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു",
|
||||||
|
"Swedish": "സ്വീഡിഷ്",
|
||||||
|
"swm": "ആഴ്ചയിലെ ആദ്യ ദിവസം തിങ്കളാഴ്ച",
|
||||||
|
"sysDef": "സിസ്റ്റം സ്ഥിരസ്ഥിതി",
|
||||||
|
"Tablespoon": "ടേബിൾസ്പൂൺ",
|
||||||
|
"tbsp": "ടേബിൾസ്പൂൺ",
|
||||||
|
"Teaspoon": "ടീസ്പൂൺ",
|
||||||
|
"Thai": "തായ്",
|
||||||
|
"Theme": "തീം",
|
||||||
|
"THU": "വ്യാഴം",
|
||||||
|
"title": "ശീർഷകം",
|
||||||
|
"tLInfo": "നിങ്ങൾ പിന്നീട് ശ്രമിക്കാൻ ആഗ്രഹിക്കുന്ന പാചകക്കുറിപ്പുകൾ ഇവിടെ പട്ടികപ്പെടുത്തിയിട്ടുണ്ട്",
|
||||||
|
"today": "ഇന്ന്",
|
||||||
|
"triedInfo": "നിങ്ങൾ %s ഈ പാചകക്കുറിപ്പ് പരീക്ഷിച്ചു",
|
||||||
|
"trnsl": "വിവർത്തനം ചെയ്യുക",
|
||||||
|
"trylater": "പിന്നീട് ശ്രമിക്കുക",
|
||||||
|
"trySer": "എല്ലാ പാചകക്കുറിപ്പുകളിലും തിരയണോ?",
|
||||||
|
"ts": "ടാഗുകൾ",
|
||||||
|
"tsInfo": "സ്പെയ്സുകൾ ഉപയോഗിച്ച് വേർതിരിക്കുക",
|
||||||
|
"tsp": "ടീസ്പൂൺ",
|
||||||
|
"TUE": "ചൊവ്വ",
|
||||||
|
"Turkish": "ടർക്കിഷ്",
|
||||||
|
"Undefined": "നിർവചിച്ചിട്ടില്ല",
|
||||||
|
"unit": "യൂണിറ്റ്",
|
||||||
|
"Unit": "യൂണിറ്റ്",
|
||||||
|
"unsaved": "സംരക്ഷിക്കാത്ത മാറ്റങ്ങൾ",
|
||||||
|
"untRec": "ശീർഷകമില്ലാത്ത പാചകക്കുറിപ്പ്",
|
||||||
|
"Vegan": "വെഗാൻ",
|
||||||
|
"Vegetarian": "വെജിറ്റേറിയൻ",
|
||||||
|
"Vietnamese": "വിയറ്റ്നാമീസ്",
|
||||||
|
"wAgo": "%s ആഴ്ച മുമ്പ്",
|
||||||
|
"WED": "ബുധൻ",
|
||||||
|
"yesterday": "ഇന്നലെ",
|
||||||
|
"yieldQ": "വിളവ് അളവ്",
|
||||||
|
"yieldU": "വിളവ് യൂണിറ്റ്",
|
||||||
|
"yld": "വരുമാനം",
|
||||||
|
"buto": "%s ലേക്ക് ബാക്കപ്പ് ചെയ്തു",
|
||||||
|
"sysDefB": "സിസ്റ്റം സ്ഥിരസ്ഥിതി + കറുപ്പ്"
|
||||||
|
}
|
|
@ -332,6 +332,17 @@
|
||||||
"tue": "dinsdag",
|
"tue": "dinsdag",
|
||||||
"mon": "maandag",
|
"mon": "maandag",
|
||||||
"sun": "zondag",
|
"sun": "zondag",
|
||||||
|
"d": "Dag",
|
||||||
|
"wk": "Week",
|
||||||
|
"mnth": "Maand",
|
||||||
"calVM": "Weergavemodus van kalender",
|
"calVM": "Weergavemodus van kalender",
|
||||||
"oAP": "%1$s lopende; %2$s onderbroken"
|
"oAP": "%1$s lopende; %2$s onderbroken",
|
||||||
|
"nvr": "Nooit",
|
||||||
|
"otaw": "Ouder dan een week",
|
||||||
|
"otam": "Ouder dan een maand",
|
||||||
|
"otay": "Ouder dan een jaar",
|
||||||
|
"admp": "Schema's automatisch verwijderen",
|
||||||
|
"plsCrt": "Druk op de plusknop om een schema toe te voegen",
|
||||||
|
"ehwmp": "Eet gezond met maaltijdschema's!",
|
||||||
|
"selMT": "Kies het soort maaltijd"
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,20 +311,5 @@
|
||||||
"prsts": "Predefinições",
|
"prsts": "Predefinições",
|
||||||
"delPrst": "Você está prestes a apagar %s das predefinições",
|
"delPrst": "Você está prestes a apagar %s das predefinições",
|
||||||
"tmrRm": "Timer removido",
|
"tmrRm": "Timer removido",
|
||||||
"notifSetg": "Configurações de notificação",
|
"notifSetg": "Configurações de notificação"
|
||||||
"calVM": "Modo de visualização de calendário",
|
|
||||||
"oAP": "%1$s em curso, %2$s em pausa",
|
|
||||||
"gtD": "Ir à data",
|
|
||||||
"random": "Aleatório",
|
|
||||||
"ystr": "Ontem",
|
|
||||||
"tmrw": "Amanhã",
|
|
||||||
"tdy": "Hoje",
|
|
||||||
"cpy": "cópia",
|
|
||||||
"sat": "sábado",
|
|
||||||
"fri": "sexta-feira",
|
|
||||||
"thu": "quinta-feira",
|
|
||||||
"wed": "quarta-feira",
|
|
||||||
"tue": "terça-feira",
|
|
||||||
"mon": "segunda-feira",
|
|
||||||
"sun": "domingo"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,17 +321,28 @@
|
||||||
"ccwt": "Cozinhe com segurança com temporizadores!",
|
"ccwt": "Cozinhe com segurança com temporizadores!",
|
||||||
"gtD": "Ir à data",
|
"gtD": "Ir à data",
|
||||||
"random": "Aleatória",
|
"random": "Aleatória",
|
||||||
"cpy": "cópia",
|
"nvr": "Nunca",
|
||||||
"oAP": "%1$s em curso, %2$s em pausa",
|
"otaw": "Mais antigas que 1 semana",
|
||||||
"calVM": "Modo de visualização de calendário",
|
"otam": "Mais antigas que 1 mês",
|
||||||
|
"otay": "Mais antigas que 1 ano",
|
||||||
|
"admp": "Eliminar automaticamente planos de refeições",
|
||||||
|
"plsCrt": "Use o botão + para criar uma",
|
||||||
|
"ehwmp": "Coma saudavelmente com planificações de refeições!",
|
||||||
|
"selMT": "Selecionar tipo de refeição",
|
||||||
"ystr": "Ontem",
|
"ystr": "Ontem",
|
||||||
"tmrw": "Amanhã",
|
"tmrw": "Amanhã",
|
||||||
"tdy": "Hoje",
|
"tdy": "Hoje",
|
||||||
"sat": "sábado",
|
"cpy": "cópia",
|
||||||
"fri": "sexta-feira",
|
"sat": "Sábado",
|
||||||
"thu": "quinta-feira",
|
"fri": "Sexta-feira",
|
||||||
"wed": "quarta-feira",
|
"thu": "Quinta-feira",
|
||||||
"tue": "terça-feira",
|
"wed": "Quarta-feira",
|
||||||
"mon": "segunda-feira",
|
"tue": "Terça-feira",
|
||||||
"sun": "domingo"
|
"mon": "Segunda-feira",
|
||||||
|
"sun": "Domingo",
|
||||||
|
"d": "Dia",
|
||||||
|
"wk": "Semana",
|
||||||
|
"mnth": "Mês",
|
||||||
|
"calVM": "Modo de vista tipo calendário",
|
||||||
|
"oAP": "%1$s a decorrer, %2$s em pausa"
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,5 +333,16 @@
|
||||||
"mon": "திங்கள்",
|
"mon": "திங்கள்",
|
||||||
"sun": "ஞாயிறு",
|
"sun": "ஞாயிறு",
|
||||||
"calVM": "கேலெண்டர் காட்சி முறை",
|
"calVM": "கேலெண்டர் காட்சி முறை",
|
||||||
"oAP": "%1$s செயலில் உள்ளது,%2$s இடைநிறுத்தப்பட்டது"
|
"oAP": "%1$s செயலில் உள்ளது,%2$s இடைநிறுத்தப்பட்டது",
|
||||||
|
"d": "நாள்",
|
||||||
|
"wk": "வாரம்",
|
||||||
|
"mnth": "மாதம்",
|
||||||
|
"nvr": "ஒருபோதும்",
|
||||||
|
"otaw": "ஒரு வாரத்திற்கும் மேலானது",
|
||||||
|
"otam": "ஒரு மாதத்திற்கும் மேலானது",
|
||||||
|
"otay": "ஒரு வருடத்திற்கும் மேலானது",
|
||||||
|
"admp": "உணவு திட்டங்களை தானாக நீக்கு",
|
||||||
|
"plsCrt": "ஒன்றை உருவாக்க பிளஸ் பொத்தானைப் பயன்படுத்தவும்",
|
||||||
|
"ehwmp": "உணவு திட்டங்களுடன் ஆரோக்கியமாக சாப்பிடுங்கள்!",
|
||||||
|
"selMT": "உணவு வகையைத் தேர்ந்தெடுக்கவும்"
|
||||||
}
|
}
|
||||||
|
|
112
app/main.ts
|
@ -1,45 +1,43 @@
|
||||||
|
import Vue from 'nativescript-vue'
|
||||||
|
import store from './store'
|
||||||
import {
|
import {
|
||||||
Application,
|
Application,
|
||||||
AndroidApplication,
|
AndroidApplication,
|
||||||
ApplicationSettings,
|
ApplicationSettings,
|
||||||
Utils,
|
Utils,
|
||||||
Device,
|
|
||||||
Color,
|
|
||||||
Frame,
|
Frame,
|
||||||
} from '@nativescript/core'
|
} from '@nativescript/core'
|
||||||
import {
|
import { localize } from '@nativescript/localize'
|
||||||
localize,
|
|
||||||
androidLaunchEventLocalizationHandler,
|
|
||||||
} from '@nativescript/localize'
|
|
||||||
import Vue from 'nativescript-vue'
|
|
||||||
import EnRecipes from './components/EnRecipes.vue'
|
import EnRecipes from './components/EnRecipes.vue'
|
||||||
import EditRecipe from './components/EditRecipe.vue'
|
import EditRecipe from './components/EditRecipe.vue'
|
||||||
import MealPlanner from './components/MealPlanner.vue'
|
import MealPlanner from './components/MealPlanner.vue'
|
||||||
import CookingTimer from './components/CookingTimer.vue'
|
import CookingTimer from './components/CookingTimer.vue'
|
||||||
import GroceryList from './components/GroceryList.vue'
|
|
||||||
import store from './store'
|
// import GroceryList from './components/GroceryList.vue'
|
||||||
|
|
||||||
import * as utils from '~/shared/utils'
|
import * as utils from '~/shared/utils'
|
||||||
|
|
||||||
export const EventBus = new Vue()
|
export const EvtBus = new Vue()
|
||||||
|
|
||||||
let renderView: any = EnRecipes
|
let renderView = EnRecipes
|
||||||
|
|
||||||
import CollectionView from '@nativescript-community/ui-collectionview/vue'
|
import CollectionView from '@nativescript-community/ui-collectionview/vue'
|
||||||
Vue.use(CollectionView)
|
Vue.use(CollectionView)
|
||||||
import { StackLayout, GridLayout, DockLayout } from '@nativescript-rtl/ui'
|
|
||||||
Vue.registerElement('RStackLayout', () => StackLayout)
|
import { RGridLayout, RStackLayout, RDockLayout, RLabel } from './rtl-ui'
|
||||||
Vue.registerElement('RGridLayout', () => GridLayout)
|
Vue.registerElement('RGridLayout', () => RGridLayout)
|
||||||
Vue.registerElement('RDockLayout', () => DockLayout)
|
Vue.registerElement('RStackLayout', () => RStackLayout)
|
||||||
|
Vue.registerElement('RDockLayout', () => RDockLayout)
|
||||||
|
Vue.registerElement('RLabel', () => RLabel)
|
||||||
|
|
||||||
import { myMixin } from './shared/mixins'
|
import { myMixin } from './shared/mixins'
|
||||||
Vue.mixin(myMixin)
|
Vue.mixin(myMixin)
|
||||||
|
|
||||||
const initFrame = () => {
|
const initFrame = () => {
|
||||||
const vm = store
|
const vm = store
|
||||||
|
// MainInit
|
||||||
//MAIN INIT
|
vm.commit('setTheme', ApplicationSettings.getString('theme', 'sysDef'))
|
||||||
vm.commit('setTheme', ApplicationSettings.getString('appTheme', 'sysDef'))
|
vm.commit('initRecipes')
|
||||||
if (!vm.state.recipes.length) vm.commit('initRecipes')
|
|
||||||
vm.commit('initMealPlans')
|
vm.commit('initMealPlans')
|
||||||
vm.commit('initListItems')
|
vm.commit('initListItems')
|
||||||
vm.commit('initTimerPresets')
|
vm.commit('initTimerPresets')
|
||||||
|
@ -50,42 +48,11 @@ const initFrame = () => {
|
||||||
hasTimerSound ? JSON.parse(hasTimerSound) : utils.getTones().defaultTone
|
hasTimerSound ? JSON.parse(hasTimerSound) : utils.getTones().defaultTone
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
// InitFrame
|
||||||
// INIT FRAME
|
|
||||||
const View = android.view.View as any
|
|
||||||
const window = Application.android.startActivity.getWindow()
|
const window = Application.android.startActivity.getWindow()
|
||||||
const decorView = window.getDecorView()
|
const decorView = window.getDecorView()
|
||||||
let sdkv = parseInt(Device.sdkVersion)
|
utils.setBarColors(window, decorView, vm.state.theme)
|
||||||
function setColors(color) {
|
Frame.topmost().className = vm.state.theme
|
||||||
window.setStatusBarColor(new Color(color).android)
|
|
||||||
sdkv >= 27 && window.setNavigationBarColor(new Color(color).android)
|
|
||||||
}
|
|
||||||
switch (vm.state.appTheme) {
|
|
||||||
case 'Light':
|
|
||||||
setColors('#f1f3f5')
|
|
||||||
break
|
|
||||||
case 'Dark':
|
|
||||||
setColors('#212529')
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
setColors('#000000')
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if (sdkv >= 27)
|
|
||||||
decorView.setSystemUiVisibility(
|
|
||||||
vm.state.appTheme == 'Light'
|
|
||||||
? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
|
|
||||||
View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
|
||||||
: View.SYSTEM_UI_FLAG_DARK_STATUS_BAR |
|
|
||||||
View.SYSTEM_UI_FLAG_DARK_NAVIGATION_BAR
|
|
||||||
)
|
|
||||||
else
|
|
||||||
decorView.setSystemUiVisibility(
|
|
||||||
vm.state.appTheme == 'Light'
|
|
||||||
? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
|
||||||
: View.SYSTEM_UI_FLAG_DARK_STATUS_BAR
|
|
||||||
)
|
|
||||||
Frame.topmost().className = store.state.appTheme
|
|
||||||
}
|
}
|
||||||
const showOverLockscreen = () => {
|
const showOverLockscreen = () => {
|
||||||
let ctx = Utils.ad.getApplicationContext()
|
let ctx = Utils.ad.getApplicationContext()
|
||||||
|
@ -103,12 +70,9 @@ const showOverLockscreen = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const intentListener = ({ intent, android }: any) => {
|
const intentListener = ({ intent, android }: any) => {
|
||||||
console.log(intent, android)
|
|
||||||
let action = ((intent || android).getStringExtra('action') ||
|
let action = ((intent || android).getStringExtra('action') ||
|
||||||
(android && android.getAction())) as string
|
(android && android.getAction())) as string
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
console.log(action)
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'new_recipe':
|
case 'new_recipe':
|
||||||
renderView = EditRecipe
|
renderView = EditRecipe
|
||||||
|
@ -118,30 +82,47 @@ const intentListener = ({ intent, android }: any) => {
|
||||||
break
|
break
|
||||||
case 'timer':
|
case 'timer':
|
||||||
renderView = CookingTimer
|
renderView = CookingTimer
|
||||||
|
switch (ApplicationSettings.getNumber('isTimer', 0)) {
|
||||||
|
case 0:
|
||||||
|
// Closing all modals if available before navigation
|
||||||
|
let modals = Frame.topmost()._getRootModalViews()
|
||||||
|
for (let i = modals.length - 1; i >= 0; i--) {
|
||||||
|
Frame.topmost()
|
||||||
|
._getRootModalViews()
|
||||||
|
[i].closeModal()
|
||||||
|
}
|
||||||
Vue.navigateTo(CookingTimer as any, {
|
Vue.navigateTo(CookingTimer as any, {
|
||||||
animated: false,
|
animated: false,
|
||||||
})
|
})
|
||||||
|
ApplicationSettings.setNumber('isTimer', 1)
|
||||||
break
|
break
|
||||||
case 'grocery':
|
case 2:
|
||||||
renderView = GroceryList
|
Vue.navigateBack()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
// case 'grocery':
|
||||||
|
// renderView = GroceryList
|
||||||
|
// break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.on(Application.resumeEvent, (args) => {
|
Application.on(Application.resumeEvent, () => {
|
||||||
console.log('App Resume')
|
|
||||||
showOverLockscreen()
|
showOverLockscreen()
|
||||||
|
if (
|
||||||
|
utils.sysLocale() !==
|
||||||
|
ApplicationSettings.getString('sysLocale', utils.sysLocale())
|
||||||
|
) {
|
||||||
|
Frame.reloadPage()
|
||||||
|
utils.updateLocale()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Application.on(Application.launchEvent, (args) => {
|
Application.on(Application.launchEvent, (args) => {
|
||||||
console.log('App Launch')
|
utils.updateLocale()
|
||||||
console.log('RTL', store.state.RTL)
|
|
||||||
store.commit('setRTL')
|
store.commit('setRTL')
|
||||||
if (args.android) {
|
|
||||||
androidLaunchEventLocalizationHandler()
|
|
||||||
intentListener(args)
|
intentListener(args)
|
||||||
}
|
|
||||||
Application.android.on(
|
Application.android.on(
|
||||||
AndroidApplication.activityNewIntentEvent,
|
AndroidApplication.activityNewIntentEvent,
|
||||||
intentListener
|
intentListener
|
||||||
|
@ -150,7 +131,6 @@ Application.on(Application.launchEvent, (args) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Application.on(Application.exitEvent, () => {
|
Application.on(Application.exitEvent, () => {
|
||||||
console.log('App Exit')
|
|
||||||
renderView = EnRecipes
|
renderView = EnRecipes
|
||||||
Application.android.off(
|
Application.android.off(
|
||||||
AndroidApplication.activityNewIntentEvent,
|
AndroidApplication.activityNewIntentEvent,
|
||||||
|
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 938 B After Width: | Height: | Size: 938 B |
Before Width: | Height: | Size: 954 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 780 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 932 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 940 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 852 B After Width: | Height: | Size: 852 B |
Before Width: | Height: | Size: 860 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 758 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 906 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 870 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1,016 B After Width: | Height: | Size: 1,016 B |
Before Width: | Height: | Size: 1,016 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1,018 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 912 B |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1,006 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |