finalize child components

pull/5370/head
ioedeveloper 3 years ago
parent 85b63b9268
commit c13301fda9
  1. 7
      apps/remix-ide/src/app/panels/file-panel.js
  2. 4
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  3. 2
      libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx
  4. 244
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
  5. 59
      libs/remix-ui/workspace/src/lib/components/file-label.tsx
  6. 116
      libs/remix-ui/workspace/src/lib/components/file-render.tsx
  7. 15
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  8. 61
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.css
  9. 42
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  10. 12
      libs/remix-ui/workspace/src/lib/types/index.ts

@ -138,8 +138,11 @@ module.exports = class Filepanel extends ViewPlugin {
this.emit('displayNewFileInput', dir)
}
async uploadFile (event) {
return await this.request.uploadFile(event)
async uploadFile (target) {
const provider = this.fileManager.currentFileProvider()
const dir = provider.workspace || '/'
return this.emit('uploadFileEvent', dir, target)
}
async processCreateWorkspace (name) {

@ -484,6 +484,10 @@ const listenOnEvents = (provider) => {
plugin.on('filePanel', 'displayNewFileInput', (path) => {
addInputField('file', path)(dispatch)
})
plugin.on('filePanel', 'uploadFileEvent', (dir: string, target) => {
uploadFile(target, dir)(dispatch)
})
}
export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.Dispatch<any>) => {

@ -1,7 +1,7 @@
import React, { useRef, useEffect } from 'react' // eslint-disable-line
import { action, FileExplorerContextMenuProps } from '../types'
import './css/file-explorer-context-menu.css'
import '../css/file-explorer-context-menu.css'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
declare global {

@ -3,16 +3,18 @@ import React, { useEffect, useState, useRef, useContext } from 'react' // eslint
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line
import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line
import { FileExplorerProps, File, MenuItems, FileExplorerState } from '../types'
import { FileSystemContext } from '@remix-ui/workspace'
import { FileExplorerProps, MenuItems, FileExplorerState } from '../types'
import { FileSystemContext } from '../contexts'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
import { contextMenuActions } from '../utils'
import './css/file-explorer.css'
import { checkSpecialChars, extractParentFromKey, getPathIcon, joinPath } from '@remix-ui/helper'
import '../css/file-explorer.css'
import { checkSpecialChars, extractNameFromKey, extractParentFromKey, joinPath } from '@remix-ui/helper'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileRender } from './file-render'
export const FileExplorer = (props: FileExplorerProps) => {
const { name, focusRoot, contextMenuItems, externalUploads, removedContextMenuItems, resetFocus, files } = props
const { name, contextMenuItems, externalUploads, removedContextMenuItems, files } = props
const [state, setState] = useState<FileExplorerState>({
ctrlKey: false,
newFileName: '',
@ -36,37 +38,13 @@ export const FileExplorer = (props: FileExplorerProps) => {
copyElement: []
})
const [canPaste, setCanPaste] = useState(false)
const editRef = useRef(null)
const global = useContext(FileSystemContext)
useEffect(() => {
if (global.fs.mode === 'browser') {
setState(prevState => {
return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...global.fs.browser.expandPath])] }
})
} else if (global.fs.mode === 'localhost') {
setState(prevState => {
return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...global.fs.localhost.expandPath])] }
})
}
}, [global.fs.browser.expandPath, global.fs.localhost.expandPath])
useEffect(() => {
if (state.focusEdit.element) {
setTimeout(() => {
if (editRef && editRef.current) {
editRef.current.focus()
}
}, 0)
}
}, [state.focusEdit.element])
useEffect(() => {
if (focusRoot) {
global.dispatchSetFocusElement([{ key: '', type: 'folder' }])
resetFocus(false)
}
}, [focusRoot])
setState(prevState => {
return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...props.expandPath])] }
})
}, [props.expandPath])
useEffect(() => {
if (contextMenuItems) {
@ -81,12 +59,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
}, [contextMenuItems])
useEffect(() => {
if (global.fs.focusEdit) {
if (props.focusEdit) {
setState(prevState => {
return { ...prevState, focusEdit: { element: global.fs.focusEdit, type: 'file', isNew: true, lastEdit: null } }
return { ...prevState, focusEdit: { element: props.focusEdit, type: 'file', isNew: true, lastEdit: null } }
})
}
}, [global.fs.focusEdit])
}, [props.focusEdit])
useEffect(() => {
if (externalUploads) {
@ -161,22 +139,16 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
}
const extractNameFromKey = (key: string):string => {
const keyPath = key.split('/')
return keyPath[keyPath.length - 1]
}
const hasReservedKeyword = (content: string): boolean => {
if (state.reservedKeywords.findIndex(value => content.startsWith(value)) !== -1) return true
else return false
}
const getFocusedFolder = () => {
if (global.fs.focusElement[0]) {
if (global.fs.focusElement[0].type === 'folder' && global.fs.focusElement[0].key) return global.fs.focusElement[0].key
else if (global.fs.focusElement[0].type === 'gist' && global.fs.focusElement[0].key) return global.fs.focusElement[0].key
else if (global.fs.focusElement[0].type === 'file' && global.fs.focusElement[0].key) return extractParentFromKey(global.fs.focusElement[0].key) ? extractParentFromKey(global.fs.focusElement[0].key) : name
if (props.focusElement[0]) {
if (props.focusElement[0].type === 'folder' && props.focusElement[0].key) return props.focusElement[0].key
else if (props.focusElement[0].type === 'gist' && props.focusElement[0].key) return props.focusElement[0].key
else if (props.focusElement[0].type === 'file' && props.focusElement[0].key) return extractParentFromKey(props.focusElement[0].key) ? extractParentFromKey(props.focusElement[0].key) : name
else return name
}
}
@ -279,12 +251,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
if (!state.ctrlKey) {
global.dispatchHandleClickFile(path, type)
} else {
if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = global.fs.focusElement.filter(item => item.key !== path)
if (props.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = props.focusElement.filter(item => item.key !== path)
global.dispatchSetFocusElement(focusElement)
} else {
const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
const nonRootFocus = props.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
nonRootFocus.push({ key: path, type })
global.dispatchSetFocusElement(nonRootFocus)
@ -294,12 +266,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
const handleClickFolder = async (path: string, type: 'folder' | 'file' | 'gist') => {
if (state.ctrlKey) {
if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = global.fs.focusElement.filter(item => item.key !== path)
if (props.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = props.focusElement.filter(item => item.key !== path)
global.dispatchSetFocusElement(focusElement)
} else {
const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
const nonRootFocus = props.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
nonRootFocus.push({ key: path, type })
global.dispatchSetFocusElement(nonRootFocus)
@ -321,14 +293,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}
const handleContextMenuFile = (pageX: number, pageY: number, path: string, content: string, type: string) => {
if (!content) return
setState(prevState => {
return { ...prevState, focusContext: { element: path, x: pageX, y: pageY, type }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path }
})
}
const handleContextMenuFolder = (pageX: number, pageY: number, path: string, content: string, type: string) => {
const handleContextMenu = (pageX: number, pageY: number, path: string, content: string, type: string) => {
if (!content) return
setState(prevState => {
return { ...prevState, focusContext: { element: path, x: pageX, y: pageY, type }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path }
@ -359,14 +324,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
} else {
editRef.current.textContent = state.focusEdit.lastEdit
// editRef.current.textContent = state.focusEdit.lastEdit
setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
} else {
if (state.focusEdit.lastEdit === content) {
editRef.current.textContent = content
// editRef.current.textContent = content
return setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
@ -384,14 +349,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
} else {
if (hasReservedKeyword(content)) {
editRef.current.textContent = state.focusEdit.lastEdit
// editRef.current.textContent = state.focusEdit.lastEdit
global.modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {})
} else {
const oldPath: string = state.focusEdit.element
const oldName = extractNameFromKey(oldPath)
const newPath = oldPath.replace(oldName, content)
editRef.current.textContent = extractNameFromKey(oldPath)
// editRef.current.textContent = extractNameFromKey(oldPath)
renamePath(oldPath, newPath)
}
}
@ -425,25 +390,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
editModeOn(parentFolder + '/blank', 'folder', true)
}
const handleEditInput = (event) => {
if (event.which === 13) {
event.preventDefault()
editModeOff(editRef.current.innerText)
}
}
const handleMouseOver = (path: string) => {
setState(prevState => {
return { ...prevState, mouseOverElement: path }
})
}
const handleMouseOut = () => {
setState(prevState => {
return { ...prevState, mouseOverElement: null }
})
}
const handleCopyClick = (path: string, type: 'folder' | 'gist' | 'file') => {
setState(prevState => {
return { ...prevState, copyElement: [{ key: path, type }] }
@ -470,113 +416,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
)
}
const label = (file: File) => {
const isEditable = (state.focusEdit.element === file.path) || (global.fs.focusEdit === file.path)
return (
<div
className='remixui_items d-inline-block w-100'
ref={ isEditable ? editRef : null}
suppressContentEditableWarning={true}
contentEditable={isEditable}
onKeyDown={handleEditInput}
onBlur={(e) => {
e.stopPropagation()
editModeOff(editRef.current.innerText)
}}
>
<span
title={file.path}
className={'remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')}
data-path={file.path}
>
{ file.name }
</span>
</div>
)
}
const renderFiles = (file: File, index: number) => {
if (!file || !file.path || typeof file === 'string' || typeof file === 'number' || typeof file === 'boolean') return
const labelClass = state.focusEdit.element === file.path
? 'bg-light' : global.fs.focusElement.findIndex(item => item.key === file.path) !== -1
? 'bg-secondary' : state.mouseOverElement === file.path
? 'bg-light border' : (state.focusContext.element === file.path) && (state.focusEdit.element !== file.path)
? 'bg-light border' : ''
const icon = getPathIcon(file.path)
const spreadProps = {
onClick: (e) => e.stopPropagation()
}
if (file.isDirectory) {
return (
<TreeViewItem
id={`treeViewItem${file.path}`}
iconX='pr-3 fa fa-folder'
iconY='pr-3 fa fa-folder-open'
key={`${file.path + index}`}
label={label(file)}
onClick={(e) => {
e.stopPropagation()
if (state.focusEdit.element !== file.path) handleClickFolder(file.path, file.type)
}}
onContextMenu={(e) => {
e.preventDefault()
e.stopPropagation()
handleContextMenuFolder(e.pageX, e.pageY, file.path, e.target.textContent, file.type)
}}
labelClass={labelClass}
controlBehaviour={ state.ctrlKey }
expand={state.expandPath.includes(file.path)}
onMouseOver={(e) => {
e.stopPropagation()
handleMouseOver(file.path)
}}
onMouseOut={(e) => {
e.stopPropagation()
if (state.mouseOverElement === file.path) handleMouseOut()
}}
>
{
file.child ? <TreeView id={`treeView${file.path}`} key={`treeView${file.path}`} {...spreadProps }>{
Object.keys(file.child).map((key, index) => {
return renderFiles(file.child[key], index)
})
}
</TreeView> : <TreeView id={`treeView${file.path}`} key={`treeView${file.path}`} {...spreadProps }/>
}
</TreeViewItem>
)
} else {
return (
<TreeViewItem
id={`treeViewItem${file.path}`}
key={`treeView${file.path}`}
label={label(file)}
onClick={(e) => {
e.stopPropagation()
if (state.focusEdit.element !== file.path) handleClickFile(file.path, file.type)
}}
onContextMenu={(e) => {
e.preventDefault()
e.stopPropagation()
handleContextMenuFile(e.pageX, e.pageY, file.path, e.target.textContent, file.type)
}}
icon={icon}
labelClass={labelClass}
onMouseOver={(e) => {
e.stopPropagation()
handleMouseOver(file.path)
}}
onMouseOut={(e) => {
e.stopPropagation()
if (state.mouseOverElement === file.path) handleMouseOut()
}}
/>
)
}
}
return (
<div>
<TreeView id='treeView'>
@ -597,7 +436,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
setState(prevState => {
return { ...prevState, expandPath }
})
resetFocus(true)
}}>
<FileExplorerMenu
title={''}
@ -613,9 +451,19 @@ export const FileExplorer = (props: FileExplorerProps) => {
<div className='pb-2'>
<TreeView id='treeViewMenu'>
{
files[props.name] && Object.keys(files[props.name]).map((key, index) => {
return renderFiles(files[props.name][key], index)
})
files[props.name] && Object.keys(files[props.name]).map((key, index) => <FileRender
file={files[props.name][key]}
index={index}
focusContext={state.focusContext}
focusEdit={state.focusEdit}
focusElement={props.focusElement}
ctrlKey={state.ctrlKey}
expandPath={state.expandPath}
editModeOff={editModeOff}
handleClickFile={handleClickFile}
handleClickFolder={handleClickFolder}
handleContextMenu={handleContextMenu}
/>)
}
</TreeView>
</div>
@ -623,7 +471,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
</TreeView>
{ state.showContextMenu &&
<FileExplorerContextMenu
actions={global.fs.focusElement.length > 1 ? state.actions.filter(item => item.multiselect) : state.actions.filter(item => !item.multiselect)}
actions={props.focusElement.length > 1 ? state.actions.filter(item => item.multiselect) : state.actions.filter(item => !item.multiselect)}
hideContextMenu={hideContextMenu}
createNewFile={handleNewFileInput}
createNewFolder={handleNewFolderInput}
@ -637,11 +485,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
pageY={state.focusContext.y}
path={state.focusContext.element}
type={state.focusContext.type}
focus={global.fs.focusElement}
onMouseOver={(e) => {
e.stopPropagation()
handleMouseOver(state.focusContext.element)
}}
focus={props.focusElement}
pushChangesToGist={pushChangesToGist}
publishFolderToGist={publishFolderToGist}
publishFileToGist={publishFileToGist}

@ -0,0 +1,59 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import React, { useEffect, useRef } from 'react'
import { FileType } from '../types'
export interface FileLabelProps {
file: FileType,
focusEdit: {
element: string
type: string
isNew: boolean
lastEdit: string
}
editModeOff: (content: string) => void
}
export const FileLabel = (props: FileLabelProps) => {
const { file, focusEdit, editModeOff } = props
const isEditable = focusEdit.element === file.path
const labelRef = useRef(null)
useEffect(() => {
if (isEditable) {
setTimeout(() => {
labelRef.current.focus()
}, 0)
}
}, [isEditable])
const handleEditInput = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.which === 13) {
event.preventDefault()
editModeOff(labelRef.current.innerText)
}
}
const handleEditBlur = (event: React.SyntheticEvent) => {
event.stopPropagation()
editModeOff(labelRef.current.innerText)
}
return (
<div
className='remixui_items d-inline-block w-100'
ref={labelRef}
suppressContentEditableWarning={true}
contentEditable={isEditable}
onKeyDown={handleEditInput}
onBlur={handleEditBlur}
>
<span
title={file.path}
className={'remixui_label ' + (file.isDirectory ? 'folder' : 'remixui_leaf')}
data-path={file.path}
>
{ file.name }
</span>
</div>
)
}

@ -0,0 +1,116 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import React, { SyntheticEvent, useState } from 'react'
import { FileType } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import { getPathIcon } from '@remix-ui/helper'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileLabel } from './file-label'
export interface RenderFileProps {
file: FileType,
index: number,
focusEdit: { element: string, type: string, isNew: boolean, lastEdit: string },
focusElement: { key: string, type: 'file' | 'folder' | 'gist' }[],
focusContext: { element: string, x: number, y: number, type: string },
ctrlKey: boolean,
expandPath: string[],
editModeOff: (content: string) => void,
handleClickFolder: (path: string, type: string) => void,
handleClickFile: (path: string, type: string) => void,
handleContextMenu: (pageX: number, pageY: number, path: string, content: string, type: string) => void
}
export const FileRender = (props: RenderFileProps) => {
const { file } = props
if (!file || !file.path || typeof file === 'string' || typeof file === 'number' || typeof file === 'boolean') return
const [hover, setHover] = useState<boolean>(false)
const labelClass = props.focusEdit.element === file.path
? 'bg-light' : props.focusElement.findIndex(item => item.key === file.path) !== -1
? 'bg-secondary' : hover
? 'bg-light border' : (props.focusContext.element === file.path) && (props.focusEdit.element !== file.path)
? 'bg-light border' : ''
const icon = getPathIcon(file.path)
const spreadProps = {
onClick: (e) => e.stopPropagation()
}
const handleFolderClick = (event: SyntheticEvent) => {
event.stopPropagation()
if (props.focusEdit.element !== file.path) props.handleClickFolder(file.path, file.type)
}
const handleFileClick = (event: SyntheticEvent) => {
event.stopPropagation()
if (props.focusEdit.element !== file.path) props.handleClickFile(file.path, file.type)
}
const handleContextMenu = (event: PointerEvent) => {
event.preventDefault()
event.stopPropagation()
props.handleContextMenu(event.pageX, event.pageY, file.path, (event.target as HTMLElement).textContent, file.type)
}
const handleMouseOut = (event: SyntheticEvent) => {
event.stopPropagation()
setHover(false)
}
const handleMouseOver = (event: SyntheticEvent) => {
event.stopPropagation()
setHover(true)
}
if (file.isDirectory) {
return (
<TreeViewItem
id={`treeViewItem${file.path}`}
iconX='pr-3 fa fa-folder'
iconY='pr-3 fa fa-folder-open'
key={`${file.path + props.index}`}
label={<FileLabel file={file} focusEdit={props.focusEdit} editModeOff={props.editModeOff} />}
onClick={handleFolderClick}
onContextMenu={handleContextMenu}
labelClass={labelClass}
controlBehaviour={ props.ctrlKey }
expand={props.expandPath.includes(file.path)}
onMouseOver={handleMouseOver}
onMouseOut={handleMouseOut}
>
{
file.child ? <TreeView id={`treeView${file.path}`} key={`treeView${file.path}`} {...spreadProps }>{
Object.keys(file.child).map((key, index) => <FileRender
file={file.child[key]}
index={index}
focusContext={props.focusContext}
focusEdit={props.focusEdit}
focusElement={props.focusElement}
ctrlKey={props.ctrlKey}
editModeOff={props.editModeOff}
handleClickFile={props.handleClickFile}
handleClickFolder={props.handleClickFolder}
handleContextMenu={props.handleContextMenu}
expandPath={props.expandPath}
/>)
}
</TreeView> : <TreeView id={`treeView${file.path}`} key={`treeView${file.path}`} {...spreadProps }/>
}
</TreeViewItem>
)
} else {
return (
<TreeViewItem
id={`treeViewItem${file.path}`}
key={`treeView${file.path}`}
label={<FileLabel file={file} focusEdit={props.focusEdit} editModeOff={props.editModeOff} />}
onClick={handleFileClick}
onContextMenu={handleContextMenu}
icon={icon}
labelClass={labelClass}
onMouseOver={handleMouseOver}
onMouseOut={handleMouseOut}
/>
)
}
}

@ -1,4 +1,5 @@
import { extractNameFromKey } from '@remix-ui/helper'
import { FileType } from '../types'
import * as _ from 'lodash'
interface Action {
type: string
@ -8,7 +9,7 @@ export interface BrowserState {
browser: {
currentWorkspace: string,
workspaces: string[],
files: { [x: string]: Record<string, File> },
files: { [x: string]: Record<string, FileType> },
expandPath: string[]
isRequesting: boolean,
isSuccessful: boolean,
@ -16,7 +17,7 @@ export interface BrowserState {
},
localhost: {
sharedFolder: string,
files: { [x: string]: Record<string, File> },
files: { [x: string]: Record<string, FileType> },
expandPath: string[],
isRequesting: boolean,
isSuccessful: boolean,
@ -469,7 +470,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
const fileAdded = (state: BrowserState, path: string): { [x: string]: Record<string, File> } => {
const fileAdded = (state: BrowserState, path: string): { [x: string]: Record<string, FileType> } => {
let files = state.mode === 'browser' ? state.browser.files : state.localhost.files
const _path = splitPath(state, path)
@ -482,7 +483,7 @@ const fileAdded = (state: BrowserState, path: string): { [x: string]: Record<str
return files
}
const fileRemoved = (state: BrowserState, path: string): { [x: string]: Record<string, File> } => {
const fileRemoved = (state: BrowserState, path: string): { [x: string]: Record<string, FileType> } => {
const files = state.mode === 'browser' ? state.browser.files : state.localhost.files
const _path = splitPath(state, path)
@ -491,7 +492,7 @@ const fileRemoved = (state: BrowserState, path: string): { [x: string]: Record<s
}
// IDEA: Modify function to remove blank input field without fetching content
const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: string, type?: 'file' | 'folder' }, deletePath?: string): { [x: string]: Record<string, File> } => {
const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: string, type?: 'file' | 'folder' }, deletePath?: string): { [x: string]: Record<string, FileType> } => {
if (!payload.fileTree) return state.mode === 'browser' ? state.browser.files : state[state.mode].files
if (state.mode === 'browser') {
if (payload.path === state.browser.currentWorkspace) {
@ -538,7 +539,7 @@ const fetchDirectoryContent = (state: BrowserState, payload: { fileTree, path: s
}
}
const fetchWorkspaceDirectoryContent = (state: BrowserState, payload: { fileTree, path: string }): { [x: string]: Record<string, File> } => {
const fetchWorkspaceDirectoryContent = (state: BrowserState, payload: { fileTree, path: string }): { [x: string]: Record<string, FileType> } => {
if (state.mode === 'browser') {
const files = normalize(payload.fileTree, payload.path)
@ -548,7 +549,7 @@ const fetchWorkspaceDirectoryContent = (state: BrowserState, payload: { fileTree
}
}
const normalize = (filesList, directory?: string, newInputType?: 'folder' | 'file'): Record<string, File> => {
const normalize = (filesList, directory?: string, newInputType?: 'folder' | 'file'): Record<string, FileType> => {
const folders = {}
const files = {}

@ -1,61 +0,0 @@
.remixui_container {
display : flex;
flex-direction : row;
width : 100%;
height : 100%;
box-sizing : border-box;
}
.remixui_fileexplorer {
display : flex;
flex-direction : column;
position : relative;
width : 100%;
padding-left : 6px;
padding-right : 6px;
padding-top : 6px;
}
.remixui_fileExplorerTree {
cursor : default;
}
.remixui_gist {
padding : 10px;
}
.remixui_gist i {
cursor : pointer;
}
.remixui_gist i:hover {
color : orange;
}
.remixui_connectToLocalhost {
padding : 10px;
}
.remixui_connectToLocalhost i {
cursor : pointer;
}
.remixui_connectToLocalhost i:hover {
color : var(--secondary)
}
.remixui_uploadFile {
padding : 10px;
}
.remixui_uploadFile label:hover {
color : var(--secondary)
}
.remixui_uploadFile label {
cursor : pointer;
}
.remixui_treeview {
overflow-y : auto;
}
.remixui_dialog {
display: flex;
flex-direction: column;
}
.remixui_dialogParagraph {
margin-bottom: 2em;
word-break: break-word;
}
.remixui_menuicon {
padding-right : 10px;
}

@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef, useContext } from 'react' // eslint-disable-line
import { FileExplorer } from './components/file-explorer' // eslint-disable-line
import './remix-ui-workspace.css'
import './css/remix-ui-workspace.css'
import { WorkspaceProps, WorkspaceState } from './types'
import { FileSystemContext } from './contexts'
@ -9,12 +9,9 @@ const canUpload = window.File || window.FileReader || window.FileList || window.
export function Workspace (props: WorkspaceProps) {
const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - '
const [state, setState] = useState<WorkspaceState>({
reset: false,
const [state] = useState<WorkspaceState>({
hideRemixdExplorer: true,
displayNewFile: false,
externalUploads: null,
uploadFileEvent: null,
loadingLocalhost: false
})
const [currentWorkspace, setCurrentWorkspace] = useState<string>(NO_WORKSPACE)
@ -50,19 +47,6 @@ export function Workspace (props: WorkspaceProps) {
return createWorkspace()
}
// props.plugin.request.createNewFile = async () => {
// if (!state.workspaces.length) await createNewWorkspace('default_workspace')
// props.plugin.resetNewFile()
// }
// props.plugin.request.uploadFile = async (target: EventTarget & HTMLInputElement) => {
// if (!state.workspaces.length) await createNewWorkspace('default_workspace')
// setState(prevState => {
// return { ...prevState, uploadFileEvent: target }
// })
// }
props.plugin.request.getCurrentWorkspace = () => {
return { name: currentWorkspace, isLocalhost: currentWorkspace === LOCALHOST, absolutePath: `${props.plugin.workspace.workspacesPath}/${currentWorkspace}` }
}
@ -120,10 +104,8 @@ export function Workspace (props: WorkspaceProps) {
}
/** ** ****/
const resetFocus = (reset) => {
setState(prevState => {
return { ...prevState, reset }
})
const resetFocus = () => {
global.dispatchSetFocusElement([{ key: '', type: 'folder' }])
}
const switchWorkspace = async (name: string) => {
@ -153,7 +135,7 @@ export function Workspace (props: WorkspaceProps) {
return (
<div className='remixui_container'>
<div className='remixui_fileexplorer' onClick={() => resetFocus(true)}>
<div className='remixui_fileexplorer' onClick={resetFocus}>
<div>
<header>
<div className="mb-2">
@ -214,14 +196,12 @@ export function Workspace (props: WorkspaceProps) {
<FileExplorer
name={currentWorkspace}
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']}
plugin={props.plugin}
focusRoot={state.reset}
contextMenuItems={props.plugin.registeredMenuItems}
removedContextMenuItems={props.plugin.removedMenuItems}
displayInput={state.displayNewFile}
externalUploads={state.uploadFileEvent}
resetFocus={resetFocus}
files={global.fs.browser.files}
expandPath={global.fs.browser.expandPath}
focusEdit={global.fs.focusEdit}
focusElement={global.fs.focusElement}
/>
}
</div>
@ -232,12 +212,12 @@ export function Workspace (props: WorkspaceProps) {
<FileExplorer
name='localhost'
menuItems={['createNewFile', 'createNewFolder']}
plugin={props.plugin}
focusRoot={state.reset}
contextMenuItems={props.plugin.registeredMenuItems}
removedContextMenuItems={props.plugin.removedMenuItems}
resetFocus={resetFocus}
files={global.fs.localhost.files}
expandPath={global.fs.localhost.expandPath}
focusEdit={global.fs.focusEdit}
focusElement={global.fs.focusElement}
/>
}
</div>

@ -28,11 +28,8 @@ export interface WorkspaceProps {
}
}
export interface WorkspaceState {
reset: boolean
hideRemixdExplorer: boolean
displayNewFile: boolean
externalUploads: EventTarget & HTMLInputElement
uploadFileEvent: EventTarget & HTMLInputElement
loadingLocalhost: boolean
}
@ -46,7 +43,7 @@ export interface Modal {
cancelFn: () => void
}
export interface File {
export interface FileType {
path: string,
name: string,
isDirectory: boolean,
@ -58,13 +55,14 @@ export interface File {
export interface FileExplorerProps {
name: string,
menuItems?: string[],
focusRoot: boolean,
contextMenuItems: MenuItems,
removedContextMenuItems: MenuItems,
displayInput?: boolean,
externalUploads?: EventTarget & HTMLInputElement,
resetFocus?: (value: boolean) => void,
files: { [x: string]: Record<string, File> }
files: { [x: string]: Record<string, FileType> },
expandPath: string[],
focusEdit: string,
focusElement: { key: string, type: 'file' | 'folder' | 'gist' }[]
}
export interface FileExplorerMenuProps {

Loading…
Cancel
Save