Merge branch 'master' into bunsenstraat-patch-1

pull/1210/head
bunsenstraat 4 years ago committed by GitHub
commit 93128aa956
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      apps/remix-ide-e2e/src/tests/gist.spec.ts
  2. 12
      apps/remix-ide/src/app/tabs/runTab/contractDropdown.js
  3. 2
      apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js
  4. 26
      apps/remix-ide/src/app/tabs/runTab/settings.js
  5. 8
      apps/remix-ide/src/app/ui/universal-dapp-ui.js
  6. 21
      apps/remix-ide/src/blockchain/blockchain.js
  7. 4
      apps/remix-ide/src/lib/gist-handler.js
  8. 5
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  9. 14
      libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts
  10. 10
      libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx
  11. 112
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  12. 9
      libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts
  13. 8
      libs/remix-ui/file-explorer/src/lib/types/index.ts

@ -54,9 +54,9 @@ module.exports = {
.click('[data-id="default_workspace-modal-footer-cancel-react"]')
.executeScript(`remix.loadgist('${gistid}')`)
// .perform((done) => { if (runtimeBrowser === 'chrome') { browser.openFile('gists') } done() })
.waitForElementVisible(`[data-id="treeViewLitreeViewItem${gistid}"]`)
.click(`[data-id="treeViewLitreeViewItem${gistid}"]`)
.openFile(`${gistid}/README.txt`)
.waitForElementVisible(`[data-id="treeViewLitreeViewItem/gist-${gistid}"]`)
.click(`[data-id="treeViewLitreeViewItem/gist-${gistid}"]`)
.openFile(`gist-${gistid}/README.txt`)
}
})
},
@ -118,9 +118,9 @@ module.exports = {
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId)
.modalFooterOKClick()
.openFile(`${testData.validGistId}/ApplicationRegistry`)
.waitForElementVisible(`div[title='default_workspace/${testData.validGistId}/ApplicationRegistry']`)
.assert.containsText(`div[title='default_workspace/${testData.validGistId}/ApplicationRegistry'] > span`, 'ApplicationRegistry')
.openFile(`gist-${testData.validGistId}/ApplicationRegistry`)
.waitForElementVisible(`div[title='default_workspace/gist-${testData.validGistId}/ApplicationRegistry']`)
.assert.containsText(`div[title='default_workspace/gist-${testData.validGistId}/ApplicationRegistry'] > span`, 'ApplicationRegistry')
.end()
}
}

@ -48,14 +48,13 @@ class ContractDropdownUI {
}
listenToContextChange () {
this.blockchain.event.register('contextChanged', () => {
this.blockchain.updateNetwork((err, { name } = {}) => {
if (err) {
this.blockchain.event.register('networkStatus', ({ error, network }) => {
if (error) {
console.log('can\'t detect network')
return
}
this.exEnvironment = this.blockchain.getProvider()
this.networkName = name
this.networkName = network.name
const savedConfig = window.localStorage.getItem(`ipfs/${this.exEnvironment}/${this.networkName}`)
@ -66,7 +65,6 @@ class ContractDropdownUI {
this.setCheckedState(this.networkName === 'Main')
}
})
})
}
setCheckedState (value) {
@ -306,10 +304,10 @@ class ContractDropdownUI {
const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data)
if (self.ipfsCheckedState) {
_paq.push(['trackEvent', 'udapp', `DeployAndPublish_${this.networkName}`])
_paq.push(['trackEvent', 'udapp', 'DeployAndPublish', this.networkName])
publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract)
} else {
_paq.push(['trackEvent', 'udapp', `DeployOnly_${this.networkName}`])
_paq.push(['trackEvent', 'udapp', 'DeployOnly', this.networkName])
}
}

@ -55,7 +55,7 @@ class DropdownLogic {
cb(null, 'abi', abi)
})
} else {
_paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithInstance'])
_paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithArtifacts'])
cb(null, 'instance')
}
}

@ -97,7 +97,7 @@ class SettingsUI {
Environment
</label>
<div class="${css.environment}">
<select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" onchange=${() => { this.updateNetwork() }} class="form-control ${css.select} custom-select">
<select id="selectExEnvOptions" data-id="settingsSelectEnvOptions" class="form-control ${css.select} custom-select">
<option id="vm-mode"
title="Execution environment does not connect to any node, everything is local and in memory only."
value="vm" name="executionContext"> JavaScript VM
@ -192,8 +192,17 @@ class SettingsUI {
this.setFinalContext()
})
this.blockchain.event.register('networkStatus', ({ error, network }) => {
if (error) {
this.netUI.innerHTML = 'can\'t detect network '
return
}
const networkProvider = this._components.networkModule.getNetworkProvider.bind(this._components.networkModule)
this.netUI.innerHTML = (networkProvider() !== 'vm') ? `${network.name} (${network.id || '-'}) network` : ''
})
setInterval(() => {
this.updateNetwork()
this.fillAccountsList()
}, 1000)
this.el = el
@ -273,7 +282,6 @@ class SettingsUI {
// set the final context. Cause it is possible that this is not the one we've originaly selected
this.selectExEnv.value = this.blockchain.getProvider()
this.event.trigger('clearInstance', [])
this.updateNetwork()
this.updatePlusButton()
}
@ -390,18 +398,6 @@ class SettingsUI {
})
}
updateNetwork () {
this.blockchain.updateNetwork((err, { id, name } = {}) => {
if (err) {
this.netUI.innerHTML = 'can\'t detect network '
return
}
const network = this._components.networkModule.getNetworkProvider.bind(this._components.networkModule)
this.netUI.innerHTML = (network() !== 'vm') ? `${name} (${id || '-'}) network` : ''
})
this.fillAccountsList()
}
// TODO: unclear what's the goal of accountListCallId, feels like it can be simplified
async fillAccountsList () {
this.accountListCallId++

@ -244,8 +244,12 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i
outputOverride.appendChild(decoded)
}
}
const info = `${lookupOnly ? 'call' : args.funABI.type !== 'fallback' ? 'lowLevelInteracions' : 'transact'}_${this.blockchain.executionContext.executionContext}`
_paq.push(['trackEvent', 'udapp', info])
let callinfo = ''
if (lookupOnly) callinfo = 'call'
else if (args.funABI.type === 'fallback' || args.funABI.type === 'receive') callinfo = 'lowLevelInteracions'
else callinfo = 'transact'
_paq.push(['trackEvent', 'udapp', callinfo, this.blockchain.getCurrentNetworkStatus().network.name])
const params = args.funABI.type !== 'fallback' ? inputsValues : ''
this.blockchain.runOrCallContractMethod(
args.contractName,

@ -41,6 +41,7 @@ class Blockchain {
this.executionContext.event.register('contextChanged', this.resetEnvironment.bind(this))
this.networkcallid = 0
this.networkStatus = { name: ' - ', id: ' - ' }
this.setupEvents()
this.setupProviders()
}
@ -57,6 +58,17 @@ class Blockchain {
this.executionContext.event.register('removeProvider', (name) => {
this.event.trigger('removeProvider', [name])
})
setInterval(() => {
this.detectNetwork((error, network) => {
this.networkStatus = { network, error }
this.event.trigger('networkStatus', [this.networkStatus])
})
}, 1000)
}
getCurrentNetworkStatus () {
return this.networkStatus
}
setupProviders () {
@ -197,15 +209,6 @@ class Blockchain {
return this.executionContext.setProviderFromEndpoint(target, context, cb)
}
updateNetwork (cb) {
this.executionContext.detectNetwork((err, { id, name } = {}) => {
if (err) {
return cb(err)
}
cb(null, { id, name })
})
}
detectNetwork (cb) {
return this.executionContext.detectNetwork(cb)
}

@ -54,7 +54,9 @@ function GistHandler (_window) {
}
const obj = {}
Object.keys(data.files).forEach((element) => {
obj['/' + gistId + '/' + element] = data.files[element]
const path = element.replace(/\.\.\./g, '/')
obj['/' + 'gist-' + gistId + '/' + path] = data.files[element]
})
fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => {
if (!errorLoadingFile) {

@ -9,6 +9,7 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
/* eslint-disable-next-line */
import './debugger-ui.css'
const helper = require('../../../../../apps/remix-ide/src/lib/helper')
const _paq = (window as any)._paq = (window as any)._paq || []
export const DebuggerUI = (props: DebuggerUIProps) => {
const debuggerModule = props.debuggerAPI
@ -167,7 +168,9 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
const web3 = await debuggerModule.getDebugWeb3()
try {
if (await web3.eth.net.getId() === 42) {
const networkId = await web3.eth.net.getId()
_paq.push(['trackEvent', 'debugger', 'startDebugging', networkId])
if (networkId === 42) {
setState(prevState => {
return {
...prevState,

@ -41,14 +41,16 @@ const normalize = (parent, filesList, newInputType?: string): any => {
if (filesList[key].isDirectory) {
folders[extractNameFromKey(key)] = {
path,
name: extractNameFromKey(path),
isDirectory: filesList[key].isDirectory
name: extractNameFromKey(path).indexOf('gist-') === 0 ? extractNameFromKey(path).split('-')[1] : extractNameFromKey(path),
isDirectory: filesList[key].isDirectory,
type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder'
}
} else {
files[extractNameFromKey(key)] = {
path,
name: extractNameFromKey(path),
isDirectory: filesList[key].isDirectory
isDirectory: filesList[key].isDirectory,
type: 'file'
}
}
})
@ -59,7 +61,8 @@ const normalize = (parent, filesList, newInputType?: string): any => {
folders[path] = {
path: path,
name: '',
isDirectory: true
isDirectory: true,
type: 'folder'
}
} else if (newInputType === 'file') {
const path = parent + '/blank'
@ -67,7 +70,8 @@ const normalize = (parent, filesList, newInputType?: string): any => {
files[path] = {
path: path,
name: '',
isDirectory: false
isDirectory: false,
type: 'file'
}
}

@ -4,7 +4,7 @@ import { FileExplorerContextMenuProps } from './types'
import './css/file-explorer-context-menu.css'
export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => {
const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, publishToGist, runScript, emit, pageX, pageY, path, type, ...otherProps } = props
const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, pushChangesToGist, publishFileToGist, publishFolderToGist, runScript, emit, pageX, pageY, path, type, ...otherProps } = props
const contextMenuRef = useRef(null)
useEffect(() => {
@ -50,7 +50,13 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) =>
deletePath(path)
break
case 'Push changes to gist':
publishToGist()
pushChangesToGist(path, type)
break
case 'Publish folder to gist':
publishFolderToGist(path, type)
break
case 'Publish file to gist':
publishFileToGist(path, type)
break
case 'Run':
runScript(path)

@ -31,14 +31,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
actions: [{
id: 'newFile',
name: 'New File',
type: ['folder'],
type: ['folder', 'gist'],
path: [],
extension: [],
pattern: []
}, {
id: 'newFolder',
name: 'New Folder',
type: ['folder'],
type: ['folder', 'gist'],
path: [],
extension: [],
pattern: []
@ -52,17 +52,31 @@ export const FileExplorer = (props: FileExplorerProps) => {
}, {
id: 'delete',
name: 'Delete',
type: ['file', 'folder'],
type: ['file', 'folder', 'gist'],
path: [],
extension: [],
pattern: []
}, {
id: 'pushChangesToGist',
name: 'Push changes to gist',
type: [],
type: ['gist'],
path: [],
extension: [],
pattern: []
}, {
id: 'publishFolderToGist',
name: 'Publish folder to gist',
type: ['folder'],
path: [],
extension: [],
pattern: ['^browser/gists/([0-9]|[a-z])*$']
pattern: []
}, {
id: 'publishFileToGist',
name: 'Publish file to gist',
type: ['file'],
path: [],
extension: [],
pattern: []
}, {
id: 'run',
name: 'Run',
@ -228,6 +242,15 @@ export const FileExplorer = (props: FileExplorerProps) => {
else return false
}
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
else return name
}
}
const createNewFile = async (newFilePath: string) => {
const fileManager = state.fileManager
@ -309,7 +332,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
// the files module. Please ask the user here if they want to overwrite
// a file and then just use `files.add`. The file explorer will
// pick that up via the 'fileAdded' event from the files module.
const parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name
const parentFolder = getFocusedFolder()
const expandPath = [...new Set([...state.expandPath, parentFolder])]
setState(prevState => {
@ -355,11 +378,23 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
}
const publishToGist = () => {
modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${name} workspace as a public gist on github.com?`, 'OK', toGist, 'Cancel', () => {})
const publishToGist = (path?: string, type?: string) => {
modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${name} workspace as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {})
}
const pushChangesToGist = (path?: string, type?: string) => {
modal('Create a public gist', 'Are you sure you want to push changes to remote gist file on github.com?', 'OK', () => toGist(path, type), 'Cancel', () => {})
}
const publishFolderToGist = (path?: string, type?: string) => {
modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${path} folder as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {})
}
const publishFileToGist = (path?: string, type?: string) => {
modal('Create a public gist', `Are you sure you want to anonymously publish ${path} file as a public gist on github.com?`, 'OK', () => toGist(path, type), 'Cancel', () => {})
}
const toGist = (id?: string) => {
const toGist = (path?: string, type?: string) => {
const filesProvider = fileSystem.provider.provider
const proccedResult = function (error, data) {
if (error) {
@ -393,7 +428,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
// If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer.
const folder = id ? '/gists/' + id : '/'
const folder = path || '/'
const id = type === 'gist' ? extractNameFromKey(path).split('-')[1] : null
packageFiles(filesProvider, folder, async (error, packaged) => {
if (error) {
@ -501,15 +537,15 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
}
const handleClickFile = (path: string) => {
const handleClickFile = (path: string, type: string) => {
path = path.indexOf(props.name + '/') === 0 ? path.replace(props.name + '/', '') : path
state.fileManager.open(path)
setState(prevState => {
return { ...prevState, focusElement: [{ key: path, type: 'file' }] }
return { ...prevState, focusElement: [{ key: path, type }] }
})
}
const handleClickFolder = async (path: string) => {
const handleClickFolder = async (path: string, type: string) => {
if (state.ctrlKey) {
if (state.focusElement.findIndex(item => item.key === path) !== -1) {
setState(prevState => {
@ -517,7 +553,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
} else {
setState(prevState => {
return { ...prevState, focusElement: [...prevState.focusElement, { key: path, type: 'folder' }] }
return { ...prevState, focusElement: [...prevState.focusElement, { key: path, type }] }
})
}
} else {
@ -531,22 +567,22 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
setState(prevState => {
return { ...prevState, focusElement: [{ key: path, type: 'folder' }], expandPath }
return { ...prevState, focusElement: [{ key: path, type }], expandPath }
})
}
}
const handleContextMenuFile = (pageX: number, pageY: number, path: string, content: string) => {
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: 'file' }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path }
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) => {
const handleContextMenuFolder = (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: 'folder' }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path }
return { ...prevState, focusContext: { element: path, x: pageX, y: pageY, type }, focusEdit: { ...prevState.focusEdit, lastEdit: content }, showContextMenu: prevState.focusEdit.element !== path }
})
}
@ -618,7 +654,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const handleNewFileInput = async (parentFolder?: string) => {
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name
if (!parentFolder) parentFolder = getFocusedFolder()
const expandPath = [...new Set([...state.expandPath, parentFolder])]
await addInputField(fileSystem.provider.provider, 'file', parentFolder)(dispatch)
@ -629,7 +665,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
const handleNewFolderInput = async (parentFolder?: string) => {
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name
if (!parentFolder) parentFolder = getFocusedFolder()
else if ((parentFolder.indexOf('.sol') !== -1) || (parentFolder.indexOf('.js') !== -1)) parentFolder = extractParentFromKey(parentFolder)
const expandPath = [...new Set([...state.expandPath, parentFolder])]
@ -705,12 +741,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
label={label(file)}
onClick={(e) => {
e.stopPropagation()
if (state.focusEdit.element !== file.path) handleClickFolder(file.path)
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)
handleContextMenuFolder(e.pageX, e.pageY, file.path, e.target.textContent, file.type)
}}
labelClass={labelClass}
controlBehaviour={ state.ctrlKey }
@ -742,12 +778,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
label={label(file)}
onClick={(e) => {
e.stopPropagation()
if (state.focusEdit.element !== file.path) handleClickFile(file.path)
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)
handleContextMenuFile(e.pageX, e.pageY, file.path, e.target.textContent, file.type)
}}
icon={icon}
labelClass={labelClass}
@ -841,6 +877,9 @@ export const FileExplorer = (props: FileExplorerProps) => {
e.stopPropagation()
handleMouseOver(state.focusContext.element)
}}
pushChangesToGist={pushChangesToGist}
publishFolderToGist={publishFolderToGist}
publishFileToGist={publishFileToGist}
/>
}
</div>
@ -850,12 +889,34 @@ export const FileExplorer = (props: FileExplorerProps) => {
export default FileExplorer
async function packageFiles (filesProvider, directory, callback) {
const isFile = filesProvider.isFile(directory)
const ret = {}
if (isFile) {
try {
filesProvider.get(directory, (error, content) => {
if (error) throw new Error('An error ocurred while getting file content. ' + directory)
if (/^\s+$/.test(content) || !content.length) {
content = '// this line is added to create a gist. Empty file is not allowed.'
}
directory = directory.replace(/\//g, '...')
ret[directory] = { content }
callback(null, ret)
})
} catch (e) {
return callback(e)
}
} else {
try {
await filesProvider.copyFolderToJson(directory, ({ path, content }) => {
if (/^\s+$/.test(content) || !content.length) {
content = '// this line is added to create a gist. Empty file is not allowed.'
}
if (path.indexOf('gist-') === 0) {
path = path.split('/')
path.shift()
path = path.join('/')
}
path = path.replace(/\//g, '...')
ret[path] = { content }
})
@ -864,6 +925,7 @@ async function packageFiles (filesProvider, directory, callback) {
return callback(e)
}
}
}
function joinPath (...paths) {
paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)

@ -258,7 +258,8 @@ const resolveDirectory = (root, path: string, files, content) => {
files = _.set(files, _path, {
isDirectory: true,
path,
name: extractNameFromKey(path),
name: extractNameFromKey(path).indexOf('gist-') === 0 ? extractNameFromKey(path).split('-')[1] : extractNameFromKey(path),
type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder',
child: { ...content[pathArr[pathArr.length - 1]], ...(prevFiles ? prevFiles.child : {}) }
})
@ -278,7 +279,8 @@ const removePath = (root, path: string, pathName, files) => {
files = _.set(files, _path, {
isDirectory: true,
path,
name: extractNameFromKey(path),
name: extractNameFromKey(path).indexOf('gist-') === 0 ? extractNameFromKey(path).split('-')[1] : extractNameFromKey(path),
type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder',
child: prevFiles ? prevFiles.child : {}
})
@ -336,7 +338,8 @@ const fileRenamed = (root, path: string, removePath: string, files, content) =>
files = _.set(files, _path, {
isDirectory: true,
path,
name: extractNameFromKey(path),
name: extractNameFromKey(path).indexOf('gist-') === 0 ? extractNameFromKey(path).split('-')[1] : extractNameFromKey(path),
type: extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder',
child: { ...content[pathArr[pathArr.length - 1]], ...prevFiles.child }
})

@ -15,6 +15,7 @@ export interface File {
path: string,
name: string,
isDirectory: boolean,
type: string,
child?: File[]
}
@ -24,7 +25,7 @@ export interface FileExplorerMenuProps {
fileManager: any,
createNewFile: (folder?: string) => void,
createNewFolder: (parentFolder?: string) => void,
publishToGist: () => void,
publishToGist: (path?: string) => void,
uploadFile: (target: EventTarget & HTMLInputElement) => void
}
@ -35,7 +36,10 @@ export interface FileExplorerContextMenuProps {
deletePath: (path: string) => void,
renamePath: (path: string, type: string) => void,
hideContextMenu: () => void,
publishToGist?: () => void,
publishToGist?: (path?: string, type?: string) => void,
pushChangesToGist?: (path?: string, type?: string) => void,
publishFolderToGist?: (path?: string, type?: string) => void,
publishFileToGist?: (path?: string, type?: string) => void,
runScript?: (path: string) => void,
emit?: (id: string, path: string) => void,
pageX: number,

Loading…
Cancel
Save