couchbase and vuex integrated
This commit is contained in:
parent
1d7bca959e
commit
52446b3cd7
13 changed files with 437 additions and 371 deletions
|
@ -15,7 +15,7 @@
|
|||
|
||||
android {
|
||||
defaultConfig {
|
||||
minSdkVersion 23
|
||||
minSdkVersion 25
|
||||
generatedDensities = []
|
||||
ndk {
|
||||
abiFilters.clear()
|
||||
|
|
|
@ -1,40 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="__PACKAGE__"
|
||||
android:versionCode="10000"
|
||||
android:versionName="1.0">
|
||||
|
||||
<supports-screens
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:largeScreens="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<application
|
||||
android:usesCleartextTraffic="true"
|
||||
android:name="com.tns.NativeScriptApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity
|
||||
android:name="com.tns.NativeScriptActivity"
|
||||
android:label="@string/title_activity_kimera"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
|
||||
android:theme="@style/LaunchScreenTheme">
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="__PACKAGE__" android:versionCode="10000" android:versionName="1.0">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
||||
<!-- <uses-permission android:name="android.permission.CAMERA" /> -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- <uses-permission android:name="android.permission.READ_USER_DICTIONARY" /> -->
|
||||
<!-- <uses-permission android:name="android.permission.INTERNET"/> -->
|
||||
<!-- <uses-feature android:name="android.hardware.camera" android:required="true" /> -->
|
||||
<application android:usesCleartextTraffic="true" android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true">
|
||||
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme">
|
||||
<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>
|
||||
</activity>
|
||||
<activity android:name="com.tns.ErrorReportActivity"/>
|
||||
<activity android:name="com.tns.ErrorReportActivity" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<!-- theme to use AFTER launch screen is loaded-->
|
||||
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:forceDarkAllowed">true</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="toolbarStyle">@style/NativeScriptToolbarStyle</item>
|
||||
|
||||
<item name="colorPrimary">@color/ns_primary</item>
|
||||
|
|
|
@ -181,6 +181,10 @@ TabView {
|
|||
background: $grayD4;
|
||||
}
|
||||
}
|
||||
.ns-dark .date-time-picker-spinners {
|
||||
color: $grayL4;
|
||||
background: $grayD4;
|
||||
}
|
||||
// ActionBar
|
||||
ActionBar {
|
||||
width: 100%;
|
||||
|
|
|
@ -75,6 +75,14 @@
|
|||
</StackLayout>
|
||||
<StackLayout row="1">
|
||||
<StackLayout class="hr m-10"></StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="sd-item orkm"
|
||||
@tap="donate"
|
||||
>
|
||||
<Label class="bx" :text="icon.donate" margin="0 24 0 0" />
|
||||
<Label text="Donate" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
@tap="navigateTo(item.component, true, false)"
|
||||
v-for="(item, index) in bottommenu"
|
||||
|
@ -88,14 +96,6 @@
|
|||
<Label class="bx" :text="icon[item.icon]" margin="0 24 0 0" />
|
||||
<Label :text="item.title" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
orientation="horizontal"
|
||||
class="sd-item orkm"
|
||||
@tap="donate"
|
||||
>
|
||||
<Label class="bx" :text="icon.donate" margin="0 24 0 0" />
|
||||
<Label text="Donate" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
|
||||
|
@ -104,7 +104,6 @@
|
|||
<!-- Home -->
|
||||
<EnRecipes
|
||||
ref="enrecipes"
|
||||
:passedRecipes="recipes"
|
||||
:filterFavorites="filterFavorites"
|
||||
:filterMustTry="filterMustTry"
|
||||
:selectedCategory="selectedCategory"
|
||||
|
@ -134,10 +133,6 @@ import About from "./About.vue"
|
|||
import PromptDialog from "./modal/PromptDialog.vue"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
const cb = new Couchbase("enrecipes")
|
||||
const cbCat = new Couchbase("categories")
|
||||
|
||||
let page
|
||||
export default {
|
||||
components: {
|
||||
|
@ -145,6 +140,7 @@ export default {
|
|||
Settings,
|
||||
About,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
selectedCategory: null,
|
||||
|
@ -180,11 +176,10 @@ export default {
|
|||
},
|
||||
],
|
||||
catEditMode: false,
|
||||
recipes: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "currentComponent"]),
|
||||
...mapState(["icon", "recipes", "currentComponent"]),
|
||||
categories() {
|
||||
let arr = this.recipes.map((e) => {
|
||||
return e.category
|
||||
|
@ -193,7 +188,12 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setCurrentComponentAction", "renameCategoryAction"]),
|
||||
...mapActions([
|
||||
"setCurrentComponentAction",
|
||||
"initializeRecipes",
|
||||
"initializeCategories",
|
||||
"renameCategoryAction",
|
||||
]),
|
||||
toggleCatEdit() {
|
||||
this.catEditMode = !this.catEditMode
|
||||
this.setComponent("EnRecipes")
|
||||
|
@ -204,37 +204,19 @@ export default {
|
|||
setComponent(comp) {
|
||||
this.setCurrentComponentAction(comp)
|
||||
},
|
||||
editCategory(item) {
|
||||
editCategory(category) {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.$showModal(PromptDialog, {
|
||||
props: {
|
||||
title: `Rename category`,
|
||||
hint: item,
|
||||
hint: category,
|
||||
action: "RENAME",
|
||||
},
|
||||
}).then((result) => {
|
||||
}).then((newCategory) => {
|
||||
this.hijackGlobalBackEvent()
|
||||
if (result.length) {
|
||||
if (this.categories.includes(result)) {
|
||||
Toast.makeText("Category already exists!", "long").show()
|
||||
} else {
|
||||
let categories = cbCat.getDocument("categories").categories
|
||||
console.log(categories, categories.indexOf(item))
|
||||
categories.splice(categories.indexOf(item), 1)
|
||||
categories.push(result)
|
||||
categories.sort()
|
||||
categories = [...new Set(categories)]
|
||||
cbCat.updateDocument("categories", {
|
||||
categories: [...categories],
|
||||
})
|
||||
this.recipes.forEach((e, i) => {
|
||||
if (e.category == item) {
|
||||
e.category = result
|
||||
cb.updateDocument(e.id, e)
|
||||
}
|
||||
})
|
||||
this.catEditMode = false
|
||||
}
|
||||
if (newCategory.length) {
|
||||
this.renameCategoryAction({ current: category, updated: newCategory })
|
||||
this.catEditMode = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -308,8 +290,7 @@ export default {
|
|||
backstackVisible: false,
|
||||
})
|
||||
this.closeDrawer()
|
||||
this.catEditMode = false
|
||||
} else if (!this.catEditMode) {
|
||||
} else if (!this.catEditMode || !isCategory) {
|
||||
this.releaseGlobalBackEvent()
|
||||
this.hijackGlobalBackEvent()
|
||||
this.setComponent(to)
|
||||
|
@ -320,6 +301,7 @@ export default {
|
|||
this.$refs.enrecipes.updateFilter()
|
||||
this.closeDrawer()
|
||||
}
|
||||
this.catEditMode = false
|
||||
},
|
||||
restartApp() {
|
||||
// Code from nativescript-master-technology
|
||||
|
@ -358,10 +340,8 @@ export default {
|
|||
created() {
|
||||
let themeName = ApplicationSettings.getString("application-theme", "Light")
|
||||
setTimeout((e) => Theme.setMode(Theme[themeName]), 50)
|
||||
this.recipes = cb.query({ select: [] })
|
||||
cb.addDatabaseChangeListener((e) => {
|
||||
this.recipes = cb.query({ select: [] })
|
||||
})
|
||||
if (!this.recipes.length) this.initializeRecipes()
|
||||
if (!this.categories.length) this.initializeCategories()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<Page @loaded="initializePage" @unloaded="releaseBackEvent">
|
||||
<Page @unloaded="releaseBackEvent">
|
||||
<ActionBar :flat="viewIsScrolled ? false : true">
|
||||
<GridLayout rows="*" columns="auto, *, auto," class="actionBarContainer">
|
||||
<Label
|
||||
|
@ -62,13 +62,22 @@
|
|||
:text="icon.close"
|
||||
androidElevation="8"
|
||||
/>
|
||||
<Label
|
||||
v-else
|
||||
@tap="takePicture"
|
||||
class="bx fab-button"
|
||||
:text="icon.camera"
|
||||
androidElevation="8"
|
||||
/>
|
||||
<GridLayout v-else rows="auto" columns="*, auto, auto, *">
|
||||
<Label
|
||||
col="1"
|
||||
@tap="takePicture"
|
||||
class="bx fab-button"
|
||||
:text="icon.camera"
|
||||
androidElevation="8"
|
||||
/>
|
||||
<Label
|
||||
col="2"
|
||||
@tap="selectPicture"
|
||||
class="bx fab-button"
|
||||
:text="icon.image"
|
||||
androidElevation="8"
|
||||
/>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</AbsoluteLayout>
|
||||
|
||||
|
@ -268,7 +277,8 @@ import {
|
|||
getFileAccess,
|
||||
knownFolders,
|
||||
} from "@nativescript/core"
|
||||
import { Mediafilepicker } from "nativescript-mediafilepicker"
|
||||
import * as imagepicker from "nativescript-imagepicker"
|
||||
import * as camera from "@nativescript/camera"
|
||||
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
|
@ -276,13 +286,8 @@ import ActionDialog from "./modal/ActionDialog.vue"
|
|||
import PromptDialog from "./modal/PromptDialog.vue"
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
import { load } from "@nativescript/core/ui/builder"
|
||||
const cb = new Couchbase("enrecipes")
|
||||
const cbCat = new Couchbase("categories")
|
||||
|
||||
export default {
|
||||
props: ["recipeID", "selectedCategory"],
|
||||
props: ["recipeIndex", "recipeID", "selectedCategory"],
|
||||
data() {
|
||||
return {
|
||||
title: "New recipe",
|
||||
|
@ -308,63 +313,33 @@ export default {
|
|||
tried: false,
|
||||
lastModified: null,
|
||||
},
|
||||
tempRecipeContent: {},
|
||||
units: [
|
||||
"unit",
|
||||
"tsp",
|
||||
"Tbsp",
|
||||
"oz",
|
||||
"cup",
|
||||
"pt",
|
||||
"qt",
|
||||
"lb",
|
||||
"gal",
|
||||
"ml",
|
||||
"L",
|
||||
"mg",
|
||||
"g",
|
||||
"kg",
|
||||
"mm",
|
||||
"cm",
|
||||
"m",
|
||||
"in",
|
||||
"°C",
|
||||
"°F",
|
||||
],
|
||||
categories: [
|
||||
"Appetizers",
|
||||
"BBQ",
|
||||
"Beverages",
|
||||
"Breads",
|
||||
"Breakfast",
|
||||
"Desserts",
|
||||
"Dinner",
|
||||
"Drinks",
|
||||
"Healthy",
|
||||
"Lunch",
|
||||
"Main dishes",
|
||||
"Meat",
|
||||
"Noodles",
|
||||
"Pasta",
|
||||
"Poultry",
|
||||
"Rice",
|
||||
"Salads",
|
||||
"Sauces",
|
||||
"Seafood",
|
||||
"Side dishes",
|
||||
"Snacks",
|
||||
"Soups",
|
||||
"Undefined",
|
||||
"Vegan",
|
||||
"Vegetarian",
|
||||
],
|
||||
tempRecipeContent: {
|
||||
imageSrc: null,
|
||||
title: null,
|
||||
category: null,
|
||||
prepTime: "00:00",
|
||||
cookTime: "00:00",
|
||||
portionSize: 1,
|
||||
ingredients: [
|
||||
{
|
||||
item: "",
|
||||
quantity: null,
|
||||
unit: "unit",
|
||||
},
|
||||
],
|
||||
instructions: [""],
|
||||
notes: [""],
|
||||
references: [""],
|
||||
isFavorite: false,
|
||||
tried: false,
|
||||
lastModified: null,
|
||||
},
|
||||
blockModal: false,
|
||||
cbCat: [],
|
||||
newRecipeID: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "currentComponent"]),
|
||||
...mapState(["icon", "units", "recipes", "categories", "currentComponent"]),
|
||||
screenWidth() {
|
||||
return Screen.mainScreen.widthDIPs
|
||||
},
|
||||
|
@ -380,31 +355,12 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setCurrentComponentAction"]),
|
||||
initializePage() {
|
||||
setTimeout((e) => {
|
||||
this.setCurrentComponentAction("EditRecipe")
|
||||
}, 500)
|
||||
this.title = this.recipeID ? "Edit recipe" : "New recipe"
|
||||
if (this.recipeID) {
|
||||
let recipe = cb.getDocument(this.recipeID)
|
||||
Object.assign(this.recipeContent, recipe)
|
||||
Object.assign(this.tempRecipeContent, recipe)
|
||||
} else {
|
||||
if (this.selectedCategory)
|
||||
this.recipeContent.category = this.selectedCategory
|
||||
Object.assign(this.tempRecipeContent, this.recipeContent)
|
||||
this.newRecipeID = this.getRandomID()
|
||||
}
|
||||
this.hijackBackEvent()
|
||||
|
||||
let isCategoriesStored = cbCat.query({ select: [] }).length
|
||||
if (isCategoriesStored) {
|
||||
this.categories = cbCat.getDocument("categories").categories
|
||||
} else {
|
||||
cbCat.createDocument({ categories: [...this.categories] }, "categories")
|
||||
}
|
||||
},
|
||||
...mapActions([
|
||||
"setCurrentComponentAction",
|
||||
"addRecipeAction",
|
||||
"overwriteRecipeAction",
|
||||
"addCategoryAction",
|
||||
]),
|
||||
getRandomID() {
|
||||
let res = ""
|
||||
let chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
@ -451,10 +407,20 @@ export default {
|
|||
this.clearEmptyFields()
|
||||
this.recipeContent.lastModified = new Date()
|
||||
if (this.recipeID) {
|
||||
cb.updateDocument(this.recipeID, this.recipeContent)
|
||||
this.overwriteRecipeAction({
|
||||
index: this.recipeIndex,
|
||||
id: this.recipeID,
|
||||
recipe: this.recipeContent,
|
||||
})
|
||||
} else {
|
||||
this.recipeContent.id = this.newRecipeID
|
||||
cb.createDocument(this.recipeContent, this.newRecipeID)
|
||||
this.addRecipeAction({
|
||||
id: this.newRecipeID,
|
||||
recipe: this.recipeContent,
|
||||
})
|
||||
}
|
||||
if (this.tempRecipeContent.imageSrc && !this.recipeContent.imageSrc) {
|
||||
getFileAccess().deleteFile(this.tempRecipeContent.imageSrc)
|
||||
}
|
||||
this.$navigateBack()
|
||||
},
|
||||
|
@ -485,15 +451,11 @@ export default {
|
|||
title: "New category",
|
||||
action: "ADD",
|
||||
},
|
||||
}).then((result) => {
|
||||
}).then((category) => {
|
||||
this.hijackBackEvent()
|
||||
if (result.length) {
|
||||
this.recipeContent.category = result
|
||||
this.categories.push(result)
|
||||
this.categories.sort()
|
||||
cbCat.updateDocument("categories", {
|
||||
categories: [...this.categories],
|
||||
})
|
||||
if (category.length) {
|
||||
this.recipeContent.category = category
|
||||
this.addCategoryAction(category)
|
||||
}
|
||||
})
|
||||
} else if (action) {
|
||||
|
@ -546,56 +508,58 @@ export default {
|
|||
}
|
||||
},
|
||||
takePicture() {
|
||||
let mediafilepicker = new Mediafilepicker()
|
||||
let vm = this
|
||||
const options = {
|
||||
width: this.screenWidth,
|
||||
height: this.screenWidth,
|
||||
lockSquare: true,
|
||||
}
|
||||
const androidOptions = {
|
||||
isFreeStyleCropEnabled: true,
|
||||
statusBarColor: "black",
|
||||
setAspectRatioOptions: {
|
||||
defaultIndex: 0,
|
||||
aspectRatios: [
|
||||
{
|
||||
aspectRatioTitle: "1:1",
|
||||
aspectRatioX: 1,
|
||||
aspectRatioY: 1,
|
||||
},
|
||||
{
|
||||
aspectRatioTitle: "16:9",
|
||||
aspectRatioX: 16,
|
||||
aspectRatioY: 9,
|
||||
},
|
||||
{
|
||||
aspectRatioTitle: "18:9",
|
||||
aspectRatioX: 18,
|
||||
aspectRatioY: 9,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
mediafilepicker.openImagePicker({
|
||||
android: {
|
||||
isCaptureMood: false, // if true then camera will open directly.
|
||||
isNeedCamera: true,
|
||||
maxNumberFiles: 1,
|
||||
isNeedFolderList: false,
|
||||
const vm = this
|
||||
camera.requestPermissions().then(
|
||||
() => {
|
||||
camera
|
||||
.takePicture({
|
||||
width: vm.screenWidth,
|
||||
height: vm.screenWidth,
|
||||
keepAspectRatio: false,
|
||||
saveToGallery: false,
|
||||
})
|
||||
.then((imageAsset) => {
|
||||
let result = imageAsset._android
|
||||
ImageSource.fromFile(result).then((savedImg) => {
|
||||
let savedImgPath = path.join(
|
||||
knownFolders.documents().getFolder("enrecipes").path,
|
||||
`${vm.getRandomID()}.jpg`
|
||||
)
|
||||
savedImg.saveToFile(savedImgPath, "jpg")
|
||||
vm.recipeContent.imageSrc = savedImgPath
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error -> " + err.message)
|
||||
})
|
||||
},
|
||||
() => {
|
||||
console.log("permission request rejected")
|
||||
}
|
||||
)
|
||||
},
|
||||
selectPicture() {
|
||||
let context = imagepicker.create({
|
||||
mode: "single",
|
||||
mediaType: "Image",
|
||||
})
|
||||
mediafilepicker.on("getFiles", function(res) {
|
||||
let result = res.object.get("results")[0].file
|
||||
ImageSource.fromFile(result).then((savedImg) => {
|
||||
let savedImgPath = path.join(
|
||||
knownFolders.documents().getFolder("enrecipes").path,
|
||||
`${vm.getRandomID()}.jpg`
|
||||
)
|
||||
savedImg.saveToFile(savedImgPath, "jpg")
|
||||
vm.recipeContent.imageSrc = savedImgPath
|
||||
context
|
||||
.authorize()
|
||||
.then(() => context.present())
|
||||
.then((selection) => {
|
||||
let result = selection[0]._android
|
||||
ImageSource.fromFile(result).then((savedImg) => {
|
||||
let savedImgPath = path.join(
|
||||
knownFolders.documents().getFolder("enrecipes").path,
|
||||
`${this.getRandomID()}.jpg`
|
||||
)
|
||||
savedImg.saveToFile(savedImgPath, "jpg")
|
||||
this.recipeContent.imageSrc = savedImgPath
|
||||
})
|
||||
})
|
||||
.catch(function(e) {
|
||||
console.log(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
removePicture() {
|
||||
confirm({
|
||||
|
@ -605,7 +569,6 @@ export default {
|
|||
cancelButtonText: "Cancel",
|
||||
}).then((e) => {
|
||||
if (e) {
|
||||
getFileAccess().deleteFile(this.recipeContent.imageSrc)
|
||||
this.recipeContent.imageSrc = null
|
||||
}
|
||||
})
|
||||
|
@ -657,5 +620,21 @@ export default {
|
|||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
setTimeout((e) => {
|
||||
this.setCurrentComponentAction("EditRecipe")
|
||||
}, 500)
|
||||
this.title = this.recipeID ? "Edit recipe" : "New recipe"
|
||||
if (this.recipeID) {
|
||||
let recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
||||
Object.assign(this.recipeContent, recipe)
|
||||
Object.assign(this.tempRecipeContent, recipe)
|
||||
} else {
|
||||
if (this.selectedCategory)
|
||||
this.recipeContent.category = this.selectedCategory
|
||||
this.newRecipeID = this.getRandomID()
|
||||
}
|
||||
this.hijackBackEvent()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -40,14 +40,14 @@
|
|||
/>
|
||||
<Label class="title orkm" :text="currentComponent" col="1" />
|
||||
<Label
|
||||
v-if="passedRecipes.length"
|
||||
v-if="recipes.length"
|
||||
class="bx"
|
||||
:text="icon.search"
|
||||
col="2"
|
||||
@tap="openSearch"
|
||||
/>
|
||||
<Label
|
||||
v-if="passedRecipes.length"
|
||||
v-if="recipes.length"
|
||||
class="bx"
|
||||
:text="icon.sort"
|
||||
col="3"
|
||||
|
@ -59,7 +59,7 @@
|
|||
<RadListView
|
||||
ref="listView"
|
||||
itemHeight="112"
|
||||
for="recipe in passedRecipes"
|
||||
for="recipe in recipes"
|
||||
swipeActions="true"
|
||||
@itemSwipeProgressChanged="onSwiping"
|
||||
@itemSwipeProgressEnded="onSwipeEnded"
|
||||
|
@ -115,7 +115,7 @@
|
|||
</v-template>
|
||||
</RadListView>
|
||||
<Label
|
||||
v-if="!passedRecipes.length && !filterFavorites && !filterMustTry"
|
||||
v-if="!recipes.length && !filterFavorites && !filterMustTry"
|
||||
class="noResults"
|
||||
text='Click the "+" icon to add a new recipe.'
|
||||
textWrap="true"
|
||||
|
@ -156,7 +156,6 @@
|
|||
|
||||
<script>
|
||||
import { Utils, AndroidApplication } from "@nativescript/core"
|
||||
import * as Toast from "nativescript-toast"
|
||||
|
||||
import EditRecipe from "./EditRecipe.vue"
|
||||
import ViewRecipe from "./ViewRecipe.vue"
|
||||
|
@ -164,12 +163,8 @@ import ActionDialog from "./modal/ActionDialog.vue"
|
|||
import ConfirmDialog from "./modal/ConfirmDialog.vue"
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
const cb = new Couchbase("enrecipes")
|
||||
|
||||
export default {
|
||||
props: [
|
||||
"passedRecipes",
|
||||
"filterFavorites",
|
||||
"filterMustTry",
|
||||
"selectedCategory",
|
||||
|
@ -192,25 +187,25 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "currentComponent"]),
|
||||
...mapState(["icon", "recipes", "currentComponent"]),
|
||||
filteredRecipes() {
|
||||
if (this.filterFavorites) {
|
||||
return this.passedRecipes.filter(
|
||||
return this.recipes.filter(
|
||||
(e) =>
|
||||
e.isFavorite && e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else if (this.filterMustTry) {
|
||||
return this.passedRecipes.filter(
|
||||
return this.recipes.filter(
|
||||
(e) => !e.tried && e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else if (this.selectedCategory) {
|
||||
return this.passedRecipes.filter(
|
||||
return this.recipes.filter(
|
||||
(e) =>
|
||||
e.category === this.selectedCategory &&
|
||||
e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
} else {
|
||||
return this.passedRecipes.filter((e) =>
|
||||
return this.recipes.filter((e) =>
|
||||
e.title.toLowerCase().includes(this.searchQuery)
|
||||
)
|
||||
}
|
||||
|
@ -343,7 +338,7 @@ export default {
|
|||
}
|
||||
},
|
||||
onSwipeEnded({ index }) {
|
||||
let recipeID = this.passedRecipes[index].id
|
||||
let recipeID = this.recipes[index].id
|
||||
if (this.rightAction && !this.deletionDialogActive)
|
||||
this.deleteRecipe(index, recipeID)
|
||||
this.rightAction = false
|
||||
|
@ -353,13 +348,13 @@ export default {
|
|||
this.$showModal(ConfirmDialog, {
|
||||
props: {
|
||||
title: "Delete recipe",
|
||||
description: `Are you sure you want to delete the recipe "${this.passedRecipes[index].title}"?`,
|
||||
description: `Are you sure you want to delete the recipe "${this.recipes[index].title}"?`,
|
||||
cancelButtonText: "CANCEL",
|
||||
okButtonText: "DELETE",
|
||||
},
|
||||
}).then((action) => {
|
||||
if (action) {
|
||||
cb.deleteDocument(recipeID)
|
||||
this.deleteRecipeAction({ index, id: recipeID })
|
||||
}
|
||||
this.deletionDialogActive = false
|
||||
})
|
||||
|
@ -405,7 +400,7 @@ export default {
|
|||
},
|
||||
})
|
||||
},
|
||||
viewRecipe({ item }) {
|
||||
viewRecipe({ item, index }) {
|
||||
this.$navigateTo(ViewRecipe, {
|
||||
transition: {
|
||||
name: "fade",
|
||||
|
@ -413,6 +408,7 @@ export default {
|
|||
curve: "easeIn",
|
||||
},
|
||||
props: {
|
||||
recipeIndex: index,
|
||||
recipeID: item.id,
|
||||
hijackGlobalBackEvent: this.hijackGlobalBackEvent,
|
||||
releaseGlobalBackEvent: this.releaseGlobalBackEvent,
|
||||
|
|
|
@ -67,6 +67,9 @@ import {
|
|||
} from "@nativescript/core"
|
||||
import * as permissions from "nativescript-permissions"
|
||||
import { Zip } from "nativescript-zip"
|
||||
import * as Toast from "nativescript-toast"
|
||||
|
||||
import * as filepicker from "nativescript-plugin-filepicker"
|
||||
|
||||
import Theme from "@nativescript/theme"
|
||||
import ActionDialog from "./modal/ActionDialog.vue"
|
||||
|
@ -174,14 +177,22 @@ export default {
|
|||
const sdDownloadPath = android.os.Environment.getExternalStoragePublicDirectory(
|
||||
android.os.Environment.DIRECTORY_DOWNLOADS
|
||||
).toString()
|
||||
let date = new Date()
|
||||
let fromPath = path.join(knownFolders.documents().path, "enrecipes")
|
||||
let destPath = path.join(sdDownloadPath, "enrecipes.zip")
|
||||
let destPath = path.join(
|
||||
sdDownloadPath,
|
||||
`enrecipes_${date.toString()}.zip`
|
||||
)
|
||||
console.log(fromPath, destPath, sdDownloadPath)
|
||||
Zip.zip({
|
||||
directory: fromPath,
|
||||
archive: destPath,
|
||||
})
|
||||
.then((success) => {
|
||||
Toast.makeText(
|
||||
"Backup file successfully saved to Downloads",
|
||||
"long"
|
||||
).show()
|
||||
console.log("success:" + success)
|
||||
})
|
||||
.catch((err) => {
|
||||
|
@ -197,13 +208,22 @@ export default {
|
|||
restoreData(args) {
|
||||
let btn = args.object
|
||||
this.highlight(args)
|
||||
permissions
|
||||
.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
.then(() => {
|
||||
alert("Restore successful!")
|
||||
let vm = this
|
||||
let context = filepicker.create({
|
||||
mode: "single", // use "multiple" for multiple selection
|
||||
extensions: ["zip"],
|
||||
})
|
||||
context
|
||||
.authorize()
|
||||
.then(function() {
|
||||
return context.present()
|
||||
})
|
||||
.catch(() => {
|
||||
console.log("Uh oh, no permissions - plan B time!")
|
||||
.then(function(selection) {
|
||||
let result = selection
|
||||
console.log(result)
|
||||
})
|
||||
.catch(function(e) {
|
||||
console.log(e)
|
||||
})
|
||||
},
|
||||
},
|
||||
|
|
|
@ -27,7 +27,13 @@
|
|||
verticalAlignment="bottom"
|
||||
/>
|
||||
</ScrollView>
|
||||
<Label row="0" col="2" class="bx" :text="icon.share" @tap="" />
|
||||
<Label
|
||||
row="0"
|
||||
col="2"
|
||||
class="bx"
|
||||
:text="icon.share"
|
||||
@tap="shareRecipe"
|
||||
/>
|
||||
<Label
|
||||
row="0"
|
||||
col="3"
|
||||
|
@ -260,18 +266,21 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { Screen, Utils } from "@nativescript/core"
|
||||
import { Screen, Utils, ImageSource, Device } from "@nativescript/core"
|
||||
import * as Toast from "nativescript-toast"
|
||||
import * as SocialShare from "nativescript-social-share"
|
||||
|
||||
import { mapState, mapActions } from "vuex"
|
||||
|
||||
import EditRecipe from "./EditRecipe.vue"
|
||||
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
const cb = new Couchbase("enrecipes")
|
||||
|
||||
export default {
|
||||
props: ["recipeID", "hijackGlobalBackEvent", "releaseGlobalBackEvent"],
|
||||
props: [
|
||||
"recipeIndex",
|
||||
"recipeID",
|
||||
"hijackGlobalBackEvent",
|
||||
"releaseGlobalBackEvent",
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
busy: false,
|
||||
|
@ -280,7 +289,7 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
...mapState(["icon", "recipes"]),
|
||||
screenWidth() {
|
||||
return Screen.mainScreen.widthDIPs
|
||||
},
|
||||
|
@ -291,17 +300,23 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["toggleMustTryAction", "setCurrentComponentAction"]),
|
||||
...mapActions(["toggleStateAction", "setCurrentComponentAction"]),
|
||||
initializePage() {
|
||||
this.recipe = cb.getDocument(this.recipeID)
|
||||
this.releaseGlobalBackEvent()
|
||||
this.busy = false
|
||||
setTimeout((e) => {
|
||||
this.setCurrentComponentAction("ViewRecipe")
|
||||
}, 500)
|
||||
this.portionScale = this.recipe.portionSize
|
||||
},
|
||||
roundedQuantity(quantity, unit) {
|
||||
return Math.round(quantity * this.isPortionScalePositive * 100) / 100
|
||||
roundedQuantity(quantity) {
|
||||
return (
|
||||
Math.round(
|
||||
(quantity / this.recipe.portionSize) *
|
||||
this.isPortionScalePositive *
|
||||
100
|
||||
) / 100
|
||||
)
|
||||
},
|
||||
editRecipe() {
|
||||
this.busy = true
|
||||
|
@ -312,15 +327,28 @@ export default {
|
|||
curve: "easeIn",
|
||||
},
|
||||
props: {
|
||||
recipeIndex: this.recipeIndex,
|
||||
recipeID: this.recipeID,
|
||||
},
|
||||
// backstackVisible: false,
|
||||
})
|
||||
},
|
||||
toggle(key) {
|
||||
this.recipe[key] = !this.recipe[key]
|
||||
cb.updateDocument(this.recipeID, this.recipe)
|
||||
this.recipe = cb.getDocument(this.recipeID)
|
||||
this.toggleStateAction({
|
||||
index: this.recipeIndex,
|
||||
id: this.recipeID,
|
||||
recipe: this.recipe,
|
||||
key,
|
||||
})
|
||||
},
|
||||
shareRecipe() {
|
||||
// if (this.recipe.imageSrc) {
|
||||
// let image = ImageSource.fromFile(this.recipe.imageSrc)
|
||||
// SocialShare.shareImage(image)
|
||||
// } else {
|
||||
// SocialShare.shareText("Text only")
|
||||
// }
|
||||
alert(Device.sdkVersion)
|
||||
},
|
||||
toggleFavorite() {
|
||||
this.recipe.isFavorite
|
||||
|
@ -345,7 +373,7 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
this.recipe = cb.getDocument(this.recipeID)
|
||||
this.recipe = this.recipes.filter((e) => e.id === this.recipeID)[0]
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -13,10 +13,10 @@ Vue.registerElement(
|
|||
() => require("nativescript-ui-sidedrawer").RadSideDrawer
|
||||
)
|
||||
|
||||
Vue.registerElement(
|
||||
"Fab",
|
||||
() => require("@nstudio/nativescript-floatingactionbutton").Fab
|
||||
)
|
||||
// Vue.registerElement(
|
||||
// "Fab",
|
||||
// () => require("@nstudio/nativescript-floatingactionbutton").Fab
|
||||
// )
|
||||
|
||||
if (TNS_ENV !== "production") {
|
||||
// Vue.use(VueDevtools)
|
||||
|
|
206
app/store.js
206
app/store.js
|
@ -1,11 +1,37 @@
|
|||
import Vue from "vue"
|
||||
import Vuex from "vuex"
|
||||
import { Couchbase } from "nativescript-couchbase-plugin"
|
||||
const recipesDB = new Couchbase("enrecipes")
|
||||
const categoriesDB = new Couchbase("categories")
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
// recipes: [],
|
||||
recipes: [],
|
||||
categories: [],
|
||||
units: [
|
||||
"unit",
|
||||
"tsp",
|
||||
"Tbsp",
|
||||
"oz",
|
||||
"cup",
|
||||
"pt",
|
||||
"qt",
|
||||
"lb",
|
||||
"gal",
|
||||
"ml",
|
||||
"L",
|
||||
"mg",
|
||||
"g",
|
||||
"kg",
|
||||
"mm",
|
||||
"cm",
|
||||
"m",
|
||||
"in",
|
||||
"°C",
|
||||
"°F",
|
||||
],
|
||||
icon: {
|
||||
home: "\ued99",
|
||||
heart: "\ued94",
|
||||
|
@ -39,71 +65,133 @@ export default new Vuex.Store({
|
|||
currentComponent: "EnRecipes",
|
||||
},
|
||||
mutations: {
|
||||
// addRecipe(state, recipe) {
|
||||
// state.recipes.push(recipe)
|
||||
// },
|
||||
// addCategory(state, category) {
|
||||
// let a = state.categories.filter((e) => e === category).length
|
||||
// if (a == 0) {
|
||||
// state.categories.push(category)
|
||||
// state.categories.sort()
|
||||
// }
|
||||
// },
|
||||
// overwriteRecipe(state, { index, recipe }) {
|
||||
// Object.assign(state.recipes[index], recipe)
|
||||
// },
|
||||
// deleteRecipe(state, index) {
|
||||
// state.recipes.splice(index, 1)
|
||||
// },
|
||||
// toggleFavorite(state, index) {
|
||||
// state.recipes[index].isFavorite = !state.recipes[index].isFavorite
|
||||
// },
|
||||
// toggleMustTry(state, index) {
|
||||
// state.recipes[index].tried = !state.recipes[index].tried
|
||||
// },
|
||||
initializeRecipes(state) {
|
||||
let a = recipesDB.query({ select: [] })
|
||||
a.forEach((e) => {
|
||||
state.recipes.push(e)
|
||||
})
|
||||
},
|
||||
initializeCategories(state) {
|
||||
let isCategoriesStored = categoriesDB.query({ select: [] }).length
|
||||
let cats
|
||||
if (isCategoriesStored) {
|
||||
cats = categoriesDB.getDocument("categories").categories
|
||||
} else {
|
||||
categoriesDB.createDocument(
|
||||
{
|
||||
categories: [
|
||||
"Appetizers",
|
||||
"BBQ",
|
||||
"Beverages",
|
||||
"Breads",
|
||||
"Breakfast",
|
||||
"Desserts",
|
||||
"Dinner",
|
||||
"Drinks",
|
||||
"Healthy",
|
||||
"Lunch",
|
||||
"Main dishes",
|
||||
"Meat",
|
||||
"Noodles",
|
||||
"Pasta",
|
||||
"Poultry",
|
||||
"Rice",
|
||||
"Salads",
|
||||
"Sauces",
|
||||
"Seafood",
|
||||
"Side dishes",
|
||||
"Snacks",
|
||||
"Soups",
|
||||
"Undefined",
|
||||
"Vegan",
|
||||
"Vegetarian",
|
||||
],
|
||||
},
|
||||
"categories"
|
||||
)
|
||||
cats = categoriesDB.getDocument("categories").categories
|
||||
}
|
||||
cats.forEach((e) => state.categories.push(e))
|
||||
},
|
||||
addRecipe(state, { id, recipe }) {
|
||||
state.recipes.push(recipe)
|
||||
recipesDB.createDocument(recipe, id)
|
||||
},
|
||||
addCategory(state, category) {
|
||||
let a = state.categories.filter((e) => e === category).length
|
||||
if (a == 0) {
|
||||
state.categories.push(category)
|
||||
state.categories.sort()
|
||||
categoriesDB.updateDocument("categories", {
|
||||
categories: [...state.categories],
|
||||
})
|
||||
}
|
||||
},
|
||||
overwriteRecipe(state, { index, id, recipe }) {
|
||||
Object.assign(state.recipes[index], recipe)
|
||||
recipesDB.updateDocument(id, recipe)
|
||||
},
|
||||
deleteRecipe(state, { index, id }) {
|
||||
state.recipes.splice(index, 1)
|
||||
recipesDB.deleteDocument(id)
|
||||
},
|
||||
toggleState(state, { index, id, recipe, key }) {
|
||||
state.recipes[index][key] = !state.recipes[index][key]
|
||||
recipesDB.updateDocument(id, recipe)
|
||||
},
|
||||
setCurrentComponent(state, comp) {
|
||||
state.currentComponent = comp
|
||||
},
|
||||
// renameCategory(state, { current, updated }) {
|
||||
// let a = state.categories.filter((e) => e === updated).length
|
||||
// if (a == 0) {
|
||||
// // add updated category to categories
|
||||
// state.categories.splice(state.categories.indexOf(current), 1)
|
||||
// state.categories.push(updated)
|
||||
// state.categories.sort()
|
||||
// // rename all occurences
|
||||
// state.recipes.forEach((e, i) => {
|
||||
// if (e.category == current) {
|
||||
// state.recipes[i].category = updated
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
renameCategory(state, { current, updated }) {
|
||||
let exists = state.categories.filter((e) => e === updated).length
|
||||
|
||||
state.categories.splice(state.categories.indexOf(current), 1)
|
||||
|
||||
// update recipes with updated category
|
||||
if (!exists) {
|
||||
state.categories.push(updated)
|
||||
state.categories.sort()
|
||||
categoriesDB.updateDocument("categories", {
|
||||
categories: [...state.categories],
|
||||
})
|
||||
}
|
||||
state.recipes.forEach((e, i) => {
|
||||
if (e.category == current) {
|
||||
state.recipes[i].category = updated
|
||||
recipesDB.inBatch(() => {
|
||||
recipesDB.updateDocument(state.recipes[i].id, state.recipes[i])
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// addRecipeAction({ commit }, recipe) {
|
||||
// commit("addRecipe", recipe)
|
||||
// },
|
||||
// addCategoryAction({ commit }, category) {
|
||||
// commit("addCategory", category)
|
||||
// },
|
||||
// overwriteRecipeAction({ commit }, updatedRecipe) {
|
||||
// commit("overwriteRecipe", updatedRecipe)
|
||||
// },
|
||||
// deleteRecipeAction({ commit }, index) {
|
||||
// commit("deleteRecipe", index)
|
||||
// },
|
||||
// toggleFavoriteAction({ commit }, index) {
|
||||
// commit("toggleFavorite", index)
|
||||
// },
|
||||
// toggleMustTryAction({ commit }, index) {
|
||||
// commit("toggleMustTry", index)
|
||||
// },
|
||||
initializeRecipes({ commit }) {
|
||||
commit("initializeRecipes")
|
||||
},
|
||||
initializeCategories({ commit }) {
|
||||
commit("initializeCategories")
|
||||
},
|
||||
addRecipeAction({ commit }, recipe) {
|
||||
commit("addRecipe", recipe)
|
||||
},
|
||||
addCategoryAction({ commit }, category) {
|
||||
commit("addCategory", category)
|
||||
},
|
||||
overwriteRecipeAction({ commit }, updatedRecipe) {
|
||||
commit("overwriteRecipe", updatedRecipe)
|
||||
},
|
||||
deleteRecipeAction({ commit }, recipe) {
|
||||
commit("deleteRecipe", recipe)
|
||||
},
|
||||
toggleStateAction({ commit }, toggledRecipe) {
|
||||
commit("toggleState", toggledRecipe)
|
||||
},
|
||||
setCurrentComponentAction({ commit }, comp) {
|
||||
commit("setCurrentComponent", comp)
|
||||
},
|
||||
// renameCategoryAction({ commit }, category) {
|
||||
// commit("renameCategory", category)
|
||||
// },
|
||||
renameCategoryAction({ commit }, category) {
|
||||
commit("renameCategory", category)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
62
package-lock.json
generated
62
package-lock.json
generated
|
@ -1095,17 +1095,20 @@
|
|||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@nativescript-community/perms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript-community/perms/-/perms-2.1.1.tgz",
|
||||
"integrity": "sha512-Ay4v1lEGTQ5rYYlYA8CKcCXuxOuyU4633r/JXi9aRG8MgxfOT+rDuQLgSz+LLCYmBK1ndfHHfyUTilkaUj1H8Q=="
|
||||
},
|
||||
"@nativescript/android": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript/android/-/android-7.0.1.tgz",
|
||||
"integrity": "sha512-VsZCJ5zfZo0+/lFwKz+S7iFb7MA2jgACB7y8dNje3/cnZl+moKPNjFqitoEP0DY4gLz9LJNbFIIaUt84tMdUSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@nativescript/camera": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript/camera/-/camera-5.0.2.tgz",
|
||||
"integrity": "sha512-frNeCLhdQ+W6oXIv05pALdmZDcwilw/NopLtQILtUwuLS7xhE+UMx6CqQxxCxMYzWKsvET2k9VLAo3mJGAoSeg==",
|
||||
"requires": {
|
||||
"nativescript-permissions": "~1.3.0"
|
||||
}
|
||||
},
|
||||
"@nativescript/core": {
|
||||
"version": "7.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@nativescript/core/-/core-7.0.12.tgz",
|
||||
|
@ -1203,11 +1206,6 @@
|
|||
"mkdirp": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"@nstudio/nativescript-floatingactionbutton": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@nstudio/nativescript-floatingactionbutton/-/nativescript-floatingactionbutton-3.0.3.tgz",
|
||||
"integrity": "sha512-xA7a/CKQ+kkuFLfgqFClEu+Hl2stMo5BS0qnpYW0gt//MHPNJf/OLlWQ5r5g2rAtw/AKZJGnCewMx2SfWaengQ=="
|
||||
},
|
||||
"@types/anymatch": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
||||
|
@ -5098,26 +5096,17 @@
|
|||
"to-regex": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"nativescript-camera": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-camera/-/nativescript-camera-4.5.0.tgz",
|
||||
"integrity": "sha512-Ecw9JH0CNgnGKXfqD1oifMoIOSnKBgWkecwVpdKfrChkQaCdKDFWdfdJ6X8+YTSwJH4n43e74JmrPzLN2eitwQ==",
|
||||
"requires": {
|
||||
"nativescript-permissions": "~1.3.0"
|
||||
}
|
||||
},
|
||||
"nativescript-couchbase-plugin": {
|
||||
"version": "0.9.6",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-couchbase-plugin/-/nativescript-couchbase-plugin-0.9.6.tgz",
|
||||
"integrity": "sha512-kMA9KHQX82TFaGnGUhY94KLOLss4pb5QmghgoEdu1sLwd94I/f1MQ+kHWbuBOdFmdQJw5oCK+Sey+A22Nd5jgA=="
|
||||
},
|
||||
"nativescript-mediafilepicker": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-mediafilepicker/-/nativescript-mediafilepicker-4.0.1.tgz",
|
||||
"integrity": "sha512-rBrZQR+46dCypIyLrzIlzmHgpmTSMGFR5a6snq8uUhtIqLlc674/nwWlNM1kFOxMh1kKxA+qyk74Of+NCKYoqQ==",
|
||||
"nativescript-imagepicker": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-imagepicker/-/nativescript-imagepicker-7.1.0.tgz",
|
||||
"integrity": "sha512-YFVwmPz7mv7mNXA7vmnIXmqPZiWxH4RoJPDL3m34egV8Ae9mKJCXZxl2LyPraOP+T4v6iXsxV9NSbjg0kMDuNQ==",
|
||||
"requires": {
|
||||
"@nativescript-community/perms": "^2.1.1",
|
||||
"ts-node": "^9.0.0"
|
||||
"nativescript-permissions": "~1.3.0"
|
||||
}
|
||||
},
|
||||
"nativescript-permissions": {
|
||||
|
@ -5125,6 +5114,19 @@
|
|||
"resolved": "https://registry.npmjs.org/nativescript-permissions/-/nativescript-permissions-1.3.11.tgz",
|
||||
"integrity": "sha512-4ox9WpVJPLfepPauqECvPfbxVE1hVPVVBLZxOs3d9+2Yrr0mSkJO7D7BQ4OUS90hHfRdPhf70aJKWxzJoqi63g=="
|
||||
},
|
||||
"nativescript-plugin-filepicker": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-plugin-filepicker/-/nativescript-plugin-filepicker-1.0.0.tgz",
|
||||
"integrity": "sha512-BOf7ycOQJGcg7ayzfbyFooMjngQgBAg6HAaws4fKQBRnI39aw7VVqXruuHSCDPqLW681/7GuECwWxknmAalOnQ==",
|
||||
"requires": {
|
||||
"nativescript-permissions": "~1.3.0"
|
||||
}
|
||||
},
|
||||
"nativescript-social-share": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-social-share/-/nativescript-social-share-1.6.0.tgz",
|
||||
"integrity": "sha512-PjSMseCWPGJbW0KPMgQBiTQke6I8cYxf0CGXtuJ0BnRhXrEjF3d+3kAnI8E3O8PeW/BFwNIqLYG4fkoQF4obyA=="
|
||||
},
|
||||
"nativescript-toast": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nativescript-toast/-/nativescript-toast-2.0.0.tgz",
|
||||
|
@ -7354,18 +7356,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
|
||||
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||
|
|
|
@ -8,15 +8,16 @@
|
|||
"run": "ns run android"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nativescript/camera": "^5.0.2",
|
||||
"@nativescript/core": "~7.0.0",
|
||||
"@nativescript/datetimepicker": "^2.0.4",
|
||||
"@nativescript/theme": "^3.0.0",
|
||||
"@nativescript/webpack": "3.0.0",
|
||||
"@nstudio/nativescript-floatingactionbutton": "^3.0.3",
|
||||
"nativescript-camera": "^4.5.0",
|
||||
"nativescript-couchbase-plugin": "^0.9.6",
|
||||
"nativescript-mediafilepicker": "^4.0.0",
|
||||
"nativescript-imagepicker": "^7.1.0",
|
||||
"nativescript-permissions": "^1.3.9",
|
||||
"nativescript-plugin-filepicker": "^1.0.0",
|
||||
"nativescript-social-share": "^1.6.0",
|
||||
"nativescript-toast": "^2.0.0",
|
||||
"nativescript-ui-listview": "^9.0.4",
|
||||
"nativescript-ui-sidedrawer": "^9.0.3",
|
||||
|
|
Loading…
Reference in a new issue