docbrown/app/assets/javascripts/initializers/initializeFetchFollowedArticles.js.erb
Nick Taylor f6e99dec8b
Nickytonline/homepage main feed component (#6164) [deploy]
* wip

* Removed reference to cached_tag_list as the feed enpoint only returns tag_list now.

* Removed reference to cached_properties.

* Updated <CommentsCount /> and <TagList /> to support additinal className

* wip

* wip

* Undid init scrolling for Algolia articles

* Converted homePageFeed.jsx to an ERB template to access Sprockets.

* Now the homePageFeed.jsx files is an ERB so it can load Sprockets assets.

* wip

* Removed accidental commit of debugger statement in ERB.

* Now different feed time frames are loaded based on the homepage feed tab clicked.

* Prevent default Algolia paging when on the homepage.

* Added a tiny comment about feed time frame.

* Now feed loads properly for each time frame on home page.

* prop name refactor.

* Reneabled default Algolia scrolling.

* On the homepage, we no longer overwrite article HTML with Algolia data for initial articles.

* Assumption is the proper URL for main_image of featured article will be sent in the feed.

* Fixed Google Analytics for featured article.

* No longer need the new-feed ID for checking if we're on the homepage.

* Trying to make codeclimate happy.

* wip

* Removed reference to cached_tag_list as the feed enpoint only returns tag_list now.

* Removed reference to cached_properties.

* Updated <CommentsCount /> and <TagList /> to support additinal className

* wip

* wip

* Undid init scrolling for Algolia articles

* Converted homePageFeed.jsx to an ERB template to access Sprockets.

* Now the homePageFeed.jsx files is an ERB so it can load Sprockets assets.

* wip

* Removed accidental commit of debugger statement in ERB.

* Now different feed time frames are loaded based on the homepage feed tab clicked.

* Prevent default Algolia paging when on the homepage.

* Added a tiny comment about feed time frame.

* Now feed loads properly for each time frame on home page.

* prop name refactor.

* Reneabled default Algolia scrolling.

* On the homepage, we no longer overwrite article HTML with Algolia data for initial articles.

* Assumption is the proper URL for main_image of featured article will be sent in the feed.

* Fixed Google Analytics for featured article.

* No longer need the new-feed ID for checking if we're on the homepage.

* Added postcst episodes to <Feed /> state.

* Breaking up Article.jsx to make codeclimate happy.

* wip

* Created the <TodaysPodcastEpisodes /> and <PodcastEpisode /> components.

* Fixed issues with some components that were updated for the <FeaturedArticle />

* Added tests for <FeaturedArticle />

* Barreled up <FeaturedArticle />

* Added Storybook stories for <FeaturedArticle />

* Featured articles don't display org, so removed that test.

* Added proper today's podcasts components to feed.

* Converted some leftover ERB + removed pro checkmark as it doesn't exist yet.

* Now logic is same as master for feed timeframe.

* Updated <FeaturedArticle /> snapshots.

* On frontpage, bookmark button state is managed by Preact components now.

* bookmarkedFeedItems is now a prop on <Feed />.

* Fixed logic check for initializing reading list icons.

* Now <Article /> and <FeaturedArticle /> receive a bookmarkClick prop.

* Removed beginnings of scroll handler in <Feed /> as we're using what's there already for now.

* Removed logic to not show main image on other time frame feeds as it was not correct.

* Fixed issue with 0 rendering when no podcast episodes in feed.

* Converted <SaveButton /> to a stateful component.

* wip - <Feed /> render prop now passes bookmarked feed item ID set and a click event.

* Moved FEED_ICONS to an export so it's easier to use JSX/JS in <Feed />

* Moved <Feed /> into article components.

* Now reading list save buttons work properly in Preact components.

* Fixed issue with Save buttons in Algolia paging/<Feed />

* Updated snapshots.

* Took <Feed /> out of articles barrel file as jest was trying to import FEED_ICONs which is an ERB template.

* Now the Preact feed is dynamically imported.

* Now the Preact <Feed /> only loads for a logged on user.

* Fixed <FeaturedArticle /> so that the save button behaves properly now.

* Updated article stories for Storybook.

* Putting this back to the order it was because I've removed my code changes for this block.

* Fixed when renderFeed is imported for a logged on user.

* Add podcasts to feed and render home from server

* Add padding to feature laoding div

* Update tests

* Add more loading articles

* Fix conflicts

* Add readinglist javascript to initscrolling

* Ensure first article is one with image

* Organize feed items outside of feed instead of in it

Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
Co-authored-by: Josh Puetz <josh@grorichpuetz.com>
2020-02-28 14:14:47 -05:00

171 lines
5.9 KiB
Text

function initializeFetchFollowedArticles() {
if ( document.getElementById("featured-story-marker") && checkUserLoggedIn() ) {
algoliaFollowedArticles();
}
insertTimes();
}
function insertArticle(article,parent,insertPlace) {
if (article){
var newItem = document.createElement("DIV");
if (article.cached_user) {
article.user = article.cached_user.table
}
if (article.cached_organization) {
article.organization = article.cached_organization.table
}
newItem.innerHTML = buildArticleHTML(article)
parent.insertBefore(newItem, insertPlace);
initializeReadingListIcons();
}
}
function insertInitialArticles(user) {
var el = document.getElementById("home-articles-object");
if (!el) {return}
el.innerHTML = "";
insertTopArticles(user);
el.outerHTML = "";
}
function insertTopArticles(user){
var el = document.getElementById("home-articles-object");
var articlesJSON = JSON.parse(el.dataset.articles)
var insertPlace = document.getElementById("article-index-hidden-div");
if (insertPlace) {
articlesJSON.forEach(function(article){
var articlePoints = 0
var containsUserID = findOne([article.user_id], user.followed_user_ids || [])
var containsOrganizationID = findOne([article.organization_id], user.followed_organization_ids || [])
var intersectedTags = intersect_arrays(user.followed_tag_names, article.cached_tag_list_array)
var followedPoints = 1
var experienceDifference = Math.abs(article['experience_level_rating'] - user.experience_level || 5)
var containsPreferredLanguage = findOne([article.language || 'en'], user.preferred_languages_array || ['en'])
JSON.parse(user.followed_tags).map(function(tag) {
if (intersectedTags.includes(tag.name)) {
followedPoints = followedPoints + tag.points
}
})
articlePoints = articlePoints + followedPoints
if (containsUserID) {
articlePoints = articlePoints + 1
}
if (containsOrganizationID) {
articlePoints = articlePoints + 1
}
var rand = Math.random();
if (rand < 0.3) {
articlePoints = articlePoints + 3
} else if (rand < 0.6) {
articlePoints = articlePoints + 6
}
if (containsPreferredLanguage) {
articlePoints = articlePoints + 1
} else {
articlePoints = articlePoints - 10
}
articlePoints = articlePoints - (experienceDifference/2);
article['points'] = articlePoints
});
var sortedArticles = articlesJSON.sort(function(a, b) {
return b.points - a.points;
});
sortedArticles.forEach(function(article){
var parent = insertPlace.parentNode;
if ( article.points > 0 && !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)
const checkBlockedContentEvent = new CustomEvent('checkBlockedContent')
window.dispatchEvent(checkBlockedContentEvent)
var followedUsersArray = [];
if (user.followed_user_ids){
followedUsersArray = user.followed_user_ids.map(function(id){return 'user_'+id});
}
var publicSearchKey = '<%= ALGOLIASEARCH_PUBLIC_SEARCH_ONLY_KEY %>'
var client = algoliasearch('<%= ApplicationConfig["ALGOLIASEARCH_APPLICATION_ID"] %>', publicSearchKey);
var index = client.initIndex('ordered_articles_<%= Rails.env %>');
var searchObj = {
hitsPerPage: 20,
page: "0",
attributesToHighlight: [],
tagFilters: [user.followed_tag_names.concat(followedUsersArray)],
}
var homeEl = document.getElementById("index-container");
if (homeEl.dataset.feed === "base-feed") {
articlesIndex = client.initIndex('ordered_articles_<%= Rails.env %>');
} else if (homeEl.dataset.feed === "latest") {
articlesIndex = client.initIndex('ordered_articles_by_published_at_<%= Rails.env %>');
} else {
searchObj["filters"] = ('published_at_int > ' + homeEl.dataset.articlesSince);
articlesIndex = client.initIndex('ordered_articles_by_positive_reactions_count_<%= Rails.env %>');
}
articlesIndex.search("*", searchObj)
.then(function searchDone(content) {
var insertPlace = document.getElementById("article-index-hidden-div");
if (insertPlace) {
var parent = insertPlace.parentNode;
content.hits.forEach(function(article){
if ( !document.getElementById("article-link-"+article.id) ) {
insertArticle(article,parent,insertPlace);
}
});
}
var el = document.getElementById("home-articles-object")
if (el){el.outerHTML = ''}
});
}
}
function findOne(haystack, arr) {
return arr.some(function (v) {
return haystack.indexOf(v) >= 0;
});
};
function intersect_arrays(a, b) {
var sorted_a = a.concat().sort();
var sorted_b = b.concat().sort();
var common = [];
var a_i = 0;
var b_i = 0;
while (a_i < a.length
&& b_i < b.length)
{
if (sorted_a[a_i] === sorted_b[b_i]) {
common.push(sorted_a[a_i]);
a_i++;
b_i++;
}
else if(sorted_a[a_i] < sorted_b[b_i]) {
a_i++;
}
else {
b_i++;
}
}
return common;
}
function insertTimes() {
var elements = document.getElementsByClassName('time-ago-indicator-initial-placeholder');
for (var i = 0; i < elements.length; i++) {
// getElementsByClassName will get updated everytime we change DOM
// so elements[0] will produce the next unchanged element every iteration
var element = elements[0];
element.outerHTML = timeAgo({ oldTimeInSeconds: element.dataset.seconds });
}
};