Skip to content

Commit

Permalink
Where available, use the GitHub organisation avatar as the image for …
Browse files Browse the repository at this point in the history
…an extension
  • Loading branch information
holly-cummins committed Dec 6, 2022
1 parent c8e12bb commit dc3de47
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 10 deletions.
8 changes: 8 additions & 0 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ module.exports = {
path: `${__dirname}/src/images`,
},
},
`github-enricher`,
{
resolve: `gatsby-plugin-remote-images`,
options: {
nodeType: "extension",
imagePath: "fields.sourceControlInfo.logoUrl",
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"gatsby-plugin-fontawesome-css": "^1.2.0",
"gatsby-plugin-image": "^2.22.0",
"gatsby-plugin-manifest": "^4.22.0",
"gatsby-plugin-remote-images": "^3.6.0-alpha",
"gatsby-plugin-sharp": "^4.22.0",
"gatsby-plugin-styled-components": "^5.23.0",
"gatsby-remark-copy-linked-files": "^5.22.0",
Expand Down
45 changes: 45 additions & 0 deletions plugins/github-enricher/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const defaultOptions = {
nodeType: "extension",
}

exports.onCreateNode = async ({ node, getNode, actions }, pluginOptions) => {
const { createNodeField } = actions

const options = {
...defaultOptions,
...pluginOptions,
}

if (node.internal.type !== options.nodeType) {
return
}

const { metadata } = node
const scmUrl = metadata["scm-url"]

if (scmUrl) {
// We should do this properly with the API, but for now make an educated guess about the image URL
// See https://stackoverflow.com/questions/22932422/get-github-avatar-from-email-or-name
// remove everything after the last backslash
const orgUrl = scmUrl.substr(0, scmUrl.lastIndexOf("/"))
const logoUrl = orgUrl + ".png"
const scmInfo = { url: scmUrl, logoUrl }

createNodeField({
node,
name: "sourceControlInfo",
value: scmInfo,
})
}
}

exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type SourceControlInfo implements Node {
url: String
logo: String
}
`
createTypes(typeDefs)
}
68 changes: 68 additions & 0 deletions plugins/github-enricher/gatsby-node.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const { onCreateNode } = require("./gatsby-node")

// This test relies on a mock in __mocks__. To validate things against
// the real implementation, rename __mocks__/node-geocoder.js to something else temporarily.

const createNodeField = jest.fn(({ node, name, value }) => {
if (!node.fields) {
node.fields = {}
}
node.fields[name] = value
})
const actions = { createNodeField }
const internal = { type: "extension" }

describe("the preprocessor", () => {
describe("for an extension with no scm information", () => {
const metadata = {}

const node = {
metadata,
internal,
}

beforeAll(async () => {
await onCreateNode({ node, actions })
})

afterAll(() => {})

it("changes nothing", async () => {
expect(node.metadata).toEqual({})
expect(node.sourceControlInfo).toBeUndefined()
})
})

describe("for an extension with a scm-url", () => {
const url = "http://gitsomething.com/someuser/somerepo"
const imageUrl = "http://gitsomething.com/someuser.png"
const metadata = {
"scm-url": url,
}

const node = {
metadata,
internal,
}

beforeAll(async () => {
await onCreateNode({ node, actions })
})

afterAll(() => {})

it("creates an scm object", async () => {
expect(node.fields.sourceControlInfo).toBeTruthy()
})

it("copies across the url", async () => {
expect(node.fields.sourceControlInfo.url).toEqual(url)
})

it("fills in an image", async () => {
expect(node.fields.sourceControlInfo.logoUrl).toEqual(imageUrl)
})

xit("adds a node for the remote image", async () => {})
})
})
3 changes: 3 additions & 0 deletions plugins/github-enricher/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "github-enricher"
}
41 changes: 31 additions & 10 deletions src/components/extension-card.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as React from "react"
import { StaticImage } from "gatsby-plugin-image"
import Link from "gatsby-link"

import styled from "styled-components"
import prettyCategory from "./util/pretty-category"
import { GatsbyImage, StaticImage } from "gatsby-plugin-image"

const Card = styled(props => <Link {...props} />)`
font-size: 3.5em;
Expand All @@ -24,8 +24,11 @@ const Card = styled(props => <Link {...props} />)`

const Logo = styled.div`
width: 80px;
height: 56px;
height: 80px;
margin-bottom: 25px;
display: flex;
justify-content: center;
align-items: center;
`

const ExtensionName = styled.div`
Expand Down Expand Up @@ -65,18 +68,36 @@ const FinerDetails = styled.div`
padding-bottom: 30px;
`

const logo = extension => {
if (extension.localImage?.childImageSharp?.gatsbyImageData) {
return (
<Logo>
<GatsbyImage
layout="constrained"
image={extension.localImage?.childImageSharp.gatsbyImageData}
alt="The extension logo"
/>
</Logo>
)
} else {
return (
<Logo>
<StaticImage
layout="constrained"
formats={["auto", "webp", "avif"]}
src="../images/generic-extension-logo.png"
alt="A generic image as a placeholder for the extension logo"
/>
</Logo>
)
}
}

const ExtensionCard = ({ extension }) => {
return (
<Card to={extension.slug} $unlisted={extension.metadata.unlisted}>
<MainInformation>
<Logo>
<StaticImage
layout="constrained"
formats={["auto", "webp", "avif"]}
src="../images/generic-extension-logo.png"
alt="The extension logo"
/>
</Logo>
{logo(extension)}
<ExtensionName $unlisted={extension.metadata.unlisted}>
{extension.name}
</ExtensionName>
Expand Down
8 changes: 8 additions & 0 deletions src/components/extension-card.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ describe("extension card", () => {
it("renders the version", () => {
expect(screen.getByText("Version: " + version)).toBeTruthy()
})

it("renders a placeholder image with appropriate source ", async () => {
const image = screen.getByAltText(
"A generic image as a placeholder for the extension logo"
)

expect(image.src).toContain("generic-extension-logo.png")
})
})

describe("an unlisted extension", () => {
Expand Down
5 changes: 5 additions & 0 deletions src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ export const pageQuery = graphql`
}
}
platforms
localImage {
childImageSharp {
gatsbyImageData(width: 80)
}
}
}
}
}
Expand Down

0 comments on commit dc3de47

Please sign in to comment.