recent workspaces WIP

fixinganerror
lianahus 2 years ago
parent 3ee974daf7
commit 72deb9284b
  1. 6
      apps/remix-ide/src/app/files/fileManager.ts
  2. 19
      apps/remix-ide/src/app/panels/file-panel.js
  3. 1
      apps/remix-ide/src/app/tabs/locales/en/home.json
  4. 1
      apps/remix-ide/src/app/tabs/locales/zh/home.json
  5. 6
      apps/remix-ide/src/remixAppManager.js
  6. 165
      libs/remix-ui/home-tab/src/lib/components/homeTabFile.tsx
  7. 22
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx

@ -206,11 +206,11 @@ class FileManager extends Plugin {
path = this.normalize(path) path = this.normalize(path)
path = this.limitPluginScope(path) path = this.limitPluginScope(path)
if (await this.exists(path)) { if (await this.exists(path)) {
await this._handleIsFile(path, `Cannot write file ${path}`) const newPath = await helper.createNonClashingNameAsync(path, this)
return await this.setFileContent(path, data) //await this._handleIsFile(path, `Cannot write file ${path}`)
return await this.setFileContent(newPath, data)
} else { } else {
const ret = await this.setFileContent(path, data) const ret = await this.setFileContent(path, data)
this.emit('fileAdded', path)
return ret return ret
} }
} catch (e) { } catch (e) {

@ -163,14 +163,31 @@ module.exports = class Filepanel extends ViewPlugin {
}) })
} }
saveRecent (workspace) {
console.log("recentWorkspaces - ", workspace)
if (!localStorage.getItem('recentWorkspaces')) {
localStorage.setItem('recentWorkspaces', JSON.stringify('"first": "", "second": "", "third": ""'))
} else {
console.log("recentWorkspaces workspace name - ", workspace.name)
const recents = JSON.parse(localStorage.getItem('recentWorkspaces'))
let newResents = '{"first": "' + workspace.name + '", "second":"' + recents.first + '", "third":"' + recents.second + '"}'
localStorage.setItem('recentWorkspaces', newResents)
}
}
setWorkspace (workspace) { setWorkspace (workspace) {
const workspaceProvider = this.fileProviders.workspace const workspaceProvider = this.fileProviders.workspace
const current = this.currentWorkspaceMetadata
this.currentWorkspaceMetadata = { name: workspace.name, isLocalhost: workspace.isLocalhost, absolutePath: `${workspaceProvider.workspacesPath}/${workspace.name}` } this.currentWorkspaceMetadata = { name: workspace.name, isLocalhost: workspace.isLocalhost, absolutePath: `${workspaceProvider.workspacesPath}/${workspace.name}` }
if (workspace.name !== " - connect to localhost - ") { if (workspace.name !== " - connect to localhost - ") {
localStorage.setItem('currentWorkspace', workspace.name) localStorage.setItem('currentWorkspace', workspace.name)
} }
this.emit('setWorkspace', workspace) this.emit('setWorkspace', workspace)
if (this.currentWorkspaceMetadata.name !== current) {
this.saveRecent(workspace)
}
} }
workspaceRenamed (oldName, workspaceName) { workspaceRenamed (oldName, workspaceName) {

@ -56,6 +56,7 @@
"home.searchDocumentation": "Search Documentation", "home.searchDocumentation": "Search Documentation",
"home.files": "Files", "home.files": "Files",
"home.newFile": "New File", "home.newFile": "New File",
"home.startCoding": "Start Coding",
"home.openFile": "Open File", "home.openFile": "Open File",
"home.accessFileSystem": "Access File System", "home.accessFileSystem": "Access File System",
"home.loadFrom": "Load from", "home.loadFrom": "Load from",

@ -54,6 +54,7 @@
"home.searchDocumentation": "搜索文档", "home.searchDocumentation": "搜索文档",
"home.files": "文件", "home.files": "文件",
"home.newFile": "新建文件", "home.newFile": "新建文件",
"home.startCoding": "Start Coding",
"home.openFile": "打开本地文件", "home.openFile": "打开本地文件",
"home.connectToLocalhost": "连接本地主机", "home.connectToLocalhost": "连接本地主机",
"home.loadFrom": "从以下来源导入", "home.loadFrom": "从以下来源导入",

@ -5,8 +5,7 @@ import {IframePlugin} from '@remixproject/engine-web'
const _paq = (window._paq = window._paq || []) const _paq = (window._paq = window._paq || [])
// requiredModule removes the plugin from the plugin manager list on UI // requiredModule removes the plugin from the plugin manager list on UI
const requiredModules = [ const requiredModules = [ // services + layout views + system views
// services + layout views + system views
'manager', 'manager',
'config', 'config',
'compilerArtefacts', 'compilerArtefacts',
@ -73,7 +72,8 @@ const requiredModules = [
'solidityumlgen', 'solidityumlgen',
'contractflattener', 'contractflattener',
'solidity-script', 'solidity-script',
'openaigpt' 'openaigpt',
'home'
] ]
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd) // dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)

@ -1,12 +1,12 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import React, {useState, useRef, useReducer} from 'react' import React, {useState, useRef, useReducer, useEffect} from 'react'
import {FormattedMessage} from 'react-intl' import {FormattedMessage} from 'react-intl'
import {ModalDialog} from '@remix-ui/modal-dialog' // eslint-disable-line import {ModalDialog} from '@remix-ui/modal-dialog' // eslint-disable-line
import {Toaster} from '@remix-ui/toaster' // eslint-disable-line import {Toaster} from '@remix-ui/toaster' // eslint-disable-line
const _paq = (window._paq = window._paq || []) // eslint-disable-line const _paq = window._paq = window._paq || [] // eslint-disable-line
import {CustomTooltip} from '@remix-ui/helper' import {CustomTooltip} from '@remix-ui/helper';
interface HomeTabFileProps { interface HomeTabFileProps {
plugin: any plugin: any
} }
@ -27,28 +27,50 @@ const loadingReducer = (state = loadingInitialState, action) => {
function HomeTabFile({plugin}: HomeTabFileProps) { function HomeTabFile({plugin}: HomeTabFileProps) {
const [state, setState] = useState<{ const [state, setState] = useState<{
searchInput: string searchInput: string,
showModalDialog: boolean showModalDialog: boolean,
modalInfo: { modalInfo: {
title: string title: string,
loadItem: string loadItem: string,
examples: Array<string> examples: Array<string>,
prefix?: string prefix?: string
},
importSource: string,
toasterMsg: string,
recentWorkspaces: {
first: string,
second: string,
third: string
} }
importSource: string
toasterMsg: string
}>({ }>({
searchInput: '', searchInput: '',
showModalDialog: false, showModalDialog: false,
modalInfo: {title: '', loadItem: '', examples: [], prefix: ''}, modalInfo: {title: '', loadItem: '', examples: [], prefix: ''},
importSource: '', importSource: '',
toasterMsg: '' toasterMsg: '',
recentWorkspaces: {first: '', second: '', third: ''}
}) })
const [, dispatch] = useReducer(loadingReducer, loadingInitialState) const [, dispatch] = useReducer(loadingReducer, loadingInitialState)
const inputValue = useRef(null) const inputValue = useRef(null)
useEffect(() => {
console.log("useEffHomeFile")
plugin.on('filePanel', 'setWorkspace', async () => {
let recents = JSON.parse(localStorage.getItem('recentWorkspaces'))
console.log("useEffHomeFilerecents ", recents)
if (!recents) recents = {first:'', second: '', third: ''}
setState(prevState => {
return { ...prevState, recentWorkspaces: { first: recents.first, second: recents.second, third: recents.third } }
})
})
return () => {
plugin.off('filePanel', 'setWorkspace')
}
}, [])
const processLoading = (type: string) => { const processLoading = (type: string) => {
_paq.push(['trackEvent', 'hometab', 'filesSection', 'importFrom' + type]) _paq.push(['trackEvent', 'hometab', 'filesSection', 'importFrom' + type])
const contentImport = plugin.contentImport const contentImport = plugin.contentImport
@ -90,10 +112,18 @@ function HomeTabFile({plugin}: HomeTabFileProps) {
}) })
} }
const createNewFile = async () => { const startCoding = async () => {
_paq.push(['trackEvent', 'hometab', 'filesSection', 'createNewFile']) _paq.push(['trackEvent', 'hometab', 'filesSection', 'startCoding'])
plugin.verticalIcons.select('filePanel') plugin.verticalIcons.select('filePanel')
await plugin.call('filePanel', 'createNewFile') const content = `
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract helloWorld {
}
`
await plugin.call('fileManager', 'writeFile', '/helloWorld.sol', content)
await plugin.call('fileManager', 'open', '/helloWorld.sol')
} }
const uploadFile = async (target) => { const uploadFile = async (target) => {
@ -133,11 +163,16 @@ function HomeTabFile({plugin}: HomeTabFileProps) {
}) })
} }
const handleSwichToRecentWorkspace = async (e, workspaceName) => {
e.preventDefault();
await plugin.call('filePanel', 'setWorkspace', { name: workspaceName, isLocalhost: false })
console.log('The link was clicked.');
}
const examples = state.modalInfo.examples.map((urlEl, key) => ( const examples = state.modalInfo.examples.map((urlEl, key) => (
<div key={key} className="p-1 user-select-auto"> <div key={key} className="p-1 user-select-auto">
<a>{urlEl}</a> <a>{urlEl}</a>
</div> </div>))
))
return ( return (
<> <>
@ -178,42 +213,68 @@ function HomeTabFile({plugin}: HomeTabFileProps) {
</ModalDialog> </ModalDialog>
<Toaster message={state.toasterMsg} /> <Toaster message={state.toasterMsg} />
<div className="justify-content-start mt-1 p-2 d-flex flex-column" id="hTFileSection"> <div className="justify-content-start mt-1 p-2 d-flex flex-column" id="hTFileSection">
<label style={{fontSize: '1.2rem'}}> <label style={{fontSize: "1.2rem"}}><FormattedMessage id='home.files' /></label>
<FormattedMessage id="home.files" /> <div className="d-flex flex-column">
</label> <div className='d-flex flex-row'>
<div className="dflex"> <button className="btn btn-primary p-2 mr-2 border my-1" data-id="homeTabStartCoding" style={{width: 'fit-content'}} onClick={() => startCoding()}><FormattedMessage id='home.startCoding' /></button>
<button className="btn btn-primary p-2 mr-2 border my-1" data-id="homeTabNewFile" style={{width: 'fit-content'}} onClick={() => createNewFile()}> <CustomTooltip
<FormattedMessage id="home.newFile" /> placement={'top'}
</button> tooltipId="overlay-tooltip"
<label className="btn p-2 mr-2 border my-1" style={{width: 'fit-content', cursor: 'pointer'}} htmlFor="openFileInput"> tooltipClasses="text-nowrap"
<FormattedMessage id="home.openFile" /> tooltipText={<FormattedMessage id='home.openFile' />}
</label> tooltipTextClasses="border bg-light text-dark p-1 pr-3"
<input >
title="open file" <span>
type="file" <label className="btn p-2 mr-2 border my-1" style={{width: 'fit-content', cursor: 'pointer'}} htmlFor="openFileInput">
id="openFileInput" <FormattedMessage id='home.openFile' />
onChange={(event) => { </label>
event.stopPropagation() <input
plugin.verticalIcons.select('filePanel') title="open file"
uploadFile(event.target) type="file"
}} id="openFileInput"
multiple onChange={
/> (event) => {
<CustomTooltip event.stopPropagation()
placement={'top'} plugin.verticalIcons.select('filePanel')
tooltipId="overlay-tooltip" uploadFile(event.target)
tooltipClasses="text-nowrap" }}
tooltipText={<FormattedMessage id="home.connectToLocalhost" />} multiple
tooltipTextClasses="border bg-light text-dark p-1 pr-3" />
> </span>
<button className="btn p-2 border my-1" style={{width: 'fit-content'}} onClick={() => connectToLocalhost()}> </CustomTooltip>
<FormattedMessage id="home.accessFileSystem" />
</button> <CustomTooltip
</CustomTooltip> placement={'top'}
tooltipId="overlay-tooltip"
tooltipClasses="text-nowrap"
tooltipText={<FormattedMessage id="home.connectToLocalhost" />}
tooltipTextClasses="border bg-light text-dark p-1 pr-3"
>
<button className="btn p-2 border my-1" style={{width: 'fit-content'}} onClick={() => connectToLocalhost()}>
<FormattedMessage id="home.accessFileSystem" />
</button>
</CustomTooltip>
</div>
<div className='d-flex flex-column'>
<label style={{fontSize: "0.8rem"}} className='mt-3'>Recent workspaces</label>
<a
className='cursor-pointer mb-1 ml-2'
href="#"
onClick={(e) => handleSwichToRecentWorkspace(e, state.recentWorkspaces.first)}>{state.recentWorkspaces.first}
</a>
<a
className='cursor-pointer mb-1 ml-2'
href="#"
onClick={(e) => handleSwichToRecentWorkspace(e, state.recentWorkspaces.second)}>{state.recentWorkspaces.second}
</a>
<a
className='cursor-pointer ml-2'
href="#"
onClick={(e) => handleSwichToRecentWorkspace(e, state.recentWorkspaces.third)}>{state.recentWorkspaces.third}
</a>
</div>
</div> </div>
<label style={{fontSize: '0.8rem'}} className="pt-2"> <label style={{fontSize: "0.8rem"}} className="pt-3"><FormattedMessage id='home.loadFrom' /></label>
<FormattedMessage id="home.loadFrom" />
</label>
<div className="d-flex"> <div className="d-flex">
<button <button
className="btn p-2 border mr-2" className="btn p-2 border mr-2"

@ -107,18 +107,18 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
<WorkspaceTemplate <WorkspaceTemplate
gsID="sUTLogo" gsID="sUTLogo"
workspaceTitle="Gnosis Safe MultiSig" workspaceTitle="Gnosis Safe MultiSig"
description={intl.formatMessage({ description={
id: 'home.gnosisSafeMultisigTemplateDesc' intl.formatMessage({ id: 'home.gnosisSafeMultisigTemplateDesc' })
})} }
callback={() => createWorkspace('gnosisSafeMultisig')} callback={() => createWorkspace("gnosisSafeMultisig")}
/> />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sUTLogo" gsID="sUTLogo"
workspaceTitle="0xProject ERC20" workspaceTitle="0xProject ERC20"
description={intl.formatMessage({ description={
id: 'home.zeroxErc20TemplateDesc' intl.formatMessage({ id: 'home.zeroxErc20TemplateDesc' })
})} }
callback={() => createWorkspace('zeroxErc20')} callback={() => createWorkspace("zeroxErc20")}
/> />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sourcifyLogo" gsID="sourcifyLogo"
@ -132,7 +132,7 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
description={intl.formatMessage({ description={intl.formatMessage({
id: 'home.ozerc721TemplateDesc' id: 'home.ozerc721TemplateDesc'
})} })}
callback={() => createWorkspace('ozerc721')} callback={() => createWorkspace("ozerc721")}
/> />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sUTLogo" gsID="sUTLogo"
@ -140,7 +140,7 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
description={intl.formatMessage({ description={intl.formatMessage({
id: 'home.ozerc1155TemplateDesc' id: 'home.ozerc1155TemplateDesc'
})} })}
callback={() => createWorkspace('ozerc1155')} callback={() => createWorkspace("ozerc1155")}
/> />
<WorkspaceTemplate <WorkspaceTemplate
gsID="solhintLogo" gsID="solhintLogo"
@ -148,7 +148,7 @@ function HomeTabGetStarted({plugin}: HomeTabGetStartedProps) {
description={intl.formatMessage({ description={intl.formatMessage({
id: 'home.remixDefaultTemplateDesc' id: 'home.remixDefaultTemplateDesc'
})} })}
callback={() => createWorkspace('remixDefault')} callback={() => createWorkspace("remixDefault")}
/> />
</Carousel> </Carousel>
</ThemeContext.Provider> </ThemeContext.Provider>

Loading…
Cancel
Save