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' ; import Toggle from 'src/components/Toggle' ; import type { MosaicTree } from 'src/helpers/hooks/useIdeState' ; interface SidebarConfigType { name : string ; icon : SvgNames ; disabled : boolean ; panel : ReactNode | null ; } const getPathById = ( tree , id , path = [ ] ) : 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 = [ { name : 'Files' , icon : 'files' , disabled : false , panel : ( < article className = "px-2 py-4" > < p > < em > Coming Soon < / em > < /p> < hr className = "my-4" / > < p > We 're working on multi-file support in tandem with the GitHub integration . < /p> < /article>), } , { name : 'GitHub' , icon : 'github' , disabled : false , panel : ( < article className = "px-2 py-4" > < p > < em > Coming Soon < /em> < /p> < hr className = "my-4" / > < p > This integration will allow you to sync a project with a GitHub repo and push changes back to it as a commit ! < /p> < /article>), } , { name : 'Visibility' , icon : 'eye' , disabled : true , panel : null , } , ] ; const DiscordLink = ( ) => ( < a className = "underline text-ch-pink-300" href = "https://discord.gg/SD7zFRNjGH" target = "_blank" rel = "noreferrer" > Discord < /a>); interface settingsConfig { title : string ; name : string ; Content : React . FC ; } const settingsConfig = [ { title : 'Editor' , name : 'editor' , Content : ( ) => ( < div className = "p-2" > < p > < em > Coming Soon < / em > < /p> < hr className = "my-2" / > < p className = "p-2" > We 're building configuration settings for the Viewer pane now. Join us on < DiscordLink / > if you want to lend a hand ! < /p> < /div>), } , { title : 'Viewer' , name : 'viewer' , Content : ( ) => ( < div className = "p-2" > < p > < em > Coming Soon < /em> < /p> < hr className = "my-2" / > < p className = "p-2" > We 're building configuration settings for the Viewer pane now. Join us on < DiscordLink / > if you want to lend a hand ! < /p> < /div>), } , { title : 'Console' , name : 'console' , Content : ( ) => { const { state , thunkDispatch } = useIdeContext ( ) ; const consolePath = React . useMemo < MosaicPath | null > ( ( ) => { try { const path = getPathById ( state . layout , 'Console' ) ; return path ; } catch ( error ) { return null ; } } , [ state . layout ] ) ; return ( < div className = "p-2" > < li className = "list-none select-none" > < label className = "grid items-center my-2 cursor-pointer" style = { { gridTemplateColumns : '1fr auto' } } > < span > Visible < /span> < Toggle offLabel = "Hide" onLabel = "Show" onChange = { ( newValue ) => { if ( consolePath ) { const newTree = updateTree ( state . layout , [ createRemoveUpdate ( state . layout , consolePath ) , ] ) ; thunkDispatch ( { type : 'setLayout' , payload : newTree } ) ; } else { 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 } /> < /label> < /li> < /div>); } , } , ] ; export const sidebarBottomConfig = [ { name : 'Settings' , icon : 'gear' , disabled : false , panel : < SettingsMenu parentName = "Settings" />, } , ] ; export const sidebarCombinedConfig = [ ... sidebarTopConfig , ... sidebarBottomConfig , ] ; function SettingsMenu ( { parentName } ) { const { state , thunkDispatch } = useIdeContext ( ) ; return ( < article className = "" > { settingsConfig . map ( ( { name , title , Content } ) => ( < details key = { 'settings-tray-' + name } open = { state . sideTray . slice ( - 1 ) [ 0 ] === name } > < summary className = "px-2 py-2 bg-ch-pink-800 bg-opacity-10 my-px cursor-pointer" onClick = { ( e ) => { e . preventDefault ( ) ; thunkDispatch ( ( dispatch ) => dispatch ( { type : 'settingsButtonClicked' , payload : [ parentName , name ] , } ) ) ; } } > { title } < /summary> < Content / > < /details>))} < /article>); }