Fix Medium embedding workflow (#707)

* fix url encoding to support direct pastes to medium

* move check for object keys length to getQueryStringState

* remove url parse from GistContainer

* use useMemo instead of memo

* remove decode()

* add copy URL button to export menu
main
Michael Fix 6 years ago committed by GitHub
parent 9ddb821fa4
commit b5ae198312
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -63,8 +63,7 @@ class Editor extends React.Component {
async componentDidMount() {
const { asPath = '' } = this.props.router
const { query } = url.parse(asPath, true)
const queryParams = getQueryStringState(query)
const initialState = Object.keys(queryParams).length ? queryParams : {}
const initialState = getQueryStringState(query)
const newState = {
// Load from localStorage

@ -15,6 +15,8 @@ const toIFrame = url =>
</iframe>
`
const toURL = url => encodeURI(`https://carbon.now.sh/embed${url}`)
const MAX_PAYLOAD_SIZE = 5e6 // bytes
function verifyPayloadSize(str) {
if (typeof str !== 'string') return true
@ -22,20 +24,23 @@ function verifyPayloadSize(str) {
return new Blob([str]).size < MAX_PAYLOAD_SIZE
}
const CopyEmbed = withRouter(
React.memo(
({ router: { asPath } }) => {
const { onClick, copied } = useCopyTextHandler(toIFrame(asPath))
return (
<Button onClick={onClick} center color={COLORS.PURPLE} padding="12px 16px" flex="1 0 68px">
{copied ? 'Copied!' : 'Copy Embed'}
</Button>
)
},
(prevProps, nextProps) => prevProps.router.asPath === nextProps.router.asPath
const CopyEmbed = withRouter(({ router: { asPath }, mapper, title, margin }) => {
const text = React.useMemo(() => mapper(asPath), [mapper, asPath])
const { onClick, copied } = useCopyTextHandler(text)
return (
<Button
onClick={onClick}
center
hoverColor={COLORS.PURPLE}
color={COLORS.DARK_PURPLE}
margin={margin}
style={{ minWidth: 48 }}
>
{copied ? 'Copied!' : title}
</Button>
)
)
})
const popoutStyle = { width: '280px', right: 0 }
@ -102,7 +107,13 @@ class ExportMenu extends React.PureComponent {
<Button center color={COLORS.PURPLE} onClick={this.handleExport('open')}>
Open
</Button>
<CopyEmbed />
<div className="save-container">
<span>Copy embed</span>
<div>
<CopyEmbed title="URL" mapper={toURL} margin="0 4px 0 0" />
<CopyEmbed title="IFrame" mapper={toIFrame} margin="0 0 0 4px" />
</div>
</div>
<div className="save-container">
<span>Save as</span>
<div>
@ -175,6 +186,11 @@ class ExportMenu extends React.PureComponent {
display: flex;
flex: 1;
}
.save-container:first-of-type {
padding: 12px 12px;
border-right: 1px solid ${COLORS.PURPLE};
}
`}
</style>
</div>

@ -1,5 +1,4 @@
import React from 'react'
import url from 'url'
import { withRouter } from 'next/router'
import { escapeHtml } from '../lib/util'
@ -9,8 +8,7 @@ class GistContainer extends React.Component {
static contextType = ApiContext
async componentDidMount() {
const { asPath = '' } = this.props.router
const { pathname } = url.parse(asPath, true)
const { pathname } = this.props.router
const path = escapeHtml(pathname.split('/').pop())
let newState = {}

@ -62,7 +62,7 @@ export const deserializeState = serializedState => {
return JSON.parse(decodeURIComponent(stateString))
}
export const getQueryStringState = query => {
const getQueryStringObject = query => {
if (query.state) {
return deserializeState(query.state)
}
@ -77,9 +77,16 @@ export const getQueryStringState = query => {
return state
}
export const getQueryStringState = query => {
const queryParams = getQueryStringObject(query)
return Object.keys(queryParams).length ? queryParams : {}
}
export const updateQueryString = (router, state) => {
const mappedState = mapper.map(reverseMappings, state)
serializeCode(mappedState)
// calls `encodeURIComponent` on each key internally
// const query = qs.stringify(mappedState)
router.replace(
{

@ -56,16 +56,15 @@ class Embed extends React.Component {
handleUpdate = updates => {
const { asPath = '' } = this.props.router
const { query } = url.parse(asPath, true)
const queryParams = getQueryStringState(query)
const initialState = Object.keys(queryParams).length ? queryParams : {}
const initialState = getQueryStringState(query)
this.setState(
{
...initialState,
...updates,
id: query.id,
copyable: queryParams.copy !== false,
readOnly: queryParams.readonly !== false,
copyable: initialState.copy !== false,
readOnly: initialState.readonly !== false,
mounted: true
},
this.postMessage

Loading…
Cancel
Save