Skip to content

Commit 5d62880

Browse files
committed
feat: add option to close dashboard when starting project
1 parent b3a6384 commit 5d62880

File tree

5 files changed

+127
-40
lines changed

5 files changed

+127
-40
lines changed

editor/src/dashboard/create.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Di
1919

2020
import { openSingleFolderDialog } from "../tools/dialog";
2121
import { isPackageManagerAvailable } from "../tools/process";
22-
import { tryAddProjectToLocalStorage } from "../tools/local-storage";
22+
import { tryAddProjectToLocalStorage, tryGetCloseDashboardOnProjectOpenFromLocalStorage } from "../tools/local-storage";
2323

2424
import { EditorProjectPackageManager, IEditorProject, EditorProjectTemplate } from "../project/typings";
2525

@@ -101,7 +101,8 @@ export function DashboardCreateProjectDialog(props: IDashboardCreateProjectDialo
101101
});
102102

103103
if (result) {
104-
ipcRenderer.send("dashboard:open-project", projectAbsolutePath);
104+
const shouldCloseDashboard = tryGetCloseDashboardOnProjectOpenFromLocalStorage();
105+
ipcRenderer.send("dashboard:open-project", projectAbsolutePath, shouldCloseDashboard);
105106
}
106107
} catch (e) {
107108
showAlert("An unexpected error occured", e.message);

editor/src/dashboard/item.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { execNodePty, NodePtyInstance } from "../tools/node-pty";
2323
import { IEditorProject } from "../project/typings";
2424

2525
import { DashboardProgressComponent } from "./progress";
26+
import { tryGetCloseDashboardOnProjectOpenFromLocalStorage } from "../tools/local-storage";
2627

2728
export interface IDashboardProjectItemProps {
2829
isOpened: boolean;
@@ -127,6 +128,11 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
127128
setPlayingAddress("");
128129
}
129130

131+
function handleLoadProject() {
132+
const shouldCloseDashboard = tryGetCloseDashboardOnProjectOpenFromLocalStorage();
133+
ipcRenderer.send("dashboard:open-project", props.project.absolutePath, shouldCloseDashboard);
134+
}
135+
130136
function handleOpenInVisualStudioCode() {
131137
execNodePty(`code "${dirname(props.project.absolutePath)}"`);
132138
}
@@ -135,7 +141,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
135141
<ContextMenu onOpenChange={(o) => setContextMenuOpen(o)}>
136142
<ContextMenuTrigger>
137143
<div
138-
onDoubleClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}
144+
onDoubleClick={handleLoadProject}
139145
className={`
140146
group
141147
flex flex-col w-full rounded-lg cursor-pointer select-none
@@ -169,7 +175,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
169175
</Button>
170176
</DropdownMenuTrigger>
171177
<DropdownMenuContent>
172-
<DropdownMenuItem onClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}>Open</DropdownMenuItem>
178+
<DropdownMenuItem onClick={handleLoadProject}>Open</DropdownMenuItem>
173179
<DropdownMenuItem className="flex items-center gap-2" onClick={() => ipcRenderer.send("editor:show-item", props.project.absolutePath)}>
174180
{`Show in ${isDarwin() ? "Finder" : "Explorer"}`}
175181
</DropdownMenuItem>
@@ -214,7 +220,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
214220
</div>
215221
</ContextMenuTrigger>
216222
<ContextMenuContent>
217-
<ContextMenuItem onClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}>Open</ContextMenuItem>
223+
<ContextMenuItem onClick={handleLoadProject}>Open</ContextMenuItem>
218224
<ContextMenuItem className="flex items-center gap-2" onClick={() => ipcRenderer.send("editor:show-item", props.project.absolutePath)}>
219225
{`Show in ${isDarwin() ? "Finder" : "Explorer"}`}
220226
</ContextMenuItem>

editor/src/dashboard/main.tsx

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@ import { wait } from "../tools/tools";
1515
import { openSingleFileDialog } from "../tools/dialog";
1616
import { ProjectType, projectsKey } from "../tools/project";
1717
import { checkNodeJSAvailable, nodeJSAvailable } from "../tools/process";
18-
import { tryAddProjectToLocalStorage, tryGetProjectsFromLocalStorage } from "../tools/local-storage";
18+
import {
19+
tryAddProjectToLocalStorage,
20+
tryGetCloseDashboardOnProjectOpenFromLocalStorage,
21+
tryGetProjectsFromLocalStorage,
22+
trySetCloseDashboardOnProjectOpenInLocalStorage,
23+
} from "../tools/local-storage";
1924

2025
import { DashboardProjectItem } from "./item";
2126
import { DashboardCreateProjectDialog } from "./create";
2227
import { DashboardWindowControls } from "./window-controls";
2328

2429
import packageJson from "../../package.json";
30+
import { Switch } from "../ui/shadcn/ui/switch";
31+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/shadcn/ui/tooltip";
2532

2633
export function createDashboard(): void {
2734
const theme = localStorage.getItem("editor-theme") ?? "dark";
@@ -48,6 +55,7 @@ export interface IDashboardState {
4855
openedProjects: string[];
4956

5057
createProject: boolean;
58+
keepDashboard: boolean;
5159
}
5260

5361
export class Dashboard extends Component<IDashboardProps, IDashboardState> {
@@ -59,48 +67,60 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
5967
projects: tryGetProjectsFromLocalStorage(),
6068

6169
createProject: false,
70+
keepDashboard: !tryGetCloseDashboardOnProjectOpenFromLocalStorage(),
6271
};
6372

6473
webFrame.setZoomFactor(0.8);
6574
}
6675

6776
public render(): ReactNode {
68-
return (
69-
<>
70-
<div className="flex flex-col gap-4 w-screen h-screen p-5 select-none overflow-x-hidden pt-10">
71-
<DashboardWindowControls />
77+
const handleKeepDashboardChanged = (checked: boolean): void => {
78+
this.setState({
79+
...this.state,
80+
keepDashboard: checked,
81+
});
7282

73-
<Fade delay={0}>
74-
<div className="flex justify-between items-end w-full mt-1">
75-
<div className="text-5xl font-semibold">Dashboard</div>
83+
trySetCloseDashboardOnProjectOpenInLocalStorage(!checked);
84+
};
7685

77-
<div className="flex flex-col items-end gap-2">
78-
<img alt="" src="assets/babylonjs_icon.png" className="w-[48px] object-contain" />
79-
<div className="text-xs">Babylon.js Editor v{packageJson.version}</div>
86+
return (
87+
<>
88+
<div className="flex flex-col gap-4 w-screen h-screen p-5 select-none pt-10">
89+
<div className="flex flex-col gap-4 flex-[0_0_auto]">
90+
<DashboardWindowControls />
91+
92+
<Fade delay={0}>
93+
<div className="flex justify-between items-end w-full mt-1">
94+
<div className="text-5xl font-semibold">Dashboard</div>
95+
96+
<div className="flex flex-col items-end gap-2">
97+
<img alt="" src="assets/babylonjs_icon.png" className="w-[48px] object-contain" />
98+
<div className="text-xs">Babylon.js Editor v{packageJson.version}</div>
99+
</div>
80100
</div>
81-
</div>
82-
</Fade>
83-
84-
<Fade delay={250}>
85-
<Separator />
86-
</Fade>
87-
88-
<Fade delay={500}>
89-
<div className="flex justify-between items-center">
90-
<div className="text-3xl font-semibold">Projects</div>
91-
92-
<div className="flex gap-2">
93-
<Button variant="secondary" className="font-semibold" onClick={() => this._handleImportProject()}>
94-
Import project
95-
</Button>
96-
<Button className="font-semibold" onClick={() => this.setState({ createProject: true })}>
97-
Create project
98-
</Button>
101+
</Fade>
102+
103+
<Fade delay={250}>
104+
<Separator />
105+
</Fade>
106+
107+
<Fade delay={500}>
108+
<div className="flex justify-between items-center">
109+
<div className="text-3xl font-semibold">Projects</div>
110+
111+
<div className="flex gap-2">
112+
<Button variant="secondary" className="font-semibold" onClick={() => this._handleImportProject()}>
113+
Import project
114+
</Button>
115+
<Button className="font-semibold" onClick={() => this.setState({ createProject: true })}>
116+
Create project
117+
</Button>
118+
</div>
99119
</div>
100-
</div>
101-
</Fade>
120+
</Fade>
121+
</div>
102122

103-
<Fade delay={750}>
123+
<Fade delay={750} className="flex-auto overflow-y-auto p-1">
104124
{!this.state.projects.length && <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">No project found.</div>}
105125

106126
{this.state.projects.length && (
@@ -116,6 +136,32 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
116136
</div>
117137
)}
118138
</Fade>
139+
140+
<Fade delay={1000} className="flex-[0_0_auto]">
141+
<div>
142+
<Separator />
143+
<div className="flex justify-end pt-3 pb-1">
144+
<TooltipProvider>
145+
<Tooltip>
146+
<TooltipTrigger className="flex gap-2 cursor-auto">
147+
<Switch checked={this.state.keepDashboard} onCheckedChange={handleKeepDashboardChanged} />
148+
<span>Keep dashboard open</span>
149+
</TooltipTrigger>
150+
<TooltipContent
151+
align="end"
152+
side="top"
153+
collisionPadding={8}
154+
className="bg-secondary text-muted-foreground text-sm rounded-lg mb-2 p-2 ring-2 ring-muted-foreground overflow-hidden"
155+
>
156+
If enabled, the dashboard will stay open when a project starts.
157+
<br />
158+
If disabled, the dashboard will close when a project starts and reopen after the project is closed.
159+
</TooltipContent>
160+
</Tooltip>
161+
</TooltipProvider>
162+
</div>
163+
</div>
164+
</Fade>
119165
</div>
120166

121167
<DashboardCreateProjectDialog

editor/src/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,20 @@ async function openDashboard(): Promise<void> {
107107
dashboardWindow.focus();
108108
}
109109

110-
ipcMain.on("dashboard:open-project", (_, file) => {
110+
function closeDashboard(): void {
111+
if (dashboardWindow) {
112+
dashboardWindow.close();
113+
dashboardWindow = null;
114+
}
115+
}
116+
117+
ipcMain.on("dashboard:open-project", (_, file: string, shouldCloseDashboard?: boolean) => {
111118
openProject(file);
112119
dashboardWindow?.minimize();
120+
121+
if (shouldCloseDashboard) {
122+
closeDashboard();
123+
}
113124
});
114125

115126
ipcMain.on("dashboard:update-projects", () => {
@@ -138,7 +149,7 @@ async function openProject(filePath: string): Promise<void> {
138149
notifyWindows("dashboard:opened-projects", openedProjects);
139150

140151
if (openedProjects.length === 0) {
141-
dashboardWindow?.restore();
152+
openDashboard();
142153
}
143154
});
144155

editor/src/tools/local-storage.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function tryGetExperimentalFeaturesEnabledFromLocalStorage(): boolean {
5454
}
5555

5656
/**
57-
* Sets wether or not experimental features are enabled in the local storage.
57+
* Sets whether or not experimental features are enabled in the local storage.
5858
* @param enabled defines wether or not experimental features are enabled.
5959
*/
6060
export function trySetExperimentalFeaturesEnabledInLocalStorage(enabled: boolean): void {
@@ -64,3 +64,26 @@ export function trySetExperimentalFeaturesEnabledInLocalStorage(enabled: boolean
6464
// Catch silently.
6565
}
6666
}
67+
68+
/**
69+
* Returns wether or not the dashboard should be closed when a project is opened.
70+
*/
71+
export function tryGetCloseDashboardOnProjectOpenFromLocalStorage(): boolean {
72+
try {
73+
return localStorage.getItem("babylonjs-editor-close-dashboard-on-project-open") === "true";
74+
} catch (e) {
75+
return false;
76+
}
77+
}
78+
79+
/**
80+
* Sets whether or not the dashboard should be closed when a project is opened.
81+
* @param enabled defines whether or not the dashboard should be closed when a project is opened.
82+
*/
83+
export function trySetCloseDashboardOnProjectOpenInLocalStorage(enabled: boolean): void {
84+
try {
85+
localStorage.setItem("babylonjs-editor-close-dashboard-on-project-open", JSON.stringify(enabled));
86+
} catch (e) {
87+
// Catch silently.
88+
}
89+
}

0 commit comments

Comments
 (0)