diff --git a/apps/remix-ide-e2e/src/tests/gist.test.ts b/apps/remix-ide-e2e/src/tests/gist.test.ts index 97d21c8e37..ff0c60f23a 100644 --- a/apps/remix-ide-e2e/src/tests/gist.test.ts +++ b/apps/remix-ide-e2e/src/tests/gist.test.ts @@ -37,9 +37,9 @@ module.exports = { .addFile('File.sol', { content: '' }) .executeScriptInTerminal(`remix.loadgist('${gistid}')`) // .perform((done) => { if (runtimeBrowser === 'chrome') { browser.openFile('gists') } done() }) - .waitForElementVisible(`[data-id="treeViewLitreeViewItemgist-${gistid}"]`) + .waitForElementVisible(`[data-id="treeViewLitreeViewItemREADME.txt"]`) - .openFile(`gist-${gistid}/README.txt`) + .openFile(`README.txt`) // Remix publish to gist /* .click('*[data-id="fileExplorerNewFilepublishToGist"]') .pause(2000) @@ -110,8 +110,8 @@ module.exports = { .waitForElementVisible('[data-id="settingsTabRemoveGistToken"]') .click('[data-id="settingsTabRemoveGistToken"]') .clickLaunchIcon('filePanel') - .waitForElementVisible('*[data-id="fileExplorerNewFilepublishToGist"]') - .click('*[data-id="fileExplorerNewFilepublishToGist"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacepublishToGist"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) .pause(10000) @@ -142,9 +142,9 @@ module.exports = { .setValue('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]', testData.validGistId) .modalFooterOKClick('gisthandler') .pause(10000) - .openFile(`gist-${testData.validGistId}/README.txt`) - .waitForElementVisible(`div[data-path='default_workspace/gist-${testData.validGistId}/README.txt']`) - .assert.containsText(`div[data-path='default_workspace/gist-${testData.validGistId}/README.txt'] > span`, 'README.txt') + .openFile(`README.txt`) + .waitForElementVisible(`div[data-path='gist ${testData.validGistId}/README.txt']`) + .assert.containsText(`div[data-path='gist ${testData.validGistId}/README.txt'] > span`, 'README.txt') }, 'Load Gist from URL and verify truncated files are loaded #group3': function (browser: NightwatchBrowser) { @@ -152,14 +152,15 @@ module.exports = { browser .url('http://127.0.0.1:8080/#gist=' + gistId) // loading the gist .refreshPage() + .currentWorkspaceIs('gist ' + gistId) .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 15000) - .waitForElementVisible(`#fileExplorerView li[data-path='gist-${gistId}/README.txt']`, 30000) - .openFile(`gist-${gistId}/scripts/deploy_with_ethers.ts`) + .waitForElementVisible(`#fileExplorerView li[data-path='contracts']`, 30000) + .openFile(`contracts/2_Owner.sol`) .getEditorValue((content) => { - browser.assert.ok(content !== '') + browser.assert.ok(content.indexOf('contract Owner {') !== -1) }) - .rightClickCustom(`li[data-path='gist-${gistId}'] div`) // saving the gist - .click('[data-id="contextMenuItempublishFolderToGist"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacepublishToGist"]') .modalFooterOKClick('fileSystem') .waitForElementVisible('*[data-shared="tooltipPopup"]', 5000) .assert.containsText('*[data-shared="tooltipPopup"]', 'Saving gist (' + gistId + ') ...') diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index 91a1df9ad4..69bbc140ca 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -128,6 +128,7 @@ const checkForAcceptAndRemember = async function (browser: NightwatchBrowser) { */ const clickAndCheckLog = async (browser: NightwatchBrowser, buttonText: string, methodResult: any, eventResult: any, payload: any, waitResult: boolean = true) => { // eslint-disable-line + console.log('clickAndCheckLog', buttonText, methodResult, eventResult, payload, waitResult) if (payload) { await setPayload(browser, payload) } else { @@ -295,7 +296,7 @@ module.exports = { }, null, '/') }, 'Should get all workspaces #group2': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"default_workspace",isGitRepo:false,hasGitSubmodules:false}, {name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false}, {name:"testspace",isGitRepo:false,hasGitSubmodules:false}], null, null) + await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"default_workspace",isGitRepo:false,hasGitSubmodules:false,isGist:null}, {name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false,isGist:null}, {name:"testspace",isGitRepo:false,hasGitSubmodules:false,isGist:null}], null, null) }, 'Should have set workspace event #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, { event: 'setWorkspace', args: [{ name: 'newspace', isLocalhost: false }] }, 'newspace') @@ -309,11 +310,11 @@ module.exports = { 'Should rename workspace #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:renameWorkspace', null, null, ['default_workspace', 'renamed']) - await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false},{name:"testspace",isGitRepo:false,hasGitSubmodules:false},{name:"newspace",isGitRepo:false,hasGitSubmodules:false},{name:"renamed",isGitRepo:false,hasGitSubmodules:false}], null, null) + await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false,isGist:null},{name:"testspace",isGitRepo:false,hasGitSubmodules:false,isGist:null},{name:"newspace",isGitRepo:false,hasGitSubmodules:false,isGist:null},{name:"renamed",isGitRepo:false,hasGitSubmodules:false,isGist:null}], null, null) }, 'Should delete workspace #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:deleteWorkspace', null, null, ['testspace']) - await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false},{name:"newspace",isGitRepo:false,hasGitSubmodules:false},{name:"renamed",isGitRepo:false,hasGitSubmodules:false}], null, null) + await clickAndCheckLog(browser, 'filePanel:getWorkspaces', [{name:"emptyworkspace",isGitRepo:false,hasGitSubmodules:false,isGist:null},{name:"newspace",isGitRepo:false,hasGitSubmodules:false,isGist:null},{name:"renamed",isGitRepo:false,hasGitSubmodules:false,isGist:null}], null, null) }, // DGIT 'Should have changes on new workspace #group3': async function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 2e4feaf0e2..d8f55573f5 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -46,6 +46,7 @@ const profile = { 'loadTemplate', 'clone', 'isExpanded', + 'isGist' ], events: ['setWorkspace', 'workspaceRenamed', 'workspaceDeleted', 'workspaceCreated'], icon: 'assets/img/fileManager.webp', @@ -131,6 +132,20 @@ module.exports = class Filepanel extends ViewPlugin { }) } + /** + * return the gist id if the current workspace is a gist workspace, otherwise returns null + * @argument {String} workspaceName - the name of the workspace to check against. default to the current workspace. + * @returns {string} gist id or null + */ + isGist (workspaceName) { + workspaceName = workspaceName || this.currentWorkspaceMetadata && this.currentWorkspaceMetadata.name + const isGist = workspaceName.startsWith('gist') + if (isGist) { + return workspaceName.split(' ')[1] + } + return null + } + getCurrentWorkspace() { return this.currentWorkspaceMetadata } diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index 3847cae628..05fef4beab 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -62,10 +62,12 @@ "filePanel.compileForNahmii": "Compile for Nahmii", "filePanel.createNewFile": "Create new file", "filePanel.createNewFolder": "Create new folder", - "filePanel.publishToGist": "Publish all files to GitHub gist", + "filePanel.publishToGist": "Publish to Gist", + "filePanel.workspace.publishToGist": "Publish workspace to GitHub gist", "filePanel.uploadFile": "Upload files", "filePanel.uploadFolder": "Upload folder", - "filePanel.updateGist": "Update the current [gist] explorer", + "filePanel.updateGist": "Update Gist", + "filePanel.workspace.updateGist": "Publish Gist update", "filePanel.viewAllBranches": "View all branches", "filePanel.createBranch": "Create branch", "filePanel.switchBranches": "Switch branches", diff --git a/libs/remix-core-plugin/src/lib/gist-handler.ts b/libs/remix-core-plugin/src/lib/gist-handler.ts index 5a1e04d98e..c3a53a75f1 100644 --- a/libs/remix-core-plugin/src/lib/gist-handler.ts +++ b/libs/remix-core-plugin/src/lib/gist-handler.ts @@ -114,10 +114,20 @@ export class GistHandler extends Plugin { return } + const gistIdWorkspace = 'gist ' + gistId + const workspaces = await this.call('filePanel', 'getWorkspaces') + const found = workspaces.find((workspace) => workspace.name === gistIdWorkspace) + if (found) { + await this.call('notification', 'alert', `workspace "${gistIdWorkspace}" already exist`) + return + } + await this.call('filePanel', 'createWorkspace', 'gist ' + gistId, '', true) + await this.call('filePanel', 'switchToWorkspace', { name: 'gist ' + gistId, isLocalHost: false }) + const obj: StringByString = {} Object.keys(data.files).forEach((element) => { const path = element.replace(/\.\.\./g, '/') - obj['/gist-' + gistId + '/' + path] = data.files[element] + obj['/' + path] = data.files[element] }) this.call('fileManager', 'setBatchFiles', obj, isElectron()? 'electron':'workspace', true, async (errorSavingFiles: any) => { if (errorSavingFiles) { diff --git a/libs/remix-ui/drag-n-drop/src/lib/types/index.ts b/libs/remix-ui/drag-n-drop/src/lib/types/index.ts index 8bd4b0066a..c81cad0b5b 100644 --- a/libs/remix-ui/drag-n-drop/src/lib/types/index.ts +++ b/libs/remix-ui/drag-n-drop/src/lib/types/index.ts @@ -4,7 +4,7 @@ export interface FileType { path: string, name: string, isDirectory: boolean, - type: 'folder' | 'file' | 'gist', + type: 'folder' | 'file', child?: File[] } diff --git a/libs/remix-ui/file-decorators/src/lib/types/index.ts b/libs/remix-ui/file-decorators/src/lib/types/index.ts index bb84b6d26c..e78a1a4136 100644 --- a/libs/remix-ui/file-decorators/src/lib/types/index.ts +++ b/libs/remix-ui/file-decorators/src/lib/types/index.ts @@ -24,6 +24,6 @@ export interface FileType { path: string, name?: string, isDirectory?: boolean, - type?: 'folder' | 'file' | 'gist', + type?: 'folder' | 'file', child?: File[] } \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 67787e1d2c..540abc8397 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -72,9 +72,10 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. dispatch(setWorkspaces(workspaces)) } if (params.gist) { - await createWorkspaceTemplate('code-sample', 'gist-template') - plugin.setWorkspace({ name: 'code-sample', isLocalhost: false }) - dispatch(setCurrentWorkspace({ name: 'code-sample', isGitRepo: false })) + const name = 'gist ' + params.gist + await createWorkspaceTemplate(name, 'gist-template') + plugin.setWorkspace({ name, isLocalhost: false }) + dispatch(setCurrentWorkspace({ name, isGitRepo: false })) await loadWorkspacePreset('gist-template') } else if (params.code || params.url || params.shareCode) { await createWorkspaceTemplate('code-sample', 'code-template') @@ -224,14 +225,19 @@ export type SolidityConfiguration = { runs: string } -export const publishToGist = async (path?: string, type?: string) => { +export const publishToGist = async (path?: string) => { // 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 = path || '/' try { - const name = extractNameFromKey(path) - const id = name && name.startsWith('gist-') ? name.split('-')[1] : null - + let id + if (path) { + // check if the current folder is a gist folder + id = await plugin.call('filePanel', 'isGist', extractNameFromKey(path)) + } else { + // check if the current workspace is a gist workspace + id = await plugin.call('filePanel', 'isGist') + } const packaged = await packageGistFiles(folder) // check for token const config = plugin.registry.get('config').api @@ -314,7 +320,7 @@ export const createNewFile = async (path: string, rootDir: string) => { } } -export const setFocusElement = async (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => { +export const setFocusElement = async (elements: { key: string, type: 'file' | 'folder' }[]) => { dispatch(focusElement(elements)) } @@ -429,7 +435,7 @@ export const emitContextMenuEvent = async (cmd: customAction) => { await plugin.call(cmd.id, cmd.name, cmd) } -export const handleClickFile = async (path: string, type: 'file' | 'folder' | 'gist') => { +export const handleClickFile = async (path: string, type: 'file' | 'folder' ) => { if (type === 'file' && path.endsWith('.md')) { // just opening the preview await plugin.call('doc-viewer' as any, 'viewDocs', [path]) @@ -520,11 +526,6 @@ const packageGistFiles = async (directory) => { 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 } }) diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 31ec69ab99..be45f3f4d7 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -2,7 +2,7 @@ import React from 'react' import { bufferToHex } from '@ethereumjs/util' import { hash } from '@remix-project/remix-lib' import { TEMPLATE_METADATA, TEMPLATE_NAMES } from '../utils/constants' -import { TemplateType } from '../utils/types' +import { TemplateType } from '../types' import IpfsHttpClient from 'ipfs-http-client' import axios, { AxiosResponse } from 'axios' import { @@ -345,9 +345,9 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe } if (data.files[element].type === 'application/json') { - obj['/' + 'gist-' + gistId + '/' + path] = { content: JSON.stringify(value.content, null, '\t') } + obj['/' + path] = { content: JSON.stringify(value.content, null, '\t') } } else - obj['/' + 'gist-' + gistId + '/' + path] = value + obj['/' + path] = value } plugin.fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => { if (errorLoadingFile) { @@ -609,6 +609,7 @@ export const getWorkspaces = async (): Promise<{ name: string; isGitRepo: boolea Object.keys(items) .filter((item) => items[item].isDirectory) .map(async (folder) => { + const name = folder.replace(workspacesPath + '/', '') const isGitRepo: boolean = await plugin.fileProviders.browser.exists('/' + folder + '/.git') const hasGitSubmodules: boolean = await plugin.fileProviders.browser.exists('/' + folder + '/.gitmodules') if (isGitRepo) { @@ -618,17 +619,19 @@ export const getWorkspaces = async (): Promise<{ name: string; isGitRepo: boolea branches = await getGitRepoBranches(folder) currentBranch = await getGitRepoCurrentBranch(folder) return { - name: folder.replace(workspacesPath + '/', ''), + name, isGitRepo, branches, currentBranch, - hasGitSubmodules + hasGitSubmodules, + isGist: null } } else { return { - name: folder.replace(workspacesPath + '/', ''), + name, isGitRepo, - hasGitSubmodules + hasGitSubmodules, + isGist: plugin.isGist(name) // plugin is filePanel } } }) diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx index 73a143acc9..08659f64e8 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer-context-menu.tsx @@ -187,15 +187,15 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => break case 'Push changes to gist': _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', 'pushToChangesoGist']) - pushChangesToGist(path, type) + pushChangesToGist(path) break case 'Publish folder to gist': _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', 'publishFolderToGist']) - publishFolderToGist(path, type) + publishFolderToGist(path) break case 'Publish file to gist': _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', 'publishFileToGist']) - publishFileToGist(path, type) + publishFileToGist(path) break case 'Run': _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', 'runScript']) @@ -227,7 +227,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => break case 'Publish Workspace to Gist': _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', 'publishWorkspace']) - publishFolderToGist(path, type) + publishFolderToGist(path) break default: _paq.push(['trackEvent', 'fileExplorer', 'contextMenu', `${item.id}/${item.name}`]) diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer-menu.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer-menu.tsx index 243f68e1a9..1ae9e7a9ad 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer-menu.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer-menu.tsx @@ -26,13 +26,6 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { placement: 'top', platforms:[appPlatformTypes.web, appPlatformTypes.desktop] }, - { - action: 'publishToGist', - title: 'Publish current workspace to GitHub gist', - icon: 'fab fa-github', - placement: 'top', - platforms:[appPlatformTypes.web] - }, { action: 'uploadFile', title: 'Upload files into current workspace', @@ -46,13 +39,6 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { icon: 'far fa-folder-upload', placement: 'top', platforms:[appPlatformTypes.web] - }, - { - action: 'updateGist', - title: 'Update the current [gist] explorer', - icon: 'fab fa-github', - placement: 'bottom-start', - platforms:[appPlatformTypes.web] } ].filter( (item) => @@ -65,16 +51,6 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { }) const enableDirUpload = {directory: '', webkitdirectory: ''} - useEffect(() => { - const actions = { - updateGist: () => {} - } - - setState((prevState) => { - return {...prevState, actions} - }) - }, []) - return ( (!global.fs.browser.isSuccessfulWorkspace ? null : <> @@ -165,7 +141,7 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { props.createNewFile() } else if (action === 'createNewFolder') { props.createNewFolder() - } else if (action === 'publishToGist') { + } else if (action === 'publishToGist' || action == 'updateGist') { props.publishToGist() } else { state.actions[action]() diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx index 6e2010f80b..c1ffe28bd5 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -143,12 +143,12 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const publishToGist = (path?: string, type?: string) => { + const publishToGist = (path?: string) => { props.modal( intl.formatMessage({ id: 'filePanel.createPublicGist' }), intl.formatMessage({ id: 'filePanel.createPublicGistMsg4' }, { name }), intl.formatMessage({ id: 'filePanel.ok' }), - () => toGist(path, type), + () => toGist(path), intl.formatMessage({ id: 'filePanel.cancel' }), () => { } ) @@ -173,7 +173,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const handleClickFolder = async (path: string, type: 'folder' | 'file' | 'gist') => { + const handleClickFolder = async (path: string, type: 'folder' | 'file' ) => { if (state.ctrlKey) { if (props.focusElement.findIndex((item) => item.key === path) !== -1) { const focusElement = props.focusElement.filter((item) => item.key !== path) diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx index 00ee0db432..8960ad22c6 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx @@ -2,13 +2,16 @@ import { appPlatformTypes } from '@remix-ui/app' import React from 'react' import {Dropdown} from 'react-bootstrap' import {HamburgerMenuItem, HamburgerSubMenuItem} from './workspace-hamburger-item' +import { WorkspaceMetadata } from '../types' export interface HamburgerMenuProps { + selectedWorkspace: WorkspaceMetadata createWorkspace: () => void renameCurrentWorkspace: () => void downloadCurrentWorkspace: () => void deleteCurrentWorkspace: () => void deleteAllWorkspaces: () => void + pushChangesToGist: () => void cloneGitRepository: () => void downloadWorkspaces: () => void restoreBackup: () => void @@ -24,7 +27,7 @@ export interface HamburgerMenuProps { } export function HamburgerMenu(props: HamburgerMenuProps) { - const {showIconsMenu, hideWorkspaceOptions, hideLocalhostOptions, hideFileOperations} = props + const {showIconsMenu, hideWorkspaceOptions, hideLocalhostOptions, hideFileOperations, selectedWorkspace} = props return ( <> + { + props.pushChangesToGist() + props.hideIconsMenu(!showIconsMenu) + }} + platforms={[appPlatformTypes.web]} + > + Promise, dispatchUploadFolder: (target?: SyntheticEvent, targetFolder?: string) => Promise, dispatchCreateNewFile: (path: string, rootDir: string) => Promise, - dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise, + dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' }[]) => Promise, dispatchCreateNewFolder: (path: string, rootDir: string) => Promise, dispatchDeletePath: (path: string[]) => Promise, dispatchRenamePath: (oldPath: string, newPath: string) => Promise, @@ -31,7 +31,7 @@ export const FileSystemContext = createContext<{ dispatchCopyFolder: (src: string, dest: string) => Promise, dispatchRunScript: (path: string) => Promise, dispatchEmitContextMenuEvent: (cmd: customAction) => Promise, - dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise + dispatchHandleClickFile: (path: string, type: 'file' | 'folder' ) => Promise dispatchHandleExpandPath: (paths: string[]) => Promise, dispatchHandleDownloadFiles: () => Promise, dispatchHandleDownloadWorkspace: () => Promise, diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index c57585ce8a..e4bbd25cec 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -117,8 +117,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await deleteAllWorkspaces() } - const dispatchPublishToGist = async (path?: string, type?: string) => { - await publishToGist(path, type) + const dispatchPublishToGist = async (path?: string) => { + await publishToGist(path) } const dispatchUploadFile = async (target?: SyntheticEvent, targetFolder?: string) => { @@ -133,7 +133,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await createNewFile(path, rootDir) } - const dispatchSetFocusElement = async (elements: {key: string; type: 'file' | 'folder' | 'gist'}[]) => { + const dispatchSetFocusElement = async (elements: {key: string; type: 'file' | 'folder' }[]) => { await setFocusElement(elements) } @@ -173,7 +173,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await emitContextMenuEvent(cmd) } - const dispatchHandleClickFile = async (path: string, type: 'file' | 'folder' | 'gist') => { + const dispatchHandleClickFile = async (path: string, type: 'file' | 'folder' ) => { await handleClickFile(path, type) } diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index 2d6b15a26c..d2f923ceb8 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -17,6 +17,7 @@ export interface BrowserState { name: string }[] currentBranch?: string + isGist: string }[] files: {[x: string]: Record} flatTree: FileType[] @@ -150,7 +151,6 @@ export const browserReducer = (state = browserInitialState, action: Actions) => case 'SET_WORKSPACES': { const payload = action.payload - return { ...state, browser: { @@ -986,8 +986,7 @@ const removeInputField = ( isDirectory: true, path, name: extractNameFromKey(path), - type: - extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder', + type: 'folder', child: prevFiles ? prevFiles.child : {} }, Object @@ -1117,8 +1116,7 @@ const normalize = ( path, name: extractNameFromKey(path), isDirectory: filesList[key].isDirectory, - type: - extractNameFromKey(path).indexOf('gist-') === 0 ? 'gist' : 'folder' + type: 'folder' } } else { files[extractNameFromKey(key)] = { diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index e71d94ffd9..68cd0b7608 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -2,13 +2,14 @@ import React, {useState, useEffect, useRef, useContext, ChangeEvent} from 'react import {FormattedMessage, useIntl} from 'react-intl' import {Dropdown} from 'react-bootstrap' import {CustomIconsToggle, CustomMenu, CustomToggle, CustomTooltip, extractNameFromKey, extractParentFromKey} from '@remix-ui/helper' +import {CopyToClipboard} from '@remix-ui/clipboard' import {FileExplorer} from './components/file-explorer' // eslint-disable-line import {FileSystemContext} from './contexts' import './css/remix-ui-workspace.css' import {ROOT_PATH, TEMPLATE_NAMES} from './utils/constants' import {HamburgerMenu} from './components/workspace-hamburger' -import {MenuItems, WorkSpaceState} from './types' +import {MenuItems, WorkSpaceState, WorkspaceMetadata} from './types' import {contextMenuActions} from './utils' import FileExplorerContextMenu from './components/file-explorer-context-menu' import { customAction } from '@remixproject/plugin-api' @@ -26,13 +27,7 @@ export function Workspace() { const LOCALHOST = ' - connect to localhost - ' const NO_WORKSPACE = ' - none - ' const [currentWorkspace, setCurrentWorkspace] = useState(NO_WORKSPACE) - const [selectedWorkspace, setSelectedWorkspace] = useState<{ - name: string - isGitRepo: boolean - hasGitSubmodules?: boolean - branches?: {remote: any; name: string}[] - currentBranch?: string - }>(null) + const [selectedWorkspace, setSelectedWorkspace] = useState(null) const [showDropdown, setShowDropdown] = useState(false) const [showIconsMenu, hideIconsMenu] = useState(false) const [showBranches, setShowBranches] = useState(false) @@ -73,7 +68,7 @@ export function Workspace() { }, mouseOverElement: null, showContextMenu: false, - reservedKeywords: [ROOT_PATH, 'gist-'], + reservedKeywords: [ROOT_PATH], copyElement: [], dragStatus: false }) @@ -437,7 +432,7 @@ export function Workspace() { } } - const handleCopyClick = (path: string, type: 'folder' | 'gist' | 'file' | 'workspace') => { + const handleCopyClick = (path: string, type: 'folder' | 'file' | 'workspace') => { setState((prevState) => { return {...prevState, copyElement: [{key: path, type}]} }) @@ -506,7 +501,6 @@ export function Workspace() { const focusElement = global.fs.focusElement if (focusElement[0]) { if (focusElement[0].type === 'folder' && focusElement[0].key) return focusElement[0].key - else if (focusElement[0].type === 'gist' && focusElement[0].key) return focusElement[0].key else if (focusElement[0].type === 'file' && focusElement[0].key) return extractParentFromKey(focusElement[0].key) ? extractParentFromKey(focusElement[0].key) : ROOT_PATH else return ROOT_PATH } @@ -570,34 +564,34 @@ export function Workspace() { } } - const pushChangesToGist = (path?: string, type?: string) => { + const pushChangesToGist = (path?: string) => { global.modal( intl.formatMessage({id: 'filePanel.createPublicGist'}), intl.formatMessage({id: 'filePanel.createPublicGistMsg1'}), intl.formatMessage({id: 'filePanel.ok'}), - () => toGist(path, type), + () => toGist(path), intl.formatMessage({id: 'filePanel.cancel'}), () => {} ) } - const publishFolderToGist = (path?: string, type?: string) => { + const publishFolderToGist = (path?: string) => { global.modal( intl.formatMessage({id: 'filePanel.createPublicGist'}), intl.formatMessage({id: 'filePanel.createPublicGistMsg2'}, {path}), intl.formatMessage({id: 'filePanel.ok'}), - () => toGist(path, type), + () => toGist(path), intl.formatMessage({id: 'filePanel.cancel'}), () => {} ) } - const publishFileToGist = (path?: string, type?: string) => { + const publishFileToGist = (path?: string) => { global.modal( intl.formatMessage({id: 'filePanel.createPublicGist'}), intl.formatMessage({id: 'filePanel.createPublicGistMsg3'}, {path}), intl.formatMessage({id: 'filePanel.ok'}), - () => toGist(path, type), + () => toGist(path), intl.formatMessage({id: 'filePanel.cancel'}), () => {} ) @@ -632,8 +626,8 @@ export function Workspace() { ) } - const toGist = (path?: string, type?: string) => { - global.dispatchPublishToGist(path, type) + const toGist = (path?: string) => { + global.dispatchPublishToGist(path) } const editModeOn = (path: string, type: string, isNew = false) => { @@ -922,7 +916,6 @@ export function Workspace() { ) } - return (
saveSampleCodeWorkspace()} className="far fa-exclamation-triangle text-warning ml-2 align-self-center" aria-hidden="true"> } + + {selectedWorkspace && selectedWorkspace.isGist && selectedWorkspace.isGist} direction="bottom" icon="far fa-copy"> + + + } +
@@ -1077,11 +1078,10 @@ export function Workspace() {
)} {!(global.fs.browser.isRequestingWorkspace || global.fs.browser.isRequestingCloning) && global.fs.mode === 'browser' && currentWorkspace !== NO_WORKSPACE && ( - void createWorkspace: (name: string, workspaceTemplateName: string) => void @@ -155,10 +173,10 @@ export interface FileExplorerContextMenuProps { renamePath: (path: string, type: string) => void downloadPath: (path: string) => void hideContextMenu: () => 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 + publishToGist?: (path?: string) => void + pushChangesToGist?: (path?: string) => void + publishFolderToGist?: (path?: string) => void + publishFileToGist?: (path?: string) => void runScript?: (path: string) => void emit?: (cmd: customAction) => void pageX: number @@ -319,4 +337,4 @@ export interface Action { export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionPayloadTypes] -export type WorkspaceElement = 'folder' | 'gist' | 'file' | 'workspace' +export type WorkspaceElement = 'folder' | 'file' | 'workspace' diff --git a/libs/remix-ui/workspace/src/lib/utils/constants.ts b/libs/remix-ui/workspace/src/lib/utils/constants.ts index e5a4b21523..823bcabdc3 100644 --- a/libs/remix-ui/workspace/src/lib/utils/constants.ts +++ b/libs/remix-ui/workspace/src/lib/utils/constants.ts @@ -1,4 +1,4 @@ -import { TemplateType } from './types' +import { TemplateType } from '../types' export const ROOT_PATH = '/' export const solTestYml = ` name: Running Solidity Unit Tests diff --git a/libs/remix-ui/workspace/src/lib/utils/index.ts b/libs/remix-ui/workspace/src/lib/utils/index.ts index 7af6507785..d29b524163 100644 --- a/libs/remix-ui/workspace/src/lib/utils/index.ts +++ b/libs/remix-ui/workspace/src/lib/utils/index.ts @@ -1,18 +1,18 @@ import { appPlatformTypes } from '@remix-ui/app' import { FileType } from '@remix-ui/file-decorators' -import { WorkspaceProps, MenuItems } from '../types' +import { MenuItems } from '../types' export const contextMenuActions: MenuItems = [{ id: 'newFile', name: 'New File', - type: ['folder', 'gist', 'workspace'], + type: ['folder', 'workspace'], multiselect: false, label: '', group: 0 }, { id: 'newFolder', name: 'New Folder', - type: ['folder', 'gist', 'workspace'], + type: ['folder', 'workspace'], multiselect: false, label: '', group: 0 @@ -26,7 +26,7 @@ export const contextMenuActions: MenuItems = [{ }, { id: 'delete', name: 'Delete', - type: ['file', 'folder', 'gist'], + type: ['file', 'folder'], multiselect: false, label: '', group: 0 @@ -80,14 +80,6 @@ export const contextMenuActions: MenuItems = [{ multiselect: false, label: '', group: 3 -}, { - id: 'pushChangesToGist', - name: 'Push changes to gist', - type: ['gist'], - multiselect: false, - label: '', - group: 4, - platform: appPlatformTypes.web }, { id: 'publishFolderToGist', name: 'Publish folder to gist', @@ -107,21 +99,12 @@ export const contextMenuActions: MenuItems = [{ }, { id: 'uploadFile', name: 'Load a Local File', - type: ['folder', 'gist', 'workspace'], + type: ['folder', 'workspace'], multiselect: false, label: 'Load a Local File', group: 4, platform: appPlatformTypes.web -}, { - id: 'publishToGist', - name: 'Push changes to gist', - type: ['folder', 'gist'], - multiselect: false, - label: 'Publish all to Gist', - group: 4, - platform: appPlatformTypes.web -}, -{ +},{ id: 'publishWorkspace', name: 'Publish Workspace to Gist', type: ['workspace'], diff --git a/libs/remix-ui/workspace/src/lib/utils/types.ts b/libs/remix-ui/workspace/src/lib/utils/types.ts deleted file mode 100644 index 750001bca5..0000000000 --- a/libs/remix-ui/workspace/src/lib/utils/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type TemplateType = { - type: 'git' | 'plugin' - url?: string - branch?: string - name?: string - endpoint?: string - params?: any[] - } \ No newline at end of file