mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-02 20:15:24 +02:00
feature/editor-improvements (#289)
* pin editor buttons on scroll * scaler scratch * fix langauge assignment 1st pass * set lang on navigate * refactor/breakup router * unify style for language selectro * refactor/code-cleanup * refactor/page specific components to page folder * Fix time card layout issue * fix timecard display * update mobile cards / fix overflow errors Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
parent
a5306c31c6
commit
284df44209
66 changed files with 778 additions and 664 deletions
42
dev/ingredientScaler/index.js
Normal file
42
dev/ingredientScaler/index.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { recipeIngredient } from "./recipeIngredient";
|
||||
import { recipeNumber } from "./recipeNumber";
|
||||
|
||||
export const ingredientScaler = {
|
||||
process(ingredientArray, scale) {
|
||||
console.log(scale);
|
||||
let workingArray = ingredientArray.map(x =>
|
||||
ingredientScaler.markIngredient(x)
|
||||
);
|
||||
return workingArray.map(x => ingredientScaler.adjustIngredients(x, scale));
|
||||
},
|
||||
|
||||
adjustIngredients(ingredient, scale) {
|
||||
var scaledQuantity = new recipeNumber(ingredient.quantity).multiply(scale);
|
||||
const newText = ingredient.text.replace(
|
||||
ingredient.quantity,
|
||||
scaledQuantity
|
||||
);
|
||||
return { ...ingredient, quantity: scaledQuantity, text: newText };
|
||||
},
|
||||
|
||||
markIngredient(ingredient) {
|
||||
console.log(ingredient);
|
||||
const returnVar = ingredient.replace(
|
||||
/^([\d/?[^\s&]*)(?: |\s)(\w*)/g,
|
||||
(match, quantity, unit) => {
|
||||
return `${unit}${quantity},${match}`;
|
||||
}
|
||||
);
|
||||
const split = returnVar.split(",");
|
||||
const [unit, quantity, match] = split;
|
||||
console.log("Split", unit, quantity, match);
|
||||
const n = new recipeNumber(quantity);
|
||||
const i = new recipeIngredient(n, unit);
|
||||
const serializedQuantity = n.isFraction() ? n.toImproperFraction() : n;
|
||||
return {
|
||||
unit: i,
|
||||
quantity: serializedQuantity.toString(),
|
||||
text: match,
|
||||
};
|
||||
},
|
||||
};
|
75
dev/ingredientScaler/recipeIngredient.js
Normal file
75
dev/ingredientScaler/recipeIngredient.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
export const recipeIngredient = function(quantity, unit) {
|
||||
this.quantity = quantity;
|
||||
this.unit = unit;
|
||||
};
|
||||
|
||||
recipeIngredient.prototype.isSingular = function() {
|
||||
return this.quantity > 0 && this.quantity <= 1;
|
||||
};
|
||||
|
||||
recipeIngredient.prototype.pluralize = function() {
|
||||
if (this.isSingular()) {
|
||||
return this.unit;
|
||||
} else {
|
||||
return `${this.unit}s`;
|
||||
}
|
||||
};
|
||||
|
||||
recipeIngredient.prototype.getSingularUnit = function() {
|
||||
if (this.isSingular()) {
|
||||
return this.unit;
|
||||
} else {
|
||||
return this.unit.replace(/s$/, "");
|
||||
}
|
||||
};
|
||||
|
||||
recipeIngredient.prototype.toString = function() {
|
||||
return `${this.quantity.toString()} ${this.pluralize()}`;
|
||||
};
|
||||
|
||||
recipeIngredient.prototype.convertUnits = function() {
|
||||
const conversion = recipeIngredient.CONVERSIONS[this.unit] || {};
|
||||
if (conversion.min && this.quantity < conversion.min.value) {
|
||||
this.unit = conversion.min.next;
|
||||
this.quantity.multiply(conversion.to[this.unit]);
|
||||
} else if (conversion.max && this.quantity >= conversion.max.value) {
|
||||
this.unit = conversion.max.next;
|
||||
this.quantity.multiply(conversion.to[this.unit]);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
recipeIngredient.CONVERSIONS = {
|
||||
cup: {
|
||||
to: {
|
||||
tablespoon: 16,
|
||||
},
|
||||
min: {
|
||||
value: 1 / 4,
|
||||
next: "tablespoon",
|
||||
},
|
||||
},
|
||||
tablespoon: {
|
||||
to: {
|
||||
teaspoon: 3,
|
||||
cup: 1 / 16,
|
||||
},
|
||||
min: {
|
||||
value: 1,
|
||||
next: "teaspoon",
|
||||
},
|
||||
max: {
|
||||
value: 4,
|
||||
next: "cup",
|
||||
},
|
||||
},
|
||||
teaspoon: {
|
||||
to: {
|
||||
tablespoon: 1 / 3,
|
||||
},
|
||||
max: {
|
||||
value: 3,
|
||||
next: "tablespoon",
|
||||
},
|
||||
},
|
||||
};
|
166
dev/ingredientScaler/recipeNumber.js
Normal file
166
dev/ingredientScaler/recipeNumber.js
Normal file
|
@ -0,0 +1,166 @@
|
|||
export const recipeNumber = function(number) {
|
||||
const match = number.match(
|
||||
/^(?:(\d+)|(?:(\d+)(?: | ))?(?:(\d+)\/(\d+))?)$/
|
||||
);
|
||||
if (!match || !match[0] || match[4] == "0") {
|
||||
throw `Invalid number: "${number}".`;
|
||||
}
|
||||
this.wholeNumber = +(match[1] || match[2]);
|
||||
this.numerator = +match[3];
|
||||
this.denominator = +match[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the number is a fraction.
|
||||
* @this {recipeNumber}
|
||||
* @return {boolean} If the number is a fraction.
|
||||
*/
|
||||
recipeNumber.prototype.isFraction = function() {
|
||||
return !!(this.numerator && this.denominator);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the fraction is proper, which is defined as
|
||||
* the numerator being strictly less than the denominator.
|
||||
* @this {recipeNumber}
|
||||
* @return {boolean} If the fraction is proper.
|
||||
*/
|
||||
recipeNumber.prototype.isProperFraction = function() {
|
||||
return this.numerator < this.denominator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the fraction is improper, which is defined as
|
||||
* the numerator being greater than or equal to the denominator.
|
||||
* @this {recipeNumber}
|
||||
* @return {boolean} If the fraction is improper.
|
||||
*/
|
||||
recipeNumber.prototype.isImproperFraction = function() {
|
||||
return this.numerator >= this.denominator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the fraction is mixed, which is defined as
|
||||
* a whole number with a proper fraction.
|
||||
* @this {recipeNumber}
|
||||
* @return {boolean} If the fraction is mixed.
|
||||
*/
|
||||
recipeNumber.prototype.isMixedFraction = function() {
|
||||
return this.isProperFraction() && !isNaN(this.wholeNumber);
|
||||
};
|
||||
|
||||
/**
|
||||
* Simplifies fractions. Examples:
|
||||
* 3/2 = 1 1/2
|
||||
* 4/2 = 2
|
||||
* 1 3/2 = 2 1/2
|
||||
* 0/1 = 0
|
||||
* 1 0/1 = 1
|
||||
* @this {recipeNumber}
|
||||
* @return {recipeNumber} The instance.
|
||||
*/
|
||||
recipeNumber.prototype.simplifyFraction = function() {
|
||||
if (this.isImproperFraction()) {
|
||||
this.wholeNumber |= 0;
|
||||
this.wholeNumber += Math.floor(this.numerator / this.denominator);
|
||||
const modulus = this.numerator % this.denominator;
|
||||
if (modulus) {
|
||||
this.numerator = modulus;
|
||||
} else {
|
||||
this.numerator = this.denominator = NaN;
|
||||
}
|
||||
} else if (this.numerator == 0) {
|
||||
this.wholeNumber |= 0;
|
||||
this.numerator = this.denominator = NaN;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reduces a fraction. Examples:
|
||||
* 2/6 = 1/3
|
||||
* 6/2 = 3/1
|
||||
* @this {recipeNumber}
|
||||
* @return {recipeNumber} The instance.
|
||||
*/
|
||||
recipeNumber.prototype.reduceFraction = function() {
|
||||
if (this.isFraction()) {
|
||||
const gcd = recipeNumber.gcd(this.numerator, this.denominator);
|
||||
this.numerator /= gcd;
|
||||
this.denominator /= gcd;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts proper fractions to improper fractions. Examples:
|
||||
* 1 1/2 = 3/2
|
||||
* 3/2 = 3/2
|
||||
* 1/2 = 1/2
|
||||
* 2 = 2
|
||||
*
|
||||
* @this {recipeNumber}
|
||||
* @return {recipeNumber} The instance.
|
||||
*/
|
||||
recipeNumber.prototype.toImproperFraction = function() {
|
||||
if (!isNaN(this.wholeNumber)) {
|
||||
this.numerator |= 0;
|
||||
this.denominator = this.denominator || 1;
|
||||
this.numerator += this.wholeNumber * this.denominator;
|
||||
this.wholeNumber = NaN;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiplies the number by some decimal value.
|
||||
* @param {number} multiplier The multiplier.
|
||||
* @this {recipeNumber}
|
||||
* @return {recipeNumber} The instance.
|
||||
*/
|
||||
recipeNumber.prototype.multiply = function(multiplier) {
|
||||
this.toImproperFraction();
|
||||
this.numerator *= multiplier;
|
||||
return this.reduceFraction().simplifyFraction();
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string representation of the number.
|
||||
* @this {recipeNumber}
|
||||
* @return {string} The string representation of the number.
|
||||
*/
|
||||
recipeNumber.prototype.toString = function() {
|
||||
let number = "";
|
||||
let fraction = "";
|
||||
if (!isNaN(this.wholeNumber)) {
|
||||
number += this.wholeNumber;
|
||||
}
|
||||
if (this.isFraction()) {
|
||||
fraction = `${this.numerator}/${this.denominator}`;
|
||||
}
|
||||
if (number && fraction) {
|
||||
number += ` ${fraction}`;
|
||||
}
|
||||
return number || fraction;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a numeric representation of the number.
|
||||
* @this {recipeNumber}
|
||||
* @return {number} The numeric representation of the number.
|
||||
*/
|
||||
recipeNumber.prototype.valueOf = function() {
|
||||
let value = this.wholeNumber || 0;
|
||||
value += this.numerator / this.denominator || 0;
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Euclid's algorithm to find the greatest common divisor of two numbers.
|
||||
* @param {number} a One number.
|
||||
* @param {number} b Another number.
|
||||
* @return {number} The GCD of the numbers.
|
||||
*/
|
||||
recipeNumber.gcd = function gcd(a, b) {
|
||||
return b ? recipeNumber.gcd(b, a % b) : a;
|
||||
};
|
11
dev/scripts/publish-release-branch.sh
Normal file
11
dev/scripts/publish-release-branch.sh
Normal file
|
@ -0,0 +1,11 @@
|
|||
git checkout dev
|
||||
git merge --strategy=ours master # keep the content of this branch, but record a merge
|
||||
git checkout master
|
||||
git merge dev # fast-forward master up to the merge
|
||||
|
||||
|
||||
## TODOs
|
||||
|
||||
# Create New Branch v0.x.x
|
||||
# Push Branch Version to Github
|
||||
# Create Pull Request
|
Loading…
Add table
Add a link
Reference in a new issue