cbillowes/curious-programmer-helium

View on GitHub
src/templates/post.jsx

Summary

Maintainability
A
0 mins
Test Coverage
import React from "react"
import { graphql } from "gatsby"
import Layout from "../layout"
import Disqus from "../components/Disqus/Disqus"
import Accordion from "../components/Accordion/Accordion"
import Tags from "../components/Tag/Tags"
import SocialLinks from "../components/Share/Share"
import PageMetadata from "../components/Metadata/Page/Metadata"
import PostMetadata from "../components/Metadata/Post/Metadata"
import CompactNavigation from "../components/PostNavigation/Compact"
import ElaborateNavigation from "../components/PostNavigation/Elaborate"
import "./post.scss"
const $ = require("jquery")

function blurCoverOnScroll() {
  if (typeof window !== "undefined" && window.scroll) {
    const background = $(".cover.default.background")
    if (background.length === 1) {
      const blurFrom = 150;
      let opacity = 1
      window.onscroll = function () {
        if (window.scrollY >= blurFrom) {
          opacity = 0
        } else {
          opacity = 1
        }

        if (opacity === 1 && !background.hasClass("opacity")) {
          background
            .addClass("opacity")
            .removeClass("no-opacity")
            .css({
              "opacity": opacity,
              "filter": `alpha(opacity=${opacity * 10})`,
              "transition": "opacity 1s ease-in-out"
            })
        }

        if (opacity === 0 && !background.hasClass("no-opacity")) {
          background
            .addClass("no-opacity")
            .removeClass("opacity")
            .css({
              "opacity": opacity,
              "filter": `alpha(opacity=${opacity * 10})`,
              "transition": "opacity 1s ease-in-out"
            })
        }
      }
    }
  }
}

function enableGifPlayback() {
  $(".gif").each(function () {
    const gif = $(this)
    gif.css({ "position": "relative" })
    const spinner = $(`<div class="loading spinner-border" role="status"><span class="sr-only">Loading...</span></div>`)
    spinner
      .css({
        "position": "absolute",
        "top": "1em",
        "left": "1em"
      })
    gif.prepend(spinner)

    const title = gif.attr("alt")
    const still = gif.find(".still")
    still
      .attr("alt", title)
      .css({ "cursor": "pointer" })
      .click(function () {
        gif.find(".loading").hide()
        gif.find(".still").hide()
        gif.find(".animated").show()
      })

    const animated = gif.find(".animated")
    animated
      .attr("alt", title)
      .css({ "cursor": "pointer" })
      .hide()
      .click(function () {
        if (gif.hasClass("loading")) return

        gif.find(".loading").hide()
        gif.find(".animated").hide()
        gif.find(".still").show()
      })
      .on("load", function () {
        gif.find(".loading").hide()
      })

    const enlarge = $(this).find("a")
    enlarge
      .html("<i>Enlarge this gif in a new window</i>")
      .attr("target", "_blank")
      .attr("nofollow")
  })
}

export default class PostTemplate extends React.Component {
  componentDidMount() {
    blurCoverOnScroll()
    enableGifPlayback()
  }

  getPostItem = (node) => {
    return {
      title: node.frontmatter.title,
      slug: node.fields.slug,
      excerpt: node.excerpt,
      timeToRead: node.timeToRead,
      cover: node.frontmatter.cover,
      date: node.fields.date,
      tags: node.frontmatter.tags
    }
  }

  render() {
    const { slug, next, prev } = this.props.pageContext
    const postNode = this.props.data.post
    const previousPost = this.getPostItem(this.props.data.prev)
    const nextPost = this.getPostItem(this.props.data.next)
    const post = postNode.frontmatter
    const blur = post.blur ? post.blur : `${post.cover}&blur`

    return (
      <Layout>
        <PageMetadata
          title={post.title}
          description={postNode.excerpt}
          slug={slug}
          images={{ cover: post.cover, ogImage: post.ogImage }} />
        {post.cover && blur ?
          <span className="cover blur background" style={{ backgroundImage: `url(${blur})` }}></span> :
          <span></span>}
        {post.cover ?
          <span className="cover default background" style={{ backgroundImage: `url(${post.cover})` }}></span> :
          <span></span>}
        <div className={`post ${post.cover ? "with-cover" : ""}`}>
          <div className="compact-navigation">
            <CompactNavigation previous={previousPost} next={nextPost} />
          </div>
          <div className="wild-container">
            <h1 id="title">{post.title}</h1>
          </div>
          <div className="container body">
            <PostMetadata tags={post.tags} date={postNode.fields.date} timeToRead={postNode.timeToRead} />
            <div className="container-post" dangerouslySetInnerHTML={{ __html: postNode.html }} />
            <Accordion content={postNode.html} />
            <div className="post-footer">
              <hr />
              <Tags tags={post.tags} />
              <SocialLinks postPath={slug} postNode={postNode} />
            </div>
            <Disqus postNode={postNode} />
          </div>
        </div>
        <ElaborateNavigation previous={previousPost} next={nextPost} />
      </Layout>
    )
  }
}

/* eslint no-undef: "off"*/
export const postQuery = graphql`
  query BlogPostBySlug($slug: String!, $next: String, $prev: String) {
    post: markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      excerpt
      timeToRead
      frontmatter {
        title
        cover
        ogImage
        blur
        tags
      }
      fields {
        slug
        date
      }
    }

    prev: markdownRemark(fields: { slug: { eq: $prev } }) {
      excerpt(pruneLength: 200)
      timeToRead
      frontmatter {
        title
        cover
        tags
      }
      fields {
        slug
        date
      }
    }

    next: markdownRemark(fields: { slug: { eq: $next } }) {
      excerpt(pruneLength: 200)
      timeToRead
      frontmatter {
        title
        cover
        tags
      }
      fields {
        slug
        date
      }
    }
  }
`