import React, { useEffect, useState } from 'react'; import { ServerContext } from '@/state/server'; import { NavLink, useLocation } from 'react-router-dom'; import { cleanDirectoryPath } from '@/helpers'; import tw from 'twin.macro'; interface Props { renderLeft?: JSX.Element; withinFileEditor?: boolean; isNewFile?: boolean; } export default ({ renderLeft, withinFileEditor, isNewFile }: Props) => { const [ file, setFile ] = useState<string | null>(null); const id = ServerContext.useStoreState(state => state.server.data!.id); const directory = ServerContext.useStoreState(state => state.files.directory); const { hash } = useLocation(); useEffect(() => { let pathHash = cleanDirectoryPath(hash); try { pathHash = decodeURI(pathHash); } catch (e) { console.warn('Error decoding URL parts in hash:', e); } if (withinFileEditor && !isNewFile) { let name = pathHash.split('/').pop() || null; if (name) { try { name = decodeURIComponent(name); } catch (e) { console.warn('Error decoding filename:', e); } } setFile(name); } }, [ withinFileEditor, isNewFile, hash ]); const breadcrumbs = (): { name: string; path?: string }[] => directory.split('/') .filter(directory => !!directory) .map((directory, index, dirs) => { if (!withinFileEditor && index === dirs.length - 1) { return { name: directory }; } return { name: directory, path: `/${dirs.slice(0, index + 1).join('/')}` }; }); return ( <div css={tw`flex flex-grow-0 items-center text-sm text-neutral-500 overflow-x-hidden`}> {renderLeft || <div css={tw`w-12`}/>} /<span css={tw`px-1 text-neutral-300`}>home</span>/ <NavLink to={`/server/${id}/files`} css={tw`px-1 text-neutral-200 no-underline hover:text-neutral-100`} > container </NavLink>/ { breadcrumbs().map((crumb, index) => ( crumb.path ? <React.Fragment key={index}> <NavLink to={`/server/${id}/files#${crumb.path}`} css={tw`px-1 text-neutral-200 no-underline hover:text-neutral-100`} > {decodeURIComponent(crumb.name)} </NavLink>/ </React.Fragment> : <span key={index} css={tw`px-1 text-neutral-300`}>{decodeURIComponent(crumb.name)}</span> )) } {file && <React.Fragment> <span css={tw`px-1 text-neutral-300`}>{file}</span> </React.Fragment> } </div> ); };