thepracticaldev/dev.to

View on GitHub
app/assets/javascripts/utilities/buildArticleHTML.js

Summary

Maintainability
D
1 day
Test Coverage
/* global timeAgo, filterXSS */

/* eslint-disable no-multi-str */

function buildArticleHTML(article) {
  if (article && article.class_name === 'PodcastEpisode') {
    return (
      '<div class="single-article single-article-small-pic single-article-single-podcast">\
      <div class="small-pic">\
       <a href="/' +
      article.podcast.slug +
      '" class="small-pic-link-wrapper">\
         <img src="' +
      article.podcast.image_url +
      '" alt="' +
      article.podcast.title +
      ' image">\
       </a>\
       </div>\
       <a href="' +
      article.path +
      '" class="small-pic-link-wrapper index-article-link" id="article-link-' +
      article.id +
      '">\
        <div class="content">\
         <h3><span class="tag-identifier">podcast</span>' +
      article.title +
      '</h3>\
        </div>\
       </a>\
       <h4><a href="/' +
      article.podcast.slug +
      '">' +
      article.podcast.title +
      '</a></h4>\
       </div>'
    );
  }

  if (article) {
    var container = document.getElementById('index-container');
    var tagString = '';
    var tagList = article.tag_list || article.cached_tag_list_array;
    if (tagList) {
      tagList.forEach(function buildTagString(t) {
        tagString =
          tagString +
          '<a href="/t/' +
          t +
          '" class="crayons-tag"><span class="crayons-tag__prefix">#</span>' +
          t +
          '</a>\n';
      });
    }

    var commentsDisplay = '';
    var commentsCount = '0';
    if ((article.comments_count || '0') > 0) {
      commentsCount = article.comments_count || '0';
    }
    if (article.class_name !== 'User') {
      commentsDisplay =
        '<a href="' +
        article.path +
        '#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost-dimmed crayons-btn--icon-left "><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z"/></svg>' +
        commentsCount +
        '<span class="hidden s:inline">&nbsp;comments</span></a>';
    }

    var flareTag = '';
    var currentTag = '';
    if (container) {
      currentTag = JSON.parse(container.dataset.params).tag;
    }
    if (article.flare_tag && currentTag !== article.flare_tag.name) {
      flareTag =
        "<span class='crayons-story__flare-tag' style='background:" +
        article.flare_tag.bg_color_hex +
        ';color:' +
        article.flare_tag.text_color_hex +
        "'>#" +
        article.flare_tag.name +
        '</span>';
    }
    if (article.class_name === 'PodcastEpisode') {
      flareTag = "<span class='crayons-story__flare-tag'>podcast</span>";
    }
    if (article.class_name === 'Comment') {
      flareTag = "<span class='crayons-story__flare-tag'>comment</span>";
    }
    if (article.class_name === 'User') {
      flareTag =
        "<span class='crayons-story__flare-tag' style='background:#5874d9;color:white;'>person</span>";
    }

    var rc = article.public_reactions_count;
    var reactionsCount = rc || '0';
    var reactionsDisplay = '';

    if (article.class_name !== 'User') {
      reactionsDisplay =
        '<a href="' +
        article.path +
        '" class="crayons-btn crayons-btn--s crayons-btn--ghost-dimmed crayons-btn--icon-left"><svg class="crayons-icon" width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z"/></svg>' +
        reactionsCount +
        '<span class="hidden s:inline">&nbsp;reactions</span></a>';
    }

    var picUrl;
    var profileUsername;
    var userName;
    if (article.class_name === 'PodcastEpisode') {
      picUrl = article.main_image;
      profileUsername = article.slug;
      userName = article.title;
    } else {
      picUrl = article.user.profile_image_90;
      profileUsername = article.user.username;
      userName = article.user.name;
    }
    var orgHeadline = '';
    var forOrganization = '';
    var organizationLogo = '';
    var organizationClasses = 'crayons-avatar--l';

    if (
      article.organization &&
      !document.getElementById('organization-article-index')
    ) {
      organizationLogo =
        '<a href="/' +
        article.organization.slug +
        '" class="crayons-logo crayons-logo--l"><img alt="' +
        article.organization.name +
        ' logo" src="' +
        article.organization.profile_image_90 +
        '" class="crayons-logo__image" loading="lazy"/></a>';
      forOrganization =
        '<span><span class="crayons-story__tertiary fw-normal"> for </span><a href="/' +
        article.organization.slug +
        '" class="crayons-story__secondary fw-medium">' +
        article.organization.name +
        '</a></span>';
      organizationClasses =
        'crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted';
    }

    var timeAgoInWords = '';
    if (article.published_at_int) {
      timeAgoInWords = timeAgo({ oldTimeInSeconds: article.published_at_int });
    }

    var publishDate = '';
    if (article.readable_publish_date) {
      if (article.published_timestamp) {
        publishDate =
          '<time datetime="' +
          article.published_timestamp +
          '">' +
          article.readable_publish_date +
          ' ' +
          timeAgoInWords +
          '</time>';
      } else {
        publishDate =
          '<time>' +
          article.readable_publish_date +
          ' ' +
          timeAgoInWords +
          '</time>';
      }
    }

    var meta =
      '<div class="crayons-story__meta">\
      <div class="crayons-story__author-pic">\
        ' +
      organizationLogo +
      '\
        <a href="/' +
      profileUsername +
      '" class="crayons-avatar ' +
      organizationClasses +
      '">\
          <img src="' +
      picUrl +
      '" alt="' +
      profileUsername +
      ' profile" class="crayons-avatar__image" loading="lazy" />\
        </a>\
      </div>\
      <div>\
        <p>\
          <a href="/' +
      profileUsername +
      '" class="crayons-story__secondary fw-medium">' +
      filterXSS(article.user.name) +
      '</a>\
          ' +
      forOrganization +
      '\
        </p>\
        <a href="' +
      article.path +
      '" class="crayons-story__tertiary fs-xs">\
          ' +
      publishDate +
      '\
        </a>\
      </div>\
    </div>';

    var bodyTextSnippet = '';
    var searchSnippetHTML = '';
    if (article.highlight && article.highlight.body_text.length > 0) {
      var firstSnippetChar = article.highlight.body_text[0];
      var startingEllipsis = '';
      if (firstSnippetChar.toLowerCase() !== firstSnippetChar.toUpperCase()) {
        startingEllipsis = '…';
      }
      bodyTextSnippet =
        startingEllipsis + article.highlight.body_text.join('...') + '…';
      if (bodyTextSnippet.length > 0) {
        searchSnippetHTML =
          '<div class="crayons-story__snippet mb-1">' +
          bodyTextSnippet +
          '</div>';
      }
    }

    var readingTimeHTML = '';
    if (article.class_name === 'Article') {
      // we have ` ... || null` for the case article.reading_time is undefined
      readingTimeHTML =
        '<small class="crayons-story__tertiary fs-xs mr-2">' +
        ((article.reading_time || null) < 1
          ? '1 min'
          : article.reading_time + ' min') +
        ' read</small>';
    }

    var saveButton = '';
    if (article.class_name === 'Article') {
      saveButton =
        '<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--s bookmark-button" data-reactable-id="' +
        article.id +
        '">\
                      <span class="bm-initial">Save</span>\
                      <span class="bm-success">Saved</span>\
                    </button>';
    } else if (article.class_name === 'User') {
      saveButton =
        '<button type="button" class="crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user"\
                       data-info=\'{"id":' +
        article.id +
        ',"className":"User"}\' data-follow-action-button>\
                       &nbsp;\
                    </button>';
    }

    var videoHTML = '';
    if (article.cloudinary_video_url) {
      videoHTML =
        '<a href="' +
        article.path +
        '" class="crayons-story__video" style="background-image:url(' +
        article.cloudinary_video_url +
        ')"><div class="crayons-story__video__time">' +
        (article.video_duration_string || article.video_duration_in_minutes) +
        '</div></a>';
    }

    return (
      '<article class="crayons-story" data-article-path="' +
      article.path +
      '" data-content-user-id="' +
      article.user_id +
      '">\
      <div role="presentation">\
        ' +
      videoHTML +
      '\
        <div class="crayons-story__body">\
          <div class="crayons-story__top">\
            ' +
      meta +
      '\
          </div>\
          <div class="crayons-story__indention">\
            <h2 class="crayons-story__title"><a href="' +
      article.path +
      '" id="article-link-' +
      article.id +
      '">' +
      flareTag +
      filterXSS(article.title) +
      '</a></h2>\
            <div class="crayons-story__tags">' +
      tagString +
      '</div>\
            ' +
      searchSnippetHTML +
      '\
            <div class="crayons-story__bottom">\
              <div class="crayons-story__details">' +
      reactionsDisplay +
      commentsDisplay +
      '</div>\
                <div class="crayons-story__save">\
                ' +
      readingTimeHTML +
      '\
                ' +
      saveButton +
      '\
              </div>\
            </div>\
          </div>\
        </div>\
      </div>\
    </article>'
    );
  }

  return '';
}

/* eslint-enable no-multi-str */