File provider actions

pull/1140/head
ioedeveloper 4 years ago
parent 3c4606ff9e
commit 48f6b50e36
  1. 2
      apps/remix-ide/src/app/panels/file-panel.js
  2. 53
      libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts
  3. 551
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  4. 88
      libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts

@ -229,7 +229,7 @@ module.exports = class Filepanel extends ViewPlugin {
/** these are called by the react component, action is already finished whent it's called */
async setWorkspace (workspace) {
this._deps.fileManager.closeAllFiles()
this._deps.fileManager.removeTabsOf(this._deps.fileProviders.workspace)
if (workspace.isLocalhost) {
this.call('manager', 'activatePlugin', 'remixd')
} else if (await this.call('manager', 'isActive', 'remixd')) {

@ -3,10 +3,12 @@ import { File } from '../types'
import { extractNameFromKey, extractParentFromKey } from '../utils'
const globalRegistry = require('../../../../../../apps/remix-ide/src/global/registry')
const fileProviders = globalRegistry.get('fileproviders').api
const browser = fileProviders.browser // eslint-disable-line
const workspace = fileProviders.workspace
const localhost = fileProviders.localhost // eslint-disable-line
const initializeProvider = () => {
const fileProviders = globalRegistry.get('fileproviders').api
const browser = fileProviders.browser // eslint-disable-line
const workspace = fileProviders.workspace
const localhost = fileProviders.localhost // eslint-disable-line
}
export const fetchDirectoryError = (error: any) => {
return {
@ -62,9 +64,9 @@ const normalize = (filesList): File[] => {
return [...folders, ...files]
}
const fetchDirectoryContent = async (folderPath: string): Promise<File[]> => {
const fetchDirectoryContent = async (provider, folderPath: string): Promise<File[]> => {
return new Promise((resolve) => {
workspace.resolveDirectory(folderPath, (error, fileTree) => {
provider.resolveDirectory(folderPath, (error, fileTree) => {
if (error) console.error(error)
const files = normalize(fileTree)
@ -73,8 +75,43 @@ const fetchDirectoryContent = async (folderPath: string): Promise<File[]> => {
})
}
export const fetchDirectory = (path: string) => (dispatch: React.Dispatch<any>) => {
const promise = fetchDirectoryContent(path)
export const fetchDirectory = (provider, path: string) => (dispatch: React.Dispatch<any>) => {
initializeProvider()
const promise = fetchDirectoryContent(provider, path)
dispatch(fetchDirectoryRequest(promise))
promise.then((files) => {
dispatch(fetchDirectorySuccess(path, files))
}).catch((error) => {
dispatch(fetchDirectoryError({ error }))
})
return promise
}
export const fetchProviderError = (error: any) => {
return {
type: 'FETCH_PROVIDER_ERROR',
payload: error
}
}
export const fetchProviderRequest = (promise: Promise<any>) => {
return {
type: 'FETCH_PROVIDER_REQUEST',
payload: promise
}
}
export const fetchProviderSuccess = (provider: any) => {
return {
type: 'FETCH_PROVIDER_SUCCESS',
payload: provider
}
}
export const setProvider = () => (dispatch: React.Dispatch<any>) => {
initializeProvider()
const promise = fetchDirectoryContent(provider, path)
dispatch(fetchDirectoryRequest(promise))
promise.then((files) => {

@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef } from 'react' // eslint-disable-line
import React, { useEffect, useState, useRef, useReducer } from 'react' // eslint-disable-line
// import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' // eslint-disable-line
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
@ -7,6 +7,8 @@ import Gists from 'gists'
import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line
import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line
import { FileExplorerProps, File } from './types'
import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem'
import { fetchDirectory } from './actions/fileSystem'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params'
@ -60,6 +62,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
mouseOverElement: null,
showContextMenu: false
})
const [fileSystem, dispatch] = useReducer(fileSystemReducer, fileSystemInitialState)
const editRef = useRef(null)
useEffect(() => {
@ -74,8 +77,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
useEffect(() => {
(async () => {
await fetchDirectory(filesProvider, name)(dispatch)
const fileManager = registry.get('filemanager').api
const files = await fetchDirectoryContent(name)
const actions = [{
id: 'newFile',
name: 'New File',
@ -121,7 +124,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
}]
setState(prevState => {
return { ...prevState, fileManager, files, actions, expandPath: [name] }
return { ...prevState, fileManager, actions, expandPath: [name] }
})
})()
}, [name])
@ -134,35 +137,35 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}, [state.fileManager])
useEffect(() => {
const { expandPath } = state
const expandFn = async () => {
let files = state.files
for (let i = 0; i < expandPath.length; i++) {
files = await resolveDirectory(expandPath[i], files)
await setState(prevState => {
return { ...prevState, files }
})
}
}
if (expandPath && expandPath.length > 0) {
expandFn()
}
}, [state.expandPath])
useEffect(() => {
// unregister event to update state in callback
if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded)
if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded)
if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved)
if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed)
filesProvider.event.register('fileAdded', fileAdded)
filesProvider.event.register('folderAdded', folderAdded)
filesProvider.event.register('fileRemoved', fileRemoved)
filesProvider.event.register('fileRenamed', fileRenamed)
}, [state.files])
// useEffect(() => {
// const { expandPath } = state
// const expandFn = async () => {
// let files = state.files
// for (let i = 0; i < expandPath.length; i++) {
// files = await resolveDirectory(expandPath[i], files)
// await setState(prevState => {
// return { ...prevState, files }
// })
// }
// }
// if (expandPath && expandPath.length > 0) {
// expandFn()
// }
// }, [state.expandPath])
// useEffect(() => {
// // unregister event to update state in callback
// if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded)
// if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded)
// if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved)
// if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed)
// filesProvider.event.register('fileAdded', fileAdded)
// filesProvider.event.register('folderAdded', folderAdded)
// filesProvider.event.register('fileRemoved', fileRemoved)
// filesProvider.event.register('fileRenamed', fileRenamed)
// }, [state.files])
useEffect(() => {
if (focusRoot) {
@ -220,44 +223,44 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}, [state.modals])
const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise<File[]> => {
if (!isChild && (state.focusEdit.element === '/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === '/blank') === -1)) {
dir = state.focusEdit.type === 'file' ? [...dir, {
path: state.focusEdit.element,
name: '',
isDirectory: false
}] : [{
path: state.focusEdit.element,
name: '',
isDirectory: true
}, ...dir]
}
dir = await Promise.all(dir.map(async (file) => {
if (file.path === folderPath) {
if ((extractParentFromKey(state.focusEdit.element) === folderPath) && state.focusEdit.isNew) {
file.child = state.focusEdit.type === 'file' ? [...await fetchDirectoryContent(folderPath), {
path: state.focusEdit.element,
name: '',
isDirectory: false
}] : [{
path: state.focusEdit.element,
name: '',
isDirectory: true
}, ...await fetchDirectoryContent(folderPath)]
} else {
file.child = await fetchDirectoryContent(folderPath)
}
return file
} else if (file.child) {
file.child = await resolveDirectory(folderPath, file.child, true)
return file
} else {
return file
}
}))
return dir
}
// const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise<File[]> => {
// if (!isChild && (state.focusEdit.element === '/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === '/blank') === -1)) {
// dir = state.focusEdit.type === 'file' ? [...dir, {
// path: state.focusEdit.element,
// name: '',
// isDirectory: false
// }] : [{
// path: state.focusEdit.element,
// name: '',
// isDirectory: true
// }, ...dir]
// }
// dir = await Promise.all(dir.map(async (file) => {
// if (file.path === folderPath) {
// if ((extractParentFromKey(state.focusEdit.element) === folderPath) && state.focusEdit.isNew) {
// file.child = state.focusEdit.type === 'file' ? [...await fetchDirectoryContent(folderPath), {
// path: state.focusEdit.element,
// name: '',
// isDirectory: false
// }] : [{
// path: state.focusEdit.element,
// name: '',
// isDirectory: true
// }, ...await fetchDirectoryContent(folderPath)]
// } else {
// file.child = await fetchDirectoryContent(folderPath)
// }
// return file
// } else if (file.child) {
// file.child = await resolveDirectory(folderPath, file.child, true)
// return file
// } else {
// return file
// }
// }))
// return dir
// }
const fetchDirectoryContent = async (folderPath: string): Promise<File[]> => {
console.log('folderPath: ', folderPath)
@ -312,61 +315,61 @@ export const FileExplorer = (props: FileExplorerProps) => {
return keyPath.join('/')
}
const createNewFile = (newFilePath: string) => {
const fileManager = state.fileManager
try {
helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
if (error) {
modal('Create File Failed', error, {
label: 'Close',
fn: async () => {}
}, null)
} else {
const createFile = await fileManager.writeFile(newName, '')
if (!createFile) {
return toast('Failed to create file ' + newName)
} else {
await fileManager.open(newName)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
})
}
}
})
} catch (error) {
return modal('File Creation Failed', typeof error === 'string' ? error : error.message, {
label: 'Close',
fn: async () => {}
}, null)
}
}
const createNewFolder = async (newFolderPath: string) => {
const fileManager = state.fileManager
const dirName = newFolderPath + '/'
try {
const exists = await fileManager.exists(dirName)
if (exists) {
return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, {
label: 'Close',
fn: () => {}
}, null)
}
await fileManager.mkdir(dirName)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] }
})
} catch (e) {
return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, {
label: 'Close',
fn: async () => {}
}, null)
}
}
// const createNewFile = (newFilePath: string) => {
// const fileManager = state.fileManager
// try {
// helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
// if (error) {
// modal('Create File Failed', error, {
// label: 'Close',
// fn: async () => {}
// }, null)
// } else {
// const createFile = await fileManager.writeFile(newName, '')
// if (!createFile) {
// return toast('Failed to create file ' + newName)
// } else {
// await fileManager.open(newName)
// setState(prevState => {
// return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
// })
// }
// }
// })
// } catch (error) {
// return modal('File Creation Failed', typeof error === 'string' ? error : error.message, {
// label: 'Close',
// fn: async () => {}
// }, null)
// }
// }
// const createNewFolder = async (newFolderPath: string) => {
// const fileManager = state.fileManager
// const dirName = newFolderPath + '/'
// try {
// const exists = await fileManager.exists(dirName)
// if (exists) {
// return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, {
// label: 'Close',
// fn: () => {}
// }, null)
// }
// await fileManager.mkdir(dirName)
// setState(prevState => {
// return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] }
// })
// } catch (e) {
// return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, {
// label: 'Close',
// fn: async () => {}
// }, null)
// }
// }
const deletePath = async (path: string) => {
if (filesProvider.isReadOnly(path)) {
@ -391,72 +394,72 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
}
const renamePath = async (oldPath: string, newPath: string) => {
try {
const fileManager = state.fileManager
const exists = await fileManager.exists(newPath)
if (exists) {
modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, {
label: 'Close',
fn: () => {}
}, null)
} else {
await fileManager.rename(oldPath, newPath)
}
} catch (error) {
modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, {
label: 'Close',
fn: async () => {}
}, null)
}
}
const removePath = (path: string, files: File[]): File[] => {
return files.map(file => {
if (file.path === path) {
return null
} else if (file.child) {
const childFiles = removePath(path, file.child)
file.child = childFiles.filter(file => file)
return file
} else {
return file
}
})
}
const fileAdded = async (filePath: string) => {
const pathArr = filePath.split('/')
const expandPath = pathArr.map((path, index) => {
return [...pathArr.slice(0, index)].join('/')
}).filter(path => path && (path !== props.name))
const files = await fetchDirectoryContent(props.name)
setState(prevState => {
const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])]
return { ...prevState, files, expandPath: uniquePaths }
})
if (filePath.includes('_test.sol')) {
plugin.event.trigger('newTestFileCreated', [filePath])
}
}
const folderAdded = async (folderPath: string) => {
const pathArr = folderPath.split('/')
const expandPath = pathArr.map((path, index) => {
return [...pathArr.slice(0, index)].join('/')
}).filter(path => path && (path !== props.name))
const files = await fetchDirectoryContent(props.name)
setState(prevState => {
const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])]
return { ...prevState, files, expandPath: uniquePaths }
})
}
// const renamePath = async (oldPath: string, newPath: string) => {
// try {
// const fileManager = state.fileManager
// const exists = await fileManager.exists(newPath)
// if (exists) {
// modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, {
// label: 'Close',
// fn: () => {}
// }, null)
// } else {
// await fileManager.rename(oldPath, newPath)
// }
// } catch (error) {
// modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, {
// label: 'Close',
// fn: async () => {}
// }, null)
// }
// }
// const removePath = (path: string, files: File[]): File[] => {
// return files.map(file => {
// if (file.path === path) {
// return null
// } else if (file.child) {
// const childFiles = removePath(path, file.child)
// file.child = childFiles.filter(file => file)
// return file
// } else {
// return file
// }
// })
// }
// const fileAdded = async (filePath: string) => {
// const pathArr = filePath.split('/')
// const expandPath = pathArr.map((path, index) => {
// return [...pathArr.slice(0, index)].join('/')
// }).filter(path => path && (path !== props.name))
// const files = await fetchDirectoryContent(props.name)
// setState(prevState => {
// const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])]
// return { ...prevState, files, expandPath: uniquePaths }
// })
// if (filePath.includes('_test.sol')) {
// plugin.event.trigger('newTestFileCreated', [filePath])
// }
// }
// const folderAdded = async (folderPath: string) => {
// const pathArr = folderPath.split('/')
// const expandPath = pathArr.map((path, index) => {
// return [...pathArr.slice(0, index)].join('/')
// }).filter(path => path && (path !== props.name))
// const files = await fetchDirectoryContent(props.name)
// setState(prevState => {
// const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])]
// return { ...prevState, files, expandPath: uniquePaths }
// })
// }
const fileExternallyChanged = (path: string, file: { content: string }) => {
const config = registry.get('config').api
@ -476,22 +479,22 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}
const fileRemoved = (filePath) => {
const files = removePath(filePath, state.files)
const updatedFiles = files.filter(file => file)
// const fileRemoved = (filePath) => {
// const files = removePath(filePath, state.files)
// const updatedFiles = files.filter(file => file)
setState(prevState => {
return { ...prevState, files: updatedFiles }
})
}
// setState(prevState => {
// return { ...prevState, files: updatedFiles }
// })
// }
const fileRenamed = async () => {
const files = await fetchDirectoryContent(props.name)
// const fileRenamed = async () => {
// const files = await fetchDirectoryContent(props.name)
setState(prevState => {
return { ...prevState, files, expandPath: [...prevState.expandPath] }
})
}
// setState(prevState => {
// return { ...prevState, files, expandPath: [...prevState.expandPath] }
// })
// }
// register to event of the file provider
// files.event.register('fileRenamed', fileRenamed)
@ -798,59 +801,59 @@ export const FileExplorer = (props: FileExplorerProps) => {
})
}
const editModeOff = async (content: string) => {
if (typeof content === 'string') content = content.trim()
const parentFolder = extractParentFromKey(state.focusEdit.element)
if (!content || (content.trim() === '')) {
if (state.focusEdit.isNew) {
const files = removePath(state.focusEdit.element, state.files)
const updatedFiles = files.filter(file => file)
setState(prevState => {
return { ...prevState, files: updatedFiles, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
} else {
editRef.current.textContent = state.focusEdit.lastEdit
setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
} else {
if (state.focusEdit.lastEdit === content) {
editRef.current.textContent = content
return setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
if (helper.checkSpecialChars(content)) {
modal('Validation Error', 'Special characters are not allowed', {
label: 'OK',
fn: () => {}
}, null)
} else {
if (state.focusEdit.isNew) {
state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content))
const files = removePath(state.focusEdit.element, state.files)
const updatedFiles = files.filter(file => file)
setState(prevState => {
return { ...prevState, files: updatedFiles }
})
} else {
const oldPath: string = state.focusEdit.element
const oldName = extractNameFromKey(oldPath)
const newPath = oldPath.replace(oldName, content)
editRef.current.textContent = extractNameFromKey(oldPath)
renamePath(oldPath, newPath)
}
setState(prevState => {
return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
})
}
}
}
// const editModeOff = async (content: string) => {
// if (typeof content === 'string') content = content.trim()
// const parentFolder = extractParentFromKey(state.focusEdit.element)
// if (!content || (content.trim() === '')) {
// if (state.focusEdit.isNew) {
// const files = removePath(state.focusEdit.element, state.files)
// const updatedFiles = files.filter(file => file)
// setState(prevState => {
// return { ...prevState, files: updatedFiles, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
// })
// } else {
// editRef.current.textContent = state.focusEdit.lastEdit
// setState(prevState => {
// return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
// })
// }
// } else {
// if (state.focusEdit.lastEdit === content) {
// editRef.current.textContent = content
// return setState(prevState => {
// return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
// })
// }
// if (helper.checkSpecialChars(content)) {
// modal('Validation Error', 'Special characters are not allowed', {
// label: 'OK',
// fn: () => {}
// }, null)
// } else {
// if (state.focusEdit.isNew) {
// state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content))
// const files = removePath(state.focusEdit.element, state.files)
// const updatedFiles = files.filter(file => file)
// setState(prevState => {
// return { ...prevState, files: updatedFiles }
// })
// } else {
// const oldPath: string = state.focusEdit.element
// const oldName = extractNameFromKey(oldPath)
// const newPath = oldPath.replace(oldName, content)
// editRef.current.textContent = extractNameFromKey(oldPath)
// renamePath(oldPath, newPath)
// }
// setState(prevState => {
// return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } }
// })
// }
// }
// }
const handleNewFileInput = async (parentFolder?: string) => {
if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name
@ -873,12 +876,12 @@ export const FileExplorer = (props: FileExplorerProps) => {
editModeOn(parentFolder + '/blank', 'folder', true)
}
const handleEditInput = (event) => {
if (event.which === 13) {
event.preventDefault()
editModeOff(editRef.current.innerText)
}
}
// const handleEditInput = (event) => {
// if (event.which === 13) {
// event.preventDefault()
// editModeOff(editRef.current.innerText)
// }
// }
const handleMouseOver = (path: string) => {
setState(prevState => {
@ -899,11 +902,11 @@ export const FileExplorer = (props: FileExplorerProps) => {
ref={state.focusEdit.element === file.path ? editRef : null}
suppressContentEditableWarning={true}
contentEditable={state.focusEdit.element === file.path}
onKeyDown={handleEditInput}
onBlur={(e) => {
e.stopPropagation()
editModeOff(editRef.current.innerText)
}}
// onKeyDown={handleEditInput}
// onBlur={(e) => {
// e.stopPropagation()
// editModeOff(editRef.current.innerText)
// }}
>
<span
title={file.path}
@ -1030,7 +1033,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
<div className='pb-2'>
<TreeView id='treeViewMenu'>
{
state.files.map((file, index) => {
fileSystem.files.files.map((file, index) => {
return renderFiles(file, index)
})
}
@ -1092,8 +1095,8 @@ async function packageFiles (filesProvider, directory, callback) {
}
}
function joinPath (...paths) {
paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)
if (paths.length === 1) return paths[0]
return paths.join('/')
}
// function joinPath (...paths) {
// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)
// if (paths.length === 1) return paths[0]
// return paths.join('/')
// }

@ -4,39 +4,91 @@ interface Action {
payload: Record<string, any>;
}
export const initialState = {
files: [],
expandPath: [],
isRequesting: false,
isSuccessful: false,
hasError: null
export const fileSystemInitialState = {
files: {
files: [],
expandPath: [],
isRequesting: false,
isSuccessful: false,
error: null
},
provider: {
provider: null,
isRequesting: false,
isSuccessful: false,
error: null
}
}
export const reducer = (state = initialState, action: Action) => {
export const fileSystemReducer = (state = fileSystemInitialState, action: Action) => {
switch (action.type) {
case 'FETCH_DIRECTORY_REQUEST': {
return {
...state,
isRequesting: true,
isSuccessful: false,
hasError: null
files: {
...state.files,
isRequesting: true,
isSuccessful: false,
error: null
}
}
}
case 'FETCH_DIRECTORY_SUCCESS': {
return {
files: action.payload.files,
expandPath: [...action.payload.path],
isRequesting: false,
isSuccessful: true,
hasError: null
...state,
files: {
...state.files,
files: action.payload.files,
expandPath: [...state.files.expandPath, action.payload.path],
isRequesting: false,
isSuccessful: true,
error: null
}
}
}
case 'FETCH_DIRECTORY_ERROR': {
return {
...state,
isRequesting: false,
isSuccessful: false,
hasError: action.payload
files: {
...state.files,
isRequesting: false,
isSuccessful: false,
error: action.payload
}
}
}
case 'FETCH_PROVIDER_REQUEST': {
return {
...state,
provider: {
...state.provider,
isRequesting: true,
isSuccessful: false,
error: null
}
}
}
case 'FETCH_PROVIDER_SUCCESS': {
return {
...state,
provider: {
...state.provider,
provider: action.payload,
isRequesting: false,
isSuccessful: true,
error: null
}
}
}
case 'FETCH_PROVIDER_ERROR': {
return {
...state,
provider: {
...state.provider,
isRequesting: false,
isSuccessful: false,
error: action.payload
}
}
}
default:

Loading…
Cancel
Save