Moving link generation into FormActions
This commit is contained in:
parent
f41518bd92
commit
42a1788c52
@ -10,54 +10,6 @@ import Message from 'components/Message';
|
|||||||
|
|
||||||
const toUrl = params => new URLSearchParams(params).toString();
|
const toUrl = params => new URLSearchParams(params).toString();
|
||||||
|
|
||||||
const createSvgLink = async ({ svg }) => {
|
|
||||||
try {
|
|
||||||
const type = 'image/svg+xml';
|
|
||||||
const blob = new Blob([svg], { type });
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: URL.createObjectURL(blob),
|
|
||||||
label: 'Download SVG',
|
|
||||||
filename: 'image.svg',
|
|
||||||
type
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e); // eslint-disable-line no-console
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const createPngLink = async ({ svg, width, height }) => {
|
|
||||||
try {
|
|
||||||
const type = 'image/png';
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
const context = canvas.getContext('2d');
|
|
||||||
const loader = new Image();
|
|
||||||
|
|
||||||
loader.width = canvas.width = Number(width) * 2;
|
|
||||||
loader.height = canvas.height = Number(height) * 2;
|
|
||||||
|
|
||||||
await new Promise(resolve => {
|
|
||||||
loader.onload = resolve;
|
|
||||||
loader.src = 'data:image/svg+xml,' + encodeURIComponent(svg);
|
|
||||||
});
|
|
||||||
|
|
||||||
context.drawImage(loader, 0, 0, loader.width, loader.height);
|
|
||||||
|
|
||||||
const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: URL.createObjectURL(blob),
|
|
||||||
label: 'Download PNG',
|
|
||||||
filename: 'image.png',
|
|
||||||
type
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e); // eslint-disable-line no-console
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class App extends React.PureComponent {
|
class App extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -134,15 +86,7 @@ class App extends React.PureComponent {
|
|||||||
this.handleRender();
|
this.handleRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSvgMarkup = async ({ svg, width, height }) => {
|
handleSvg = imageDetails => this.setState({ imageDetails });
|
||||||
if (svg !== this.state.svg) {
|
|
||||||
this.setState({
|
|
||||||
svg,
|
|
||||||
svgLink: await createSvgLink({ svg }),
|
|
||||||
pngLink: await createPngLink({ svg, width, height })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
@ -154,8 +98,7 @@ class App extends React.PureComponent {
|
|||||||
loading,
|
loading,
|
||||||
loadingError,
|
loadingError,
|
||||||
Render,
|
Render,
|
||||||
svgLink,
|
imageDetails
|
||||||
pngLink
|
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const formProps = {
|
const formProps = {
|
||||||
@ -163,20 +106,19 @@ class App extends React.PureComponent {
|
|||||||
syntax,
|
syntax,
|
||||||
expr
|
expr
|
||||||
};
|
};
|
||||||
const actions = {
|
const actionProps = {
|
||||||
permalinkUrl,
|
imageDetails,
|
||||||
svgLink,
|
permalinkUrl
|
||||||
pngLink
|
|
||||||
};
|
};
|
||||||
const renderProps = {
|
const renderProps = {
|
||||||
onRender: this.handleSvgMarkup,
|
onRender: this.handleSvg,
|
||||||
syntax,
|
syntax,
|
||||||
expr
|
expr
|
||||||
};
|
};
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Form { ...formProps }>
|
<Form { ...formProps }>
|
||||||
<FormActions { ...actions } />
|
{ Render && <FormActions { ...actionProps } /> }
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
{ loading && <Loader /> }
|
{ loading && <Loader /> }
|
||||||
|
@ -74,7 +74,7 @@ Form.propTypes = {
|
|||||||
children: PropTypes.oneOfType([
|
children: PropTypes.oneOfType([
|
||||||
PropTypes.arrayOf(PropTypes.node),
|
PropTypes.arrayOf(PropTypes.node),
|
||||||
PropTypes.node
|
PropTypes.node
|
||||||
]).isRequired
|
])
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Form;
|
export default Form;
|
||||||
|
@ -6,7 +6,99 @@ import LinkIcon from 'react-feather/dist/icons/link';
|
|||||||
|
|
||||||
import style from './style.module.css';
|
import style from './style.module.css';
|
||||||
|
|
||||||
|
const createSvgLink = async ({ svg }) => {
|
||||||
|
try {
|
||||||
|
const type = 'image/svg+xml';
|
||||||
|
const blob = new Blob([svg], { type });
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: 'Download SVG',
|
||||||
|
filename: 'image.svg',
|
||||||
|
type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createPngLink = async ({ svg, width, height }) => {
|
||||||
|
try {
|
||||||
|
const type = 'image/png';
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
const loader = new Image();
|
||||||
|
|
||||||
|
loader.width = canvas.width = width * 2;
|
||||||
|
loader.height = canvas.height = height * 2;
|
||||||
|
|
||||||
|
await new Promise(resolve => {
|
||||||
|
loader.onload = resolve;
|
||||||
|
loader.src = 'data:image/svg+xml,' + encodeURIComponent(svg);
|
||||||
|
});
|
||||||
|
|
||||||
|
context.drawImage(loader, 0, 0, loader.width, loader.height);
|
||||||
|
|
||||||
|
const blob = await new Promise(resolve => canvas.toBlob(resolve, type));
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: URL.createObjectURL(blob),
|
||||||
|
label: 'Download PNG',
|
||||||
|
filename: 'image.png',
|
||||||
|
type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e); // eslint-disable-line no-console
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class FormActions extends React.PureComponent {
|
class FormActions extends React.PureComponent {
|
||||||
|
state = {}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { imageDetails } = this.props;
|
||||||
|
|
||||||
|
if (!imageDetails) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageDetails.svg) {
|
||||||
|
this.generateDownloadLinks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
const { imageDetails } = this.props;
|
||||||
|
const { imageDetails: prevImageDetails } = prevProps;
|
||||||
|
|
||||||
|
if (!imageDetails) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prevImageDetails) {
|
||||||
|
this.generateDownloadLinks();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageDetails.svg !== prevImageDetails.svg
|
||||||
|
|| imageDetails.width !== prevImageDetails.width
|
||||||
|
|| imageDetails.height !== prevImageDetails.height) {
|
||||||
|
this.generateDownloadLinks();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateDownloadLinks() {
|
||||||
|
const { imageDetails: { svg, width, height } } = this.props;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
svgLink: await createSvgLink({ svg }),
|
||||||
|
pngLink: await createPngLink({ svg, width, height })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
downloadLink({ url, filename, type, label }) {
|
downloadLink({ url, filename, type, label }) {
|
||||||
return <li>
|
return <li>
|
||||||
<a href={ url } download={ filename } type={ type }>
|
<a href={ url } download={ filename } type={ type }>
|
||||||
@ -17,10 +109,12 @@ class FormActions extends React.PureComponent {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
permalinkUrl,
|
permalinkUrl
|
||||||
|
} = this.props;
|
||||||
|
const {
|
||||||
svgLink,
|
svgLink,
|
||||||
pngLink
|
pngLink
|
||||||
} = this.props;
|
} = this.state;
|
||||||
|
|
||||||
return <ul className={ style.actions }>
|
return <ul className={ style.actions }>
|
||||||
{ pngLink && this.downloadLink(pngLink) }
|
{ pngLink && this.downloadLink(pngLink) }
|
||||||
@ -34,8 +128,11 @@ class FormActions extends React.PureComponent {
|
|||||||
|
|
||||||
FormActions.propTypes = {
|
FormActions.propTypes = {
|
||||||
permalinkUrl: PropTypes.string,
|
permalinkUrl: PropTypes.string,
|
||||||
svgLink: PropTypes.object,
|
imageDetails: PropTypes.shape({
|
||||||
pngLink: PropTypes.object
|
svg: PropTypes.string,
|
||||||
|
width: PropTypes.number,
|
||||||
|
height: PropTypes.number
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FormActions;
|
export default FormActions;
|
||||||
|
@ -16,8 +16,8 @@ class Render extends React.PureComponent {
|
|||||||
const svg = this.svgContainer.current.querySelector('svg');
|
const svg = this.svgContainer.current.querySelector('svg');
|
||||||
this.props.onRender({
|
this.props.onRender({
|
||||||
svg: svg.outerHTML,
|
svg: svg.outerHTML,
|
||||||
width: svg.getAttribute('width'),
|
width: Number(svg.getAttribute('width')),
|
||||||
height: svg.getAttribute('height')
|
height: Number(svg.getAttribute('height'))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user