Skip to content

Commit bf6c2a3

Browse files
committed
Persistence, Projects Options
1 parent ae487fd commit bf6c2a3

6 files changed

Lines changed: 325 additions & 84 deletions

File tree

src/App.tsx

Lines changed: 65 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ import { useEffect } from "react";
33
import { useNodeFactoryContext } from "@utils/nodeFactory";
44
import { useNodeSystemContext } from "@utils/nodeSystem";
55
import { useNodeHistoryContext } from "@utils/nodeHistory";
6-
import { downloadScript } from "@utils/compilerTools";
76
import { usePromptContext } from "@utils/prompt";
87
import { usePalleteContext } from "@utils/pallete";
98
import { useVariablesContext } from "@utils/variables";
9+
import { loadProject, saveProject } from "@utils/engineTools";
10+
import {
11+
getBreadcrumb,
12+
getWindowTools,
13+
loadActiveProjectId,
14+
updatePalleteRegistry,
15+
} from "@utils/projectTools";
1016

1117
import { AppWindow } from "@components/window/AppWindow";
1218
import { Canvas } from "@components/engine/Canvas";
1319
import { Prompt } from "@components/commons/Prompt";
14-
import { loadProject, saveProject } from "@utils/engineTools";
1520

1621
export default function App() {
1722
const { newNode } = useNodeFactoryContext()!;
@@ -49,92 +54,54 @@ export default function App() {
4954
requestPrompt,
5055
} = usePromptContext()!;
5156

52-
const windowTools = [
53-
{
54-
name: "Refresh",
55-
icon: "RefreshCw",
56-
action: () => window.location.reload(),
57-
},
58-
{
59-
name: "Close Node",
60-
icon: "CircleChevronUp",
61-
action: closeNode,
62-
disabled: isEntry(activeNode)
63-
},
64-
{
65-
name: "Load Project",
66-
icon: "HardDriveUpload",
67-
action: () => loadProject(
57+
const windowTools = getWindowTools(
58+
closeNode,
59+
isEntry,
60+
activeNode,
61+
overrideNodeSystem,
62+
overrideVariables,
63+
openNode,
64+
removeNode,
65+
nodeSystem,
66+
entries,
67+
statesList,
68+
customComponents,
69+
);
70+
71+
const windowExtraTitle = getBreadcrumb(
72+
nodeHistory,
73+
activeNode,
74+
);
75+
76+
useEffect(() => {
77+
(async () => {
78+
const requireLoading = await loadActiveProjectId();
79+
if (!requireLoading) return;
80+
81+
loadProject(
6882
overrideNodeSystem,
6983
overrideVariables,
7084
openNode,
7185
removeNode,
72-
),
73-
},
74-
{
75-
name: "Save Project",
76-
icon: "HardDriveDownload",
77-
action: () => saveProject(
78-
nodeSystem,
79-
entries,
80-
{
81-
states: statesList,
82-
customComponents,
83-
}
84-
),
85-
},
86-
{
87-
name: "Compile Project",
88-
icon: "Rocket",
89-
action: () => downloadScript(nodeSystem, entries),
90-
},
91-
];
92-
93-
const windowExtraTitle = [
94-
...nodeHistory.current,
95-
activeNode
96-
].join(" > ");
86+
)
87+
})();
88+
}, [
89+
overrideNodeSystem,
90+
overrideVariables,
91+
openNode,
92+
removeNode,
93+
]);
9794

9895
useEffect(() => {
99-
entries.map(
100-
entry => ({
101-
name: entry,
102-
icon: "Component",
103-
action: () => openNode(entry, true),
104-
})
105-
).forEach(suggestion => addSuggestion(
106-
suggestion, "Entries"
107-
));
108-
109-
addSuggestion({
110-
name: "New Entry",
111-
icon: "NotebookPen",
112-
action: () => {
113-
(async () => {
114-
const entryName = (
115-
await requestPrompt(
116-
"Enter the name of the new Entry Point"
117-
)
118-
)?.trim().toUpperCase();
119-
120-
if (!entryName) return;
121-
createEntry(entryName);
122-
openNode(entryName, true);
123-
})();
124-
}
125-
}, "Create");
126-
127-
addSuggestion({
128-
name: "New Component",
129-
icon: "Puzzle",
130-
action: promptComponent,
131-
}, "Register");
132-
133-
addSuggestion({
134-
name: "New State",
135-
icon: "Puzzle",
136-
action: promptState,
137-
}, "Register");
96+
updatePalleteRegistry(
97+
addSuggestion,
98+
openNode,
99+
entries,
100+
createEntry,
101+
requestPrompt,
102+
promptComponent,
103+
promptState,
104+
)
138105
}, [
139106
addSuggestion,
140107
openNode,
@@ -145,6 +112,22 @@ export default function App() {
145112
promptState,
146113
]);
147114

115+
useEffect(() => {
116+
saveProject(
117+
nodeSystem,
118+
entries,
119+
{
120+
states: statesList,
121+
customComponents,
122+
},
123+
);
124+
}, [
125+
entries,
126+
nodeSystem,
127+
statesList,
128+
customComponents,
129+
]);
130+
148131
return (<>
149132
<AppWindow
150133
tools={windowTools}

src/defs/PyWebview.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface PyWebview {
88
file_types?: string[],
99
) => Promise<void>;
1010
load_file: () => Promise<string>;
11+
load_project_id: () => Promise<string | null>;
1112
}
1213
}
1314

src/utils/desktopTools.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,18 @@ const setupDesktopTools = () => {
7171
return promise;
7272
}
7373

74+
const loadProjectId = async (): Promise<string | null> => {
75+
if (!isDesktop()) return null;
76+
return pwv!.api.load_project_id() || null;
77+
}
78+
7479
return {
7580
isDesktop,
7681
closeWindow,
7782
toggleWindowFullscreen,
7883
saveFile,
7984
loadFile,
85+
loadProjectId,
8086
}
8187
};
8288

@@ -86,5 +92,6 @@ export const {
8692
toggleWindowFullscreen,
8793
saveFile,
8894
loadFile,
95+
loadProjectId,
8996
} = setupDesktopTools();
9097

src/utils/engineTools.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
} from "@defs/Node";
77

88
import { loadFile, saveFile } from "@utils/desktopTools";
9+
import { loadData, saveData } from "./persistentTools";
910

1011
type PackedNode = {
1112
id: string;
@@ -34,13 +35,24 @@ type PackedNodeSystem = {
3435
};
3536

3637
const setupEngineTools = () => {
38+
let projectId: string | null = null;
39+
40+
const setProjectId = (id: string) => {
41+
projectId = id;
42+
};
43+
44+
const getProjectId = (): string | null => {
45+
return projectId;
46+
};
47+
3748
const saveProject = (
3849
nodeSystem: NodeSystem,
3950
entries: string[],
4051
variables: {
4152
states: Variable[];
4253
customComponents: Variable[];
4354
},
55+
download: boolean = false,
4456
) => {
4557
const savedNodes: PackedNodeMap = {};
4658

@@ -82,12 +94,33 @@ const setupEngineTools = () => {
8294

8395
const packedSystem = packNodeSystem(nodeSystem);
8496
const dataJSON = JSON.stringify({
97+
projectId,
8598
entries,
8699
nodes: savedNodes,
87100
system: packedSystem,
88101
variables,
89102
});
90103

104+
if (!download) {
105+
if (projectId) {
106+
saveData(`p:${projectId}`, dataJSON);
107+
saveData("activeProjectId", projectId);
108+
109+
const projectMap = JSON.parse(
110+
loadData(`projectMap`) || "{}"
111+
);
112+
113+
projectMap[projectId] = {
114+
id: projectId,
115+
status: "accessible",
116+
};
117+
118+
saveData(`projectMap`, JSON.stringify(projectMap));
119+
}
120+
121+
return;
122+
}
123+
91124
saveFile(dataJSON, "project.json", [
92125
"Project Files (*.json)",
93126
"All Files (*.*)"
@@ -96,7 +129,7 @@ const setupEngineTools = () => {
96129

97130
const loadProject = async (
98131
overrideNodeSystem: (
99-
system: NodeSystem,
132+
system: NodeSystem,
100133
entries: string[],
101134
) => void,
102135
overrideVariables: (
@@ -105,11 +138,15 @@ const setupEngineTools = () => {
105138
) => void,
106139
openNode: (nodeId: string) => void,
107140
removeNode: (nodeId: string) => void,
141+
upload: boolean = false,
108142
) => {
109-
const fileContents: string | null = await loadFile();
143+
let fileContents: string | null = loadData(`p:${projectId}`);
144+
145+
if (upload) fileContents = await loadFile();
110146
if (!fileContents) return;
111147

112148
const data: {
149+
projectId: string;
113150
entries: string[];
114151
nodes: PackedNodeMap;
115152
system: PackedNodeSystem;
@@ -169,6 +206,8 @@ const setupEngineTools = () => {
169206
loadedSystem[baseId] = group;
170207
}
171208

209+
setProjectId(data.projectId);
210+
172211
overrideNodeSystem(
173212
loadedSystem,
174213
data.entries
@@ -183,11 +222,15 @@ const setupEngineTools = () => {
183222
return {
184223
saveProject,
185224
loadProject,
225+
setProjectId,
226+
getProjectId,
186227
}
187228
};
188229

189230
export const {
190231
saveProject,
191232
loadProject,
233+
setProjectId,
234+
getProjectId,
192235
} = setupEngineTools();
193236

src/utils/persistentTools.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const setupPersistentTools = () => {
2+
const persistenceKey = 'graphscript-persistence:';
3+
4+
const saveData = (key: string, value: string) => {
5+
localStorage.setItem(`${persistenceKey}${key}`, value);
6+
};
7+
8+
const loadData = (key: string): string | null => {
9+
return localStorage.getItem(`${persistenceKey}${key}`);
10+
};
11+
12+
const wipeData = (key: string) => {
13+
localStorage.removeItem(`${persistenceKey}${key}`);
14+
};
15+
16+
return {
17+
saveData,
18+
loadData,
19+
wipeData,
20+
}
21+
};
22+
23+
export const {
24+
saveData,
25+
loadData,
26+
wipeData,
27+
} = setupPersistentTools();
28+

0 commit comments

Comments
 (0)