mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 05:33:02 -05:00
Add more loaders so we can track the progress better (#145)
* Add more loaders so we can track the progress better * fix lint
This commit is contained in:
parent
78688988d6
commit
1f8f4bf539
10 changed files with 271 additions and 103 deletions
|
@ -25,6 +25,10 @@ class RemoteComponentsLibrary {
|
||||||
public remaining(): number {
|
public remaining(): number {
|
||||||
return this.queue.length;
|
return this.queue.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public total(): number {
|
||||||
|
return Object.keys(this.components).length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const remoteComponentLibrary = new RemoteComponentsLibrary();
|
export const remoteComponentLibrary = new RemoteComponentsLibrary();
|
||||||
|
|
|
@ -4,16 +4,52 @@ import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
||||||
import { translateRemoteChildren } from '@plugin/translators';
|
import { translateRemoteChildren } from '@plugin/translators';
|
||||||
import { sleep } from '@plugin/utils';
|
import { sleep } from '@plugin/utils';
|
||||||
|
|
||||||
|
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||||
import { PenpotDocument } from '@ui/types';
|
import { PenpotDocument } from '@ui/types';
|
||||||
|
|
||||||
import { transformPageNode } from '.';
|
import { transformPageNode } from '.';
|
||||||
|
|
||||||
export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
|
const downloadImages = async (): Promise<Record<string, Uint8Array>> => {
|
||||||
|
const imageToDownload = Object.entries(imagesLibrary.all());
|
||||||
|
const images: Record<string, Uint8Array> = {};
|
||||||
|
let currentImage = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'images'
|
||||||
|
});
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: imageToDownload.length
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [key, image] of imageToDownload) {
|
||||||
|
const bytes = await image?.getBytesAsync();
|
||||||
|
|
||||||
|
if (bytes) {
|
||||||
|
images[key] = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentImage++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(20);
|
||||||
|
|
||||||
|
return images;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processPages = async (node: DocumentNode): Promise<PenpotPage[]> => {
|
||||||
const children = [];
|
const children = [];
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
|
|
||||||
figma.ui.postMessage({
|
figma.ui.postMessage({
|
||||||
type: 'PROGRESS_TOTAL_PAGES',
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
data: node.children.length
|
data: node.children.length
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,13 +59,19 @@ export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotD
|
||||||
children.push(await transformPageNode(page));
|
children.push(await transformPageNode(page));
|
||||||
|
|
||||||
figma.ui.postMessage({
|
figma.ui.postMessage({
|
||||||
type: 'PROGRESS_PROCESSED_PAGES',
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
data: currentPage++
|
data: currentPage++
|
||||||
});
|
});
|
||||||
|
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
|
||||||
|
const children = await processPages(node);
|
||||||
|
|
||||||
if (remoteComponentLibrary.remaining() > 0) {
|
if (remoteComponentLibrary.remaining() > 0) {
|
||||||
children.push({
|
children.push({
|
||||||
name: 'External Components',
|
name: 'External Components',
|
||||||
|
@ -37,20 +79,10 @@ export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotD
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const images: Record<string, Uint8Array> = {};
|
|
||||||
|
|
||||||
for (const [key, image] of Object.entries(imagesLibrary.all())) {
|
|
||||||
const bytes = await image?.getBytesAsync();
|
|
||||||
|
|
||||||
if (!bytes) continue;
|
|
||||||
|
|
||||||
images[key] = bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: node.name,
|
name: node.name,
|
||||||
children,
|
children,
|
||||||
components: componentsLibrary.all(),
|
components: componentsLibrary.all(),
|
||||||
images
|
images: await downloadImages()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ export const transformSceneNode = async (
|
||||||
let penpotNode: PenpotNode | undefined;
|
let penpotNode: PenpotNode | undefined;
|
||||||
|
|
||||||
figma.ui.postMessage({
|
figma.ui.postMessage({
|
||||||
type: 'PROGRESS_NODE',
|
type: 'PROGRESS_CURRENT_ITEM',
|
||||||
data: node.name
|
data: node.name
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,30 @@ export const translateChildren = async (
|
||||||
|
|
||||||
export const translateRemoteChildren = async (): Promise<PenpotNode[]> => {
|
export const translateRemoteChildren = async (): Promise<PenpotNode[]> => {
|
||||||
const transformedChildren: PenpotNode[] = [];
|
const transformedChildren: PenpotNode[] = [];
|
||||||
|
let currentRemote = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'remote'
|
||||||
|
});
|
||||||
|
|
||||||
while (remoteComponentLibrary.remaining() > 0) {
|
while (remoteComponentLibrary.remaining() > 0) {
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: remoteComponentLibrary.total()
|
||||||
|
});
|
||||||
|
|
||||||
const child = remoteComponentLibrary.next();
|
const child = remoteComponentLibrary.next();
|
||||||
|
|
||||||
const penpotNode = await transformSceneNode(child);
|
const penpotNode = await transformSceneNode(child);
|
||||||
|
|
||||||
if (penpotNode) transformedChildren.push(penpotNode);
|
if (penpotNode) transformedChildren.push(penpotNode);
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentRemote++
|
||||||
|
});
|
||||||
|
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,38 @@
|
||||||
import { LoadingIndicator } from '@create-figma-plugin/ui';
|
import { LoadingIndicator } from '@create-figma-plugin/ui';
|
||||||
|
import { JSX } from 'react';
|
||||||
|
|
||||||
import { useFigmaContext } from '@ui/context';
|
import { Steps, useFigmaContext } from '@ui/context';
|
||||||
|
|
||||||
import { Stack } from './Stack';
|
import { Stack } from './Stack';
|
||||||
|
|
||||||
export const ExporterProgress = () => {
|
type Messages = {
|
||||||
const { currentNode, totalPages, processedPages, downloading } = useFigmaContext();
|
total: string;
|
||||||
|
current?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stepMessages: Record<Steps, Messages> = {
|
||||||
|
processing: {
|
||||||
|
total: 'pages processed 💪',
|
||||||
|
current: 'Currently processing layer'
|
||||||
|
},
|
||||||
|
remote: {
|
||||||
|
total: 'remote components processed 📦',
|
||||||
|
current: 'Currently processing layer'
|
||||||
|
},
|
||||||
|
images: {
|
||||||
|
total: 'images downloaded 📸'
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
total: 'images optimized 📸'
|
||||||
|
},
|
||||||
|
downloading: {
|
||||||
|
total: 'Generating Penpot file 🚀',
|
||||||
|
current: 'Please wait, this process might take a while...'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const StepProgress = (): JSX.Element | null => {
|
||||||
|
const { currentItem, totalItems, processedItems, step } = useFigmaContext();
|
||||||
|
|
||||||
const truncateText = (text: string, maxChars: number) => {
|
const truncateText = (text: string, maxChars: number) => {
|
||||||
if (text.length <= maxChars) {
|
if (text.length <= maxChars) {
|
||||||
|
@ -15,29 +42,45 @@ export const ExporterProgress = () => {
|
||||||
return text.slice(0, maxChars) + '...';
|
return text.slice(0, maxChars) + '...';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!step) return null;
|
||||||
|
|
||||||
|
const currentText = stepMessages[step].current;
|
||||||
|
|
||||||
|
switch (step) {
|
||||||
|
case 'processing':
|
||||||
|
case 'remote':
|
||||||
|
case 'images':
|
||||||
|
case 'optimization':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{processedItems} of {totalItems} {stepMessages[step].total}
|
||||||
|
{currentItem && currentText ? (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
{currentText}
|
||||||
|
<br />
|
||||||
|
{'“' + truncateText(currentItem, 35) + '”'}
|
||||||
|
</>
|
||||||
|
) : undefined}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
case 'downloading':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{stepMessages[step].total}
|
||||||
|
<br />
|
||||||
|
{currentText}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ExporterProgress = () => {
|
||||||
return (
|
return (
|
||||||
<Stack space="small" horizontalAlign="center">
|
<Stack space="small" horizontalAlign="center">
|
||||||
<LoadingIndicator />
|
<LoadingIndicator />
|
||||||
<span style={{ textAlign: 'center' }}>
|
<span style={{ textAlign: 'center' }}>
|
||||||
{!downloading ? (
|
<StepProgress />
|
||||||
<>
|
|
||||||
{processedPages} of {totalPages} pages exported 💪
|
|
||||||
{currentNode ? (
|
|
||||||
<>
|
|
||||||
<br />
|
|
||||||
Currently exporting layer
|
|
||||||
<br />
|
|
||||||
{'“' + truncateText(currentNode, 35) + '”'}
|
|
||||||
</>
|
|
||||||
) : undefined}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
Generating Penpot file 🚀
|
|
||||||
<br />
|
|
||||||
Please wait, this process might take a while...
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
export * from './createGenericContext';
|
export * from './createGenericContext';
|
||||||
export * from './FigmaContext';
|
export * from './FigmaContext';
|
||||||
|
export * from './messages';
|
||||||
|
export * from './useFigma';
|
||||||
|
|
58
ui-src/context/messages.ts
Normal file
58
ui-src/context/messages.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import { PenpotDocument } from '@ui/types';
|
||||||
|
|
||||||
|
import { Steps } from '.';
|
||||||
|
|
||||||
|
export type MessageData = { pluginMessage?: PluginMessage };
|
||||||
|
|
||||||
|
type PluginMessage =
|
||||||
|
| PenpotDocumentMessage
|
||||||
|
| CustomFontsMessage
|
||||||
|
| ChangesDetectedMessage
|
||||||
|
| ProgressStepMessage
|
||||||
|
| ProgressCurrentItemMessage
|
||||||
|
| ProgressTotalItemsMessage
|
||||||
|
| ProgressProcessedItemsMessage;
|
||||||
|
|
||||||
|
type PenpotDocumentMessage = {
|
||||||
|
type: 'PENPOT_DOCUMENT';
|
||||||
|
data: PenpotDocument;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CustomFontsMessage = {
|
||||||
|
type: 'CUSTOM_FONTS';
|
||||||
|
data: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type ChangesDetectedMessage = {
|
||||||
|
type: 'CHANGES_DETECTED';
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProgressStepMessage = {
|
||||||
|
type: 'PROGRESS_STEP';
|
||||||
|
data: Steps;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProgressCurrentItemMessage = {
|
||||||
|
type: 'PROGRESS_CURRENT_ITEM';
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProgressTotalItemsMessage = {
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS';
|
||||||
|
data: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProgressProcessedItemsMessage = {
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS';
|
||||||
|
data: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendMessage = (pluginMessage: PluginMessage) => {
|
||||||
|
window.dispatchEvent(
|
||||||
|
new MessageEvent<MessageData>('message', {
|
||||||
|
data: {
|
||||||
|
pluginMessage
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
|
@ -2,89 +2,54 @@ import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { FormValues } from '@ui/components/ExportForm';
|
import { FormValues } from '@ui/components/ExportForm';
|
||||||
import { parse } from '@ui/parser';
|
import { parse } from '@ui/parser';
|
||||||
import { PenpotDocument } from '@ui/types';
|
|
||||||
|
import { MessageData } from '.';
|
||||||
|
|
||||||
export type UseFigmaHook = {
|
export type UseFigmaHook = {
|
||||||
missingFonts: string[] | undefined;
|
missingFonts: string[] | undefined;
|
||||||
needsReload: boolean;
|
needsReload: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
exporting: boolean;
|
exporting: boolean;
|
||||||
downloading: boolean;
|
step: Steps | undefined;
|
||||||
currentNode: string | undefined;
|
currentItem: string | undefined;
|
||||||
totalPages: number | undefined;
|
totalItems: number;
|
||||||
processedPages: number | undefined;
|
processedItems: number;
|
||||||
reload: () => void;
|
reload: () => void;
|
||||||
cancel: () => void;
|
cancel: () => void;
|
||||||
exportPenpot: (data: FormValues) => void;
|
exportPenpot: (data: FormValues) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PluginMessage =
|
export type Steps = 'processing' | 'remote' | 'images' | 'optimization' | 'downloading';
|
||||||
| PenpotDocumentMessage
|
|
||||||
| CustomFontsMessage
|
|
||||||
| ChangesDetectedMessage
|
|
||||||
| ProgressNodeMessage
|
|
||||||
| ProgressTotalPagesMessage
|
|
||||||
| ProgressProcessedPagesMessage;
|
|
||||||
|
|
||||||
type PenpotDocumentMessage = {
|
|
||||||
type: 'PENPOT_DOCUMENT';
|
|
||||||
data: PenpotDocument;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CustomFontsMessage = {
|
|
||||||
type: 'CUSTOM_FONTS';
|
|
||||||
data: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type ChangesDetectedMessage = {
|
|
||||||
type: 'CHANGES_DETECTED';
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProgressNodeMessage = {
|
|
||||||
type: 'PROGRESS_NODE';
|
|
||||||
data: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProgressTotalPagesMessage = {
|
|
||||||
type: 'PROGRESS_TOTAL_PAGES';
|
|
||||||
data: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProgressProcessedPagesMessage = {
|
|
||||||
type: 'PROGRESS_PROCESSED_PAGES';
|
|
||||||
data: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFigma = (): UseFigmaHook => {
|
export const useFigma = (): UseFigmaHook => {
|
||||||
const [missingFonts, setMissingFonts] = useState<string[]>();
|
const [missingFonts, setMissingFonts] = useState<string[]>();
|
||||||
const [needsReload, setNeedsReload] = useState(false);
|
const [needsReload, setNeedsReload] = useState(false);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [exporting, setExporting] = useState(false);
|
const [exporting, setExporting] = useState(false);
|
||||||
const [downloading, setDownloading] = useState(false);
|
|
||||||
const [currentNode, setCurrentNode] = useState<string | undefined>();
|
const [step, setStep] = useState<Steps>();
|
||||||
const [totalPages, setTotalPages] = useState<number | undefined>();
|
const [currentItem, setCurrentItem] = useState<string | undefined>();
|
||||||
const [processedPages, setProcessedPages] = useState<number | undefined>();
|
const [totalItems, setTotalItems] = useState<number>(0);
|
||||||
|
const [processedItems, setProcessedItems] = useState<number>(0);
|
||||||
|
|
||||||
const postMessage = (type: string, data?: unknown) => {
|
const postMessage = (type: string, data?: unknown) => {
|
||||||
parent.postMessage({ pluginMessage: { type, data } }, '*');
|
parent.postMessage({ pluginMessage: { type, data } }, '*');
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMessage = async (event: MessageEvent<{ pluginMessage?: PluginMessage }>) => {
|
const onMessage = async (event: MessageEvent<MessageData>) => {
|
||||||
if (!event.data.pluginMessage) return;
|
if (!event.data.pluginMessage) return;
|
||||||
|
|
||||||
const { pluginMessage } = event.data;
|
const { pluginMessage } = event.data;
|
||||||
|
|
||||||
switch (pluginMessage.type) {
|
switch (pluginMessage.type) {
|
||||||
case 'PENPOT_DOCUMENT': {
|
case 'PENPOT_DOCUMENT': {
|
||||||
setDownloading(true);
|
|
||||||
|
|
||||||
const file = await parse(pluginMessage.data);
|
const file = await parse(pluginMessage.data);
|
||||||
const blob = await file.export();
|
const blob = await file.export();
|
||||||
|
|
||||||
download(blob, `${pluginMessage.data.name}.zip`);
|
download(blob, `${pluginMessage.data.name}.zip`);
|
||||||
|
|
||||||
setExporting(false);
|
setExporting(false);
|
||||||
setDownloading(false);
|
setStep(undefined);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -98,17 +63,21 @@ export const useFigma = (): UseFigmaHook => {
|
||||||
setNeedsReload(true);
|
setNeedsReload(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'PROGRESS_NODE': {
|
case 'PROGRESS_STEP': {
|
||||||
setCurrentNode(pluginMessage.data);
|
setStep(pluginMessage.data);
|
||||||
|
setProcessedItems(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'PROGRESS_TOTAL_PAGES': {
|
case 'PROGRESS_CURRENT_ITEM': {
|
||||||
setTotalPages(pluginMessage.data);
|
setCurrentItem(pluginMessage.data);
|
||||||
setProcessedPages(0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'PROGRESS_PROCESSED_PAGES': {
|
case 'PROGRESS_TOTAL_ITEMS': {
|
||||||
setProcessedPages(pluginMessage.data);
|
setTotalItems(pluginMessage.data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'PROGRESS_PROCESSED_ITEMS': {
|
||||||
|
setProcessedItems(pluginMessage.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +104,8 @@ export const useFigma = (): UseFigmaHook => {
|
||||||
|
|
||||||
const exportPenpot = (data: FormValues) => {
|
const exportPenpot = (data: FormValues) => {
|
||||||
setExporting(true);
|
setExporting(true);
|
||||||
|
setStep('processing');
|
||||||
|
setProcessedItems(0);
|
||||||
|
|
||||||
postMessage('export', data);
|
postMessage('export', data);
|
||||||
};
|
};
|
||||||
|
@ -154,10 +125,10 @@ export const useFigma = (): UseFigmaHook => {
|
||||||
needsReload,
|
needsReload,
|
||||||
loading,
|
loading,
|
||||||
exporting,
|
exporting,
|
||||||
downloading,
|
step,
|
||||||
currentNode,
|
currentItem,
|
||||||
totalPages,
|
totalItems,
|
||||||
processedPages,
|
processedItems,
|
||||||
reload,
|
reload,
|
||||||
cancel,
|
cancel,
|
||||||
exportPenpot
|
exportPenpot
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
||||||
|
import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||||
|
|
||||||
import { createItems } from '.';
|
import { createItems } from '.';
|
||||||
|
|
||||||
export const createPage = (file: PenpotFile, { name, options, children = [] }: PenpotPage) => {
|
export const createPage = async (
|
||||||
|
file: PenpotFile,
|
||||||
|
{ name, options, children = [] }: PenpotPage
|
||||||
|
) => {
|
||||||
file.addPage(name, options);
|
file.addPage(name, options);
|
||||||
|
|
||||||
createItems(file, children);
|
createItems(file, children);
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
|
||||||
file.closePage();
|
file.closePage();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
||||||
|
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
||||||
|
import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
|
import { sendMessage } from '@ui/context';
|
||||||
import { createFile } from '@ui/lib/penpot';
|
import { createFile } from '@ui/lib/penpot';
|
||||||
import { createComponentLibrary, createPage } from '@ui/parser/creators';
|
import { createComponentLibrary, createPage } from '@ui/parser/creators';
|
||||||
import { uiComponents, uiImages } from '@ui/parser/libraries';
|
import { uiComponents, uiImages } from '@ui/parser/libraries';
|
||||||
|
@ -7,14 +10,45 @@ import { PenpotDocument } from '@ui/types';
|
||||||
|
|
||||||
import { idLibrary, parseImage } from '.';
|
import { idLibrary, parseImage } from '.';
|
||||||
|
|
||||||
|
const optimizeImages = async (images: Record<string, Uint8Array>) => {
|
||||||
|
const imagesToOptimize = Object.entries(images);
|
||||||
|
let imagesOptimized = 1;
|
||||||
|
|
||||||
|
sendMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'optimization'
|
||||||
|
});
|
||||||
|
|
||||||
|
sendMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: imagesToOptimize.length
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [key, bytes] of imagesToOptimize) {
|
||||||
|
if (bytes) {
|
||||||
|
uiImages.register(key, await parseImage(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: imagesOptimized++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const parse = async ({ name, children = [], components, images }: PenpotDocument) => {
|
export const parse = async ({ name, children = [], components, images }: PenpotDocument) => {
|
||||||
componentsLibrary.init(components);
|
componentsLibrary.init(components);
|
||||||
|
|
||||||
for (const [key, bytes] of Object.entries(images)) {
|
await optimizeImages(images);
|
||||||
if (!bytes) continue;
|
|
||||||
|
|
||||||
uiImages.register(key, await parseImage(bytes));
|
sendMessage({
|
||||||
}
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'downloading'
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(20);
|
||||||
|
|
||||||
uiComponents.init();
|
uiComponents.init();
|
||||||
idLibrary.init();
|
idLibrary.init();
|
||||||
|
@ -22,7 +56,7 @@ export const parse = async ({ name, children = [], components, images }: PenpotD
|
||||||
const file = createFile(name);
|
const file = createFile(name);
|
||||||
|
|
||||||
for (const page of children) {
|
for (const page of children) {
|
||||||
createPage(file, page);
|
await createPage(file, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
createComponentLibrary(file);
|
createComponentLibrary(file);
|
||||||
|
|
Loading…
Reference in a new issue