Skip to content

Commit e207173

Browse files
fix progressive loading state handling
1 parent 3a0c55f commit e207173

2 files changed

Lines changed: 85 additions & 63 deletions

File tree

editor/hooks/use-design.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,14 @@ export function useDesign({
114114
const _2_converted_to_reflect = convert.intoReflectNode(
115115
_1_converted_to_figma
116116
);
117-
setDesign(<TargetNodeConfig>{
117+
118+
const res = <TargetNodeConfig>{
118119
...targetnodeconfig,
119120
raw: last_response,
120121
figma: _1_converted_to_figma,
121122
reflect: _2_converted_to_reflect,
122-
});
123+
};
124+
setDesign(res);
123125
} else {
124126
if (figmaAccessToken || personalAccessToken) {
125127
fetch
@@ -163,7 +165,7 @@ export function useDesign({
163165
}
164166
}
165167
}
166-
}, [router, figmaAccessToken]);
168+
}, [router, figmaAccessToken, props["url"]]);
167169
return design;
168170
}
169171

editor/pages/to-code/index.tsx

Lines changed: 80 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import React, {
2-
useEffect,
3-
useState,
4-
useCallback,
5-
useReducer,
6-
useMemo,
7-
} from "react";
1+
import React, { useEffect, useCallback, useReducer } from "react";
82
import { useRouter } from "next/router";
93
import { SigninToContinueBannerPrmoptProvider } from "components/prompt-banner-signin-to-continue";
104
import { Editor } from "scaffolds/editor";
@@ -27,7 +21,8 @@ import { PendingState } from "core/utility-types";
2721
import { DesignInput } from "@designto/config/input";
2822
import { convert } from "@design-sdk/figma-node-conversion";
2923
import { mapper } from "@design-sdk/figma-remote";
30-
import { analyze, parseFileAndNodeId } from "@design-sdk/figma-url";
24+
import { parseFileAndNodeId } from "@design-sdk/figma-url";
25+
import { TargetNodeConfig } from "query/target-node";
3126

3227
const pending_workspace_state = createPendingWorkspaceState();
3328
//
@@ -70,64 +65,75 @@ export default function Page() {
7065
}, []);
7166
// endregion global state
7267

73-
const design = useDesign({ type: "use-router", router: router });
68+
const _design_param: string = router.query[P_DESIGN] as string;
69+
const _input = parseFileAndNodeId(_design_param);
70+
const design = useDesign({ type: "use-url", url: _design_param });
7471

7572
useEffect(() => {
76-
if (initialState.type === "success") return;
77-
78-
if (design) {
79-
// TODO: set preferences to workspace state.
80-
const framework_config = get_framework_config_from_query(router.query);
81-
const isDebug = router.query.debug;
82-
const preview_runner_framework = get_preview_runner_framework(
83-
router.query
84-
);
85-
const enable_components = get_enable_components_config_from_query(
86-
router.query
87-
);
88-
initialDispatcher({
89-
type: "set",
90-
value: {
91-
selectedNodes: [design.node],
92-
selectedLayersOnPreview: [],
93-
selectedPage: null, // TODO:
94-
design: {
95-
pages: [], // TODO:
96-
key: design.file,
97-
input: DesignInput.fromApiResponse({
98-
...design,
99-
entry: design.reflect,
100-
}),
101-
},
102-
},
103-
});
104-
}
105-
}, [design, router]);
73+
// TODO: set preferences to workspace state.
74+
const framework_config = get_framework_config_from_query(router.query);
75+
const isDebug = router.query.debug;
76+
const preview_runner_framework = get_preview_runner_framework(router.query);
77+
const enable_components = get_enable_components_config_from_query(
78+
router.query
79+
);
80+
}, [router.query]);
10681

10782
// background whole file fetching
108-
const _design_param: string = router.query[P_DESIGN] as string;
109-
const _file_key = parseFileAndNodeId(_design_param)?.file;
110-
const file = useDesignFile({ file: _file_key });
83+
const file = useDesignFile({ file: _input?.file });
11184
const prevstate =
11285
initialState.type == "success" && initialState.value.history.present;
113-
const selectedPage = useMemo(() => {
86+
87+
const selectedPage = (pages: { id: string }[], selectedNodes: string[]) => {
11488
if (prevstate.selectedPage) {
11589
return prevstate.selectedPage;
11690
}
11791

118-
if (prevstate?.selectedNodes && file?.document?.children) {
119-
return prevstate.selectedNodes.length > 0
120-
? file.document.children.find((page) => {
121-
return isChildrenOf(prevstate.selectedNodes[0], page);
92+
if (selectedNodes && pages) {
93+
return selectedNodes.length > 0
94+
? pages.find((page) => {
95+
return isChildrenOf(selectedNodes[0], page);
12296
})?.id ?? null
12397
: // find page of current selection.
12498
null;
12599
}
126100

127101
return file?.document?.children?.[0].id ?? null; // otherwise, return first page.
128-
}, [file?.document?.children]);
102+
};
103+
104+
function initializeDesign(design: TargetNodeConfig): EditorSnapshot {
105+
return {
106+
selectedNodes: [design.node],
107+
selectedLayersOnPreview: [],
108+
selectedPage: null,
109+
design: {
110+
pages: [],
111+
key: design.file,
112+
input: DesignInput.fromApiResponse({
113+
...design,
114+
entry: design.reflect,
115+
}),
116+
},
117+
};
118+
}
119+
120+
useEffect(() => {
121+
if (design) {
122+
if (initialState.type === "success") return;
123+
initialDispatcher({
124+
type: "set",
125+
value: initializeDesign(design),
126+
});
127+
}
128+
}, [design, router.query]);
129129

130130
useEffect(() => {
131+
if (_input?.node) {
132+
if (!design) {
133+
// if target design is specified, whole file fetching should wait until design is loaded.
134+
return;
135+
}
136+
}
131137
if (file) {
132138
let val: EditorSnapshot;
133139

@@ -140,34 +146,47 @@ export default function Page() {
140146
}),
141147
type: "design",
142148
}));
149+
143150
if (prevstate) {
144151
val = {
145152
...prevstate,
146153
design: {
147154
...prevstate.design,
148155
pages: pages,
149156
},
150-
selectedPage: selectedPage,
157+
selectedPage: selectedPage(pages, prevstate.selectedNodes),
151158
};
152159
} else {
153-
val = {
154-
selectedNodes: [],
155-
selectedLayersOnPreview: [],
156-
design: {
157-
input: null,
158-
key: _file_key,
159-
pages: pages,
160-
},
161-
selectedPage: selectedPage,
162-
};
160+
if (design) {
161+
const initialState = initializeDesign(design);
162+
val = {
163+
...initialState,
164+
design: {
165+
...initialState.design,
166+
pages: pages,
167+
},
168+
selectedPage: selectedPage(pages, initialState.selectedNodes),
169+
};
170+
} else {
171+
val = {
172+
selectedNodes: [],
173+
selectedLayersOnPreview: [],
174+
design: {
175+
input: null,
176+
key: _input.file,
177+
pages: pages,
178+
},
179+
selectedPage: selectedPage(pages, null),
180+
};
181+
}
163182
}
164183

165184
initialDispatcher({
166185
type: "set",
167186
value: val,
168187
});
169188
}
170-
}, [file?.document?.children]);
189+
}, [_input?.url, design, file?.document?.children]);
171190
// endregion
172191

173192
const safe_value =
@@ -190,6 +209,7 @@ type Tree = {
190209
};
191210

192211
function isChildrenOf(child: string, parent: Tree) {
212+
if (!parent) return false;
193213
if (child === parent.id) return true;
194214
if (parent.children?.length === 0) return false;
195215
return parent.children?.some((c) => isChildrenOf(child, c)) ?? false;

0 commit comments

Comments
 (0)