JSFiddle - React, Tailwind, and code Playground

RSS feed reader

by Hugo Carneiro

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.2.1/jquery-migrate.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/jfhovinne/jFeed@0d411f761c26013fb8f960d5a0a20f848706fdc5/build/dist/jquery.jfeed.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<section class="py-5 text-center container">
  <div class="row py-lg-5">
    <div class="col-lg-6 col-md-8 mx-auto">
      <h1 class="fw-light">RSS feeds</h1>
      <p class="lead text-muted">Click to load feed</p>
      <div class="btn-group feeds-list">
        <a href="#" class="btn btn-outline-secondary" data-url="https://feeds.bbci.co.uk/news/rss.xml">BBC News</a>
        <a href="#" class="btn btn-outline-secondary" data-url="https://www.buzzfeed.com/uk/index.xml">Buzzfeed</a>
        <a href="#" class="btn btn-primary active" data-url="https://fliplet.com/feed">Fliplet</a>
        <a href="#" class="btn btn-outline-secondary" data-url="https://www.ft.com/news-feed">FT</a>
      </div>
    </div>
  </div>
</section>

<!-- Pagination -->
<section class="py-5 text-center container pagination-holder visually-hidden">
  <div class="row py-lg-5">
    <nav>
      <ul class="pagination">
      </ul>
    </nav>
  </div>
</section>

<div class="container">
  <!-- Loading state UI -->
  <div class="alert alert-secondary loading-holder visually-hidden">Loading...</div>

  <!-- Error state UI -->
  <div class="alert alert-danger no-rss visually-hidden">
    <h5>Unable to load feed</h5>
    <!-- Show error message, if applicable -->
    <span...

CSS

.card-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  overflow: hidden;
}

JavaScript

var feedsLoaded = [];
var totalFeeds = 30;
var feedsPerPage = 5;
var totalPages = 1;
var previousPage = 1;
var currentPage = 1;
var itemsOffset = 0;
var feedItemTemplate = $("#feed-item-template").html();
var feedItemCompiledTemplate = Handlebars.compile(feedItemTemplate);
var paginationTemplate = $("#pagination-items-template").html();
var paginationCompiledTemplate = Handlebars.compile(paginationTemplate);

/**
 * Loads up to 30 posts from the feed URL. Function must return a Promise.
 * @param {String} url - Feed URL
 * @return {Promise<Array>} Promise resolves with the feed list, including a "thumbnail" property for the post thumbnail, if available
 */
function getFeed(url) {
  // 1) Use https://cors-anywhere.herokuapp.com to enable cross-origin requests and load the feed using jFeed. See https://github.com/jfhovinne/jFeed to learn more about jFeed
  // 2) Combine with the use of https://rss2json.com/ to retrieve any post thumbnails or if any error is encountered with jFeed. rss2json.com must only be used for post thumbnails and as a fallback system for processing errors from jFeed.
  // 3) Each feed should only be loaded once until the page reloads

  return new Promise((resolve, reject) => {
    $.ajax({
      url: 'https://api.rss2json.com/v1/api.json',
      method: 'GET',
      dataType: 'json',
      data: {
        rss_url: url,
        api_key: 'e1y0txvwmerevbcru0oy2jm2dtmbsu1wvjujhrfh',
        count: totalFeeds
      },
      success: function(feed) {
        resolve(feed);
      },
      error: function(error) {
        reject(error);
      }
    });

    /*
    jQuery.getFeed({
      url: 'https://cors-anywhere.herokuapp.com/' + url,
      success: function(feed) {
      	console.log(feed);
        resolve(feed);
      },
      error: function(error) {
        reject(error);
      }
    });
    */
  });
}

function calculatePages() {
  var feedURL = getActiveFeed();
  var getNewFeed = getFeedLoaded(feedURL);

  // Get the total number of pages...