From 0fda7ebbbbb9b230040479fb85781019ef66570f Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Mon, 11 Oct 2021 22:23:23 +1100 Subject: [PATCH] Update mosaic tree to remove and add the console. --- .../components/IdeContainer/IdeContainer.tsx | 2 +- .../components/IdeSideBar/sidebarConfig.tsx | 90 ++++++++++++++++--- app/web/src/helpers/hooks/useIdeState.ts | 4 +- 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/app/web/src/components/IdeContainer/IdeContainer.tsx b/app/web/src/components/IdeContainer/IdeContainer.tsx index 0286838..ab96998 100644 --- a/app/web/src/components/IdeContainer/IdeContainer.tsx +++ b/app/web/src/components/IdeContainer/IdeContainer.tsx @@ -110,7 +110,7 @@ const IdeContainer = () => { }} value={state.layout} onChange={(newLayout) => - thunkDispatch({ type: 'setLayout', payload: { message: newLayout } }) + thunkDispatch({ type: 'setLayout', payload: newLayout }) } onRelease={handleViewerSizeUpdate} /> diff --git a/app/web/src/components/IdeSideBar/sidebarConfig.tsx b/app/web/src/components/IdeSideBar/sidebarConfig.tsx index 5659a38..eaee359 100644 --- a/app/web/src/components/IdeSideBar/sidebarConfig.tsx +++ b/app/web/src/components/IdeSideBar/sidebarConfig.tsx @@ -1,7 +1,8 @@ -import React, { ReactNode } from 'react' +import { ReactNode } from 'react' import { SvgNames } from 'src/components/Svg/Svg' import { useIdeContext } from 'src/helpers/hooks/useIdeContext' - +import { createRemoveUpdate, updateTree } from 'react-mosaic-component' +import type { MosaicPath } from 'react-mosaic-component' interface SidebarConfigType { name: string icon: SvgNames @@ -9,6 +10,39 @@ interface SidebarConfigType { panel: ReactNode | null } +interface MosaicTree { + first: string | MosaicTree + second: string | MosaicTree +} + +const getPathById = ( + tree: MosaicTree, + id: string, + path: MosaicPath = [] +): MosaicPath => { + if (tree.first === id || tree.second === id) { + return [...path, tree.first === id ? 'first' : 'second'] + } + if (typeof tree.first !== 'string' && typeof tree.second !== 'string') { + throw new Error('id not found') + } + try { + if (typeof tree.first !== 'string') { + return getPathById(tree.first, id, [...path, 'first']) + } + } catch (error) { + throw new Error('id not found') + } + try { + if (typeof tree.second !== 'string') { + return getPathById(tree.second, id, [...path, 'second']) + } + } catch (error) { + throw new Error('id not found') + } + throw new Error('id not found') +} + export const sidebarTopConfig: SidebarConfigType[] = [ { name: 'Files', @@ -106,20 +140,52 @@ const settingsConfig: settingsConfig[] = [ title: 'Console', name: 'console', Content: () => { - const { state, thunkDispatch } = useIdeContext() + const { state, thunkDispatch } = useIdeContext() + const consolePath = React.useMemo(() => { + try { + const path = getPathById(state.layout, 'Console') + return path + } catch (error) { + return null + } + }, [state.layout]) return (
-
  • +
  • Visible
    - { - state.consoleVisible = !state.consoleVisible - if (state.consoleVisible) - thunkDispatch({ type: 'resetLayout'}) - else - thunkDispatch({ type: 'setLayout', payload:{ message:{ direction: 'row', first: 'Editor', second: 'Viewer'}}}) - }} - checked={state.consoleVisible}/> + if (consolePath) { + const newTree = updateTree(state.layout, [ + createRemoveUpdate(state.layout, consolePath), + ]) + thunkDispatch({ type: 'setLayout', payload: newTree }) + } else { + // Split 'Viewer' panel to add console back in + const viewerPath = getPathById(state.layout, 'Viewer') + const newTree = { ...state.layout } + let temp = newTree + viewerPath.forEach((name) => { + if (newTree[name] === 'Viewer') { + newTree[name] = { + direction: 'column', + first: 'Viewer', + second: 'Console', + splitPercentage: 70, + } + return + } + temp = { ...newTree[name] } + }) + thunkDispatch({ type: 'setLayout', payload: newTree }) + } + }} + checked={!!consolePath} + />
  • ) diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts index 8e2a79e..679f184 100644 --- a/app/web/src/helpers/hooks/useIdeState.ts +++ b/app/web/src/helpers/hooks/useIdeState.ts @@ -57,7 +57,6 @@ export interface State { isLoading: boolean threeInstance: RootState sideTray: string[] // could probably be an array of a union type - consoleVisible: boolean } const code = '' @@ -94,7 +93,6 @@ export const initialState: State = { isLoading: false, threeInstance: null, sideTray: [], - consoleVisible: true, } const reducer = (state: State, { type, payload }): State => { @@ -170,7 +168,7 @@ const reducer = (state: State, { type, payload }): State => { case 'setLayout': return { ...state, - layout: payload.message, + layout: payload, } case 'updateCamera': return {