Merge pull request #4 from dawnlabs/about

Add /about Page
main
Jake Dexheimer 7 years ago committed by GitHub
commit cae623c3e4

@ -1,18 +1,41 @@
import React from 'react'
import Link from 'next/link'
import { PALETTE } from '../lib/constants'
const Footer = (props) => (
<div className="footer">
<span>a project by <a href="https://twitter.com/dawn_labs">@dawn_labs ¬</a></span>
<div>
<Link href="/about"><a>about</a></Link>
<a href="mailto:hi@dawnlabs.io?subject=Carbon%20Feedback&anp;body=">send feedback</a>
<a href="#">tweet</a>
<a href="#">star</a>
</div>
<div>a project by <a href="https://twitter.com/dawn_labs">@dawn_labs</a> ¬</div>
<style jsx>{`
.footer {
margin: 48px 0;
}
div {
text-align: center;
font-size: 14px;
margin: 32px 0;
color: rgba(255, 255, 255, 0.5);
margin: 16px 0;
color: ${PALETTE.GRAY};
}
a {
color: #C694E8;
margin-right: 16px;
color: #fff;
text-decoration: none;
}
a:last-child {
margin-right: 0;
}
a:hover {
border-bottom: 1px solid #fff;
}
`}</style>
</div>
)

@ -1,29 +1,30 @@
import React from 'react'
import Logo from './svg/Logo'
const Header = (props) => (
<div className="header">
const Header = ({ enableHeroText }) => (
<div className="header mt3 mb4">
<div className="header-content">
<Logo />
<h1>The easiest way to create images from source code. Start typing, or drag a file into the text area to get started.</h1>
<a className="mb3" href="/"><Logo /></a>
{ enableHeroText ? (<h2>The easiest way to create images from source code.<br/> Start typing, or drag a file into the text area to get started.</h2>) : null }
</div>
<style jsx>{`
.header {
margin: 40px 0 48px;
width: 648px;
width: 632px;
}
.header-content {
display: flex;
justify-content: space-between;
flex-direction: column;
align-items: center;
}
h1 {
max-width: 472px;
font-size: 20px;
line-height: 1.5;
color: #fff;
.header-content a {
height: 64px;
}
h2 {
text-align: center;
margin-top: 0;
}
`}</style>
</div>

@ -5,6 +5,7 @@ export default () => (
<div className="meta">
<Head>
<link rel="stylesheet" href='//cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/codemirror.min.css' />
<link rel="stylesheet" href="/static/type-system.css" />
{
THEMES.map((theme, i) => (
<link key={i} rel="stylesheet" href={`//cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/theme/${theme.id}.min.css`}/>
@ -24,7 +25,12 @@ export default () => (
<style jsx global>{`
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
background: #000;
color: #fff;
background: #121212;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 500;
}
*, *:after, *:before {
@ -37,7 +43,8 @@ export default () => (
}
::selection {
background-color: rgba(256, 256, 256, 0.165);
background: rgba(255,255,255,.99);
color: #121212;
}
#toolbar > div {

@ -0,0 +1,27 @@
import React from 'react'
import Meta from './Meta'
import Header from './Header'
import Footer from './Footer'
export default ({ children, enableHeroText }) => (
<div className="main">
<Meta />
<Header enableHeroText={enableHeroText} />
<div className="page">
{ children }
</div>
<Footer />
<style jsx>{`
.main {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
min-width: 848px;
min-height: 704px;
}
`}</style>
</div>
)

@ -1,7 +1,7 @@
import React from 'react'
export default () => (
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 280 280">
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 280 280">
<g fill="#F8E81C" fillRule="evenodd">
<path fillRule="nonzero" d="M140,280 C62.680135,280 0,217.319865 0,140 C0,62.680135 62.680135,0 140,0 C217.319865,0 280,62.680135 280,140 C280,217.319865 217.319865,280 140,280 Z M140,272 C212.901587,272 272,212.901587 272,140 C272,67.098413 212.901587,8 140,8 C67.098413,8 8,67.098413 8,140 C8,212.901587 67.098413,272 140,272 Z M140.501845,259.926199 C74.5455954,259.926199 21.0774908,206.458095 21.0774908,140.501845 C21.0774908,74.5455954 74.5455954,21.0774908 140.501845,21.0774908 C206.458095,21.0774908 259.926199,74.5455954 259.926199,140.501845 C259.926199,206.458095 206.458095,259.926199 140.501845,259.926199 Z M140.501845,251.926199 C202.039817,251.926199 251.926199,202.039817 251.926199,140.501845 C251.926199,78.9638734 202.039817,29.0774908 140.501845,29.0774908 C78.9638734,29.0774908 29.0774908,78.9638734 29.0774908,140.501845 C29.0774908,202.039817 78.9638734,251.926199 140.501845,251.926199 Z"/>
<g transform="translate(49 118)">

@ -50,7 +50,7 @@ export const THEMES = [
export const LANGUAGES = [
{
name: 'Auto Detect'
name: 'Auto'
},
{
name: 'Plain Text'
@ -230,8 +230,9 @@ export const LANGUAGES = [
]
export const PALETTE = {
EDITOR_BG: '#1A1A1A',
SECONDARY: '#fff'
EDITOR_BG: '#121212',
SECONDARY: '#fff',
GRAY: '#646464'
}
export const DEFAULT_CODE = `const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj)

@ -0,0 +1,47 @@
import Page from '../components/Page'
import Meta from '../components/Meta'
import Header from '../components/Header'
import Footer from '../components/Footer'
import { PALETTE } from '../lib/constants'
export default () => (
<Page>
<div className="about">
<div className="mb4">
<h2>What does this do?</h2>
<p>You know all of those code screenshots you see on Twitter? Although the code's usually impressive, we think there's room for improvement in the aesthetic department. Carbon is the easiest way to create beautiful images of your source code. Now you can impress all of your followers with your newfound design prowess. 🎨</p>
</div>
<div className="mb4">
<h2>How do I use it?</h2>
<h4 className="mb0">Import</h4>
<p className="mb1 mt2">There are a few different ways to import code into Carbon:</p>
<ul className="mt0 mb3">
<li>Drag a file into the editor</li>
<li>Append a GitHub Gist id to the url</li>
<li>Paste your code directly</li>
</ul>
<h4 className="mb0">Customization</h4>
<p className="mt2 mb3">Once you've got all of your code into Carbon, you can customize your image by changing the syntax theme, background color, window theme, or padding.</p>
<h4 className="mb0">Export/Sharing</h4>
<p className="mt2">After you've customized your image, you can copy a link to the image, save it, or share it on Twitter.</p>
</div>
<div className="mb4">
<h2>I want to make this better.</h2>
<p>Please do.</p>
</div>
</div>
<style jsx>{`
h4 {
color: ${PALETTE.GRAY};
}
ul {
list-style-position: inside;
}
.about {
max-width: 632px;
}
`}</style>
</Page>
)

@ -0,0 +1,100 @@
import React from 'react'
import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd'
import Axios from 'axios'
import domtoimage from 'dom-to-image'
import Page from '../components/Page'
import ReadFileDropContainer from '../components/ReadFileDropContainer'
import Toolbar from '../components/Toolbar'
import CodeImage from '../components/CodeImage'
import api from '../lib/api'
import { THEMES, LANGUAGES, PALETTE, DEFAULT_CODE } from '../lib/constants'
class Editor extends React.Component {
/* pathname, asPath, err, req, res */
static async getInitialProps ({ asPath }) {
try {
if (asPath !== '/') {
const content = await api.getGist(asPath)
return { content }
}
} catch (e) {
console.log(e)
}
return {}
}
constructor() {
super()
this.state = {
background: '#ABB8C3',
theme: THEMES[0].id,
language: 'javascript', // TODO LANGUAGES[0]
dropShadow: true,
windowControls: true,
paddingVertical: '48px',
paddingHorizontal: '32px'
}
}
save () {
// domtoimage.toPng(document.getElementById('container'))
domtoimage.toPng(document.getElementById('container'))
.then((dataUrl) => {
const link = document.createElement('a')
link.download = 'snippet.png'
link.href = dataUrl
link.click()
})
}
upload () {
domtoimage.toBlob(document.getElementById('container'))
.then(api.uploadImage)
.then(res => res.data.id)
.then(id => `http://i.imgur.com/${id}`)
.then(console.log)
}
render () {
return (
<Page enableHeroText>
{/* TODO this doesn't update the render */}
<ReadFileDropContainer
onDrop={(droppedContent) => {
console.log(droppedContent)
this.setState({ droppedContent })
}}
>
<div id="editor">
<Toolbar
save={this.save}
upload={this.upload}
onBGChange={color => this.setState({ background: color })}
onThemeChange={theme => this.setState({ theme: theme.id })}
onLanguageChange={language => this.setState({ language })}
onSettingsChange={(key, value) => this.setState({ [key]: value })}
bg={this.state.background}
enabled={this.state}
/>
<CodeImage config={this.state}>
{this.state.droppedContent || this.props.content || DEFAULT_CODE}
</CodeImage>
</div>
</ReadFileDropContainer>
<style jsx>{`
#editor {
background: ${PALETTE.EDITOR_BG};
border: 3px solid ${PALETTE.SECONDARY};
border-radius: 8px;
padding: 16px;
}
`}
</style>
</Page>
)
}
}
export default DragDropContext(HTML5Backend)(Editor)

@ -1,116 +1,2 @@
import React from 'react'
import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd'
import Axios from 'axios'
import domtoimage from 'dom-to-image'
import ReadFileDropContainer from '../components/ReadFileDropContainer'
import Meta from '../components/Meta'
import Toolbar from '../components/Toolbar'
import { WINDOW_THEMES } from '../components/ThemeSelect'
import CodeImage from '../components/CodeImage'
import Header from '../components/Header'
import Footer from '../components/Footer'
import api from '../lib/api'
import { THEMES, LANGUAGES, PALETTE, DEFAULT_CODE } from '../lib/constants'
class Index extends React.Component {
/* pathname, asPath, err, req, res */
static async getInitialProps ({ asPath }) {
try {
if (asPath !== '/') {
const content = await api.getGist(asPath)
return { content }
}
} catch (e) {
console.log(e)
}
return {}
}
constructor() {
super()
this.state = {
background: '#ABB8C3',
theme: THEMES[0].id,
language: 'javascript', // TODO LANGUAGES[0]
windowTheme: WINDOW_THEMES[0],
dropShadow: true,
windowControls: true,
paddingVertical: '48px',
paddingHorizontal: '32px'
}
}
save () {
domtoimage.toPng(document.getElementById('container'))
.then((dataUrl) => {
const link = document.createElement('a')
link.download = 'snippet.png'
link.href = dataUrl
link.click()
})
}
upload () {
domtoimage.toBlob(document.getElementById('container'))
.then(api.uploadImage)
.then(res => res.data.id)
.then(id => `http://i.imgur.com/${id}`)
.then(console.log)
}
render () {
return (
<div className="main">
<Meta />
<Header />
{/* TODO this doesn't update the render */}
<ReadFileDropContainer
onDrop={(droppedContent) => {
console.log(droppedContent)
this.setState({ droppedContent })
}}
>
<div id="editor">
<Toolbar
save={this.save}
upload={this.upload}
onBGChange={color => this.setState({ background: color })}
onThemeChange={theme => this.setState({ theme: theme.id })}
onLanguageChange={language => this.setState({ language })}
onSettingsChange={(key, value) => this.setState({ [key]: value })}
bg={this.state.background}
enabled={this.state}
/>
<CodeImage config={this.state}>
{this.state.droppedContent || this.props.content || DEFAULT_CODE}
</CodeImage>
</div>
</ReadFileDropContainer>
<Footer />
<style jsx>{`
.main {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
height: 100vh;
min-width: 848px;
min-height: 704px;
}
#editor {
background: ${PALETTE.EDITOR_BG};
border: 3px solid ${PALETTE.SECONDARY};
border-radius: 8px;
padding: 16px;
}
`}
</style>
</div>
)
}
}
export default DragDropContext(HTML5Backend)(Index)
import Editor from './editor'
export default Editor

@ -0,0 +1,89 @@
:root {
--h0: 4.5rem;
--h1: 3rem;
--h2: 2.25rem;
--h3: 1.5rem;
--h4: 1.125rem;
--h5: .75rem;
--lh: calc(4/3);
--mx: 32em;
--m1: calc(2/3 * 1em);
--m2: calc(4/3 * 1em);
--m3: calc(8/3 * 1em);
--m4: calc(16/3 * 1em);
--x1: .5rem;
--x2: 1rem;
--x3: 2rem;
--x4: 4rem;
--x5: 8rem;
--x6: 16rem;
}
body {
font-family: -apple-system, sans-serif;
font-size: var(--h4);
line-height: var(--lh);
margin: 2rem;
}
h1, h2, h3 {
margin-top: var(--m1);
margin-bottom: 0;
}
h4, h5, h6,
p, dl, ol, ul, blockquote {
margin-top: var(--m2);
margin-bottom: var(--m2);
}
h1 { font-size: var(--h2) }
h2, h3 { font-size: var(--h3) }
h4 { font-size: var(--h4) }
h5, h6 { font-size: var(--h5) }
.h0 { font-size: var(--h0) }
.h1 { font-size: var(--h1) }
.h2 { font-size: var(--h2) }
.h3 { font-size: var(--h3) }
.h4 { font-size: var(--h4) }
.h5 { font-size: var(--h5) }
.h6 { font-size: var(--h5) }
@media screen and (min-width: 40em) {
.xh0 { font-size: var(--h0) }
.xh1 { font-size: var(--h1) }
.xh2 { font-size: var(--h2) }
.xh3 { font-size: var(--h3) }
.xh4 { font-size: var(--h4) }
.xh5 { font-size: var(--h5) }
.xh6 { font-size: var(--h5) }
}
.lh1 { line-height: 1 }
/* h0, h1, h3 */
.lh2 { line-height: calc(7/6 * 1em) }
/* For body copy */
.lh3 { line-height: calc(16/9 * 1em) }
.mt0 { margin-top: 0 }
.mb0 { margin-bottom: 0 }
.mt1 { margin-top: var(--x1) }
.mb1 { margin-bottom: var(--x1) }
.mt2 { margin-top: var(--x2) }
.mb2 { margin-bottom: var(--x2) }
.mt3 { margin-top: var(--x3) }
.mb3 { margin-bottom: var(--x3) }
.mt4 { margin-top: var(--x4) }
.mb4 { margin-bottom: var(--x4) }
.mt5 { margin-top: var(--x5) }
.mb5 { margin-bottom: var(--x5) }
.mt6 { margin-top: var(--x6) }
.mb6 { margin-bottom: var(--x6) }
.mx { max-width: var(--mx) }
.bold { font-weight: bold }
Loading…
Cancel
Save