Add usability features to html_variants (#991)
This commit is contained in:
parent
e84714857b
commit
735a96432c
13 changed files with 161 additions and 29 deletions
|
|
@ -116,7 +116,7 @@
|
|||
margin-left: 2px;
|
||||
font-family: $monospace;
|
||||
.row{
|
||||
padding: calc(5px + 0.2vw) 0px;
|
||||
padding: calc(3px + 0.1vw) 0px;
|
||||
display: inline-block;
|
||||
width: 96%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,13 @@ class HtmlVariantsController < ApplicationController
|
|||
|
||||
def index
|
||||
authorize HtmlVariant
|
||||
@user_variants = current_user.html_variants.order("created_at DESC")
|
||||
@all_published_variants = HtmlVariant.where(published: true).order("created_at DESC")
|
||||
@preview_path = Article.where(featured: true, published: true).order("published_at DESC").first&.path.to_s
|
||||
@html_variants = if params[:state] == "mine"
|
||||
current_user.html_variants.order("created_at DESC").includes(:user)
|
||||
elsif params[:state] == "admin"
|
||||
HtmlVariant.where(published: true).order("created_at DESC").includes(:user)
|
||||
else
|
||||
HtmlVariant.where(published: true, approved: true).order("success_rate DESC").includes(:user)
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
|
|
@ -13,11 +17,19 @@ class HtmlVariantsController < ApplicationController
|
|||
@html_variant = HtmlVariant.new
|
||||
if params[:fork_id]
|
||||
@fork = HtmlVariant.find(params[:fork_id])
|
||||
@html_variant.name = @fork.name + " FORK"
|
||||
@html_variant.name = @fork.name + " FORK-#{rand(10000)}"
|
||||
@html_variant.html = @fork.html
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@story_show = true
|
||||
@@article_show = true
|
||||
@html_variant = HtmlVariant.find(params[:id])
|
||||
authorize @html_variant
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def edit
|
||||
@html_variant = HtmlVariant.find(params[:id])
|
||||
authorize @html_variant
|
||||
|
|
@ -29,7 +41,8 @@ class HtmlVariantsController < ApplicationController
|
|||
@html_variant.group = "article_show_sidebar_cta"
|
||||
@html_variant.user_id = current_user.id
|
||||
if @html_variant.save
|
||||
redirect_to "/html_variants"
|
||||
flash[:success] = "HTML Variant Created"
|
||||
redirect_to "/html_variants/#{@html_variant.id}/edit"
|
||||
else
|
||||
render :new
|
||||
end
|
||||
|
|
@ -39,7 +52,8 @@ class HtmlVariantsController < ApplicationController
|
|||
@html_variant = HtmlVariant.find(params[:id])
|
||||
authorize @html_variant
|
||||
if @html_variant.update(html_variant_params)
|
||||
redirect_to "/html_variants"
|
||||
flash[:success] = "HTML Variant Updated"
|
||||
redirect_to "/html_variants/#{@html_variant.id}/edit"
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class HtmlVariant < ApplicationRecord
|
|||
belongs_to :user, optional: true
|
||||
has_many :html_variant_trials
|
||||
has_many :html_variant_successes
|
||||
before_save :prefix_all_images
|
||||
|
||||
def calculate_success_rate!
|
||||
self.success_rate = html_variant_successes.size.to_f / (html_variant_trials.size * 10.0) # x10 because we only capture every 10th
|
||||
|
|
@ -37,4 +38,46 @@ class HtmlVariant < ApplicationRecord
|
|||
errors.add(:base, "cannot change once published and approved")
|
||||
end
|
||||
end
|
||||
|
||||
def prefix_all_images
|
||||
# wrap with Cloudinary or allow if from giphy or githubusercontent.com
|
||||
doc = Nokogiri::HTML.fragment(html)
|
||||
doc.css("img").each do |img|
|
||||
src = img.attr("src")
|
||||
next unless src
|
||||
# allow image to render as-is
|
||||
img["src"] = if giphy_img?(src)
|
||||
src.gsub("https://media.", "https://i.")
|
||||
else
|
||||
img_of_size(src, 420)
|
||||
end
|
||||
end
|
||||
self.html = doc.to_html
|
||||
end
|
||||
|
||||
def giphy_img?(source)
|
||||
uri = URI.parse(source)
|
||||
return false if uri.scheme != "https"
|
||||
return false if uri.userinfo || uri.fragment || uri.query
|
||||
return false if uri.host != "media.giphy.com" && uri.host != "i.giphy.com"
|
||||
return false if uri.port != 443 # I think it has to be this if its https?
|
||||
|
||||
uri.path.ends_with?(".gif")
|
||||
end
|
||||
|
||||
def img_of_size(source, width = 420)
|
||||
quality = if source && (source.include? ".gif")
|
||||
66
|
||||
else
|
||||
"auto"
|
||||
end
|
||||
cl_image_path(source,
|
||||
type: "fetch",
|
||||
width: width,
|
||||
crop: "limit",
|
||||
quality: quality,
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true).gsub(",", "%2C")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
<%= follow_button(@actor) %>
|
||||
</div>
|
||||
<% if @actor.class.name == "User" %>
|
||||
<%= render "articles/user_metadata" %>
|
||||
<%= render "articles/user_metadata", context: "sidebar" %>
|
||||
<% elsif @actor.class.name == "Organization" && @actor.approved_and_filled_out_cta? %>
|
||||
<div class="primary-sticky-nav-org-summary">
|
||||
<%= @actor.cta_processed_html.html_safe %>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
.user-profile-header {min-height: 398px;}
|
||||
</style>
|
||||
<% end %>
|
||||
<% if @user.email_public %>
|
||||
<% if @user.email_public && context != "sidebar" %>
|
||||
<div class="row">
|
||||
<div class="key">
|
||||
email
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<%= render "articles/user_metadata" %>
|
||||
<%= render "articles/user_metadata", context: "profile" %>
|
||||
</div>
|
||||
<% elsif @tag %>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
<% flash.each do |key, value| %>
|
||||
<div class="flash flash-<%= key %>"><%= value %></div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if @html_variant.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(@html_variant.errors.count, "error") %> prohibited this block from being saved:</h2>
|
||||
|
|
@ -18,9 +23,17 @@
|
|||
<% end %>
|
||||
<%= f.label :html %>
|
||||
<%= f.text_area :html, placeholder: 'HTML to be shown. Make sure all CSS is properly scoped, and all HTML tags are closed, etc. Manditory field.' %>
|
||||
<%= f.label :published %>
|
||||
<%= f.check_box :published %>
|
||||
<%= f.label :target_tag %>
|
||||
<%= f.text_field :target_tag, placeholder: 'One tag, e.g. javascript. Optional targeting.' %>
|
||||
<div class="form-sub-details">
|
||||
<%= f.label :published %>
|
||||
<%= f.check_box :published %>
|
||||
<%= f.label :target_tag %>
|
||||
<%= f.text_field :target_tag, placeholder: 'One tag, e.g. javascript. Optional targeting.' %>
|
||||
</div>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
<% if @html_variant.html.present? %>
|
||||
<h1 style="text-align:center;">Preview:</h1>
|
||||
<div class="html-variant-wrapper" style="width: 310px;margin:20px auto;">
|
||||
<%= @html_variant.html.html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -1,14 +1,36 @@
|
|||
<style>
|
||||
.html-variants-page {
|
||||
margin: 100px auto;
|
||||
width: 800px;
|
||||
width: 1100px;
|
||||
max-width: 96%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.html-variants-page nav a {
|
||||
display: inline-block;
|
||||
padding: 5px 12px;
|
||||
border-radius: 3px;
|
||||
color: blue;
|
||||
}
|
||||
.html-variants-page nav a.selected {
|
||||
background: blue;
|
||||
color: white;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 a {
|
||||
border: 1px solid black;
|
||||
padding: 10px 40px;
|
||||
border-radius: 100px;
|
||||
}
|
||||
.flash {
|
||||
background: green;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
input, textarea {
|
||||
width: 100%;
|
||||
font-size: 20px;
|
||||
|
|
@ -25,6 +47,17 @@
|
|||
}
|
||||
textarea {
|
||||
height: calc(100vh - 500px);
|
||||
font-size: 0.8em;
|
||||
overflow-x: scroll;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.form-sub-details input {
|
||||
display: inline-block;
|
||||
max-width: 40%;
|
||||
margin-left: 1%;
|
||||
}
|
||||
.form-sub-details input[type="checkbox"] {
|
||||
max-width: 5%;
|
||||
}
|
||||
#error_explanation {
|
||||
margin-bottom: 20px;
|
||||
|
|
@ -33,16 +66,28 @@
|
|||
border: 1px solid black;
|
||||
padding: 15px 15px 5px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 15px;
|
||||
margin: 15px;
|
||||
width: 450px;
|
||||
height: 550px;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.html-variants-page-single-variant h3 {
|
||||
margin-top: 0px;
|
||||
font-size:1.3em;
|
||||
|
||||
}
|
||||
.html-variants-page-single-variant iframe {
|
||||
border: 0px;
|
||||
width: 310px;
|
||||
height: 350px;
|
||||
}
|
||||
.html-variants-page-single-variant-details {
|
||||
margin: 5px 0px 0px;
|
||||
padding: 10px 0px;
|
||||
padding: 10px;
|
||||
border-top: 1px solid gray;
|
||||
position: absolute;
|
||||
bottom:0;left:0;right:0;
|
||||
}
|
||||
.pill {
|
||||
padding: 3px 10px;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
<div class="html-variants-page-single-variant">
|
||||
@<%= html_variant.user.username %>:
|
||||
<h3>
|
||||
<%= html_variant.name %>
|
||||
</h3>
|
||||
<%= html_variant.html %>
|
||||
<iframe src="/html_variants/<%= html_variant.id %>"></iframe>
|
||||
<div class="html-variants-page-single-variant-details">
|
||||
<% if html_variant.published %>
|
||||
<span class='pill published'>published</span>
|
||||
<a class='pill' href="/html_variants/new?fork_id=<%= html_variant.id %>">fork</a>
|
||||
<% else %>
|
||||
<a class='pill' href="/html_variants/<%= html_variant.id %>/edit">edit</a>
|
||||
<a class='pill' href="/html_variants/<%= html_variant.id %>/edit">view/edit</a>
|
||||
<% end %>
|
||||
<a class='pill' href="<%= @preview_path %>?html_variant_id=<%= html_variant.id %>&state=<%= html_variant.updated_at.to_i %>" target="_blank">preview</a>
|
||||
<% if html_variant.approved %>
|
||||
<span class='pill approved'>approved</span>
|
||||
<span class='pill approved'><%= html_variant.success_rate %></span>
|
||||
<% elsif admin %>
|
||||
<%= form_for(html_variant) do |f| %>
|
||||
<%= f.hidden_field :approved, value: "true" %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<%= render "page_styles" %>
|
||||
|
||||
<div class="html-variants-page" >
|
||||
<div><a href="/html_variants">👈 View All</a>
|
||||
<h1><%= @html_variant.name %></h1>
|
||||
<%= render "form" %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,12 +4,19 @@
|
|||
<h1>
|
||||
HTML Variants <a href="/html_variants/new">New</a>
|
||||
</h1>
|
||||
<h2>Your HTML Variants</h2>
|
||||
<% @user_variants.each do |html_variant| %>
|
||||
<%= render "single_html_variant", html_variant: html_variant, admin: false %>
|
||||
<nav>
|
||||
<a href="/html_variants" class="<%= "selected" if params[:state].blank? %>">Leaderboard</a>
|
||||
<a href="/html_variants?state=mine" class="<%= "selected" if params[:state] == "mine" %>">Mine</a>
|
||||
</nav>
|
||||
<% if params[:state] == "mine" %>
|
||||
<h2>My Entries</h2>
|
||||
<% elsif params[:state] == "admin" %>
|
||||
<h2>All Published Entries</h2>
|
||||
<% else %>
|
||||
<h2>Leaderboard</h2>
|
||||
<% end %>
|
||||
<h2>All Published</h2>
|
||||
<% @all_published_variants.each do |html_variant| %>
|
||||
<%= render "single_html_variant", html_variant: html_variant, admin: true %>
|
||||
<% @html_variants.each do |html_variant| %>
|
||||
<%= render "single_html_variant", html_variant: html_variant, admin: params[:state] == "admin" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<%= render "page_styles" %>
|
||||
|
||||
<div class="html-variants-page" >
|
||||
<div><a href="/html_variants">👈 View All</a>
|
||||
<%= render "form" %>
|
||||
</div>
|
||||
|
|
|
|||
9
app/views/html_variants/show.html.erb
Normal file
9
app/views/html_variants/show.html.erb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<%= render "layouts/styles" %>
|
||||
<style>
|
||||
body{padding-top: 20px !important; }
|
||||
</style>
|
||||
<div class="primary-sticky-nav">
|
||||
<div class="html-variant-wrapper">
|
||||
<%= @html_variant.html.html_safe %>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Reference in a new issue