diff --git a/app/lib/screens/layout-view/index.tsx b/app/lib/screens/layout-view/index.tsx
index 907e547f..fe74405f 100644
--- a/app/lib/screens/layout-view/index.tsx
+++ b/app/lib/screens/layout-view/index.tsx
@@ -1,5 +1,7 @@
import React from "react";
+import { PluginSdk } from "../../utils/plugin-provider/plugin-app-sdk";
export default function LayoutViewScreen() {
+ PluginSdk.selectedNodeId;
return
Layout view
;
}
diff --git a/app/lib/utils/plugin-provider/events.ts b/app/lib/utils/plugin-provider/events.ts
index 12572137..a4bc51e2 100644
--- a/app/lib/utils/plugin-provider/events.ts
+++ b/app/lib/utils/plugin-provider/events.ts
@@ -3,6 +3,7 @@ export const PLUGIN_SDK_NS_RESPONSE_ALL = "bridged/response/*";
export const PLC_REMOTE_API_REQ = "pugin-consumer/remote-api/request";
export const PLC_REMOTE_API_RES = "pugin-consumer/remote-api/response";
export const PLUGIN_SDK_NS_REMOTE_API = `${PLUGIN_SDK_NAMESPACE_BASE_TOKEN}/remote-api`;
+export const PLUGIN_SDK_NS_GENERAL_STATE_DATA = `${PLUGIN_SDK_NAMESPACE_BASE_TOKEN}/general-state-data`;
// region sync
export const PLUGIN_SDK_NS_SYNC = `${PLUGIN_SDK_NAMESPACE_BASE_TOKEN}/sync`;
@@ -46,6 +47,9 @@ export interface BasePluginEvent {
data: T;
}
+/**
+ * An Event object interface to pass Plugin events from / to PluginService and PluginApp
+ */
export interface TransportPluginEvent extends BasePluginEvent {
origin: "app" | "server";
type: "response" | "request";
diff --git a/app/lib/utils/plugin-provider/plugin-app-sdk/index.ts b/app/lib/utils/plugin-provider/plugin-app-sdk/index.ts
index 02244e34..825d19d7 100644
--- a/app/lib/utils/plugin-provider/plugin-app-sdk/index.ts
+++ b/app/lib/utils/plugin-provider/plugin-app-sdk/index.ts
@@ -20,6 +20,7 @@ import {
import { NotifyRequest } from "../interfaces/notify/notify.requests";
import { nanoid } from "nanoid";
import { DragAndDropOnCanvasRequest } from "../interfaces/dragdrop/dragdrop.requests";
+import { ReflectSceneNode } from "@bridged.xyz/design-sdk/lib/nodes";
export class PluginSdk {
static window: Window;
@@ -28,15 +29,26 @@ export class PluginSdk {
}
// region general canvas api
- static get selectedNodes(): string {
+ static get selectedNodeIds(): readonly string[] {
throw "not implemented";
- return "";
+ return [];
}
- static get selectedNode(): string {
+ static get selectedNodes(): readonly ReflectSceneNode[] {
+ throw "not implemented";
+ return [];
+ }
+
+ static get selectedNodeId(): string {
+ // TODO
+ throw "not implemented";
+ return undefined;
+ }
+
+ static get selectedNode(): ReflectSceneNode {
// TODO
throw "not implemented";
- return "";
+ return undefined;
}
// enderegion general canvas api
diff --git a/app/lib/utils/plugin-provider/plugin-server/index.ts b/app/lib/utils/plugin-provider/plugin-service/index.ts
similarity index 96%
rename from app/lib/utils/plugin-provider/plugin-server/index.ts
rename to app/lib/utils/plugin-provider/plugin-service/index.ts
index 33481ecd..1b448991 100644
--- a/app/lib/utils/plugin-provider/plugin-server/index.ts
+++ b/app/lib/utils/plugin-provider/plugin-service/index.ts
@@ -35,10 +35,10 @@ interface HanderProps {
}
figma.on("selectionchange", () => {
- PluginSdkServer.onSelectionChange();
+ PluginSdkService.onSelectionChange();
});
-export class PluginSdkServer {
+export class PluginSdkService {
static onSelectionChange() {
const selection = figma.currentPage.selection;
if (selection.length == 0) {
@@ -69,11 +69,11 @@ export class PluginSdkServer {
}
static handleDragAndDropEvent(key: string, data: any, position: { x; y }) {
- if (!PluginSdkServer.dragAndDropHandlers.has(key)) {
+ if (!PluginSdkService.dragAndDropHandlers.has(key)) {
throw `no handler found for event ${key} on drag and drop handler`;
}
- PluginSdkServer.dragAndDropHandlers.get(key)(data, position);
+ PluginSdkService.dragAndDropHandlers.get(key)(data, position);
}
static handle(event: TransportPluginEvent): boolean {
@@ -292,5 +292,5 @@ function handleDragDropped(props: HanderProps) {
const x = bounds.x + xFromCanvas / zoom - offset.x;
const y = bounds.y + yFromCanvas / zoom - offset.y;
- PluginSdkServer.handleDragAndDropEvent(eventKey, customData, { x: x, y: y });
+ PluginSdkService.handleDragAndDropEvent(eventKey, customData, { x: x, y: y });
}
diff --git a/app/lib/utils/plugin-provider/pugin-app/README.md b/app/lib/utils/plugin-provider/pugin-app/README.md
new file mode 100644
index 00000000..c5fe9a65
--- /dev/null
+++ b/app/lib/utils/plugin-provider/pugin-app/README.md
@@ -0,0 +1,7 @@
+# Plugin SDK React component
+
+```tsx
+
+
+
+```
diff --git a/app/lib/utils/plugin-provider/pugin-app/index.tsx b/app/lib/utils/plugin-provider/pugin-app/index.tsx
index ebe5d52b..3a141123 100644
--- a/app/lib/utils/plugin-provider/pugin-app/index.tsx
+++ b/app/lib/utils/plugin-provider/pugin-app/index.tsx
@@ -1,14 +1,17 @@
import React, { useEffect } from "react";
+import { useSetRecoilState } from "recoil";
import Axios from "axios";
import {
PLC_REMOTE_API_REQ,
PLC_REMOTE_API_RES,
PLUGIN_SDK_NAMESPACE_BASE_TOKEN,
+ PLUGIN_SDK_NS_GENERAL_STATE_DATA,
PLUGIN_SDK_NS_REMOTE_API,
TransportPluginEvent,
} from "../events";
import { NetworkRequest } from "../interfaces/remote-api/remote-api.requests";
import { PluginSdk } from "../plugin-app-sdk";
+import { currentlySelectedPrimaryNodeId } from "./states/canvas";
export function PluginApp(props: { children: any }) {
useEffect(() => {
@@ -30,33 +33,9 @@ export function PluginApp(props: { children: any }) {
}
// endregion validate
- PluginSdk.handle(message);
-
- if (message.namespace == PLUGIN_SDK_NS_REMOTE_API) {
- // call remote request
- const requestManifest = message.data as NetworkRequest;
- Axios.request({
- method: requestManifest.method,
- url: requestManifest.url,
- data: requestManifest.data,
- headers: requestManifest.headers,
- })
- .then((r) => {
- networkResponseToCodeThread(
- window,
- requestManifest.requestId,
- r.data
- );
- })
- .catch((e) => {
- networkResponseToCodeThread(
- window,
- requestManifest.requestId,
- null,
- e
- );
- });
- }
+ registerPluginSdkHandler(message);
+ registerPluginGlobalStateHandler(message);
+ registerPluginRemoteCallHandler(message);
});
console.info("PluginApp initiallized");
@@ -65,6 +44,47 @@ export function PluginApp(props: { children: any }) {
return {props.children}
;
}
+function registerPluginSdkHandler(message: TransportPluginEvent) {
+ PluginSdk.handle(message);
+}
+
+/**
+ * registers global state handler managed by plugin. such like current selection.
+ */
+function registerPluginGlobalStateHandler(message: TransportPluginEvent) {
+ if (message.namespace == PLUGIN_SDK_NS_GENERAL_STATE_DATA) {
+ if (message.key == "general.canvas.selection-change") {
+ // update selection change
+ const setCrrentSelection = useSetRecoilState(
+ currentlySelectedPrimaryNodeId
+ );
+ // ...
+ }
+ }
+}
+
+/**
+ * registers handler for remote http(s) call
+ */
+function registerPluginRemoteCallHandler(message: TransportPluginEvent) {
+ if (message.namespace == PLUGIN_SDK_NS_REMOTE_API) {
+ // call remote request
+ const requestManifest = message.data as NetworkRequest;
+ Axios.request({
+ method: requestManifest.method,
+ url: requestManifest.url,
+ data: requestManifest.data,
+ headers: requestManifest.headers,
+ })
+ .then((r) => {
+ networkResponseToCodeThread(window, requestManifest.requestId, r.data);
+ })
+ .catch((e) => {
+ networkResponseToCodeThread(window, requestManifest.requestId, null, e);
+ });
+ }
+}
+
function networkResponseToCodeThread(
window: Window,
requestId: string,
diff --git a/app/lib/utils/plugin-provider/plugin-app-sdk/states/current-node.ts b/app/lib/utils/plugin-provider/pugin-app/states/canvas.ts
similarity index 100%
rename from app/lib/utils/plugin-provider/plugin-app-sdk/states/current-node.ts
rename to app/lib/utils/plugin-provider/pugin-app/states/canvas.ts
diff --git a/app/lib/utils/plugin-provider/pugin-app/utils/canvas.ts b/app/lib/utils/plugin-provider/pugin-app/utils/canvas.ts
new file mode 100644
index 00000000..c36191a2
--- /dev/null
+++ b/app/lib/utils/plugin-provider/pugin-app/utils/canvas.ts
@@ -0,0 +1,22 @@
+import { ReflectSceneNode } from "@bridged.xyz/design-sdk/lib/nodes";
+
+export function getPrimarySelectedNode(selection: readonly ReflectSceneNode[]) {
+ // if (){
+ // }
+}
+
+export enum SelectionAnalysis {
+ empty = "empty",
+ single = "single",
+ multi = "multi",
+}
+
+export function analyzeSelection(selection: readonly any[]): SelectionAnalysis {
+ if (selection.length == 0) {
+ return SelectionAnalysis.empty;
+ } else if (selection.length == 1) {
+ return SelectionAnalysis.single;
+ } else {
+ return SelectionAnalysis.multi;
+ }
+}
diff --git a/app/lib/utils/plugin-provider/pugin-app/utils/index.ts b/app/lib/utils/plugin-provider/pugin-app/utils/index.ts
new file mode 100644
index 00000000..df456a37
--- /dev/null
+++ b/app/lib/utils/plugin-provider/pugin-app/utils/index.ts
@@ -0,0 +1 @@
+export * from "./canvas";
diff --git a/figma/src/code.ts b/figma/src/code.ts
index 4bc5db1a..e2034663 100644
--- a/figma/src/code.ts
+++ b/figma/src/code.ts
@@ -1,7 +1,11 @@
-import { PluginSdkServer } from "app/lib/utils/plugin-provider/plugin-server";
+import { PluginSdkService } from "app/lib/utils/plugin-provider/plugin-service";
import { convertIntoReflectNode } from "@bridged.xyz/design-sdk/lib/nodes/conversion";
import { buildApp } from "core/lib/flutter";
import { retrieveFlutterColors } from "core/lib/flutter/utils/fetch-colors";
+import {
+ analyzeSelection,
+ SelectionAnalysis,
+} from "app/lib/utils/plugin-provider/pugin-app/utils";
import {
hideAllExcept,
hideAllOnly,
@@ -49,8 +53,6 @@ async function showUI() {
figma.showUI(__html__, { width: width, height: height });
}
-showUI();
-
function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
@@ -169,44 +171,39 @@ async function runon(node: SceneNode) {
data: retrieveFlutterColors([convertedSelection]),
});
}
-
figma.on("selectionchange", () => {
+ // clear the console for better debugging
console.clear();
console.warn("log cleared. optimized for new build");
console.log("selection", figma.currentPage.selection);
- const selectionCount = figma.currentPage.selection.length;
-
- // ignore when nothing was selected
- if (selectionCount === 0) {
- figma.ui.postMessage({
- type: "empty",
- });
- return;
- }
-
- // force to single selection
- // return false or raise error if more than one node is selected.
- if (selectionCount >= 2) {
- figma.notify("only single selection is supported", {
- timeout: 1.5,
- });
- return false;
- }
-
- if (selectionCount === 1) {
- const target = figma.currentPage.selection[0];
- figma.ui.postMessage({
- type: "selectionchange",
- data: target,
- });
-
- runon(target);
- return;
+ const selectionType = analyzeSelection(figma.currentPage.selection);
+ switch (selectionType) {
+ case SelectionAnalysis.empty:
+ // ignore when nothing was selected
+ figma.ui.postMessage({
+ type: "empty",
+ });
+ return;
+ case SelectionAnalysis.multi:
+ // force to single selection
+ // return false or raise error if more than one node is selected.
+ figma.notify("only single selection is supported", {
+ timeout: 1.5,
+ });
+ return false;
+ case SelectionAnalysis.single:
+ const target = figma.currentPage.selection[0];
+ figma.ui.postMessage({
+ type: "selectionchange",
+ data: target,
+ });
+ runon(target);
+ return;
}
});
-PluginSdkServer.registerDragAndDropHandler(
+PluginSdkService.registerDragAndDropHandler(
EK_ICON_DRAG_AND_DROPPED,
(data, pos): Promise => {
createIcon(
@@ -225,7 +222,7 @@ PluginSdkServer.registerDragAndDropHandler(
figma.ui.onmessage = async (msg) => {
console.log("[event] figma plugin data received", msg);
- const generalHandlingResult = PluginSdkServer.handle(msg);
+ const generalHandlingResult = PluginSdkService.handle(msg);
// if event is handled by general event handler, no additional handling is required.
if (generalHandlingResult) {
return;
@@ -303,3 +300,9 @@ function hideAllOnlyFromCurrentSelection(only: NodeType) {
hideAllOnly(selection, only);
}
}
+
+function main() {
+ showUI();
+}
+
+main();
diff --git a/packages/lint b/packages/lint
index 327d90c9..332ddb0c 160000
--- a/packages/lint
+++ b/packages/lint
@@ -1 +1 @@
-Subproject commit 327d90c987f65b06b84945d1ba893aa0b7252be7
+Subproject commit 332ddb0c27253359dd638fda5da7356e54a6eadd