diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 73832ac32c..eb0303e45d 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -179,7 +179,7 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { } } -export const init = (provider, workspaceName: string, plugin) => (dispatch: React.Dispatch) => { +export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { const path = extractParentFromKey(filePath) || workspaceName @@ -201,15 +201,36 @@ export const init = (provider, workspaceName: string, plugin) => (dispatch: Reac dispatch(fileRemovedSuccess(path, removePath)) }) - provider.event.register('fileRenamed', async (oldPath, newPath) => { + provider.event.register('fileRenamed', async (oldPath) => { const path = extractParentFromKey(oldPath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileRenamedSuccess(path, oldPath, data)) }) + provider.event.register('fileExternallyChanged', async (path: string, file: { content: string }) => { + const config = registry.get('config').api + const editor = registry.get('editor').api + + if (config.get('currentFile') === path && editor.currentContent() !== file.content) { + if (provider.isReadOnly(path)) return editor.setText(file.content) + dispatch(displayNotification( + path + ' changed', + 'This file has been changed outside of Remix IDE.', + 'Replace by the new content', 'Keep the content displayed in Remix', + () => { + editor.setText(file.content) + } + )) + } + }) + provider.event.register('fileRenamedError', async () => { + dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel')) + }) + provider.event.register('rootFolderChanged', async () => { + fetchDirectory(provider, workspaceName)(dispatch) + }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) - dispatch(setPlugin(plugin)) } else { dispatch(fetchProviderError('No provider available')) } @@ -222,13 +243,6 @@ export const setCurrentWorkspace = (name: string) => { } } -export const setPlugin = (plugin) => { - return { - type: 'SET_PLUGIN', - payload: plugin - } -} - export const addInputFieldSuccess = (path: string, files: File[]) => { return { type: 'ADD_INPUT_FIELD', @@ -257,3 +271,20 @@ export const removeInputFieldSuccess = (path: string) => { export const removeInputField = (path: string) => (dispatch: React.Dispatch) => { return dispatch(removeInputFieldSuccess(path)) } + +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 closeNotificationModal = () => (dispatch: React.Dispatch) => { + dispatch(hideNotification()) +} 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 820699b95d..a83b81d044 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -108,7 +108,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { - init(props.filesProvider, props.name, props.plugin)(dispatch) + init(props.filesProvider, props.name, props.plugin, props.registry)(dispatch) } }, [props.filesProvider]) @@ -120,6 +120,18 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [fileSystem.provider.provider]) + useEffect(() => { + if (fileSystem.notification.message) { + modal(fileSystem.notification.title, fileSystem.notification.message, { + label: fileSystem.notification.labelOk, + fn: fileSystem.notification.actionOk + }, { + label: fileSystem.notification.labelCancel, + fn: fileSystem.notification.actionCancel + }) + } + }, [fileSystem.notification.message]) + useEffect(() => { if (state.focusEdit.element) { setTimeout(() => { @@ -140,14 +152,6 @@ export const FileExplorer = (props: FileExplorerProps) => { })() }, [name]) - // useEffect(() => { - // if (state.fileManager) { - // filesProvider.event.register('fileExternallyChanged', fileExternallyChanged) - // filesProvider.event.register('fileRenamedError', fileRenamedError) - // filesProvider.event.register('rootFolderChanged', rootFolderChanged) - // } - // }, [state.fileManager]) - useEffect(() => { if (focusRoot) { setState(prevState => { @@ -312,42 +316,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const fileExternallyChanged = (path: string, file: { content: string }) => { - const config = registry.get('config').api - const editor = registry.get('editor').api - - if (config.get('currentFile') === path && editor.currentContent() !== file.content) { - if (filesProvider.isReadOnly(path)) return editor.setText(file.content) - modal(path + ' changed', 'This file has been changed outside of Remix IDE.', { - label: 'Replace by the new content', - fn: () => { - editor.setText(file.content) - } - }, { - label: 'Keep the content displayed in Remix', - fn: () => {} - }) - } - } - - // register to event of the file provider - // files.event.register('fileRenamed', fileRenamed) - const fileRenamedError = (error: string) => { - modal('File Renamed Failed', error, { - label: 'Close', - fn: () => {} - }, null) - } - - // register to event of the file provider - // files.event.register('rootFolderChanged', rootFolderChanged) - const rootFolderChanged = async () => { - const files = await fetchDirectoryContent(name) - setState(prevState => { - return { ...prevState, files } - }) - } - const uploadFile = (target) => { const filesProvider = fileSystem.provider.provider // TODO The file explorer is merely a view on the current state of diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 99b4fcb8d0..df4475108e 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -20,11 +20,13 @@ export const fileSystemInitialState = { isSuccessful: false, error: null }, - plugin: { - plugin: null, - isRequesting: false, - isSuccessful: false, - error: null + notification: { + title: null, + message: null, + actionOk: () => {}, + actionCancel: () => {}, + labelOk: null, + labelCancel: null } } @@ -141,18 +143,6 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } - case 'SET_PLUGIN': { - return { - ...state, - plugin: { - ...state.plugin, - plugin: action.payload, - isRequesting: false, - isSuccessful: true, - error: null - } - } - } case 'ADD_INPUT_FIELD': { return { ...state, @@ -227,6 +217,25 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'DISPLAY_NOTIFICATION': { + return { + ...state, + notification: { + title: action.payload.title, + message: action.payload.message, + actionOk: action.payload.actionOk || fileSystemInitialState.notification.actionOk, + actionCancel: action.payload.actionCancel || fileSystemInitialState.notification.actionCancel, + labelOk: action.payload.labelOk, + labelCancel: action.payload.labelCancel + } + } + } + case 'HIDE_NOTIFICATION': { + return { + ...state, + notification: fileSystemInitialState.notification + } + } default: throw new Error() } diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts b/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts deleted file mode 100644 index e69de29bb2..0000000000 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 61c554dc3a..17d6975414 100644 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts @@ -6,7 +6,7 @@ export interface FileExplorerProps { menuItems?: string[], plugin: any, focusRoot: boolean, - contextMenuItems: { name: string, type: string[], path: string[], extension: string[], pattern: string[] }[], + contextMenuItems: { id: string, name: string, type: string[], path: string[], extension: string[], pattern: string[] }[], displayInput?: boolean, externalUploads?: EventTarget & HTMLInputElement }