diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
index 986034c39d..76c365c3b4 100644
--- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
+++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx
@@ -1,7 +1,6 @@
import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line
import './remix-ui-home-tab.css'
-import JSZip from 'jszip'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import PluginButton from './components/pluginButton' // eslint-disable-line
@@ -176,46 +175,6 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
const startPluginManager = async () => {
plugin.verticalIcons.select('pluginManager')
}
- 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) {
- const 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
- }
- const downloadFiles = async () => {
- try {
- plugin.call('notification', 'toast', 'preparing files for download, please wait..')
- const zip = new JSZip()
- zip.file("readme.txt", "This is a Remix backup file.\nThis zip should be used by the restore backup tool in Remix.\nThe .workspaces directory contains your workspaces.")
- const browserProvider = fileManager.getProvider('browser')
- await browserProvider.copyFolderToJson('/', ({ path, content }) => {
- zip.file(path, content)
- })
- zip.generateAsync({ type: 'blob' }).then(function (blob) {
- const today = new Date()
- const date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate()
- const time = today.getHours() + 'h' + today.getMinutes() + 'min'
- saveAs(blob, `remix-backup-at-${time}-${date}.zip`)
- _paq.push(['trackEvent', 'Backup', 'download', 'home'])
- }).catch((e) => {
- _paq.push(['trackEvent', 'Backup', 'error', e.message])
- plugin.call('notification', 'toast', e.message)
- })
- } catch (e) {
- plugin.call('notification', 'toast', e.message)
- }
- }
const restoreBackupZip = async () => {
await plugin.appManager.activatePlugin(['restorebackupzip'])
@@ -336,10 +295,6 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {
-
-
-
-
diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts
index 7e1a47e43a..ed1b47ce39 100644
--- a/libs/remix-ui/workspace/src/lib/actions/index.ts
+++ b/libs/remix-ui/workspace/src/lib/actions/index.ts
@@ -5,13 +5,14 @@ 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 { listenOnPluginEvents, listenOnProviderEvents } from './events'
import { createWorkspaceTemplate, getWorkspaces, loadWorkspacePreset, setPlugin } from './workspace'
+import { QueryParams } from '@remix-project/remix-lib'
+import JSZip from 'jszip'
export * from './events'
export * from './workspace'
-import { QueryParams } from '@remix-project/remix-lib'
-
const queryParams = new QueryParams()
+const _paq = window._paq = window._paq || []
let plugin, dispatch: React.Dispatch
@@ -269,6 +270,33 @@ export const handleExpandPath = (paths: string[]) => {
dispatch(setExpandPath(paths))
}
+export const handleDownloadFiles = async () => {
+ try {
+ plugin.call('notification', 'toast', 'preparing files for download, please wait..')
+ const zip = new JSZip()
+
+ zip.file("readme.txt", "This is a Remix backup file.\nThis zip should be used by the restore backup tool in Remix.\nThe .workspaces directory contains your workspaces.")
+ const browserProvider = plugin.fileManager.getProvider('browser')
+
+ await browserProvider.copyFolderToJson('/', ({ path, content }) => {
+ zip.file(path, content)
+ })
+ zip.generateAsync({ type: 'blob' }).then(function (blob) {
+ const today = new Date()
+ const date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate()
+ const time = today.getHours() + 'h' + today.getMinutes() + 'min'
+
+ saveAs(blob, `remix-backup-at-${time}-${date}.zip`)
+ _paq.push(['trackEvent', 'Backup', 'download', 'home'])
+ }).catch((e) => {
+ _paq.push(['trackEvent', 'Backup', 'error', e.message])
+ plugin.call('notification', 'toast', e.message)
+ })
+ } catch (e) {
+ plugin.call('notification', 'toast', e.message)
+ }
+}
+
const packageGistFiles = async (directory) => {
const workspaceProvider = plugin.fileProviders.workspace
const isFile = await workspaceProvider.isFile(directory)
@@ -344,3 +372,23 @@ const getOriginalFiles = async (id) => {
const data = await res.json()
return data.files || []
}
+
+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) {
+ const 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
+}
diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts
index 1aedce98b5..cb0d3a758b 100644
--- a/libs/remix-ui/workspace/src/lib/contexts/index.ts
+++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts
@@ -27,5 +27,6 @@ export const FileSystemContext = createContext<{
dispatchRunScript: (path: string) => Promise,
dispatchEmitContextMenuEvent: (cmd: customAction) => Promise,
dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise
- dispatchHandleExpandPath: (paths: string[]) => Promise
+ dispatchHandleExpandPath: (paths: string[]) => Promise,
+ dispatchHandleDownloadFiles: () => Promise
}>(null)
diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
index 904ed7cade..3803e34c14 100644
--- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
+++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
@@ -5,7 +5,7 @@ import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { FileSystemContext } from '../contexts'
import { browserReducer, browserInitialState } from '../reducers/workspace'
-import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, 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, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles } from '../actions'
import { Modal, WorkspaceProps } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Workspace } from '../remix-ui-workspace'
@@ -115,6 +115,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await handleExpandPath(paths)
}
+ const dispatchHandleDownloadFiles = async () => {
+ await handleDownloadFiles()
+ }
+
useEffect(() => {
dispatchInitWorkspace()
}, [])
@@ -214,7 +218,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchRunScript,
dispatchEmitContextMenuEvent,
dispatchHandleClickFile,
- dispatchHandleExpandPath
+ dispatchHandleExpandPath,
+ dispatchHandleDownloadFiles
}
return (
diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
index a51224f86c..11eec79c16 100644
--- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
@@ -50,6 +50,14 @@ export function Workspace () {
global.modal('Delete Current Workspace', 'Are you sure to delete the current workspace?', 'OK', onFinishDeleteWorkspace, '')
}
+ const downloadWorkspaces = async () => {
+ try {
+ await global.dispatchHandleDownloadFiles()
+ } catch (e) {
+ console.error(e)
+ }
+ }
+
const onFinishRenameWorkspace = async () => {
if (workspaceRenameInput.current === undefined) return
// @ts-ignore: Object is possibly 'null'.
@@ -156,9 +164,20 @@ export function Workspace () {
e.stopPropagation()
deleteCurrentWorkspace()
}}
- className='fas fa-trash'
+ className='fas fa-trash remixui_menuicon'
title='Delete'>
+ {
+ e.stopPropagation()
+ downloadWorkspaces()
+ }}
+ className='far fa-download remixui_menuicon'
+ title='Download Workspaces'>
+