diff --git a/.eslintrc.js b/.eslintrc.js index 0e747b9..cd70472 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,24 +2,24 @@ module.exports = { globals: { __PATH_PREFIX__: true, }, - 'parser': 'babel-eslint', // uses babel-eslint transforms - 'settings': { - 'react': { - 'version': 'detect', // detect react version + parser: "babel-eslint", // uses babel-eslint transforms + settings: { + react: { + version: "detect", // detect react version }, }, - 'env': { - 'node': true, // defines things like process.env when generating through node - 'browser': true + env: { + node: true, // defines things like process.env when generating through node + browser: true, }, - 'extends': [ - 'eslint:recommended', // use recommended configs - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', + extends: [ + "eslint:recommended", // use recommended configs + "plugin:react/recommended", + "plugin:react-hooks/recommended", ], - 'rules': { - 'react/prop-types': 0, - 'no-unused-vars': 1, - 'react/jsx-sort-props': 1, + rules: { + "react/prop-types": 0, + "no-unused-vars": 1, + "react/jsx-sort-props": 1, }, }; diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f27c930..5ddaf2e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,9 +6,9 @@ name: deploy # events but only for the master branch on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -18,24 +18,24 @@ jobs: runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - name: Set Node.js - uses: actions/setup-node@master - with: - node-version: 16.x - - name: Install dependencies - run: yarn install --prod --pure-lockfile - - name: Lint - run: yarn run lint - - name: Build - run: yarn run build - - name: upload - uses: burnett01/rsync-deployments@4.1 - with: - switches: -zr --delete --exclude node_modules --exclude '.git*' - path: ./public/ - remote_path: www/personal-website - remote_host: droplet.chuckdries.com - remote_user: ${{ secrets.CI_USER }} - remote_key: ${{ secrets.CI_SSH_KEY }} + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + - name: Set Node.js + uses: actions/setup-node@master + with: + node-version: 16.x + - name: Install dependencies + run: yarn install --prod --pure-lockfile + - name: Lint + run: yarn run lint + - name: Build + run: yarn run build + - name: upload + uses: burnett01/rsync-deployments@4.1 + with: + switches: -zr --delete --exclude node_modules --exclude '.git*' + path: ./public/ + remote_path: www/personal-website + remote_host: droplet.chuckdries.com + remote_user: ${{ secrets.CI_USER }} + remote_key: ${{ secrets.CI_SSH_KEY }} diff --git a/.vscode/launch.json b/.vscode/launch.json index 3020d97..837b529 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,71 +1,68 @@ -{ - "version": "0.2.0", - "configurations": [{ - "name": "Launch Chrome", - "type": "chrome", - "request": "launch", - "url": "http://localhost:3000", - "sourceMaps": true, - "webRoot": "${workspaceRoot}" - }, - { - "name": "Launch Unix", - "type": "node", - "request": "launch", - "program": "/usr/local/bin/lite-server", - "stopOnEntry": false, - "args": [], - "cwd": "${workspaceRoot}", - "preLaunchTask": null, - "runtimeExecutable": null, - "runtimeArgs": [ - "--nolazy" - ], - "env": { - "NODE_ENV": "development" - }, - "externalConsole": false, - "sourceMaps": false, - "outDir": null - }, - { - "name": "Launch on Windows", - "type": "node", - "request": "launch", - "program": "C:\\Users\\chuckdries\\AppData\\Roaming\\npm\\node_modules\\lite-server\\index.js", - "stopOnEntry": false, - "args": [], - "cwd": "${workspaceRoot}", - "preLaunchTask": null, - "runtimeExecutable": null, - "runtimeArgs": [ - "--nolazy" - ], - "env": { - "NODE_ENV": "development" - }, - "console": "internalConsole", - "sourceMaps": true, - "outDir": null - }, - - { - "name": "Attach Chrome", - "type": "chrome", - "request": "attach", - "port": 9222 - }, - { - "name": "Attach", - "type": "node", - "request": "attach", - "port": 3000, - "address": "localhost", - "restart": false, - "sourceMaps": false, - "outDir": null, - "localRoot": "${workspaceRoot}", - "remoteRoot": null - } - ] -} \ No newline at end of file +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Chrome", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000", + "sourceMaps": true, + "webRoot": "${workspaceRoot}" + }, + { + "name": "Launch Unix", + "type": "node", + "request": "launch", + "program": "/usr/local/bin/lite-server", + "stopOnEntry": false, + "args": [], + "cwd": "${workspaceRoot}", + "preLaunchTask": null, + "runtimeExecutable": null, + "runtimeArgs": ["--nolazy"], + "env": { + "NODE_ENV": "development" + }, + "externalConsole": false, + "sourceMaps": false, + "outDir": null + }, + { + "name": "Launch on Windows", + "type": "node", + "request": "launch", + "program": "C:\\Users\\chuckdries\\AppData\\Roaming\\npm\\node_modules\\lite-server\\index.js", + "stopOnEntry": false, + "args": [], + "cwd": "${workspaceRoot}", + "preLaunchTask": null, + "runtimeExecutable": null, + "runtimeArgs": ["--nolazy"], + "env": { + "NODE_ENV": "development" + }, + "console": "internalConsole", + "sourceMaps": true, + "outDir": null + }, + + { + "name": "Attach Chrome", + "type": "chrome", + "request": "attach", + "port": 9222 + }, + { + "name": "Attach", + "type": "node", + "request": "attach", + "port": 3000, + "address": "localhost", + "restart": false, + "sourceMaps": false, + "outDir": null, + "localRoot": "${workspaceRoot}", + "remoteRoot": null + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index fe71598..1cf3971 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "python.linting.pylintEnabled": false -} \ No newline at end of file + "python.linting.pylintEnabled": false +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5cfa26c..7e7f519 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,16 +1,16 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "command": "gulp", - "tasks": [ - { - "label": "default", - "type": "gulp", - "task": "default", - "isBackground": true, - "problemMatcher": [], - "group": "build" - } - ] -} \ No newline at end of file +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "command": "gulp", + "tasks": [ + { + "label": "default", + "type": "gulp", + "task": "default", + "isBackground": true, + "problemMatcher": [], + "group": "build" + } + ] +} diff --git a/TODO.md b/TODO.md index 0938d47..82277b0 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,12 @@ - Gallery + - [x] Custom image metadata - [ ] add metadata to image files - [ ] image details page (modal route?) - [ ] gallery page - Homepage + - [ ] homepage basic layout - [ ] homepage aesthetics - [ ] homepage to gallery page transition @@ -14,6 +16,7 @@ - [ ] About page? - Portfolio/Projects page + - basic layout - source data - aesthetics @@ -21,4 +24,4 @@ - [x] tailwind (done-ish) - [ ] typescript - [ ] graphql codegen -- [ ] static files (resume) \ No newline at end of file +- [ ] static files (resume) diff --git a/gatsby-browser.js b/gatsby-browser.js index 4fee747..1496df7 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -1,17 +1,17 @@ -import './src/styles/global.css'; -import posthog from 'posthog-js'; +import "./src/styles/global.css"; +import posthog from "posthog-js"; -const env = process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || 'development'; -if (env === 'production') { - posthog.init('HR8Gte105aCHNx2BqhL1XkbvH9kzKGptxjkbhuTj6Ek', { api_host: 'https://posthog.chuckdries.com' }); +const env = + process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development"; +if (env === "production") { + posthog.init("HR8Gte105aCHNx2BqhL1XkbvH9kzKGptxjkbhuTj6Ek", { + api_host: "https://posthog.chuckdries.com", + }); } export const onRouteUpdate = function () { - if ( - env === 'production' && - typeof window.plausible === 'object' - ) { - window.plausible('pageview'); - posthog.capture('$pageview'); + if (env === "production" && typeof window.plausible === "object") { + window.plausible("pageview"); + posthog.capture("$pageview"); } }; // import * as React from 'react'; diff --git a/gatsby-config.js b/gatsby-config.js index 70fd045..9f16039 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -1,56 +1,56 @@ module.exports = { siteMetadata: { - title: 'Chuck Dries', - siteUrl: 'https://chuckdries.com', + title: "Chuck Dries", + siteUrl: "https://chuckdries.com", }, plugins: [ - 'gatsby-plugin-sass', - 'gatsby-plugin-image', - 'gatsby-plugin-react-helmet', + "gatsby-plugin-sass", + "gatsby-plugin-image", + "gatsby-plugin-react-helmet", { - resolve: 'gatsby-plugin-manifest', + resolve: "gatsby-plugin-manifest", options: { - icon: 'src/images/glasses-outline.svg', + icon: "src/images/glasses-outline.svg", }, }, - 'gatsby-plugin-mdx', - 'gatsby-plugin-sharp', - 'gatsby-transformer-sharp', - 'gatsby-plugin-postcss', + "gatsby-plugin-mdx", + "gatsby-plugin-sharp", + "gatsby-transformer-sharp", + "gatsby-plugin-postcss", { - resolve: 'gatsby-source-filesystem', + resolve: "gatsby-source-filesystem", options: { - name: 'images', - path: './src/images/', + name: "images", + path: "./src/images/", }, - __key: 'images', + __key: "images", }, { - resolve: 'gatsby-source-filesystem', + resolve: "gatsby-source-filesystem", options: { - name: 'gallery', - path: './data/gallery/', + name: "gallery", + path: "./data/gallery/", }, - __key: 'gallery', + __key: "gallery", }, { - resolve: 'gatsby-source-filesystem', + resolve: "gatsby-source-filesystem", options: { - name: 'pages', - path: './src/pages/', + name: "pages", + path: "./src/pages/", }, - __key: 'pages', + __key: "pages", }, { - resolve: 'gatsby-plugin-eslint', + resolve: "gatsby-plugin-eslint", options: { - stages: ['develop'], - extensions: ['js', 'jsx'], - exclude: ['node_modules', '.cache', 'public'], + stages: ["develop"], + extensions: ["js", "jsx"], + exclude: ["node_modules", ".cache", "public"], // Any eslint-webpack-plugin options below }, }, - 'gatsby-plugin-preval', - 'gatsby-plugin-robots-txt', + "gatsby-plugin-preval", + "gatsby-plugin-robots-txt", ], }; diff --git a/gatsby-node.js b/gatsby-node.js index 37926c7..c05253d 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -1,12 +1,12 @@ -const fs = require('fs'); -const util = require('util'); -const path = require('path'); -const { read } = require('fast-exif'); -const iptc = require('node-iptc'); -const Vibrant = require('node-vibrant'); -const chroma = require('chroma-js'); -const chalk = require('chalk'); -const R = require('ramda'); +const fs = require("fs"); +const util = require("util"); +const path = require("path"); +const { read } = require("fast-exif"); +const iptc = require("node-iptc"); +const Vibrant = require("node-vibrant"); +const chroma = require("chroma-js"); +const chalk = require("chalk"); +const R = require("ramda"); const readFile = util.promisify(fs.readFile); @@ -15,9 +15,11 @@ const badContrast = (color1, color2) => chroma.contrast(color1, color2) < 4.5; const logColorsWithContrast = (color1, color2, text) => { const c1hex = color1.hex(); const c2hex = color2.hex(); - console.log(chalk.hex(c1hex).bgHex(c2hex)( - `${text} ${c1hex}/${c2hex} ${chroma.contrast(color1, color2)}` - )); + console.log( + chalk.hex(c1hex).bgHex(c2hex)( + `${text} ${c1hex}/${c2hex} ${chroma.contrast(color1, color2)}` + ) + ); }; function processColors(vibrantData, imagePath) { @@ -29,7 +31,10 @@ function processColors(vibrantData, imagePath) { let LightMuted = chroma(vibrantData.LightMuted.getRgb()); // first pass - darken bg and lighten relevant fg colors - if (badContrast(DarkVibrant, Vibrant) || badContrast(DarkVibrant, LightMuted)) { + if ( + badContrast(DarkVibrant, Vibrant) || + badContrast(DarkVibrant, LightMuted) + ) { DarkVibrant = DarkVibrant.darken(); if (badContrast(DarkVibrant, Vibrant)) { Vibrant = Vibrant.brighten(); @@ -39,7 +44,10 @@ function processColors(vibrantData, imagePath) { } } // second pass - first doesn't always do enough - if (badContrast(DarkVibrant, Vibrant) || badContrast(DarkVibrant, LightMuted)) { + if ( + badContrast(DarkVibrant, Vibrant) || + badContrast(DarkVibrant, LightMuted) + ) { // DarkVibrant = DarkVibrant.darken(); if (badContrast(DarkVibrant, Vibrant)) { Vibrant = Vibrant.brighten(2); @@ -49,16 +57,15 @@ function processColors(vibrantData, imagePath) { } } - if (badContrast(DarkVibrant, Vibrant)){ - console.warn('contrast still too low', imagePath); - logColorsWithContrast(Vibrant, DarkVibrant, 'V-DV'); + if (badContrast(DarkVibrant, Vibrant)) { + console.warn("contrast still too low", imagePath); + logColorsWithContrast(Vibrant, DarkVibrant, "V-DV"); } - if (badContrast(DarkVibrant, LightMuted)){ - console.warn('contrast still too low', imagePath); - logColorsWithContrast(LightMuted, DarkVibrant, 'LM-DV'); + if (badContrast(DarkVibrant, LightMuted)) { + console.warn("contrast still too low", imagePath); + logColorsWithContrast(LightMuted, DarkVibrant, "LM-DV"); } - return { Vibrant: Vibrant.rgb(), DarkVibrant: DarkVibrant.rgb(), @@ -82,25 +89,20 @@ function transformMetaToNodeData(exifData, iptcData, vibrantData, imagePath) { const gps = { longitude: null, latitude: null }; if (exifData) { - if ( - exifData.gps && - exifData.gps.GPSLongitude && - exifData.gps.GPSLatitude - ) { + if (exifData.gps && exifData.gps.GPSLongitude && exifData.gps.GPSLatitude) { gps.longitude = convertDMSToDD( exifData.gps.GPSLongitude, - exifData.gps.GPSLongitudeRef === 'E' + exifData.gps.GPSLongitudeRef === "E" ); gps.latitude = convertDMSToDD( exifData.gps.GPSLatitude, - exifData.gps.GPSLatitudeRef === 'N' + exifData.gps.GPSLatitudeRef === "N" ); } } const vibrant = vibrantData ? processColors(vibrantData, imagePath) : null; - return { exif: exifData?.exif, gps, @@ -110,10 +112,9 @@ function transformMetaToNodeData(exifData, iptcData, vibrantData, imagePath) { }; } - exports.onCreateNode = async function ({ node, actions }) { const { createNodeField } = actions; - if (node.internal.type === 'File' && node.sourceInstanceName === 'gallery') { + if (node.internal.type === "File" && node.sourceInstanceName === "gallery") { const file = await readFile(node.absolutePath); const iptcData = iptc(file); const exifData = await read(node.absolutePath); @@ -123,8 +124,13 @@ exports.onCreateNode = async function ({ node, actions }) { createNodeField({ node, - name: 'imageMeta', - value: transformMetaToNodeData(exifData, iptcData, vibrantData, node.absolutePath), + name: "imageMeta", + value: transformMetaToNodeData( + exifData, + iptcData, + vibrantData, + node.absolutePath + ), }); } }; @@ -135,45 +141,46 @@ exports.createPages = async ({ graphql, actions, reporter }) => { const { createPage } = actions; // get all images const galleryImages = await graphql(` - { - allFile(filter: { - sourceInstanceName: { eq: "gallery" }} - ) { - edges { - node { - relativePath, - base, - fields { - imageMeta { - dateTaken - } + { + allFile(filter: { sourceInstanceName: { eq: "gallery" } }) { + edges { + node { + relativePath + base + fields { + imageMeta { + dateTaken } } } } } - `); + } + `); // Handle errors if (galleryImages.errors) { - reporter.panicOnBuild('Error while running GraphQL query.'); + reporter.panicOnBuild("Error while running GraphQL query."); return; } // Create pages for each markdown file. - const galleryImageTemplate = path.resolve('src/components/GalleryImage/GalleryImage.js'); - // const diffDate = (a, b) => + const galleryImageTemplate = path.resolve( + "src/components/GalleryImage/GalleryImage.js" + ); + // const diffDate = (a, b) => // new Date(R.path(['node', 'childImageSharp', 'fields', 'imageMeta', 'dateTaken'], a)).getTime() - new Date(R.path(['node', 'childImageSharp', 'fields', 'imageMeta', 'dateTaken'],b)).getTime(); - - const edges = R.sort(R.descend((edge) => - new Date(R.path(['node', 'fields', 'imageMeta', 'dateTaken'], edge))), - galleryImages.data.allFile.edges); + + const edges = R.sort( + R.descend( + (edge) => + new Date(R.path(["node", "fields", "imageMeta", "dateTaken"], edge)) + ), + galleryImages.data.allFile.edges + ); edges.forEach(({ node }, index) => { - const nextImage = index === edges.length - 1 - ? null - : edges[index + 1].node.base; - const prevImage = index === 0 - ? null - : edges[index - 1].node.base; + const nextImage = + index === edges.length - 1 ? null : edges[index + 1].node.base; + const prevImage = index === 0 ? null : edges[index - 1].node.base; const page = { path: `photogallery/${node.base}`, component: galleryImageTemplate, diff --git a/gatsby-ssr.js b/gatsby-ssr.js index 387e300..aa2bdc3 100644 --- a/gatsby-ssr.js +++ b/gatsby-ssr.js @@ -1 +1 @@ -import './src/styles/global.css'; \ No newline at end of file +import "./src/styles/global.css"; diff --git a/postcss.config.js b/postcss.config.js index 996d458..8665375 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,7 +1,7 @@ module.exports = { plugins: { tailwindcss: {}, - 'postcss-nested': {}, + "postcss-nested": {}, autoprefixer: {}, }, }; diff --git a/src/breakpoints.js b/src/breakpoints.js index 4ff08b7..97aca46 100644 --- a/src/breakpoints.js +++ b/src/breakpoints.js @@ -1,4 +1,4 @@ -import preval from 'babel-plugin-preval/macro'; +import preval from "babel-plugin-preval/macro"; const themeBreakpoints = preval` const R = require('ramda') const resolveConfig = require('tailwindcss/resolveConfig'); @@ -7,4 +7,4 @@ const {theme} = resolveConfig(tailwindConfig); module.exports = R.map(size => parseInt(size, 10), theme.screens); `; -export default themeBreakpoints; \ No newline at end of file +export default themeBreakpoints; diff --git a/src/components/GalleryImage/GalleryImage.js b/src/components/GalleryImage/GalleryImage.js index 7594e5d..785fa69 100644 --- a/src/components/GalleryImage/GalleryImage.js +++ b/src/components/GalleryImage/GalleryImage.js @@ -1,5 +1,5 @@ -import React from 'react'; -import { graphql, navigate, Link } from 'gatsby'; +import React from "react"; +import { graphql, navigate, Link } from "gatsby"; import { getAspectRatio, getMeta, @@ -8,19 +8,21 @@ import { getVibrant, getVibrantToHelmetSafeBodyStyle, hasName, -} from '../../utils'; -import { GatsbyImage, getImage } from 'gatsby-plugin-image'; -import { Helmet } from 'react-helmet'; -import classnames from 'classnames'; -import posthog from 'posthog-js'; -import MetadataItem from './MetadataItem'; +} from "../../utils"; +import { GatsbyImage, getImage } from "gatsby-plugin-image"; +import { Helmet } from "react-helmet"; +import classnames from "classnames"; +import posthog from "posthog-js"; +import MetadataItem from "./MetadataItem"; const logKeyShortcut = (keyCode) => { try { // eslint-disable-next-line - posthog.capture('[key shortcut]', { keyCode }); - window.plausible('KeyShortcut', {props: { keyCode }}); - } catch (e) {/* do nothing */} + posthog.capture("[key shortcut]", { keyCode }); + window.plausible("KeyShortcut", { props: { keyCode } }); + } catch (e) { + /* do nothing */ + } }; const GalleryImage = ({ data, pageContext }) => { @@ -29,32 +31,31 @@ const GalleryImage = ({ data, pageContext }) => { React.useEffect(() => { const keyListener = (e) => { - switch (e.code) { - case 'ArrowRight': { - logKeyShortcut(e.code); - if (pageContext.nextImage) { - navigate(`/photogallery/${pageContext.nextImage}/`); + case "ArrowRight": { + logKeyShortcut(e.code); + if (pageContext.nextImage) { + navigate(`/photogallery/${pageContext.nextImage}/`); + } + return; } - return; - } - case 'ArrowLeft': { - logKeyShortcut(e.code); - if (pageContext.prevImage) { - navigate(`/photogallery/${pageContext.prevImage}/`); + case "ArrowLeft": { + logKeyShortcut(e.code); + if (pageContext.prevImage) { + navigate(`/photogallery/${pageContext.prevImage}/`); + } + return; + } + case "Escape": + case "KeyG": { + logKeyShortcut(e.code); + navigate("/photogallery/"); } - return; - } - case 'Escape': - case 'KeyG': { - logKeyShortcut(e.code); - navigate('/photogallery/'); - } } }; - document.addEventListener('keydown', keyListener); + document.addEventListener("keydown", keyListener); return () => { - document.removeEventListener('keydown', keyListener); + document.removeEventListener("keydown", keyListener); }; }, [pageContext]); @@ -62,128 +63,193 @@ const GalleryImage = ({ data, pageContext }) => { const meta = getMeta(image); let locationString; if (meta.iptc.city || meta.iptc.province_or_state) { - const location = [meta.iptc.city, meta.iptc.province_or_state].filter(Boolean); - locationString = location.join(', '); + const location = [meta.iptc.city, meta.iptc.province_or_state].filter( + Boolean + ); + locationString = location.join(", "); } const vibrant = getVibrant(image, true); - const orientationClasses = ar > 1 ? 'flex-col mx-auto' : 'portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col'; - const shutterSpeed = React.useMemo(() => getShutterFractionFromExposureTime(meta.exif.ExposureTime || 0), [meta]); + const orientationClasses = + ar > 1 + ? "flex-col mx-auto" + : "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col"; + const shutterSpeed = React.useMemo( + () => getShutterFractionFromExposureTime(meta.exif.ExposureTime || 0), + [meta] + ); const dateTaken = React.useMemo(() => new Date(meta.dateTaken), [meta]); - return (<> - - {name} - Gallery | Chuck Dries - - -
- -
-
- -
-
-
-

{image.base}

- {hasName(image) &&

{name}

} -

{meta.iptc.caption}

+ return ( + <> + + {name} - Gallery | Chuck Dries + + +
+ +
+
+ +
+
+
+

+ {image.base} +

+ {hasName(image) && ( +

{name}

+ )} +

{meta.iptc.caption}

+
+ { +
+ } + + + + +
- {
} - - - - -
+
-
-
- ); + + ); }; export const query = graphql` query GalleryImage($imageFilename: String) { - allFile(filter: {sourceInstanceName: {eq: "gallery"}, base: {eq: $imageFilename}}) { - edges { - node { - base - childImageSharp{ - fluid { - aspectRatio + allFile( + filter: { + sourceInstanceName: { eq: "gallery" } + base: { eq: $imageFilename } + } + ) { + edges { + node { + base + childImageSharp { + fluid { + aspectRatio + } + gatsbyImageData( + layout: CONSTRAINED + # placeholder: BLURRED + placeholder: DOMINANT_COLOR + # placeholder: TRACED_SVG + height: 2160 + ) } - gatsbyImageData( - layout: CONSTRAINED - # placeholder: BLURRED - placeholder: DOMINANT_COLOR - # placeholder: TRACED_SVG - height: 2160 - ) - } - fields { - imageMeta { - dateTaken - iptc { - caption - object_name - keywords - city - province_or_state - } - exif { - FNumber - ExposureTime - ISO - } - vibrant { - ...VibrantColors + fields { + imageMeta { + dateTaken + iptc { + caption + object_name + keywords + city + province_or_state + } + exif { + FNumber + ExposureTime + ISO + } + vibrant { + ...VibrantColors + } } } } } } } -} - - `; export default GalleryImage; diff --git a/src/components/GalleryImage/MetadataItem.js b/src/components/GalleryImage/MetadataItem.js index cb077e8..88ec1da 100644 --- a/src/components/GalleryImage/MetadataItem.js +++ b/src/components/GalleryImage/MetadataItem.js @@ -1,21 +1,20 @@ -import classNames from 'classnames'; -import React from 'react'; +import classNames from "classnames"; +import React from "react"; -const MetadataItem = ({ - aspectRatio, - icon, - data, - title, -}) => data ? ( -
- - - - {data} -
-) : null; +const MetadataItem = ({ aspectRatio, icon, data, title }) => + data ? ( +
+ + + + {data} +
+ ) : null; -export default MetadataItem; \ No newline at end of file +export default MetadataItem; diff --git a/src/components/Index/HeroLink.js b/src/components/Index/HeroLink.js index e3a5044..c9359db 100644 --- a/src/components/Index/HeroLink.js +++ b/src/components/Index/HeroLink.js @@ -1,5 +1,5 @@ -import * as React from 'react'; -import classnames from 'classnames'; +import * as React from "react"; +import classnames from "classnames"; export const HeroA = ({ href, @@ -9,8 +9,14 @@ export const HeroA = ({ ...linkProps }) => ( {children} -); \ No newline at end of file + > + {children} + +); diff --git a/src/components/MasonryGallery.js b/src/components/MasonryGallery.js index b79c072..69a3446 100644 --- a/src/components/MasonryGallery.js +++ b/src/components/MasonryGallery.js @@ -1,33 +1,41 @@ -import * as React from 'react'; -import { Link } from 'gatsby'; -import { GatsbyImage, getImage } from 'gatsby-plugin-image'; -import * as R from 'ramda'; -import { getAspectRatio, getName } from '../utils'; -import useBreakpoint from 'use-breakpoint'; +import * as React from "react"; +import { Link } from "gatsby"; +import { GatsbyImage, getImage } from "gatsby-plugin-image"; +import * as R from "ramda"; +import { getAspectRatio, getName } from "../utils"; +import useBreakpoint from "use-breakpoint"; -import themeBreakpoints from '../breakpoints'; +import themeBreakpoints from "../breakpoints"; const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => { - const breakpoints = React.useMemo(() => - R.pick(R.keys(itemsPerRowByBreakpoint), themeBreakpoints) - , [itemsPerRowByBreakpoint]); + const breakpoints = React.useMemo( + () => R.pick(R.keys(itemsPerRowByBreakpoint), themeBreakpoints), + [itemsPerRowByBreakpoint] + ); - const { breakpoint } = useBreakpoint(breakpoints, 'sm'); + const { breakpoint } = useBreakpoint(breakpoints, "sm"); - const aspectRatios = React.useMemo(() => R.map(getAspectRatio, images), [images]); - const rowAspectRatioSumsByBreakpoint = React.useMemo(() => R.map(R.pipe( - R.splitEvery(R.__, aspectRatios), - R.map(R.sum) - ))(itemsPerRowByBreakpoint), [aspectRatios, itemsPerRowByBreakpoint]); + const aspectRatios = React.useMemo( + () => R.map(getAspectRatio, images), + [images] + ); + const rowAspectRatioSumsByBreakpoint = React.useMemo( + () => + R.map(R.pipe(R.splitEvery(R.__, aspectRatios), R.map(R.sum)))( + itemsPerRowByBreakpoint + ), + [aspectRatios, itemsPerRowByBreakpoint] + ); const itemsPerRow = itemsPerRowByBreakpoint[breakpoint]; - const rowAspectRatioSumsForCurrentBP = rowAspectRatioSumsByBreakpoint[breakpoint]; - + const rowAspectRatioSumsForCurrentBP = + rowAspectRatioSumsByBreakpoint[breakpoint]; + return (
@@ -36,22 +44,24 @@ const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => { const rowAspectRatioSum = rowAspectRatioSumsForCurrentBP[rowIndex]; // const width = ((getAspectRatio(image) / rowAspectRatioSum) * 100).toFixed(10); const ar = getAspectRatio(image); - const widthNumber = rowAspectRatioSum === ar - // image is only one in row - ? 100 / itemsPerRow - // image is one of several in row - : ((ar / rowAspectRatioSum) * 100).toFixed(5); + const widthNumber = + rowAspectRatioSum === ar + ? // image is only one in row + 100 / itemsPerRow + : // image is one of several in row + ((ar / rowAspectRatioSum) * 100).toFixed(5); const width = `${widthNumber}%`; return ( - { ); })} -
); +
+ ); // return null; }; diff --git a/src/components/resume/ResumeLayout.js b/src/components/resume/ResumeLayout.js index e211436..2d57584 100644 --- a/src/components/resume/ResumeLayout.js +++ b/src/components/resume/ResumeLayout.js @@ -1,10 +1,10 @@ -import * as React from 'react'; -import classnames from 'classnames'; -import { MDXProvider } from '@mdx-js/react'; +import * as React from "react"; +import classnames from "classnames"; +import { MDXProvider } from "@mdx-js/react"; -import '../../styles/resume.css'; +import "../../styles/resume.css"; -const MyH1 = props =>

; +const MyH1 = (props) =>

; // const MyParagraph = props => ( //

// ); @@ -14,12 +14,13 @@ const components = { // p: MyParagraph, }; - const ResumeLayout = ({ pageContext, children }) => { - console.log('pc', pageContext); + console.log("pc", pageContext); return ( -

{children}
+
+ {children} +
); }; diff --git a/src/fragments.js b/src/fragments.js index a258faf..a1782ef 100644 --- a/src/fragments.js +++ b/src/fragments.js @@ -1,4 +1,4 @@ -import { graphql } from 'gatsby'; +import { graphql } from "gatsby"; export const VibrantColorsFragment = graphql` fragment VibrantColors on FileFieldsImageMetaVibrant { @@ -9,4 +9,4 @@ export const VibrantColorsFragment = graphql` Vibrant Muted } -`; \ No newline at end of file +`; diff --git a/src/html.js b/src/html.js index e4e3a7f..29a6594 100644 --- a/src/html.js +++ b/src/html.js @@ -1,7 +1,8 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React from "react"; +import PropTypes from "prop-types"; -const env = process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || 'development'; +const env = + process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development"; export default function HTML(props) { return ( @@ -9,25 +10,40 @@ export default function HTML(props) { - + {props.headComponents} - {env === 'production' && } + {env === "production" && ( + + )} {/* eslint-disable-next-line */} - {env === 'production' && } + {env === "production" && ( + + )} {props.preBodyComponents}
{props.postBodyComponents} - + ); diff --git a/src/pages/404.js b/src/pages/404.js index 16abeea..5b0d2ef 100644 --- a/src/pages/404.js +++ b/src/pages/404.js @@ -1,11 +1,11 @@ -import * as React from 'react'; -import { Link } from 'gatsby'; +import * as React from "react"; +import { Link } from "gatsby"; // styles const pageStyles = { - color: '#232129', - padding: '96px', - fontFamily: '-apple-system, Roboto, sans-serif, serif', + color: "#232129", + padding: "96px", + fontFamily: "-apple-system, Roboto, sans-serif, serif", }; const headingStyles = { marginTop: 0, @@ -17,10 +17,10 @@ const paragraphStyles = { marginBottom: 48, }; const codeStyles = { - color: '#8A6534', + color: "#8A6534", padding: 4, - backgroundColor: '#FFF4DB', - fontSize: '1.25rem', + backgroundColor: "#FFF4DB", + fontSize: "1.25rem", borderRadius: 4, }; @@ -31,13 +31,13 @@ const NotFoundPage = () => { Not found

Page not found

- Sorry{' '} + Sorry{" "} 😔 - {' '} + {" "} we couldn’t find what you were looking for.
- {process.env.NODE_ENV === 'development' ? ( + {process.env.NODE_ENV === "development" ? ( <>
Try creating a page in src/pages/. diff --git a/src/pages/asdf-resume.mdx b/src/pages/asdf-resume.mdx index 34607a8..996738a 100644 --- a/src/pages/asdf-resume.mdx +++ b/src/pages/asdf-resume.mdx @@ -2,8 +2,8 @@ title: Charles Dries Resume --- -import ResumeLayout from '../components/resume/ResumeLayout' -export default ResumeLayout +import ResumeLayout from "../components/resume/ResumeLayout"; +export default ResumeLayout; # Hello, World! diff --git a/src/pages/index.js b/src/pages/index.js index 8225557..bc99fd3 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,47 +1,69 @@ -import * as React from 'react'; -import { Link, graphql } from 'gatsby'; -import { GatsbyImage, getImage } from 'gatsby-plugin-image'; -import { Helmet } from 'react-helmet'; -import { take } from 'ramda'; -import classnames from 'classnames'; -import posthog from 'posthog-js'; +import * as React from "react"; +import { Link, graphql } from "gatsby"; +import { GatsbyImage, getImage } from "gatsby-plugin-image"; +import { Helmet } from "react-helmet"; +import { take } from "ramda"; +import classnames from "classnames"; +import posthog from "posthog-js"; -import { getVibrantToHelmetSafeBodyStyle, getVibrant, getAspectRatio } from '../utils'; -import { HeroA } from '../components/Index/HeroLink'; +import { + getVibrantToHelmetSafeBodyStyle, + getVibrant, + getAspectRatio, +} from "../utils"; +import { HeroA } from "../components/Index/HeroLink"; -const env = process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || 'development'; +const env = + process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development"; const getDifferentRand = (range, lastNs, iterations = 0) => { const n = Math.floor(Math.random() * range); - if (lastNs.findIndex(x => x === n) > -1 && iterations < 5) { - console.log('got dupe, trying again', n); + if (lastNs.findIndex((x) => x === n) > -1 && iterations < 5) { + console.log("got dupe, trying again", n); return getDifferentRand(range, lastNs, iterations + 1); } return n; }; -const IndexPage = ({ data: { allFile: { edges } } }) => { +const IndexPage = ({ + data: { + allFile: { edges }, + }, +}) => { const [isClient, setIsClient] = React.useState(false); const [imageIndex, setImageIndex] = React.useState(0); const images = React.useMemo(() => edges.map((edge) => edge.node), [edges]); const image = React.useMemo(() => { - console.log('ii', imageIndex); + console.log("ii", imageIndex); return images[imageIndex]; }, [images, imageIndex]); - const shuffleImage = React.useCallback((currentImage) => { - const lastThreeImages = JSON.parse(localStorage.getItem('lastHeros')) || []; - if (env === 'production') { - try { - // eslint-disable-next-line - posthog.capture('[shuffle image]', { currentImage: currentImage?.base }); - window.plausible('Shuffle', {props: { currentImage: currentImage?.base }}); - } catch (e) {/* do nothing */} - } - const index = getDifferentRand(images.length, lastThreeImages); - localStorage.setItem('lastHeros', JSON.stringify(take(3, [index, ...lastThreeImages]))); - setImageIndex(index); - }, [images.length]); + const shuffleImage = React.useCallback( + (currentImage) => { + const lastThreeImages = + JSON.parse(localStorage.getItem("lastHeros")) || []; + if (env === "production") { + try { + // eslint-disable-next-line + posthog.capture("[shuffle image]", { + currentImage: currentImage?.base, + }); + window.plausible("Shuffle", { + props: { currentImage: currentImage?.base }, + }); + } catch (e) { + /* do nothing */ + } + } + const index = getDifferentRand(images.length, lastThreeImages); + localStorage.setItem( + "lastHeros", + JSON.stringify(take(3, [index, ...lastThreeImages])) + ); + setImageIndex(index); + }, + [images.length] + ); // pick random image on page hydration React.useEffect(() => { @@ -54,165 +76,257 @@ const IndexPage = ({ data: { allFile: { edges } } }) => { React.useEffect(() => { const keyListener = (e) => { switch (e.code) { - case 'ArrowRight': { - if (imageIndex === images.length - 1) { - setImageIndex(0); + case "ArrowRight": { + if (imageIndex === images.length - 1) { + setImageIndex(0); + return; + } + setImageIndex(imageIndex + 1); return; } - setImageIndex(imageIndex + 1); - return; - } - case 'ArrowLeft': { - if (imageIndex === 0) { - setImageIndex(images.length - 1); + case "ArrowLeft": { + if (imageIndex === 0) { + setImageIndex(images.length - 1); + return; + } + setImageIndex(imageIndex - 1); return; } - setImageIndex(imageIndex - 1); - return; - } } }; - document.addEventListener('keydown', keyListener); + document.addEventListener("keydown", keyListener); return () => { - document.removeEventListener('keydown', keyListener); + document.removeEventListener("keydown", keyListener); }; }, [imageIndex, images.length]); const vibrant = getVibrant(image); const ar = getAspectRatio(image); - return (<> - - Chuck Dries - - - {/* WIP: ipad portrait hits md breakpoint, looks bad */} -

1 || !isClient - ? 'landscape:grid portrait:flex portrait:flex-col' : 'portrait:grid landscape:flex landscape:flex-row-reverse')} - > - {isClient ? - + + Chuck Dries + + + {/* WIP: ipad portrait hits md breakpoint, looks bad */} +
1 || !isClient + ? "landscape:grid portrait:flex portrait:flex-col" + : "portrait:grid landscape:flex landscape:flex-row-reverse" + )} + > + {isClient ? ( + 1 || !isClient + ? "landscape:h-screen portrait:h-two-thirds-vw" + : "h-screen portrait:w-full landscape:w-1/2" + )} + image={getImage(image)} + loading="eager" + style={{ + gridArea: "1/1", + }} + /> + ) : ( + // 67vw = 1/1.49253731 = 1/aspect ratio of my camera lol +
+ )} +
1 || !isClient ? 'landscape:h-screen portrait:h-two-thirds-vw' : 'h-screen portrait:w-full landscape:w-1/2', + "relative grid", + ar <= 1 + ? "place-items-end landscape:place-items-center" + : "place-items-end" )} - image={getImage(image)} - loading="eager" - style={{ - gridArea: '1/1', - }} /> - // 67vw = 1/1.49253731 = 1/aspect ratio of my camera lol - :
} -
-
-
-
+ style={{ gridArea: "1/1" }} + > +
+
+
+ + + + + + +
- + Photography Gallery -
- 1 && "landscape:shadow-lg", + "md:px-6 px-4 md:py-5 py-3 rounded-l-md mb-4", + isClient && + "bg-vibrant-dark bg-opacity-60 backdrop-filter backdrop-blur-xl" + )} > - Photography Gallery - -
-
1 && 'landscape:shadow-lg', - 'md:px-6 px-4 md:py-5 py-3 rounded-l-md mb-4', isClient && - 'bg-vibrant-dark bg-opacity-60 backdrop-filter backdrop-blur-xl' - )} - > -
1 || !isClient ? 'landscape:flex' : 'portrait:flex')} - > -
-

Chuck Dries

-

Full Stack Software Engineer & Hobbyist Photographer

+
1 || !isClient ? "landscape:flex" : "portrait:flex" + )} + > +
+

+ Chuck Dries +

+

+ Full Stack Software Engineer & Hobbyist Photographer +

+
+ {/* {
} */} + +
    +
  • Software Engineer, Axosoft
  • +
  • + + chuck@chuckdries.com + + /602.618.0414 +
  • +
  • + + Github + + / + + LinkedIn + + / + + Devpost + + / + + Resume [pdf] + + / + + Medium (blog) + +
  • +
- {/* {
} */} - -
    -
  • Software Engineer, Axosoft
  • -
  • chuck@chuckdries.com/602.618.0414
  • -
  • - Github/ - LinkedIn/ - Devpost/ - Resume [pdf]/ - Medium (blog) -
  • -
-
-
+ +
-
- -
- ); +
+ + ); }; export const query = graphql` -{ - allFile( - filter: { sourceInstanceName: {eq: "gallery"} } - sort: {order: DESC, fields: fields___imageMeta___dateTaken} - ) { - edges { - node { - relativePath - base - childImageSharp { - fluid { - aspectRatio + { + allFile( + filter: { sourceInstanceName: { eq: "gallery" } } + sort: { order: DESC, fields: fields___imageMeta___dateTaken } + ) { + edges { + node { + relativePath + base + childImageSharp { + fluid { + aspectRatio + } + gatsbyImageData( + layout: FULL_WIDTH + placeholder: NONE + breakpoints: [750, 1080, 1366, 1920, 2560] + ) } - gatsbyImageData( - layout: FULL_WIDTH - placeholder: NONE - breakpoints: [750, 1080, 1366, 1920, 2560] - ) - } - fields { - imageMeta { - vibrant { - ...VibrantColors + fields { + imageMeta { + vibrant { + ...VibrantColors + } } } } } } } -} `; export default IndexPage; diff --git a/src/pages/photogallery.js b/src/pages/photogallery.js index 3d5bb9c..759038c 100644 --- a/src/pages/photogallery.js +++ b/src/pages/photogallery.js @@ -1,87 +1,95 @@ -import * as React from 'react'; -import { graphql, Link } from 'gatsby'; -import { navigate } from 'gatsby'; -import { Helmet } from 'react-helmet'; +import * as React from "react"; +import { graphql, Link } from "gatsby"; +import { navigate } from "gatsby"; +import { Helmet } from "react-helmet"; -import MasonryGallery from '../components/MasonryGallery'; +import MasonryGallery from "../components/MasonryGallery"; // TODO: caption and title more images // TODO: more images const GalleryPage = ({ data }) => { - const images = React.useMemo(() => - data.allFile.edges - .map(edge => edge.node, [data]) - , [data]); + const images = React.useMemo( + () => data.allFile.edges.map((edge) => edge.node, [data]), + [data] + ); - return (<> - - Photo Gallery | Chuck Dries - - - -
-

Photo Gallery

-
- + return ( + <> + + Photo Gallery | Chuck Dries + + + +
+

+ Photo Gallery +

+
+ +
-
- ); + + ); }; export const query = graphql` -query GalleryPageQuery { - allFile( - filter: { sourceInstanceName: { eq: "gallery" } } - sort: {order: DESC, fields: fields___imageMeta___dateTaken} - ) { - edges { - node { - relativePath - base - childImageSharp{ - fluid { - aspectRatio + query GalleryPageQuery { + allFile( + filter: { sourceInstanceName: { eq: "gallery" } } + sort: { order: DESC, fields: fields___imageMeta___dateTaken } + ) { + edges { + node { + relativePath + base + childImageSharp { + fluid { + aspectRatio + } + gatsbyImageData(layout: CONSTRAINED, height: 550) } - gatsbyImageData( - layout: CONSTRAINED - height: 550 - ) - } - fields { - imageMeta { - dateTaken - iptc { - object_name + fields { + imageMeta { + dateTaken + iptc { + object_name + } } } } } } } -}`; +`; export default GalleryPage; diff --git a/src/styles/global.css b/src/styles/global.css index f6a90bc..7309d09 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,6 +1,6 @@ /* @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap'); */ /* black, bold, regular */ -@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&display=swap"); @tailwind base; @tailwind components; @@ -30,7 +30,7 @@ scroll-snap-align: start; } .scroll-padding-6 { - scroll-padding: theme('spacing.6'); + scroll-padding: theme("spacing.6"); } @variants responsive { .h-two-thirds-vw { @@ -63,7 +63,7 @@ a { margin-left: 3px; transform: translate(0px); display: inline-block; - transition: all .2s; + transition: all 0.2s; } .arrow-left-before:before { diff --git a/src/styles/resume.css b/src/styles/resume.css index 94711bd..b54eff5 100644 --- a/src/styles/resume.css +++ b/src/styles/resume.css @@ -3,4 +3,3 @@ @apply text-3xl font-bold; } } - diff --git a/src/utils.js b/src/utils.js index 5dcbd08..ac2d33e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,31 +2,36 @@ export const getMeta = (image) => image.fields.imageMeta; -export const getName = (image) => getMeta(image)?.iptc.object_name || image.base; +export const getName = (image) => + getMeta(image)?.iptc.object_name || image.base; // some pleasing default colors for SSR and initial hydration export const getVibrant = (image) => getMeta(image)?.vibrant; export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name); -export const getAspectRatio = (image) => image.childImageSharp.fluid.aspectRatio; +export const getAspectRatio = (image) => + image.childImageSharp.fluid.aspectRatio; -export const getRgba = (palette, alpha) => `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, ${alpha || 1})`; +export const getRgba = (palette, alpha) => + `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, ${alpha || 1})`; // work around SSR bug in react-helmet export const getVibrantToHelmetSafeBodyStyle = (vibrant) => { const style = { - '--muted': vibrant.Muted, - '--dark-muted': vibrant.DarkMuted, - '--light-muted': vibrant.LightMuted, - '--vibrant': vibrant.Vibrant, - '--dark-vibrant': vibrant.DarkVibrant, - '--light-vibrant': vibrant.LightVibrant, + "--muted": vibrant.Muted, + "--dark-muted": vibrant.DarkMuted, + "--light-muted": vibrant.LightMuted, + "--vibrant": vibrant.Vibrant, + "--dark-vibrant": vibrant.DarkVibrant, + "--light-vibrant": vibrant.LightVibrant, }; - if (typeof window === 'undefined') { + if (typeof window === "undefined") { return style; } - return Object.keys(style).map(key => `${(key)}: ${style[key]}`).join(';'); + return Object.keys(style) + .map((key) => `${key}: ${style[key]}`) + .join(";"); }; const gcd = (a, b) => { @@ -40,12 +45,12 @@ const gcd = (a, b) => { export const getShutterFractionFromExposureTime = (exposureTime) => { let fraction = exposureTime; const len = fraction.toString().length - 2; - + let denominator = Math.pow(10, len); let numerator = fraction * denominator; - + const divisor = gcd(numerator, denominator); - + numerator /= divisor; denominator /= divisor; return `${numerator}/${denominator}`; diff --git a/static/editme.html b/static/editme.html index 0611faf..b9d6713 100644 --- a/static/editme.html +++ b/static/editme.html @@ -6,7 +6,8 @@

contenteditable can be applied to visible style tags

- This paragraph is editable, as is the style tag below. Edit it to see the layout change in real time. + This paragraph is editable, as is the style tag below. Edit it to see the + layout change in real time.

     
-
+  
 
-
-    
-    
+  
+     
     
-
-
+  
 
diff --git a/static/learn.html b/static/learn.html
index 028cd7a..4b308b9 100644
--- a/static/learn.html
+++ b/static/learn.html
@@ -1,19 +1,16 @@
-
-
-
-
-    
-    Document
-    
-
-
-
-    a tags are for links
-    

p tags are for paragraphs

-

h1 through h6 are for headers

- imgs are for images -
divs are just boxes
- - - - \ No newline at end of file + + + + + Document + + + + + a tags are for links +

p tags are for paragraphs

+

h1 through h6 are for headers

+ imgs are for images +
divs are just boxes
+ + diff --git a/static/roboticchuck.html b/static/roboticchuck.html index 53ae0ef..1e2c063 100644 --- a/static/roboticchuck.html +++ b/static/roboticchuck.html @@ -1,77 +1,101 @@ - - - - - + + + + Robotic Chuck - + body { + margin: auto; + max-width: 800px; + line-height: 1.5; + } - + code, + #output { + padding: 5px; + background: #eee; + border: 1px solid #ccc; + border-radius: 3px; + display: inline-block; + } + + p { + max-width: 800px; + } + + input, + textarea { + width: 100%; + padding: 5px; + /*max-width: 800px;*/ + } + + #genbutton { + color: white; + background: #01c106; + padding: 1em; + border: 1px solid #1e7931; + font-size: 1em; + border-radius: 3px; + } + + + +

-

Title of box:

+

Title of box:

+

Description text:

- +

Enter the links to generate according to this format:

[
     {
@@ -87,20 +111,37 @@
         "url": "yet-another-url"
     }
 ]
-

This format is known as JSON, it's an internet standard that's supposed to be easy for humans and computers to read. - Note how commas are used to separate multiple items but are never used after the last item in a set. This is important, - it will not work if you include a trailing comma where there should not be one.

- -

Generate Code

+

+ This format is known as JSON, it's an internet standard that's supposed to + be easy for humans and computers to read. Note how commas are used to + separate multiple items but are never used after the last item in a set. + This is important, it will not work if you include a trailing comma where + there should not be one. +

+ +

+ Generate Code +

Paste the following code into a safeembed

-

Don't forget: For each page you embed on, add the following bit of code just before the </h4> at the end of the line on the line that corresponds to the current page.

+

+ Don't forget: For each page you embed on, add the following bit + of code just before the </h4> at the end of the line on + the line that corresponds to the current page. +

<span class="here">(You are here)</span>
- -

The code generated will look roughly like this:

-
-

Gryphon overrides certain styles by default, so make sure to test on your article.

- - - \ No newline at end of file +

The code generated will look roughly like this:

+
+

+ Gryphon overrides certain styles by default, so make sure to test on your + article. +

+ + diff --git a/tailwind.config.js b/tailwind.config.js index 5b8e451..76a56f9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,34 +1,34 @@ -const defaultTheme = require('tailwindcss/defaultTheme'); +const defaultTheme = require("tailwindcss/defaultTheme"); module.exports = { - purge: ['./src/**/*.{js,jsx,ts,tsx}'], + purge: ["./src/**/*.{js,jsx,ts,tsx}"], // darkMode: 'media', // or 'media' or 'class' theme: { screens: { - 'sm': '640px', - 'md': '768px', - 'lg': '1024px', - 'xl': '1280px', - '2xl': '1536px', - 'portrait': {'raw': '(orientation: portrait)'}, - 'landscape': {'raw': '(orientation: landscape)'}, + sm: "640px", + md: "768px", + lg: "1024px", + xl: "1280px", + "2xl": "1536px", + portrait: { raw: "(orientation: portrait)" }, + landscape: { raw: "(orientation: landscape)" }, }, spacing: { - '0': '0px', - '1': '4px', - '2': '8px', - '3': '12px', - '4': '16px', - '5': '24px', - '6': '32px', - '7': '48px', - '8': '80px', - '9': '800px', + 0: "0px", + 1: "4px", + 2: "8px", + 3: "12px", + 4: "16px", + 5: "24px", + 6: "32px", + 7: "48px", + 8: "80px", + 9: "800px", }, fontFamily: { ...defaultTheme.fontFamily, // serif: ['Didot', 'Didot LT', 'STD', 'Hoefler Text' , 'Garamond', 'Times New Roman', 'serif'] - serif: ['Playfair Display', 'serif'], + serif: ["Playfair Display", "serif"], }, extend: { colors: { @@ -40,7 +40,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--vibrant), var(${opacityVariable}, 1))`; } - return 'rgb(var(--vibrant))'; + return "rgb(var(--vibrant))"; }, light: ({ opacityVariable, opacityValue }) => { if (opacityValue !== undefined) { @@ -49,7 +49,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--light-vibrant), var(${opacityVariable}, 1))`; } - return 'rgb(var(--light-vibrant))'; + return "rgb(var(--light-vibrant))"; }, dark: ({ opacityVariable, opacityValue }) => { if (opacityValue !== undefined) { @@ -58,7 +58,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--dark-vibrant), var(${opacityVariable}, 1))`; } - return 'rgb(var(--dark-vibrant))'; + return "rgb(var(--dark-vibrant))"; }, }, muted: { @@ -69,7 +69,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--muted), var(${opacityVariable}, 1))`; } - return 'rgb(var(--muted))'; + return "rgb(var(--muted))"; }, light: ({ opacityVariable, opacityValue }) => { if (opacityValue !== undefined) { @@ -78,7 +78,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--light-muted), var(${opacityVariable}, 1))`; } - return 'rgb(var(--light-muted))'; + return "rgb(var(--light-muted))"; }, dark: ({ opacityVariable, opacityValue }) => { if (opacityValue !== undefined) { @@ -87,7 +87,7 @@ module.exports = { if (opacityVariable !== undefined) { return `rgba(var(--dark-muted), var(${opacityVariable}, 1))`; } - return 'rgb(var(--dark-muted))'; + return "rgb(var(--dark-muted))"; }, }, },