Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
Hosted Weblate 2021-06-08 18:19:45 +02:00
commit 3ca8f605d4
75 changed files with 1158 additions and 1050 deletions

View file

@ -1,15 +1,14 @@
import { TimerNotif } from './shared/utils'
const superProto = android.app.Service.prototype
android.app.Service.extend('com.tns.ForegroundService', {
onStartCommand: function(intent, flags, startId) {
console.log('onStartCommand')
superProto.onStartCommand.call(this, intent, flags, startId)
return android.app.Service.START_STICKY
},
onCreate: function() {
console.log('onCreate')
superProto.onCreate.call(this)
this.startForeground(777, this.getNotification())
this.startForeground(6, this.getNotification())
},
onBind: function(intent) {
return superProto.onBind.call(this, intent)
@ -18,17 +17,16 @@ android.app.Service.extend('com.tns.ForegroundService', {
return superProto.onUnbind.call(this, intent)
},
onDestroy: function() {
console.log('onDestroy')
this.stopForeground(true)
},
getNotification: function() {
return TimerNotif.getNotification(
{
bID: 'bringToFront',
bID: 'info',
cID: 'cti',
cName: 'Cooking Timer info',
description: `0 ongoing, 0 paused`,
nID: 777,
nID: 6,
priority: -2,
sound: null,
title: 'EnRecipes is running',

View file

@ -37,7 +37,7 @@ Page {
@extend .tb;
@extend .tw;
font-size: 25;
padding: 16;
padding: 16 16 24;
}
.Light {
color: $gray9;
@ -156,6 +156,7 @@ TextField.combField,
#searchBar {
border-color: transparent;
}
// -----------------------------
// Elements
TextField,
@ -181,28 +182,15 @@ TextView {
width: 100%;
}
progress {
margin: 16;
color: $orange;
width: 100%;
height: 2;
background-color: $gray5;
}
Switch {
background-color: $orange;
off-background-color: $gray5;
}
// -----------------------------
// Side Drawer
.segment {
border-radius: 12;
margin: 0 4 0 0;
padding: 0 12;
.value {
padding-left: 8;
vertical-alignment: center;
}
&.select {
color: $orange;
@extend .hl;
}
}
button {
background-color: transparent;
z-index: 0;
@ -214,14 +202,13 @@ button {
@extend .fade;
}
&.ico {
padding: 0;
margin: 0;
width: 48;
height: 48;
padding: 0;
margin: 0;
}
&.text {
@extend .tb;
horizontal-alignment: left;
color: $orange;
}
&.big {
@ -235,12 +222,6 @@ button {
&.min {
width: 40;
height: 40;
}
&.x {
width: 32;
height: 32;
min-width: 0;
margin: 0 0 0 4;
vertical-alignment: center;
}
&.rate {
@ -249,8 +230,31 @@ button {
height: 32;
}
}
ActivityIndicator {
width: 24;
height: 24;
margin: 12;
color: $orange;
}
// -----------------------------
// HOME
// Home
.segment {
border-radius: 12;
margin: 0 4 0 0;
padding: 0 12;
.value {
padding: 0 0 0 8;
vertical-alignment: center;
&.rtl {
padding: 0 8 0 0;
}
}
&.select {
color: $orange;
@extend .hl;
}
}
.emptyState {
padding: 16 16 8;
label {
@ -261,13 +265,18 @@ button {
font-size: 17;
}
}
// -----------------------------
// Recipe Items
// Recipe Item
.recipeItem {
padding: 8 16;
.recipeInfo {
vertical-alignment: center;
padding: 0 0 4 8;
&.rtl {
transform: none;
padding: 0 8 4 0;
}
}
.title {
padding: 0 0 4;
@ -275,6 +284,9 @@ button {
.attr {
font-size: 10;
padding: 0 6 1 2;
&.rtl {
padding: 0 2 1 6;
}
}
}
.simple .recipeInfo {
@ -283,7 +295,6 @@ button {
.minimal .title {
padding: 0;
}
.grid {
padding: 8;
.recipeInfo {
@ -311,39 +322,34 @@ button {
.imgHolder {
border-radius: 12;
}
// -----------------------------
// COOKING TIMER
.singleTimer {
padding: 8 16;
// -----------------------------
// CookingTimer
.timer {
padding: 8 16 0;
.info {
margin: 8;
}
.recipeTitle {
horizontal-alignment: left;
// font-size: 12;
margin: 8 8 8 16;
&.r {
margin: 8 16 8 8;
}
}
progress {
color: $orange;
width: 100%;
height: 4;
margin: 8 0 0;
}
}
// -----------------------------
// SETTINGS
// Settings
.group-info {
padding: 16 16 16 72;
line-height: 4;
}
.options-list {
.options {
.option {
vertical-align: center;
padding: 14 8;
margin: 0 16;
padding: 14 12;
.ico {
padding: 0;
margin: 0 24 0 16;
margin: 0 24 0 12;
}
.info,
.sub {
@ -359,7 +365,7 @@ button {
}
// -----------------------------
// ABOUT
// About
.app-info {
.icon {
horizontal-alignment: center;
@ -372,8 +378,9 @@ button {
line-height: 4;
}
}
// -----------------------------
// VIEW RECIPE
// ViewRecipe
.photo {
border-radius: 12;
margin: 24 16 0 0;
@ -396,15 +403,12 @@ button {
@extend .tw;
}
}
.clickable {
color: $orange;
}
.ingredient {
padding: 0 16;
.value {
@extend .tw;
vertical-align: center;
padding: 14 0 14 16;
padding: 14 16;
line-height: 4;
}
}
@ -416,13 +420,12 @@ button {
}
.value {
@extend .tw;
padding: 14 0 14 16;
padding: 14 16;
line-height: 4;
}
}
.done {
opacity: 0.5;
// @extend .fade;
.value {
text-decoration: line-through;
}
@ -443,8 +446,9 @@ button {
font-size: 12;
line-height: 4;
}
// -----------------------------
// APPBAR
// AppBar
.appbar {
z-index: 4;
min-height: 56;
@ -461,13 +465,16 @@ button {
padding: 14 16;
}
.fab {
margin-left: 4;
margin-left: 8;
}
&.home {
margin: 8 8 0;
}
}
.toolbar {
z-index: 4;
padding: 4;
margin-bottom: 0;
margin: 0 0 52;
horizontal-alignment: left;
.tool {
padding: 0 12;
@ -475,19 +482,20 @@ button {
vertical-alignment: center;
}
.ico {
padding-right: 8;
padding: 0 8 0 0;
&.rtl {
padding: 0 0 0 8;
}
}
}
}
.fab {
width: 48;
height: 48;
margin: 0 4 0 0;
border-radius: 12;
background: $orange;
}
// -----------------------------
// EDIT RECIPE
// EditRecipe
.sectionTitle {
@extend .tb;
@extend .tw;
@ -504,8 +512,9 @@ button {
font-size: 17;
color: $orange;
}
// -----------------------------
// MEAL PLANNER
// MealPlanner
.calendar {
padding: 0 8;
.navBtn {
@ -541,13 +550,13 @@ button {
}
.recipeTitle {
@extend .tw;
text-align: left;
padding: 16 8;
line-height: 4;
}
}
// -----------------------------
// DIALOGS
// Dialogs
.modal {
max-width: 320;
width: 100%;
@ -567,13 +576,12 @@ button {
padding: 0 16 8;
}
ListPicker {
width: 25%;
height: 128;
width: 30%;
height: 144;
margin: 16 0;
}
.listItem {
@extend .tw;
width: 100%;
letter-spacing: 0;
text-transform: none;
line-height: 4;
@ -607,32 +615,9 @@ button {
padding: 16;
line-height: 4;
}
// -----------------------------
ActivityIndicator {
width: 24;
height: 24;
margin: 12;
color: $orange;
}
// -----------------------------
// Transitions
.blink {
animation-name: blink;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: ease;
}
@keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.hl {
animation-name: hl;
animation-duration: 0.2s;
@ -661,3 +646,18 @@ ActivityIndicator {
opacity: 0.5;
}
}
// -----------------------------
// Helpers
.rtl {
transform: scaleX(-1);
}
.clickable {
color: $orange;
}
.hal {
horizontal-alignment: left;
&.r {
horizontal-alignment: right;
}
}

View file

@ -1,11 +1,17 @@
<template>
<Page @loaded="onPageLoad" actionBarHidden="true">
<GridLayout rows="*, auto" columns="auto, *">
<Page @loaded="pgLoad" actionBarHidden="true">
<RGridLayout :isRtl="RTL" rows="*, auto" columns="auto, *">
<OptionsList title="intf" :items="items" />
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
<GridLayout
:isRtl="RTL"
row="1"
class="appbar"
rows="*"
columns="auto, *"
>
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
</GridLayout>
</GridLayout>
</RGridLayout>
</Page>
</template>
@ -16,7 +22,7 @@ import {
Device,
Frame,
} from "@nativescript/core";
import { localize, overrideLocale } from "@nativescript/localize";
import { localize } from "@nativescript/localize";
import Action from "../modals/Action";
import Confirm from "../modals/Confirm";
import OptionsList from "../sub/OptionsList";
@ -27,11 +33,11 @@ export default {
components: { OptionsList },
data() {
return {
appLanguage: "English",
applang: 0,
};
},
computed: {
...mapState(["icon", "language", "appTheme", "layout"]),
...mapState(["icon", "language", "appTheme", "layout", "RTL"]),
items() {
return [
{},
@ -39,23 +45,21 @@ export default {
type: "list",
icon: "lang",
title: "lang",
subTitle: this.appLanguage,
action: this.selectAppLanguage,
subTitle: this.applang,
action: this.setAppLang,
},
{
type: "list",
icon: "theme",
title: "Theme",
subTitle: localize(
ApplicationSettings.getString("appTheme", "sysDef")
),
subTitle: ApplicationSettings.getString("appTheme", "sysDef"),
action: this.selectThemes,
},
{
type: "list",
icon: "layout",
title: "listVM",
subTitle: localize(this.layout),
subTitle: this.layout,
action: this.setLayoutMode,
},
{},
@ -63,12 +67,12 @@ export default {
},
},
methods: {
...mapActions(["setTheme", "setLayout"]),
onPageLoad({ object }) {
...mapActions(["setTheme", "setLayout", "setRTL"]),
pgLoad({ object }) {
object.bindingContext = new Observable();
},
// LANGUAGE SELECTION
selectAppLanguage() {
setAppLang() {
let languages = this.language.map((e) => e.title);
this.$showModal(Action, {
props: {
@ -76,26 +80,19 @@ export default {
list: [...languages],
},
}).then((action) => {
if (action && this.appLanguage !== action) {
let currentLocale = Device.language.split("-")[0];
if (action && this.applang !== action) {
let currentLocale = ApplicationSettings.getString(
"appLocale",
"none"
).split("-");
let locale = this.language.filter((e) => e.title === action)[0]
.locale;
if (currentLocale !== locale) {
this.$showModal(Confirm, {
props: {
title: "appRst",
description: localize("nLangInfo"),
cancelButtonText: "cBtn",
okButtonText: "rst",
},
}).then((result) => {
if (result) {
this.appLanguage = action;
ApplicationSettings.setString("appLanguage", action);
overrideLocale(locale);
setTimeout(utils.restartApp, 250);
}
});
this.applang = action;
ApplicationSettings.setString("applang", action);
ApplicationSettings.setString("appLocale", locale);
utils.updateLocale();
this.setRTL();
}
}
});
@ -111,7 +108,7 @@ export default {
if (
action &&
(ApplicationSettings.getString("appTheme") != this.appTheme
? true
? 1
: this.appTheme != action)
) {
this.setTheme(action);
@ -136,10 +133,7 @@ export default {
},
},
created() {
this.appLanguage = ApplicationSettings.getString(
"appLanguage",
localize("sysDef")
);
this.applang = ApplicationSettings.getString("applang", "sysDef");
},
};
</script>

View file

@ -320,5 +320,21 @@
"texp": "%s timers expired",
"dismiss": "Dismiss",
"dismissAll": "Dismiss all timers",
"ttv": "Tap to view"
"ttv": "Tap to view",
"oAP": "%1$s ongoing, %2$s paused",
"calVM": "Calendar view mode",
"mnthly": "Monthly",
"wkly": "Weekly",
"dly": "Daily",
"sun": "Sunday",
"mon": "Monday",
"tue": "Tuesday",
"wed": "Wednesday",
"thu": "Thursday",
"fri": "Friday",
"sat": "Saturday",
"cpy": "copy",
"tdy": "Today",
"tmrw": "Tomorrow",
"ystr": "Yesterday"
}

View file

@ -1,15 +1,98 @@
import {
Application,
AndroidApplication,
ApplicationSettings,
Utils,
Device,
Color,
Frame,
} from '@nativescript/core'
import {
localize,
androidLaunchEventLocalizationHandler,
} from '@nativescript/localize'
import { Application, AndroidApplication, Utils } from '@nativescript/core'
import Vue from 'nativescript-vue'
import EnRecipes from './components/EnRecipes.vue'
import EditRecipe from './components/EditRecipe.vue'
import MealPlanner from './components/MealPlanner.vue'
import CookingTimer from './components/CookingTimer.vue'
import GroceryList from './components/GroceryList.vue'
import store from './store'
import * as utils from '~/shared/utils'
const keepScreenOn = () => {
export const EventBus = new Vue()
let renderView: any = EnRecipes
import CollectionView from '@nativescript-community/ui-collectionview/vue'
Vue.use(CollectionView)
import { StackLayout, GridLayout, DockLayout } from '@nativescript-rtl/ui'
Vue.registerElement('RStackLayout', () => StackLayout)
Vue.registerElement('RGridLayout', () => GridLayout)
Vue.registerElement('RDockLayout', () => DockLayout)
import { myMixin } from './shared/mixins'
Vue.mixin(myMixin)
const initFrame = () => {
const vm = store
//MAIN INIT
vm.commit('setTheme', ApplicationSettings.getString('appTheme', 'sysDef'))
if (!vm.state.recipes.length) vm.commit('initRecipes')
vm.commit('initMealPlans')
vm.commit('initListItems')
vm.commit('initTimerPresets')
if (!Object.keys(vm.state.timerSound).length) {
let hasTimerSound = ApplicationSettings.getString('timerSound', null)
vm.commit(
'setTimerSound',
hasTimerSound ? JSON.parse(hasTimerSound) : utils.getTones().defaultTone
)
}
// INIT FRAME
const View = android.view.View as any
const window = Application.android.startActivity.getWindow()
const decorView = window.getDecorView()
let sdkv = parseInt(Device.sdkVersion)
function setColors(color) {
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 = () => {
let ctx = Utils.ad.getApplicationContext()
const pm = ctx.getSystemService(android.content.Context.POWER_SERVICE)
let isScreenOff = !pm.isInteractive()
if (isScreenOff) {
console.log('keepScreenOn')
console.log('showOverLockscreen')
const window = Application.android.startActivity.getWindow()
const windowMgr = android.view.WindowManager
const flags =
@ -17,42 +100,63 @@ const keepScreenOn = () => {
windowMgr.LayoutParams.FLAG_TURN_SCREEN_ON |
windowMgr.LayoutParams.FLAG_KEEP_SCREEN_ON
window.addFlags(flags)
function clearFlags(args) {
args.cancel = true
window.clearFlags(flags)
Application.android.off(
AndroidApplication.activityBackPressedEvent,
clearFlags
)
}
Application.android.on(
AndroidApplication.activityBackPressedEvent,
clearFlags
)
}
}
Application.on(Application.resumeEvent, keepScreenOn)
const intentListener = ({ intent, android }: any) => {
console.log(intent, android)
let action = ((intent || android).getStringExtra('action') ||
(android && android.getAction())) as string
if (action) {
console.log(action)
switch (action) {
case 'new_recipe':
renderView = EditRecipe
break
case 'planner':
renderView = MealPlanner
break
case 'timer':
renderView = CookingTimer
Vue.navigateTo(CookingTimer as any, {
animated: false,
})
break
case 'grocery':
renderView = GroceryList
break
}
}
}
Application.on(Application.resumeEvent, (args) => {
console.log('App Resume')
showOverLockscreen()
})
Application.on(Application.launchEvent, (args) => {
console.log('launching')
console.log('App Launch')
console.log('RTL', store.state.RTL)
store.commit('setRTL')
if (args.android) {
androidLaunchEventLocalizationHandler()
intentListener(args)
}
Application.android.on(
AndroidApplication.activityNewIntentEvent,
intentListener
)
Frame.on(Frame.loadedEvent, initFrame)
})
import Vue from 'nativescript-vue'
import EnRecipes from './components/EnRecipes.vue'
import CookingTimer from './components/CookingTimer.vue'
import store from './store'
export const EventBus = new Vue()
import CollectionView from '@nativescript-community/ui-collectionview/vue'
Vue.use(CollectionView)
import { lvMixin } from './shared/mixins'
Vue.mixin(lvMixin)
Application.on(Application.exitEvent, () => {
console.log('App Exit')
renderView = EnRecipes
Application.android.off(
AndroidApplication.activityNewIntentEvent,
intentListener
)
})
Vue.config.silent = false
@ -60,37 +164,5 @@ Vue.filter('L', localize)
new Vue({
store,
render: (h) => h(EnRecipes),
render: (h) => h('Frame', [h(renderView)]),
}).$start()
const intentListener = ({ intent, android }: any) => {
let ct = 'CookingTimer'
let action = (intent || android).getStringExtra('action')
console.log('calling: ', action)
if (action == 'open_timer' && store.state.currentComponent != ct) {
let openTimer = setInterval(() => {
let comp = store.state.currentComponent
if (comp == ct) clearInterval(openTimer)
else {
if (comp == 'CTSettings') Vue.navigateBack()
else {
Vue.navigateTo(CookingTimer)
store.commit('setComponent', 'CookingTimer')
}
}
}, 250)
}
}
Application.on(Application.launchEvent, () => {
Application.android.on(
AndroidApplication.activityNewIntentEvent,
intentListener
)
})
Application.on(Application.exitEvent, () => {
store.commit('setComponent', 'EnRecipes')
Application.android.off(
AndroidApplication.activityNewIntentEvent,
intentListener
)
})

View file

@ -11,13 +11,14 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" tools:node="remove" />
<uses-permission android:name="android.permission.INTERNET" tools:node="remove" />
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" />
<application android:extractNativeLibs="true" android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:hardwareAccelerated="true" android:largeHeap="true" android:theme="@style/AppTheme">
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:launchMode="singleInstance" android:screenOrientation="userPortrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize">
<application android:extractNativeLibs="true" android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/app_icon" android:label="@string/app_name" android:supportsRtl="true" android:hardwareAccelerated="true" android:largeHeap="true" android:theme="@style/AppTheme">
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:launchMode="singleTop" android:screenOrientation="userPortrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize">
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
</activity>
<activity android:name="com.tns.ErrorReportActivity" />
<service android:name="com.tns.ForegroundService" android:enabled="true" android:exported="false" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<foreground android:drawable="@drawable/app_icon_fg" />
<background android:drawable="@color/white" />
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@drawable/sc_add_fg" />
<background android:drawable="@color/orange" />
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@drawable/sc_grocery_fg" />
<background android:drawable="@color/orange" />
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@drawable/sc_planner_fg" />
<background android:drawable="@color/orange" />
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<foreground android:drawable="@drawable/sc_timer_fg" />
<background android:drawable="@color/orange" />
</adaptive-icon>

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 954 B

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 860 B

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 1,016 B

After

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,018 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -6,11 +6,18 @@ import {
Color,
path,
knownFolders,
TimerInfo,
} from '@nativescript/core'
import { localize } from '@nativescript/localize'
let timerOne
declare const global, android, androidx, com, java, Array: any
const PowerManager = android.os.PowerManager
const pm = Utils.android
.getApplicationContext()
.getSystemService(android.content.Context.POWER_SERVICE)
const wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 'Timers')
export const restartApp = () => {
const ctx = Utils.ad.getApplicationContext()
let mStartActivity = new android.content.Intent(
@ -60,14 +67,14 @@ export const vibrate = (duration) => {
if (vibratorService.hasVibrator()) vibratorService.vibrate(duration)
}
export const timer = (dur, callback) => {
clearInterval(timerOne)
callback(true)
clearInterval(timerOne)
timerOne = setInterval(() => {
dur--
callback(true)
if (dur == 0) {
callback(false)
clearInterval(timerOne)
callback(false)
}
}, 1000)
}
@ -285,12 +292,12 @@ export const shareText = (text, subject) => {
intent.putExtra(android.content.Intent.EXTRA_TEXT, text)
share(intent, subject)
}
export const shareImage = (image, subject) => {
export const shareImage = (image, subject, title) => {
let ctx = Application.android.context
const intent = getSendIntent('image/jpeg')
const baos = new java.io.ByteArrayOutputStream()
image.android.compress(android.graphics.Bitmap.CompressFormat.JPEG, 100, baos)
const tmpFile = new java.io.File(ctx.getExternalCacheDir(), 'EnRecipes.jpg')
const tmpFile = new java.io.File(ctx.getCacheDir(), `${title}.jpg`)
const fos = new java.io.FileOutputStream(tmpFile)
fos.write(baos.toByteArray())
fos.flush()
@ -304,6 +311,14 @@ export const shareImage = (image, subject) => {
share(intent, subject)
}
export const keepScreenOn = (bool) => {
let ctx =
Application.android.foregroundActivity || Application.android.startActivity
let window = ctx.getWindow()
let flag = android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
bool ? window.addFlags(flag) : window.clearFlags(flag)
}
// TIMER NOTIFICATION
export class TimerNotif {
static getIcon(ctx, icon) {
@ -322,26 +337,25 @@ export class TimerNotif {
// nID ? NotifySrv.cancel(nID) : NotifySrv.cancelAll()
NotifySrv.cancel(nID)
}
static getNotification(
{
multi,
actions,
bID,
cID,
cName,
description,
nID,
priority,
sound,
title,
vibrate,
}: {
multi?: boolean
actions?: boolean
bID: string
cID: string
cName: string
description: string
nID: number
priority: number
sound: string
title: string
@ -361,7 +375,6 @@ export class TimerNotif {
if (sdkv >= 26) {
const importance =
priority > 0 ? NotifyMgr.IMPORTANCE_HIGH : NotifyMgr.IMPORTANCE_MIN
console.log(priority, importance)
const AudioAttributes = android.media.AudioAttributes
const audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
@ -386,7 +399,7 @@ export class TimerNotif {
const PendingIntent = android.app.PendingIntent
const mainInt = new Intent(ctx, com.tns.NativeScriptActivity.class)
mainInt.putExtra('action', 'open_timer')
mainInt.putExtra('action', 'timer')
const mainPInt = PendingIntent.getActivity(
ctx,
1,
@ -395,10 +408,15 @@ export class TimerNotif {
)
// Action intent
let actionInt1, actionInt2, actionPInt1, actionPInt2
let actionInt1,
actionInt2,
actionInt3,
actionPInt1,
actionPInt2,
actionPInt3
if (actions) {
actionInt1 = new Intent(bID)
actionInt1.putExtra('action', 'stop')
actionInt1.putExtra('action', 'delay')
actionPInt1 = PendingIntent.getBroadcast(
ctx,
2,
@ -406,18 +424,26 @@ export class TimerNotif {
PendingIntent.FLAG_UPDATE_CURRENT
)
actionInt2 = new Intent(bID)
actionInt2.putExtra('action', 'delay')
actionInt2.putExtra('action', 'dismiss')
actionPInt2 = PendingIntent.getBroadcast(
ctx,
3,
actionInt2,
PendingIntent.FLAG_UPDATE_CURRENT
)
actionInt3 = new Intent(bID)
actionInt3.putExtra('action', 'dismissAll')
actionPInt3 = PendingIntent.getBroadcast(
ctx,
4,
actionInt3,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
// CREATE NOTIFICATION
let icon = TimerNotif.getIcon(ctx, 'ic_stat_notify_silhouette')
let icon = this.getIcon(ctx, 'notify_icon_sil')
let builder = new NotificationCompat.Builder(ctx, cID)
.setColor(new Color('#ff5200').android)
.setContentIntent(mainPInt)
@ -434,10 +460,12 @@ export class TimerNotif {
if (description) builder.setContentText(description)
if (vibrate) builder.setVibrate([500, 1000])
if (actions) {
builder.setDeleteIntent(actionPInt2)
builder.setFullScreenIntent(mainPInt, true)
builder.addAction(null, 'Stop', actionPInt1)
builder.addAction(null, 'Delay', actionPInt2)
if (multi) builder.addAction(null, localize('dismissAll'), actionPInt3)
else {
builder.addAction(null, localize('delay'), actionPInt1)
builder.addAction(null, localize('dismiss'), actionPInt2)
}
}
let notification = builder.build()
notification.flags =
@ -450,7 +478,45 @@ export class TimerNotif {
const NotifySrv = ctx.getSystemService(
android.content.Context.NOTIFICATION_SERVICE
)
NotifySrv.notify(data.nID, TimerNotif.getNotification(data, ctx))
NotifySrv.notify(data.nID, this.getNotification(data, ctx))
}
}
export class Printer {
static PrintPackage = global.androidx.print
static isSupported() {
return this.PrintPackage.PrintHelper.systemSupportsPrint()
}
static print(view) {
return new Promise((resolve, reject) => {
try {
let img: any
img = android.graphics.Bitmap.createBitmap(
view.getMeasuredWidth(),
view.getMeasuredHeight(),
android.graphics.Bitmap.Config.ARGB_8888
)
view.android.draw(new android.graphics.Canvas(img))
this.printImage(img).then(resolve, reject)
} catch (e) {
reject(e)
}
})
}
static printImage(img) {
return new Promise((resolve, reject) => {
try {
let callback = (success) => resolve(success)
let printHelper = new this.PrintPackage.PrintHelper(
Application.android.foregroundActivity
)
printHelper.setScaleMode(this.PrintPackage.PrintHelper.SCALE_MODE_FIT)
let jobName = 'MyPrintJob'
printHelper.printBitmap(jobName, img)
callback(true)
} catch (e) {
reject(e)
}
})
}
}
@ -489,3 +555,15 @@ export const getTones = () => {
return { tones, defaultTone: defaultToneUri ? defaultTone : tones[0] }
}
//DETECT RTL LANGUAGE
export const RTL = (): boolean => {
const ctx = Utils.android.getApplicationContext()
const config = ctx.getResources().getConfiguration()
return config.getLayoutDirection() == android.view.View.LAYOUT_DIRECTION_RTL
}
//WAKE LOCK
export const wakeLock = (bool) => {
bool ? !wl.isHeld() && wl.acquire() : wl.isHeld() && wl.release()
}

View file

@ -5,11 +5,17 @@ import { openOrCreate } from '@akylas/nativescript-sqlite'
import {
getFileAccess,
File,
ApplicationSettings,
Application,
knownFolders,
path,
} from '@nativescript/core'
import {
getNumber,
setNumber,
getString,
setString,
} from '@nativescript/core/application-settings'
import * as utils from '~/shared/utils'
// OPEN DATABASE FILE
const db = openOrCreate(
@ -31,6 +37,11 @@ db.execute(
'CREATE TABLE IF NOT EXISTS mealPlans (date INT, type TEXT, title TEXT)'
)
// CREATE timerPresets TABLE
db.execute(
'CREATE TABLE IF NOT EXISTS timerPresets (id INT PRIMARY KEY, label TEXT, time TEXT)'
)
const defaultCuisines = [
'American',
'Brazilian',
@ -136,21 +147,22 @@ const defaultUnits = [
'medium',
'large',
]
const listItems = {
cuisines: {
sort: true,
sort: 1,
defaultItems: defaultCuisines,
},
categories: {
sort: true,
sort: 1,
defaultItems: defaultCategories,
},
yieldUnits: {
sort: false,
sort: 0,
defaultItems: defaultYieldUnits,
},
units: {
sort: false,
sort: 0,
defaultItems: defaultUnits,
},
}
@ -227,10 +239,15 @@ export default new Vuex.Store({
trans: '\ue93c',
delay: '\ue93d',
ring: '\ue93e',
print: '\ue93f',
},
currentComponent: 'EnRecipes',
sortType: 'Oldest first',
sortType: 'random',
language: [
{
locale: 'ar',
title: 'العربية',
},
{
locale: 'da',
title: 'Dansk',
@ -239,10 +256,18 @@ export default new Vuex.Store({
locale: 'de',
title: 'Deutsch',
},
{
locale: 'en-IN',
title: 'English (IN)',
},
{
locale: 'en-GB',
title: 'English (UK)',
},
{
locale: 'en-US',
title: 'English (US)',
},
{
locale: 'es',
title: 'Español',
@ -267,10 +292,6 @@ export default new Vuex.Store({
locale: 'hi',
title: 'हिंदी',
},
{
locale: 'ml',
title: 'മലയാളം',
},
{
locale: 'id',
title: 'Indonesia',
@ -279,6 +300,14 @@ export default new Vuex.Store({
locale: 'it',
title: 'Italiano',
},
{
locale: 'ja',
title: '日本語',
},
{
locale: 'ml',
title: 'മലയാളം',
},
{
locale: 'nb-NO',
title: 'Norsk bokmål',
@ -287,10 +316,10 @@ export default new Vuex.Store({
locale: 'nl',
title: 'Nederlands',
},
// {
// locale: 'pt',
// title: 'Português',
// },
{
locale: 'pt',
title: 'Português',
},
{
locale: 'pt-BR',
title: 'Português (BR)',
@ -308,97 +337,114 @@ export default new Vuex.Store({
title: 'తెలుగు',
},
],
shakeEnabled: ApplicationSettings.getBoolean('shakeEnabled', true),
shakeEnabled: getNumber('shakeEnabled', 1),
importSummary: {
found: 0,
imported: 0,
updated: 0,
},
layout: ApplicationSettings.getString('layout', 'detailed'),
layout: getString('layout', 'detailed'),
selectedCuisine: null,
selectedCategory: null,
selectedTag: null,
appTheme: 'sysDef',
mondayFirst: ApplicationSettings.getBoolean('mondayFirst', false),
timerDelay: ApplicationSettings.getString('timerDelay', '1 minute'),
mondayFirst: getNumber('mondayFirst', 0),
timerDelay: getString('timerDelay', '1 minute'),
timerSound: {},
timerVibrate: ApplicationSettings.getBoolean('timerVibrate', false),
timerPresets: [
{
id: 534534563,
label: 'Soft Eggs',
recipeID: null,
time: '00:06:00',
timerInterval: null,
isPaused: false,
preset: 1,
},
{
id: 564646,
label: 'Medium Eggs',
recipeID: null,
time: '00:08:00',
timerInterval: null,
isPaused: false,
preset: 1,
},
{
id: 43276767,
label: 'Hard Eggs',
recipeID: null,
time: '00:10:00',
timerInterval: null,
isPaused: false,
preset: 1,
},
],
timerVibrate: getNumber('timerVibrate', 0),
timerPresets: [],
activeTimers: [],
timerIntervals: [],
FGService: 0,
RTL: 0,
},
mutations: {
addTimerPreset(state, timer) {
state.timerPresets.push(timer)
setRTL(state) {
state.RTL = utils.RTL() as any | 0
},
removeTimerPreset(state, index) {
state.timerPresets.splice(index, 1)
setFGService(state, val) {
state.FGService = val
},
addTimerPreset(state, timer) {
let i = state.timerPresets.findIndex((e) => e.id == timer.id)
if (state.timerPresets.some((e) => e.id == timer.id)) {
state.timerPresets.splice(i, 1, timer)
} else state.timerPresets.push(timer)
db.execute(
`REPLACE INTO timerPresets (id, label, time) VALUES (?, ?, ?)`,
[timer.id, timer.label, timer.time]
)
},
deleteTimerPreset(state, i) {
let id = state.timerPresets[i]
state.timerPresets.splice(i, 1)
db.execute(`DELETE FROM timerPresets WHERE id = ${id}`)
},
initTimerPresets(state) {
if (!state.timerPresets.length)
db.select(`SELECT * FROM timerPresets`).then((res) => {
res.forEach((t) => {
t.recipeID = 0
t.timerInt = 0
t.isPaused = 0
t.preset = 1
t.done = 0
state.timerPresets.push(t)
})
})
},
importTimerPresets(state, timers) {
let newPresets = timers.filter(
(e) => !state.timerPresets.some((f) => f.id === e.id)
)
newPresets.forEach((t) => {
db.execute(
`INSERT INTO timerPresets (id, label, time) VALUES (?, ?, ?)`,
[t.id, t.label, t.time]
)
state.timerPresets.push(t)
})
},
clearTimerInterval(state) {
state.activeTimers.forEach((e) => {
clearInterval(e.timerInterval)
e.timerInterval = null
clearInterval(e.timerInt)
e.timerInt = 0
})
},
addActiveTimer(state, { timer, index }) {
state.activeTimers.splice(index, 0, timer)
addActiveTimer(state, { timer, i }) {
state.activeTimers.splice(i, 0, timer)
},
sortActiveTimers(state) {
let a = state.activeTimers.reduce((acc, e) => {
;(acc[e.recipeID] = acc[e.recipeID] || []).push(e)
return acc
}, {})
state.activeTimers = [...(<any>Object).values(a).flat(2)]
},
updateActiveTimer(state, timer) {
let index = state.activeTimers.findIndex((e) => e.id == timer.id)
state.activeTimers.splice(index, 1, timer)
let i = state.activeTimers.findIndex((e) => e.id == timer.id)
state.activeTimers.splice(i, 1, timer)
},
removeActiveTimer(state, index) {
state.activeTimers.splice(index, 1)
removeActiveTimer(state, i) {
state.activeTimers.splice(i, 1)
},
setTimerDelay(state, delay) {
state.timerDelay = delay
ApplicationSettings.setString('timerDelay', delay)
setString('timerDelay', delay)
},
setTimerSound(state, sound) {
state.timerSound = {
title: sound.title,
uri: sound.uri,
}
ApplicationSettings.setString('timerSound', JSON.stringify(sound))
state.timerSound = sound
setString('timerSound', JSON.stringify(sound))
},
setTimerVibrate(state, bool) {
state.timerVibrate = bool
ApplicationSettings.setBoolean('timerVibrate', bool)
setTimerVibrate(state, n) {
state.timerVibrate = n
setNumber('timerVibrate', n)
},
clearImportSummary(state) {
for (const key in state.importSummary) state.importSummary[key] = 0
},
setFirstDay(state, bool) {
state.mondayFirst = bool
ApplicationSettings.setBoolean('mondayFirst', bool)
setFirstDay(state, n) {
state.mondayFirst = n | 0
setNumber('mondayFirst', n | 0)
},
setTheme(state, theme) {
switch (theme) {
@ -414,7 +460,7 @@ export default new Vuex.Store({
state.appTheme = theme
break
}
ApplicationSettings.setString('appTheme', theme)
setString('appTheme', theme)
},
clearFilter(state) {
state.selectedCuisine = state.selectedCategory = state.selectedTag = null
@ -436,8 +482,8 @@ export default new Vuex.Store({
state.recipes.push(e)
})
})
state.shakeEnabled = ApplicationSettings.getBoolean('shakeEnabled', true)
state.sortType = ApplicationSettings.getString('sortType', 'Oldest first')
state.shakeEnabled = getNumber('shakeEnabled', 1)
state.sortType = getString('sortType', 'random')
},
importRecipesFromJSON(state, recipes) {
let localRecipesIDs, partition
@ -463,6 +509,12 @@ export default new Vuex.Store({
r.yieldQuantity = r.yield.quantity
r.yieldUnit = r.yield.unit
delete r.yield
function getTime(d) {
return new Date(d).getTime()
}
r.lastTried = getTime(r.lastTried)
r.lastModified = getTime(r.lastModified)
r.created = getTime(r.created)
return r
})
}
@ -492,9 +544,9 @@ export default new Vuex.Store({
JSON.stringify(r.notes),
r.favorite ? 1 : 0,
r.tried ? 1 : 0,
r.lastTried ? new Date(r.lastTried).getTime() : null,
r.lastModified ? new Date(r.lastModified).getTime() : null,
r.created ? new Date(r.created).getTime() : null,
r.lastTried,
r.lastModified,
r.created,
]
)
})
@ -533,9 +585,9 @@ export default new Vuex.Store({
JSON.stringify(r.notes),
r.favorite ? 1 : 0,
r.tried ? 1 : 0,
r.lastTried ? new Date(r.lastTried).getTime() : null,
r.lastModified ? new Date(r.lastModified).getTime() : null,
r.created ? new Date(r.created).getTime() : null,
r.lastTried,
r.lastModified,
r.created,
]
)
}
@ -649,9 +701,9 @@ export default new Vuex.Store({
function exist({ id }, index: number) {
if (id === recipe.id) {
i = index
return true
return 1
}
return false
return 0
}
state.recipes.some(exist)
? Object.assign(state.recipes[i], recipe)
@ -659,9 +711,9 @@ export default new Vuex.Store({
},
deleteRecipes(state, ids) {
ids.forEach((id: string) => {
let index = state.recipes.findIndex((e) => e.id === id)
getFileAccess().deleteFile(state.recipes[index].image)
state.recipes.splice(index, 1)
let i = state.recipes.findIndex((e) => e.id === id)
getFileAccess().deleteFile(state.recipes[i].image)
state.recipes.splice(i, 1)
db.execute(`DELETE FROM recipes WHERE id = '${id}'`)
state.recipes.forEach((e, i) => {
if (e.combinations.includes(id)) {
@ -774,11 +826,11 @@ export default new Vuex.Store({
type = 'snacks'
break
}
return f.title === e.title && f.date === date && f.type === type
return f.title == e.title && f.date == date && f.type == type
})
} else {
return !state.mealPlans.some(
(f) => f.title === e.title && f.date === e.date && f.type === e.type
(f) => f.title == e.title && f.date == e.date && f.type == e.type
)
}
})
@ -835,47 +887,48 @@ export default new Vuex.Store({
)
})
},
addMealPlan(state, { date, type, title }) {
addMealPlan(state, { date, type, title, index, inDB }) {
let mealPlan = {
date,
type,
title,
}
state.mealPlans.push(mealPlan)
const cols = Object.keys(mealPlan).join(', ')
const placeholder = Object.keys(mealPlan)
.fill('?')
.join(', ')
db.execute(
`INSERT INTO mealPlans (${cols}) VALUES (${placeholder})`,
Object.values(mealPlan)
)
},
deleteMealPlan(state, { date, type, title }) {
let index = state.mealPlans.findIndex(
(e) => e.title === title && e.type === type && e.date === date
)
state.mealPlans.splice(index, 1)
state.mealPlans = [...state.mealPlans]
db.execute(
`DELETE FROM mealPlans WHERE date = ${date} AND type = '${type}' AND title = '${title}'`
)
},
toggleState(state, { id, key, setDate }) {
let index = state.recipes.findIndex((e) => e.id == id)
state.recipes[index][key] = state.recipes[index][key] ? 0 : 1
db.execute(
`UPDATE recipes SET ${key} = ${state.recipes[index][key]} WHERE id = '${id}'`
)
if (setDate) {
state.recipes[index].lastTried = new Date().getTime()
if (inDB) {
const cols = Object.keys(mealPlan).join(', ')
const placeholder = Object.keys(mealPlan)
.fill('?')
.join(', ')
db.execute(
`UPDATE recipes SET lastTried = ${state.recipes[index].lastTried} WHERE id = '${id}'`
`INSERT INTO mealPlans (${cols}) VALUES (${placeholder})`,
Object.values(mealPlan)
)
if (index === null) state.mealPlans.push(mealPlan)
} else {
state.mealPlans.splice(index, 0, mealPlan)
}
},
setComponent(state, comp) {
state.currentComponent = comp
deleteMealPlan(state, { date, type, title, index, inDB }) {
if (inDB) {
db.execute(
`DELETE FROM mealPlans WHERE date = ${date} AND type = '${type}' AND title = '${title}'`
)
} else {
state.mealPlans.splice(index, 1)
state.mealPlans = [...state.mealPlans]
}
},
toggleState(state, { id, key, setDate }) {
let i = state.recipes.findIndex((e) => e.id == id)
state.recipes[i][key] = state.recipes[i][key] ? 0 : 1
db.execute(
`UPDATE recipes SET ${key} = ${state.recipes[i][key]} WHERE id = '${id}'`
)
if (setDate) {
state.recipes[i].lastTried = new Date().getTime()
db.execute(
`UPDATE recipes SET lastTried = ${state.recipes[i].lastTried} WHERE id = '${id}'`
)
}
},
unSyncCombinations(state, { id, combinations }) {
state.recipes.forEach((e, i) => {
@ -890,19 +943,17 @@ export default new Vuex.Store({
})
},
setShake(state, shake) {
state.shakeEnabled = shake
ApplicationSettings.setBoolean('shakeEnabled', shake)
state.shakeEnabled = shake | 0
setNumber('shakeEnabled', shake | 0)
},
setRating(state, { id, rating }) {
let index = state.recipes.findIndex((e) => e.id == id)
state.recipes[index].rating = rating
let i = state.recipes.findIndex((e) => e.id == id)
state.recipes[i].rating = rating
db.execute(`UPDATE recipes SET rating = ${rating} WHERE id = '${id}'`)
},
toggleCart(state, { id }) {
let index = state.recipes.indexOf(
state.recipes.filter((e) => e.id === id)[0]
)
state.recipes[index].inBag = !state.recipes[index].inBag
let i = state.recipes.indexOf(state.recipes.filter((e) => e.id === id)[0])
state.recipes[i].inBag = !state.recipes[i].inBag
},
unlinkBrokenImages(state) {
state.recipes.forEach((r, i) => {
@ -924,11 +975,26 @@ export default new Vuex.Store({
},
},
actions: {
setRTL({ commit }) {
commit('setRTL')
},
sortActiveTimers({ commit }) {
commit('sortActiveTimers')
},
setFGService({ commit }, val) {
commit('setFGService', val)
},
addTimerPreset({ commit }, timer) {
commit('addTimerPreset', timer)
},
removeTimerPreset({ commit }, timer) {
commit('removeTimerPreset', timer)
deleteTimerPreset({ commit }, timer) {
commit('deleteTimerPreset', timer)
},
initTimerPresets({ commit }) {
commit('initTimerPresets')
},
importTimerPresets({ commit }, timers) {
commit('importTimerPresets', timers)
},
clearTimerInterval({ commit }) {
commit('clearTimerInterval')
@ -939,8 +1005,8 @@ export default new Vuex.Store({
updateActiveTimer({ commit }, timer) {
commit('updateActiveTimer', timer)
},
removeActiveTimer({ commit }, index) {
commit('removeActiveTimer', index)
removeActiveTimer({ commit }, i) {
commit('removeActiveTimer', i)
},
setTimerDelay({ commit }, delay) {
commit('setTimerDelay', delay)
@ -948,14 +1014,14 @@ export default new Vuex.Store({
setTimerSound({ commit }, sound) {
commit('setTimerSound', sound)
},
setTimerVibrate({ commit }, bool) {
commit('setTimerVibrate', bool)
setTimerVibrate({ commit }, n) {
commit('setTimerVibrate', n)
},
clearImportSummary({ commit }) {
commit('clearImportSummary')
},
setFirstDay({ commit }, bool) {
commit('setFirstDay', bool)
setFirstDay({ commit }, n) {
commit('setFirstDay', n)
},
setTheme({ commit }, theme) {
commit('setTheme', theme)
@ -1017,9 +1083,6 @@ export default new Vuex.Store({
toggleStateAction({ commit }, toggledRecipe) {
commit('toggleState', toggledRecipe)
},
setComponent({ commit }, comp) {
commit('setComponent', comp)
},
unSyncCombinationsAction({ commit }, combinations) {
commit('unSyncCombinations', combinations)
},

1233
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,8 @@
"dependencies": {
"@akylas/nativescript-sqlite": "^3.3.12",
"@nativescript-community/ui-collectionview": "^4.0.29",
"@nativescript/core": "^8.0.5",
"@nativescript-rtl/ui": "^0.1.8",
"@nativescript/core": "^8.0.7",
"@nativescript/local-notifications": "^5.0.3",
"@nativescript/localize": "^5.0.4",
"@triniwiz/nativescript-accelerometer": "^4.0.3",
@ -32,11 +33,11 @@
"devDependencies": {
"@nativescript/android": "8.0.0",
"@nativescript/types": "^8.0.1",
"@nativescript/webpack": "beta",
"@types/node": "^15.3.0",
"@nativescript/webpack": "^5.0.0-beta.12",
"@types/node": "^15.9.0",
"nativescript-vue-template-compiler": "~2.9.0",
"sass": "^1.32.13",
"sass": "^1.34.1",
"typescript": "^4.2.4",
"vue": "^2.6.12"
"vue": "^2.6.13"
}
}