2020-09-15 11:10:16 +00:00
|
|
|
<template>
|
2021-02-28 15:10:26 +00:00
|
|
|
<Page @loaded="onPageLoad">
|
|
|
|
<ActionBar androidElevation="1">
|
|
|
|
<GridLayout rows="*" columns="auto, *">
|
|
|
|
<MDButton
|
|
|
|
class="er left"
|
|
|
|
variant="text"
|
|
|
|
:text="icon.back"
|
|
|
|
automationText="Back"
|
|
|
|
@tap="$navigateBack()"
|
|
|
|
col="0"
|
|
|
|
/>
|
|
|
|
<Label class="title orkm" :text="'Settings' | L" col="1" />
|
2020-10-14 19:32:32 +00:00
|
|
|
</GridLayout>
|
2021-02-28 15:10:26 +00:00
|
|
|
</ActionBar>
|
|
|
|
<ScrollView>
|
|
|
|
<StackLayout class="main-container">
|
|
|
|
<Label :text="'intf' | L" class="group-header orkm" />
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="selectAppLanguage"
|
|
|
|
>
|
|
|
|
<Label
|
|
|
|
col="0"
|
|
|
|
verticalAlignment="center"
|
|
|
|
class="er"
|
|
|
|
:text="icon.lang"
|
|
|
|
/>
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'lang' | L" />
|
|
|
|
<Label :text="appLanguage" class="info" />
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout columns="auto, *" class="option mdr" @tap="selectThemes">
|
|
|
|
<Label
|
|
|
|
col="0"
|
|
|
|
verticalAlignment="center"
|
|
|
|
class="er"
|
|
|
|
:text="icon.theme"
|
|
|
|
/>
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'Theme' | L" />
|
|
|
|
<Label :text="`${appTheme}` | L" class="info" />
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<StackLayout class="hr m-10"></StackLayout>
|
|
|
|
<Label :text="'opts' | L" class="group-header orkm" />
|
|
|
|
<GridLayout columns="auto, *, auto" class="option">
|
|
|
|
<Label
|
|
|
|
col="0"
|
|
|
|
verticalAlignment="center"
|
|
|
|
class="er"
|
|
|
|
:text="icon.shuf"
|
|
|
|
/>
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'sVw' | L" textWrap="true" />
|
|
|
|
<Label :text="`sVwInfo` | L" class="info" textWrap="true" />
|
|
|
|
</StackLayout>
|
|
|
|
<Switch
|
|
|
|
:color="shakeEnabled ? '#ff5200' : '#858585'"
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="2"
|
|
|
|
:checked="shakeEnabled"
|
|
|
|
@checkedChange="toggleShake"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<StackLayout class="hr m-10"></StackLayout>
|
|
|
|
<Label :text="'db' | L" class="group-header orkm" />
|
|
|
|
<GridLayout columns="auto, *" class="option mdr" @tap="exportCheck">
|
|
|
|
<Label col="0" class="er" :text="icon.exp" />
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'expBu' | L" textWrap="true" />
|
|
|
|
<Label
|
|
|
|
v-if="!backupInProgress"
|
|
|
|
:text="'buInfo' | L"
|
|
|
|
class="info"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
<GridLayout class="progressContainer" v-else columns="*, 64">
|
|
|
|
<MDProgress
|
|
|
|
col="0"
|
|
|
|
:value="backupProgress"
|
|
|
|
maxValue="100"
|
|
|
|
></MDProgress>
|
|
|
|
<Label col="1" :text="` ${backupProgress}%`" />
|
|
|
|
</GridLayout>
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout columns="auto, *" class="option mdr" @tap="importCheck">
|
|
|
|
<Label col="0" class="er" :text="icon.imp" />
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'impBu' | L" textWrap="true" />
|
|
|
|
<Label :text="'impInfo' | L" class="info" textWrap="true" />
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<StackLayout class="hr m-10"></StackLayout>
|
|
|
|
<Label :text="'rest' | L" class="group-header orkm" />
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="resetListItems('cuisines')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.reset" />
|
|
|
|
<Label
|
|
|
|
col="1"
|
|
|
|
verticalAlignment="center"
|
|
|
|
:text="'restCuiL' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="resetListItems('categories')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.reset" />
|
|
|
|
<Label
|
|
|
|
col="1"
|
|
|
|
verticalAlignment="center"
|
|
|
|
:text="'restCatL' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="resetListItems('yieldUnits')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.reset" />
|
|
|
|
<Label
|
|
|
|
col="1"
|
|
|
|
verticalAlignment="center"
|
|
|
|
:text="'restYUL' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="resetListItems('units')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.reset" />
|
|
|
|
<Label
|
|
|
|
col="1"
|
|
|
|
verticalAlignment="center"
|
|
|
|
:text="'restUL' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<Label class="group-info" :text="'restInfo' | L" textWrap="true" />
|
2021-01-13 05:02:48 +00:00
|
|
|
|
2021-02-28 15:10:26 +00:00
|
|
|
<StackLayout class="hr m-10"></StackLayout>
|
|
|
|
<Label :text="'help' | L" class="group-header orkm" />
|
2021-01-13 05:02:48 +00:00
|
|
|
|
2021-02-28 15:10:26 +00:00
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="openURL('https://t.me/enrecipes')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.tg" />
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'joinTG' | L" textWrap="true" />
|
|
|
|
<Label :text="'tgInfo' | L" class="info" textWrap="true" />
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="
|
|
|
|
openURL(
|
|
|
|
'https://github.com/vishnuraghavb/EnRecipes/wiki/User-Guide'
|
|
|
|
)
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.help" />
|
|
|
|
<Label
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="1"
|
|
|
|
:text="'guide' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="
|
|
|
|
openURL(
|
|
|
|
'https://github.com/vishnuraghavb/EnRecipes/blob/main/PRIVACY.md'
|
|
|
|
)
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.priv" />
|
|
|
|
<Label
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="1"
|
|
|
|
:text="'priv' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<StackLayout class="hr m-10"></StackLayout>
|
|
|
|
<Label :text="'About' | L" class="group-header orkm" />
|
2021-01-13 05:02:48 +00:00
|
|
|
|
2021-02-28 15:10:26 +00:00
|
|
|
<GridLayout columns="auto, *" class="option">
|
|
|
|
<Label col="0" class="er" :text="icon.info" />
|
|
|
|
<StackLayout col="1">
|
|
|
|
<Label :text="'ver' | L" />
|
|
|
|
<Label :text="getVersion" class="info" textWrap="true" />
|
|
|
|
</StackLayout>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="openURL('https://github.com/vishnuraghavb/enrecipes')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.gh" />
|
|
|
|
<Label
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="1"
|
|
|
|
:text="'gh' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="openURL('https://www.vishnuraghav.com/donate')"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.don" />
|
|
|
|
<Label
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="1"
|
|
|
|
:text="'donate' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<GridLayout
|
|
|
|
columns="auto, *"
|
|
|
|
class="option mdr"
|
|
|
|
@tap="
|
|
|
|
openURL(
|
|
|
|
'https://hosted.weblate.org/projects/enrecipes/app-translations'
|
|
|
|
)
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<Label col="0" class="er" :text="icon.trans" />
|
|
|
|
<Label
|
|
|
|
verticalAlignment="center"
|
|
|
|
col="1"
|
|
|
|
:text="'trnsl' | L"
|
|
|
|
textWrap="true"
|
|
|
|
/>
|
|
|
|
</GridLayout>
|
|
|
|
<Label class="group-info" :text="'appInfo' | L" textWrap="true" />
|
|
|
|
</StackLayout>
|
|
|
|
</ScrollView>
|
|
|
|
</Page>
|
2020-09-15 11:10:16 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-10-24 18:02:35 +00:00
|
|
|
import {
|
2021-01-13 05:02:48 +00:00
|
|
|
Application,
|
|
|
|
Utils,
|
2020-10-24 18:02:35 +00:00
|
|
|
ApplicationSettings,
|
|
|
|
path,
|
|
|
|
knownFolders,
|
2020-11-03 19:57:31 +00:00
|
|
|
File,
|
|
|
|
Folder,
|
2020-12-07 14:45:00 +00:00
|
|
|
Observable,
|
2021-02-28 15:10:26 +00:00
|
|
|
Device,
|
|
|
|
} from "@nativescript/core";
|
|
|
|
import * as Permissions from "@nativescript-community/perms";
|
|
|
|
import { Zip } from "@nativescript/zip";
|
|
|
|
import * as Toast from "nativescript-toast";
|
|
|
|
import * as Filepicker from "nativescript-plugin-filepicker";
|
|
|
|
import Theme from "@nativescript/theme";
|
|
|
|
import { localize, overrideLocale } from "@nativescript/localize";
|
|
|
|
import { mapState, mapActions } from "vuex";
|
|
|
|
import ActionDialog from "./modal/ActionDialog.vue";
|
|
|
|
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
|
|
|
import * as utils from "~/shared/utils";
|
2020-09-15 11:10:16 +00:00
|
|
|
export default {
|
|
|
|
data() {
|
|
|
|
return {
|
2020-11-03 19:57:31 +00:00
|
|
|
appTheme: "Light",
|
2020-12-07 14:45:00 +00:00
|
|
|
appLanguage: "English",
|
2020-11-06 09:07:41 +00:00
|
|
|
backupProgress: 0,
|
|
|
|
backupInProgress: false,
|
2021-02-28 15:10:26 +00:00
|
|
|
};
|
2020-09-15 11:10:16 +00:00
|
|
|
},
|
2020-10-14 19:32:32 +00:00
|
|
|
computed: {
|
2021-02-28 15:10:26 +00:00
|
|
|
...mapState([
|
|
|
|
"icon",
|
|
|
|
"recipes",
|
|
|
|
"cuisines",
|
|
|
|
"categories",
|
|
|
|
"yieldUnits",
|
|
|
|
"units",
|
|
|
|
"mealPlans",
|
|
|
|
"currentComponent",
|
|
|
|
"language",
|
|
|
|
"shakeEnabled",
|
|
|
|
"importSummary",
|
|
|
|
]),
|
2021-01-13 05:02:48 +00:00
|
|
|
getVersion() {
|
2021-02-28 15:10:26 +00:00
|
|
|
let ctx = Application.android.context;
|
|
|
|
return ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0)
|
|
|
|
.versionName;
|
2021-01-13 05:02:48 +00:00
|
|
|
},
|
2020-10-14 19:32:32 +00:00
|
|
|
},
|
2020-09-15 11:10:16 +00:00
|
|
|
methods: {
|
2021-02-28 15:10:26 +00:00
|
|
|
...mapActions([
|
|
|
|
"setCurrentComponentAction",
|
|
|
|
"importListItemsAction",
|
|
|
|
"importRecipesAction",
|
|
|
|
"importMealPlansAction",
|
|
|
|
"resetListItemsAction",
|
|
|
|
"setShakeAction",
|
|
|
|
"unlinkBrokenImages",
|
|
|
|
]),
|
|
|
|
onPageLoad(args) {
|
2020-12-07 14:45:00 +00:00
|
|
|
const page = args.object;
|
|
|
|
page.bindingContext = new Observable();
|
2021-02-28 15:10:26 +00:00
|
|
|
this.setCurrentComponentAction("Settings");
|
2020-10-21 17:54:45 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
// HELPERS
|
2021-02-28 15:10:26 +00:00
|
|
|
openURL(url) {
|
|
|
|
Utils.openUrl(url);
|
2021-01-13 05:02:48 +00:00
|
|
|
},
|
2020-12-07 14:45:00 +00:00
|
|
|
// LANGUAGE SELECTION
|
|
|
|
selectAppLanguage() {
|
2021-02-28 15:10:26 +00:00
|
|
|
let languages = this.language.map((e) => e.title);
|
|
|
|
this.$showModal(ActionDialog, {
|
2020-12-07 14:45:00 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "lang",
|
2021-02-28 15:10:26 +00:00
|
|
|
list: [...languages],
|
2020-12-29 10:35:19 +00:00
|
|
|
stretch: true,
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "lang",
|
2020-12-07 14:45:00 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((action) => {
|
|
|
|
if (action && action !== "Cancel" && this.appLanguage !== action) {
|
|
|
|
let currentLocale = Device.language.split("-")[0];
|
|
|
|
let locale = this.language.filter((e) => e.title === action)[0]
|
|
|
|
.locale;
|
|
|
|
if (currentLocale !== locale) {
|
|
|
|
this.$showModal(ConfirmDialog, {
|
2020-12-07 14:45:00 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "appRst",
|
2021-02-28 15:10:26 +00:00
|
|
|
description: localize("nLangInfo"),
|
2021-01-13 05:02:48 +00:00
|
|
|
cancelButtonText: "cBtn",
|
|
|
|
okButtonText: "rst",
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "res",
|
|
|
|
bgColor: "#ff5200",
|
2020-12-07 14:45:00 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((result) => {
|
|
|
|
if (result) {
|
|
|
|
this.appLanguage = action;
|
|
|
|
ApplicationSettings.setString("appLanguage", action);
|
|
|
|
overrideLocale(locale);
|
|
|
|
setTimeout(utils.restartApp, 250);
|
2020-12-07 14:45:00 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-12-07 14:45:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-12-07 14:45:00 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
// THEME SELECTION
|
|
|
|
selectThemes() {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.$showModal(ActionDialog, {
|
2020-10-21 17:54:45 +00:00
|
|
|
props: {
|
|
|
|
title: "Theme",
|
2021-02-28 15:10:26 +00:00
|
|
|
list: ["Light", "Dark"],
|
2021-01-13 05:02:48 +00:00
|
|
|
stretch: false,
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "theme",
|
2020-10-21 17:54:45 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((action) => {
|
|
|
|
if (action && action !== "Cancel" && this.appTheme !== action) {
|
|
|
|
this.$showModal(ConfirmDialog, {
|
2020-10-21 17:54:45 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "appRst",
|
2021-02-28 15:10:26 +00:00
|
|
|
description: localize("nThmInfo"),
|
2021-01-13 05:02:48 +00:00
|
|
|
cancelButtonText: "cBtn",
|
|
|
|
okButtonText: "rst",
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "res",
|
|
|
|
bgColor: "#ff5200",
|
2020-10-21 17:54:45 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((result) => {
|
|
|
|
if (result) {
|
|
|
|
this.appTheme = action;
|
|
|
|
ApplicationSettings.setString("appTheme", action);
|
|
|
|
setTimeout(utils.restartApp, 250);
|
2020-10-21 17:54:45 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-10-21 17:54:45 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-09-15 11:10:16 +00:00
|
|
|
},
|
2020-12-29 10:35:19 +00:00
|
|
|
// SHAKE VIEW RANDOM RECIPE
|
2021-02-28 15:10:26 +00:00
|
|
|
toggleShake(args) {
|
|
|
|
let checked = args.object.checked;
|
2021-02-28 17:34:27 +00:00
|
|
|
if (checked && !utils.hasAccelerometer()) {
|
|
|
|
args.object.checked = false;
|
|
|
|
Toast.makeText(localize("noAccSensor"), "long").show();
|
|
|
|
} else {
|
|
|
|
ApplicationSettings.setBoolean("shakeEnabled", checked);
|
|
|
|
this.setShakeAction(checked);
|
|
|
|
}
|
2020-12-29 10:35:19 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
// EXPORT HANDLERS
|
|
|
|
exportCheck() {
|
2021-02-28 15:10:26 +00:00
|
|
|
if (!this.recipes.length) {
|
|
|
|
Toast.makeText(localize("aFBu")).show();
|
2020-12-29 10:35:19 +00:00
|
|
|
} else {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.permissionCheck(
|
|
|
|
this.permissionConfirmation,
|
|
|
|
localize("reqAcc"),
|
|
|
|
this.exportBackup
|
|
|
|
);
|
2020-11-06 09:07:41 +00:00
|
|
|
}
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
exportBackup() {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.exportFiles("create");
|
|
|
|
let date = new Date();
|
|
|
|
let formattedDate =
|
|
|
|
date.getFullYear() +
|
|
|
|
"-" +
|
|
|
|
("0" + (date.getMonth() + 1)).slice(-2) +
|
|
|
|
"-" +
|
|
|
|
("0" + date.getDate()).slice(-2) +
|
|
|
|
"_" +
|
|
|
|
("0" + date.getHours()).slice(-2) +
|
|
|
|
("0" + date.getMinutes()).slice(-2) +
|
|
|
|
("0" + date.getSeconds()).slice(-2);
|
|
|
|
const sdDownloadPath = Folder.fromPath(
|
|
|
|
android.os.Environment.getExternalStorageDirectory().getAbsolutePath()
|
|
|
|
).getFolder("Download").path;
|
|
|
|
let fromPath = path.join(knownFolders.documents().path, "EnRecipes");
|
|
|
|
let destPath = path.join(
|
|
|
|
sdDownloadPath,
|
|
|
|
`EnRecipes-Backup_${formattedDate}.zip`
|
|
|
|
);
|
|
|
|
this.backupInProgress = true;
|
|
|
|
Zip.zip({
|
2020-11-03 19:57:31 +00:00
|
|
|
directory: fromPath,
|
|
|
|
archive: destPath,
|
2021-02-28 15:10:26 +00:00
|
|
|
onProgress: (progress) => {
|
|
|
|
this.backupProgress = progress;
|
2020-11-06 09:07:41 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((success) => {
|
|
|
|
Toast.makeText(
|
|
|
|
"Backup file successfully saved to Download folder",
|
|
|
|
"long"
|
|
|
|
).show();
|
|
|
|
this.exportFiles("delete");
|
|
|
|
setTimeout((e) => (this.backupInProgress = false), 3000);
|
|
|
|
});
|
2020-09-15 11:10:16 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
exportFiles(option) {
|
|
|
|
const folder = path.join(knownFolders.documents().path, "EnRecipes");
|
|
|
|
const EnRecipesFile = File.fromPath(path.join(folder, "recipes.json"));
|
|
|
|
let userCuisinesFile,
|
|
|
|
userCategoriesFile,
|
|
|
|
userYieldUnitsFile,
|
|
|
|
userUnitsFile,
|
|
|
|
mealPlansFile;
|
|
|
|
if (this.cuisines.length)
|
|
|
|
userCuisinesFile = File.fromPath(
|
|
|
|
path.join(folder, "userCuisines.json")
|
|
|
|
);
|
|
|
|
if (this.categories.length)
|
|
|
|
userCategoriesFile = File.fromPath(
|
|
|
|
path.join(folder, "userCategories.json")
|
|
|
|
);
|
|
|
|
if (this.yieldUnits.length)
|
|
|
|
userYieldUnitsFile = File.fromPath(
|
|
|
|
path.join(folder, "userYieldUnits.json")
|
|
|
|
);
|
|
|
|
if (this.units.length)
|
|
|
|
userUnitsFile = File.fromPath(path.join(folder, "userUnits.json"));
|
|
|
|
if (this.mealPlans.length)
|
|
|
|
mealPlansFile = File.fromPath(path.join(folder, "mealPlans.json"));
|
|
|
|
switch (option) {
|
2020-11-10 18:28:48 +00:00
|
|
|
case "create":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.writeDataToFile(EnRecipesFile, this.recipes);
|
|
|
|
this.cuisines.length &&
|
|
|
|
this.writeDataToFile(userCuisinesFile, this.cuisines);
|
|
|
|
this.categories.length &&
|
|
|
|
this.writeDataToFile(userCategoriesFile, this.categories);
|
|
|
|
this.yieldUnits.length &&
|
|
|
|
this.writeDataToFile(userYieldUnitsFile, this.yieldUnits);
|
|
|
|
this.units.length && this.writeDataToFile(userUnitsFile, this.units);
|
|
|
|
this.mealPlans.length &&
|
|
|
|
this.writeDataToFile(mealPlansFile, this.mealPlans);
|
|
|
|
break;
|
2020-11-10 18:28:48 +00:00
|
|
|
case "delete":
|
2021-02-28 15:10:26 +00:00
|
|
|
EnRecipesFile.remove();
|
|
|
|
this.cuisines.length && userCuisinesFile.remove();
|
|
|
|
this.categories.length && userCategoriesFile.remove();
|
|
|
|
this.yieldUnits.length && userYieldUnitsFile.remove();
|
|
|
|
this.units.length && userUnitsFile.remove();
|
|
|
|
this.mealPlans.length && mealPlansFile.remove();
|
|
|
|
break;
|
2020-11-10 18:28:48 +00:00
|
|
|
default:
|
2021-02-28 15:10:26 +00:00
|
|
|
break;
|
2020-11-03 19:57:31 +00:00
|
|
|
}
|
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
writeDataToFile(file, data) {
|
|
|
|
file.writeText(JSON.stringify(data));
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
// IMPORT HANDLERS
|
|
|
|
importCheck() {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.permissionCheck(
|
|
|
|
this.permissionConfirmation,
|
|
|
|
localize("reqAcc"),
|
|
|
|
this.openFilePicker
|
|
|
|
);
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
|
|
|
openFilePicker() {
|
2021-02-28 15:10:26 +00:00
|
|
|
Filepicker.create({
|
2020-12-29 10:35:19 +00:00
|
|
|
mode: "single",
|
2021-02-28 15:10:26 +00:00
|
|
|
extensions: ["zip"],
|
|
|
|
})
|
|
|
|
.present()
|
|
|
|
.then((selection) => {
|
|
|
|
Toast.makeText(localize("vrfy") + "...").show();
|
|
|
|
let zipPath = selection[0];
|
|
|
|
this.validateZipContent(zipPath);
|
|
|
|
});
|
2020-11-06 09:07:41 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
importDataToDB(data, db, zipPath) {
|
|
|
|
switch (db) {
|
2020-11-06 09:07:41 +00:00
|
|
|
case "EnRecipesDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importImages(zipPath);
|
|
|
|
this.importRecipesAction(data);
|
|
|
|
break;
|
2020-12-29 10:35:19 +00:00
|
|
|
case "userCuisinesDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importListItemsAction({
|
2020-12-29 10:35:19 +00:00
|
|
|
data,
|
|
|
|
listName: "cuisines",
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
|
|
|
break;
|
2020-11-06 09:07:41 +00:00
|
|
|
case "userCategoriesDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importListItemsAction({
|
2020-12-29 10:35:19 +00:00
|
|
|
data,
|
|
|
|
listName: "categories",
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
|
|
|
break;
|
2020-11-06 09:07:41 +00:00
|
|
|
case "userYieldUnitsDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importListItemsAction({
|
2020-12-29 10:35:19 +00:00
|
|
|
data,
|
|
|
|
listName: "yieldUnits",
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
|
|
|
break;
|
2020-12-29 10:35:19 +00:00
|
|
|
case "userUnitsDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importListItemsAction({
|
2020-12-29 10:35:19 +00:00
|
|
|
data,
|
|
|
|
listName: "units",
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
|
|
|
break;
|
2020-11-23 09:49:58 +00:00
|
|
|
case "mealPlansDB":
|
2021-02-28 15:10:26 +00:00
|
|
|
this.importMealPlansAction(data);
|
|
|
|
break;
|
2020-11-06 09:07:41 +00:00
|
|
|
default:
|
2021-02-28 15:10:26 +00:00
|
|
|
break;
|
2020-11-06 09:07:41 +00:00
|
|
|
}
|
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
hasValidJSON(data) {
|
2020-12-29 10:35:19 +00:00
|
|
|
try {
|
2021-02-28 15:10:26 +00:00
|
|
|
JSON.parse(data) && Array.isArray(JSON.parse(data));
|
|
|
|
} catch (e) {
|
2020-12-29 10:35:19 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
isFileDataValid(file) {
|
|
|
|
const files = file.filter((e) => File.exists(e.path));
|
|
|
|
if (files.length) {
|
|
|
|
let isValid = files.map((e) => false);
|
|
|
|
files.forEach((file, i) => {
|
|
|
|
File.fromPath(file.path)
|
|
|
|
.readText()
|
|
|
|
.then((data) => {
|
|
|
|
isValid[i] = this.hasValidJSON(data);
|
|
|
|
if (!isValid[i]) {
|
|
|
|
this.failedImport(
|
|
|
|
`${localize("buMod")}\n\n${localize("invFile")}: ${file.file}`
|
|
|
|
);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (isValid.every((e) => e === true)) {
|
|
|
|
files.forEach((file, i) => {
|
|
|
|
File.fromPath(file.path)
|
|
|
|
.readText()
|
|
|
|
.then((data) => {
|
|
|
|
this.importDataToDB(
|
|
|
|
JSON.parse(data),
|
|
|
|
file.db,
|
|
|
|
file.zipPath
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2020-12-29 10:35:19 +00:00
|
|
|
} else {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.failedImport(localize("buEmp"));
|
2020-12-29 10:35:19 +00:00
|
|
|
}
|
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
failedImport(description) {
|
|
|
|
this.$showModal(ConfirmDialog, {
|
2020-12-29 10:35:19 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "impFail",
|
2020-12-29 10:35:19 +00:00
|
|
|
description,
|
|
|
|
okButtonText: "OK",
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "alert",
|
|
|
|
bgColor: "#c92a2a",
|
2020-12-29 10:35:19 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
validateZipContent(zipPath) {
|
|
|
|
Zip.unzip({
|
2020-11-03 19:57:31 +00:00
|
|
|
archive: zipPath,
|
|
|
|
overwrite: true,
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((extractedFolderPath) => {
|
|
|
|
let cacheFolderPath = extractedFolderPath + "/EnRecipes";
|
|
|
|
const EnRecipesFilePath = cacheFolderPath + "/recipes.json";
|
|
|
|
const userCuisinesFilePath = cacheFolderPath + "/userCuisines.json";
|
|
|
|
const userCategoriesFilePath = cacheFolderPath + "/userCategories.json";
|
|
|
|
const userYieldUnitsFilePath = cacheFolderPath + "/userYieldUnits.json";
|
|
|
|
const userUnitsFilePath = cacheFolderPath + "/userUnits.json";
|
|
|
|
const mealPlansFilePath = cacheFolderPath + "/mealPlans.json";
|
|
|
|
if (Folder.exists(cacheFolderPath)) {
|
|
|
|
this.isFileDataValid([
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: EnRecipesFilePath,
|
|
|
|
db: "EnRecipesDB",
|
|
|
|
file: "recipes.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: userCuisinesFilePath,
|
|
|
|
db: "userCuisinesDB",
|
|
|
|
file: "userCuisines.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: userCategoriesFilePath,
|
|
|
|
db: "userCategoriesDB",
|
|
|
|
file: "userCategories.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: userYieldUnitsFilePath,
|
|
|
|
db: "userYieldUnitsDB",
|
|
|
|
file: "userYieldUnits.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: userUnitsFilePath,
|
|
|
|
db: "userUnitsDB",
|
|
|
|
file: "userUnits.json",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
zipPath,
|
|
|
|
path: mealPlansFilePath,
|
|
|
|
db: "mealPlansDB",
|
|
|
|
file: "mealPlans.json",
|
|
|
|
},
|
|
|
|
]);
|
2020-12-29 10:35:19 +00:00
|
|
|
} else {
|
2021-02-28 15:10:26 +00:00
|
|
|
Folder.fromPath(extractedFolderPath).remove();
|
|
|
|
this.failedImport(localize("buInc"));
|
2020-11-06 09:07:41 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
if (Folder.exists(cacheFolderPath + "/Images")) {
|
|
|
|
this.importImages(cacheFolderPath + "/Images");
|
2020-11-03 19:57:31 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
importImages(sourcePath) {
|
|
|
|
let dest = knownFolders.documents().path;
|
|
|
|
Zip.unzip({
|
2020-11-06 09:07:41 +00:00
|
|
|
archive: sourcePath,
|
|
|
|
directory: dest,
|
|
|
|
overwrite: true,
|
2021-02-28 15:10:26 +00:00
|
|
|
}).then((res) => {
|
|
|
|
this.showImportSummary();
|
|
|
|
this.unlinkBrokenImages();
|
|
|
|
});
|
2020-12-29 10:35:19 +00:00
|
|
|
},
|
|
|
|
showImportSummary() {
|
2021-02-28 15:10:26 +00:00
|
|
|
let { found, imported, updated } = this.importSummary;
|
|
|
|
let exists = Math.abs(found - imported - updated) + updated;
|
|
|
|
let importedNote = `\n${imported} ${localize("recI")}`;
|
|
|
|
let existsNote = `\n${exists} ${localize("recE")}`;
|
|
|
|
let updatedNote = `\n${updated} ${localize("recU")}`;
|
|
|
|
this.$showModal(ConfirmDialog, {
|
2020-12-29 10:35:19 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "impSuc",
|
2021-02-28 15:10:26 +00:00
|
|
|
description: `${found} ${localize(
|
|
|
|
"recF"
|
|
|
|
)}${importedNote}${existsNote}${updatedNote}`,
|
2020-12-29 10:35:19 +00:00
|
|
|
okButtonText: "OK",
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "succ",
|
|
|
|
bgColor: "#69db7c",
|
2020-12-29 10:35:19 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-11-03 19:57:31 +00:00
|
|
|
},
|
2020-11-10 18:28:48 +00:00
|
|
|
// PERMISSIONS HANDLER
|
2021-02-28 15:10:26 +00:00
|
|
|
permissionCheck(confirmation, description, action) {
|
|
|
|
if (!ApplicationSettings.getBoolean("storagePermissionAsked", false)) {
|
|
|
|
confirmation(description).then((e) => {
|
|
|
|
if (e) {
|
|
|
|
Permissions.request("photo").then((res) => {
|
|
|
|
let status = res[Object.keys(res)[0]];
|
|
|
|
if (status === "authorized") action();
|
|
|
|
if (status !== "denied")
|
|
|
|
ApplicationSettings.setBoolean("storagePermissionAsked", true);
|
|
|
|
else Toast.makeText(localize("dend")).show();
|
|
|
|
});
|
2020-11-03 19:57:31 +00:00
|
|
|
}
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-12-29 10:35:19 +00:00
|
|
|
} else {
|
2021-02-28 15:10:26 +00:00
|
|
|
Permissions.check("photo").then((res) => {
|
|
|
|
let status = res[Object.keys(res)[0]];
|
|
|
|
if (status !== "authorized") {
|
|
|
|
confirmation(description).then((e) => {
|
|
|
|
e && utils.openAppSettingsPage();
|
|
|
|
});
|
|
|
|
} else action();
|
|
|
|
});
|
2020-11-03 19:57:31 +00:00
|
|
|
}
|
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
permissionConfirmation(description) {
|
|
|
|
return this.$showModal(ConfirmDialog, {
|
2020-11-10 18:28:48 +00:00
|
|
|
props: {
|
2021-01-13 05:02:48 +00:00
|
|
|
title: "grant",
|
2020-11-10 18:28:48 +00:00
|
|
|
description,
|
2021-01-13 05:02:48 +00:00
|
|
|
cancelButtonText: "nNBtn",
|
|
|
|
okButtonText: "conBtn",
|
2021-02-28 15:10:26 +00:00
|
|
|
helpIcon: "folder",
|
|
|
|
bgColor: "#ff5200",
|
2020-11-10 18:28:48 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
});
|
2020-11-10 18:28:48 +00:00
|
|
|
},
|
2020-12-29 10:35:19 +00:00
|
|
|
// RESET
|
2021-02-28 15:10:26 +00:00
|
|
|
resetListItems(listName) {
|
|
|
|
this.resetListItemsAction(listName);
|
|
|
|
Toast.makeText(localize("restDone")).show();
|
|
|
|
},
|
2020-09-15 11:10:16 +00:00
|
|
|
},
|
2020-11-23 09:49:58 +00:00
|
|
|
mounted() {
|
2021-02-28 15:10:26 +00:00
|
|
|
this.appTheme = ApplicationSettings.getString("appTheme", "Light");
|
|
|
|
this.appLanguage = ApplicationSettings.getString(
|
|
|
|
"appLanguage",
|
|
|
|
localize("sysDef")
|
|
|
|
);
|
2020-10-14 19:32:32 +00:00
|
|
|
},
|
2021-02-28 15:10:26 +00:00
|
|
|
};
|
2020-09-15 11:10:16 +00:00
|
|
|
</script>
|