Commit 39d47a4a authored by ioedeveloper's avatar ioedeveloper

create new file with plugin call

parent 825db4a6
......@@ -132,7 +132,10 @@ module.exports = class Filepanel extends ViewPlugin {
}
async createNewFile () {
return await this.request.createNewFile()
const provider = this.fileManager.currentFileProvider()
const dir = provider.workspace || '/'
this.emit('displayNewFileInput', dir)
}
async uploadFile (event) {
......
......@@ -11,9 +11,10 @@ import { customAction } from '@remixproject/plugin-api/lib/file-system/file-pane
import { contextMenuActions } from './utils'
import './css/file-explorer.css'
import { extractParentFromKey } from '@remix-ui/helper'
export const FileExplorer = (props: FileExplorerProps) => {
const { name, focusRoot, contextMenuItems, displayInput, externalUploads, removedContextMenuItems, resetFocus, files } = props
const { name, focusRoot, contextMenuItems, externalUploads, removedContextMenuItems, resetFocus, files } = props
const [state, setState] = useState<FileExplorerState>({
focusElement: [{
key: '',
......@@ -62,7 +63,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
if (editRef && editRef.current) {
editRef.current.focus()
}
}, 150)
}, 0)
}
}, [state.focusEdit.element])
......@@ -88,11 +89,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
}, [contextMenuItems])
useEffect(() => {
if (displayInput) {
handleNewFileInput()
plugin.resetNewFile()
if (global.fs.focusEdit) {
setState(prevState => {
return { ...prevState, focusEdit: { element: global.fs.focusEdit, type: 'file', isNew: true, lastEdit: null } }
})
}
}, [displayInput])
}, [global.fs.focusEdit])
useEffect(() => {
if (externalUploads) {
......@@ -173,14 +175,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
return keyPath[keyPath.length - 1]
}
const extractParentFromKey = (key: string):string => {
if (!key) return
const keyPath = key.split('/')
keyPath.pop()
return keyPath.join('/')
}
const hasReservedKeyword = (content: string): boolean => {
if (state.reservedKeywords.findIndex(value => content.startsWith(value)) !== -1) return true
else return false
......@@ -196,22 +190,11 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const createNewFile = async (newFilePath: string) => {
const fileManager = state.fileManager
try {
const newName = await helper.createNonClashingNameAsync(newFilePath, fileManager)
const createFile = await fileManager.writeFile(newName, '')
if (!createFile) {
return global.toast('Failed to create file ' + newName)
} else {
const path = newName.indexOf(props.name + '/') === 0 ? newName.replace(props.name + '/', '') : newName
await fileManager.open(path)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
})
}
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 () => {})
}
......@@ -536,12 +519,14 @@ 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={state.focusEdit.element === file.path ? editRef : null}
ref={ isEditable ? editRef : null}
suppressContentEditableWarning={true}
contentEditable={state.focusEdit.element === file.path}
contentEditable={isEditable}
onKeyDown={handleEditInput}
onBlur={(e) => {
e.stopPropagation()
......
......@@ -19,3 +19,25 @@ export const checkSpecialChars = (name: string) => {
export const checkSlash = (name: string) => {
return name.match(/\//) != null
}
export const createNonClashingNameAsync = async (name, fileManager, prefix = '') => {
if (!name) name = 'Undefined'
let counter
let ext = 'sol'
const reg = /(.*)\.([^.]+)/g
const split = reg.exec(name)
if (split) {
name = split[1]
ext = split[2]
}
let exist = true
do {
const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext)
if (isDuplicate) counter = (counter | 0) + 1
else exist = false
} while (exist)
return name + counter + prefix + '.' + ext
}
import React from 'react'
import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import axios, { AxiosResponse } from 'axios'
import { checkSpecialChars, checkSlash, extractParentFromKey, extractNameFromKey } from '@remix-ui/helper'
import { checkSpecialChars, checkSlash, extractParentFromKey, extractNameFromKey, createNonClashingNameAsync } from '@remix-ui/helper'
import Gists from 'gists'
const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params')
......@@ -421,7 +421,6 @@ const listenOnEvents = (provider) => {
})
provider.event.on('fileRenamed', async (oldPath: string, newPath: string) => {
console.log('oldPath: ', oldPath, 'newPath: ', newPath)
await executeEvent('fileRenamed', oldPath, newPath)
})
......@@ -469,9 +468,14 @@ const listenOnEvents = (provider) => {
))
}
})
provider.event.on('fileRenamedError', async () => {
dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel'))
})
plugin.on('filePanel', 'displayNewFileInput', (path) => {
addInputField('file', path)(dispatch)
})
}
export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.Dispatch<any>) => {
......@@ -750,6 +754,20 @@ export const uploadFile = (target, targetFolder: string) => async (dispatch: Rea
})
}
export const createNewFile = (path: string, rootDir: string) => async (dispatch: React.Dispatch<any>) => {
const fileManager = plugin.fileManager
const newName = await createNonClashingNameAsync(path, fileManager)
const createFile = await fileManager.writeFile(newName, '')
if (!createFile) {
return dispatch(displayPopUp('Failed to create file ' + newName))
} else {
const path = newName.indexOf(rootDir + '/') === 0 ? newName.replace(rootDir + '/', '') : newName
await fileManager.open(path)
}
}
const fileAdded = async (filePath: string) => {
await dispatch(fileAddedSuccess(filePath))
if (filePath.includes('_test.sol')) {
......
......@@ -15,5 +15,6 @@ export const FileSystemContext = createContext<{
dispatchRenameWorkspace: (oldName: string, workspaceName: string) => Promise<void>,
dispatchDeleteWorkspace: (workspaceName: string) => Promise<void>,
dispatchPublishToGist: (path?: string, type?: string) => Promise<void>,
dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>
dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>
}>(null)
......@@ -5,7 +5,7 @@ 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 } from '../actions/workspace'
import { initWorkspace, fetchDirectory, addInputField, removeInputField, createWorkspace, fetchWorkspaceDirectory, switchToWorkspace, renameWorkspace, deleteWorkspace, clearPopUp, publishToGist, uploadFile, createNewFile } from '../actions/workspace'
import { Modal, WorkspaceProps } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Workspace } from '../remix-ui-workspace'
......@@ -70,6 +70,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await uploadFile(target, targetFolder)(fsDispatch)
}
const dispatchCreateNewFile = async (path: string, rootDir: string) => {
await createNewFile(path, rootDir)(fsDispatch)
}
useEffect(() => {
if (modals.length > 0) {
setFocusModal(() => {
......@@ -154,7 +158,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchRenameWorkspace,
dispatchDeleteWorkspace,
dispatchPublishToGist,
dispatchUploadFile
dispatchUploadFile,
dispatchCreateNewFile
}
return (
<FileSystemContext.Provider value={value}>
......
......@@ -32,7 +32,8 @@ export interface BrowserState {
labelCancel: string
},
readonly: boolean,
popup: string
popup: string,
focusEdit: string
}
export const browserInitialState: BrowserState = {
......@@ -63,7 +64,8 @@ export const browserInitialState: BrowserState = {
labelCancel: ''
},
readonly: false,
popup: ''
popup: '',
focusEdit: ''
}
export const browserReducer = (state = browserInitialState, action: Action) => {
......@@ -320,7 +322,8 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
localhost: {
...state.localhost,
files: state.mode === 'localhost' ? fetchDirectoryContent(state, payload) : state.localhost.files
}
},
focusEdit: payload.path + '/' + 'blank'
}
}
......@@ -336,7 +339,8 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
localhost: {
...state.localhost,
files: state.mode === 'localhost' ? fetchDirectoryContent(state, payload, payload.path + '/' + 'blank') : state.localhost.files
}
},
focusEdit: null
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment