Add additional content boxes under posts (#86)
* Add additional content boxes under posts * Fix issue with classic article for under content
This commit is contained in:
parent
4d04f7f852
commit
c1e623ebc2
28 changed files with 442 additions and 46 deletions
|
|
@ -38,6 +38,7 @@ function callInitalizers(){
|
|||
initializeAnalytics();
|
||||
initializeCommentDropdown();
|
||||
initializeSettings();
|
||||
initializeAdditionalContentBoxes();
|
||||
if (!initializeLiveArticle.called){
|
||||
initializeLiveArticle();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
function initializeAdditionalContentBoxes() {
|
||||
var el = document.getElementById("additional-content-area");
|
||||
if (el) {
|
||||
window.fetch('/additional_content_boxes?article_id='+el.dataset.articleId, {
|
||||
method: 'GET',
|
||||
credentials: 'same-origin'
|
||||
}).then(function (response) {
|
||||
if (response.status === 200) {
|
||||
response.text().then(function(html){
|
||||
el.innerHTML = html;
|
||||
initializeReadingListIcons();
|
||||
initializeAllFollowButts();
|
||||
})
|
||||
} else {
|
||||
// there's currently no errorCb.
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,16 @@
|
|||
function initializeSponsorshipVisibility() {
|
||||
var el = document.getElementById("sponsorship-widget");
|
||||
var el = document.getElementById("sponsorship-widget") || document.getElementById("partner-content-display");
|
||||
var user = userData();
|
||||
if (el) {
|
||||
setTimeout(function(){
|
||||
if (window.ga) {
|
||||
if (document.querySelectorAll('[data-partner-seen]').length === 0) {
|
||||
ga('send', 'event', 'view', 'sponsor displayed on page', el.dataset.details, null);
|
||||
el.dataset.partnerSeen = "true";
|
||||
}
|
||||
}
|
||||
}, 400)
|
||||
}
|
||||
if (el && user && user.display_sponsors){
|
||||
el.classList.add("showing");
|
||||
setTimeout(function(){
|
||||
|
|
|
|||
|
|
@ -78,3 +78,165 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.show-page-content-display {
|
||||
vertical-align:top;
|
||||
font-family: $helvetica;
|
||||
margin:40px auto;
|
||||
position: relative;
|
||||
overflow:hidden;
|
||||
a{
|
||||
color: $black;
|
||||
}
|
||||
.content-classification{
|
||||
margin: 30px 20px 0px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
font-size:0.78em;
|
||||
.content-classification-text{
|
||||
background: lighten($yellow, 12%);
|
||||
display: inline-block;
|
||||
padding: 6px 25px;
|
||||
}
|
||||
}
|
||||
.main-content-display{
|
||||
padding:20px 0px;
|
||||
width: calc(90% - 60px);
|
||||
padding: 30px;
|
||||
margin-bottom: 60px;
|
||||
@media screen and ( min-width: 680px ){
|
||||
float: left;
|
||||
width: calc(97% - 365px);
|
||||
border-right: 2px solid $light-medium-gray;
|
||||
margin-left: 3%;
|
||||
margin-top:10px;
|
||||
padding: 15px 45px 35px 15px;
|
||||
}
|
||||
h2{
|
||||
margin:0px auto 10px;
|
||||
font-size:2.2em;
|
||||
}
|
||||
.content-author{
|
||||
|
||||
img{
|
||||
border-radius: 100%;
|
||||
width: 28px;
|
||||
vertical-align: -7px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
a{
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.cta{
|
||||
padding: 7px 20px;
|
||||
font-size: 1.2em;
|
||||
margin-top: 10px;
|
||||
margin-right: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
.engagement-count{
|
||||
font-family: $helvetica-condensed;
|
||||
color: $medium-gray;
|
||||
margin-top: -18px;
|
||||
margin-bottom: -25px;
|
||||
img{
|
||||
height: 20px;
|
||||
min-width: 27px;
|
||||
vertical-align: -3px;
|
||||
margin-right: 3px;
|
||||
&.comments-bubble{
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bookmark-engage{
|
||||
font-family: $helvetica-condensed;
|
||||
background: darken($purple, 26%);
|
||||
color: white;
|
||||
letter-spacing: 1px;
|
||||
border: 0px;
|
||||
font-size: 1.2em;
|
||||
padding: 7px 16px;
|
||||
margin-top: 10px;
|
||||
.bm-success{
|
||||
display: none;
|
||||
}
|
||||
&.selected{
|
||||
background: white;
|
||||
color: darken($purple, 26%);
|
||||
.bm-success{
|
||||
display: inline-block;
|
||||
img{
|
||||
width: 18px;
|
||||
vertical-align: -2px;
|
||||
}
|
||||
}
|
||||
.bm-initial{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.secondary-content-display{
|
||||
display: none;
|
||||
@media screen and ( min-width: 680px ){
|
||||
display: block;
|
||||
}
|
||||
float: left;
|
||||
width: 300px;
|
||||
text-align:center;
|
||||
padding:20px 0px;
|
||||
.profile-pic-wrapper{
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
border-radius: 100%;
|
||||
margin: auto;
|
||||
&.wide-profile-image-wrapper{
|
||||
height: 50px;
|
||||
width: 150px;
|
||||
margin-top: 50px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
img{
|
||||
vertical-align: middle;
|
||||
&.profile-image{
|
||||
width: calc(100% - 8px);
|
||||
height: calc(100% - 8px);
|
||||
border-radius: 100%;
|
||||
}
|
||||
&.wide-image{
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
}
|
||||
}
|
||||
.org-name{
|
||||
font-weight: bold;
|
||||
margin: 10px auto;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.follow-action-button{
|
||||
background: $green;
|
||||
color: $black;
|
||||
border: 0;
|
||||
font-size: 1em;
|
||||
border: 0;
|
||||
padding: 3px 6px;
|
||||
border-radius: 3px;
|
||||
width:170px;
|
||||
}
|
||||
.org-summary{
|
||||
font-size:0.88em;
|
||||
width: 200px;
|
||||
margin: 20px auto;
|
||||
text-align:left;
|
||||
a{
|
||||
color: $bold-blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
app/controllers/additional_content_boxes_controller.rb
Normal file
16
app/controllers/additional_content_boxes_controller.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
class AdditionalContentBoxesController < ApplicationController
|
||||
|
||||
def index
|
||||
articles_ids = params[:article_id].split(",")
|
||||
@article = Article.find(articles_ids[0])
|
||||
@for_user_article = ClassicArticle.
|
||||
new(current_user || @article, {not_ids: articles_ids}).get
|
||||
if (!user_signed_in? || current_user&.display_sponsors) && @article.user.permit_adjacent_sponsors
|
||||
@boosted_article = BoostedArticle.
|
||||
new(current_user, @article, {not_ids: (articles_ids+[@for_user_article])}).get
|
||||
end
|
||||
@alt_classic = ClassicArticle.
|
||||
new(@article, {not_ids: (articles_ids+[@for_user_article])}).get unless @boosted_article
|
||||
render "boxes", layout: false
|
||||
end
|
||||
end
|
||||
|
|
@ -53,6 +53,22 @@ class Internal::ArticlesController < Internal::ApplicationController
|
|||
page(params[:page]).
|
||||
limited_columns_internal_select.
|
||||
per(50)
|
||||
when "classic-candidate"
|
||||
@articles = Article.where("positive_reactions_count > ?", ClassicArticle.new.minimum_reaction_count).
|
||||
includes(:user).
|
||||
order("positive_reactions_count DESC").
|
||||
where(featured: false).
|
||||
page(params[:page]).
|
||||
per(100).
|
||||
limited_columns_internal_select
|
||||
when "classic"
|
||||
@articles = Article.where("positive_reactions_count > ?", ClassicArticle.new.minimum_reaction_count).
|
||||
includes(:user).
|
||||
order("positive_reactions_count DESC").
|
||||
where(featured: true).
|
||||
page(params[:page]).
|
||||
per(100).
|
||||
limited_columns_internal_select
|
||||
else #MIX
|
||||
@articles = Article.
|
||||
where(published: true).
|
||||
|
|
@ -96,6 +112,7 @@ class Internal::ArticlesController < Internal::ApplicationController
|
|||
def article_params
|
||||
params.require(:article).permit(:featured,
|
||||
:social_image,
|
||||
:body_markdown,
|
||||
:approved,
|
||||
:live_now,
|
||||
:main_image_background_hex_color,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class OrganizationsController < ApplicationController
|
|||
def organization_params
|
||||
params.require(:organization).permit(:name,
|
||||
:summary,
|
||||
:tag_line,
|
||||
:slug,
|
||||
:url,
|
||||
:proof,
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ class StoriesController < ApplicationController
|
|||
assign_second_and_third_user
|
||||
not_found if permission_denied?
|
||||
set_surrogate_key_header @article.record_key
|
||||
@classic_article = ClassicArticle.new(@article).get
|
||||
unless user_signed_in?
|
||||
response.headers["Surrogate-Control"] = "max-age=10000, stale-while-revalidate=30, stale-if-error=86400"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ class UsersController < ApplicationController
|
|||
prefer_language_fr
|
||||
prefer_language_it
|
||||
display_sponsors
|
||||
permit_adjacent_sponsors
|
||||
feed_admin_publish_permission]
|
||||
accessible << %i[password password_confirmation] unless params[:user][:password].blank?
|
||||
params.require(:user).
|
||||
|
|
|
|||
18
app/labor/boosted_article.rb
Normal file
18
app/labor/boosted_article.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
class BoostedArticle
|
||||
|
||||
attr_accessor :user, :article, :tags, :not_ids
|
||||
def initialize(user, article, options)
|
||||
@user = user
|
||||
@article = article
|
||||
@tags = (user&.cached_followed_tag_names.to_a + article.decorate.cached_tag_list_array).compact
|
||||
@not_ids = options[:not_ids]
|
||||
end
|
||||
|
||||
def get
|
||||
Article.where(boosted: true).
|
||||
includes(:user).
|
||||
includes(:organization).
|
||||
where.not(id: not_ids, organization_id: nil).
|
||||
tagged_with(tags, any: true).sample
|
||||
end
|
||||
end
|
||||
|
|
@ -1,35 +1,53 @@
|
|||
class ClassicArticle
|
||||
attr_accessor :user
|
||||
def initialize(user)
|
||||
@user = user
|
||||
attr_accessor :input, :not_ids
|
||||
def initialize(input=nil, options={})
|
||||
@input = input
|
||||
@not_ids = options[:not_ids]
|
||||
end
|
||||
|
||||
def get
|
||||
possible_articles = []
|
||||
5.times do
|
||||
possible_articles << cached_qualifying_article
|
||||
if rand(5) == 1
|
||||
random_high_quality_article
|
||||
else
|
||||
qualifying_articles(random_supported_tag_names).where.not(id: not_ids).compact.sample ||
|
||||
random_high_quality_article
|
||||
end
|
||||
possible_articles.compact.sample
|
||||
end
|
||||
|
||||
def cached_qualifying_article
|
||||
Rails.cache.fetch("classic-article-for-tag-#{random_supported_tag_name}_#{rand(0..1)}", expires_in: 45.minutes) do
|
||||
Article.tagged_with(random_supported_tag_name).
|
||||
def qualifying_articles(tag_names)
|
||||
tag_name = tag_names.sample
|
||||
Rails.cache.fetch("classic-article-for-tag-#{tag_name}}", expires_in: 45.minutes) do
|
||||
articles = Article.tagged_with(tag_name).
|
||||
includes(:user).
|
||||
where(published: true, featured: true).
|
||||
where("positive_reactions_count > ?", minimum_reaction_count).
|
||||
where("published_at > ?", 10.months.ago).
|
||||
order("RANDOM()").
|
||||
first
|
||||
order("RANDOM()")
|
||||
end
|
||||
end
|
||||
|
||||
def random_supported_tag_name
|
||||
user.decorate.cached_followed_tags.where(supported: true).where.not(name: "ama").sample&.name
|
||||
def random_high_quality_article
|
||||
Article.where(published: true, featured: true).
|
||||
where("positive_reactions_count > ?", 75).
|
||||
includes(:user).
|
||||
order("RANDOM()").
|
||||
where.not(id: not_ids).
|
||||
first
|
||||
end
|
||||
|
||||
def random_supported_tag_names
|
||||
if input.class.name == "User"
|
||||
input.decorate.cached_followed_tags.where(supported: true).where.not(name: "ama").pluck(:name)
|
||||
elsif input.class.name == "Article"
|
||||
Tag.where(supported: true, name: input.decorate.cached_tag_list_array).where.not(name: "ama").pluck(:name)
|
||||
else
|
||||
["discuss"]
|
||||
end
|
||||
end
|
||||
|
||||
def minimum_reaction_count
|
||||
if Rails.env.production?
|
||||
36
|
||||
45
|
||||
else
|
||||
1
|
||||
end
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class Article < ApplicationRecord
|
|||
:video, :user_id, :organization_id, :video_source_url, :video_code,
|
||||
:video_thumbnail_url, :video_closed_caption_track_url, :social_image,
|
||||
:published_from_feed, :crossposted_at, :published_at, :featured_number,
|
||||
:live_now, :last_buffered, :facebook_last_buffered, :created_at
|
||||
:live_now, :last_buffered, :facebook_last_buffered, :created_at, :body_markdown
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +329,7 @@ class Article < ApplicationRecord
|
|||
end
|
||||
|
||||
def evaluate_front_matter(front_matter)
|
||||
token_msg = "From the DEV community. Sharing ideas that makes us all better developers."
|
||||
token_msg = body_text[0..80] + "..."
|
||||
self.title = front_matter["title"] if front_matter["title"].present?
|
||||
if front_matter["tags"].present?
|
||||
ActsAsTaggableOn::Taggable::Cache.included(Article)
|
||||
|
|
@ -402,7 +402,7 @@ class Article < ApplicationRecord
|
|||
end
|
||||
|
||||
def set_last_comment_at
|
||||
self.last_comment_at = Time.now if published && last_comment_at < 30.days.ago
|
||||
self.last_comment_at = published_at.present? if published_at.present? && last_comment_at.blank?
|
||||
end
|
||||
|
||||
def title_to_slug
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class Organization < ApplicationRecord
|
|||
length: { maximum: 50 }
|
||||
validates :summary,
|
||||
length: { maximum: 250 }
|
||||
validates :tag_line,
|
||||
length: { maximum: 60 }
|
||||
validates :jobs_email, email: true, allow_blank: true
|
||||
validates :text_color_hex, format: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/
|
||||
validates :bg_color_hex, format: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/
|
||||
|
|
|
|||
13
app/views/additional_content_boxes/_article_box.html.erb
Normal file
13
app/views/additional_content_boxes/_article_box.html.erb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<div class="container show-page-content-display"
|
||||
data-details="<%= article.organization&.slug %>__<%= article.slug %>"
|
||||
id="<%= article.organization ? "partner-content-display" : "classic_article_#{article.id}" %>">
|
||||
<div class="content-classification">
|
||||
<span class="content-classification-text"><%= classification %></span>
|
||||
</div>
|
||||
<div class="main-content-display">
|
||||
<%= render "additional_content_boxes/article_content_area", article: article, organization: article.organization %>
|
||||
</div>
|
||||
<div class="secondary-content-display">
|
||||
<%= render "additional_content_boxes/article_followable_area", followable: article.organization || article.user, follow_cue: follow_cue %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<h2><a href="<%= article.path %>" class="<%= 'partner-link' if organization %>" data-details="<%= organization&.slug %>__<%= article.slug %>"><%= article.title %></a></h2>
|
||||
<div class="content-author">
|
||||
<a href="<%= article.user.path %>">
|
||||
<img class="profile-pic" src="<%= ProfileImage.new(article.user).get(50)%>" alt="<%= article.user.username %> profile image"/>
|
||||
<span><%= article.user.name %></span>
|
||||
</a>
|
||||
</div>
|
||||
<p>
|
||||
<a href="<%= article.path %>" class="<%= 'partner-link' if organization %>" data-details="<%= organization&.slug %>__<%= article.slug %>">
|
||||
<%= article.description %>
|
||||
</a>
|
||||
<div class="engagement-count">
|
||||
<% if article.positive_reactions_count > 0 %>
|
||||
<img src="<%= asset_path("reactions-stack.png") %>" alt="Reactions" /> <%= article.positive_reactions_count %>
|
||||
<% end %>
|
||||
<% if article.comments_count > 0 %>
|
||||
<img src="<%= asset_path("comments-bubble.png") %>" alt="Reactions" class="comments-bubble"/> <%= article.comments_count %>
|
||||
<% end %>
|
||||
</div>
|
||||
</p>
|
||||
<a href="<%= article.path %>" class="cta<%= ' partner-link' if organization %>" data-details="<%= organization&.slug %>__<%= article.slug %>">READ POST</a>
|
||||
<button
|
||||
class="article-engagement-count bookmark-engage<%= ' partner-link' if organization %>"
|
||||
data-reactable-id="<%= article.id %>"
|
||||
aria-label="Save to reading list"
|
||||
data-details="<%= organization&.slug %>__<%= article.slug %>"
|
||||
title="Save to reading list">
|
||||
<span class="bm-success"><img src="<%= asset_path("readinglist-button.png") %>" alt="bookmark" /> SAVED</span>
|
||||
<span class="bm-initial">SAVE FOR LATER</span>
|
||||
</button>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<% if followable.class.name == "Organization" && followable.nav_image.present? %>
|
||||
<div class="profile-pic-wrapper wide-profile-image-wrapper">
|
||||
<a href="<%= followable.path %>" />
|
||||
<img class="wide-image" src="<%= CloudinaryHelper.cl_image_path(followable.nav_image_url,
|
||||
type: "fetch",
|
||||
crop: "fill",
|
||||
width: 220,
|
||||
quality: "auto",
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true) %>" />
|
||||
</a>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="profile-pic-wrapper">
|
||||
<a href="<%= followable.path %>" />
|
||||
<img class="profile-image" src="<%= ProfileImage.new(followable).get(200) %>" style="border: 4px solid <%= followable.bg_color_hex %>" />
|
||||
</div>
|
||||
<div class="org-name">
|
||||
<a href="<%= followable.path %>" /><%= followable.name %></a>
|
||||
</div>
|
||||
<% end %>
|
||||
<button class="cta follow-action-button user-profile-follow-button" style="color:<%= user_colors(followable)[:text] %>;background-color:<%=user_colors(followable)[:bg] %>" data-info='{"id":<%= followable.id%>,"className":"<%= followable.class.name %>"}'> </button>
|
||||
<div class="org-summary"><%= follow_cue&.html_safe || followable.summary %></div>
|
||||
17
app/views/additional_content_boxes/boxes.html.erb
Normal file
17
app/views/additional_content_boxes/boxes.html.erb
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<% if @boosted_article %>
|
||||
<%= render "additional_content_boxes/article_box",
|
||||
article: @boosted_article,
|
||||
classification: "From one of our Community Sponsors",
|
||||
follow_cue: @boosted_article.organization.tag_line || @boosted_article.organization.summary %>
|
||||
<% elsif @alt_classic %>
|
||||
<%= render "additional_content_boxes/article_box",
|
||||
article: @alt_classic,
|
||||
classification: "Classic Post from #{@alt_classic.readable_publish_date}",
|
||||
follow_cue: "Follow <a href='#{@alt_classic.user.path}'>@#{@alt_classic.user.username}</a> to see more of their posts in your feed." %>
|
||||
<% end %>
|
||||
<% if @for_user_article %>
|
||||
<%= render "additional_content_boxes/article_box",
|
||||
article: @for_user_article,
|
||||
classification: "One More You Might Like",
|
||||
follow_cue: "Follow <a href='#{@for_user_article.user.path}'>@#{@for_user_article.user.username}</a> to see more of their posts in your feed." %>
|
||||
<% end %>
|
||||
|
|
@ -180,7 +180,14 @@
|
|||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% cache("article-bottom-content-#{@article.id}", :expires_in => 12.hours) do %>
|
||||
<% cache("article-bottom-content-#{@article.cached_tag_list_array.sort}", :expires_in => 6.hours) do %>
|
||||
<% if @classic_article %>
|
||||
<%= render "additional_content_boxes/article_box",
|
||||
article: @classic_article,
|
||||
classification: "Classic Post from #{@classic_article.readable_publish_date}",
|
||||
follow_cue: "Follow <a href='#{@classic_article.user.path}'>@#{@classic_article.user.username}</a> to see more of their posts in your feed." %>
|
||||
<% end %>
|
||||
<div id="additional-content-area" data-article-id="<%= @article.id %>,<%= @classic_article&.id %>"></div>
|
||||
<%= render 'articles/bottom_content' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -39,31 +39,40 @@
|
|||
  Live Now: <input name="article[live_now]" type="checkbox" <%= "checked" if article.live_now %>>
|
||||
  Image BG color: <input name="article[main_image_background_hex_color]" value="<%= article.main_image_background_hex_color %>" id="featured_number_<%= article.id %>"><br/><br/>
|
||||
Social Image: <input name="article[social_image]" value="<%= article.social_image %>" id="featured_number_<%= article.id %>">
|
||||
|
||||
<% if params[:state]&.include?("classic") %>
|
||||
<br/><br>
|
||||
<textarea cols="70" rows="6" wrap="hard" name="article[body_markdown]" /><%= article.body_markdown %></textarea>
|
||||
<% end %>
|
||||
|
||||
    <button class="btn btn-primary">SUBMIT</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="inner-row" style="padding:10px;margin-top:20px;font-weight:800;">
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="230" /><%= article.title %></textarea>
|
||||
<% if article.last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 TWEETED <%= time_ago_in_words(article.last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 TWEET 🚀🚀🚀🚀🚀🚀</button>
|
||||
|
||||
<% unless params[:state]&.include?("classic") %>
|
||||
<div class="inner-row" style="padding:10px;margin-top:20px;font-weight:800;">
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="twitter" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Twitter </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="tweet" maxlength="230" /><%= article.title %></textarea>
|
||||
<% if article.last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 TWEETED <%= time_ago_in_words(article.last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 TWEET 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Facebook & LinkedIn </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required/></textarea>
|
||||
<% if article.facebook_last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 POSTED <%= time_ago_in_words(article.facebook_last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 POST 🚀🚀🚀🚀🚀🚀</button>
|
||||
<%= form_tag "/internal/buffer_updates" do %>
|
||||
<input type="hidden" name="social_channel" value="facebook" />
|
||||
<input type="hidden" name="article_id" value="<%= article.id %>" />
|
||||
<p> Facebook & LinkedIn </p>
|
||||
<textarea cols="37" rows="6" wrap="hard" name="fb_post" required/></textarea>
|
||||
<% if article.facebook_last_buffered %>
|
||||
<button class="btn btn-danger" style="font-size:1em;">🙈 POSTED <%= time_ago_in_words(article.facebook_last_buffered) %> ago</button>
|
||||
<% else %>
|
||||
<button class="btn btn-info" style="font-size:1em;">😎 POST 🚀🚀🚀🚀🚀🚀</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
<a href="/internal/articles?state=top-3" style="padding:10px;<%= "background:#89ffba" if params[:state] == "top-3" %>">Top (3 mo)</a> |
|
||||
<a href="/internal/articles?state=top-6" style="padding:10px;<%= "background:#89ffba" if params[:state] == "top-6" %>">Top (6 mo)</a> |
|
||||
<a href="/internal/articles?state=spam" style="padding:10px;<%= "background:#89ffba" if params[:state] == "spam" %>">Spam?</a>
|
||||
<a href="/internal/articles?state=classic" style="padding:10px;<%= "background:#89ffba" if params[:state] == "classic" %>">Classic</a>
|
||||
<a href="/internal/articles?state=classic-candidate" style="padding:10px;<%= "background:#89ffba" if params[:state] == "classic-candidate" %>">Classic Candidate</a>
|
||||
</h3>
|
||||
<br/>
|
||||
<% if params[:state] && params[:state].include?("top-") && params[:state] != "top-3" && params[:state] != "top-6" %>
|
||||
|
|
@ -44,7 +46,7 @@
|
|||
|
||||
|
||||
<div class="row" style="font-size:1.5em;border:0px">
|
||||
<h1>Newest Articles</h1>
|
||||
<h1>All Articles</h1>
|
||||
<%= paginate @articles %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -52,14 +52,18 @@
|
|||
|
||||
<h2>Sponsors</h2>
|
||||
<h4 style="font-weight:400">
|
||||
You have the option to remove sponsor messaging (where it is practical to do so). Our wonderful sponsors help sustain the platform and improve your experience, and we strive to make their presence unobtrusive, but feel free to use this setting if you wish.
|
||||
You have the option to remove sponsor messaging (where it is practical to do so). Our wonderful sponsors help sustain the platform and improve your experience, and we strive to make their presence constructive to the community, but feel free to use this setting if you wish.
|
||||
</h4>
|
||||
|
||||
<%= form_for(@user) do |f| %>
|
||||
<div class="checkbox-field">
|
||||
<div class="sub-field">
|
||||
<%= f.check_box :display_sponsors %>
|
||||
<%= f.label :display_sponsors, "Display Sponsors" %>
|
||||
<%= f.label :display_sponsors, "Display Sponsors (When browsing)" %>
|
||||
</div>
|
||||
<div class="sub-field">
|
||||
<%= f.check_box :permit_adjacent_sponsors %>
|
||||
<%= f.label :permit_adjacent_sponsors, "Permit Nearby Sponsors (When publishing)" %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@
|
|||
<%= f.label :tech_stack, "Our Stack" %>
|
||||
<%= f.text_area :tech_stack, maxlength: 200 %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :tag_line %>
|
||||
<%= f.text_area :tag_line, maxlegth: 60 %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :summary %>
|
||||
<%= f.text_area :summary, maxlegth: 250 %>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"users",
|
||||
"settings",
|
||||
"about",
|
||||
"additional_content_boxes",
|
||||
"features",
|
||||
"privacy",
|
||||
"terms",
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ Rails.application.routes.draw do
|
|||
resources :github_repos, only: [:create, :update]
|
||||
resources :buffered_articles, only: [:index]
|
||||
resources :events, only: [:index, :show]
|
||||
resources :additional_content_boxes, only: [:index]
|
||||
get "/notifications/:username" => "notifications#index"
|
||||
patch "/onboarding_update" => "users#onboarding_update"
|
||||
# resources :users
|
||||
|
|
|
|||
5
db/migrate/20180316143921_add_boosted_to_articles.rb
Normal file
5
db/migrate/20180316143921_add_boosted_to_articles.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class AddBoostedToArticles < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :articles, :boosted, :boolean, default: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddTaglineToOrganizations < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :organizations, :tag_line, :string
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class AddPermitAdjacentSponsorsToUsers < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :users, :permit_adjacent_sponsors, :boolean, default: true
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20180304151124) do
|
||||
ActiveRecord::Schema.define(version: 20180316174324) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -106,6 +106,7 @@ ActiveRecord::Schema.define(version: 20180304151124) do
|
|||
t.string "video_source_url"
|
||||
t.string "video_thumbnail_url"
|
||||
t.datetime "last_comment_at", default: "2017-01-01 05:00:00"
|
||||
t.boolean "boosted", default: false
|
||||
t.index ["featured_number"], name: "index_articles_on_featured_number"
|
||||
t.index ["hotness_score"], name: "index_articles_on_hotness_score"
|
||||
t.index ["published_at"], name: "index_articles_on_published_at"
|
||||
|
|
@ -363,6 +364,7 @@ ActiveRecord::Schema.define(version: 20180304151124) do
|
|||
t.datetime "updated_at", null: false
|
||||
t.string "url"
|
||||
t.string "zip_code"
|
||||
t.string "tag_line"
|
||||
t.index ["slug"], name: "index_organizations_on_slug", unique: true
|
||||
end
|
||||
|
||||
|
|
@ -615,6 +617,7 @@ ActiveRecord::Schema.define(version: 20180304151124) do
|
|||
t.string "username"
|
||||
t.string "website_url"
|
||||
t.datetime "workshop_expiration"
|
||||
t.boolean "permit_adjacent_sponsors", default: true
|
||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||
t.index ["language_settings"], name: "index_users_on_language_settings", using: :gin
|
||||
t.index ["organization_id"], name: "index_users_on_organization_id"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue