Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion editor/src/dashboard/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { EditorProjectPackageManager, IEditorProject, EditorProjectTemplate } fr

export interface IDashboardCreateProjectDialogProps {
isOpened: boolean;
closeDashboardOnProjectOpen: boolean;
onClose: () => void;
}

Expand Down Expand Up @@ -101,7 +102,7 @@ export function DashboardCreateProjectDialog(props: IDashboardCreateProjectDialo
});

if (result) {
ipcRenderer.send("dashboard:open-project", projectAbsolutePath);
ipcRenderer.send("dashboard:open-project", projectAbsolutePath, props.closeDashboardOnProjectOpen);
}
} catch (e) {
showAlert("An unexpected error occured", e.message);
Expand Down
12 changes: 8 additions & 4 deletions editor/src/dashboard/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { DashboardProgressComponent } from "./progress";
export interface IDashboardProjectItemProps {
isOpened: boolean;
project: ProjectType;

closeDashboardOnProjectOpen: boolean;
onRemove: () => void;
}

Expand Down Expand Up @@ -127,6 +127,10 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
setPlayingAddress("");
}

function handleLoadProject() {
ipcRenderer.send("dashboard:open-project", props.project.absolutePath, props.closeDashboardOnProjectOpen);
}

function handleOpenInVisualStudioCode() {
execNodePty(`code "${dirname(props.project.absolutePath)}"`);
}
Expand All @@ -135,7 +139,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
<ContextMenu onOpenChange={(o) => setContextMenuOpen(o)}>
<ContextMenuTrigger>
<div
onDoubleClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}
onDoubleClick={handleLoadProject}
className={`
group
flex flex-col w-full rounded-lg cursor-pointer select-none
Expand Down Expand Up @@ -169,7 +173,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}>Open</DropdownMenuItem>
<DropdownMenuItem onClick={handleLoadProject}>Open</DropdownMenuItem>
<DropdownMenuItem className="flex items-center gap-2" onClick={() => ipcRenderer.send("editor:show-item", props.project.absolutePath)}>
{`Show in ${isDarwin() ? "Finder" : "Explorer"}`}
</DropdownMenuItem>
Expand Down Expand Up @@ -214,7 +218,7 @@ export function DashboardProjectItem(props: IDashboardProjectItemProps) {
</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem onClick={() => ipcRenderer.send("dashboard:open-project", props.project.absolutePath)}>Open</ContextMenuItem>
<ContextMenuItem onClick={handleLoadProject}>Open</ContextMenuItem>
<ContextMenuItem className="flex items-center gap-2" onClick={() => ipcRenderer.send("editor:show-item", props.project.absolutePath)}>
{`Show in ${isDarwin() ? "Finder" : "Explorer"}`}
</ContextMenuItem>
Expand Down
108 changes: 76 additions & 32 deletions editor/src/dashboard/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ import { wait } from "../tools/tools";
import { openSingleFileDialog } from "../tools/dialog";
import { ProjectType, projectsKey } from "../tools/project";
import { checkNodeJSAvailable, nodeJSAvailable } from "../tools/process";
import { tryAddProjectToLocalStorage, tryGetProjectsFromLocalStorage } from "../tools/local-storage";
import {
tryAddProjectToLocalStorage,
tryGetCloseDashboardOnProjectOpenFromLocalStorage,
tryGetProjectsFromLocalStorage,
trySetCloseDashboardOnProjectOpenInLocalStorage,
} from "../tools/local-storage";

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

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

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

createProject: boolean;
closeDashboardOnProjectOpen: boolean;
}

export class Dashboard extends Component<IDashboardProps, IDashboardState> {
Expand All @@ -59,48 +67,61 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
projects: tryGetProjectsFromLocalStorage(),

createProject: false,
closeDashboardOnProjectOpen: tryGetCloseDashboardOnProjectOpenFromLocalStorage(),
};

webFrame.setZoomFactor(0.8);
}

public render(): ReactNode {
return (
<>
<div className="flex flex-col gap-4 w-screen h-screen p-5 select-none overflow-x-hidden pt-10">
<DashboardWindowControls />

<Fade delay={0}>
<div className="flex justify-between items-end w-full mt-1">
<div className="text-5xl font-semibold">Dashboard</div>
const handleKeepDashboardChanged = (checked: boolean): void => {
const shouldClose = !checked;

<div className="flex flex-col items-end gap-2">
<img alt="" src="assets/babylonjs_icon.png" className="w-[48px] object-contain" />
<div className="text-xs">Babylon.js Editor v{packageJson.version}</div>
</div>
</div>
</Fade>
this.setState({
closeDashboardOnProjectOpen: shouldClose,
});

<Fade delay={250}>
<Separator />
</Fade>
trySetCloseDashboardOnProjectOpenInLocalStorage(shouldClose);
};

<Fade delay={500}>
<div className="flex justify-between items-center">
<div className="text-3xl font-semibold">Projects</div>

<div className="flex gap-2">
<Button variant="secondary" className="font-semibold" onClick={() => this._handleImportProject()}>
Import project
</Button>
<Button className="font-semibold" onClick={() => this.setState({ createProject: true })}>
Create project
</Button>
return (
<>
<div className="flex flex-col gap-4 w-screen h-screen p-5 select-none pt-10">
<div className="flex flex-col gap-4 flex-[0_0_auto]">
<DashboardWindowControls />

<Fade delay={0}>
<div className="flex justify-between items-end w-full mt-1">
<div className="text-5xl font-semibold">Dashboard</div>

<div className="flex flex-col items-end gap-2">
<img alt="" src="assets/babylonjs_icon.png" className="w-[48px] object-contain" />
<div className="text-xs">Babylon.js Editor v{packageJson.version}</div>
</div>
</div>
</div>
</Fade>
</Fade>

<Fade delay={250}>
<Separator />
</Fade>

<Fade delay={500}>
<div className="flex justify-between items-center">
<div className="text-3xl font-semibold">Projects</div>

<div className="flex gap-2">
<Button variant="secondary" className="font-semibold" onClick={() => this._handleImportProject()}>
Import project
</Button>
<Button className="font-semibold" onClick={() => this.setState({ createProject: true })}>
Create project
</Button>
</div>
</div>
</Fade>
</div>

<Fade delay={750}>
<Fade delay={750} className="flex-auto overflow-y-auto p-2">
{!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>}

{this.state.projects.length && (
Expand All @@ -110,16 +131,39 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
project={project}
key={project.absolutePath}
isOpened={this.state.openedProjects.includes(project.absolutePath)}
closeDashboardOnProjectOpen={this.state.closeDashboardOnProjectOpen}
onRemove={() => this._tryRemoveProjectFromLocalStorage(project)}
/>
))}
</div>
)}
</Fade>

<Fade delay={1000} className="flex-[0_0_auto]">
<div>
<Separator />
<div className="flex justify-end pt-3 pb-1">
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="flex items-center gap-2 cursor-auto">
<Switch checked={!this.state.closeDashboardOnProjectOpen} onCheckedChange={handleKeepDashboardChanged} />
<span>Keep dashboard open</span>
</TooltipTrigger>
<TooltipContent align="end" side="top" collisionPadding={8}>
If enabled, the dashboard will stay open when a project starts.
<br />
If disabled, the dashboard will close when a project starts and reopen after the project is closed.
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
</Fade>
</div>

<DashboardCreateProjectDialog
isOpened={this.state.createProject}
closeDashboardOnProjectOpen={this.state.closeDashboardOnProjectOpen}
onClose={() => {
this.setState({
createProject: false,
Expand Down
15 changes: 13 additions & 2 deletions editor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,20 @@ async function openDashboard(): Promise<void> {
dashboardWindow.focus();
}

ipcMain.on("dashboard:open-project", (_, file) => {
function closeDashboard(): void {
if (dashboardWindow) {
dashboardWindow.close();
dashboardWindow = null;
}
}

ipcMain.on("dashboard:open-project", (_, file: string, shouldCloseDashboard?: boolean) => {
openProject(file);
dashboardWindow?.minimize();

if (shouldCloseDashboard) {
closeDashboard();
}
});

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

if (openedProjects.length === 0) {
dashboardWindow?.restore();
openDashboard();
}
});

Expand Down
25 changes: 24 additions & 1 deletion editor/src/tools/local-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function tryGetExperimentalFeaturesEnabledFromLocalStorage(): boolean {
}

/**
* Sets wether or not experimental features are enabled in the local storage.
* Sets whether or not experimental features are enabled in the local storage.
* @param enabled defines wether or not experimental features are enabled.
*/
export function trySetExperimentalFeaturesEnabledInLocalStorage(enabled: boolean): void {
Expand All @@ -64,3 +64,26 @@ export function trySetExperimentalFeaturesEnabledInLocalStorage(enabled: boolean
// Catch silently.
}
}

/**
* Returns wether or not the dashboard should be closed when a project is opened.
*/
export function tryGetCloseDashboardOnProjectOpenFromLocalStorage(): boolean {
try {
return localStorage.getItem("babylonjs-editor-close-dashboard-on-project-open") === "true";
} catch (e) {
return false;
}
}

/**
* Sets whether or not the dashboard should be closed when a project is opened.
* @param enabled defines whether or not the dashboard should be closed when a project is opened.
*/
export function trySetCloseDashboardOnProjectOpenInLocalStorage(enabled: boolean): void {
try {
localStorage.setItem("babylonjs-editor-close-dashboard-on-project-open", JSON.stringify(enabled));
} catch (e) {
// Catch silently.
}
}