From 8b589cd5afbfb7bf5ed64f90b3571e79c433a31f Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 02:49:54 +0100 Subject: [PATCH 1/9] context-menu --- apps/remix-ide/src/app/panels/file-panel.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 91f33673dd..51ae8734a5 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -34,7 +34,7 @@ var canUpload = window.File || window.FileReader || window.FileList || window.Bl const profile = { name: 'fileExplorers', displayName: 'File explorers', - methods: [], + methods: ['registerContextMenuItem'], events: [], icon: 'assets/img/fileManager.webp', description: ' - ', @@ -102,6 +102,15 @@ module.exports = class Filepanel extends ViewPlugin { return this.el } + /** + * + * @param { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } + */ + registerContextMenuItem (action, callback) { + if (!action.name || !callback) return + + } + renderComponent () { ReactDOM.render(
From 378e8155b01fd8222c004bee3c786b62dd9e0b03 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 04:48:47 +0100 Subject: [PATCH 2/9] Register context menu items --- apps/remix-ide/src/app/panels/file-panel.js | 11 +++++++++-- .../src/lib/file-explorer-context-menu.tsx | 9 +++++---- .../file-explorer/src/lib/file-explorer.tsx | 13 ++++++++++++- libs/remix-ui/file-explorer/src/lib/types/index.ts | 5 +++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 51ae8734a5..6521803a70 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -66,6 +66,7 @@ module.exports = class Filepanel extends ViewPlugin { } } this.reset = false + this.registeredMenuItems = [] this.el = yo`
@@ -106,9 +107,13 @@ module.exports = class Filepanel extends ViewPlugin { * * @param { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } */ - registerContextMenuItem (action, callback) { - if (!action.name || !callback) return + registerContextMenuItem (item, callback) { + if (!item.name || !callback) return console.error('menu name and item is mandatory') + if (!item.type && !item.path && !item.extension && !item.pattern) return console.error('invalid menu match criteria provided') + item.action = callback + this.registeredMenuItems = [...this.registeredMenuItems, item] + this.renderComponent() } renderComponent () { @@ -125,6 +130,7 @@ module.exports = class Filepanel extends ViewPlugin { menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} plugin={this} focusRoot={this.reset} + contextMenuItems={this.registeredMenuItems} />
@@ -136,6 +142,7 @@ module.exports = class Filepanel extends ViewPlugin { menuItems={['createNewFile', 'createNewFolder']} plugin={this} focusRoot={this.reset} + contextMenuItems={this.registeredMenuItems} /> }
diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx index aebd8eb053..7728bdb305 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx @@ -24,10 +24,10 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => const menu = () => { return actions.filter(item => { - if (item.type.findIndex(name => name === type) !== -1) return true - else if (item.path.findIndex(key => key === path) !== -1) return true - else if (item.extension.findIndex(ext => path.endsWith(ext)) !== -1) return true - else if (item.pattern.filter(value => path.match(new RegExp(value))).length > 0) return true + if (item.type && Array.isArray(item.type) && (item.type.findIndex(name => name === type) !== -1)) return true + else if (item.path && Array.isArray(item.path) && (item.path.findIndex(key => key === path) !== -1)) return true + else if (item.extension && Array.isArray(item.extension) && (item.extension.findIndex(ext => path.endsWith(ext)) !== -1)) return true + else if (item.pattern && Array.isArray(item.pattern) && (item.pattern.filter(value => path.match(new RegExp(value))).length > 0)) return true else return false }).map((item, index) => { return
  • runScript(path) break default: + item.action && item.action() break } hideContextMenu() diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 16ab028599..c476e8b853 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -16,7 +16,7 @@ import './css/file-explorer.css' const queryParams = new QueryParams() export const FileExplorer = (props: FileExplorerProps) => { - const { filesProvider, name, registry, plugin, focusRoot } = props + const { filesProvider, name, registry, plugin, focusRoot, contextMenuItems } = props const [state, setState] = useState({ focusElement: [{ key: name, @@ -165,6 +165,17 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [focusRoot]) + useEffect(() => { + if (contextMenuItems) { + setState(prevState => { + // filter duplicate items + const items = contextMenuItems.filter(({ name }) => prevState.actions.findIndex(action => action.name === name) === -1) + + return { ...prevState, actions: [...prevState.actions, ...items] } + }) + } + }, [contextMenuItems]) + const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise => { if (!isChild && (state.focusEdit.element === 'browser/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === 'browser/blank') === -1)) { dir = state.focusEdit.type === 'file' ? [...dir, { diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts index e2225dfc24..0fcabc94f3 100644 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts @@ -5,7 +5,8 @@ export interface FileExplorerProps { filesProvider: any, menuItems?: string[], plugin: any, - focusRoot: boolean + focusRoot: boolean, + contextMenuItems: { name: string, type: string[], path: string[], extension: string[], pattern: string[] }[] } export interface File { @@ -26,7 +27,7 @@ export interface FileExplorerMenuProps { } export interface FileExplorerContextMenuProps { - actions: { name: string, type: string[], path: string[], extension: string[], pattern: string[] }[], + actions: { name: string, type: string[], path: string[], extension: string[], pattern: string[], action?: (...args) => void }[], createNewFile: (folder?: string) => void, createNewFolder: (parentFolder?: string) => void, deletePath: (path: string) => void, From 6a8a134a17c04630508191a66115ebb7a1c46bee Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 04:51:42 +0100 Subject: [PATCH 3/9] Remove unused prop --- libs/remix-ui/file-explorer/src/lib/types/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts index 0fcabc94f3..27bb218336 100644 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts @@ -33,7 +33,6 @@ export interface FileExplorerContextMenuProps { deletePath: (path: string) => void, renamePath: (path: string, type: string) => void, hideContextMenu: () => void, - extractParentFromKey?: (key: string) => string, publishToGist?: () => void, runScript?: (path: string) => void, pageX: number, From aef57c91569f9519ec29490b3ed2e029401ce012 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 04:59:16 +0100 Subject: [PATCH 4/9] Update error logs --- apps/remix-ide/src/app/panels/file-panel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 6521803a70..d3065e60a9 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -108,8 +108,8 @@ module.exports = class Filepanel extends ViewPlugin { * @param { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } */ registerContextMenuItem (item, callback) { - if (!item.name || !callback) return console.error('menu name and item is mandatory') - if (!item.type && !item.path && !item.extension && !item.pattern) return console.error('invalid menu match criteria provided') + if (!item.name || !callback) return console.error('menu name and callback is mandatory') + if (!item.type && !item.path && !item.extension && !item.pattern) return console.error('invalid file matching criteria provided') item.action = callback this.registeredMenuItems = [...this.registeredMenuItems, item] From 5f18d5fe913d7fcdbd43245051807a909484f6a1 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 07:41:16 +0100 Subject: [PATCH 5/9] Update api docs for context menu --- apps/remix-ide/src/app/panels/file-panel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index d3065e60a9..d9ddbe078e 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -105,7 +105,8 @@ module.exports = class Filepanel extends ViewPlugin { /** * - * @param { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } + * @param item { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } + * @param callback (...args) => void */ registerContextMenuItem (item, callback) { if (!item.name || !callback) return console.error('menu name and callback is mandatory') From 9f4599eb7c4187eb2baff1849766dfa177131143 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 07:53:16 +0100 Subject: [PATCH 6/9] Include path as callback argument --- .../file-explorer/src/lib/file-explorer-context-menu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx index 7728bdb305..6f884221e1 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx @@ -56,7 +56,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => runScript(path) break default: - item.action && item.action() + item.action && item.action(path) break } hideContextMenu() From 2cb01ff79f8511c80fb92108d2eb1d9d6c00e95a Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 16:33:33 +0100 Subject: [PATCH 7/9] Use event emitter for ciontext menu action --- apps/remix-ide/src/app/panels/file-panel.js | 8 ++++---- .../src/lib/file-explorer-context-menu.tsx | 4 ++-- .../remix-ui/file-explorer/src/lib/file-explorer.tsx | 12 ++++++++++++ libs/remix-ui/file-explorer/src/lib/types/index.ts | 3 ++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index d9ddbe078e..dfdf8c7e01 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -108,11 +108,11 @@ module.exports = class Filepanel extends ViewPlugin { * @param item { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } * @param callback (...args) => void */ - registerContextMenuItem (item, callback) { - if (!item.name || !callback) return console.error('menu name and callback is mandatory') - if (!item.type && !item.path && !item.extension && !item.pattern) return console.error('invalid file matching criteria provided') + registerContextMenuItem (item) { + if (!item) throw new Error('Invalid register context menu argument') + if (!item.name || !item.id) throw new Error('Item name and id is mandatory') + if (!item.type && !item.path && !item.extension && !item.pattern) throw new Error('Invalid file matching criteria provided') - item.action = callback this.registeredMenuItems = [...this.registeredMenuItems, item] this.renderComponent() } diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx index 6f884221e1..3a842d91b3 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer-context-menu.tsx @@ -4,7 +4,7 @@ import { FileExplorerContextMenuProps } from './types' import './css/file-explorer-context-menu.css' export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => { - const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, publishToGist, runScript, pageX, pageY, path, type, ...otherProps } = props + const { actions, createNewFile, createNewFolder, deletePath, renamePath, hideContextMenu, publishToGist, runScript, emit, pageX, pageY, path, type, ...otherProps } = props const contextMenuRef = useRef(null) useEffect(() => { @@ -56,7 +56,7 @@ export const FileExplorerContextMenu = (props: FileExplorerContextMenuProps) => runScript(path) break default: - item.action && item.action(path) + emit && emit(item.id, path) break } hideContextMenu() diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index c476e8b853..e7e2f6e31f 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -76,36 +76,42 @@ export const FileExplorer = (props: FileExplorerProps) => { const accessToken = config.get('settings/gist-access-token') const files = await fetchDirectoryContent(name) const actions = [{ + id: 'newFile', name: 'New File', type: ['folder'], path: [], extension: [], pattern: [] }, { + id: 'newFolder', name: 'New Folder', type: ['folder'], path: [], extension: [], pattern: [] }, { + id: 'rename', name: 'Rename', type: ['file', 'folder'], path: [], extension: [], pattern: [] }, { + id: 'delete', name: 'Delete', type: ['file', 'folder'], path: [], extension: [], pattern: [] }, { + id: 'pushChangesToGist', name: 'Push changes to gist', type: [], path: [], extension: [], pattern: ['^browser/gists/([0-9]|[a-z])*$'] }, { + id: 'run', name: 'Run', type: [], path: [], @@ -614,6 +620,10 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } + const emitContextMenuEvent = (id: string, path: string) => { + plugin.emit(id, path) + } + const handleHideModal = () => { setState(prevState => { return { ...prevState, modalOptions: { ...state.modalOptions, hide: true } } @@ -850,6 +860,7 @@ export const FileExplorer = (props: FileExplorerProps) => { deletePath={deletePath} renamePath={editModeOn} publishToGist={publishToGist} + emit={emitContextMenuEvent} pageX={state.focusContext.x} pageY={state.focusContext.y} path={file.path} @@ -886,6 +897,7 @@ export const FileExplorer = (props: FileExplorerProps) => { deletePath={deletePath} renamePath={editModeOn} runScript={runScript} + emit={emitContextMenuEvent} pageX={state.focusContext.x} pageY={state.focusContext.y} path={file.path} diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts index 27bb218336..caa203ab7b 100644 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts @@ -27,7 +27,7 @@ export interface FileExplorerMenuProps { } export interface FileExplorerContextMenuProps { - actions: { name: string, type: string[], path: string[], extension: string[], pattern: string[], action?: (...args) => void }[], + actions: { name: string, type: string[], path: string[], extension: string[], pattern: string[], id: string }[], createNewFile: (folder?: string) => void, createNewFolder: (parentFolder?: string) => void, deletePath: (path: string) => void, @@ -35,6 +35,7 @@ export interface FileExplorerContextMenuProps { hideContextMenu: () => void, publishToGist?: () => void, runScript?: (path: string) => void, + emit?: (id: string, path: string) => void, pageX: number, pageY: number, path: string, From b31cb45c8ee0087287c0a268fadeb166a71521a9 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 19 Jan 2021 16:57:46 +0100 Subject: [PATCH 8/9] Update context menu params docs --- apps/remix-ide/src/app/panels/file-panel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index dfdf8c7e01..bdc92aefad 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -105,7 +105,7 @@ module.exports = class Filepanel extends ViewPlugin { /** * - * @param item { name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } + * @param item { id: string, name: string, type?: string[], path?: string[], extension?: string[], pattern?: string[] } * @param callback (...args) => void */ registerContextMenuItem (item) { From 0c7f92ede62ee18f25e308f31713236f9026c440 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 20 Jan 2021 16:01:16 +0100 Subject: [PATCH 9/9] Removed exposed method --- apps/remix-ide/src/app/panels/file-panel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index bdc92aefad..ca5e94417e 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -34,7 +34,7 @@ var canUpload = window.File || window.FileReader || window.FileList || window.Bl const profile = { name: 'fileExplorers', displayName: 'File explorers', - methods: ['registerContextMenuItem'], + methods: [], events: [], icon: 'assets/img/fileManager.webp', description: ' - ',