recipe
This commit is contained in:
parent
0957d84ca0
commit
26b4401450
@ -29,14 +29,14 @@
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="column is-one-third-desktop">
|
||||
<div class="message">
|
||||
<div class="message-header">
|
||||
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 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">
|
||||
{{i.display_name}}
|
||||
</li>
|
||||
@ -47,7 +47,7 @@
|
||||
<div class="column">
|
||||
<div class="message">
|
||||
<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>
|
||||
@ -130,8 +130,8 @@
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<button type="button is-primary" class="button" @click="convert">Convert</button>
|
||||
<button type="button" class="button">Close</button>
|
||||
<button type="button" class="button is-primary" @click="convert">Convert</button>
|
||||
<button type="button" class="button" @click="showConvertDialog = false">Close</button>
|
||||
</div>
|
||||
</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: {
|
||||
convert() {
|
||||
this.showConvertDialog = false;
|
||||
this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }});
|
||||
},
|
||||
|
||||
|
@ -8,6 +8,11 @@
|
||||
<div class="subtitle tags">
|
||||
<span v-for="tag in recipe.tags" :key="tag" class="tag is-medium">{{tag}}</span>
|
||||
</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>
|
||||
<recipe-show :recipe="recipe"></recipe-show>
|
||||
</div>
|
||||
@ -34,17 +39,34 @@
|
||||
computed: {
|
||||
...mapState({
|
||||
recipeId: state => state.route.params.id,
|
||||
routeQuery: state => state.route.query,
|
||||
scale: state => state.route.query.scale || null,
|
||||
system: state => state.route.query.system || 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() {
|
||||
this.loadResource(
|
||||
api.getRecipe(this.recipeId, this.scale, this.system, this.unit)
|
||||
.then(data => { this.recipe = data; return data; })
|
||||
);
|
||||
this.refreshData();
|
||||
},
|
||||
|
||||
components: {
|
||||
|
@ -27,4 +27,37 @@ Vue.mixin({
|
||||
.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) {
|
||||
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 :active_time, numericality: true, allow_blank: true
|
||||
|
||||
attr_accessor :converted_scale, :converted_system, :converted_unit
|
||||
|
||||
def scale(factor, auto_unit = false)
|
||||
self.converted_scale = factor
|
||||
recipe_ingredients.each do |ri|
|
||||
ri.scale(factor, auto_unit)
|
||||
end
|
||||
end
|
||||
|
||||
def convert_to_metric
|
||||
self.converted_system = 'metric'
|
||||
recipe_ingredients.each do |ri|
|
||||
ri.to_metric
|
||||
end
|
||||
end
|
||||
|
||||
def convert_to_standard
|
||||
self.converted_system = 'standard'
|
||||
recipe_ingredients.each do |ri|
|
||||
ri.to_standard
|
||||
end
|
||||
end
|
||||
|
||||
def convert_to_mass
|
||||
self.converted_unit = 'mass'
|
||||
recipe_ingredients.each do |ri|
|
||||
ri.to_mass
|
||||
end
|
||||
end
|
||||
|
||||
def convert_to_volume
|
||||
self.converted_unit = 'volume'
|
||||
recipe_ingredients.each do |ri|
|
||||
ri.to_volume
|
||||
end
|
||||
|
@ -3,6 +3,8 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
|
||||
<title>Parsley</title>
|
||||
|
||||
<%= 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)
|
||||
|
||||
|
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