1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2025-02-14 21:10:41 +01:00

Merge pull request #75 from kremalicious/fixes

Fixes
This commit is contained in:
Matthias Kretschmann 2018-12-07 14:11:36 +01:00 committed by GitHub
commit f81542ba37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 147 additions and 158 deletions

View File

@ -23,5 +23,10 @@
"semi": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"prettier/prettier": "error"
},
"settings": {
"react": {
"version": "16"
}
}
}

View File

@ -3,7 +3,7 @@ language: node_js
node_js: node
addons:
chrome: stable
chrome: beta
cache:
directories:
@ -13,12 +13,6 @@ cache:
install:
- npm i
before_script:
- export DISPLAY=:99.0
- export CHROME_PATH="$(pwd)/chrome-linux/chrome"
- sh -e /etc/init.d/xvfb start
- sleep 3 # wait for xvfb to boot
script:
- npm test
- npm run build

View File

@ -14,7 +14,7 @@
</p>
- [🎉 Features](#-features)
- [⛵️ Lighthouse score](#-lighthouse-score)
- [⛵️ Lighthouse score](#-lighthouse-score)
- [💍 One data file to rule all pages](#-one-data-file-to-rule-all-pages)
- [💅 Theme switcher](#-theme-switcher)
- [🏆 SEO component](#-seo-component)

View File

@ -3,6 +3,18 @@ const remark = require('remark')
const markdown = require('remark-parse')
const html = require('remark-html')
function truncate(n, useWordBoundary) {
if (this.length <= n) {
return this
}
const subString = this.substr(0, n - 1)
return (
(useWordBoundary
? subString.substr(0, subString.lastIndexOf(' '))
: subString) + '...'
)
}
exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions
@ -29,6 +41,15 @@ exports.onCreateNode = ({ node, actions }) => {
name: 'descriptionHtml',
value: descriptionHtml
})
// Create excerpt from description
const excerpt = truncate.apply(description, [320, true])
createNodeField({
node,
name: 'excerpt',
value: excerpt
})
}
}

View File

@ -22,17 +22,17 @@
},
"dependencies": {
"file-saver": "^2.0.0",
"gatsby": "^2.0.60",
"gatsby": "^2.0.63",
"gatsby-image": "^2.0.22",
"gatsby-plugin-favicon": "^3.1.4",
"gatsby-plugin-matomo": "^0.6.0",
"gatsby-plugin-offline": "^2.0.18",
"gatsby-plugin-react-helmet": "^3.0.4",
"gatsby-plugin-sass": "^2.0.5",
"gatsby-plugin-sass": "^2.0.7",
"gatsby-plugin-sharp": "^2.0.14",
"gatsby-plugin-sitemap": "^2.0.3",
"gatsby-plugin-svgr": "^2.0.1",
"gatsby-source-filesystem": "^2.0.10",
"gatsby-source-filesystem": "^2.0.11",
"gatsby-transformer-json": "^2.1.6",
"gatsby-transformer-sharp": "^2.1.9",
"gatsby-transformer-yaml": "^2.1.6",
@ -44,7 +44,7 @@
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-helmet": "^5.2.0",
"react-pose": "^4.0.2",
"react-pose": "^4.0.4",
"remark": "^10.0.1",
"remark-html": "^9.0.0",
"remark-parse": "^6.0.3",
@ -52,9 +52,9 @@
"vcf": "^2.0.1"
},
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/node": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@babel/core": "^7.2.0",
"@babel/node": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@svgr/webpack": "^4.1.0",
"ava": "^0.25.0",
"babel-eslint": "^10.0.1",
@ -70,7 +70,7 @@
"prepend": "^1.0.2",
"prettier": "^1.15.3",
"prettier-stylelint": "^0.4.2",
"slugify": "^1.3.3",
"slugify": "^1.3.4",
"stylelint": "^9.9.0",
"stylelint-config-css-modules": "^1.3.0",
"stylelint-config-standard": "^18.2.0",

View File

@ -12,26 +12,22 @@ set -e;
function s3sync {
aws s3 sync ./public s3://"$1" \
--exclude "*" \
--include "*.js" \
--include "*.css" \
--include "static/*" \
--include "icons/*" \
--exclude "sw.js" \
--exclude "workbox*/*" \
--cache-control public,max-age=31536000,immutable \
--delete \
--acl public-read \
--quiet
--acl public-read
aws s3 sync ./public s3://"$1" \
--exclude "*" \
--include "*.html" \
--include "sw.js" \
--include "chunk-map.json" \
--include "sitemap.xml" \
--include ".iconstats.json" \
--include "humans.txt" \
--include "robots.txt" \
--cache-control public,max-age=0,must-revalidate \
--delete \
--acl public-read \
--quiet
--acl public-read
}
##

View File

@ -8,14 +8,17 @@ const launchChromeAndRunLighthouse = (
opts = { chromeFlags: ['--headless'] },
config = null
) =>
chromeLauncher.launch({ chromeFlags: opts.chromeFlags }).then(chrome => {
chromeLauncher
.launch({ chromeFlags: opts.chromeFlags })
.then(async chrome => {
opts.port = chrome.port
return lighthouse(url, opts, config).then(results =>
chrome.kill().then(() => results.lhr)
)
const results = await lighthouse(url, opts, config)
await chrome.kill()
return results.lhr
})
let scores
test.before(async () => {
console.log(`Auditing ${siteMetadata.siteUrl}.\n`) // eslint-disable-line no-console
scores = await launchChromeAndRunLighthouse(siteMetadata.siteUrl).then(

View File

@ -1,20 +1,8 @@
import React from 'react'
import React, { PureComponent } from 'react'
import Helmet from 'react-helmet'
import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby'
function truncate(n, useWordBoundary) {
if (this.length <= n) {
return this
}
const subString = this.substr(0, n - 1)
return (
(useWordBoundary
? subString.substr(0, subString.lastIndexOf(' '))
: subString) + '...'
)
}
const query = graphql`
query {
dataYaml {
@ -22,7 +10,6 @@ const query = graphql`
tagline
description
url
email
img {
childImageSharp {
resize(width: 980) {
@ -31,11 +18,7 @@ const query = graphql`
}
}
social {
Email
Blog
Twitter
GitHub
Dribbble
}
gpg
addressbook
@ -43,31 +26,15 @@ const query = graphql`
}
`
const SEO = ({ project }) => (
<StaticQuery
query={query}
render={data => {
const meta = data.dataYaml
const title = project.title || meta.title
const tagline = meta.tagline
const description = project.description
? truncate.apply(project.description, [320, true])
: truncate.apply(meta.description, [320, true])
const image = project.img
? project.img.childImageSharp.twitterImage.src
: meta.img.childImageSharp.resize.src
const url = project.slug ? `${meta.url}${project.slug}` : meta.url
const MetaTags = ({ title, description, url, image, meta }) => {
return (
<Helmet
defaultTitle={`${title.toLowerCase()} { ${tagline.toLowerCase()} }`}
titleTemplate={`%s // ${title.toLowerCase()} { ${tagline.toLowerCase()} }`}
defaultTitle={`${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
titleTemplate={`%s // ${meta.title.toLowerCase()} { ${meta.tagline.toLowerCase()} }`}
title={title}
>
<html lang="en" />
<title>{title}</title>
{/* General tags */}
<meta name="description" content={description} />
<meta name="image" content={`${meta.url}${image}`} />
@ -87,16 +54,47 @@ const SEO = ({ project }) => (
<meta name="twitter:image" content={`${meta.url}${image}`} />
</Helmet>
)
}
MetaTags.propTypes = {
title: PropTypes.string,
description: PropTypes.string,
url: PropTypes.string,
image: PropTypes.string,
meta: PropTypes.object
}
export default class SEO extends PureComponent {
static propTypes = {
project: PropTypes.object
}
render() {
return (
<StaticQuery
query={query}
render={data => {
const { project } = this.props
const meta = data.dataYaml
const title = (project && project.title) || meta.title
const description =
(project && project.fields.excerpt) || meta.description
const image =
(project && project.img.childImageSharp.twitterImage.src) ||
meta.img.childImageSharp.resize.src
const url = (project && `${meta.url}${project.slug}`) || meta.url
return (
<MetaTags
title={title}
description={description}
url={url}
image={image}
meta={meta}
/>
)
}}
/>
)
SEO.propTypes = {
project: PropTypes.object
)
}
}
SEO.defaultProps = {
project: {}
}
export default SEO

View File

@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby'
import posed from 'react-pose'
import { moveInBottom } from '../atoms/Transitions'
import { ReactComponent as Logo } from '../../images/logo.svg'
import styles from './LogoUnit.module.scss'
@ -19,37 +18,21 @@ const query = graphql`
const Animation = posed.div(moveInBottom)
export default class LogoUnit extends PureComponent {
state = { isMinimal: false }
static propTypes = {
minimal: PropTypes.bool
}
checkMinimal = () => {
const { minimal } = this.props
this.setState({ isMinimal: minimal })
}
componentDidMount() {
this.checkMinimal()
}
componentDidUpdate() {
this.checkMinimal()
}
render() {
return (
<StaticQuery
query={query}
render={data => {
const { title, tagline } = data.dataYaml
const { isMinimal } = this.state
const { minimal } = this.props
return (
<Animation>
<div className={isMinimal ? styles.minimal : styles.logounit}>
<div className={minimal ? styles.minimal : styles.logounit}>
<Logo className={styles.logounit__logo} />
<h1 className={styles.logounit__title}>
{title.toLowerCase()}

View File

@ -22,24 +22,8 @@ export default class Header extends PureComponent {
minimal: PropTypes.bool
}
state = { isMinimal: this.props.minimal }
checkMinimal = () => {
const { minimal } = this.props
this.setState({ isMinimal: minimal })
}
componentDidMount() {
this.checkMinimal()
}
componentDidUpdate() {
this.checkMinimal()
}
render() {
const { isMinimal } = this.state
const { minimal } = this.props
return (
<StaticQuery
@ -48,16 +32,16 @@ export default class Header extends PureComponent {
const meta = data.dataYaml
return (
<header className={isMinimal ? styles.minimal : styles.header}>
<header className={minimal ? styles.minimal : styles.header}>
<ThemeSwitch />
<Link className={styles.header__link} to={'/'}>
<LogoUnit minimal={isMinimal} />
<LogoUnit minimal={minimal} />
</Link>
<Networks hide={isMinimal} />
<Networks hide={minimal} />
<Availability hide={isMinimal && !meta.availability.status} />
<Availability hide={minimal && !meta.availability.status} />
</header>
)
}}

View File

@ -27,19 +27,23 @@ class ProjectMeta extends PureComponent {
}
}
const ProjectImages = ({ projectImages, title }) => (
class ProjectImages extends PureComponent {
static propTypes = {
projectImages: PropTypes.array,
title: PropTypes.string
}
render() {
return (
<FullWidth>
{projectImages.map(({ node }) => (
{this.props.projectImages.map(({ node }) => (
<div className={styles.imageWrap} key={node.id}>
<ProjectImage fluid={node.fluid} alt={title} />
<ProjectImage fluid={node.fluid} alt={this.props.title} />
</div>
))}
</FullWidth>
)
ProjectImages.propTypes = {
projectImages: PropTypes.array,
title: PropTypes.string
)
}
}
export default class Project extends PureComponent {
@ -49,9 +53,10 @@ export default class Project extends PureComponent {
}
render() {
const project = this.props.data.projectsYaml
const projectImages = this.props.data.projectImages.edges
const descriptionHtml = this.props.data.projectsYaml.fields.descriptionHtml
const { data } = this.props
const project = data.projectsYaml
const projectImages = data.projectImages.edges
const descriptionHtml = data.projectsYaml.fields.descriptionHtml
const { title, links, techstack } = project
return (
@ -76,14 +81,14 @@ export default class Project extends PureComponent {
}
}
export const projectAndProjectsQuery = graphql`
export const projectQuery = graphql`
query($slug: String!) {
projectsYaml(slug: { eq: $slug }) {
title
slug
description
fields {
descriptionHtml
excerpt
}
links {
title