2022-08-17 13:11:22 -05:00
|
|
|
import { useState } from 'react'
|
2022-08-16 00:33:35 -05:00
|
|
|
import { useTranslation } from 'next-i18next'
|
|
|
|
import Popout from 'shared/components/popout'
|
|
|
|
import WebLink from 'shared/components/web-link'
|
2022-08-21 10:26:35 +01:00
|
|
|
import Worker from 'web-worker';
|
|
|
|
import fileSaver from 'file-saver'
|
2022-08-16 00:33:35 -05:00
|
|
|
import theme from '@freesewing/plugin-theme'
|
|
|
|
import {pagesPlugin} from '../layout/print/plugin'
|
2022-08-24 00:23:45 -05:00
|
|
|
import {utils} from '@freesewing/core'
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
export const exports = {
|
|
|
|
exportForPrinting: ['a4', 'a3', 'a2', 'a1', 'a0', 'letter', 'tabloid'],
|
|
|
|
exportForEditing: ['svg', 'pdf'],
|
|
|
|
exportAsData: ['json', 'yaml', 'github gist'],
|
|
|
|
}
|
|
|
|
|
|
|
|
export const defaultPdfSettings = {
|
2022-08-17 00:34:25 -05:00
|
|
|
size: 'a4',
|
2022-08-16 00:33:35 -05:00
|
|
|
orientation: 'portrait',
|
|
|
|
margin: 10,
|
|
|
|
coverPage: true
|
|
|
|
}
|
|
|
|
|
2022-08-24 00:23:45 -05:00
|
|
|
export const handleExport = async(format, gist, design, t, app, onComplete, onError) => {
|
2022-08-21 10:26:35 +01:00
|
|
|
app.startLoading();
|
2022-08-17 13:11:22 -05:00
|
|
|
|
2022-08-21 10:26:35 +01:00
|
|
|
const worker = new Worker(new URL('./export_worker.js', import.meta.url), {type: module});
|
2022-08-17 13:11:22 -05:00
|
|
|
|
2022-08-21 10:26:35 +01:00
|
|
|
worker.addEventListener('message', e => {
|
2022-08-24 00:23:45 -05:00
|
|
|
if (e.data.success) {
|
|
|
|
if (e.data.blob) {
|
|
|
|
const fileType = exports.exportForPrinting.indexOf(format) === -1 ? format : 'pdf'
|
|
|
|
fileSaver.saveAs(e.data.blob, `freesewing-${gist.design || 'gist'}.${fileType}`)
|
|
|
|
}
|
|
|
|
onComplete && onComplete(e)
|
|
|
|
} else {
|
|
|
|
//FIXME notify the user of the error
|
|
|
|
console.log(e.data.error)
|
|
|
|
onError && onError(e)
|
2022-08-16 00:33:35 -05:00
|
|
|
}
|
2022-08-21 10:26:35 +01:00
|
|
|
app.stopLoading()
|
|
|
|
})
|
2022-08-16 00:33:35 -05:00
|
|
|
|
2022-08-21 10:26:35 +01:00
|
|
|
let svg = ''
|
2022-08-17 13:11:22 -05:00
|
|
|
// pdf settings
|
2022-08-16 00:33:35 -05:00
|
|
|
const settings = {
|
|
|
|
...defaultPdfSettings,
|
|
|
|
...(gist._state.layout?.forPrinting?.page || {})
|
|
|
|
}
|
2022-08-21 10:26:35 +01:00
|
|
|
const workerArgs = {format, gist, settings}
|
|
|
|
|
|
|
|
if (exports.exportAsData.indexOf(format) === -1) {
|
2022-08-23 11:08:40 -05:00
|
|
|
gist.embed=false
|
2022-08-21 10:26:35 +01:00
|
|
|
// make a pattern instance for export rendering
|
|
|
|
const layout = gist.layouts?.printingLayout || gist.layout || true
|
|
|
|
let pattern = new design({...gist, layout})
|
|
|
|
|
|
|
|
|
|
|
|
// add the theme and translation to the pattern
|
|
|
|
pattern.use(theme, {stripped: format !== 'svg'})
|
|
|
|
pattern.use({
|
|
|
|
hooks: {
|
|
|
|
insertText: (locale, text, {t}) => t(text)
|
|
|
|
}
|
|
|
|
},{t})
|
|
|
|
|
|
|
|
// a specified size should override the gist one
|
|
|
|
if (format !== 'pdf') {
|
|
|
|
settings.size = format
|
|
|
|
}
|
2022-08-16 00:33:35 -05:00
|
|
|
|
2022-08-21 10:26:35 +01:00
|
|
|
try {
|
|
|
|
// add pages to pdf exports
|
|
|
|
if (format !== 'svg') {
|
|
|
|
pattern.use(pagesPlugin({
|
|
|
|
...settings,
|
|
|
|
printStyle: true,
|
|
|
|
renderBlanks: false,
|
|
|
|
setPatternSize: true
|
|
|
|
}))
|
2022-08-24 00:23:45 -05:00
|
|
|
|
|
|
|
workerArgs.strings = {
|
|
|
|
design: utils.capitalize(gist.design),
|
|
|
|
tagline: t('common:sloganCome') + '. ' + t('common:sloganStay'),
|
|
|
|
url: window.location.href
|
|
|
|
}
|
2022-08-21 10:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pattern.draft();
|
|
|
|
svg = pattern.render()
|
|
|
|
workerArgs.svg = svg
|
|
|
|
if (pattern.parts.pages) {
|
|
|
|
workerArgs.pages = pattern.parts.pages.pages
|
|
|
|
}
|
|
|
|
} catch(err) {
|
|
|
|
console.log(err)
|
|
|
|
app.stopLoading();
|
2022-08-16 00:33:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-21 10:26:35 +01:00
|
|
|
worker.postMessage(workerArgs)
|
2022-08-16 00:33:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const ExportDraft = ({ gist, design, app }) => {
|
|
|
|
|
|
|
|
const [link, setLink] = useState(false)
|
|
|
|
const [format, setFormat] = useState(false)
|
|
|
|
|
|
|
|
const { t } = useTranslation(['app'])
|
2022-08-21 10:26:35 +01:00
|
|
|
const doExport = (format) => {
|
|
|
|
setLink(false)
|
|
|
|
setFormat(format)
|
|
|
|
handleExport(format, gist, design, t, app, (e) => {
|
|
|
|
if (e.data.link) {setLink(e.data.link)}
|
|
|
|
})
|
|
|
|
}
|
2022-08-16 00:33:35 -05:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="max-w-screen-xl m-auto">
|
|
|
|
<h2>{t('export')}</h2>
|
|
|
|
<p className="text-lg sm:text-xl">{t('exportPattern-txt')}</p>
|
|
|
|
{link && (
|
|
|
|
<Popout link compact>
|
|
|
|
<span className="font-bold mr-4 uppercase text-sm">
|
|
|
|
{format}:
|
|
|
|
</span>
|
|
|
|
<WebLink href={link} txt={link} />
|
|
|
|
</Popout>
|
|
|
|
)}
|
|
|
|
<div className="flex flex-row flex-wrap gap-8">
|
|
|
|
{Object.keys(exports).map(type => (
|
|
|
|
<div key={type} className="flex flex-col gap-2 w-full sm:w-auto">
|
|
|
|
<h4>{t(type)}</h4>
|
|
|
|
{exports[type].map(format => (
|
|
|
|
<button key={format}
|
|
|
|
className="btn btn-primary"
|
2022-08-21 10:26:35 +01:00
|
|
|
onClick={() => doExport(format)}
|
2022-08-16 00:33:35 -05:00
|
|
|
>
|
|
|
|
{type === 'exportForPrinting' ? `${format} pdf` : format }
|
|
|
|
</button>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ExportDraft
|