Commit 501d4b01 authored by ioedeveloper's avatar ioedeveloper

Update loading code from url params and fetch gist using axios

parent da9207dd
...@@ -3,7 +3,7 @@ import { ViewPlugin } from '@remixproject/engine-web' ...@@ -3,7 +3,7 @@ import { ViewPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
import React from 'react' // eslint-disable-line import React from 'react' // eslint-disable-line
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { FileSystemProvider, Workspace } from '@remix-ui/workspace' // eslint-disable-line import { FileSystemProvider } from '@remix-ui/workspace' // eslint-disable-line
import { checkSpecialChars, checkSlash } from '../../lib/helper' import { checkSpecialChars, checkSlash } from '../../lib/helper'
const { RemixdHandle } = require('../files/remixd-handle.js') const { RemixdHandle } = require('../files/remixd-handle.js')
const { GitHandle } = require('../files/git-handle.js') const { GitHandle } = require('../files/git-handle.js')
...@@ -63,15 +63,17 @@ module.exports = class Filepanel extends ViewPlugin { ...@@ -63,15 +63,17 @@ module.exports = class Filepanel extends ViewPlugin {
this.appManager = appManager this.appManager = appManager
} }
onActivation () {
this.renderComponent()
}
render () { render () {
return this.el return this.el
} }
renderComponent () { renderComponent () {
ReactDOM.render( ReactDOM.render(
<FileSystemProvider plugin={this}> <FileSystemProvider plugin={this} />
<Workspace plugin={this} />
</FileSystemProvider>
, this.el) , this.el)
} }
......
...@@ -13,14 +13,15 @@ export interface FileExplorerProps { ...@@ -13,14 +13,15 @@ export interface FileExplorerProps {
removedContextMenuItems: MenuItems, removedContextMenuItems: MenuItems,
displayInput?: boolean, displayInput?: boolean,
externalUploads?: EventTarget & HTMLInputElement, externalUploads?: EventTarget & HTMLInputElement,
resetFocus?: (value: boolean) => void resetFocus?: (value: boolean) => void,
files: { [x: string]: Record<string, File> }
} }
export interface File { export interface File {
path: string, path: string,
name: string, name: string,
isDirectory: boolean, isDirectory: boolean,
type: string, type: 'folder' | 'file' | 'gist',
child?: File[] child?: File[]
} }
...@@ -34,7 +35,7 @@ export interface FileExplorerMenuProps { ...@@ -34,7 +35,7 @@ export interface FileExplorerMenuProps {
uploadFile: (target: EventTarget & HTMLInputElement) => void uploadFile: (target: EventTarget & HTMLInputElement) => void
} }
export type action = { name: string, type: string[], path: string[], extension: string[], pattern: string[], id: string, multiselect: boolean, label: string } export type action = { name: string, type?: Array<'folder' | 'gist' | 'file'>, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string }
export interface FileExplorerContextMenuProps { export interface FileExplorerContextMenuProps {
actions: action[], actions: action[],
...@@ -58,3 +59,44 @@ export interface FileExplorerContextMenuProps { ...@@ -58,3 +59,44 @@ export interface FileExplorerContextMenuProps {
copy?: (path: string, type: string) => void, copy?: (path: string, type: string) => void,
paste?: (destination: string, type: string) => void paste?: (destination: string, type: string) => void
} }
export interface FileExplorerState {
focusElement: {
key: string
type: 'folder' | 'file' | 'gist'
}[]
fileManager: any
ctrlKey: boolean
newFileName: string
actions: {
id: string
name: string
type?: Array<'folder' | 'gist' | 'file'>
path?: string[]
extension?: string[]
pattern?: string[]
multiselect: boolean
label: string
}[]
focusContext: {
element: string
x: number
y: number
type: string
}
focusEdit: {
element: string
type: string
isNew: boolean
lastEdit: string
}
expandPath: string[]
toasterMsg: string
mouseOverElement: string
showContextMenu: boolean
reservedKeywords: string[]
copyElement: {
key: string
type: 'folder' | 'gist' | 'file'
}[]
}
import { MenuItems } from '../types'
export const extractNameFromKey = (key: string): string => { export const extractNameFromKey = (key: string): string => {
const keyPath = key.split('/') const keyPath = key.split('/')
...@@ -11,3 +13,65 @@ export const extractParentFromKey = (key: string):string => { ...@@ -11,3 +13,65 @@ export const extractParentFromKey = (key: string):string => {
return keyPath.join('/') return keyPath.join('/')
} }
export const contextMenuActions: MenuItems = [{
id: 'newFile',
name: 'New File',
type: ['folder', 'gist'],
multiselect: false,
label: ''
}, {
id: 'newFolder',
name: 'New Folder',
type: ['folder', 'gist'],
multiselect: false,
label: ''
}, {
id: 'rename',
name: 'Rename',
type: ['file', 'folder'],
multiselect: false,
label: ''
}, {
id: 'delete',
name: 'Delete',
type: ['file', 'folder', 'gist'],
multiselect: false,
label: ''
}, {
id: 'run',
name: 'Run',
extension: ['.js'],
multiselect: false,
label: ''
}, {
id: 'pushChangesToGist',
name: 'Push changes to gist',
type: ['gist'],
multiselect: false,
label: ''
}, {
id: 'publishFolderToGist',
name: 'Publish folder to gist',
type: ['folder'],
multiselect: false,
label: ''
}, {
id: 'publishFileToGist',
name: 'Publish file to gist',
type: ['file'],
multiselect: false,
label: ''
}, {
id: 'copy',
name: 'Copy',
type: ['folder', 'file'],
multiselect: false,
label: ''
}, {
id: 'deleteAll',
name: 'Delete All',
type: ['folder', 'file'],
multiselect: true,
label: ''
}]
export * from './lib/remix-ui-helper'; export * from './lib/remix-ui-helper'
export function remixUiHelper(): string { export const extractNameFromKey = (key: string): string => {
return 'remix-ui-helper'; const keyPath = key.split('/')
return keyPath[keyPath.length - 1]
}
export const extractParentFromKey = (key: string):string => {
if (!key) return
const keyPath = key.split('/')
keyPath.pop()
return keyPath.join('/')
}
export const checkSpecialChars = (name: string) => {
return name.match(/[:*?"<>\\'|]/) != null
}
export const checkSlash = (name: string) => {
return name.match(/\//) != null
} }
export * from './lib/remix-ui-workspace'
export * from './lib/providers/FileSystemProvider' export * from './lib/providers/FileSystemProvider'
export * from './lib/contexts'
// var modalDialogCustom = require('../app/ui/modal-dialog-custom')
import * as request from 'request'
export class GistHandler {
handleLoad (params) {
let loadingFromGist = false
let gistId
if (params.gist) {
loadingFromGist = true
} else {
gistId = params.gist
loadingFromGist = !!gistId
}
return gistId
}
getGistId (str: string) {
const idr = /[0-9A-Fa-f]{8,}/
const match = idr.exec(str)
return match ? match[0] : null
}
loadFromGist (params, fileManager) {
const gistId = this.handleLoad(params)
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)
}
})
})
}
}
import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import { checkSpecialChars, checkSlash } from '../../../../../../apps/remix-ide/src/lib/helper'
import React from 'react' import React from 'react'
import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import axios, { AxiosResponse } from 'axios'
import { checkSpecialChars, checkSlash } from '@remix-ui/helper'
// const GistHandler = require('../../../../../../apps/remix-ide/src/lib/gist-handler')
const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params') const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params')
const examples = require('../../../../../../apps/remix-ide/src/app/editor/examples') const examples = require('../../../../../../apps/remix-ide/src/app/editor/examples')
// const queuedEvents = [] // const queuedEvents = []
...@@ -51,6 +51,19 @@ const fetchDirectorySuccess = (path: string, files) => { ...@@ -51,6 +51,19 @@ const fetchDirectorySuccess = (path: string, files) => {
} }
} }
export const displayNotification = (title: string, message: string, labelOk: string, labelCancel: string, actionOk?: (...args) => void, actionCancel?: (...args) => void) => {
return {
type: 'DISPLAY_NOTIFICATION',
payload: { title, message, labelOk, labelCancel, actionOk, actionCancel }
}
}
export const hideNotification = () => {
return {
type: 'DISPLAY_NOTIFICATION'
}
}
export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => (dispatch: React.Dispatch<any>) => { export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => (dispatch: React.Dispatch<any>) => {
const provider = mode === 'browser' ? plugin.fileProviders.workspace : plugin.fileProviders.localhost const provider = mode === 'browser' ? plugin.fileProviders.workspace : plugin.fileProviders.localhost
const promise = new Promise((resolve) => { const promise = new Promise((resolve) => {
...@@ -73,34 +86,75 @@ export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => ( ...@@ -73,34 +86,75 @@ export const fetchDirectory = (mode: 'browser' | 'localhost', path: string) => (
const createWorkspaceTemplate = async (workspaceName: string, setDefaults = true, template: 'gist-template' | 'code-template' | 'default-template' = 'default-template') => { const createWorkspaceTemplate = async (workspaceName: string, setDefaults = true, template: 'gist-template' | 'code-template' | 'default-template' = 'default-template') => {
if (!workspaceName) throw new Error('workspace name cannot be empty') if (!workspaceName) throw new Error('workspace name cannot be empty')
if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed') if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed')
if (await workspaceExists(workspaceName)) throw new Error('workspace already exists') if (await workspaceExists(workspaceName) && template === 'default-template') throw new Error('workspace already exists')
else { else {
const workspaceProvider = plugin.fileProviders.workspace const workspaceProvider = plugin.fileProviders.workspace
await workspaceProvider.createWorkspace(workspaceName) await workspaceProvider.createWorkspace(workspaceName)
if (setDefaults) { if (setDefaults) {
const queryParams = new QueryParams()
const params = queryParams.get()
switch (template) { switch (template) {
case 'code-template': case 'code-template':
// creates a new workspace code-sample and loads code from url params. // creates a new workspace code-sample and loads code from url params.
try { try {
const queryParams = new QueryParams()
const params = queryParams.get()
await workspaceProvider.createWorkspace(workspaceName) await workspaceProvider.createWorkspace(workspaceName)
let path = ''; let content = ''
if (params.code) {
const hash = bufferToHex(keccakFromString(params.code)) const hash = bufferToHex(keccakFromString(params.code))
const fileName = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol'
const path = fileName
await workspaceProvider.set(path, atob(params.code)) path = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol'
await plugin.fileManager.openFile(fileName) content = atob(params.code)
await workspaceProvider.set(path, content)
} else if (params.url) {
const data = await plugin.call('contentImport', 'resolve', params.url)
path = data.cleanUrl
content = data.content
await workspaceProvider.set(path, content)
}
await plugin.fileManager.openFile(path)
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }
break break
case 'gist-template': case 'gist-template':
// creates a new workspace gist-sample and get the file from gist // creates a new workspace gist-sample and get the file from gist
try {
const gistId = params.gist
const response: AxiosResponse = await axios.get(`https://api.github.com/gists/${gistId}`)
const data = response.data
console.log('data: ', data)
if (!data.files) {
dispatch(displayNotification('Gist load error', 'No files found', 'OK', null, () => {}, null))
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('', errorLoadingFile.message || errorLoadingFile)
// }
// })
} catch (e) {
dispatch(displayNotification('Gist load error', e.message, 'OK', null, () => {}, null))
console.error(e)
}
break break
case 'default-template': case 'default-template':
// creates a new workspace and populates it with default project template. // creates a new workspace and populates it with default project template.
// insert example contracts // insert example contracts
...@@ -150,29 +204,17 @@ const getWorkspaces = async (): Promise<string[]> | undefined => { ...@@ -150,29 +204,17 @@ const getWorkspaces = async (): Promise<string[]> | undefined => {
export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.Dispatch<any>) => { export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.Dispatch<any>) => {
if (filePanelPlugin) { if (filePanelPlugin) {
console.log('filePanelPlugin: ', filePanelPlugin)
plugin = filePanelPlugin plugin = filePanelPlugin
dispatch = reducerDispatch dispatch = reducerDispatch
const provider = filePanelPlugin.fileProviders.workspace const provider = filePanelPlugin.fileProviders.workspace
const queryParams = new QueryParams() const queryParams = new QueryParams()
// const gistHandler = new GistHandler()
const params = queryParams.get() const params = queryParams.get()
// let loadedFromGist = false
const workspaces = await getWorkspaces() || [] const workspaces = await getWorkspaces() || []
// if (params.gist) {
// initialWorkspace = 'gist-sample'
// await provider.createWorkspace(initialWorkspace)
// loadedFromGist = gistHandler.loadFromGist(params, plugin.fileManager)
// }
// if (loadedFromGist) {
// dispatch(setWorkspaces(workspaces))
// dispatch(setCurrentWorkspace(initialWorkspace))
// return
// }
if (params.gist) { if (params.gist) {
await createWorkspaceTemplate('gist-sample', true, 'gist-template')
} else if (params.code) { dispatch(setCurrentWorkspace('gist-sample'))
} else if (params.code || params.url) {
await createWorkspaceTemplate('code-sample', true, 'code-template') await createWorkspaceTemplate('code-sample', true, 'code-template')
dispatch(setCurrentWorkspace('code-sample')) dispatch(setCurrentWorkspace('code-sample'))
} else { } else {
...@@ -225,7 +267,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React. ...@@ -225,7 +267,7 @@ export const initWorkspace = (filePanelPlugin) => async (reducerDispatch: React.
// provider.event.on('createWorkspace', (name) => { // provider.event.on('createWorkspace', (name) => {
// createNewWorkspace(name) // createNewWorkspace(name)
// }) // })
dispatch(setWorkspaces(workspaces)) // dispatch(setWorkspaces(workspaces))
dispatch(setMode('browser')) dispatch(setMode('browser'))
} }
} }
......
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import React, { useReducer, useState, useEffect } from 'react' import React, { useReducer, useState, useEffect } from 'react'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileSystemContext } from '../contexts' import { FileSystemContext } from '../contexts'
import { browserReducer, browserInitialState } from '../reducers/workspace' import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, initLocalhost, fetchDirectory } from '../actions/workspace' import { initWorkspace, initLocalhost, fetchDirectory } from '../actions/workspace'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line import { Modal, WorkspaceProps } from '../types'
import { Modal } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Workspace } from '../remix-ui-workspace'
export const FileSystemProvider = ({ filePanel, children }) => { export const FileSystemProvider = (props: WorkspaceProps) => {
const { plugin } = props
const [fs, fsDispatch] = useReducer(browserReducer, browserInitialState) const [fs, fsDispatch] = useReducer(browserReducer, browserInitialState)
const [focusModal, setFocusModal] = useState<Modal>({ const [focusModal, setFocusModal] = useState<Modal>({
hide: true, hide: true,
...@@ -21,11 +24,11 @@ export const FileSystemProvider = ({ filePanel, children }) => { ...@@ -21,11 +24,11 @@ export const FileSystemProvider = ({ filePanel, children }) => {
const [modals, setModals] = useState<Modal[]>([]) const [modals, setModals] = useState<Modal[]>([])
const dispatchInitWorkspace = async () => { const dispatchInitWorkspace = async () => {
await initWorkspace(filePanel)(fsDispatch) await initWorkspace(plugin)(fsDispatch)
} }
const dispatchInitLocalhost = async () => { const dispatchInitLocalhost = async () => {
await initLocalhost(filePanel)(fsDispatch) await initLocalhost(plugin)(fsDispatch)
} }
const dispatchFetchDirectory = async (path: string) => { const dispatchFetchDirectory = async (path: string) => {
...@@ -34,7 +37,7 @@ export const FileSystemProvider = ({ filePanel, children }) => { ...@@ -34,7 +37,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
useEffect(() => { useEffect(() => {
if (modals.length > 0) { if (modals.length > 0) {
setModals(modals => { setFocusModal(() => {
const focusModal = { const focusModal = {
hide: false, hide: false,
title: modals[0].title, title: modals[0].title,
...@@ -44,14 +47,12 @@ export const FileSystemProvider = ({ filePanel, children }) => { ...@@ -44,14 +47,12 @@ export const FileSystemProvider = ({ filePanel, children }) => {
cancelLabel: modals[0].cancelLabel, cancelLabel: modals[0].cancelLabel,
cancelFn: modals[0].cancelFn cancelFn: modals[0].cancelFn
} }
return focusModal
modals.shift()
return {
...modals,
focusModal,
modals: modals
}
}) })
const modalList = modals.slice()
modalList.shift()
setModals(modalList)
} }
}, [modals]) }, [modals])
...@@ -62,7 +63,10 @@ export const FileSystemProvider = ({ filePanel, children }) => { ...@@ -62,7 +63,10 @@ export const FileSystemProvider = ({ filePanel, children }) => {
} }
const modal = (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => { const modal = (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
setModals(modals => [...modals, { message, title, okLabel, okFn, cancelLabel, cancelFn }]) setModals(modals => {
modals.push({ message, title, okLabel, okFn, cancelLabel, cancelFn })
return [...modals]
})
} }
const value = { const value = {
...@@ -74,7 +78,7 @@ export const FileSystemProvider = ({ filePanel, children }) => { ...@@ -74,7 +78,7 @@ export const FileSystemProvider = ({ filePanel, children }) => {
} }
return ( return (
<FileSystemContext.Provider value={value}> <FileSystemContext.Provider value={value}>
{ children } <Workspace plugin={plugin} />
<ModalDialog id='fileSystem' { ...focusModal } handleHide={ handleHideModal } /> <ModalDialog id='fileSystem' { ...focusModal } handleHide={ handleHideModal } />
</FileSystemContext.Provider> </FileSystemContext.Provider>
) )
......
import { extractNameFromKey } from '@remix-ui/file-explorer' import { extractNameFromKey, File } from '@remix-ui/file-explorer'
interface Action { interface Action {
type: string type: string
payload: any payload: any
...@@ -7,36 +7,52 @@ export interface BrowserState { ...@@ -7,36 +7,52 @@ export interface BrowserState {
browser: { browser: {
currentWorkspace: string, currentWorkspace: string,
workspaces: string[], workspaces: string[],
files: [] files: { [x: string]: Record<string, File> }
isRequesting: boolean, isRequesting: boolean,
isSuccessful: boolean, isSuccessful: boolean,
error: string error: string
}, },
localhost: { localhost: {
files: [], files: { [x: string]: Record<string, File> },
isRequesting: boolean, isRequesting: boolean,
isSuccessful: boolean, isSuccessful: boolean,
error: string error: string
}, },
mode: 'browser' | 'localhost' mode: 'browser' | 'localhost',
notification: {
title: string,
message: string,
actionOk: () => void,
actionCancel: (() => void) | null,
labelOk: string,
labelCancel: string
}
} }
export const browserInitialState: BrowserState = { export const browserInitialState: BrowserState = {
browser: { browser: {
currentWorkspace: '', currentWorkspace: '',
workspaces: [], workspaces: [],
files: [], files: {},
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
error: null error: null
}, },
localhost: { localhost: {
files: [], files: {},
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
error: null error: null
}, },
mode: 'browser' mode: 'browser',
notification: {
title: '',
message: '',
actionOk: () => {},
actionCancel: () => {},
labelOk: '',
labelCancel: ''
}
} }
export const browserReducer = (state = browserInitialState, action: Action) => { export const browserReducer = (state = browserInitialState, action: Action) => {
...@@ -67,9 +83,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => { ...@@ -67,9 +83,11 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
} }
case 'SET_MODE': { case 'SET_MODE': {
const payload = action.payload as 'browser' | 'localhost'
return { return {
...state, ...state,
mode: action.payload mode: payload
} }
} }
...@@ -84,6 +102,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => { ...@@ -84,6 +102,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
} }
} }
} }
case 'FETCH_DIRECTORY_SUCCESS': { case 'FETCH_DIRECTORY_SUCCESS': {
const payload = action.payload as { path: string, files } const payload = action.payload as { path: string, files }
...@@ -98,6 +117,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => { ...@@ -98,6 +117,7 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
} }
} }
} }
case 'FETCH_DIRECTORY_ERROR': { case 'FETCH_DIRECTORY_ERROR': {
return { return {
...state, ...state,
...@@ -109,6 +129,29 @@ export const browserReducer = (state = browserInitialState, action: Action) => { ...@@ -109,6 +129,29 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
} }
} }
} }
case 'DISPLAY_NOTIFICATION': {
const payload = action.payload as { title: string, message: string, actionOk: () => void, actionCancel: () => void, labelOk: string, labelCancel: string }
return {
...state,
notification: {
title: payload.title,
message: payload.message,
actionOk: payload.actionOk || browserInitialState.notification.actionOk,
actionCancel: payload.actionCancel || browserInitialState.notification.actionCancel,
labelOk: payload.labelOk,
labelCancel: payload.labelCancel
}
}
}
case 'HIDE_NOTIFICATION': {
return {
...state,
notification: browserInitialState.notification
}
}
default: default:
throw new Error() throw new Error()
} }
...@@ -120,7 +163,7 @@ const fetchDirectoryContent = (fileTree, folderPath: string) => { ...@@ -120,7 +163,7 @@ const fetchDirectoryContent = (fileTree, folderPath: string) => {
return { [extractNameFromKey(folderPath)]: files } return { [extractNameFromKey(folderPath)]: files }
} }
const normalize = (filesList): any => { const normalize = (filesList): Record<string, File> => {
const folders = {} const folders = {}
const files = {} const files = {}
......
...@@ -11,7 +11,6 @@ export function Workspace (props: WorkspaceProps) { ...@@ -11,7 +11,6 @@ export function Workspace (props: WorkspaceProps) {
const LOCALHOST = ' - connect to localhost - ' const LOCALHOST = ' - connect to localhost - '
const NO_WORKSPACE = ' - none - ' const NO_WORKSPACE = ' - none - '
const [state, setState] = useState<WorkspaceState>({ const [state, setState] = useState<WorkspaceState>({
workspaces: [],
reset: false, reset: false,
hideRemixdExplorer: true, hideRemixdExplorer: true,
displayNewFile: false, displayNewFile: false,
...@@ -28,7 +27,10 @@ export function Workspace (props: WorkspaceProps) { ...@@ -28,7 +27,10 @@ export function Workspace (props: WorkspaceProps) {
}, []) }, [])
useEffect(() => { useEffect(() => {
if (global.fs.browser.currentWorkspace) setCurrentWorkspace(global.fs.browser.currentWorkspace) if (global.fs.browser.currentWorkspace) {
setCurrentWorkspace(global.fs.browser.currentWorkspace)
global.dispatchFetchDirectory(global.fs.browser.currentWorkspace)
}
}, [global.fs.browser.currentWorkspace]) }, [global.fs.browser.currentWorkspace])
props.plugin.resetNewFile = () => { props.plugin.resetNewFile = () => {
...@@ -46,18 +48,18 @@ export function Workspace (props: WorkspaceProps) { ...@@ -46,18 +48,18 @@ export function Workspace (props: WorkspaceProps) {
return setWorkspace(workspaceName) return setWorkspace(workspaceName)
} }
props.plugin.request.createNewFile = async () => { // props.plugin.request.createNewFile = async () => {
if (!state.workspaces.length) await createNewWorkspace('default_workspace') // if (!state.workspaces.length) await createNewWorkspace('default_workspace')
props.plugin.resetNewFile() // props.plugin.resetNewFile()
} // }
props.plugin.request.uploadFile = async (target: EventTarget & HTMLInputElement) => { // props.plugin.request.uploadFile = async (target: EventTarget & HTMLInputElement) => {
if (!state.workspaces.length) await createNewWorkspace('default_workspace') // if (!state.workspaces.length) await createNewWorkspace('default_workspace')
setState(prevState => { // setState(prevState => {
return { ...prevState, uploadFileEvent: target } // return { ...prevState, uploadFileEvent: target }
}) // })
} // }
props.plugin.request.getCurrentWorkspace = () => { props.plugin.request.getCurrentWorkspace = () => {
return { name: currentWorkspace, isLocalhost: currentWorkspace === LOCALHOST, absolutePath: `${props.plugin.workspace.workspacesPath}/${currentWorkspace}` } return { name: currentWorkspace, isLocalhost: currentWorkspace === LOCALHOST, absolutePath: `${props.plugin.workspace.workspacesPath}/${currentWorkspace}` }
...@@ -287,6 +289,7 @@ export function Workspace (props: WorkspaceProps) { ...@@ -287,6 +289,7 @@ export function Workspace (props: WorkspaceProps) {
displayInput={state.displayNewFile} displayInput={state.displayNewFile}
externalUploads={state.uploadFileEvent} externalUploads={state.uploadFileEvent}
resetFocus={resetFocus} resetFocus={resetFocus}
files={global.fs.browser.files}
/> />
} }
</div> </div>
...@@ -304,6 +307,7 @@ export function Workspace (props: WorkspaceProps) { ...@@ -304,6 +307,7 @@ export function Workspace (props: WorkspaceProps) {
contextMenuItems={props.plugin.registeredMenuItems} contextMenuItems={props.plugin.registeredMenuItems}
removedContextMenuItems={props.plugin.removedMenuItems} removedContextMenuItems={props.plugin.removedMenuItems}
resetFocus={resetFocus} resetFocus={resetFocus}
files={global.fs.localhost.files}
/> />
} }
</div> </div>
......
import { MenuItems } from '@remix-ui/file-explorer' import { MenuItems } from '@remix-ui/file-explorer'
export interface WorkspaceProps { export interface WorkspaceProps {
plugin: { plugin: {
setWorkspace: ({ name: string, isLocalhost: boolean }, setEvent: boolean) => void, setWorkspace: ({ name: string, isLocalhost: boolean }, setEvent: boolean) => void,
...@@ -29,7 +28,6 @@ export interface WorkspaceProps { ...@@ -29,7 +28,6 @@ export interface WorkspaceProps {
} }
} }
export interface WorkspaceState { export interface WorkspaceState {
workspaces: string[]
reset: boolean reset: boolean
hideRemixdExplorer: boolean hideRemixdExplorer: boolean
displayNewFile: boolean displayNewFile: boolean
...@@ -48,3 +46,11 @@ export interface Modal { ...@@ -48,3 +46,11 @@ export interface Modal {
cancelLabel: string cancelLabel: string
cancelFn: () => void cancelFn: () => void
} }
export interface File {
path: string,
name: string,
isDirectory: boolean,
type: 'folder' | 'file' | 'gist',
child?: File[]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment