Export remaining file-explorer functions to actions

pull/5370/head
ioedeveloper 3 years ago
parent 83f288f6d0
commit d97430919f
  1. 0
      apps/remix-ide/contracts/me.sol
  2. 0
      apps/remix-ide/contracts/shoulder.sol
  3. 145
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  4. 5
      libs/remix-ui/file-explorer/src/lib/types/index.ts
  5. 27
      libs/remix-ui/helper/src/lib/remix-ui-helper.ts
  6. 94
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  7. 12
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  8. 50
      libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
  9. 15
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  10. 18
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -1,25 +1,19 @@
import React, { useEffect, useState, useRef, useReducer, useContext } from 'react' // eslint-disable-line
import React, { useEffect, useState, useRef, useContext } from 'react' // eslint-disable-line
// import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' // eslint-disable-line
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster' // 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 * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import { FileSystemContext } from '@remix-ui/workspace'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel'
import { contextMenuActions } from './utils'
import './css/file-explorer.css'
import { extractParentFromKey } from '@remix-ui/helper'
import { checkSpecialChars, extractParentFromKey, getPathIcon, joinPath } from '@remix-ui/helper'
export const FileExplorer = (props: FileExplorerProps) => {
const { name, focusRoot, contextMenuItems, externalUploads, removedContextMenuItems, resetFocus, files } = props
const [state, setState] = useState<FileExplorerState>({
focusElement: [{
key: '',
type: 'folder'
}],
ctrlKey: false,
newFileName: '',
actions: contextMenuActions,
@ -69,9 +63,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
useEffect(() => {
if (focusRoot) {
setState(prevState => {
return { ...prevState, focusElement: [{ key: '', type: 'folder' }] }
})
global.dispatchSetFocusElement([{ key: '', type: 'folder' }])
resetFocus(false)
}
}, [focusRoot])
@ -181,10 +173,10 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const getFocusedFolder = () => {
if (state.focusElement[0]) {
if (state.focusElement[0].type === 'folder' && state.focusElement[0].key) return state.focusElement[0].key
else if (state.focusElement[0].type === 'gist' && state.focusElement[0].key) return state.focusElement[0].key
else if (state.focusElement[0].type === 'file' && state.focusElement[0].key) return extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name
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
else return name
}
}
@ -192,62 +184,29 @@ export const FileExplorer = (props: FileExplorerProps) => {
const createNewFile = async (newFilePath: string) => {
try {
global.dispatchCreateNewFile(newFilePath, props.name)
// setState(prevState => {
// return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
// })
} catch (error) {
return global.modal('File Creation Failed', typeof error === 'string' ? error : error.message, 'Close', async () => {})
}
}
const createNewFolder = async (newFolderPath: string) => {
const fileManager = state.fileManager
const dirName = newFolderPath + '/'
try {
const exists = await fileManager.exists(dirName)
if (exists) {
return global.modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, 'Close', () => {})
}
await fileManager.mkdir(dirName)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] }
})
global.dispatchCreateNewFolder(newFolderPath, props.name)
} catch (e) {
return global.modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, 'Close', async () => {})
}
}
const deletePath = async (path: string | string[]) => {
const deletePath = async (path: string[]) => {
if (global.fs.readonly) return global.toast('cannot delete file. ' + name + ' is a read only explorer')
if (!Array.isArray(path)) path = [path]
global.modal(`Delete ${path.length > 1 ? 'items' : 'item'}`, deleteMessage(path), 'OK', async () => {
const fileManager = state.fileManager
for (const p of path) {
try {
await fileManager.remove(p)
} catch (e) {
const isDir = await state.fileManager.isDirectory(p)
global.toast(`Failed to remove ${isDir ? 'folder' : 'file'} ${p}.`)
}
}
}, 'Cancel', () => {})
global.modal(`Delete ${path.length > 1 ? 'items' : 'item'}`, deleteMessage(path), 'OK', () => { global.dispatchDeletePath(path) }, 'Cancel', () => {})
}
const renamePath = async (oldPath: string, newPath: string) => {
try {
const fileManager = state.fileManager
const exists = await fileManager.exists(newPath)
if (exists) {
global.modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, 'Close', () => {})
} else {
await fileManager.rename(oldPath, newPath)
}
global.dispatchRenamePath(oldPath, newPath)
} catch (error) {
global.modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, 'Close', async () => {})
}
@ -264,22 +223,18 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const copyFile = (src: string, dest: string) => {
const fileManager = state.fileManager
try {
fileManager.copyFile(src, dest)
global.dispatchCopyFile(src, dest)
} catch (error) {
console.log('Oops! An error ocurred while performing copyFile operation.' + error)
global.modal('Copy File Failed', 'Unexpected error while copying file: ' + src, 'Close', async () => {})
}
}
const copyFolder = (src: string, dest: string) => {
const fileManager = state.fileManager
try {
fileManager.copyDir(src, dest)
global.dispatchCopyFolder(src, dest)
} catch (error) {
console.log('Oops! An error ocurred while performing copyDir operation.' + error)
global.modal('Copy Folder Failed', 'Unexpected error while copying folder: ' + src, 'Close', async () => {})
}
}
@ -304,54 +259,50 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const runScript = async (path: string) => {
const filesProvider = fileSystem.provider.provider
filesProvider.get(path, (error, content: string) => {
if (error) return console.log(error)
plugin.call('scriptRunner', 'execute', content)
})
try {
global.dispatchRunScript(path)
} catch (error) {
global.toast('Run script failed')
}
}
const emitContextMenuEvent = (cmd: customAction) => {
plugin.call(cmd.id, cmd.name, cmd)
try {
global.dispatchEmitContextMenuEvent(cmd)
} catch (error) {
global.toast(error)
}
}
const handleClickFile = (path: string, type: 'folder' | 'file' | 'gist') => {
path = path.indexOf(props.name + '/') === 0 ? path.replace(props.name + '/', '') : path
if (!state.ctrlKey) {
state.fileManager.open(path)
setState(prevState => {
return { ...prevState, focusElement: [{ key: path, type }] }
})
global.dispatchHandleClickFile(path, type)
} else {
if (state.focusElement.findIndex(item => item.key === path) !== -1) {
setState(prevState => {
return { ...prevState, focusElement: prevState.focusElement.filter(item => item.key !== path) }
})
if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = global.fs.focusElement.filter(item => item.key !== path)
global.dispatchSetFocusElement(focusElement)
} else {
setState(prevState => {
const nonRootFocus = prevState.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
nonRootFocus.push({ key: path, type })
return { ...prevState, focusElement: nonRootFocus }
})
global.dispatchSetFocusElement(nonRootFocus)
}
}
}
const handleClickFolder = async (path: string, type: 'folder' | 'file' | 'gist') => {
if (state.ctrlKey) {
if (state.focusElement.findIndex(item => item.key === path) !== -1) {
setState(prevState => {
return { ...prevState, focusElement: [...prevState.focusElement.filter(item => item.key !== path)] }
})
if (global.fs.focusElement.findIndex(item => item.key === path) !== -1) {
const focusElement = global.fs.focusElement.filter(item => item.key !== path)
global.dispatchSetFocusElement(focusElement)
} else {
setState(prevState => {
const nonRootFocus = prevState.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
const nonRootFocus = global.fs.focusElement.filter((el) => { return !(el.key === '' && el.type === 'folder') })
nonRootFocus.push({ key: path, type })
return { ...prevState, focusElement: nonRootFocus }
})
global.dispatchSetFocusElement(nonRootFocus)
}
} else {
let expandPath = []
@ -363,8 +314,9 @@ export const FileExplorer = (props: FileExplorerProps) => {
expandPath = [...new Set(state.expandPath.filter(key => key && (typeof key === 'string') && !key.startsWith(path)))]
}
global.dispatchSetFocusElement([{ key: path, type }])
setState(prevState => {
return { ...prevState, focusElement: [{ key: path, type }], expandPath }
return { ...prevState, expandPath }
})
}
}
@ -419,7 +371,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
if (helper.checkSpecialChars(content)) {
if (checkSpecialChars(content)) {
global.modal('Validation Error', 'Special characters are not allowed', 'OK', () => {})
} else {
if (state.focusEdit.isNew) {
@ -547,11 +499,11 @@ export const FileExplorer = (props: FileExplorerProps) => {
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' : state.focusElement.findIndex(item => item.key === file.path) !== -1
? '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 = helper.getPathIcon(file.path)
const icon = getPathIcon(file.path)
const spreadProps = {
onClick: (e) => e.stopPropagation()
}
@ -654,7 +606,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
createNewFolder={handleNewFolderInput}
publishToGist={publishToGist}
uploadFile={uploadFile}
fileManager={state.fileManager}
/>
</div>
}
@ -672,7 +623,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
</TreeView>
{ state.showContextMenu &&
<FileExplorerContextMenu
actions={state.focusElement.length > 1 ? state.actions.filter(item => item.multiselect) : state.actions.filter(item => !item.multiselect)}
actions={global.fs.focusElement.length > 1 ? state.actions.filter(item => item.multiselect) : state.actions.filter(item => !item.multiselect)}
hideContextMenu={hideContextMenu}
createNewFile={handleNewFileInput}
createNewFolder={handleNewFolderInput}
@ -686,7 +637,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
pageY={state.focusContext.y}
path={state.focusContext.element}
type={state.focusContext.type}
focus={state.focusElement}
focus={global.fs.focusElement}
onMouseOver={(e) => {
e.stopPropagation()
handleMouseOver(state.focusContext.element)
@ -701,9 +652,3 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
export default FileExplorer
function joinPath (...paths) {
paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)
if (paths.length === 1) return paths[0]
return paths.join('/')
}

@ -25,7 +25,6 @@ export interface File {
export interface FileExplorerMenuProps {
title: string,
menuItems: string[],
fileManager: any,
createNewFile: (folder?: string) => void,
createNewFolder: (parentFolder?: string) => void,
publishToGist: (path?: string) => void,
@ -58,10 +57,6 @@ export interface FileExplorerContextMenuProps {
}
export interface FileExplorerState {
focusElement: {
key: string
type: 'folder' | 'file' | 'gist'
}[]
ctrlKey: boolean
newFileName: string
actions: {

@ -20,9 +20,9 @@ export const checkSlash = (name: string) => {
return name.match(/\//) != null
}
export const createNonClashingNameAsync = async (name, fileManager, prefix = '') => {
export const createNonClashingNameAsync = async (name: string, fileManager, prefix = '') => {
if (!name) name = 'Undefined'
let counter
let _counter
let ext = 'sol'
const reg = /(.*)\.([^.]+)/g
const split = reg.exec(name)
@ -33,11 +33,30 @@ export const createNonClashingNameAsync = async (name, fileManager, prefix = '')
let exist = true
do {
const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext)
const isDuplicate = await fileManager.exists(name + _counter + prefix + '.' + ext)
if (isDuplicate) counter = (counter | 0) + 1
if (isDuplicate) _counter = (_counter | 0) + 1
else exist = false
} while (exist)
const counter = _counter || ''
return name + counter + prefix + '.' + ext
}
export const joinPath = (...paths) => {
paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)
if (paths.length === 1) return paths[0]
return paths.join('/')
}
export const getPathIcon = (path: string) => {
return path.endsWith('.txt')
? 'far fa-file-alt' : path.endsWith('.md')
? 'far fa-file-alt' : path.endsWith('.sol')
? 'fak fa-solidity-mono' : path.endsWith('.js')
? 'fab fa-js' : path.endsWith('.json')
? 'fas fa-brackets-curly' : path.endsWith('.vy')
? 'fak fa-vyper-mono' : path.endsWith('.lex')
? 'fak fa-lexon' : path.endsWith('.contract')
? 'fab fa-ethereum' : 'far fa-file'
}

@ -3,6 +3,7 @@ import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import axios, { AxiosResponse } from 'axios'
import { checkSpecialChars, checkSlash, extractParentFromKey, extractNameFromKey, createNonClashingNameAsync } from '@remix-ui/helper'
import Gists from 'gists'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel/type'
const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params')
const examples = require('../../../../../../apps/remix-ide/src/app/editor/examples')
@ -194,6 +195,13 @@ const hidePopUp = () => {
}
}
const focusElement = (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => {
return {
type: 'SET_FOCUS_ELEMENT',
payload: elements
}
}
const createWorkspaceTemplate = async (workspaceName: string, setDefaults = true, template: 'gist-template' | 'code-template' | 'default-template' = 'default-template') => {
if (!workspaceName) throw new Error('workspace name cannot be empty')
if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed')
@ -765,9 +773,95 @@ export const createNewFile = (path: string, rootDir: string) => async (dispatch:
const path = newName.indexOf(rootDir + '/') === 0 ? newName.replace(rootDir + '/', '') : newName
await fileManager.open(path)
setFocusElement([{ key: path, type: 'file' }])(dispatch)
}
}
export const setFocusElement = (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => async (dispatch: React.Dispatch<any>) => {
dispatch(focusElement(elements))
}
export const createNewFolder = (path: string, rootDir: string) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
const dirName = path + '/'
const exists = await fileManager.exists(dirName)
if (exists) {
return dispatch(displayNotification('Rename File Failed', `A file or folder ${extractNameFromKey(path)} already exists at this location. Please choose a different name.`, 'Close', null, () => {}))
}
await fileManager.mkdir(dirName)
path = path.indexOf(rootDir + '/') === 0 ? path.replace(rootDir + '/', '') : path
dispatch(focusElement([{ key: path, type: 'folder' }]))
}
export const deletePath = (path: string[]) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
for (const p of path) {
try {
await fileManager.remove(p)
} catch (e) {
const isDir = await fileManager.isDirectory(p)
dispatch(displayPopUp(`Failed to remove ${isDir ? 'folder' : 'file'} ${p}.`))
}
}
}
export const renamePath = (oldPath: string, newPath: string) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
const exists = await fileManager.exists(newPath)
if (exists) {
dispatch(displayNotification('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, 'Close', null, () => {}))
} else {
await fileManager.rename(oldPath, newPath)
}
}
export const copyFile = (src: string, dest: string) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
try {
fileManager.copyFile(src, dest)
} catch (error) {
console.log('Oops! An error ocurred while performing copyFile operation.' + error)
dispatch(displayPopUp('Oops! An error ocurred while performing copyFile operation.' + error))
}
}
export const copyFolder = (src: string, dest: string) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
try {
fileManager.copyDir(src, dest)
} catch (error) {
console.log('Oops! An error ocurred while performing copyDir operation.' + error)
dispatch(displayPopUp('Oops! An error ocurred while performing copyDir operation.' + error))
}
}
export const runScript = (path: string) => async (dispatch: React.Dispatch<any>) => {
const provider = plugin.fileManager.currentFileProvider()
provider.get(path, (error, content: string) => {
if (error) {
dispatch(displayPopUp(error))
return console.log(error)
}
plugin.call('scriptRunner', 'execute', content)
})
}
export const emitContextMenuEvent = (cmd: customAction) => async () => {
plugin.call(cmd.id, cmd.name, cmd)
}
export const handleClickFile = (path: string, type: 'file' | 'folder' | 'gist') => async (dispatch: React.Dispatch<any>) => {
plugin.fileManager.open(path)
dispatch(focusElement([{ key: path, type }]))
}
const fileAdded = async (filePath: string) => {
await dispatch(fileAddedSuccess(filePath))
if (filePath.includes('_test.sol')) {

@ -1,3 +1,4 @@
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel/type'
import { createContext, SyntheticEvent } from 'react'
import { BrowserState } from '../reducers/workspace'
@ -16,5 +17,14 @@ export const FileSystemContext = createContext<{
dispatchDeleteWorkspace: (workspaceName: string) => Promise<void>,
dispatchPublishToGist: (path?: string, type?: string) => Promise<void>,
dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>
dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>,
dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>,
dispatchCreateNewFolder: (path: string, rootDir: string) => Promise<void>,
dispatchDeletePath: (path: string[]) => Promise<void>,
dispatchRenamePath: (oldPath: string, newPath: string) => Promise<void>,
dispatchCopyFile: (src: string, dest: string) => Promise<void>,
dispatchCopyFolder: (src: string, dest: string) => Promise<void>,
dispatchRunScript: (path: string) => Promise<void>,
dispatchEmitContextMenuEvent: (cmd: customAction) => Promise<void>,
dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void>
}>(null)

@ -5,10 +5,11 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileSystemContext } from '../contexts'
import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, fetchDirectory, addInputField, removeInputField, createWorkspace, fetchWorkspaceDirectory, switchToWorkspace, renameWorkspace, deleteWorkspace, clearPopUp, publishToGist, uploadFile, createNewFile } from '../actions/workspace'
import { initWorkspace, fetchDirectory, addInputField, removeInputField, createWorkspace, fetchWorkspaceDirectory, switchToWorkspace, renameWorkspace, deleteWorkspace, clearPopUp, publishToGist, uploadFile, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile } from '../actions/workspace'
import { Modal, WorkspaceProps } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Workspace } from '../remix-ui-workspace'
import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel/type'
export const FileSystemProvider = (props: WorkspaceProps) => {
const { plugin } = props
@ -74,6 +75,42 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await createNewFile(path, rootDir)(fsDispatch)
}
const dispatchSetFocusElement = async (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => {
await setFocusElement(elements)(fsDispatch)
}
const dispatchCreateNewFolder = async (path: string, rootDir: string) => {
await createNewFolder(path, rootDir)(fsDispatch)
}
const dispatchDeletePath = async (path: string[]) => {
await deletePath(path)(fsDispatch)
}
const dispatchRenamePath = async (oldPath: string, newPath: string) => {
await renamePath(oldPath, newPath)(fsDispatch)
}
const dispatchCopyFile = async (src: string, dest: string) => {
await copyFile(src, dest)(fsDispatch)
}
const dispatchCopyFolder = async (src: string, dest: string) => {
await copyFolder(src, dest)(fsDispatch)
}
const dispatchRunScript = async (path: string) => {
await runScript(path)(fsDispatch)
}
const dispatchEmitContextMenuEvent = async (cmd: customAction) => {
await emitContextMenuEvent(cmd)
}
const dispatchHandleClickFile = async (path: string, type: 'file' | 'folder' | 'gist') => {
await handleClickFile(path, type)
}
useEffect(() => {
if (modals.length > 0) {
setFocusModal(() => {
@ -159,7 +196,16 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchDeleteWorkspace,
dispatchPublishToGist,
dispatchUploadFile,
dispatchCreateNewFile
dispatchCreateNewFile,
dispatchSetFocusElement,
dispatchCreateNewFolder,
dispatchDeletePath,
dispatchRenamePath,
dispatchCopyFile,
dispatchCopyFolder,
dispatchRunScript,
dispatchEmitContextMenuEvent,
dispatchHandleClickFile
}
return (
<FileSystemContext.Provider value={value}>

@ -33,7 +33,8 @@ export interface BrowserState {
},
readonly: boolean,
popup: string,
focusEdit: string
focusEdit: string,
focusElement: { key: string, type: 'file' | 'folder' | 'gist' }[]
}
export const browserInitialState: BrowserState = {
@ -65,7 +66,8 @@ export const browserInitialState: BrowserState = {
},
readonly: false,
popup: '',
focusEdit: ''
focusEdit: '',
focusElement: []
}
export const browserReducer = (state = browserInitialState, action: Action) => {
@ -453,6 +455,15 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
}
}
case 'SET_FOCUS_ELEMENT': {
const payload = action.payload as { key: string, type: 'file' | 'folder' | 'gist' }[]
return {
...state,
focusElement: payload
}
}
default:
throw new Error()
}

@ -45,12 +45,6 @@ export function Workspace (props: WorkspaceProps) {
}
}, [global.fs.browser.workspaces])
props.plugin.resetNewFile = () => {
setState(prevState => {
return { ...prevState, displayNewFile: !state.displayNewFile }
})
}
/* implement an external API, consumed by the parent */
props.plugin.request.createWorkspace = () => {
return createWorkspace()
@ -73,18 +67,6 @@ export function Workspace (props: WorkspaceProps) {
return { name: currentWorkspace, isLocalhost: currentWorkspace === LOCALHOST, absolutePath: `${props.plugin.workspace.workspacesPath}/${currentWorkspace}` }
}
const createNewWorkspace = async (workspaceName) => {
try {
await props.plugin.fileManager.closeAllFiles()
await props.plugin.createWorkspace(workspaceName)
await setWorkspace(workspaceName)
global.toast('New default workspace has been created.')
} catch (e) {
global.modal('Create Default Workspace', e.message, 'OK', onFinishRenameWorkspace, '')
console.error(e)
}
}
/* workspace creation, renaming and deletion */
const renameCurrentWorkspace = () => {

Loading…
Cancel
Save