Refactor LayerUI (#1434)

* chore(gitignore): add .idea to gitignore

* refactor(layerui): pass named function to react.memo so that in dev tools the name shows up

This makes debugging easier as well

* refactor(layerui): break the functional component into multiple render methods
This commit is contained in:
Aakansha Doshi 2020-04-18 01:54:19 +05:30 committed by GitHub
parent 9131813661
commit a18342b5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 221 additions and 199 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ static
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
yarn.lock yarn.lock
.idea

View File

@ -114,7 +114,7 @@ import {
TAP_TWICE_TIMEOUT, TAP_TWICE_TIMEOUT,
} from "../time_constants"; } from "../time_constants";
import { LayerUI } from "./LayerUI"; import LayerUI from "./LayerUI";
import { ScrollBars, SceneState } from "../scene/types"; import { ScrollBars, SceneState } from "../scene/types";
import { generateCollaborationLink, getCollaborationLinkData } from "../data"; import { generateCollaborationLink, getCollaborationLinkData } from "../data";
import { mutateElement, newElementWith } from "../element/mutateElement"; import { mutateElement, newElementWith } from "../element/mutateElement";

View File

@ -40,8 +40,7 @@ interface LayerUIProps {
onLockToggle: () => void; onLockToggle: () => void;
} }
export const LayerUI = React.memo( const LayerUI = ({
({
actionManager, actionManager,
appState, appState,
setAppState, setAppState,
@ -54,7 +53,7 @@ export const LayerUI = React.memo(
}: LayerUIProps) => { }: LayerUIProps) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
function renderExportDialog() { const renderExportDialog = () => {
const createExporter = (type: ExportType): ExportCB => ( const createExporter = (type: ExportType): ExportCB => (
exportedElements, exportedElements,
scale, scale,
@ -92,44 +91,15 @@ export const LayerUI = React.memo(
}} }}
/> />
); );
} };
return isMobile ? ( const renderCanvasActions = () => (
<MobileMenu
appState={appState}
elements={elements}
actionManager={actionManager}
exportButton={renderExportDialog()}
setAppState={setAppState}
onUsernameChange={onUsernameChange}
onRoomCreate={onRoomCreate}
onRoomDestroy={onRoomDestroy}
onLockToggle={onLockToggle}
/>
) : (
<>
{appState.isLoading && <LoadingMessage />}
{appState.errorMessage && (
<ErrorDialog
message={appState.errorMessage}
onClose={() => setAppState({ errorMessage: null })}
/>
)}
{appState.showShortcutsDialog && (
<ShortcutsDialog
onClose={() => setAppState({ showShortcutsDialog: null })}
/>
)}
<FixedSideContainer side="top">
<HintViewer appState={appState} elements={elements} />
<div className="App-menu App-menu_top">
<Stack.Col gap={4}>
<Section heading="canvasActions"> <Section heading="canvasActions">
{/* the zIndex ensures this menu has higher stacking order, {/* the zIndex ensures this menu has higher stacking order,
see https://github.com/excalidraw/excalidraw/pull/1445 */} see https://github.com/excalidraw/excalidraw/pull/1445 */}
<Island padding={4} style={{ zIndex: 1 }}> <Island padding={4} style={{ zIndex: 1 }}>
<Stack.Col gap={4}> <Stack.Col gap={4}>
<Stack.Row gap={1} justifyContent={"space-between"}> <Stack.Row gap={1} justifyContent="space-between">
{actionManager.renderAction("loadScene")} {actionManager.renderAction("loadScene")}
{actionManager.renderAction("saveScene")} {actionManager.renderAction("saveScene")}
{renderExportDialog()} {renderExportDialog()}
@ -147,7 +117,9 @@ export const LayerUI = React.memo(
</Stack.Col> </Stack.Col>
</Island> </Island>
</Section> </Section>
{showSelectedShapeActions(appState, elements) && ( );
const renderSelectedShapeActions = () => (
<Section heading="selectedShapeActions"> <Section heading="selectedShapeActions">
<Island className={CLASSES.SHAPE_ACTIONS_MENU} padding={4}> <Island className={CLASSES.SHAPE_ACTIONS_MENU} padding={4}>
<SelectedShapeActions <SelectedShapeActions
@ -158,7 +130,20 @@ export const LayerUI = React.memo(
/> />
</Island> </Island>
</Section> </Section>
)} );
const renderFixedSideContainer = () => {
const shouldRenderSelectedShapeActions = showSelectedShapeActions(
appState,
elements,
);
return (
<FixedSideContainer side="top">
<HintViewer appState={appState} elements={elements} />
<div className="App-menu App-menu_top">
<Stack.Col gap={4}>
{renderCanvasActions()}
{shouldRenderSelectedShapeActions && renderSelectedShapeActions()}
</Stack.Col> </Stack.Col>
<Section heading="shapes"> <Section heading="shapes">
{(heading) => ( {(heading) => (
@ -197,9 +182,10 @@ export const LayerUI = React.memo(
</Stack.Col> </Stack.Col>
</div> </div>
</FixedSideContainer> </FixedSideContainer>
<aside> );
<GitHubCorner /> };
</aside>
const renderFooter = () => (
<footer role="contentinfo"> <footer role="contentinfo">
<LanguageList <LanguageList
onChange={(lng) => { onChange={(lng) => {
@ -221,10 +207,44 @@ export const LayerUI = React.memo(
</button> </button>
)} )}
</footer> </footer>
);
return isMobile ? (
<MobileMenu
appState={appState}
elements={elements}
actionManager={actionManager}
exportButton={renderExportDialog()}
setAppState={setAppState}
onUsernameChange={onUsernameChange}
onRoomCreate={onRoomCreate}
onRoomDestroy={onRoomDestroy}
onLockToggle={onLockToggle}
/>
) : (
<>
{appState.isLoading && <LoadingMessage />}
{appState.errorMessage && (
<ErrorDialog
message={appState.errorMessage}
onClose={() => setAppState({ errorMessage: null })}
/>
)}
{appState.showShortcutsDialog && (
<ShortcutsDialog
onClose={() => setAppState({ showShortcutsDialog: null })}
/>
)}
{renderFixedSideContainer()}
<aside>
<GitHubCorner />
</aside>
{renderFooter()}
</> </>
); );
}, };
(prev, next) => {
const areEqual = (prev: LayerUIProps, next: LayerUIProps) => {
const getNecessaryObj = (appState: AppState): Partial<AppState> => { const getNecessaryObj = (appState: AppState): Partial<AppState> => {
const { const {
draggingElement, draggingElement,
@ -247,5 +267,6 @@ export const LayerUI = React.memo(
prev.elements === next.elements && prev.elements === next.elements &&
keys.every((key) => prevAppState[key] === nextAppState[key]) keys.every((key) => prevAppState[key] === nextAppState[key])
); );
}, };
);
export default React.memo(LayerUI, areEqual);