Skip to content

Instantly share code, notes, and snippets.

@jamesgarrett
Created November 20, 2017 19:56
Show Gist options
  • Save jamesgarrett/f2fb76d9f2bfa6709eff5bd134c78308 to your computer and use it in GitHub Desktop.
Save jamesgarrett/f2fb76d9f2bfa6709eff5bd134c78308 to your computer and use it in GitHub Desktop.
Project 02
import $ from 'jquery';
import _ from 'lodash';
$(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: true, // You can have only one default source
formatResponse: function(response) {
return _.map(response.data.children, function(child) {
return {
title: child.data.title,
author: child.data.author,
score: child.data.score,
link: child.data.url,
thumbnail: child.data.thumbnail,
tag: child.data.subreddit,
description: child.data.domain
};
});
}
},
{
displayName: "Digg",
url: "http://digg.com/api/news/popular.json",
proxyRequired: true,
defaultSource: false,
formatResponse: function(response) {
const articles = response.data.feed;
return _.map(articles, function(article) {
return {
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) {
const articles = response.new;
return _.map(articles, function(article) {
return {
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 = {
getArticlesMarkup: function(articles) {
return _.map(articles, function(article) {
return Utils.getSingleArticleMarkup(article);
});
},
getSingleArticleMarkup: function(article) {
return `<article class="article clearfix">
<section class="featuredImage">
<img src="${article.thumbnail}" alt="">
</section>
<section class="articleContent">
<a href="${article.link}"><h3>${article.title}</h3></a>
<h6>${article.tag}</h6>
</section>
<section class="impressions">${article.score}</section>
<section class="hidden description">${article.description}</section>
</article>`
},
getSourcesMarkup: function(SOURCES) {
return _.map(SOURCES, function(source) {
return Utils.getSingleSourceMarkup(source);
});
},
getSingleSourceMarkup: function(source) {
return `<li class="sourceListItem"><a href="#" id="${source.displayName}">${source.displayName}</a></li>`
},
truncateString: function (str, length) {
return str.length > length ? str.substring(0, length - 3) + '...' : str
}
};
// 1) Show loading view
// 2) Determine default feed => showDefaultFeed
// 3) Make AJAX request for feed data => requestFeed
// 3.5) Show loading screen
// 4) Format response into specific shape
// 5) Build out HTML for articles using formatted response
// 5.5) Build out HTML for one article
// 6) Add the HTML for articles to page
// 7) Show Feed view
// App object to store all app relates metods
// listen on
// for each li in sources dropdown
// listen on clicks for each element in list
// if a user clicks,
// remove active classes
// display loader
// display feed which matches index
var App = {
init: function() {
// Methods that need to be called on initialization
App.showDefaultFeed();
App.renderSources();
App.bindEvents();
},
bindEvents: function() {
$('.sources-dropdown li').on("click", function(){
App.showFeed(SOURCES[$(this).index()]);
});
$(document).on("click", ".article a", function(event){
event.preventDefault();
App.setView('detail');
const link = $(this);
const article = $(this).closest('.article');
App.renderDetail(link, article);
});
$(document).on('click', '.closePopUp', function(event){
$(this).addClass('hidden loader');
$('#popUp').addClass('hidden');
});
},
showDefaultFeed: function() {
const defaultFeed = _.find(SOURCES, { defaultSource: true });
App.showFeed(defaultFeed);
},
showFeed: function(feed) {
const request = App.requestFeed(feed.url, feed.proxyRequired);
request.done(function(response) {
const articles = feed.formatResponse(response);
App.renderFeed(articles);
App.setView("feed");
});
},
requestFeed: function(url, proxyRequired) {
const feedUrl = proxyRequired ? PROXY_URL + url : url;
App.setView("loader");
return $.ajax(feedUrl, {
dataType: "json"
});
},
renderFeed: function(articles) {
const articlesMarkup = Utils.getArticlesMarkup(articles);
$('#main').html(articlesMarkup);
},
renderSources: function(){
const sourcesMarkup = Utils.getSourcesMarkup(SOURCES);
$('.sources-dropdown').html(sourcesMarkup);
},
renderDetail: function(link, article){
const href = $(link).attr("href");
const title = $(link).find("h3").text();
const description = $(article).find("section.description").text();
const truncated = Utils.truncateString(description, 345);
$('#popUp .container h1').html(title);
$('#popUp .container a').attr('href', href);
$('#popUp .container p').html(truncated);
console.log(description);
},
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