Skip to content

Commit

Permalink
Add more loaders so we can track the progress better
Browse files Browse the repository at this point in the history
  • Loading branch information
jordisala1991 committed Jun 6, 2024
1 parent 7868898 commit 8fea3fb
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 103 deletions.
4 changes: 4 additions & 0 deletions plugin-src/RemoteComponentLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class RemoteComponentsLibrary {
public remaining(): number {
return this.queue.length;
}

public total(): number {
return Object.keys(this.components).length;
}
}

export const remoteComponentLibrary = new RemoteComponentsLibrary();
60 changes: 46 additions & 14 deletions plugin-src/transformers/transformDocumentNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,52 @@ import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
import { translateRemoteChildren } from '@plugin/translators';
import { sleep } from '@plugin/utils';

import { PenpotPage } from '@ui/lib/types/penpotPage';
import { PenpotDocument } from '@ui/types';

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 = [];
let currentPage = 1;

figma.ui.postMessage({
type: 'PROGRESS_TOTAL_PAGES',
type: 'PROGRESS_TOTAL_ITEMS',
data: node.children.length
});

Expand All @@ -23,34 +59,30 @@ export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotD
children.push(await transformPageNode(page));

figma.ui.postMessage({
type: 'PROGRESS_PROCESSED_PAGES',
type: 'PROGRESS_PROCESSED_ITEMS',
data: currentPage++
});

await sleep(0);
}

return children;
};

export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
const children = await processPages(node);

if (remoteComponentLibrary.remaining() > 0) {
children.push({
name: 'External Components',
children: await translateRemoteChildren()
});
}

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 {
name: node.name,
children,
components: componentsLibrary.all(),
images
images: await downloadImages()
};
};
2 changes: 1 addition & 1 deletion plugin-src/transformers/transformSceneNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const transformSceneNode = async (
let penpotNode: PenpotNode | undefined;

figma.ui.postMessage({
type: 'PROGRESS_NODE',
type: 'PROGRESS_CURRENT_ITEM',
data: node.name
});

Expand Down
16 changes: 16 additions & 0 deletions plugin-src/translators/translateChildren.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,30 @@ export const translateChildren = async (

export const translateRemoteChildren = async (): Promise<PenpotNode[]> => {
const transformedChildren: PenpotNode[] = [];
let currentRemote = 1;

figma.ui.postMessage({
type: 'PROGRESS_STEP',
data: 'remote'
});

while (remoteComponentLibrary.remaining() > 0) {
figma.ui.postMessage({
type: 'PROGRESS_TOTAL_ITEMS',
data: remoteComponentLibrary.total()
});

const child = remoteComponentLibrary.next();

const penpotNode = await transformSceneNode(child);

if (penpotNode) transformedChildren.push(penpotNode);

figma.ui.postMessage({
type: 'PROGRESS_PROCESSED_ITEMS',
data: currentRemote++
});

await sleep(0);
}

Expand Down
87 changes: 65 additions & 22 deletions ui-src/components/ExporterProgress.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
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';

export const ExporterProgress = () => {
const { currentNode, totalPages, processedPages, downloading } = useFigmaContext();
type Messages = {
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) => {
if (text.length <= maxChars) {
Expand All @@ -15,29 +42,45 @@ export const ExporterProgress = () => {
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 (
<Stack space="small" horizontalAlign="center">
<LoadingIndicator />
<span style={{ textAlign: 'center' }}>
{!downloading ? (
<>
{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...
</>
)}
<StepProgress />
</span>
</Stack>
);
Expand Down
2 changes: 2 additions & 0 deletions ui-src/context/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './createGenericContext';
export * from './FigmaContext';
export * from './messages';
export * from './useFigma';
58 changes: 58 additions & 0 deletions ui-src/context/messages.ts
Original file line number Diff line number Diff line change
@@ -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
}
})
);
};
Loading

0 comments on commit 8fea3fb

Please sign in to comment.