Skip to content

Commit 81b98c4

Browse files
committed
add editor loading screen
1 parent 743245b commit 81b98c4

File tree

8 files changed

+81
-51
lines changed

8 files changed

+81
-51
lines changed

packages/main/src/mainWindow.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ async function createWindow() {
1414
},
1515
});
1616

17+
browserWindow.setMenuBarVisibility(false);
18+
1719
/**
1820
* If the 'show' property of the BrowserWindow's constructor is omitted from the initialization options,
1921
* it then defaults to 'true'. This can cause flickering as the window loads the html content,

packages/renderer/src/components/Dropdown/component.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ function Dropdown(props: Props) {
1212
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
1313
const open = Boolean(anchorEl);
1414

15-
const handleClick = useCallback((event: MouseEvent<HTMLElement>) => {
16-
setAnchorEl(event.currentTarget);
15+
const handleClick = useCallback((e: MouseEvent<HTMLElement>) => {
16+
e.stopPropagation();
17+
setAnchorEl(e.currentTarget);
1718
}, []);
1819

19-
const handleSelect = useCallback((_: MouseEvent<HTMLLIElement>, option: Option) => {
20+
const handleSelect = useCallback((e: MouseEvent<HTMLLIElement>, option: Option) => {
21+
e.stopPropagation();
2022
setAnchorEl(null);
2123
option.handler();
2224
}, []);
2325

24-
const handleClose = useCallback(() => {
26+
const handleClose = useCallback((e: MouseEvent<HTMLElement>) => {
27+
e.stopPropagation();
2528
setAnchorEl(null);
2629
}, []);
2730

packages/renderer/src/components/ProjectCard/component.tsx

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { useCallback, useState } from 'react';
22
import ViewModuleIcon from '@mui/icons-material/ViewModule';
33
import cx from 'classnames';
4-
import { Link } from 'react-router-dom';
54

65
import { getThumbnailUrl } from '/@/modules/project';
76
import { t } from '/@/modules/store/translation/utils';
@@ -13,10 +12,14 @@ import type { Props } from './types';
1312

1413
import './styles.css';
1514

16-
export function ProjectCard({ project, onDelete, onDuplicate }: Props) {
15+
export function ProjectCard({ project, onClick, onDelete, onDuplicate }: Props) {
1716
const [open, setOpen] = useState(false);
1817
const parcels = project.layout.cols * project.layout.rows;
1918

19+
const handleClick = useCallback(() => {
20+
if (onClick) onClick(project);
21+
}, [project, onClick]);
22+
2023
const handleDeleteProject = useCallback(() => {
2124
onDelete(project);
2225
handleCloseModal();
@@ -48,36 +51,37 @@ export function ProjectCard({ project, onDelete, onDuplicate }: Props) {
4851
];
4952

5053
return (
51-
<div className={cx('ProjectCard', { 'has-thumbnail': !!thumbnailUrl })}>
52-
<Link
53-
to={`/editor?path=${encodeURIComponent(project.path)}`}
54-
className="project-thumbnail"
55-
style={thumbnailUrl ? { backgroundImage: `url(${thumbnailUrl})` } : {}}
56-
/>
57-
<div className="project-data">
58-
<Link
59-
to={`/editor?path=${encodeURIComponent(project.path)}`}
60-
className="title-wrapper"
61-
>
62-
<div className="title">{project.title}</div>
63-
<div
64-
className="description"
65-
title={project.description}
66-
>
67-
<ViewModuleIcon className="Icon" /> {t('scene_list.parcel_count', { parcels })}
68-
</div>
69-
</Link>
70-
<Dropdown
71-
className="options-dropdown"
72-
options={dropdownOptions}
54+
<>
55+
<div
56+
className={cx('ProjectCard', { 'has-thumbnail': !!thumbnailUrl })}
57+
onClick={handleClick}
58+
>
59+
<div
60+
className="project-thumbnail"
61+
style={thumbnailUrl ? { backgroundImage: `url(${thumbnailUrl})` } : {}}
7362
/>
63+
<div className="project-data">
64+
<div className="title-wrapper">
65+
<div className="title">{project.title}</div>
66+
<div
67+
className="description"
68+
title={project.description}
69+
>
70+
<ViewModuleIcon className="Icon" /> {t('scene_list.parcel_count', { parcels })}
71+
</div>
72+
</div>
73+
<Dropdown
74+
className="options-dropdown"
75+
options={dropdownOptions}
76+
/>
77+
</div>
7478
</div>
7579
<DeleteProject
7680
open={open}
7781
project={project}
7882
onClose={handleCloseModal}
7983
onSubmit={handleDeleteProject}
8084
/>
81-
</div>
85+
</>
8286
);
8387
}

packages/renderer/src/components/ProjectCard/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Project } from '/shared/types/projects';
22

33
export type Props = {
44
project: Project;
5+
onClick: (project: Project) => void;
56
onDelete: (project: Project) => void;
67
onDuplicate: (project: Project) => void;
78
};

packages/renderer/src/components/SceneList/component.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ function NoScenesAnchor(content: string) {
2929
}
3030

3131
export function SceneList({ projects, sortBy, onSort }: Props) {
32-
const { deleteProject, duplicateProject, importProject, createProject } = useWorkspace();
32+
const { selectProject, deleteProject, duplicateProject, importProject, createProject } =
33+
useWorkspace();
3334

3435
const sort = useCallback(
3536
(_sortBy: SortBy) => {
@@ -65,6 +66,7 @@ export function SceneList({ projects, sortBy, onSort }: Props) {
6566
<ProjectCard
6667
key={project.path}
6768
project={project}
69+
onClick={selectProject}
6870
onDelete={deleteProject}
6971
onDuplicate={duplicateProject}
7072
/>

packages/renderer/src/hooks/useEditor.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
import { useCallback, useMemo } from 'react';
2-
import { useSearchParams } from 'react-router-dom';
1+
import { useCallback } from 'react';
32

43
import { useDispatch, useSelector } from '#store';
54

65
import type { DeployOptions } from '/shared/types/ipc';
76
import { actions } from '/@/modules/store/editor';
87

9-
import { useWorkspace } from './useWorkspace';
10-
118
export const useEditor = () => {
129
const dispatch = useDispatch();
1310
const editor = useSelector(state => state.editor);
14-
const [search] = useSearchParams();
15-
const path = useMemo(() => search.get('path'), [search]);
16-
const workspace = useWorkspace();
17-
const project = useMemo(() => {
18-
return workspace.projects.find(project => project.path === path);
19-
}, [workspace.projects, path]);
11+
const { project } = editor;
2012

2113
const startInspector = useCallback(() => {
2214
dispatch(actions.startInspector());

packages/renderer/src/hooks/useWorkspace.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,60 @@
11
import { useDispatch, useSelector } from '#store';
22
import { useCallback } from 'react';
3-
import { actions } from '/@/modules/store/workspace';
3+
44
import { type Project, type SortBy } from '/shared/types/projects';
55

6+
import { actions as editorActions } from '/@/modules/store/editor';
7+
import { actions as workspaceActions } from '/@/modules/store/workspace';
8+
import { useNavigate } from 'react-router-dom';
9+
610
export const useWorkspace = () => {
711
const dispatch = useDispatch();
12+
const navigate = useNavigate();
813
const workspace = useSelector(state => state.workspace);
914

1015
const getWorkspace = useCallback(() => {
11-
dispatch(actions.getWorkspace());
16+
dispatch(workspaceActions.getWorkspace());
1217
}, []);
1318

1419
const setSortBy = useCallback((type: SortBy) => {
15-
dispatch(actions.setSortBy(type));
20+
dispatch(workspaceActions.setSortBy(type));
21+
}, []);
22+
23+
const selectProject = useCallback((project: Project) => {
24+
dispatch(editorActions.setProject(project));
25+
navigate('/editor');
1626
}, []);
1727

1828
const createProject = useCallback(() => {
19-
dispatch(actions.createProject());
29+
dispatch(workspaceActions.createProject());
30+
navigate('/editor');
2031
}, []);
2132

2233
const deleteProject = useCallback((project: Project) => {
23-
dispatch(actions.deleteProject(project.path));
34+
dispatch(workspaceActions.deleteProject(project.path));
2435
}, []);
2536

2637
const duplicateProject = useCallback((project: Project) => {
27-
dispatch(actions.duplicateProject(project.path));
38+
dispatch(workspaceActions.duplicateProject(project.path));
2839
}, []);
2940

3041
const importProject = useCallback(() => {
31-
dispatch(actions.importProject());
42+
dispatch(workspaceActions.importProject());
3243
}, []);
3344

3445
const reimportProject = useCallback((path: string) => {
35-
dispatch(actions.reimportProject(path));
46+
dispatch(workspaceActions.reimportProject(path));
3647
}, []);
3748

3849
const unlistProjects = useCallback((paths: string[]) => {
39-
dispatch(actions.unlistProjects(paths));
50+
dispatch(workspaceActions.unlistProjects(paths));
4051
}, []);
4152

4253
return {
4354
...workspace,
4455
getWorkspace,
4556
setSortBy,
57+
selectProject,
4658
createProject,
4759
deleteProject,
4860
duplicateProject,

packages/renderer/src/modules/store/editor/slice.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { editor } from '#preload';
2-
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
2+
import { createAsyncThunk, createSlice, type PayloadAction } from '@reduxjs/toolkit';
3+
4+
import { type Project } from '/shared/types/projects';
5+
import { actions as workspaceActions } from '../workspace';
36

47
// actions
58
export const startInspector = createAsyncThunk('editor/startInspector', editor.startInspector);
@@ -9,6 +12,7 @@ export const openPreview = createAsyncThunk('editor/openPreview', editor.openPre
912

1013
// state
1114
export type EditorState = {
15+
project?: Project;
1216
inspectorPort: number;
1317
previewPort: number;
1418
publishPort: number;
@@ -34,7 +38,11 @@ const initialState: EditorState = {
3438
export const slice = createSlice({
3539
name: 'editor',
3640
initialState,
37-
reducers: {},
41+
reducers: {
42+
setProject: (state, { payload: project }: PayloadAction<Project>) => {
43+
state.project = project;
44+
},
45+
},
3846
extraReducers: builder => {
3947
builder.addCase(startInspector.pending, state => {
4048
state.inspectorPort = 0;
@@ -72,6 +80,12 @@ export const slice = createSlice({
7280
state.error = action.error.message || null;
7381
state.loadingPublish = false;
7482
});
83+
builder.addCase(workspaceActions.createProject.pending, state => {
84+
state.project = undefined;
85+
});
86+
builder.addCase(workspaceActions.createProject.fulfilled, (state, action) => {
87+
state.project = action.payload;
88+
});
7589
},
7690
});
7791

0 commit comments

Comments
 (0)