Merge pull request #7 from dawnlabs/twitter

Add upload to twitter support
main
Michael Fix 7 years ago committed by GitHub
commit 5c91b2b81d

@ -16,8 +16,8 @@ const Toolbar = (props) => (
/> />
<Settings onChange={props.onSettingsChange} enabled={props.enabled} /> <Settings onChange={props.onSettingsChange} enabled={props.enabled} />
<div className="buttons"> <div className="buttons">
<CopyButton /> <Button className="tweetButton" onClick={props.upload} title={props.uploading ? 'Loading...' : 'Tweet Image'} color="#57b5f9" style={{ marginRight: '8px' }} />
<Button onClick={props.save} title="Save Image" color="#57b5f9" /> <Button onClick={props.save} title="Save Image" color="#c198fb" />
</div> </div>
<style jsx>{` <style jsx>{`
#toolbar { #toolbar {

@ -0,0 +1,31 @@
const Twitter = require('twitter')
console.log(process.env);
const client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
})
const uploadImage = (data) => client.post('media/upload', { media_data: data })
const uploadTweet = (media) => client.post('statuses/update', { status: 'carbon copy', media_ids: media.media_id_string })
const extractImageUrl = (response) => response.entities.media[0].display_url
const respondSuccess = (res, url) => res.json({ url })
const respondFail = (res, err) => {
console.error(`Error: ${err.message || err}`)
res.status(500).send()
}
module.exports = (req, res) => {
if (!req.body.data) {
return res.status(400).send()
}
uploadImage(req.body.data)
.then(uploadTweet)
.then(extractImageUrl)
.then(respondSuccess.bind(null, res))
.catch(respondFail.bind(null, res))
}

@ -1,5 +1,7 @@
import axios from 'axios' import axios from 'axios'
const DOMAIN = process.browser ? document.location.origin : ''
const gistClient = axios.create({ const gistClient = axios.create({
baseURL: 'https://api.github.com', baseURL: 'https://api.github.com',
timeout: 5000, timeout: 5000,
@ -9,6 +11,16 @@ const gistClient = axios.create({
} }
}); });
async function tweet (encodedImage) {
const processedData = encodedImage.split(',')[1]
return axios.post(`${DOMAIN}/twitter`, { data: processedData })
.then(res => res.data.url)
.then(url => encodeURIComponent(`Built with #Carbon, by @dawn_labs ${url}`))
.then(uri => `https://twitter.com/intent/tweet?text=${uri}`)
.then(openTwitterUrl)
}
async function uploadImage (encodedImage) { async function uploadImage (encodedImage) {
// upload image // upload image
const url = 'https://api.imgur.com/3/image' const url = 'https://api.imgur.com/3/image'
@ -40,5 +52,16 @@ const getGist = (id) => {
export default { export default {
uploadImage, uploadImage,
getGist getGist,
tweet
}
// private
function openTwitterUrl (twitterUrl) {
const width = 575, height = 400
const left = (window.outerWidth - width) / 2
const right = (window.outerHeight - height) / 2
const opts = `status=1,width=${width},height=${height},top=${top},left=${left}`
window.open(twitterUrl, 'twitter', opts)
} }

@ -1,5 +1,5 @@
{ {
"name": "code-image-2", "name": "carbon",
"version": "1.0.0", "version": "1.0.0",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",
@ -27,6 +27,15 @@
"react-dom": "^15.5.4", "react-dom": "^15.5.4",
"react-spinkit": "^3.0.0", "react-spinkit": "^3.0.0",
"react-spinner": "^0.2.7", "react-spinner": "^0.2.7",
"react-syntax-highlight": "^0.0.6" "react-syntax-highlight": "^0.0.6",
"twitter": "^1.7.1"
},
"now": {
"env": {
"TWITTER_CONSUMER_KEY": "@twitter-consumer-key",
"TWITTER_CONSUMER_SECRET":"@twitter-consumer-secret",
"TWITTER_ACCESS_TOKEN_KEY": "@twitter-access-token-key",
"TWITTER_ACCESS_TOKEN_SECRET": "@twitter-access-token-secret"
}
} }
} }

@ -1,7 +1,6 @@
import React from 'react' import React from 'react'
import HTML5Backend from 'react-dnd-html5-backend' import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd' import { DragDropContext } from 'react-dnd'
import Axios from 'axios'
import domtoimage from 'dom-to-image' import domtoimage from 'dom-to-image'
import Page from '../components/Page' import Page from '../components/Page'
@ -34,11 +33,15 @@ class Editor extends React.Component {
dropShadow: true, dropShadow: true,
windowControls: true, windowControls: true,
paddingVertical: '48px', paddingVertical: '48px',
paddingHorizontal: '32px' paddingHorizontal: '32px',
uploading: false
} }
this.save = this.save.bind(this)
this.upload = this.upload.bind(this)
} }
save () { getCarbonImage () {
const node = document.getElementById('section') const node = document.getElementById('section')
const config = { const config = {
@ -50,7 +53,11 @@ class Editor extends React.Component {
height: node.offsetHeight * 2 height: node.offsetHeight * 2
} }
domtoimage.toPng(node, config) return domtoimage.toPng(node, config)
}
save () {
this.getCarbonImage()
.then((dataUrl) => { .then((dataUrl) => {
const link = document.createElement('a') const link = document.createElement('a')
link.download = 'snippet.png' link.download = 'snippet.png'
@ -60,11 +67,14 @@ class Editor extends React.Component {
} }
upload () { upload () {
domtoimage.toBlob(document.getElementById('container')) this.setState({ uploading: true })
.then(api.uploadImage) this.getCarbonImage()
.then(res => res.data.id) .then(api.tweet)
.then(id => `http://i.imgur.com/${id}`) .then(() => this.setState({ uploading: false }))
.then(console.log) .catch((err) => {
console.error(err)
this.setState({ uploading: false })
})
} }
render () { render () {
@ -77,6 +87,7 @@ class Editor extends React.Component {
<Toolbar <Toolbar
save={this.save} save={this.save}
upload={this.upload} upload={this.upload}
uploading={this.state.uploading}
onBGChange={color => this.setState({ background: color })} onBGChange={color => this.setState({ background: color })}
onThemeChange={theme => this.setState({ theme: theme.id })} onThemeChange={theme => this.setState({ theme: theme.id })}
onLanguageChange={language => this.setState({ language: language.module })} onLanguageChange={language => this.setState({ language: language.module })}

@ -32,7 +32,7 @@ app.prepare()
// api endpoints // api endpoints
server.post('/upload', bodyParser.json(), wrap(require('./handlers/upload'))) server.post('/upload', bodyParser.json(), wrap(require('./handlers/upload')))
server.post('/twitter', bodyParser.json({ limit: '5mb' }), require('./handlers/twitter'))
server.listen(port, (err) => { server.listen(port, (err) => {
if (err) throw err if (err) throw err

@ -1215,6 +1215,10 @@ decamelize@^1.0.0, decamelize@^1.1.1:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
deep-extend@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.0.tgz#6ef4a09b05f98b0e358d6d93d4ca3caec6672803"
deep-extend@~0.4.0: deep-extend@~0.4.0:
version "0.4.2" version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -3148,7 +3152,7 @@ repeating@^2.0.0:
dependencies: dependencies:
is-finite "^1.0.0" is-finite "^1.0.0"
request@^2.81.0: request@^2.72.0, request@^2.81.0:
version "2.81.0" version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies: dependencies:
@ -3552,6 +3556,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5" version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
twitter@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/twitter/-/twitter-1.7.1.tgz#0762378f1dc1c050e48f666aca904e24b1a962f4"
dependencies:
deep-extend "^0.5.0"
request "^2.72.0"
type-is@~1.6.15: type-is@~1.6.15:
version "1.6.15" version "1.6.15"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"

Loading…
Cancel
Save