recipe
This commit is contained in:
parent
0957d84ca0
commit
26b4401450
@ -29,14 +29,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column is-one-third-desktop">
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
Ingredients
|
Ingredients
|
||||||
<button class="button is-small" type="button" @click="showConvertDialog = true">Convert</button>
|
<button class="button is-small is-primary" type="button" @click="showConvertDialog = true">Convert</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="message-body content">
|
<div class="message-body content">
|
||||||
<ul v-if="recipe.ingredients.length > 0">
|
<ul v-if="recipe.ingredients.length > 0" v-click-strike>
|
||||||
<li v-for="i in recipe.ingredients">
|
<li v-for="i in recipe.ingredients">
|
||||||
{{i.display_name}}
|
{{i.display_name}}
|
||||||
</li>
|
</li>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<div class="message-header">Directions</div>
|
<div class="message-header">Directions</div>
|
||||||
<div class="message-body content" v-html="recipe.rendered_steps">
|
<div class="message-body content" v-html="recipe.rendered_steps" v-click-strike>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -130,8 +130,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="button is-primary" class="button" @click="convert">Convert</button>
|
<button type="button" class="button is-primary" @click="convert">Convert</button>
|
||||||
<button type="button" class="button">Close</button>
|
<button type="button" class="button" @click="showConvertDialog = false">Close</button>
|
||||||
</div>
|
</div>
|
||||||
</app-modal>
|
</app-modal>
|
||||||
|
|
||||||
@ -185,8 +185,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
recipe: {
|
||||||
|
handler: function(r) {
|
||||||
|
if (r) {
|
||||||
|
this.scaleValue = r.converted_scale || '1';
|
||||||
|
this.systemConvertValue = r.converted_system;
|
||||||
|
this.unitConvertValue = r.converted_unit;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
convert() {
|
convert() {
|
||||||
|
this.showConvertDialog = false;
|
||||||
this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }});
|
this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8,6 +8,11 @@
|
|||||||
<div class="subtitle tags">
|
<div class="subtitle tags">
|
||||||
<span v-for="tag in recipe.tags" :key="tag" class="tag is-medium">{{tag}}</span>
|
<span v-for="tag in recipe.tags" :key="tag" class="tag is-medium">{{tag}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tags">
|
||||||
|
<span v-if="isScaled" class="tag is-large">{{recipe.converted_scale}} X</span>
|
||||||
|
<span v-if="recipe.converted_system !== null" class="tag is-large">{{recipe.converted_system}}</span>
|
||||||
|
<span v-if="recipe.converted_unit !== null" class="tag is-large">{{recipe.converted_unit}}</span>
|
||||||
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<recipe-show :recipe="recipe"></recipe-show>
|
<recipe-show :recipe="recipe"></recipe-show>
|
||||||
</div>
|
</div>
|
||||||
@ -34,17 +39,34 @@
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
recipeId: state => state.route.params.id,
|
recipeId: state => state.route.params.id,
|
||||||
|
routeQuery: state => state.route.query,
|
||||||
scale: state => state.route.query.scale || null,
|
scale: state => state.route.query.scale || null,
|
||||||
system: state => state.route.query.system || null,
|
system: state => state.route.query.system || null,
|
||||||
unit: state => state.route.query.unit || null
|
unit: state => state.route.query.unit || null
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
isScaled() {
|
||||||
|
return this.recipe.converted_scale !== null && this.recipe.converted_scale.length > 0 && this.recipe.converted_scale !== "1";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
routeQuery() {
|
||||||
|
this.refreshData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
refreshData() {
|
||||||
|
this.loadResource(
|
||||||
|
api.getRecipe(this.recipeId, this.scale, this.system, this.unit)
|
||||||
|
.then(data => { this.recipe = data; return data; })
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.loadResource(
|
this.refreshData();
|
||||||
api.getRecipe(this.recipeId, this.scale, this.system, this.unit)
|
|
||||||
.then(data => { this.recipe = data; return data; })
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
|
@ -27,4 +27,37 @@ Vue.mixin({
|
|||||||
.then(() => this.setLoading(false));
|
.then(() => this.setLoading(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function clickStrikeClick(evt) {
|
||||||
|
const isStrikable = el => el && el.tagName === "LI";
|
||||||
|
const strikeClass = "is-strikethrough";
|
||||||
|
|
||||||
|
let t = evt.target;
|
||||||
|
|
||||||
|
while (t !== null && t !== this && !isStrikable(t)) {
|
||||||
|
t = t.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStrikable(t)) {
|
||||||
|
const classList = t.className.split(" ");
|
||||||
|
const strIdx = classList.findIndex(c => c === strikeClass);
|
||||||
|
if (strIdx >= 0) {
|
||||||
|
classList.splice(strIdx, 1);
|
||||||
|
} else {
|
||||||
|
classList.push(strikeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
t.className = classList.join(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.directive('click-strike', {
|
||||||
|
bind(el) {
|
||||||
|
el.addEventListener("click", clickStrikeClick);
|
||||||
|
},
|
||||||
|
|
||||||
|
unbind(el) {
|
||||||
|
el.removeEventListener("click", clickStrikeClick);
|
||||||
|
}
|
||||||
});
|
});
|
@ -42,3 +42,7 @@ body {
|
|||||||
.pagination:not(:last-child) {
|
.pagination:not(:last-child) {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.is-strikethrough {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
@ -16,31 +16,38 @@ class Recipe < ApplicationRecord
|
|||||||
validates :total_time, numericality: true, allow_blank: true
|
validates :total_time, numericality: true, allow_blank: true
|
||||||
validates :active_time, numericality: true, allow_blank: true
|
validates :active_time, numericality: true, allow_blank: true
|
||||||
|
|
||||||
|
attr_accessor :converted_scale, :converted_system, :converted_unit
|
||||||
|
|
||||||
def scale(factor, auto_unit = false)
|
def scale(factor, auto_unit = false)
|
||||||
|
self.converted_scale = factor
|
||||||
recipe_ingredients.each do |ri|
|
recipe_ingredients.each do |ri|
|
||||||
ri.scale(factor, auto_unit)
|
ri.scale(factor, auto_unit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_to_metric
|
def convert_to_metric
|
||||||
|
self.converted_system = 'metric'
|
||||||
recipe_ingredients.each do |ri|
|
recipe_ingredients.each do |ri|
|
||||||
ri.to_metric
|
ri.to_metric
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_to_standard
|
def convert_to_standard
|
||||||
|
self.converted_system = 'standard'
|
||||||
recipe_ingredients.each do |ri|
|
recipe_ingredients.each do |ri|
|
||||||
ri.to_standard
|
ri.to_standard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_to_mass
|
def convert_to_mass
|
||||||
|
self.converted_unit = 'mass'
|
||||||
recipe_ingredients.each do |ri|
|
recipe_ingredients.each do |ri|
|
||||||
ri.to_mass
|
ri.to_mass
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_to_volume
|
def convert_to_volume
|
||||||
|
self.converted_unit = 'volume'
|
||||||
recipe_ingredients.each do |ri|
|
recipe_ingredients.each do |ri|
|
||||||
ri.to_volume
|
ri.to_volume
|
||||||
end
|
end
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="manifest" href="/manifest.json">
|
||||||
|
|
||||||
<title>Parsley</title>
|
<title>Parsley</title>
|
||||||
|
|
||||||
<%= stylesheet_pack_tag 'application' %>
|
<%= stylesheet_pack_tag 'application' %>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
json.extract! recipe, :id, :name, :rating, :yields, :total_time, :active_time, :created_at, :updated_at, :step_text
|
json.extract! recipe, :id, :name, :rating, :yields, :total_time, :active_time, :created_at, :updated_at, :step_text, :converted_scale, :converted_system, :converted_unit
|
||||||
|
|
||||||
json.rendered_steps MarkdownProcessor.render(recipe.step_text)
|
json.rendered_steps MarkdownProcessor.render(recipe.step_text)
|
||||||
|
|
||||||
|
8
public/manifest.json
Normal file
8
public/manifest.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "Parsley",
|
||||||
|
"short_name": "Parsley",
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#4a4a4a",
|
||||||
|
"description": "A simply readable Hacker News app."
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user