diff --git a/site/src/components/devices.js b/site/src/components/devices.js index baade62..19646c7 100644 --- a/site/src/components/devices.js +++ b/site/src/components/devices.js @@ -1,7 +1,7 @@ /* Used to specify the main breakpoints used for the site */ const size = { - small: '401px', + small: '501px', medium: '601px', large: '821px', wide: '1051px' diff --git a/site/src/components/header.js b/site/src/components/header.js index c6884da..880f6c5 100644 --- a/site/src/components/header.js +++ b/site/src/components/header.js @@ -1,39 +1,79 @@ import { Link } from 'gatsby'; +import { GatsbyImage, getImage } from "gatsby-plugin-image"; import PropTypes from 'prop-types'; import React from 'react'; import styled from 'styled-components'; import humanize from 'humanize-plus'; import moment from 'moment'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faCamera, faClock } from '@fortawesome/free-solid-svg-icons'; import { device } from './devices'; -const TextHeader = styled.header` + +const BaseHeader = styled.header` + background: var(--darkened-grey); + background: -moz-radial-gradient(circle, var(--dark-grey) 0%, var(--darkened-grey) 100% ); + background: -webkit-radial-gradient(circle, var(--dark-grey) 0%, var(--darkened-grey) 100% ); + background: radial-gradient(circle, var(--dark-grey) 0%, var(--darkened-grey) 100% ); + box-sizing: border-box; border-bottom: 2px solid var(--highlight); - min-height: 50vh; - margin: 0; - padding: var(--gutter) 0; - /** Put the background gradient in**/ - background-color: var(--darkened-grey); - background: linear-gradient(45deg, var(--dark-base) 30%, var(--highlight) 100%); + margin: 0; -webkit-box-shadow: 0 0.5rem 0.8rem #aaa; -moz-box-shadow: 0 0.5rem 0.8rem #aaa; box-shadow: 0 0.65rem 0.8rem #aaa; + .headerimage, .imagefill { + min-height: 60vh; + + @media only screen and ${device.small} { + min-height: 60vh; + } + + @media only screen and ${device.medium} { + min-height: 65vh; + } + + @media only screen and ${device.large} { + min-height: 40vh; + max-height: 60vh; + } + + @media only screen and ${device.wide} { + max-height: 70vh; + } + } +`; + +const TextHeader = styled(BaseHeader)` + /**padding: var(--gutter) 0;**/ + + /** @media only screen and ${device.medium} { min-height: 60vh; max-height: 90vh; padding: var(--gutter) 0; } - // put the little shadow along the bottom for big screens. @media only screen and ${device.large} { min-height: 70vh; } + **/ + + .imagefill { + /** Put the background gradient in**/ + background-color: var(--darkened-grey); + background: linear-gradient(45deg, var(--dark-base) 30%, var(--highlight) 100%); + } `; -const ImageHeader = styled(TextHeader)` +const ImageHeader = styled(BaseHeader)` + /** this is a noop as sizing handled in base **/ +`; + +const OldImageHeader = styled(BaseHeader)` background-color: var(--darkened-grey); background-repeat: no-repeat; background-position: center; @@ -61,37 +101,40 @@ const ImageHeader = styled(TextHeader)` const Container = styled.div` margin:0; width: 100vw; + margin-top: -10rem; padding-top: 0rem; + padding-bottom: var(--gutter); + position: relative; + z-index: 2; + @media only screen and ${device.small} { + margin-top: -12rem; + padding-bottom: calc(0.5 * var(--gutter)); + } @media only screen and ${device.medium} { - /** width: 90vw; - margin: 0 5vw;**/ } @media only screen and ${device.large} { - max-width: 687px; } @media only screen and ${device.wide} { max-width: 1020px; margin: 0 auto; + margin-top: -15rem; } ` const StyledTitle = styled.h1` background-color: var(--light-base); padding: var(--gutter); - margin: 0rem var(--gutter); color: var(--dark-base); - min-height: 25vh; - max-height: 35vh; width: min-content; - min-width: 60vw; - max-width: calc(100% - 2 * var(--gutter)); - border-radius: 0.2rem; + min-width: 90vw; + min-height: 14rem; box-sizing: border-box; font-size: 4rem; line-height: 4rem; + margin: 0; &.enlarge { font-size: 5rem; @@ -131,6 +174,10 @@ const StyledTitle = styled.h1` color: var(--dark-grey); } + @media only screen and ${device.small} { + min-width: 80vw; + } + @media only screen and ${device.medium} { padding: var(--gutter); max-width: 70vw; @@ -143,15 +190,12 @@ const StyledTitle = styled.h1` line-height: 6rem; width: 61vw; max-height: 40vh; + min-width: 70vw; } @media only screen and ${device.wide} { - min-width: unset; - max-width: calc(66% - var(--gutter)); - min-height: 35vh; - max-height: 45vh; - margin: 0; - /**width: 45%;**/ + min-width: 67%; + width: 67%; } `; @@ -160,7 +204,10 @@ const Para = styled.p` padding: 0 var(--gutter); font-size: 1.8rem; margin: var(--gutter) 0; + margin-block-end: 0; box-sizing: border-box; + width: min-content; + min-width: 70vw; @media only screen and ${device.medium} { font-size: 2rem; @@ -174,7 +221,7 @@ const Para = styled.p` } @media only screen and ${device.wide} { - max-width: 61%; + min-width: 67%; } `; @@ -193,11 +240,13 @@ const Lede = styled(Para)` const PostData = styled(Para)` font-size: 1.8rem; - margin-bottom: 0; - - & span { - color: var(--light-base); - } + color: var(--lightened-grey); + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: flex-start; + gap: calc(0.5 * var(--gutter)); + min-width: 90vw; @media only screen and ${device.medium} { font-size: 2rem; @@ -231,13 +280,75 @@ Title.defaultProps = { const Featured = styled.p` color: var(--highlight); - margin: 0 var(--gutter); + margin: calc(0.5 * var(--gutter)) var(--gutter); text-transform: uppercase; font-size: 1.8rem; + text-decoration: underline; `; +const Header = ({ + title, date, excerpt, url, + featured=false, + featuredimage, featuredImageBy, + smalltitle, largetitle, + readingTime=0, wordCount={} }) => { + + let formatted_date; + if (typeof(date) !== 'undefined') { + formatted_date = moment(date).format('ddd, MMM Do YYYY'); + } + + const rounded_time = Math.ceil(readingTime) || 0; + const humanised_words = humanize.compactInteger(wordCount.words, 1) || 0; + + const PostHeader = (featuredimage === null) ? TextHeader : ImageHeader; + const postimage = getImage(featuredimage); + + return ( + + { featuredimage !== null && + + } + { featuredimage === null && +
+ } + + {title} + { featured && + Featured Post + } + { excerpt != null && excerpt.length > 0 && + {excerpt} + } + { typeof(date) !== 'undefined' && + Published: {formatted_date} + } + { rounded_time > 0 && + + + + + + {rounded_time} min + ({humanised_words} words) + + + } + { typeof(featuredimage) !== 'undefined' && + featuredImageBy && + + + + + {featuredImageBy} + + } + + + ); +}; -const Header = ({ title, date, excerpt, url, featured=false, featuredimage, +const OldHeader = ({ title, date, excerpt, url, featured=false, featuredimage, smalltitle, largetitle, readingTime={} }) => { let formatted_date; @@ -248,7 +359,7 @@ const Header = ({ title, date, excerpt, url, featured=false, featuredimage, const rounded_time = Math.ceil(readingTime.minutes) || 0; const humanised_words = humanize.compactInteger(readingTime.words, 1) || 0; - const PostHeader = (typeof(featuredimage) === 'undefined') ? TextHeader : ImageHeader; + const PostHeader = (typeof(featuredimage) === 'undefined') ? TextHeader : OldImageHeader; return ( @@ -287,3 +398,5 @@ Header.defaultProps = { }; export default Header; + +export { OldHeader, Header }; diff --git a/site/src/components/layout.js b/site/src/components/layout.js index 1463385..ad4e64e 100644 --- a/site/src/components/layout.js +++ b/site/src/components/layout.js @@ -45,15 +45,10 @@ export const Article = styled.article` & section { margin-top: var(--gutter); - & h2 { - box-shadow: var(--gutter) 0 0 var(--light-base), calc(var(--gutter) * -1) 0 0 var(--light-base); - } - & h2, & h3 { margin: 0; margin-left: var(--gutter); padding: 0px 0px 0.5rem; - box-decoration-break: clone; } & h4, & h5 { diff --git a/site/src/components/list-layout.js b/site/src/components/list-layout.js index 3993bf4..f8191d7 100644 --- a/site/src/components/list-layout.js +++ b/site/src/components/list-layout.js @@ -4,24 +4,29 @@ import Nav from './nav'; import Footer from './footer'; import { ListArticle } from './article'; import { Aside, Main } from './layout'; -import { pathDate, getFeaturedImageSources } from '../lib/utils'; +import { pathDate } from '../lib/utils'; const Layout = ({ children, featured={}, slug}) => { // determine the featured article and pull it from the list. - const {frontmatter={}, fields={}} = featured; + const { + frontmatter={}, fields={}, + timeToRead, wordCount + } = featured; const excerpt = frontmatter.excerpt || fields.excerpt || featured?.excerpt || ''; const url = `/${pathDate(frontmatter.date)}/${frontmatter.slug}/`; const {title, date} = frontmatter; - const featuredImageSrc = getFeaturedImageSources(frontmatter?.featureimage?.childImageSharp); + const featuredImage = frontmatter?.featureimage || null; + const {imageby} = frontmatter; return ( <>
+ readingTime={timeToRead} wordCount={wordCount} />
{children}
diff --git a/site/src/components/nav.js b/site/src/components/nav.js index b360c6a..775da81 100644 --- a/site/src/components/nav.js +++ b/site/src/components/nav.js @@ -14,7 +14,7 @@ import { device } from './devices'; const NavButton = styled.button` display: inline-block; - z-index: 3; // place above content + z-index: 103; // place above content transform: ${({ isOpen }) => isOpen ? 'rotate(90deg)' : 'none'}; position: fixed; @@ -48,7 +48,7 @@ const NavMenuOverlay = styled.div` width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); - z-index: 1; + z-index: 101; @media only screen and ${device.large} { display: none; @@ -60,7 +60,7 @@ const NavDrawer = styled.nav` flex-direction: column; position: fixed; - z-index: 2; + z-index: 102; top: 0; right: ${({ isOpen }) => isOpen ? '0' : '-100%'}; diff --git a/site/src/components/page-head.js b/site/src/components/page-head.js index 9cade71..b86e0b7 100644 --- a/site/src/components/page-head.js +++ b/site/src/components/page-head.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types' -// import Helmet from 'react-helmet' import { useStaticQuery, graphql } from 'gatsby'; +import { getSrc } from "gatsby-plugin-image" import humanize from 'humanize-plus'; @@ -29,8 +29,8 @@ function PageHead({ description, meta, title, type, tweet, image, readingTime, w const card_meta = []; - if (typeof(image.share) !== 'undefined') { - const image_url = `${site.siteMetadata.siteUrl}${image.share}`; + if (image !== '') { + const image_url = `${site.siteMetadata.siteUrl}${getSrc(image)}`; card_meta.push({property: `og:image`, content: image_url }); card_meta.push({ name: `twitter:image`, content: image_url}); diff --git a/site/src/components/post-layout.js b/site/src/components/post-layout.js index 560c616..65e3c53 100644 --- a/site/src/components/post-layout.js +++ b/site/src/components/post-layout.js @@ -10,7 +10,16 @@ import Nav from './nav'; import Footer from './footer'; import { Main, Aside } from './layout'; -const Layout = ({ children, frontmatter, featuredimage, path, readingTime, tags, relatedposts}) => { +const Layout = ({ + children, + frontmatter, + featuredimage, + path, + readingTime, + wordCount, + tags, + relatedposts, +}) => { const { title, date, excerpt, slug, small_title=false, large_title=false, imageby, imagelink } = frontmatter; @@ -20,7 +29,8 @@ const Layout = ({ children, frontmatter, featuredimage, path, readingTime, tags, return ( <>
diff --git a/site/src/pages/index.js b/site/src/pages/index.js index a128062..9b17ba0 100644 --- a/site/src/pages/index.js +++ b/site/src/pages/index.js @@ -131,24 +131,13 @@ export const pageQuery = graphql` featured featureimage { childImageSharp { - base: gatsbyImageData(width: 400, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - small: gatsbyImageData(width: 400, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - medium: gatsbyImageData(width: 750, quality: 90 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - large: gatsbyImageData(width: 1050, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - wide: gatsbyImageData(width: 1600, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} + gatsbyImageData( + layout: FULL_WIDTH ) - share: gatsbyImageData(width: 1200, quality: 90) } } + imageby + imagelink featureimage_position small_title large_title diff --git a/site/src/styles/global.css b/site/src/styles/global.css index 65ae823..15f683f 100644 --- a/site/src/styles/global.css +++ b/site/src/styles/global.css @@ -79,7 +79,7 @@ h2 { h3 { font-family: var(--heading-font-family); font-weight: var(--heading-font-weight); - font-size: 3.4rem; + font-size: 3.0rem; } h4 { @@ -107,15 +107,11 @@ article h1 { } article h2 { - background-color: var(--light-base); + color: var(--dark-base); } -article h2, article h3{ color: var(--dark-base); - display: inline; - box-decoration-break: clone; - -webkit-box-decoration-break: clone; } article h4, diff --git a/site/src/styles/theme.css b/site/src/styles/theme.css index 4f863c1..3551b02 100644 --- a/site/src/styles/theme.css +++ b/site/src/styles/theme.css @@ -115,7 +115,7 @@ } /** change gutter values depending on screen size **/ -@media only screen and (min-width: 501px) { /** Medium up **/ +@media only screen and (min-width: 601px) { /** Medium up **/ :root { --gutter: var(--gutter-medium); } diff --git a/site/src/templates/article.js b/site/src/templates/article.js index 3f0c00b..0a59600 100644 --- a/site/src/templates/article.js +++ b/site/src/templates/article.js @@ -3,7 +3,6 @@ import { graphql } from 'gatsby'; import Layout from '../components/post-layout'; import PageHead from '../components/page-head'; -import { getFeaturedImageSources } from '../lib/utils'; export const Head = ({location, params, data, pageContext}) => { const { markdownRemark} = data; @@ -25,18 +24,18 @@ export const Head = ({location, params, data, pageContext}) => { export default function Template({ data, location }) { const { markdownRemark } = data; - const { fields, frontmatter, html, timeToRead } = markdownRemark; + const { fields, frontmatter, html, timeToRead, wordCount } = markdownRemark; let taglist = null; if (fields) { taglist = fields.taglist || []; } - const featuredImageSrc = getFeaturedImageSources(frontmatter?.featureimage?.childImageSharp); + const featuredImage = frontmatter?.featureimage || null; return ( -
{ const { markdownRemark} = data; @@ -11,7 +10,7 @@ export const Head = ({data}) => { const excerpt = frontmatter.excerpt || markdownRemark.excerpt || ''; const twitter_excerpt = frontmatter.twitter_excerpt || excerpt; - const featuredImageSrc = getFeaturedImageSources(frontmatter?.featureimage?.childImageSharp); + const featuredImage = frontmatter?.featureimage || ''; return ( <> @@ -20,7 +19,7 @@ export const Head = ({data}) => { description={excerpt} type="article" tweet={twitter_excerpt} - image={featuredImageSrc} + image={featuredImage} readingTime={timeToRead} words={wordCount.words} /> @@ -30,14 +29,15 @@ export const Head = ({data}) => { export default function Template({ data, location }) { const { markdownRemark} = data; - const { fields, frontmatter, html, related} = markdownRemark; + const { fields, frontmatter, html, related, timeToRead, wordCount} = markdownRemark; const { taglist } = fields; - const featuredImageSrc = getFeaturedImageSources(frontmatter?.featureimage?.childImageSharp); + const featuredImage = frontmatter?.featureimage || null; return ( -
0) { - featuredPost = featured.edges[0]; + featuredPost = featured.edges[0].node; // filter the main posts so that the featured post is pulled out as it // is going to be displayed separately. Do this just by taking the slug // from the featured posts and then filtering the main post list against it @@ -52,7 +52,7 @@ export default function Template({ pageContext, data}) { const pluralPosts = (filteredPosts?.length > 1) ? 'posts' : 'post'; return ( - + {filteredPosts.length > 0 ? (

{filteredPosts?.length || ''} other {pluralPosts} tagged "{tag}"

) : ( @@ -110,24 +110,13 @@ export const pageQuery = graphql` excerpt featureimage { childImageSharp { - base: gatsbyImageData(width: 400, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - small: gatsbyImageData(width: 400, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - medium: gatsbyImageData(width: 750, quality: 90 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - large: gatsbyImageData(width: 1050, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} - ) - wide: gatsbyImageData(width: 1600, quality: 100 - transformOptions: {duotone: {highlight:"#FF5E9A", shadow:"#000000", opacity: 80}} + gatsbyImageData( + layout: FULL_WIDTH ) - share: gatsbyImageData(width: 1200, quality: 90) } } + imageby + imagelink featureimage_position small_title large_title @@ -162,24 +151,13 @@ export const pageQuery = graphql` featured featureimage { childImageSharp { - base: gatsbyImageData(width: 400, quality: 100 - transformOptions: {duotone: {highlight:"FF5E9A", shadow:"000000", opacity: 80}} - ) - small: gatsbyImageData(width: 500, quality: 100 - transformOptions: {duotone: {highlight:"FF5E9A", shadow:"000000", opacity: 80}} - ) - medium: gatsbyImageData(width: 750, quality: 90 - transformOptions: {duotone: {highlight:"FF5E9A", shadow:"000000", opacity: 80}} - ) - large: gatsbyImageData(width: 1050, quality: 100 - transformOptions: {duotone: {highlight:"FF5E9A", shadow:"000000", opacity: 80}} - ) - wide: gatsbyImageData(width: 1600, quality: 100 - transformOptions: {duotone: {highlight:"FF5E9A", shadow:"000000", opacity: 80}} + gatsbyImageData( + layout: FULL_WIDTH ) - share: gatsbyImageData(width: 1200, quality: 90) } } + imageby + imagelink featureimage_position } excerpt(pruneLength: 220)