Skip to content

Commit

Permalink
Update feed for slightly more customized top articles (#642)
Browse files Browse the repository at this point in the history
* Update home feed logic and display

* Remove console log
  • Loading branch information
benhalpern committed Sep 12, 2018
1 parent 5255078 commit 91f9903
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,28 @@ function insertArticle(article,parent,insertPlace) {
}
}

function insertInitialArticles(user) {
var el = document.getElementById("home-articles-object")
if (!el) {return}
var articlesJSON = JSON.parse(el.dataset.articles)
el.outerHTML = "";
var insertPlace = document.getElementById("article-index-hidden-div");
if (insertPlace) {
var parent = insertPlace.parentNode;
articlesJSON.forEach(function(article){
var containsTag = findOne(user.followed_tag_names, article.cached_tag_list_array)
var containsUserID = findOne([article.user_id], user.followed_user_ids)
if ( (containsTag || containsUserID) && !document.getElementById("article-link-"+article.id) ) {
insertArticle(article,parent,insertPlace);
}
});
}
}

function algoliaFollowedArticles(){
var user = userData();
if (user && user.followed_tag_names && user.followed_tag_names.length > 0) {
insertInitialArticles(user)
var followedUsersArray = [];
if (user.followed_user_ids){
followedUsersArray = user.followed_user_ids.map(function(id){return 'user_'+id});
Expand Down Expand Up @@ -53,4 +72,10 @@ function algoliaFollowedArticles(){
}
});
}
}
}

function findOne(haystack, arr) {
return arr.some(function (v) {
return haystack.indexOf(v) >= 0;
});
};
7 changes: 4 additions & 3 deletions app/assets/javascripts/utilities/buildArticleHTML.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ function buildArticleHTML(article) {
else if (article) {
var container = document.getElementById("index-container");
var tagString = ""
if(article.tag_list) {
article.tag_list.forEach(function(t){
var tagList = article.tag_list || article.cached_tag_list_array
if(tagList) {
tagList.forEach(function(t){
tagString = tagString + '<a href="/t/'+t+'"><span class="tag">#'+t+'</span></a>\n'
});
}
var commentsCountHTML = ""
if ((article.comments_count || '0') > 0 && article.class_name != "User") {
commentsCountHTML = '<div class="article-engagement-count comments-count"><a href="'+article.path+'"><img src="<%= asset_path("comments-bubble.png") %>" alt="chat" /><span class="engagement-count-number">'+(article.comments_count || '0')+'</span></a></div>'
commentsCountHTML = '<div class="article-engagement-count comments-count"><a href="'+article.path+'#comments"><img src="<%= asset_path("comments-bubble.png") %>" alt="chat" /><span class="engagement-count-number">'+(article.comments_count || '0')+'</span></a></div>'
}
var flareTag = ""
if (container){
Expand Down
30 changes: 29 additions & 1 deletion app/assets/stylesheets/articles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@
}
&.comments-count {
left:93px;
img{
width: 28px;
}
}
&.reactions-count {
left:20px;
Expand Down Expand Up @@ -1359,4 +1362,29 @@
&.showing {
display:block;
}
}
}

.single-article-loading{
@extend .animated-background;
}

@keyframes placeHolderShimmer{
0%{
background-position: -468px 0
}
100%{
background-position: 468px 0
}
}

.animated-background {
animation-duration: 1.25s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #F6F6F6;
background: linear-gradient(to right, #F6F6F6 8%, #F0F0F0 18%, #F6F6F6 33%);
background-size: 800px 104px;
position: relative;
}
5 changes: 3 additions & 2 deletions app/black_box/black_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ class BlackBox
def self.article_hotness_score(article)
return (article.featured_number || 10000) / 10000 unless Rails.env.production?
reaction_points = article.reactions.sum(:points)
super_recent_bonus = article.published_at > 3.hours.ago ? 10 : 0
recency_bonus = article.published_at > 12.hours.ago ? 50 : 0
today_bonus = article.published_at > 36.hours.ago ? 250 : 0
today_bonus = article.published_at > 32.hours.ago ? 280 : 0
FunctionCaller.new("blackbox-production-articleHotness",
{ article: article, user: article.user }.to_json).call +
reaction_points + recency_bonus + today_bonus
reaction_points + recency_bonus + super_recent_bonus + today_bonus
end

def self.comment_quality_score(comment)
Expand Down
7 changes: 5 additions & 2 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def handle_tag_index
def handle_base_index
@home_page = true
@page = (params[:page] || 1).to_i
num_articles = user_signed_in? ? 3 : 15
num_articles = user_signed_in? ? 9 : 15
@stories = article_finder(num_articles)

if ["week", "month", "year", "infinity"].include?(params[:timeframe])
Expand All @@ -110,7 +110,10 @@ def handle_base_index
where("featured_number > ?", 1449999999)
@featured_story = Article.new
else
@stories = @stories.where(featured: true).order("hotness_score DESC")
@default_home_feed = true
@stories = @stories.
where("reactions_count > ? OR featured = ?", 10, true).
order("hotness_score DESC")
@featured_story = @stories.where.not(main_image: nil).first&.decorate || Article.new
end
@stories = @stories.decorate
Expand Down
4 changes: 2 additions & 2 deletions app/labor/cache_buster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ def bust_home_pages(article)
end
TIMEFRAMES.each do |timeframe|
if Article.where(published: true).where("published_at > ?", timeframe[0]).
order("positive_reactions_count DESC").limit(4).pluck(:id).include?(article.id)
order("positive_reactions_count DESC").limit(3).pluck(:id).include?(article.id)
bust("/top/#{timeframe[1]}")
bust("/top/#{timeframe[1]}?i=i")
bust("/top/#{timeframe[1]}/?i=i")
end
if Article.where(published: true).where("published_at > ?", timeframe[0]).
order("hotness_score DESC").limit(3).pluck(:id).include?(article.id)
order("hotness_score DESC").limit(2).pluck(:id).include?(article.id)
bust("/")
bust("?i=i")
end
Expand Down
14 changes: 6 additions & 8 deletions app/models/article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,12 @@ class Article < ApplicationRecord
:featured, :published, :published_at, :featured_number,
:comments_count, :reactions_count, :positive_reactions_count,
:path, :class_name, :user_name, :user_username, :comments_blob,
:body_text, :tag_keywords_for_search, :search_score, :readable_publish_date
:body_text, :tag_keywords_for_search, :search_score, :readable_publish_date, :flare_tag
attribute :user do
{ username: user.username,
name: user.name,
profile_image_90: ProfileImage.new(user).get(90) }
end
attribute :flare_tag do
FlareTag.new(self).tag_hash
end
tags do
[tag_list,
"user_#{user_id}",
Expand All @@ -134,7 +131,7 @@ class Article < ApplicationRecord
enqueue: :trigger_delayed_index do
attributes :title, :path, :class_name, :comments_count,
:tag_list, :positive_reactions_count, :id, :hotness_score,
:readable_publish_date
:readable_publish_date, :flare_tag
attribute :published_at_int do
published_at.to_i
end
Expand All @@ -143,9 +140,6 @@ class Article < ApplicationRecord
name: user.name,
profile_image_90: ProfileImage.new(user).get(90) }
end
attribute :flare_tag do
FlareTag.new(self).tag_hash
end
tags do
[tag_list,
"user_#{user_id}",
Expand Down Expand Up @@ -315,6 +309,10 @@ def class_name
self.class.name
end

def flare_tag
FlareTag.new(self).tag_hash
end

def update_main_image_background_hex
return if main_image.blank? || main_image_background_hex_color != "#dddddd"
update_column(:main_image_background_hex_color, ColorFromImage.new(main_image).main)
Expand Down
6 changes: 5 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class User < ApplicationRecord
attribute :user do
{ username: user.username,
name: user.username,
profile_image_90: ProfileImage.new(user).get(90) }
profile_image_90: profile_image_90 }
end
attribute :title, :path, :tag_list, :main_image, :id,
:featured, :published, :published_at, :featured_number, :comments_count,
Expand Down Expand Up @@ -355,6 +355,10 @@ def settings_tab_list
tab_list
end

def profile_image_90
ProfileImage.new(self).get(90)
end

private

def send_welcome_notification
Expand Down
80 changes: 52 additions & 28 deletions app/views/articles/_main_stories_feed.html.erb
Original file line number Diff line number Diff line change
@@ -1,34 +1,58 @@
<% num_showing = 0 %>
<% @stories.each_with_index do |story,i| %>
<% next if story.id == @featured_story.id %>
<% num_showing += 1 %>
<% break if (num_showing == 3 && user_signed_in?) && @home_page %>
<% if !user_signed_in? && i == 4 %>
<div class="single-article single-article-small-pic feed-cta" id="in-feed-cta">
<div class="cta-container" id="cta-content">
<h2>
<% if @tag.blank? %>
Need more relevant posts?<br />Sign in to customize your feed:
<% else %>
<a href="/">dev.to</a> is a community of <br/><%= number_with_delimiter User.all.size %> amazing humans who code.
<% end %>
</h2>
<div class="button-container">
<a href="/users/auth/twitter?callback_url=<%= ApplicationConfig["APP_PROTOCOL"] %><%= ApplicationConfig["APP_DOMAIN"] %>/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
TWITTER
</a>
<a href="/users/auth/github?state=in-feed-cta" class="cta cta-button" data-no-instant>
GITHUB
</a>
</div>
<% if !user_signed_in? || !@default_home_feed %>
<% @stories.each_with_index do |story,i| %>
<% next if story.id == @featured_story.id %>
<% if !user_signed_in? && i == 4 %>
<div class="single-article single-article-small-pic feed-cta" id="in-feed-cta">
<div class="cta-container" id="cta-content">
<h2>
<% if @tag.blank? %>
Need more relevant posts?<br />Sign in to customize your feed:
<% else %>
<a href="/">dev.to</a> is a community of <br/><%= number_with_delimiter User.all.size %> amazing humans who code.
<% end %>
</h2>
<div class="button-container">
<a href="/users/auth/twitter?callback_url=<%= ApplicationConfig["APP_PROTOCOL"] %><%= ApplicationConfig["APP_DOMAIN"] %>/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
TWITTER
</a>
<a href="/users/auth/github?state=in-feed-cta" class="cta cta-button" data-no-instant>
GITHUB
</a>
</div>
</div>
</div>
</div>
<% end %>
<%= render "articles/single_story", story: story %>
<% if i == 0 && @comments && @comments.size > 0 && @user %>
<%= render "articles/comments_section" %>
<% end %>
<%= render "articles/single_story", story: story %>
<% if i == 0 && @comments && @comments.size > 0 && @user %>
<%= render "articles/comments_section" %>
<% end %>
<% end %>
<% else %>
<div id="home-articles-object" data-articles="
<%=@stories.to_json(only:
[:title, :path, :id, :user_id, :comments_count, :positive_reactions_count],
methods:
[:readable_publish_date, :cached_tag_list_array, :flare_tag, :class_name],
include: [user: {only: [:username, :name], methods: [:profile_image_90]}]) %>">
<% 3.times do %>
<div class="single-article single-article-small-pic">
<div class="small-pic" >
<div class="color single-article-loading"></div>
</div>
<div class="content">
<h3 class="single-article-loading">&nbsp;</h3>
</div>
<h4 class="single-article-loading" style="width:46%">
&nbsp;
</h4>
<div class="tags single-article-loading" style="width:56%">
</div>
</div>
<% end %>
</div>
<% end %>
<% if @stories.length == 0 && @comments && @comments.size > 0 && @user %>
<%= render "articles/comments_section" %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/articles/_single_story.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</div>
<% if story.comments_count > 0 %>
<div class="article-engagement-count comments-count">
<a href="<%=story.path%>#comments-container">
<a href="<%=story.path%>#comments">
<img src="<%= asset_path("comments-bubble.png") %>" alt="chat" /><span class="engagement-count-number"><%= story.comments_count %></span>
</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/views/articles/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@
</div>
<% if @featured_story.comments_count > 0 %>
<div class="article-engagement-count comments-count featured-engagement-count">
<a href="<%=@featured_story.path%>"><img src="<%= asset_path("comments-bubble.png") %>" alt="chat" />
<a href="<%=@featured_story.path%>#comments"><img src="<%= asset_path("comments-bubble.png") %>" alt="chat" />
<span class="engagement-count-number"><%= @featured_story.comments_count %></span>
</a>
</div>
Expand Down
1 change: 1 addition & 0 deletions app/views/articles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
<% end %>
<% end %>
<%= render 'articles/org_branding', organization: @organization %>
<div id="comments" style="margin-top: -50px;padding-bottom:50px;position:relative;z-index:-100"></div>
<% if @article.show_comments %>
<div class="comments-container-container">
<div
Expand Down

0 comments on commit 91f9903

Please sign in to comment.