Skip to content

Instantly share code, notes, and snippets.

@juliaamosova
Created August 19, 2017 04:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juliaamosova/94e43c1b65a3b65bbf9f166139d3cc6e to your computer and use it in GitHub Desktop.
Save juliaamosova/94e43c1b65a3b65bbf9f166139d3cc6e to your computer and use it in GitHub Desktop.
Feedr Project App
$(document).ready(function(){
// Array to store all feed sources
var SOURCES = [
{
displayName: "Reddit",
url: "https://www.reddit.com/r/worldnews/top/.json",
proxyRequired: false,
defaultSource: false, // You can have only one default source
formatResponse: function(response) {
return _.map(response.data.children, function(child) {
var data = child.data;
return {
/* Adding 'id' in order to be able to identify a single article
that had been clicked on when need to open a single article view */
id: _.uniqueId(),
title: data.title,
author: data.author,
score: data.score,
link: data.url,
thumbnail: data.thumbnail,
tag: data.subreddit,
description: data.domain
};
});
}
},
{
// Digg is a default feed
displayName: "Digg",
url: "http://digg.com/api/news/popular.json",
proxyRequired: true,
defaultSource: true,
formatResponse: function(response) {
var articles = response.data.feed;
return _.map(articles, function(article) {
return {
/* Adding 'id' in order to be able to identify a single article
that had been clicked on when need to open a single article view */
id: _.uniqueId(),
description: article.content.description,
score: article.digg_score,
link: article.content.url,
tag: article.content.kicker,
title: article.content.title,
thumbnail: article.content.media.images[0].url
};
});
}
},
{
displayName: "Mashable",
url: "http://mashable.com/stories.json",
proxyRequired: true,
defaultSource: false,
formatResponse: function(response) {
var articles = response.new;
return _.map(articles, function(article) {
return {
/* Adding 'id' in order to be able to identify a single article
that had been clicked on when need to open a single article view */
id: _.uniqueId(),
description: article.content.plain,
score: article.shares.total,
link: article.link,
tag: article.channel,
title: article.title,
thumbnail: article.responsive_images[2].image
};
});
}
}
];
// Prefix url for proxy
var PROXY_URL = "https://accesscontrolalloworiginall.herokuapp.com/";
// Utils object to store any misc. methods
var Utils = {
markupFromArticles: function(articles) {
var articlesMarkup = _.map(articles, function(article) {
return Utils.markupFromSingleArticle(article);
});
return articlesMarkup.join('');
},
markupFromSingleArticle: function(article) {
return Utils.articleTemplate(article);
},
articleTemplate: _.template('<article class="article clearfix">' +
'<section class="featuredImage">' +
'<img src="<%= thumbnail %>" alt=""></section>' +
// Including an 'id' directly in the HTML
'<section class="articleContent" articleId="<%= id %>">' +
'<a href=#><h3><%= title %></h3></a>' +
'<h6><%= tag %></h6>' +
'</section>' +
'<section class="impressions"><%= score %></section>' +
'</article>')
};
// App object to store all app relates methods
var App = {
init: function() {
// Methods that need to be called on initialization
App.populateMenu();
App.bindEvents();
App.showDefaultFeed();
},
// Method that populates Dropdown menu when clicked on "News Source"
populateMenu: function() {
SOURCES.forEach(function(feed) {
var $dropDownItem = $("<li class='feed-selector'><a href=#>" + feed.displayName + "</a></li>");
$dropDownItem.on('click', function() {
App.showFeed(feed);
})
$dropDownItem.appendTo(".sources-dropdown");
});
},
bindEvents: function(feed) {
// Clicking on "News Source" section
$("nav ul li").on('click', function() {
$(this).find(".sources-dropdown").toggle();
});
// Clicking on 'Feedr' logo
$("a h1").on('click', function() {
App.showDefaultFeed(feed);
});
// Clicking on Search icon
$("header #search").on('click', function() {
$(this).toggleClass("active");
});
},
showDefaultFeed: function() {
// Determine default feed
var defaultFeed = _.findWhere(SOURCES, { defaultSource: true });
App.showFeed(defaultFeed);
},
currentArticles: [],
showFeed: function(feed) {
var request = App.requestFeed(feed.url, feed.proxyRequired);
request.done(function(response) {
var currentArticles = feed.formatResponse(response);
App.currentArticles = currentArticles;
App.renderFeed(currentArticles);
})
/* Adding 'fail' event to the 'request'.
If feed can't be loaded, an alert will pop-up with error message dispalyed */
.fail(function() {
alert("The feed can't be loaded!");
});
},
requestFeed: function(feedUrl, proxyRequired) {
var url = proxyRequired ? PROXY_URL + feedUrl : feedUrl;
// Show loading view
App.setView("loader");
return $.ajax(url, {
dataType: "json"
});
},
renderFeed: function(articles) {
var articlesHTML = Utils.markupFromArticles(articles);
$('#main').html(articlesHTML);
App.setView("feed");
// Clicking on each individual article
$(".articleContent").on('click', function() {
var articleId = $(this).attr("articleId");
var article = _.find(App.currentArticles, function(item) {
return item.id === articleId;
});
App.requestSingleArticle(article);
})
},
// Display PopUp window with single article
requestSingleArticle: function(article) {
var content = "<h1>" + article.title + "</h1><p>" + article.description + "</p><a href='" + article.link + "' class='popUpAction' target='_blank'>Read More</a>";
App.setView("detail");
$("#popUp .container").html(content);
$('.closePopUp').on ('click', function() {
App.setView("feed");
})
},
setView: function(viewType) {
var $popup = $('#popUp');
var $closePopUp = $('.closePopUp');
if (viewType === 'loader') {
$popup.removeClass('hidden');
$closePopUp.addClass('hidden');
$popup.addClass('loader');
}
else if (viewType === 'detail') {
$popup.removeClass('hidden');
$closePopUp.removeClass('hidden');
$popup.removeClass('loader');
}
else if (viewType === 'feed') {
$popup.addClass('hidden');
$closePopUp.addClass('hidden');
}
}
};
App.init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment