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
45 changes: 7 additions & 38 deletions packages/origine2/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
import './App.css';
import DashBoard from './pages/dashboard/DashBoard';
import Editor from './pages/editor/Editor';
import { ReactNode, useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import '@icon-park/react/styles/index.css';
import './config/themes/theme.css';
import './assets/font-family.css';
import useEditorStore from './store/useEditorStore';
import useHashRoute, { IPage } from './hooks/useHashRoute';
import useLanguage from './hooks/useLanguage';
import TemplateEditor from './pages/templateEditor/TemplateEditor';
import GameEditorProvider from './components/Provider/GameEditorProvider';
import TemplateEditorProvider from './components/Provider/TemplateEditorProvider';
import { eventBus } from '@/utils/eventBus';
import { initMonaco } from "@/utils/initMonaco";

export const routers: { [key in IPage]: { url: string; element: ReactNode } } = {
dashboard: {
url: '#/dashboard',
element: <DashBoard />,
},
game: {
url: '#/game',
element: (
<GameEditorProvider>
<Editor />
</GameEditorProvider>
),
},
template: {
url: '#/template',
element: (
<TemplateEditorProvider>
<TemplateEditor />
</TemplateEditorProvider>
),
},
};
import { initMonaco } from '@/utils/initMonaco';
import { useHashRouter, RouterPage } from '@/router';

function App() {
useEffect(() => {
initMonaco();
}, []);

// 建立 WS 连接
useEffect(() => {

}, []);
// // 建立 WS 连接
// useEffect(() => {}, []);

useHashRoute();
useHashRouter();
useLanguage();

const page = useEditorStore.use.page();
Expand All @@ -62,7 +31,7 @@ function App() {

return (
<div className="App" key={appKeyLang}>
{routers[page].element || routers.dashboard.element}
<RouterPage page={page} />
</div>
);
}
Expand Down
44 changes: 0 additions & 44 deletions packages/origine2/src/hooks/useHashRoute.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/origine2/src/pages/dashboard/DashBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import classNames from "classnames";
import useEditorStore from "@/store/useEditorStore";
import {api} from "@/api";
import useSWR, {useSWRConfig} from "swr";
import {redirect} from "@/hooks/useHashRoute";
import { goTo } from '@/router';
import {t} from "@lingui/macro";
import { useRelease } from "@/hooks/useRelease";
import { __INFO } from "@/config/info";
Expand Down Expand Up @@ -89,7 +89,7 @@ export default function DashBoard() {
const selectedValue = subPage;

const onTabSelect = (event: SelectTabEvent, data: SelectTabData) => {
redirect('dashboard', data.value as string);
goTo('dashboard', data.value as string);
};

// 当前选中的游戏
Expand Down
4 changes: 2 additions & 2 deletions packages/origine2/src/pages/dashboard/GameElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { api } from "@/api";
import { Button, Checkbox, Dialog, DialogActions, DialogBody, DialogContent, DialogSurface, DialogTitle, Input, Menu, MenuButton, MenuItem, MenuList, MenuPopover, MenuTrigger } from "@fluentui/react-components";
import { Delete24Filled, Delete24Regular, FolderOpen24Filled, FolderOpen24Regular, MoreVertical24Filled, MoreVertical24Regular, Open24Filled, Open24Regular, Rename24Filled, Rename24Regular, bundleIcon } from "@fluentui/react-icons";
import { localStorageRename } from "@/utils/localStorageRename";
import { routers } from "@/App";
import { routes } from '@/router';
import { t } from "@lingui/macro";
import { GameInfoDto } from "@/api/Api";

Expand Down Expand Up @@ -84,7 +84,7 @@ export default function GameElement(props: IGameElementProps) {
<div className={styles.gameElement_sub}>
<span className={styles.gameElement_dir}>{props.gameInfo.dir}</span>
<div className={styles.gameElement_action} onClick={(event) => event.stopPropagation()}>
<Button appearance='primary' as='a' href={`${routers.game.url}/${props.gameInfo.dir}`}>
<Button appearance='primary' as='a' href={`${routes.game.url}/${props.gameInfo.dir}`}>
<span style={{textWrap: 'nowrap'}}>{t`编辑游戏`}</span>
</Button>
<Menu>
Expand Down
4 changes: 2 additions & 2 deletions packages/origine2/src/pages/dashboard/TemplateElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Delete24Filled, Delete24Regular, FolderOpen24Filled, FolderOpen24Regula
import { useMemo } from "react";
import { useValue } from "../../hooks/useValue";
import { api } from "@/api";
import { routers } from "@/App";
import { routes } from '@/router';
import { t } from "@lingui/macro";
import { localStorageRename } from "@/utils/localStorageRename";
import { TemplateInfoDto } from "@/api/Api";
Expand Down Expand Up @@ -78,7 +78,7 @@ export default function TemplateElement(props: ITemplateElementProps){
<div className={styles.templateElement_sub}>
<span className={styles.templateElement_dir}>{props.templateInfo.dir}</span>
<div className={styles.templateElement_action} onClick={(event) => event.stopPropagation()}>
<Button appearance='primary' as='a' href={`${routers.template.url}/${props.templateInfo.dir}`}>
<Button appearance='primary' as='a' href={`${routes.template.url}/${props.templateInfo.dir}`}>
<span style={{textWrap: 'nowrap'}}>{t`编辑模板`}</span>
</Button>
<Menu>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { redirect } from "@/hooks/useHashRoute";
import { goTo } from "@/router";
import { gameListFetcher } from "@/pages/dashboard/DashBoard";
import useEditorStore from "@/store/useEditorStore";
import { GameEditorContext, createGameEditorStore } from "@/store/useGameEditorStore";
Expand All @@ -11,15 +11,15 @@ const GameEditorProvider = ({ children }: { children: ReactNode }) => {
const gameDir = useEditorStore.use.subPage();

if (page !== 'game' || !gameDir) {
redirect('dashboard', 'game');
goTo('dashboard', 'game');
};
Comment on lines 13 to 15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When a component redirects, it's a good practice to stop its rendering process to avoid unnecessary computations and potential side effects from hooks that run after the redirection logic. Here, the component continues to render after goTo is called. You should add return null; to exit early. This also allows removing the redundant semicolon on line 15.

  if (page !== 'game' || !gameDir) {
    goTo('dashboard', 'game');
    return null;
  }


const { data: gameList, isLoading: gameListLoading } = useSWR("game-list", gameListFetcher);
const fristLoading = gameListLoading && !gameList;
const inGameList = gameList && gameList.length > 0 && gameList.some((game) => game.dir === gameDir);

if (!fristLoading && !inGameList) {
redirect('dashboard', 'game');
goTo('dashboard', 'game');
}
Comment on lines 21 to 23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the check above, you should return null after redirecting to prevent the component from rendering further in the current pass.

  if (!fristLoading && !inGameList) {
    goTo('dashboard', 'game');
    return null;
  }


return (
Expand All @@ -45,4 +45,4 @@ const GameEditorContextProvider = ({ children }: { children: ReactNode }) => {
);
};

export default GameEditorProvider;
export default GameEditorProvider;
4 changes: 2 additions & 2 deletions packages/origine2/src/pages/editor/Topbar/Topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
import useEditorStore from "@/store/useEditorStore";
import {useGameEditorContext} from "@/store/useGameEditorStore";
import {IGameEditorSidebarTabs, IGameEditorTopbarTabs} from "@/types/gameEditor";
import {redirect} from "@/hooks/useHashRoute";
import { goTo } from '@/router';
import {t} from "@lingui/macro";
import BackDashboardButton from "@/pages/editor/Topbar/components/BackDashboardButton";

Expand Down Expand Up @@ -90,7 +90,7 @@ export default function TopBar() {
}
}, [isShowAddSceneTab]);

const backToDashboard = () => redirect('dashboard', 'game');
const backToDashboard = () => goTo('dashboard', 'game');

return <div className={styles.editor_topbar}>
<Toolbar>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { redirect } from "@/hooks/useHashRoute";
import { goTo } from "@/router";
import { templateListFetcher } from "@/pages/dashboard/DashBoard";
import useEditorStore from "@/store/useEditorStore";
import { TemplateEditorContext, createTemplateEditorStore } from "@/store/useTemplateEditorStore";
Expand All @@ -11,15 +11,15 @@ const TemplateEditorProvider = ({ children }: { children: ReactNode }) => {
const templateDir = useEditorStore.use.subPage();

if (page !== 'template' || !templateDir) {
redirect('dashboard', 'template');
goTo('dashboard', 'template');
}
Comment on lines 13 to 15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

When a component redirects, it's a good practice to stop its rendering process to avoid unnecessary computations. Here, the component continues to render after goTo is called. You should add return null; to exit early.

  if (page !== 'template' || !templateDir) {
    goTo('dashboard', 'template');
    return null;
  }


const {data: templateList, isLoading: templateListLoading} = useSWR("template-list", templateListFetcher);
const fristLoading = templateListLoading && !templateList;
const inTemplateList = templateList && templateList.length > 0 && templateList.some((template) => template.dir === templateDir);

if (!fristLoading && !inTemplateList) {
redirect('dashboard', 'template');
goTo('dashboard', 'template');
}
Comment on lines 21 to 23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the check above, you should return null after redirecting to prevent the component from rendering further in the current pass.

  if (!fristLoading && !inTemplateList) {
    goTo('dashboard', 'template');
    return null;
  }


return (
Expand All @@ -38,7 +38,7 @@ const TemplateEditorProvider = ({ children }: { children: ReactNode }) => {
const TemplateEditorContextProvider = ({ children }: { children: ReactNode}) => {
const page = useEditorStore.use.page();
const subPage = useEditorStore.use.subPage();
if (page !== 'template' || !subPage) redirect('dashboard');
if (page !== 'template' || !subPage) goTo('dashboard');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent the component from continuing its render cycle after redirection, you should return early. This avoids running subsequent hooks and logic unnecessarily.

  if (page !== 'template' || !subPage) {
    goTo('dashboard');
    return null;
  }

const templateEditorStore = useRef(createTemplateEditorStore(subPage)).current;
return(
<TemplateEditorContext.Provider value={templateEditorStore}>
Expand All @@ -47,4 +47,4 @@ const TemplateEditorContextProvider = ({ children }: { children: ReactNode}) =>
);
};

export default TemplateEditorProvider;
export default TemplateEditorProvider;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ArrowLeftFilled, ArrowLeftRegular, bundleIcon, NavigationFilled, Navigat
import {ITab} from '@/types/templateEditor';
import {t} from "@lingui/macro";
import BackDashboardButton from "@/pages/editor/Topbar/components/BackDashboardButton";
import {redirect} from "@/hooks/useHashRoute";
import { goTo } from '@/router';
import CommonTips from "@/pages/editor/GraphicalEditor/components/CommonTips";
import { api } from '@/api';
import { GameInfoDto } from '@/api/Api';
Expand Down Expand Up @@ -44,7 +44,7 @@ export default function TemplateEditorSidebar() {
updateCurrentTab(newTab);
};

const backToDashboard = () => redirect('dashboard', 'template');
const backToDashboard = () => goTo('dashboard', 'template');

// 当前模板没有id时自动添加
useEffect(() => {
Expand Down
72 changes: 72 additions & 0 deletions packages/origine2/src/router/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useEffect, type ReactNode } from 'react';
import useEditorStore from '@/store/useEditorStore';
import DashBoard from '@/pages/dashboard/DashBoard';
import GameEditorProvider from '@/pages/editor/GameEditorProvider';
import Editor from '@/pages/editor/Editor';
import TemplateEditorProvider from '@/pages/templateEditor/TemplateEditorProvider';
import TemplateEditor from '@/pages/templateEditor/TemplateEditor';

export type IPage = 'dashboard' | 'game' | 'template';

export const routes: { [key in IPage]: { url: string; element: ReactNode } } = {
dashboard: {
url: '#/dashboard',
element: <DashBoard />,
},
game: {
url: '#/game',
element: (
<GameEditorProvider>
<Editor />
</GameEditorProvider>
),
},
template: {
url: '#/template',
element: (
<TemplateEditorProvider>
<TemplateEditor />
</TemplateEditorProvider>
),
},
};

export function RouterPage({ page }: { page: IPage }) {
return routes[page].element || routes.dashboard.element;
}

export const goTo = (page: IPage, subPage?: string) => {
window.location.hash = `${routes[page].url}${subPage ? `/${subPage}` : ''}`;
};

export function useHashRouter() {
const updatePage = useEditorStore.use.updatePage();
const updateSubPage = useEditorStore.use.updateSubPage();

useEffect(() => {
const handleHashChange = () => {
const [, _page, _subPage] = window.location.hash.split('/');
if (['game', 'template'].includes(_page) && _subPage && _subPage.length > 0) {
updatePage(_page as IPage);
try {
updateSubPage(decodeURIComponent(_subPage));
} catch (error) {
console.warn('Update sub page error!', error);
updateSubPage(_page);
goTo('dashboard', _page);
}
} else if (_page === 'dashboard' && ['game', 'template'].includes(_subPage)) {
updatePage('dashboard');
updateSubPage(_subPage);
} else {
updateSubPage('game');
goTo('dashboard', 'game');
}
};
handleHashChange();
window.addEventListener('hashchange', handleHashChange);
return () => {
window.removeEventListener('hashchange', handleHashChange);
};
}, []);
}
2 changes: 1 addition & 1 deletion packages/origine2/src/types/editor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IViewType, ISortBy, ISortOrder } from "@/components/Assets/Assets";
import { IPage } from "@/hooks/useHashRoute";
import { type IPage } from '@/router';
import {IGameEditorState} from "@/types/gameEditor";

export interface IEditorState {
Expand Down