enrecipes/app/store.js
2021-01-23 22:50:15 +05:30

779 lines
20 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: {
alert: "\ue900",
back: "\ue901",
bag: "\ue902",
bagged: "\ue903",
cal: "\ue904",
cam: "\ue905",
category: "\ue906",
cog: "\ue907",
comb: "\ue908",
cuisine: "\ue909",
del: "\ue90a",
diff: "\ue90b",
don: "\ue90c",
done: "\ue90d",
edit: "\ue90e",
exp: "\ue910",
fav: "\ue911",
faved: "\ue912",
folder: "\ue913",
gh: "\ue914",
help: "\ue915",
home: "\ue916",
img: "\ue917",
imp: "\ue918",
info: "\ue919",
items: "\ue91a",
l1:"\ue91b",
l2:"\ue91c",
l3:"\ue91d",
lang: "\ue91e",
left: "\ue91f",
menu: "\ue920",
noresult: "\ue921",
notes: "\ue922",
plus: "\ue923",
plusc: "\ue924",
price:"\ue925",
priv:"\ue926",
err: "\ue90f",
res: "\ue927",
reset: "\ue928",
right: "\ue929",
save: "\ue92a",
sear: "\ue92b",
selall: "\ue92c",
share: "\ue92d",
shuf: "\ue92e",
sort: "\ue92f",
star: "\ue930",
starred: "\ue931",
steps: "\ue932",
succ: "\ue933",
tag: "\ue934",
text: "\ue935",
tg: "\ue936",
theme: "\ue937",
time: "\ue938",
timer: "\ue939",
tod: "\ue93a",
trans: "\ue93b",
tried: "\ue93c",
try: "\ue93d",
unit: "\ue93e",
x: "\ue93f",
yield: "\ue940",
zip: "\ue941"
},
currentComponent: "EnRecipes",
sortType: "Oldest first",
language: [
{
locale: "da",
title: "Dansk"
}, {
locale: "de",
title: "Deutsch"
}, {
locale: "en-GB",
title: "English (UK)"
}, {
locale: "es",
title: "Español"
}, {
locale: "fr",
title: "Français"
}, {
locale: "fr-BE",
title: "Français (BE)"
}, {
locale: "fr-CA",
title: "Français (CA)"
}, {
locale: "fr-CH",
title: "Français (CH)"
}, {
locale: "it",
title: "Italiano"
}, {
locale: "nb-NO",
title: "Norsk bokmål"
}, {
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("inBag"))
// r.inBag = 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("inBag"))
// r.inBag = 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]);
}
});
},
deleteRecipes(state, ids) {
ids.forEach(id => {
let index = state.recipes.findIndex(e => e.id === 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}) {
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) {
let plans = mealPlansDB.getDocument("mealPlans").mealPlans
if (plans.length && plans[0].hasOwnProperty("eventColor")) {
plans.forEach(p => {
let d = new Date(p.startDate)
p.date = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0).getTime()
switch (new Date(p.date).getHours()) {
case 0:
p.type = "breakfast"
break;
case 5:
p.type = "lunch"
break;
case 10:
p.type = "dinner"
break;
case 15:
p.type = "snacks"
break;
}
delete p.startDate
delete p.endDate
delete p.eventColor
state.mealPlans.push(p)
})
mealPlansDB.updateDocument("mealPlans", {mealPlans: state.mealPlans})
} else
state.mealPlans = [...plans]
} else {
mealPlansDB.createDocument({
mealPlans: []
}, "mealPlans")
}
},
importMealPlans(state, mealPlans) {
let newMealPlans = mealPlans.filter(e => {
if (e.hasOwnProperty("eventColor")) {
return !state.mealPlans.some(f => {
let d = new Date(e.startDate)
let date = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0).getTime()
let type
switch (d.getHours()) {
case 0:
type = "breakfast"
break;
case 5:
type = "lunch"
break;
case 10:
type = "dinner"
break;
case 15:
type = "snacks"
break;
}
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)
}
})
let updatedMealPlans = []
if (newMealPlans[0].hasOwnProperty("eventColor")) {
newMealPlans.forEach(p => {
let d = new Date(p.startDate)
p.date = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0).getTime()
switch (d.getHours()) {
case 0:
p.type = "breakfast"
break;
case 5:
p.type = "lunch"
break;
case 10:
p.type = "dinner"
break;
case 15:
p.type = "snacks"
break;
}
delete p.startDate
delete p.endDate
delete p.eventColor
updatedMealPlans.push(p)
});
}
state.mealPlans = [
...state.mealPlans,
...updatedMealPlans
];
mealPlansDB.updateDocument("mealPlans", {mealPlans: state.mealPlans});
},
addMealPlan(state, {title, date, type, index}) {
let mealPlan = {
title,
date,
type
}
if (index != null)
state.mealPlans.splice(index, 0, mealPlan);
else
state.mealPlans.push(mealPlan);
mealPlansDB.updateDocument("mealPlans", {
mealPlans: [...state.mealPlans]
});
},
deleteMealPlan(state, {title, date, type, index}) {
state.mealPlans.splice(index, 1);
state.mealPlans = [...state.mealPlans];
mealPlansDB.updateDocument("mealPlans", {
mealPlans: [...state.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].inBag = !state.recipes[index].inBag
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);
},
deleteRecipesAction({
commit
}, ids) {
commit("deleteRecipes", ids);
},
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");
}
}
});