Add export to imgur (#1158)

* add button and functionality

* Create a share menu and for twitter and imgur

* follow 'tweet' patterns

* remove unused carbonRef prop

* remove unused exportImgur

* share menu

* remove Share SVG

* combine tweet and imgur button components

* delete unused tweet and imgur button components

* remove options.filename

* onClickImgur

* change to async await to fix loading state

* NEXT_PUBLIC_IMGUR_CLIENT_ID

* return promise to fix loading state (remove async/await)

Co-authored-by: Mike Fix <mrfix84@gmail.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
main
Amit Keinan 4 years ago committed by GitHub
parent 2b7339cdd5
commit ecd8e631b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,9 +13,9 @@ import Overlay from './Overlay'
import BackgroundSelect from './BackgroundSelect'
import Carbon from './Carbon'
import ExportMenu from './ExportMenu'
import ShareMenu from './ShareMenu'
import CopyMenu from './CopyMenu'
import Themes from './Themes'
import TweetButton from './TweetButton'
import FontFace from './FontFace'
import LanguageIcon from './svg/Language'
import {
@ -180,7 +180,7 @@ class Editor extends React.Component {
return domtoimage.toBlob(node, config)
}
// Twitter needs regular dataURLs
// Twitter and Imgur needs regular dataURLs
return domtoimage.toPng(node, config)
}
@ -190,6 +190,12 @@ class Editor extends React.Component {
)
}
imgur = () => {
const prefix = this.state.name || 'carbon'
return this.getCarbonImage({ format: 'png' }).then(data => this.context.imgur(data, prefix))
}
exportImage = (format = 'png', options = {}) => {
const link = document.createElement('a')
@ -378,7 +384,7 @@ class Editor extends React.Component {
<div id="style-editor-button" />
<div className="buttons">
<CopyMenu copyImage={this.copyImage} carbonRef={this.carbonNode.current} />
<TweetButton onClick={this.tweet} />
<ShareMenu tweet={this.tweet} imgur={this.imgur} />
<ExportMenu
onChange={this.updateSetting}
exportImage={this.exportImage}

@ -0,0 +1,83 @@
import React from 'react'
import { useAsyncCallback, useOnline as useOnlineListener } from 'actionsack'
import { useAPI } from './ApiContext'
import { COLORS } from '../lib/constants'
import Button from './Button'
import Popout, { managePopout } from './Popout'
import { Down as ArrowDown } from './svg/Arrows'
const popoutStyle = { width: '120px', right: 8 }
function ShareMenu({ isVisible, toggleVisibility, tweet, imgur }) {
const api = useAPI()
const online = useOnlineListener()
const [onClickTweet, { loading: tweeting }] = useAsyncCallback(tweet)
const [onClickImgur, { loading: imguring }] = useAsyncCallback(imgur)
if (!api || !api.tweet) {
return null
}
if (!online) {
return null
}
return (
<div className="share-menu-container">
<div className="flex">
<Button
center
border
large
padding="0 16px"
margin="0"
onClick={onClickTweet}
color={COLORS.BLUE}
style={{ borderBottomRightRadius: 0, borderTopRightRadius: 0 }}
>
{tweeting ? 'Loading…' : 'Tweet'}
</Button>
<Button
id="export-menu"
border
large
center
color={COLORS.BLUE}
padding="0 8px"
margin="0 8px 0 -1px"
onClick={toggleVisibility}
data-cy="export-button"
style={{ borderBottomLeftRadius: 0, borderTopLeftRadius: 0 }}
title="Export menu dropdown"
>
<ArrowDown color={COLORS.BLUE} />
</Button>
</div>
<Popout hidden={!isVisible} borderColor={COLORS.BLUE} pointerRight="7px" style={popoutStyle}>
<div className="share-row flex">
<Button padding="8px" color={COLORS.BLUE} onClick={onClickImgur}>
{imguring ? 'Uploading...' : 'Upload to Imgur'}
</Button>
</div>
</Popout>
<style jsx>
{`
.share-menu-container {
position: relative;
color: ${COLORS.BLUE};
flex: 1;
}
.share-row {
flex-direction: column;
/* justify-content: space-between; */
}
`}
</style>
</div>
)
}
export default managePopout(React.memo(ShareMenu))

@ -1,37 +0,0 @@
import React from 'react'
import { useAsyncCallback, useOnline as useOnlineListener } from 'actionsack'
import { useAPI } from './ApiContext'
import Button from './Button'
import { COLORS } from '../lib/constants'
function TweetButton(props) {
const api = useAPI()
const online = useOnlineListener()
const [onClick, { loading }] = useAsyncCallback(props.onClick)
if (!api || !api.tweet) {
return null
}
if (!online) {
return null
}
return (
<Button
center
border
large
padding="0 16px"
margin="0 8px 0 0"
onClick={onClick}
color={COLORS.BLUE}
>
{loading ? 'Loading…' : 'Tweet'}
</Button>
)
}
export default React.memo(TweetButton)

@ -73,6 +73,27 @@ const unsplash = {
},
}
const imgur = (data, title) => {
const image = data.split(',')[1]
return axios
.post(
'https://api.imgur.com/3/image',
{ image, title },
{
headers: {
Authorization: `Client-ID ${process.env.NEXT_PUBLIC_IMGUR_CLIENT_ID}`,
},
}
)
.then(res => res.data.data.link)
.then(link => window.open(link, '_blank'))
.catch(e => {
console.error(e)
return null
})
}
function getSnippet(uid = '', { host, filename } = {}) {
return client
.get(`/snippets/${uid}`, {
@ -165,5 +186,6 @@ export default {
tweet: debounce(tweet, ms('5s'), { leading: true, trailing: false }),
image: debounce(image, ms('5s'), { leading: true, trailing: false }),
unsplash,
imgur,
downloadThumbnailImage,
}

Loading…
Cancel
Save