diff --git a/src/app/compiler/compiler-imports.js b/src/app/compiler/compiler-imports.js
index 21e5549a50..244d1c4f31 100644
--- a/src/app/compiler/compiler-imports.js
+++ b/src/app/compiler/compiler-imports.js
@@ -110,10 +110,18 @@ module.exports = class CompilerImports extends Plugin {
})
}
- import (url, loadingCb, cb) {
+ import (url, force, loadingCb, cb) {
+ if (typeof force !== 'boolean') {
+ let temp = loadingCb
+ loadingCb = force
+ cb = temp
+ force = false
+ }
if (!loadingCb) loadingCb = () => {}
+ if (!cb) cb = () => {}
var self = this
+ if (force) delete this.previouslyHandled[url]
var imported = this.previouslyHandled[url]
if (imported) {
return cb(null, imported.content, imported.cleanUrl, imported.type, url)
diff --git a/src/app/files/file-explorer.js b/src/app/files/file-explorer.js
index 9ed63ca39a..0249ab783a 100644
--- a/src/app/files/file-explorer.js
+++ b/src/app/files/file-explorer.js
@@ -194,17 +194,29 @@ function fileExplorer (localRegistry, files, menuItems) {
if (self.files.readonly) return
if (key === self.files.type) return
MENU_HANDLE && MENU_HANDLE.hide(null, true)
- MENU_HANDLE = contextMenu(event, {
- 'Rename': () => {
+ let actions = {}
+ const provider = self._deps.fileManager.fileProviderOf(key)
+ if (provider.isExternalFolder(key)) {
+ actions['Discard changes'] = () => {
+ modalDialogCustom.confirm(
+ 'Discard changes',
+ 'Are you sure you want to discard all your changes?',
+ () => { files.discardChanges(key) },
+ () => {}
+ )
+ }
+ } else {
+ actions['Rename'] = () => {
if (self.files.readonly) { 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)
- },
- 'Delete': () => {
- if (self.files.readonly) { 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?', () => { files.remove(key) }, () => {})
}
- })
+ }
+ actions['Delete'] = () => {
+ if (self.files.readonly) { 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?', () => { files.remove(key) }, () => {})
+ }
+ MENU_HANDLE = contextMenu(event, actions)
})
self.treeView.event.register('leafRightClick', function (key, data, label, event) {
@@ -212,7 +224,7 @@ function fileExplorer (localRegistry, files, menuItems) {
MENU_HANDLE && MENU_HANDLE.hide(null, true)
let actions = {}
const provider = self._deps.fileManager.fileProviderOf(key)
- if (!provider.isReadOnly(key)) {
+ if (!provider.isExternalFolder(key)) {
actions['Rename'] = () => {
if (self.files.readonly) { return tooltip('cannot rename file. ' + self.files.type + ' is a read only explorer') }
var name = label.querySelector('span[data-path="' + key + '"]')
@@ -226,15 +238,6 @@ function fileExplorer (localRegistry, files, menuItems) {
() => {}
)
}
- } else {
- actions['Delete from remix'] = () => {
- modalDialogCustom.confirm(
- 'Delete from remix',
- 'Are you sure you want to delete this file from remix?',
- () => { files.remove(key) },
- () => {}
- )
- }
}
MENU_HANDLE = contextMenu(event, actions)
})
diff --git a/src/app/files/fileManager.js b/src/app/files/fileManager.js
index e1b9a57381..ced094987b 100644
--- a/src/app/files/fileManager.js
+++ b/src/app/files/fileManager.js
@@ -49,7 +49,7 @@ class FileManager extends Plugin {
localhostExplorer: this._components.registry.get('fileproviders/localhost').api,
filesProviders: this._components.registry.get('fileproviders').api
}
-
+ this._deps.browserExplorer.event.register('fileChanged', (path) => { this.fileChangedEvent(path) })
this._deps.browserExplorer.event.register('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) })
this._deps.localhostExplorer.event.register('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) })
this._deps.browserExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) })
@@ -58,6 +58,10 @@ class FileManager extends Plugin {
this._deps.localhostExplorer.event.register('closed', (event) => { this.removeTabsOf(this._deps.localhostExplorer) })
}
+ fileChangedEvent (path) {
+ this.syncEditor(path)
+ }
+
fileRenamedEvent (oldName, newName, isFolder) {
if (!isFolder) {
this._deps.config.set('currentFile', '')
diff --git a/src/app/files/fileProvider.js b/src/app/files/fileProvider.js
index 21c5c679e2..29cc29cfd6 100644
--- a/src/app/files/fileProvider.js
+++ b/src/app/files/fileProvider.js
@@ -1,13 +1,59 @@
'use strict'
-var EventManager = require('../../lib/events')
+const CompilerImport = require('../compiler/compiler-imports')
+const EventManager = require('../../lib/events')
+const modalDialogCustom = require('../ui/modal-dialog-custom')
+const tooltip = require('../ui/tooltip')
+const remixLib = require('remix-lib')
+const Storage = remixLib.Storage
class FileProvider {
constructor (name) {
this.event = new EventManager()
this.type = name
- this.normalizedNames = {} // contains the raw url associated with the displayed path
- this.readonlyItems = ['browser']
+ this.providerExternalsStorage = new Storage('providerExternals:')
+ this.externalFolders = [this.type + '/swarm', this.type + '/ipfs', this.type + '/github', this.type + '/gist', this.type + '/https']
+ }
+
+ addNormalizedName (path, url) {
+ this.providerExternalsStorage.set(this.type + '/' + path, url)
+ }
+
+ removeNormalizedName (path) {
+ this.providerExternalsStorage.remove(path)
+ }
+
+ normalizedNameExists (path) {
+ return this.providerExternalsStorage.exists(path)
+ }
+
+ getNormalizedName (path) {
+ return this.providerExternalsStorage.get(path)
+ }
+
+ isExternalFolder (path) {
+ return this.externalFolders.includes(path)
+ }
+
+ discardChanges (path) {
+ this.remove(path)
+ const compilerImport = new CompilerImport()
+ this.providerExternalsStorage.keys().map(value => {
+ if (value.indexOf(path) === 0) {
+ compilerImport.import(
+ this.getNormalizedName(value),
+ true,
+ (loadingMsg) => { tooltip(loadingMsg) },
+ (error, content, cleanUrl, type, url) => {
+ if (error) {
+ modalDialogCustom.alert(error)
+ } else {
+ this.addExternal(type + '/' + cleanUrl, content, url)
+ }
+ }
+ )
+ }
+ })
}
exists (path, cb) {
@@ -25,7 +71,7 @@ class FileProvider {
get (path, cb) {
cb = cb || function () {}
- if (this.normalizedNames[path]) path = this.normalizedNames[path] // ensure we actually use the normalized path from here
+ if (this.normalizedNameExists[path]) path = this.getNormalizedName(path) // ensure we actually use the normalized path from here
var unprefixedpath = this.removePrefix(path)
var exists = window.remixFileSystem.existsSync(unprefixedpath)
if (!exists) return cb(null, null)
@@ -36,10 +82,6 @@ class FileProvider {
set (path, content, cb) {
cb = cb || function () {}
- if (this.isReadOnly(path)) {
- cb(new Error('It is not possible to modify a readonly item'))
- return false
- }
var unprefixedpath = this.removePrefix(path)
var exists = window.remixFileSystem.existsSync(unprefixedpath)
if (!exists && unprefixedpath.indexOf('/') !== -1) {
@@ -70,26 +112,17 @@ class FileProvider {
return true
}
- addReadOnly (path, content, url) {
- this.readonlyItems.push(this.type + '/' + path)
- if (!url) this.normalizedNames[url] = path
+ // this will not add a folder as readonly but keep the original url to be able to restore it later
+ addExternal (path, content, url) {
+ if (url) this.addNormalizedName(path, url)
return this.set(path, content)
}
isReadOnly (path) {
- return this.readonlyItems.includes(path)
- }
-
- _removeFromReadonlyList (path) {
- const indexToRemove = this.readonlyItems.indexOf(path)
- if (indexToRemove !== -1) {
- this.readonlyItems.splice(indexToRemove, 1)
- }
+ return false
}
remove (path) {
- this._removeFromReadonlyList(path)
-
var unprefixedpath = this.removePrefix(path)
if (!this._exists(unprefixedpath)) {
return false
diff --git a/src/app/tabs/compile-tab.js b/src/app/tabs/compile-tab.js
index ededb6d5f2..28aaab0a4c 100644
--- a/src/app/tabs/compile-tab.js
+++ b/src/app/tabs/compile-tab.js
@@ -313,7 +313,7 @@ class CompileTab extends ViewPlugin {
modalDialogCustom.alert(yo`Metadata published successfully.
${result}
`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
- this.fileProvider.addReadOnly('swarm/' + item.hash, item.content)
+ this.fileProvider.addExternal('swarm/' + item.hash, item.content)
})
} else {
publishOnIpfs(contract, this.fileManager, function (err, uploaded) {
@@ -330,7 +330,7 @@ class CompileTab extends ViewPlugin {
modalDialogCustom.alert(yo`Metadata published successfully.
${result}
`)
}
}, (item) => { // triggered each time there's a new verified publish (means hash correspond)
- this.fileProvider.addReadOnly('ipfs/' + item.hash, item.content)
+ this.fileProvider.addExternal('ipfs/' + item.hash, item.content)
})
}
}
diff --git a/src/app/tabs/compileTab/compileTab.js b/src/app/tabs/compileTab/compileTab.js
index f2751d1d8c..e8f88da2cc 100644
--- a/src/app/tabs/compileTab/compileTab.js
+++ b/src/app/tabs/compileTab/compileTab.js
@@ -93,7 +93,7 @@ class CompileTab {
if (error) return cb(error)
if (this.fileProvider) {
- this.fileProvider.addReadOnly(cleanUrl, content, url)
+ this.fileProvider.addExternal(cleanUrl, content, url)
}
cb(null, content)
})
diff --git a/src/app/ui/landing-page/landing-page.js b/src/app/ui/landing-page/landing-page.js
index 908a78d284..a87235cd2e 100644
--- a/src/app/ui/landing-page/landing-page.js
+++ b/src/app/ui/landing-page/landing-page.js
@@ -106,7 +106,7 @@ export class LandingPage extends ViewPlugin {
if (error) {
modalDialogCustom.alert(error)
} else {
- fileProviders['browser'].addReadOnly(type + '/' + cleanUrl, content, url)
+ fileProviders['browser'].addExternal(type + '/' + cleanUrl, content, url)
this.verticalIcons.select('fileExplorers')
}
}