@@ -0,0 +1,62 @@
1+import React, { useRef, useState } from 'react';
2+import * as ob from 'urbit-ob';
3+import { saveAs } from 'file-saver';
4+import { sigil, stringRenderer } from 'urbit-sigil-js';
5+
6+import { dataURItoBlob, loadImg, initCanvas } from 'lib/SigilDownloader';
7+
8+import WithTooltip from 'components/WithTooltip';
9+
10+export default function SigilDownloader({ point, children }) {
11+ const [downloaded, setDownloaded] = useState(false);
12+ const downloadSigil = () => {
13+ const patp = ob.patp(point);
14+
15+ const _size = 1024 / window.devicePixelRatio;
16+ const pngSize = 1024;
17+
18+ const DATA_URI_PREFIX = 'data:image/svg+xml;base64,';
19+
20+ // initialize canvas element
21+ const canvas = initCanvas(canvasRef.current, { x: _size, y: _size });
22+ const ctx = canvas.getContext('2d');
23+
24+ // make sigil svg and encoded into base64
25+ const svg = sigil({
26+ patp,
27+ full: true,
28+ renderer: stringRenderer,
29+ size: _size,
30+ colors: ['#FFFFFF', '#000000'],
31+ margin: (54 / 256) * _size,
32+ });
33+
34+ // FF rendering hack
35+ const svgDocument = new DOMParser().parseFromString(svg, 'image/svg+xml');
36+ svgDocument.documentElement.width.baseVal.valueAsString = `${pngSize}px`;
37+ svgDocument.documentElement.height.baseVal.valueAsString = `${pngSize}px`;
38+ const svgText = new XMLSerializer().serializeToString(svgDocument);
39+ const svg64 = btoa(svgText);
40+
41+ const pngTask = loadImg(DATA_URI_PREFIX + svg64, _size, _size).then(img => {
42+ ctx.drawImage(img, 0, 0, _size, _size);
43+ const png = dataURItoBlob(canvas.toDataURL('image/png'));
44+ saveAs(png, `${patp}.png`);
45+ ctx.clearRect(0, 0, pngSize, pngSize);
46+
47+ setDownloaded(true);
48+ });
49+
50+ return pngTask;
51+ };
52+ const canvasRef = useRef(null);
53+
54+ return (
55+ <WithTooltip content={downloaded ? 'Downloaded!' : 'Download'}>
56+ {React.Children.map(children, child =>
57+ React.cloneElement(child, { onClick: downloadSigil })
58+ )}
59+ <canvas style={{ display: 'none' }} ref={canvasRef} />
60+ </WithTooltip>
61+ );
62+}