Commit 3a57fc43 authored by gxkai's avatar gxkai

chore: 下载空间

parent 2e7a02fd
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
THE SOFTWARE. THE SOFTWARE.
--> -->
<meta http-equiv="X-UA-Compatible" content="chrome=1"> <meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Remix - Ethereum IDE</title> <title>Baas IDE</title>
<link rel="stylesheet" href="assets/css/pygment_trac.css"> <link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="icon" type="x-icon" href="assets/img/icon.png"> <link rel="icon" type="x-icon" href="assets/img/icon.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css">
<script src="assets/js/browserfs.min.js"></script> <script src="assets/js/browserfs.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!-- Matomo --> <!-- Matomo -->
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
} }
const defaultVersion = '0.8.0' const defaultVersion = '0.8.0'
let versionToLoad = urlParams().appVersion ? urlParams().appVersion : defaultVersion let versionToLoad = urlParams().appVersion ? urlParams().appVersion : defaultVersion
let assets = { let assets = {
'0.8.0': ['https://use.fontawesome.com/releases/v5.8.1/css/all.css', 'assets/css/pygment_trac.css'], '0.8.0': ['https://use.fontawesome.com/releases/v5.8.1/css/all.css', 'assets/css/pygment_trac.css'],
'0.7.7': ['assets/css/font-awesome.min.css', 'assets/css/pygment_trac.css'] '0.7.7': ['assets/css/font-awesome.min.css', 'assets/css/pygment_trac.css']
......
...@@ -5,12 +5,15 @@ import { customAction } from '@remixproject/plugin-api/lib/file-system/file-pane ...@@ -5,12 +5,15 @@ import { customAction } from '@remixproject/plugin-api/lib/file-system/file-pane
import { displayNotification, displayPopUp, fetchDirectoryError, fetchDirectoryRequest, fetchDirectorySuccess, focusElement, fsInitializationCompleted, hidePopUp, removeInputFieldSuccess, setCurrentWorkspace, setExpandPath, setMode, setWorkspaces } from './payload' import { displayNotification, displayPopUp, fetchDirectoryError, fetchDirectoryRequest, fetchDirectorySuccess, focusElement, fsInitializationCompleted, hidePopUp, removeInputFieldSuccess, setCurrentWorkspace, setExpandPath, setMode, setWorkspaces } from './payload'
import { listenOnPluginEvents, listenOnProviderEvents } from './events' import { listenOnPluginEvents, listenOnProviderEvents } from './events'
import { createWorkspaceTemplate, getWorkspaces, loadWorkspacePreset, setPlugin } from './workspace' import { createWorkspaceTemplate, getWorkspaces, loadWorkspacePreset, setPlugin } from './workspace'
import JSZip from 'jszip'
export * from './events' export * from './events'
export * from './workspace' export * from './workspace'
const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params') const QueryParams = require('../../../../../../apps/remix-ide/src/lib/query-params')
const queryParams = new QueryParams() const queryParams = new QueryParams()
const globalRegistry = require('../../../../../../apps/remix-ide/src/global/registry')
const tooltip = require('../../../../../../apps/remix-ide/src/app/ui/tooltip')
let plugin, dispatch: React.Dispatch<any> let plugin, dispatch: React.Dispatch<any>
...@@ -215,6 +218,41 @@ export const publishToBaas = async (path?: string, type?: string) => { ...@@ -215,6 +218,41 @@ export const publishToBaas = async (path?: string, type?: string) => {
dispatch(displayNotification('Publish to gist Failed', 'Failed to create gist: ' + error.message, 'Close', null, async () => {})) dispatch(displayNotification('Publish to gist Failed', 'Failed to create gist: ' + error.message, 'Close', null, async () => {}))
} }
} }
const saveAs = (blob, name) => {
const node = document.createElement('a')
node.download = name
node.rel = 'noopener'
node.href = URL.createObjectURL(blob)
setTimeout(function () { URL.revokeObjectURL(node.href) }, 4E4) // 40s
setTimeout(function () {
try {
node.dispatchEvent(new MouseEvent('click'))
} catch (e) {
var evt = document.createEvent('MouseEvents')
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,
20, false, false, false, false, 0, null)
node.dispatchEvent(evt)
}
}, 0) // 40s
}
// todo 下载文件夹
export const downloadFile = async (folder?: string) => {
try {
tooltip('preparing files for download, please wait..')
const fileProviders = globalRegistry.get('fileproviders').api
const zip = new JSZip()
await fileProviders.browser.copyFolderToJson(`/`, ({ path, content }) => {
zip.file(`${folder}${path}`, content)
})
zip.generateAsync({ type: 'blob' }).then(function (blob) {
saveAs(blob, `${folder}.zip`)
}).catch((e) => {
tooltip(e.message)
})
} catch (e) {
tooltip(e.message)
}
}
export const clearPopUp = async () => { export const clearPopUp = async () => {
dispatch(hidePopUp()) dispatch(hidePopUp())
......
...@@ -25,6 +25,11 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { ...@@ -25,6 +25,11 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
icon: 'fa fa-upload' icon: 'fa fa-upload'
}, },
{ {
action: 'downloadFile',
title: 'export current workspace',
icon: 'fa fa-download'
},
{
action: 'updateGist', action: 'updateGist',
title: 'Update the current [gist] explorer', title: 'Update the current [gist] explorer',
icon: 'fab fa-github' icon: 'fab fa-github'
...@@ -78,7 +83,9 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => { ...@@ -78,7 +83,9 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
props.createNewFolder() props.createNewFolder()
} else if (action === 'publishToGist') { } else if (action === 'publishToGist') {
props.publishToGist() props.publishToGist()
} else { } else if (action === 'downloadFile') {
props.downloadFile()
}else {
state.actions[action]() state.actions[action]()
} }
}} }}
......
...@@ -176,6 +176,11 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -176,6 +176,11 @@ export const FileExplorer = (props: FileExplorerProps) => {
props.dispatchUploadFile(target, parentFolder) props.dispatchUploadFile(target, parentFolder)
} }
const downloadFile = () => {
const parentFolder = getFocusedFolder()
props.dispatchDownloadFile(parentFolder)
}
const copyFile = (src: string, dest: string) => { const copyFile = (src: string, dest: string) => {
try { try {
props.dispatchCopyFile(src, dest) props.dispatchCopyFile(src, dest)
...@@ -418,6 +423,7 @@ export const FileExplorer = (props: FileExplorerProps) => { ...@@ -418,6 +423,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
createNewFolder={handleNewFolderInput} createNewFolder={handleNewFolderInput}
publishToGist={publishToGist} publishToGist={publishToGist}
uploadFile={uploadFile} uploadFile={uploadFile}
downloadFile={downloadFile}
/> />
</div> </div>
} }
......
...@@ -18,6 +18,7 @@ export const FileSystemContext = createContext<{ ...@@ -18,6 +18,7 @@ export const FileSystemContext = createContext<{
dispatchDeleteWorkspace: (workspaceName: string) => Promise<void>, dispatchDeleteWorkspace: (workspaceName: string) => Promise<void>,
dispatchPublishToGist: (path?: string, type?: string) => Promise<void>, dispatchPublishToGist: (path?: string, type?: string) => Promise<void>,
dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>, dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchDownloadFile: (targetFolder?: string) => Promise<void>,
dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>, dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>,
dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>, dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>,
dispatchCreateNewFolder: (path: string, rootDir: string) => Promise<void>, dispatchCreateNewFolder: (path: string, rootDir: string) => Promise<void>,
......
...@@ -5,7 +5,33 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line ...@@ -5,7 +5,33 @@ import { Toaster } from '@remix-ui/toaster' // 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, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, publishToBaas, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from '../actions' import {
initWorkspace,
fetchDirectory,
removeInputField,
deleteWorkspace,
clearPopUp,
publishToGist,
publishToBaas,
createNewFile,
setFocusElement,
createNewFolder,
deletePath,
renamePath,
copyFile,
copyFolder,
runScript,
emitContextMenuEvent,
handleClickFile,
handleExpandPath,
addInputField,
createWorkspace,
fetchWorkspaceDirectory,
renameWorkspace,
switchToWorkspace,
uploadFile,
downloadFile
} from '../actions'
import { Modal, WorkspaceProps } from '../types' import { Modal, WorkspaceProps } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Workspace } from '../remix-ui-workspace' import { Workspace } from '../remix-ui-workspace'
...@@ -67,6 +93,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { ...@@ -67,6 +93,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await publishToGist(path, type) await publishToGist(path, type)
} }
const dispatchDownloadFile = async (path?: string) => {
await downloadFile(path)
}
// 上传到bass // 上传到bass
const dispatchPublishToBaas = async (path?: string, type?: string) => { const dispatchPublishToBaas = async (path?: string, type?: string) => {
await publishToBaas(path, type) await publishToBaas(path, type)
...@@ -220,7 +250,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { ...@@ -220,7 +250,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchRunScript, dispatchRunScript,
dispatchEmitContextMenuEvent, dispatchEmitContextMenuEvent,
dispatchHandleClickFile, dispatchHandleClickFile,
dispatchHandleExpandPath dispatchHandleExpandPath,
dispatchDownloadFile
} }
return ( return (
<FileSystemContext.Provider value={value}> <FileSystemContext.Provider value={value}>
......
...@@ -178,7 +178,7 @@ export function Workspace () { ...@@ -178,7 +178,7 @@ export function Workspace () {
{ (global.fs.mode === 'browser') && (currentWorkspace !== NO_WORKSPACE) && { (global.fs.mode === 'browser') && (currentWorkspace !== NO_WORKSPACE) &&
<FileExplorer <FileExplorer
name={currentWorkspace} name={currentWorkspace}
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']} menuItems={['createNewFile', 'createNewFolder', canUpload ? 'uploadFile' : '', 'downloadFile']}
contextMenuItems={global.fs.browser.contextMenu.registeredMenuItems} contextMenuItems={global.fs.browser.contextMenu.registeredMenuItems}
removedContextMenuItems={global.fs.browser.contextMenu.removedMenuItems} removedContextMenuItems={global.fs.browser.contextMenu.removedMenuItems}
files={global.fs.browser.files} files={global.fs.browser.files}
...@@ -196,6 +196,7 @@ export function Workspace () { ...@@ -196,6 +196,7 @@ export function Workspace () {
dispatchCopyFile={global.dispatchCopyFile} dispatchCopyFile={global.dispatchCopyFile}
dispatchCopyFolder={global.dispatchCopyFolder} dispatchCopyFolder={global.dispatchCopyFolder}
dispatchPublishToGist={global.dispatchPublishToGist} dispatchPublishToGist={global.dispatchPublishToGist}
dispatchDownloadFile={global.dispatchDownloadFile}
dispatchRunScript={global.dispatchRunScript} dispatchRunScript={global.dispatchRunScript}
dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent} dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent}
dispatchHandleClickFile={global.dispatchHandleClickFile} dispatchHandleClickFile={global.dispatchHandleClickFile}
...@@ -231,6 +232,7 @@ export function Workspace () { ...@@ -231,6 +232,7 @@ export function Workspace () {
dispatchCopyFile={global.dispatchCopyFile} dispatchCopyFile={global.dispatchCopyFile}
dispatchCopyFolder={global.dispatchCopyFolder} dispatchCopyFolder={global.dispatchCopyFolder}
dispatchPublishToGist={global.dispatchPublishToGist} dispatchPublishToGist={global.dispatchPublishToGist}
dispatchDownloadFile={global.dispatchDownloadFile}
dispatchRunScript={global.dispatchRunScript} dispatchRunScript={global.dispatchRunScript}
dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent} dispatchEmitContextMenuEvent={global.dispatchEmitContextMenuEvent}
dispatchHandleClickFile={global.dispatchHandleClickFile} dispatchHandleClickFile={global.dispatchHandleClickFile}
......
...@@ -80,6 +80,7 @@ export interface FileExplorerProps { ...@@ -80,6 +80,7 @@ export interface FileExplorerProps {
dispatchCopyFolder: (src: string, dest: string) => Promise<void>, dispatchCopyFolder: (src: string, dest: string) => Promise<void>,
dispatchRunScript: (path: string) => Promise<void>, dispatchRunScript: (path: string) => Promise<void>,
dispatchPublishToGist: (path?: string, type?: string) => Promise<void>, dispatchPublishToGist: (path?: string, type?: string) => Promise<void>,
dispatchDownloadFile: (path?: string, type?: string) => Promise<void>,
dispatchEmitContextMenuEvent: (cmd: customAction) => Promise<void>, dispatchEmitContextMenuEvent: (cmd: customAction) => Promise<void>,
dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void>, dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void>,
dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>, dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>,
...@@ -95,7 +96,8 @@ export interface FileExplorerMenuProps { ...@@ -95,7 +96,8 @@ export interface FileExplorerMenuProps {
createNewFile: (folder?: string) => void, createNewFile: (folder?: string) => void,
createNewFolder: (parentFolder?: string) => void, createNewFolder: (parentFolder?: string) => void,
publishToGist: (path?: string) => void, publishToGist: (path?: string) => void,
uploadFile: (target: EventTarget & HTMLInputElement) => void uploadFile: (target: EventTarget & HTMLInputElement) => void,
downloadFile: (fold?: string) => void,
} }
export interface FileExplorerContextMenuProps { export interface FileExplorerContextMenuProps {
actions: action[], actions: action[],
......
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