Merge pull request #1879 from ethereum/gist_handler_in_react

Gist handler in react
pull/5370/head
bunsenstraat 3 years ago committed by GitHub
commit b2b67556b8
  1. 15
      apps/remix-ide-e2e/src/commands/modalFooterCancelClick.ts
  2. 11
      apps/remix-ide-e2e/src/commands/modalFooterOKClick.ts
  3. 38
      apps/remix-ide-e2e/src/tests/gist.test.ts
  4. 4
      apps/remix-ide-e2e/src/types/index.d.ts
  5. 11
      apps/remix-ide/src/app.js
  6. 2
      apps/remix-ide/src/app/files/fileManager.ts
  7. 3
      apps/remix-ide/src/app/panels/terminal.js
  8. 53
      apps/remix-ide/src/app/plugins/test.ts
  9. 3
      apps/remix-ide/src/app/ui/landing-page/landing-page.js
  10. 5
      apps/remix-ide/src/lib/cmdInterpreterAPI.js
  11. 74
      apps/remix-ide/src/lib/gist-handler.js
  12. 2
      apps/remix-ide/src/remixAppManager.js
  13. 16
      apps/remix-ide/test/compiler-test.js
  14. 52
      apps/remix-ide/test/gist-handler-test.js
  15. 5
      apps/remix-ide/test/index.js
  16. 23
      apps/remix-ide/test/query-params-test.js
  17. 1
      libs/remix-core-plugin/src/index.ts
  18. 138
      libs/remix-core-plugin/src/lib/gist-handler.ts
  19. 1
      libs/remix-ui/app/src/index.ts
  20. 2
      libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
  21. 52
      libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx
  22. 4
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  23. 6
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  24. 10
      workspace.json

@ -1,14 +1,15 @@
import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events'
class ModalFooterOKClick extends EventEmitter {
command (this: NightwatchBrowser): NightwatchBrowser {
this.api.waitForElementVisible('#modal-footer-cancel').perform((client, done) => {
this.api.execute(function () {
const elem = document.querySelector('#modal-footer-cancel') as HTMLElement
class ModalFooterCancelClick extends EventEmitter {
command (this: NightwatchBrowser, id?: string): NightwatchBrowser {
const clientId = id ? `*[data-id="${id}-modal-footer-cancel-react"]` : '#modal-footer-cancel'
this.api.waitForElementVisible(clientId).perform((client, done) => {
this.api.execute(function (clientId) {
const elem = document.querySelector(clientId) as HTMLElement
elem.click()
}, [], () => {
}, [clientId], () => {
done()
this.emit('complete')
})
@ -17,4 +18,4 @@ class ModalFooterOKClick extends EventEmitter {
}
}
module.exports = ModalFooterOKClick
module.exports = ModalFooterCancelClick

@ -2,13 +2,14 @@ import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events'
class ModalFooterOKClick extends EventEmitter {
command (this: NightwatchBrowser): NightwatchBrowser {
this.api.waitForElementVisible('#modal-footer-ok').perform((client, done) => {
this.api.execute(function () {
const elem = document.querySelector('#modal-footer-ok') as HTMLElement
command (this: NightwatchBrowser, id?: string): NightwatchBrowser {
const clientId = id ? `*[data-id="${id}-modal-footer-ok-react"]` : '#modal-footer-ok'
this.api.waitForElementVisible(clientId).perform((client, done) => {
this.api.execute(function (clientId) {
const elem = document.querySelector(clientId) as HTMLElement
elem.click()
}, [], () => {
}, [clientId], () => {
done()
this.emit('complete')
})

@ -76,29 +76,34 @@ module.exports = {
.waitForElementVisible('button[data-id="landingPageImportFromGistButton"]')
.pause(1000)
.scrollAndClick('button[data-id="landingPageImportFromGistButton"]')
.waitForElementVisible('*[data-id="modalDialogModalTitle"]')
.assert.containsText('*[data-id="modalDialogModalTitle"]', 'Load a Gist')
.waitForElementVisible('*[data-id="modalDialogModalBody"]')
.assert.containsText('*[data-id="modalDialogModalBody"]', 'Enter the ID of the Gist or URL you would like to load.')
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.modalFooterCancelClick()
.waitForElementVisible('*[data-id="gisthandlerModalDialogModalTitle-react"]')
.assert.containsText('*[data-id="gisthandlerModalDialogModalTitle-react"]', 'Load a Gist')
.waitForElementVisible('*[data-id="gisthandlerModalDialogModalBody-react"]')
.assert.containsText('*[data-id="gisthandlerModalDialogModalBody-react"]', 'Enter the ID of the Gist or URL you would like to load.')
.waitForElementVisible('*[data-id="modalDialogCustomPromp"]')
.modalFooterCancelClick('gisthandler')
},
'Display Error Message For Invalid Gist ID': function (browser: NightwatchBrowser) {
browser
.pause(1000)
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('filePanel')
.scrollAndClick('*[data-id="landingPageImportFromGistButton"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', testData.invalidGistId)
.modalFooterOKClick()
.waitForElementVisible('*[data-id="modalDialogModalBody"]')
.assert.containsText('*[data-id="modalDialogModalBody"]', 'Not Found')
.modalFooterOKClick()
.waitForElementVisible('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]')
.execute(() => {
(document.querySelector('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]') as any).focus()
}, [], () => {})
.setValue('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]', testData.invalidGistId)
.modalFooterOKClick('gisthandler')
.waitForElementVisible('*[data-id="gisthandlerModalDialogModalBody-react"]')
.assert.containsText('*[data-id="gisthandlerModalDialogModalBody-react"]', 'Not Found')
.modalFooterOKClick('gisthandler')
},
'Display Error Message For Missing Gist Token When Publishing': function (browser: NightwatchBrowser) {
browser
.pause(1000)
.waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000)
.clickLaunchIcon('settings')
.waitForElementVisible('[data-id="settingsTabRemoveGistToken"]')
@ -129,9 +134,12 @@ module.exports = {
.click('[data-id="settingsTabSaveGistToken"]')
.clickLaunchIcon('filePanel')
.scrollAndClick('*[data-id="landingPageImportFromGistButton"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptText"]')
.setValue('*[data-id="modalDialogCustomPromptText"]', testData.validGistId)
.modalFooterOKClick()
.waitForElementVisible('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]')
.execute(() => {
(document.querySelector('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]') as any).focus()
}, [], () => {})
.setValue('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]', testData.validGistId)
.modalFooterOKClick('gisthandler')
.openFile(`gist-${testData.validGistId}/README.txt`)
.waitForElementVisible(`div[title='default_workspace/gist-${testData.validGistId}/README.txt']`)
.assert.containsText(`div[title='default_workspace/gist-${testData.validGistId}/README.txt'] > span`, 'README.txt')

@ -18,7 +18,7 @@ declare module 'nightwatch' {
goToVMTraceStep(step: number, incr?: number): NightwatchBrowser,
checkVariableDebug(id: string, debugValue: NightwatchCheckVariableDebugValue): NightwatchBrowser,
addAtAddressInstance(address: string, isValidFormat: boolean, isValidChecksum: boolean): NightwatchBrowser,
modalFooterOKClick(): NightwatchBrowser,
modalFooterOKClick(id?: string): NightwatchBrowser,
clickInstance(index: number): NightwatchBrowser,
journalLastChildIncludes(val: string): NightwatchBrowser,
executeScript(script: string): NightwatchBrowser,
@ -32,7 +32,7 @@ declare module 'nightwatch' {
scrollToLine(line: number): NightwatchBrowser,
waitForElementContainsText(id: string, value: string, timeout?: number): NightwatchBrowser,
getModalBody(callback: (value: string, cb: VoidFunction) => void): NightwatchBrowser,
modalFooterCancelClick(): NightwatchBrowser,
modalFooterCancelClick(id?: string): NightwatchBrowser,
selectContract(contractName: string): NightwatchBrowser,
createContract(inputParams: string): NightwatchBrowser,
getAddressAtPosition(index: number, cb: (pos: string) => void): NightwatchBrowser,

@ -12,11 +12,10 @@ import { VerticalIcons } from './app/components/vertical-icons'
import { LandingPage } from './app/ui/landing-page/landing-page'
import { MainPanel } from './app/components/main-panel'
import { FramingService } from './framingService'
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, GistHandler } from '@remix-project/core-plugin'
import migrateFileSystem from './migrateFileSystem'
import Registry from './app/state/registry'
@ -106,6 +105,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 +167,7 @@ class AppComponent {
self.engine.register([
self.modal,
self.gistHandler,
configPlugin,
blockchain,
contentImport,
@ -243,9 +245,7 @@ class AppComponent {
contentImport
)
const testplugin = new ModalPluginTester()
self.engine.register([
testplugin,
compileTab,
run,
debug,
@ -280,10 +280,9 @@ 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'])
self.appManager.on('filePanel', 'workspaceInitializationCompleted', async () => {
await self.appManager.registerContextMenuItems()

@ -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 = {

@ -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')

@ -1,53 +0,0 @@
import { Plugin } from '@remixproject/engine'
import { Profile } from '@remixproject/plugin-utils'
import { AlertModal } from 'libs/remix-ui/app/src/lib/remix-app/interface'
import { ModalTypes } from 'libs/remix-ui/app/src/lib/remix-app/types'
import { AppModal } from '../../../../../libs/remix-ui/app/src'
const profile:Profile = {
name: 'testerplugin',
displayName: 'testerplugin',
description: 'testerplugin',
methods: []
}
export class ModalPluginTester extends Plugin {
constructor () {
super(profile)
}
handleMessage (message: any): void {
console.log(message)
}
onActivation (): void {
// just a modal
let mod:AppModal = {
id: 'modal1',
title: 'test',
message: 'test',
okFn: this.handleMessage,
okLabel: 'yes',
cancelFn: null,
cancelLabel: 'no'
}
// this.call('modal', 'modal', mod)
// modal with callback
mod = { ...mod, message: 'gist url', modalType: ModalTypes.prompt, defaultValue: 'prompting' }
// this.call('modal', 'modal', mod)
// modal with password
mod = { ...mod, message: 'enter password to give me eth', modalType: ModalTypes.password, defaultValue: 'pass' }
// this.call('modal', 'modal', mod)
const al:AlertModal = {
id: 'myalert',
message: 'alert message'
}
// this.call('modal', 'alert', al)
// set toaster
// this.call('modal', 'toast', 'toast message')
}
}

@ -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')

@ -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('gistHandler', 'load', id)
if (cb) cb()
}

@ -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

@ -9,7 +9,7 @@ const _paq = window._paq = window._paq || []
const requiredModules = [ // services + layout views + system views
'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme',
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic']
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler']
const dependentModules = ['git', 'hardhat', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd)

@ -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)
})

@ -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

@ -1,5 +0,0 @@
'use strict'
require('./compiler-test')
require('./gist-handler-test')
require('./query-params-test')

@ -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')
})

@ -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'

@ -0,0 +1,138 @@
/* global fetch */
'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
try {
value = await (() => {
return new Promise((resolve, reject) => {
const modalContent = {
id: 'gisthandler',
title: 'Load a Gist',
message: 'Enter the ID of the Gist or URL you would like to load.',
modalType: 'prompt',
okLabel: 'OK',
cancelLabel: 'Cancel',
okFn: (value) => {
setTimeout(() => resolve(value), 0)
},
cancelFn: () => {
setTimeout(() => reject(new Error('Canceled')), 0)
},
hideFn: () => {
setTimeout(() => reject(new Error('Hide')), 0)
}
}
this.call('modal', 'modal', modalContent)
})
})()
} catch (e) {
// the modal has been canceled
return
}
if (value !== '') {
gistId = getGistId(value)
if (gistId) {
cb(gistId)
} else {
const modalContent = {
id: 'gisthandler',
title: 'Gist load error',
message: 'Error while loading gist. Please provide a valid Gist ID or URL.'
}
this.call('modal', 'alert', modalContent)
}
} else {
const modalContent = {
id: 'gisthandlerEmpty',
title: 'Gist load error',
message: 'Error while loading gist. Id cannot be empty.'
}
this.call('modal', 'alert', modalContent)
}
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 (await fetch(`https://api.github.com/gists/${gistId}`)).json() as any
if (!data.files) {
const modalContent = {
id: 'gisthandler',
title: 'Gist load error',
message: data.message,
modalType: 'alert',
okLabel: 'OK'
}
await this.call('modal', 'modal', modalContent)
return
}
} catch (e: any) {
const modalContent = {
id: 'gisthandler',
title: 'Gist load error',
message: e.message
}
await this.call('modal', 'alert', modalContent)
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 modalContent = {
id: 'gisthandler',
title: 'Gist load error',
message: errorSavingFiles.message || errorSavingFiles
}
this.call('modal', 'alert', modalContent)
}
})
})
}
}
const getGistId = (str) => {
var idr = /[0-9A-Fa-f]{8,}/
var match = idr.exec(str)
return match ? match[0] : null
}

@ -3,3 +3,4 @@ export { dispatchModalContext } from './lib/remix-app/context/context'
export { ModalProvider } from './lib/remix-app/context/provider'
export { AppModal } from './lib/remix-app/interface/index'
export { AlertModal } from './lib/remix-app/interface/index'
export * from './lib/remix-app/types/index'

@ -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 = () => {

@ -86,40 +86,38 @@ export const ModalDialog = (props: ModalDialogProps) => {
{props.title && props.title}
</h6>
{!props.showCancelIcon &&
<span className="modal-close" onClick={() => handleHide()}>
<i title="Close" className="fas fa-times" aria-hidden="true"></i>
</span>
<span className="modal-close" onClick={() => handleHide()}>
<i title="Close" className="fas fa-times" aria-hidden="true"></i>
</span>
}
</div>
<div className="modal-body text-break remixModalBody" data-id={`${props.id}ModalDialogModalBody-react`}>
{ props.children ? props.children : props.message }
{props.children ? props.children : props.message}
</div>
<div className="modal-footer" data-id={`${props.id}ModalDialogModalFooter-react`}>
{/* todo add autofocus ^^ */}
{ props.okLabel &&
<span
data-id={`${props.id}-modal-footer-ok-react`}
className={'modal-ok btn btn-sm ' + (state.toggleBtn ? 'btn-dark' : 'btn-light')}
onClick={() => {
if (props.okFn) props.okFn()
handleHide()
}}
>
{ props.okLabel ? props.okLabel : 'OK' }
</span>
{ props.okLabel && <span
data-id={`${props.id}-modal-footer-ok-react`}
className={'modal-ok btn btn-sm ' + (state.toggleBtn ? 'btn-dark' : 'btn-light')}
onClick={() => {
if (props.okFn) props.okFn()
handleHide()
}}
>
{props.okLabel ? props.okLabel : 'OK'}
</span>
}
{ props.cancelLabel &&
<span
data-id={`${props.id}-modal-footer-cancel-react`}
className={'modal-cancel btn btn-sm ' + (state.toggleBtn ? 'btn-light' : 'btn-dark')}
data-dismiss="modal"
onClick={() => {
if (props.cancelFn) props.cancelFn()
handleHide()
}}
>
{ props.cancelLabel ? props.cancelLabel : 'Cancel' }
</span>
{ props.cancelLabel && <span
data-id={`${props.id}-modal-footer-cancel-react`}
className={'modal-cancel btn btn-sm ' + (state.toggleBtn ? 'btn-light' : 'btn-dark')}
data-dismiss="modal"
onClick={() => {
if (props.cancelFn) props.cancelFn()
handleHide()
}}
>
{props.cancelLabel ? props.cancelLabel : 'Cancel'}
</span>
}
</div>
</div>

@ -25,7 +25,7 @@ export interface ClipboardEvent<T = Element> extends SyntheticEvent<T, any> {
}
export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const { call, _deps, on, config, event, gistHandler, version } = props.plugin
const { call, _deps, on, config, event, version } = props.plugin
const [_cmdIndex, setCmdIndex] = useState(-1)
const [_cmdTemp, setCmdTemp] = useState('')
@ -178,7 +178,7 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
}
function loadgist (id, cb) {
gistHandler.loadFromGist({ gist: id }, _deps.fileManager)
props.plugin.call('gistHandler', 'load', id)
if (cb) cb()
}

@ -117,11 +117,7 @@ export const loadWorkspacePreset = async (template: 'gist-template' | 'code-temp
obj['/' + 'gist-' + gistId + '/' + path] = data.files[element]
})
plugin.fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => {
if (!errorLoadingFile) {
const provider = plugin.fileManager.getProvider('workspace')
provider.lastLoadedGistId = gistId
} else {
if (errorLoadingFile) {
dispatch(displayNotification('', errorLoadingFile.message || errorLoadingFile, 'OK', null, () => {}, null))
}
})

@ -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"
}
]
}
}
}
},

Loading…
Cancel
Save