From c3efdd588cc1a80c38c1ed518f34ec5352f66966 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Fri, 8 Nov 2019 20:51:46 +0100 Subject: [PATCH 1/7] unique name for create file --- src/app/files/file-explorer.js | 6 ++---- src/app/files/fileProvider.js | 37 +++++++++++++++++++--------------- src/lib/helper.js | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index b46dc6a439..4c7f0cb332 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -579,13 +579,11 @@ fileExplorer.prototype.copyFiles = function () { } } -fileExplorer.prototype.createNewFile = function (parentFolder) { +fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') { let self = this modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { - helper.createNonClashingName(input, self.files, (error, newName) => { + helper.createNonClashingName(parentFolder + '/' + input, self.files, (error, newName) => { if (error) return modalDialogCustom.alert('Failed to create file ' + newName + ' ' + error) - const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder - newName = currentPath ? currentPath + '/' + newName : self.files.type + '/' + newName if (!self.files.set(newName, '')) { modalDialogCustom.alert('Failed to create file ' + newName) diff --git a/src/app/files/fileProvider.js b/src/app/files/fileProvider.js index 9d288f3223..b7cfb2822e 100644 --- a/src/app/files/fileProvider.js +++ b/src/app/files/fileProvider.js @@ -131,23 +131,28 @@ class FileProvider { return false } + /** + * Removes the folder recursively + * @param {*} path is the folder to be removed + */ remove (path) { - var unprefixedpath = this.removePrefix(path) - if (!this._exists(unprefixedpath)) { - return false - } - const stat = window.remixFileSystem.statSync(unprefixedpath) - try { - if (stat.isDirectory()) { - window.remixFileSystem.rmdirSync(unprefixedpath, console.log) - } else { - window.remixFileSystem.unlinkSync(unprefixedpath, console.log) - } - this.event.trigger('fileRemoved', [this._normalizePath(unprefixedpath)]) - return true - } catch (e) { - console.log(e) - return false + path = this.removePrefix(path) + if (window.remixFileSystem.existsSync(path)) { + window.remixFileSystem.readdirSync(path).forEach((file, index) => { + let curPath = path + '/' + file + let stat = window.remixFileSystem.statSync(curPath) + try { + if (stat.isDirectory()) { + this.remove(curPath) + window.remixFileSystem.rmdirSync(curPath, console.log) + } else { // delete file + window.remixFileSystem.unlinkSync(curPath, console.log) + } + } catch (e) { + console.log(e) + return false + } + }) } } diff --git a/src/lib/helper.js b/src/lib/helper.js index b72c3aa3a0..e2d12e83ed 100644 --- a/src/lib/helper.js +++ b/src/lib/helper.js @@ -12,6 +12,7 @@ module.exports = { return data.slice(0, 5) + '...' + data.slice(len - 5, len) }, createNonClashingNameWithPrefix (name, fileProvider, prefix, cb) { + if (name === '') name = 'Undefined' var counter = '' var ext = 'sol' var reg = /(.*)\.([^.]+)/g From 58ae06851ffc499922c4f0286eba7ce5f9037aaf Mon Sep 17 00:00:00 2001 From: LianaHus Date: Mon, 11 Nov 2019 21:52:07 +0100 Subject: [PATCH 2/7] fixed - same name - empty name - remove empty folder - close deleted file tab issues --- src/app/files/file-explorer.js | 28 ++++++++++++++++++----- src/app/files/fileProvider.js | 42 +++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index 4c7f0cb332..e2c5f83503 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -213,7 +213,7 @@ function fileExplorer (localRegistry, files, menuItems) { modalDialogCustom.confirm( 'Discard changes', 'Are you sure you want to discard all your changes?', - () => { files.discardChanges(key) }, + () => { self.files.discardChanges(key) }, () => {} ) } @@ -244,6 +244,9 @@ function fileExplorer (localRegistry, files, menuItems) { modalDialogCustom.confirm('Confirm to delete a folder', 'Are you sure you want to delete this folder?', () => { if (!files.remove(key)) tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) + else { + self.updatePath('browser') + } }, () => {}) } MENU_HANDLE = contextMenu(event, actions) @@ -265,7 +268,10 @@ function fileExplorer (localRegistry, files, menuItems) { if (self.files.isReadOnly(key)) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') } modalDialogCustom.confirm( 'Delete a file', 'Are you sure you want to delete this file?', - () => { files.remove(key) }, + () => { + files.remove(key) + self.updatePath('browser') + }, () => {} ) } @@ -599,14 +605,24 @@ fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') { fileExplorer.prototype.createNewFolder = function (parentFolder) { let self = this - modalDialogCustom.prompt('Create new folder', '', '', (input) => { + modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { + if (input === '') { + modalDialogCustom.alert('Failed to create folder. The name can not be empty') + return false + } + const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder let newName = currentPath ? currentPath + '/' + input : self.files.type + '/' + input newName = newName + '/' - if (!self.files.set(newName, '')) { - modalDialogCustom.alert('Failed to create folder ' + newName) - } + self.files.exists(newName, (error, exist) => { + if (error) return modalDialogCustom.alert('Unexpected error while creating folder: ' + error) + if (!exist) { + self.files.set(newName, '') + } else { + modalDialogCustom.alert('Folder already exists.', () => {}) + } + }) }, null, true) } diff --git a/src/app/files/fileProvider.js b/src/app/files/fileProvider.js index b7cfb2822e..8aaf2d238f 100644 --- a/src/app/files/fileProvider.js +++ b/src/app/files/fileProvider.js @@ -64,6 +64,8 @@ class FileProvider { } exists (path, cb) { + // todo check the type (directory/file) as well #2386 + // currently it is not possible to have a file and folder with same path cb(null, this._exists(path)) } @@ -138,22 +140,36 @@ class FileProvider { remove (path) { path = this.removePrefix(path) if (window.remixFileSystem.existsSync(path)) { - window.remixFileSystem.readdirSync(path).forEach((file, index) => { - let curPath = path + '/' + file - let stat = window.remixFileSystem.statSync(curPath) - try { - if (stat.isDirectory()) { - this.remove(curPath) - window.remixFileSystem.rmdirSync(curPath, console.log) - } else { // delete file - window.remixFileSystem.unlinkSync(curPath, console.log) + const stat = window.remixFileSystem.statSync(path) + try { + if (!stat.isDirectory()) { + window.remixFileSystem.unlinkSync(path, console.log) + this.event.trigger('fileRemoved', [this._normalizePath(path)]) + return true + } else { + let items = window.remixFileSystem.readdirSync(path) + if (items.length !== 0) { + items.forEach((item, index) => { + let curPath = path + '/' + item + if (window.remixFileSystem.statSync(curPath).isDirectory()) { // delete folder + this.remove(curPath) + } else { // delete file + window.remixFileSystem.unlinkSync(curPath, console.log) + this.event.trigger('fileRemoved', [this._normalizePath(path)]) + } + }) + if (window.remixFileSystem.readdirSync(path).length === 0) window.remixFileSystem.rmdirSync(path, console.log) + } else { + // folder is empty + window.remixFileSystem.rmdirSync(path, console.log) } - } catch (e) { - console.log(e) - return false } - }) + } catch (e) { + console.log(e) + return false + } } + return true } rename (oldPath, newPath, isFolder) { From 387e5fe7481d7414a9437e899c031df518c85289 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Mon, 11 Nov 2019 22:09:59 +0100 Subject: [PATCH 3/7] cleanup context menu for externals --- src/app/files/file-explorer.js | 35 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index e2c5f83503..02d08dc017 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -208,6 +208,8 @@ function fileExplorer (localRegistry, files, menuItems) { MENU_HANDLE && MENU_HANDLE.hide(null, true) let actions = {} const provider = self._deps.fileManager.fileProviderOf(key) + actions['Create File'] = () => self.createNewFile(key) + actions['Create Folder'] = () => self.createNewFolder(key) if (provider.isExternalFolder(key)) { actions['Discard changes'] = () => { modalDialogCustom.confirm( @@ -219,6 +221,21 @@ function fileExplorer (localRegistry, files, menuItems) { } } else { const folderPath = extractExternalFolder(key) + actions['Rename'] = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') } + var name = label.querySelector('span[data-path="' + key + '"]') + if (name) editModeOn(name) + } + actions['Delete'] = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } + modalDialogCustom.confirm('Confirm to delete a folder', 'Are you sure you want to delete this folder?', + () => { + if (!files.remove(key)) tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) + else { + self.updatePath('browser') + } + }, () => {}) + } if (folderPath === 'browser/gists') { actions['Push changes to gist'] = () => { const id = key.substr(key.lastIndexOf('/') + 1, key.length - 1) @@ -230,24 +247,6 @@ function fileExplorer (localRegistry, files, menuItems) { ) } } - actions['Create File'] = () => self.createNewFile(key) - actions['Create Folder'] = () => self.createNewFolder(key) - - actions['Rename'] = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') } - var name = label.querySelector('span[data-path="' + key + '"]') - if (name) editModeOn(name) - } - } - actions['Delete'] = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } - modalDialogCustom.confirm('Confirm to delete a folder', 'Are you sure you want to delete this folder?', - () => { - if (!files.remove(key)) tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) - else { - self.updatePath('browser') - } - }, () => {}) } MENU_HANDLE = contextMenu(event, actions) }) From 7e128f1bac12cb5eb995fb1ba3dd6f03c9d6e1e2 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 12 Nov 2019 10:37:28 +0100 Subject: [PATCH 4/7] added path as a tooltip for tab --- src/app/panels/tab-proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/panels/tab-proxy.js b/src/app/panels/tab-proxy.js index 7240e05f16..47f2988553 100644 --- a/src/app/panels/tab-proxy.js +++ b/src/app/panels/tab-proxy.js @@ -132,7 +132,7 @@ export class TabProxy { id: name, title, icon, - tooltip: title + tooltip: name }) this._handlers[name] = { switchTo, close } } From b7d5bf428b5d03d2bc6b594735f31a32e6381834 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 12 Nov 2019 10:37:57 +0100 Subject: [PATCH 5/7] used toasters/tooltips instead of modaldialogcustom.alert --- src/app/files/file-explorer.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index 02d08dc017..cfc8a58867 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -158,7 +158,6 @@ function fileExplorer (localRegistry, files, menuItems) { var isFile = false Object.keys(value).filter(function keep (x) { if (x === '/content') isFile = true - // if (x === '/readOnly') isReadOnly = true if (x[0] !== '/') return true }).forEach(function (x) { newValue[x] = value[x] }) return { @@ -230,8 +229,9 @@ function fileExplorer (localRegistry, files, menuItems) { if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } modalDialogCustom.confirm('Confirm to delete a folder', 'Are you sure you want to delete this folder?', () => { - if (!files.remove(key)) tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) - else { + if (!files.remove(key)) { + tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) + } else { self.updatePath('browser') } }, () => {}) @@ -587,11 +587,12 @@ fileExplorer.prototype.copyFiles = function () { fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') { let self = this modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { + if (input === '') input = 'New file' helper.createNonClashingName(parentFolder + '/' + input, self.files, (error, newName) => { - if (error) return modalDialogCustom.alert('Failed to create file ' + newName + ' ' + error) + if (error) return tooltip('Failed to create file ' + newName + ' ' + error) if (!self.files.set(newName, '')) { - modalDialogCustom.alert('Failed to create file ' + newName) + tooltip('Failed to create file ' + newName) } else { self._deps.fileManager.switchFile(newName) if (newName.includes('_test.sol')) { @@ -606,7 +607,7 @@ fileExplorer.prototype.createNewFolder = function (parentFolder) { let self = this modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { if (input === '') { - modalDialogCustom.alert('Failed to create folder. The name can not be empty') + tooltip('Failed to create folder. The name can not be empty') return false } @@ -615,11 +616,11 @@ fileExplorer.prototype.createNewFolder = function (parentFolder) { newName = newName + '/' self.files.exists(newName, (error, exist) => { - if (error) return modalDialogCustom.alert('Unexpected error while creating folder: ' + error) + if (error) return tooltip('Unexpected error while creating folder: ' + error) if (!exist) { self.files.set(newName, '') } else { - modalDialogCustom.alert('Folder already exists.', () => {}) + tooltip('Folder already exists.', () => {}) } }) }, null, true) From 6ae754da7a37b57f0ccbc601248f6fa7ae631806 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 12 Nov 2019 12:00:06 +0100 Subject: [PATCH 6/7] fixes after review --- src/app/files/file-explorer.js | 7 +++---- src/app/files/fileProvider.js | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js index cfc8a58867..c172d0e421 100644 --- a/src/app/files/file-explorer.js +++ b/src/app/files/file-explorer.js @@ -587,7 +587,7 @@ fileExplorer.prototype.copyFiles = function () { fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') { let self = this modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { - if (input === '') input = 'New file' + if (!input) input = 'New file' helper.createNonClashingName(parentFolder + '/' + input, self.files, (error, newName) => { if (error) return tooltip('Failed to create file ' + newName + ' ' + error) @@ -606,9 +606,8 @@ fileExplorer.prototype.createNewFile = function (parentFolder = 'browser') { fileExplorer.prototype.createNewFolder = function (parentFolder) { let self = this modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { - if (input === '') { - tooltip('Failed to create folder. The name can not be empty') - return false + if (!input) { + return tooltip('Failed to create folder. The name can not be empty') } const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder diff --git a/src/app/files/fileProvider.js b/src/app/files/fileProvider.js index 8aaf2d238f..ce1605c142 100644 --- a/src/app/files/fileProvider.js +++ b/src/app/files/fileProvider.js @@ -147,10 +147,10 @@ class FileProvider { this.event.trigger('fileRemoved', [this._normalizePath(path)]) return true } else { - let items = window.remixFileSystem.readdirSync(path) + const items = window.remixFileSystem.readdirSync(path) if (items.length !== 0) { items.forEach((item, index) => { - let curPath = path + '/' + item + const curPath = `${path}/${item}` if (window.remixFileSystem.statSync(curPath).isDirectory()) { // delete folder this.remove(curPath) } else { // delete file From e434cd0bf7d5a57b47003a09224056ff7d2feb3d Mon Sep 17 00:00:00 2001 From: LianaHus Date: Tue, 12 Nov 2019 12:34:58 +0100 Subject: [PATCH 7/7] last fix --- src/lib/helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/helper.js b/src/lib/helper.js index e2d12e83ed..8628418f5e 100644 --- a/src/lib/helper.js +++ b/src/lib/helper.js @@ -12,7 +12,7 @@ module.exports = { return data.slice(0, 5) + '...' + data.slice(len - 5, len) }, createNonClashingNameWithPrefix (name, fileProvider, prefix, cb) { - if (name === '') name = 'Undefined' + if (!name) name = 'Undefined' var counter = '' var ext = 'sol' var reg = /(.*)\.([^.]+)/g