diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index d537d0812e..07043a4284 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -16,7 +16,7 @@ import { ModalPluginTester } from './app/plugins/test' import { WalkthroughService } from './walkthroughService' -import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, FetchAndCompile, CompilerImports, EditorContextListener } from '@remix-project/core-plugin' +import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, FetchAndCompile, CompilerImports, EditorContextListener, LoadFromGistHandler, GistHandler } from '@remix-project/core-plugin' import migrateFileSystem from './migrateFileSystem' import Registry from './app/state/registry' @@ -106,6 +106,8 @@ class AppComponent { } // SERVICES + // ----------------- gist service --------------------------------- + self.gistHandler = new GistHandler() // ----------------- theme service --------------------------------- self.themeModule = new ThemeModule() Registry.getInstance().put({ api: self.themeModule, name: 'themeModule' }) @@ -166,6 +168,7 @@ class AppComponent { self.engine.register([ self.modal, + self.gistHandler, configPlugin, blockchain, contentImport, @@ -280,7 +283,7 @@ class AppComponent { await self.appManager.activatePlugin(['sidePanel']) // activating host plugin separately await self.appManager.activatePlugin(['home']) await self.appManager.activatePlugin(['settings', 'config']) - await self.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'contextualListener', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport']) + await self.appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'contextualListener', 'terminal', 'blockchain', 'fetchAndCompile', 'contentImport', 'gistHandler']) await self.appManager.activatePlugin(['settings']) await self.appManager.activatePlugin(['walkthrough']) await self.appManager.activatePlugin(['testerplugin']) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index c526f36600..a57a10f53f 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -22,7 +22,7 @@ const profile = { icon: 'assets/img/fileManager.webp', permission: true, version: packageJson.version, - methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile'], + methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile', 'setBatchFiles'], kind: 'file-system' } const errorMsg = { diff --git a/apps/remix-ide/src/app/panels/terminal.js b/apps/remix-ide/src/app/panels/terminal.js index 4837f24203..272284c53c 100644 --- a/apps/remix-ide/src/app/panels/terminal.js +++ b/apps/remix-ide/src/app/panels/terminal.js @@ -13,8 +13,6 @@ const AutoCompletePopup = require('../ui/auto-complete-popup') import { CompilerImports } from '@remix-project/core-plugin' // eslint-disable-line -const GistHandler = require('../../lib/gist-handler') - const KONSOLES = [] function register (api) { KONSOLES.push(api) } @@ -32,7 +30,6 @@ class Terminal extends Plugin { constructor (opts, api) { super(profile) this.fileImport = new CompilerImports() - this.gistHandler = new GistHandler() this.event = new EventManager() this.globalRegistry = Registry.getInstance() this.element = document.createElement('div') diff --git a/apps/remix-ide/src/app/ui/landing-page/landing-page.js b/apps/remix-ide/src/app/ui/landing-page/landing-page.js index a100c4ea4e..b05271dc96 100644 --- a/apps/remix-ide/src/app/ui/landing-page/landing-page.js +++ b/apps/remix-ide/src/app/ui/landing-page/landing-page.js @@ -5,8 +5,6 @@ import * as packageJson from '../../../../../../package.json' import { ViewPlugin } from '@remixproject/engine-web' import { RemixUiHomeTab } from '@remix-ui/home-tab' // eslint-disable-line -const GistHandler = require('../../../lib/gist-handler') - const profile = { name: 'home', displayName: 'Home', @@ -26,7 +24,6 @@ export class LandingPage extends ViewPlugin { this.contentImport = contentImport this.appManager = appManager this.verticalIcons = verticalIcons - this.gistHandler = new GistHandler() this.el = document.createElement('div') this.el.setAttribute('id', 'landingPageHomeContainer') this.el.setAttribute('class', 'remixui_homeContainer justify-content-between bg-light d-flex') diff --git a/apps/remix-ide/src/lib/cmdInterpreterAPI.js b/apps/remix-ide/src/lib/cmdInterpreterAPI.js index 530846873d..97d27f3a17 100644 --- a/apps/remix-ide/src/lib/cmdInterpreterAPI.js +++ b/apps/remix-ide/src/lib/cmdInterpreterAPI.js @@ -6,7 +6,6 @@ var async = require('async') var EventManager = require('../lib/events') var toolTip = require('../app/ui/tooltip') -var GistHandler = require('./gist-handler') class CmdInterpreterAPI { constructor (terminal, blockchain) { @@ -17,7 +16,6 @@ class CmdInterpreterAPI { self._components.registry = Registry.getInstance() self._components.terminal = terminal self._components.fileImport = new CompilerImports() - self._components.gistHandler = new GistHandler() self._deps = { fileManager: self._components.registry.get('filemanager').api, editor: self._components.registry.get('editor').api, @@ -35,8 +33,7 @@ class CmdInterpreterAPI { log () { arguments[0] != null ? this._components.terminal.commands.html(arguments[0]) : this._components.terminal.commands.html(arguments[1]) } loadgist (id, cb) { - const self = this - self._components.gistHandler.loadFromGist({ gist: id }, this._deps.fileManager) + this._components.terminal.call('loadFromGistHandler', 'load', id) if (cb) cb() } diff --git a/apps/remix-ide/src/lib/gist-handler.js b/apps/remix-ide/src/lib/gist-handler.js deleted file mode 100644 index da881e1103..0000000000 --- a/apps/remix-ide/src/lib/gist-handler.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict' -var modalDialogCustom = require('../app/ui/modal-dialog-custom') -var request = require('request') - -// Allowing window to be overriden for testing -function GistHandler (_window) { - if (_window !== undefined) { - modalDialogCustom = _window - } - - this.handleLoad = function (params, cb) { - if (!cb) cb = () => {} - var loadingFromGist = false - var gistId - if (params.gist === '') { - loadingFromGist = true - modalDialogCustom.prompt('Load a Gist', 'Enter the ID of the Gist or URL you would like to load.', null, (target) => { - if (target !== '') { - gistId = getGistId(target) - if (gistId) { - cb(gistId) - } else { - modalDialogCustom.alert('Gist load error', 'Error while loading gist. Please provide a valid Gist ID or URL.') - } - } - }) - return loadingFromGist - } else { - gistId = params.gist - loadingFromGist = !!gistId - } - if (loadingFromGist) { - cb(gistId) - } - return loadingFromGist - } - - function getGistId (str) { - var idr = /[0-9A-Fa-f]{8,}/ - var match = idr.exec(str) - return match ? match[0] : null - } - - this.loadFromGist = (params, fileManager) => { - const self = this - return self.handleLoad(params, function (gistId) { - request.get({ - url: `https://api.github.com/gists/${gistId}`, - json: true - }, async (error, response, data = {}) => { - if (error || !data.files) { - modalDialogCustom.alert('Gist load error', error || data.message) - return - } - const obj = {} - Object.keys(data.files).forEach((element) => { - const path = element.replace(/\.\.\./g, '/') - - obj['/' + 'gist-' + gistId + '/' + path] = data.files[element] - }) - fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => { - if (!errorLoadingFile) { - const provider = fileManager.getProvider('workspace') - provider.lastLoadedGistId = gistId - } else { - modalDialogCustom.alert('Gist load error', errorLoadingFile.message || errorLoadingFile) - } - }) - }) - }) - } -} - -module.exports = GistHandler diff --git a/apps/remix-ide/test/compiler-test.js b/apps/remix-ide/test/compiler-test.js deleted file mode 100644 index 5af70fd14f..0000000000 --- a/apps/remix-ide/test/compiler-test.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -var test = require('tape') - -var Compiler = require('@remix-project/remix-solidity').Compiler - -test('compiler.compile smoke', function (t) { - t.plan(1) - - var noop = function () {} - var fakeImport = function (url, cb) { cb('Not implemented') } - var compiler = new Compiler(fakeImport) - compiler.compileJSON = noop - compiler.compile({ 'test': '' }, 'test') - t.ok(compiler) -}) diff --git a/apps/remix-ide/test/gist-handler-test.js b/apps/remix-ide/test/gist-handler-test.js deleted file mode 100644 index 07eaad830c..0000000000 --- a/apps/remix-ide/test/gist-handler-test.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict' -var modalDialogCustom -if (typeof window !== 'undefined') { - modalDialogCustom = require('../app/ui/modal-dialog-custom') -} -// ^ this class can be load in a non browser context when running node unit testing. -// should not load UI in that case - -// Allowing window to be overriden for testing -function GistHandler (_window) { - if (_window !== undefined) { - modalDialogCustom = _window - } - - this.handleLoad = function (params, cb) { - if (!cb) cb = () => {} - var loadingFromGist = false - var gistId - if (params['gist'] === '') { - loadingFromGist = true - modalDialogCustom.prompt( - 'Load a Gist', - 'Enter the URL or ID of the Gist you would like to load.', - null, - target => { - if (target !== '') { - gistId = getGistId(target) - if (gistId) { - cb(gistId) - } - } - } - ) - return loadingFromGist - } else { - gistId = params['gist'] - loadingFromGist = !!gistId - } - if (loadingFromGist) { - cb(gistId) - } - return loadingFromGist - } - - function getGistId (str) { - var idr = /[0-9A-Fa-f]{8,}/ - var match = idr.exec(str) - return match ? match[0] : null - } -} - -module.exports = GistHandler diff --git a/apps/remix-ide/test/index.js b/apps/remix-ide/test/index.js deleted file mode 100644 index 84d8a5c68f..0000000000 --- a/apps/remix-ide/test/index.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict' - -require('./compiler-test') -require('./gist-handler-test') -require('./query-params-test') diff --git a/apps/remix-ide/test/query-params-test.js b/apps/remix-ide/test/query-params-test.js deleted file mode 100644 index c9062f6da0..0000000000 --- a/apps/remix-ide/test/query-params-test.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' - -var test = require('tape') - -var QueryParams = require('../src/lib/query-params') - -test('queryParams.get', function (t) { - t.plan(2) - - var fakeWindow = {location: {hash: '#wat=sup&foo=bar', search: ''}} - var params = new QueryParams(fakeWindow).get() - t.equal(params.wat, 'sup') - t.equal(params.foo, 'bar') -}) - -test('queryParams.update', function (t) { - t.plan(1) - - var fakeWindow = {location: {hash: '#wat=sup', search: ''}} - var qp = new QueryParams(fakeWindow) - qp.update({foo: 'bar'}) - t.equal(fakeWindow.location.hash, '#wat=sup&foo=bar') -}) diff --git a/libs/remix-core-plugin/src/index.ts b/libs/remix-core-plugin/src/index.ts index fe8a5c661e..b91e6b76a6 100644 --- a/libs/remix-core-plugin/src/index.ts +++ b/libs/remix-core-plugin/src/index.ts @@ -4,3 +4,4 @@ export { FetchAndCompile } from './lib/compiler-fetch-and-compile' export { CompilerImports } from './lib/compiler-content-imports' export { CompilerArtefacts } from './lib/compiler-artefacts' export { EditorContextListener } from './lib/editor-context-listener' +export { GistHandler } from './lib/gist-handler' diff --git a/libs/remix-core-plugin/src/lib/gist-handler.ts b/libs/remix-core-plugin/src/lib/gist-handler.ts new file mode 100644 index 0000000000..7a6c305d32 --- /dev/null +++ b/libs/remix-core-plugin/src/lib/gist-handler.ts @@ -0,0 +1,85 @@ +'use strict' +import { Plugin } from '@remixproject/engine' + +interface StringByString { + [key: string]: string; +} + +const profile = { + name: 'gistHandler', + methods: ['load'], + events: [], + version: '0.0.1' +} + +export class GistHandler extends Plugin { + + constructor () { + super(profile) + } + + async handleLoad (gistId: String | null, cb: Function) { + if (!cb) cb = () => {} + + var loadingFromGist = false + if (!gistId) { + loadingFromGist = true + let value: string = await this.call('modal', 'prompt-value', 'Load a Gist', 'Enter the ID of the Gist or URL you would like to load.', null) + if (value !== '') { + gistId = getGistId(value) + if (gistId) { + cb(gistId) + } else { + await this.call('modal', 'alert', 'Gist load error', 'Error while loading gist. Please provide a valid Gist ID or URL.') + } + } else { + await this.call('modal', 'alert', 'Gist load error', 'Error while loading gist. Id cannot be empty.') + } + return loadingFromGist + } else { + loadingFromGist = !!gistId + } + if (loadingFromGist) { + cb(gistId) + } + return loadingFromGist + } + + load (gistId: String | null) { + const self = this + return self.handleLoad(gistId, async (gistId: String | null) => { + let data: any + try { + data = (await fetch(`https://api.github.com/gists/${gistId}`)).json() as any + if (!data.files) { + this.call('model', 'alert', 'Gist load error', data.message) + return + } + } catch (e: any) { + this.call('model', 'alert', 'Gist load error', e.message) + return + } + + const obj: StringByString = {} + Object.keys(data.files).forEach((element) => { + const path = element.replace(/\.\.\./g, '/') + obj['/' + 'gist-' + gistId + '/' + path] = data.files[element] + }) + this.call('fileManager', 'setBatchFiles', obj, 'workspace', true, async (errorSavingFiles: any) => { + if (!errorSavingFiles) { + const provider = await this.call('fileManager', 'getProviderByName', 'workspace') + } else { + this.call('model', 'alert', 'Gist load error', errorSavingFiles.message || errorSavingFiles) + } + }) + + + }) + } +} + +const getGistId = (str) => { + var idr = /[0-9A-Fa-f]{8,}/ + var match = idr.exec(str) + return match ? match[0] : null +} \ No newline at end of file diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx index 13dec9d47d..4345514a17 100644 --- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx +++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx @@ -136,7 +136,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => { plugin.appManager.activatePlugin('remixd') } const importFromGist = () => { - plugin.gistHandler.loadFromGist({ gist: '' }, fileManager) + plugin.call('gistHandler', 'load', '') plugin.verticalIcons.select('filePanel') } const switchToPreviousVersion = () => { diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index fddabeba59..957f7ee004 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -120,8 +120,7 @@ export const loadWorkspacePreset = async (template: 'gist-template' | 'code-temp if (!errorLoadingFile) { const provider = plugin.fileManager.getProvider('workspace') - provider.lastLoadedGistId = gistId - } else { + } else { dispatch(displayNotification('', errorLoadingFile.message || errorLoadingFile, 'OK', null, () => {}, null)) } }) diff --git a/workspace.json b/workspace.json index 1718e70f69..d4a9f6fcd4 100644 --- a/workspace.json +++ b/workspace.json @@ -82,16 +82,6 @@ "apps/remix-ide/src/assets/js/**/*.js" ] } - }, - "test": { - "builder": "@nrwl/workspace:run-commands", - "options": { - "commands": [ - { - "command": "csslint && node apps/remix-ide/test/index.js" - } - ] - } } } },