677 lines
18 KiB
JavaScript
677 lines
18 KiB
JavaScript
import Vue from "vue";
|
|
import Vuex from "vuex";
|
|
Vue.use(Vuex);
|
|
import {Couchbase} from "nativescript-couchbase-plugin";
|
|
import {getFileAccess, File, ApplicationSettings} from "@nativescript/core";
|
|
const EnRecipesDB = new Couchbase("EnRecipes");
|
|
const userCuisinesDB = new Couchbase("userCuisines");
|
|
const userCategoriesDB = new Couchbase("userCategories");
|
|
const userYieldUnitsDB = new Couchbase("userYieldUnits");
|
|
const userUnitsDB = new Couchbase("userUnits");
|
|
const mealPlansDB = new Couchbase("mealPlans");
|
|
const defaultCuisines = [
|
|
"American",
|
|
"Brazilian",
|
|
"British",
|
|
"Chinese",
|
|
"Danish",
|
|
"Egyptian",
|
|
"Filipino",
|
|
"French",
|
|
"German",
|
|
"Greek",
|
|
"Indian",
|
|
"Irish",
|
|
"Italian",
|
|
"Jamaican",
|
|
"Japanese",
|
|
"Jewish",
|
|
"Kenyan",
|
|
"Korean",
|
|
"Mexican",
|
|
"Nigerian",
|
|
"Portuguese",
|
|
"Russian",
|
|
"Scottish",
|
|
"Spanish",
|
|
"Sri Lankan",
|
|
"Swedish",
|
|
"Thai",
|
|
"Turkish",
|
|
"Vietnamese"
|
|
];
|
|
const defaultCategories = [
|
|
"Appetizers",
|
|
"Barbecue",
|
|
"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"
|
|
];
|
|
const defaultYieldUnits = [
|
|
"Serving",
|
|
"Piece",
|
|
"Teaspoon",
|
|
"Tablespoon",
|
|
"Fluid Ounce",
|
|
"Ounce",
|
|
"Pound",
|
|
"Gram",
|
|
"Kilogram",
|
|
"Cup",
|
|
"Gallon",
|
|
"Millilitre",
|
|
"Litre",
|
|
"Roll",
|
|
"Patty",
|
|
"Loaf"
|
|
];
|
|
const defaultUnits = [
|
|
"unit",
|
|
"tsp",
|
|
"dsp",
|
|
"tbsp",
|
|
"fl oz",
|
|
"cup",
|
|
"pt",
|
|
"qt",
|
|
"gal",
|
|
"ml",
|
|
"l",
|
|
"oz",
|
|
"lb",
|
|
"mg",
|
|
"g",
|
|
"kg",
|
|
"cm",
|
|
"in",
|
|
"leaf",
|
|
"clove",
|
|
"piece",
|
|
"pinch",
|
|
"drop",
|
|
"dozen",
|
|
"stick",
|
|
"small",
|
|
"medium",
|
|
"large"
|
|
];
|
|
const listItems = {
|
|
cuisines: {
|
|
db: userCuisinesDB,
|
|
key: "userCuisines",
|
|
stateName: "cuisines",
|
|
sort: true,
|
|
defaultItems: defaultCuisines
|
|
},
|
|
categories: {
|
|
db: userCategoriesDB,
|
|
key: "userCategories",
|
|
stateName: "categories",
|
|
sort: true,
|
|
defaultItems: defaultCategories
|
|
},
|
|
yieldUnits: {
|
|
db: userYieldUnitsDB,
|
|
key: "userYieldUnits",
|
|
stateName: "yieldUnits",
|
|
sort: false,
|
|
defaultItems: defaultYieldUnits
|
|
},
|
|
units: {
|
|
db: userUnitsDB,
|
|
key: "userUnits",
|
|
stateName: "units",
|
|
sort: false,
|
|
defaultItems: defaultUnits
|
|
}
|
|
};
|
|
export default new Vuex.Store({
|
|
state: {
|
|
recipes: [],
|
|
cuisines: [],
|
|
categories: [],
|
|
yieldUnits: [],
|
|
units: [],
|
|
mealPlans: [],
|
|
icon: {
|
|
home: "\ued3b",
|
|
heart: "\ued36",
|
|
heartLine: "\uea6c",
|
|
cuisine: "\ueb3e",
|
|
category: "\uec7c",
|
|
categoryLine: "\ue99c",
|
|
tag: "\uee12",
|
|
tagLine: "\ueb97",
|
|
cog: "\ueca6",
|
|
info: "\ued49",
|
|
menu: "\ueac1",
|
|
search: "\ueb54",
|
|
sort: "\ueac2",
|
|
plus: "\ueb21",
|
|
plusCircle: "\ueb22",
|
|
close: "\uebe9",
|
|
image: "\ued47",
|
|
food: "\ueb3e",
|
|
back: "\uea95",
|
|
save: "\uedeb",
|
|
camera: "\uec61",
|
|
share: "\uedf3",
|
|
edit: "\uedba",
|
|
theme: "\uecaa",
|
|
link: "\ueaa0",
|
|
file: "\ued02",
|
|
detail: "\ue9f9",
|
|
user: "\uee33",
|
|
trash: "\uee26",
|
|
donate: "\uece2",
|
|
trylater: "\uec31",
|
|
trylaterLine: "\ue94a",
|
|
note: "\ueb04",
|
|
copy: "\ue9e6",
|
|
check: "\ue9a4",
|
|
telegram: "\ueec7",
|
|
time: "\uee1a",
|
|
timeLine: "\ueba2",
|
|
item: "\ue99d",
|
|
step: "\ue948",
|
|
source: "\ueaa0",
|
|
export: "\ued07",
|
|
import: "\ued0c",
|
|
outline: "\ueb07",
|
|
calendar: "\uec55",
|
|
today: "\ue97c",
|
|
globe: "\uea5a",
|
|
lock: "\ued61",
|
|
github: "\uee8b",
|
|
gitlab: "\uee8c",
|
|
shuffle: "\ueb6b",
|
|
reset: "\ueb3d",
|
|
emptyCart: "\ue999",
|
|
cart: "\uec77",
|
|
meter: "\uee11",
|
|
meterLine: "\ueb96",
|
|
star: "\uee0a",
|
|
starLine: "\ueb83",
|
|
compass: "\uecb4",
|
|
show: "\uedfd",
|
|
ruler: "\uede9",
|
|
dish: "\uecd9",
|
|
restart: "\ueb3f",
|
|
fail: "\uee58",
|
|
success: "\uec85",
|
|
folder: "\ued1e",
|
|
error: "\uecf7",
|
|
zip: "\ued03",
|
|
text: "\ued82"
|
|
},
|
|
currentComponent: "EnRecipes",
|
|
sortType: "Oldest first",
|
|
language: [
|
|
{
|
|
locale: "da",
|
|
title: "Dansk"
|
|
}, {
|
|
locale: "de",
|
|
title: "Deutsch"
|
|
}, {
|
|
locale: "en-GB",
|
|
title: "English (United Kingdom)"
|
|
}, {
|
|
locale: "es",
|
|
title: "Español"
|
|
}, {
|
|
locale: "nl",
|
|
title: "Nederlands"
|
|
}, {
|
|
locale: "pt",
|
|
title: "Português"
|
|
}, {
|
|
locale: "ru",
|
|
title: "Русский"
|
|
}, {
|
|
locale: "ta",
|
|
title: "தமிழ்"
|
|
}
|
|
],
|
|
shakeEnabled: true,
|
|
importSummary: {
|
|
found: 0,
|
|
imported: 0,
|
|
updated: 0
|
|
}
|
|
},
|
|
mutations: {
|
|
setSortType(state, sortType) {
|
|
state.sortType = sortType
|
|
},
|
|
initializeRecipes(state) {
|
|
EnRecipesDB.query({select: []}).forEach(r => {
|
|
if (r.timeRequired) {
|
|
r.prepTime = "00:00";
|
|
r.cookTime = r.timeRequired;
|
|
delete r.timeRequired;
|
|
}
|
|
if (!r.hasOwnProperty("cuisine"))
|
|
r.cuisine = "Undefined"
|
|
if (!r.hasOwnProperty("tags"))
|
|
r.tags = []
|
|
if (!r.hasOwnProperty("difficulty"))
|
|
r.difficulty = "Easy"
|
|
if (!r.hasOwnProperty("rating"))
|
|
r.rating = 0
|
|
if (!r.hasOwnProperty("created"))
|
|
r.created = r.lastModified
|
|
if (!r.hasOwnProperty("inCart"))
|
|
r.inCart = false
|
|
state.recipes.push(r);
|
|
});
|
|
state.shakeEnabled = ApplicationSettings.getBoolean("shakeEnabled", true)
|
|
state.sortType = ApplicationSettings.getString("sortType", "Oldest first")
|
|
},
|
|
importRecipes(state, recipes) {
|
|
let localRecipesIDs,
|
|
partition
|
|
let imported = 0
|
|
let updated = 0
|
|
function getUpdatedData(data) {
|
|
return data.map(recipe => {
|
|
let r = Object.assign({}, recipe);
|
|
if (r.timeRequired) {
|
|
r.prepTime = "00:00";
|
|
r.cookTime = r.timeRequired;
|
|
delete r.timeRequired;
|
|
}
|
|
if (!r.hasOwnProperty("cuisine"))
|
|
r.cuisine = "Undefined"
|
|
if (!r.hasOwnProperty("tags"))
|
|
r.tags = []
|
|
if (!r.hasOwnProperty("difficulty"))
|
|
r.difficulty = "Easy"
|
|
if (!r.hasOwnProperty("rating"))
|
|
r.rating = 0
|
|
if (!r.hasOwnProperty("created"))
|
|
r.created = r.lastModified
|
|
if (!r.hasOwnProperty("inCart"))
|
|
r.inCart = false
|
|
return r;
|
|
});
|
|
}
|
|
function createDocuments(data) {
|
|
data = getUpdatedData(data);
|
|
state.recipes = [
|
|
...state.recipes,
|
|
...data
|
|
];
|
|
data.forEach(recipe => {
|
|
imported++
|
|
EnRecipesDB.createDocument(recipe, recipe.id);
|
|
});
|
|
}
|
|
function updateDocuments(data) {
|
|
data = getUpdatedData(data);
|
|
data.forEach(recipe => {
|
|
let recipeIndex = state.recipes.map((e, i) => {
|
|
let d1 = new Date(e.lastModified).getTime();
|
|
let d2 = new Date(recipe.lastModified).getTime();
|
|
return e.id === recipe.id && d1 < d2
|
|
? i
|
|
: -1;
|
|
}).filter(e => e >= 0)[0];
|
|
if (recipeIndex >= 0) {
|
|
updated++
|
|
Object.assign(state.recipes[recipeIndex], recipe);
|
|
EnRecipesDB.updateDocument(recipe.id, recipe);
|
|
}
|
|
});
|
|
}
|
|
if (state.recipes.length) {
|
|
localRecipesIDs = state.recipes.map(e => e.id);
|
|
partition = recipes.reduce((result, recipe, i) => {
|
|
localRecipesIDs.indexOf(recipe.id) < 0
|
|
? result[0].push(recipe) // create candidates
|
|
: result[1].push(recipe); // update candidates
|
|
return result;
|
|
}, [[], []]);
|
|
if (partition[0].length)
|
|
createDocuments(partition[0]);
|
|
if (partition[1].length)
|
|
updateDocuments(partition[1]);
|
|
}
|
|
else {
|
|
createDocuments(recipes);
|
|
}
|
|
state.importSummary.found = recipes.length
|
|
state.importSummary.imported = imported
|
|
state.importSummary.updated = updated
|
|
},
|
|
addRecipe(state, {id, recipe}) {
|
|
state.recipes.push(recipe);
|
|
EnRecipesDB.createDocument(recipe, id);
|
|
},
|
|
overwriteRecipe(state, {id, recipe}) {
|
|
let index = state.recipes.indexOf(state.recipes.filter(e => e.id === id)[0]);
|
|
Object.assign(state.recipes[index], recipe);
|
|
EnRecipesDB.updateDocument(id, recipe);
|
|
},
|
|
deleteRecipe(state, {index, id}) {
|
|
getFileAccess().deleteFile(state.recipes[index].imageSrc);
|
|
state.recipes.splice(index, 1);
|
|
EnRecipesDB.deleteDocument(id);
|
|
state.recipes.forEach((e, i) => {
|
|
if (e.combinations.includes(id)) {
|
|
state.recipes[i].combinations.splice(e.combinations.indexOf(id), 1);
|
|
EnRecipesDB.updateDocument(state.recipes[i].id, state.recipes[i]);
|
|
}
|
|
});
|
|
},
|
|
initializeListItems(state) {
|
|
function initialize(listName) {
|
|
let userItems;
|
|
let db = listItems[listName].db;
|
|
let key = listItems[listName].key;
|
|
let stateName = listItems[listName].stateName;
|
|
let defaultItems = listItems[listName].defaultItems;
|
|
if (!state[stateName].length) {
|
|
let isStored = db.query({select: []}).length;
|
|
if (isStored) {
|
|
userItems = db.getDocument(key)[key];
|
|
if (userItems.some(e => defaultItems.includes(e)))
|
|
state[stateName] = userItems;
|
|
else
|
|
state[stateName] = [
|
|
...defaultItems,
|
|
...userItems
|
|
];
|
|
}
|
|
else {
|
|
if (listItems[listName].sort) {
|
|
state[stateName].sort();
|
|
}
|
|
state[stateName] = defaultItems;
|
|
db.createDocument({
|
|
[key]: []
|
|
}, key);
|
|
}
|
|
}
|
|
}["cuisines", "categories", "yieldUnits", "units"].forEach(item => {
|
|
initialize(item);
|
|
});
|
|
},
|
|
importListItems(state, {data, listName}) {
|
|
let db = listItems[listName].db;
|
|
let key = listItems[listName].key;
|
|
let stateName = listItems[listName].stateName;
|
|
let items = new Set([
|
|
...state[stateName],
|
|
...data
|
|
]);
|
|
state[stateName] = [...items];
|
|
if (listItems[listName].sort)
|
|
state[stateName].sort();
|
|
db.updateDocument(key, {[key]: state[stateName]});
|
|
},
|
|
addListItem(state, {item, listName}) {
|
|
console.log(item, listName);
|
|
let db = listItems[listName].db;
|
|
let key = listItems[listName].key;
|
|
let stateName = listItems[listName].stateName;
|
|
let lowercase = state[stateName].map(e => e.toLowerCase());
|
|
if (lowercase.indexOf(item.toLowerCase()) == -1) {
|
|
state[stateName].push(item);
|
|
db.updateDocument(key, {[key]: state[stateName]});
|
|
if (listItems[listName].sort)
|
|
state[stateName].sort();
|
|
}
|
|
},
|
|
removeListItem(state, {item, listName}) {
|
|
let db = listItems[listName].db;
|
|
let key = listItems[listName].key;
|
|
let stateName = listItems[listName].stateName;
|
|
let index = state[stateName].indexOf(item);
|
|
state[stateName].splice(index, 1);
|
|
db.updateDocument(key, {[key]: state[stateName]});
|
|
if (listItems[listName].sort)
|
|
state[stateName].sort();
|
|
}
|
|
,
|
|
resetListItems(state, listName) {
|
|
let stateName = listItems[listName].stateName;
|
|
let defaultItems = listItems[listName].defaultItems;
|
|
state[listName] = [...defaultItems];
|
|
if (listItems[listName].sort) {
|
|
state[stateName].sort();
|
|
}
|
|
},
|
|
initializeMealPlans(state) {
|
|
let isMealPlansDBStored = mealPlansDB.query({select: []}).length;
|
|
if (isMealPlansDBStored) {
|
|
state.mealPlans = mealPlansDB.getDocument("mealPlans").mealPlans;
|
|
} else {
|
|
mealPlansDB.createDocument({
|
|
mealPlans: []
|
|
}, "mealPlans");
|
|
}
|
|
},
|
|
importMealPlans(state, mealPlans) {
|
|
let newMealPlans = mealPlans.filter(e => !state.mealPlans.some(f => f.title === e.title && f.startDate === e.startDate));
|
|
state.mealPlans = [
|
|
...state.mealPlans,
|
|
...newMealPlans
|
|
];
|
|
mealPlansDB.updateDocument("mealPlans", {mealPlans: state.mealPlans});
|
|
},
|
|
addMealPlan(state, {event, eventColor, index}) {
|
|
let mealPlan = {
|
|
title: event.title,
|
|
startDate: event.startDate,
|
|
endDate: event.endDate,
|
|
eventColor
|
|
}
|
|
if (index != null)
|
|
state.mealPlans.splice(index, 0, mealPlan);
|
|
else
|
|
state.mealPlans.push(mealPlan);
|
|
mealPlansDB.updateDocument("mealPlans", {
|
|
mealPlans: [...state.mealPlans]
|
|
});
|
|
},
|
|
deleteMealPlan(state, {title, startDate}) {
|
|
let mealPlan = state.mealPlans.filter(e => {
|
|
let sd = new Date(e.startDate).getTime();
|
|
return e.title === title && sd === startDate.getTime();
|
|
})[0];
|
|
let index = state.mealPlans.indexOf(mealPlan);
|
|
state.mealPlans.splice(index, 1);
|
|
state.mealPlans = [...state.mealPlans];
|
|
let mealPlans = mealPlansDB.getDocument("mealPlans").mealPlans;
|
|
mealPlans.splice(index, 1);
|
|
mealPlansDB.updateDocument("mealPlans", {
|
|
mealPlans: [...mealPlans]
|
|
});
|
|
},
|
|
toggleState(state, {id, recipe, key, setDate}) {
|
|
let index = state.recipes.indexOf(state.recipes.filter(e => e.id === id)[0]);
|
|
state.recipes[index][key] = !state.recipes[index][key];
|
|
if (setDate)
|
|
state.recipes[index].lastTried = new Date();
|
|
EnRecipesDB.updateDocument(id, recipe);
|
|
},
|
|
setRecipeAsTried(state, {id, recipe}) {
|
|
let index = state.recipes.indexOf(state.recipes.filter(e => e.id === id)[0]);
|
|
state.recipes[index].tried = true;
|
|
state.recipes[index].lastTried = new Date();
|
|
EnRecipesDB.updateDocument(id, recipe);
|
|
},
|
|
setLastTriedDate(state, index) {
|
|
state.recipes[index].lastTried = new Date();
|
|
EnRecipesDB.updateDocument(state.recipes[index].id, state.recipes[index]);
|
|
},
|
|
setCurrentComponent(state, comp) {
|
|
state.currentComponent = comp;
|
|
},
|
|
unSyncCombinations(state, {id, combinations}) {
|
|
state.recipes.forEach((e, i) => {
|
|
if (combinations.includes(e.id)) {
|
|
state.recipes[i].combinations.splice(e.combinations.indexOf(id), 1);
|
|
EnRecipesDB.updateDocument(state.recipes[i].id, state.recipes[i]);
|
|
}
|
|
});
|
|
},
|
|
setShake(state, shake) {
|
|
state.shakeEnabled = shake;
|
|
},
|
|
setRating(state, {id, recipe, rating}) {
|
|
let index = state.recipes.indexOf(state.recipes.filter(e => e.id === id)[0]);
|
|
state.recipes[index].rating = rating
|
|
EnRecipesDB.updateDocument(id, recipe);
|
|
},
|
|
toggleCart(state, {id, recipe}) {
|
|
let index = state.recipes.indexOf(state.recipes.filter(e => e.id === id)[0]);
|
|
state.recipes[index].inCart = !state.recipes[index].inCart
|
|
EnRecipesDB.updateDocument(id, recipe);
|
|
},
|
|
unlinkBrokenImages(state) {
|
|
state.recipes.forEach((r, i) => {
|
|
if (r.imageSrc && !File.exists(r.imageSrc)) {
|
|
r.imageSrc = null
|
|
Object.assign(state.recipes[i], r);
|
|
EnRecipesDB.updateDocument(r.id, r);
|
|
}
|
|
})
|
|
}
|
|
},
|
|
actions: {
|
|
setSortTypeAction({
|
|
commit
|
|
}, sortType) {
|
|
commit("setSortType", sortType)
|
|
},
|
|
initializeRecipes({commit}) {
|
|
commit("initializeRecipes");
|
|
},
|
|
importRecipesAction({
|
|
commit
|
|
}, recipes) {
|
|
commit("importRecipes", recipes);
|
|
},
|
|
addRecipeAction({
|
|
commit
|
|
}, recipe) {
|
|
commit("addRecipe", recipe);
|
|
},
|
|
overwriteRecipeAction({
|
|
commit
|
|
}, updatedRecipe) {
|
|
commit("overwriteRecipe", updatedRecipe);
|
|
},
|
|
deleteRecipeAction({
|
|
commit
|
|
}, recipe) {
|
|
commit("deleteRecipe", recipe);
|
|
},
|
|
initializeListItems({commit}) {
|
|
commit("initializeListItems");
|
|
},
|
|
importListItemsAction({
|
|
commit
|
|
}, data) {
|
|
commit("importListItems", data);
|
|
},
|
|
addListItemAction({
|
|
commit
|
|
}, item) {
|
|
commit("addListItem", item);
|
|
},
|
|
removeListItemAction({
|
|
commit
|
|
}, item) {
|
|
commit("removeListItem", item);
|
|
},
|
|
resetListItemsAction({
|
|
commit
|
|
}, listName) {
|
|
commit("resetListItems", listName);
|
|
},
|
|
initializeMealPlans({commit}) {
|
|
commit("initializeMealPlans");
|
|
},
|
|
importMealPlansAction({
|
|
commit
|
|
}, mealPlans) {
|
|
commit("importMealPlans", mealPlans);
|
|
},
|
|
addMealPlanAction({
|
|
commit
|
|
}, mealPlan) {
|
|
commit("addMealPlan", mealPlan);
|
|
},
|
|
deleteMealPlanAction({
|
|
commit
|
|
}, mealPlan) {
|
|
commit("deleteMealPlan", mealPlan);
|
|
},
|
|
toggleStateAction({
|
|
commit
|
|
}, toggledRecipe) {
|
|
commit("toggleState", toggledRecipe);
|
|
},
|
|
setRecipeAsTriedAction({
|
|
commit
|
|
}, recipe) {
|
|
commit("setRecipeAsTried", recipe);
|
|
},
|
|
setLastTriedDateAction({
|
|
commit
|
|
}, index) {
|
|
commit("setLastTriedDate", index);
|
|
},
|
|
setCurrentComponentAction({
|
|
commit
|
|
}, comp) {
|
|
commit("setCurrentComponent", comp);
|
|
},
|
|
unSyncCombinationsAction({
|
|
commit
|
|
}, combinations) {
|
|
commit("unSyncCombinations", combinations);
|
|
},
|
|
setShakeAction({
|
|
commit
|
|
}, shake) {
|
|
commit("setShake", shake);
|
|
},
|
|
setRatingAction({
|
|
commit
|
|
}, rating) {
|
|
commit("setRating", rating);
|
|
},
|
|
toggleCartAction({
|
|
commit
|
|
}, recipe) {
|
|
commit("toggleCart", recipe);
|
|
},
|
|
unlinkBrokenImages({commit}) {
|
|
commit("unlinkBrokenImages");
|
|
}
|
|
}
|
|
});
|