Skip to content

Commit

Permalink
copy manager - enable dynamic page loading
Browse files Browse the repository at this point in the history
  • Loading branch information
origami-z committed Jun 11, 2024
1 parent 16a46b2 commit 3ee7339
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 39 deletions.
3 changes: 2 additions & 1 deletion packages/copy-manager/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
"https://fonts.gstatic.com",
"https://fonts.googleapis.com"
]
}
},
"documentAccess": "dynamic-page"
}
3 changes: 2 additions & 1 deletion packages/copy-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"build:main": "esbuild plugin-src/code.ts --bundle --outfile=dist/code.js --target=es6",
"build:ui": "npx vite build --minify esbuild --emptyOutDir=false",
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"",
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'"
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'",
"lint:plugin": "eslint ./plugin-src"
},
"repository": {
"type": "git",
Expand Down
28 changes: 28 additions & 0 deletions packages/copy-manager/plugin-src/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-env node */
module.exports = {
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@figma/figma-plugins/recommended",
],
rules: {
"@typescript-eslint/no-explicit-any": 1,
"@typescript-eslint/no-floating-promises": ["error"],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn", // or "error"
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
},
ignorePatterns: [".eslintrc.cjs"],
parserOptions: {
project: ["./tsconfig.json", "./__tests__/tsconfig.json"],
tsconfigRootDir: __dirname, // important option
},
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
};
20 changes: 10 additions & 10 deletions packages/copy-manager/plugin-src/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ figma.ui.onmessage = async (msg: PostToFigmaMessage) => {
persistDataInFigma();
}
} else if (msg.type === "focus-node") {
focusNode(msg.id);
void focusNode(msg.id);
} else if (msg.type === "scan-text-node-info") {
const nodesInfo = await scanTextNodesInfo(msg.autoTrigger);
// console.log({ nodesInfo });
sendTextNodesInfoToUI(nodesInfo);
} else if (msg.type === "update-node-key") {
updateNodeKey(msg.nodeId, msg.key);
await updateNodeKey(msg.nodeId, msg.key);
figma.ui.postMessage({
type: "partial-update-text-node-info-result",
partialTextNodesInfo: [{ id: msg.nodeId, key: msg.key }],
} satisfies PostToUIMessage);
} else if (msg.type === "update-node-selected") {
updateNodeSelected(msg.nodeId, msg.checked);
await updateNodeSelected(msg.nodeId, msg.checked);
figma.ui.postMessage({
type: "partial-update-text-node-info-result",
partialTextNodesInfo: [{ id: msg.nodeId, checked: msg.checked }],
Expand Down Expand Up @@ -133,15 +133,15 @@ async function updateWithLang(lang: string) {

const totalTopLvlNodes = topLvlNodes.length;

const { data, meta } = parsedCsv;
const { data } = parsedCsv;

let notificationHandle: NotificationHandler = figma.notify("Update start...");

const infoMap = getNodeInfoMap(data);

let updatedLayersCount = 0;

// We want to send figma.notify message between frame processing
// We want to send figma.notify message between frame processing, thus using Timeout between processing nodes
async function processFirstNode(nodes: SceneNode[]) {
const firstNode = nodes[0];

Expand All @@ -160,7 +160,7 @@ async function updateWithLang(lang: string) {

if (nodes.length > 1) {
setTimeout(() => {
processFirstNode(nodes.slice(1));
void processFirstNode(nodes.slice(1));
}, 20);
} else {
notificationHandle?.cancel();
Expand All @@ -175,7 +175,7 @@ async function updateWithLang(lang: string) {
}
}

processFirstNode(topLvlNodes);
void processFirstNode(topLvlNodes);
}

async function parseCsvAndDetectRevision(csvString: string) {
Expand Down Expand Up @@ -220,7 +220,7 @@ async function exportCsvFile() {
topLvlNode: SceneNode;
}[] = [];

// We want to send figma.notify message between frame processing
// We want to send figma.notify message between frame processing, thus using Timeout between processing nodes
async function processFirstNode(nodes: SceneNode[]) {
const firstNode = nodes[0];

Expand All @@ -242,7 +242,7 @@ async function exportCsvFile() {

if (nodes.length > 1) {
setTimeout(() => {
processFirstNode(nodes.slice(1));
void processFirstNode(nodes.slice(1));
}, 20);
} else {
notificationHandle?.cancel();
Expand All @@ -264,5 +264,5 @@ async function exportCsvFile() {
}, 20);
}
}
processFirstNode(topLvlNodes);
void processFirstNode(topLvlNodes);
}
16 changes: 8 additions & 8 deletions packages/copy-manager/plugin-src/pluginDataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export const writeNodeKey = (node: TextNode, key: string) => {
);
};

export const updateNodeKey = (id: string, key: string) => {
export const updateNodeKey = async (id: string, key: string) => {
// console.log("updateNodeKey", { id, key });
const nodeToFind = figma.root.findOne((x) => x.id === id);
if (nodeToFind) {
writeNodeKey(nodeToFind as any, key);
const nodeToFind = figma.currentPage.findOne((x) => x.id === id);
if (nodeToFind && nodeToFind.type === "TEXT") {
writeNodeKey(nodeToFind, key);
}
};

Expand Down Expand Up @@ -57,11 +57,11 @@ export const writeSelected = (node: TextNode, selected: boolean) => {
// console.log("after set plugin data", getSelected(node));
};

export const updateNodeSelected = (id: string, selected: boolean) => {
export const updateNodeSelected = async (id: string, selected: boolean) => {
// console.log("updateNodeKey", { id, key });
const nodeToFind = figma.root.findOne((x) => x.id === id);
if (nodeToFind) {
writeSelected(nodeToFind as any, selected);
const nodeToFind = figma.currentPage.findOne((x) => x.id === id);
if (nodeToFind && nodeToFind.type === "TEXT") {
writeSelected(nodeToFind, selected);
}
};

Expand Down
10 changes: 6 additions & 4 deletions packages/copy-manager/plugin-src/processors/csvProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
import {
CsvExportSettings,
CsvNodeInfoMap,
NodeProcessors,
NodeUpdater,
UpdaterSettings,
iterate,
iterateUpdate,
Expand Down Expand Up @@ -73,7 +75,7 @@ export const csvTextNodeProcess = (
export const csvChildrenNodeProcess = (
node: SceneNode & ChildrenMixin,
settings: CsvExportSettings,
processors: any
processors: NodeProcessors<CsvNodeInfo[]>
): CsvNodeInfo[] => {
return node.children
.slice()
Expand Down Expand Up @@ -125,7 +127,7 @@ export const parseCsvString = <T extends CsvNodeInfo>(input: string) => {
export const getNodeInfoMap = <T extends CsvNodeInfo>(
nodeInfos: T[]
): CsvNodeInfoMap => {
let map: CsvNodeInfoMap = {};
const map: CsvNodeInfoMap = {};
nodeInfos.forEach((x) => {
const nodeInfoWithNormalId = {
...x,
Expand Down Expand Up @@ -177,7 +179,7 @@ const updateListOption = async (
if (["ORDERED", "UNORDERED", "NONE"].includes(nodeInfo.listOption)) {
await loadAllFonts(node);
node.setRangeListOptions(0, node.characters.length, {
type: nodeInfo.listOption as any,
type: nodeInfo.listOption as TextListOptions["type"],
});
return true;
} else {
Expand Down Expand Up @@ -216,7 +218,7 @@ export const csvChildrenNodeUpdater = async (
node: SceneNode & ChildrenMixin,
nodeInfoMap: CsvNodeInfoMap,
settings: UpdaterSettings,
processors: any
processors: NodeUpdater<string[]>
) => {
const results = [];
for (let index = 0; index < node.children.length; index++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SelectableTextNodeInfo } from "../../shared-src/messages";
import { getNodeKey, getSelected } from "../pluginDataUtils";
import { sortNodeByPosition } from "../utils";
import { iterate } from "./iterate";
import { sortNodeByPosition, DEFAULT_HEADING_SETTINGS } from "../utils";
import { CsvExportSettings, NodeProcessors, iterate } from "./iterate";

export async function scanTextNodesInfo(autoTrigger: boolean) {
if (figma.currentPage.selection.length === 0) {
Expand All @@ -14,16 +14,18 @@ export async function scanTextNodesInfo(autoTrigger: boolean) {
const textNodesInfo: SelectableTextNodeInfo[] = [];

for (const selectedNode of figma.currentPage.selection) {
const info = await textNodeInfoProcessor(selectedNode, {});
const info = await textNodeInfoProcessor(selectedNode, {
...DEFAULT_HEADING_SETTINGS,
topLvlNodeName: figma.currentPage.name,
});
textNodesInfo.push(...info);
}

return textNodesInfo;
}

export const textNodeInfoTextNodeProcess = (
node: TextNode,
settings: any
node: TextNode
): SelectableTextNodeInfo[] => {
if (!node.visible || node.characters.length === 0) {
return [];
Expand All @@ -45,8 +47,8 @@ export const textNodeInfoTextNodeProcess = (

export const textNodeInfoChildrenNodeProcess = (
node: SceneNode & ChildrenMixin,
settings: any,
processors: any
settings: CsvExportSettings,
processors: NodeProcessors<SelectableTextNodeInfo[]>
): SelectableTextNodeInfo[] => {
return node.children
.slice()
Expand All @@ -64,7 +66,7 @@ const emptyProcess = () => null;

export const textNodeInfoProcessor = async (
node: SceneNode,
settings: any
settings: CsvExportSettings
): Promise<SelectableTextNodeInfo[]> => {
return (
iterate<SelectableTextNodeInfo[]>(node, settings, {
Expand Down
15 changes: 8 additions & 7 deletions packages/copy-manager/plugin-src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
SelectableTextNodeInfo,
} from "../shared-src/messages";
import { PLUGIN_RELAUNCH_KEY_REVIEW_REVISION } from "./pluginDataUtils";
import { textNodeInfoProcessor } from "./processors/textNodeInfoProcessor";

export type HeadingSettings = {
h1: number;
Expand All @@ -19,8 +18,9 @@ export const DEFAULT_HEADING_SETTINGS: HeadingSettings = {
h4: 18,
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isChildrenMixin = (node: any): node is ChildrenMixin => {
return !!(node as any).children;
return "children" in node;
};

export const isRectNodeImage = (node: RectangleNode): boolean => {
Expand Down Expand Up @@ -94,12 +94,13 @@ export function sendTextNodesInfoToUI(nodesInfo: SelectableTextNodeInfo[]) {
} satisfies PostToUIMessage);
}

export function focusNode(id: string) {
const nodeToFocus = figma.root.findOne((x) => x.id === id);
export async function focusNode(id: string) {
const nodeToFocus = figma.currentPage.findOne((x) => x.id === id);
if (nodeToFocus !== null) {
// TODO: Switch current page first
figma.currentPage.selection = [nodeToFocus as any];
figma.currentPage.selection = [nodeToFocus];
} else {
figma.notify(`Cannot find node with id "${id}"`, { error: true });
figma.notify(`Cannot find node with id "${id}" on this page`, {
error: true,
});
}
}

0 comments on commit 3ee7339

Please sign in to comment.