mirror of https://github.com/embarklabs/embark.git
Merge pull request #152 from status-im/feature/editor-tabs
Add editor tabs
This commit is contained in:
commit
1862848105
|
@ -282,7 +282,7 @@ export const files = {
|
|||
export const FILE = createRequestTypes('FILE');
|
||||
export const file = {
|
||||
request: (file) => action(FILE[REQUEST], file),
|
||||
success: (file) => action(FILE[SUCCESS], file),
|
||||
success: (file) => action(FILE[SUCCESS], {file}),
|
||||
failure: (error) => action(FILE[FAILURE], {error})
|
||||
};
|
||||
|
||||
|
@ -300,20 +300,6 @@ export const removeFile = {
|
|||
failure: (error) => action(REMOVE_FILE[FAILURE], {error})
|
||||
};
|
||||
|
||||
export const CURRENT_FILE = createRequestTypes('CURRENT_FILE');
|
||||
export const currentFile = {
|
||||
request: () => action(CURRENT_FILE[REQUEST]),
|
||||
success: (file) => action(CURRENT_FILE[SUCCESS], {currentFiles: [file]}),
|
||||
failure: () => action(CURRENT_FILE[FAILURE])
|
||||
};
|
||||
|
||||
export const SAVE_CURRENT_FILE = createRequestTypes('SAVE_CURRENT_FILE');
|
||||
export const saveCurrentFile = {
|
||||
request: (file) => action(SAVE_CURRENT_FILE[REQUEST], file),
|
||||
success: (file) => action(SAVE_CURRENT_FILE[SUCCESS], {currentFiles: [file]}),
|
||||
failure: () => action(SAVE_CURRENT_FILE[FAILURE])
|
||||
};
|
||||
|
||||
export const GAS_ORACLE = createRequestTypes('GAS_ORACLE');
|
||||
export const gasOracle = {
|
||||
request: () => action(GAS_ORACLE[REQUEST]),
|
||||
|
@ -410,6 +396,27 @@ export const debuggerInfo = {
|
|||
success: (data) => action(DEBUGGER_INFO[SUCCESS], {data})
|
||||
};
|
||||
|
||||
export const FETCH_EDITOR_TABS = createRequestTypes('FETCH_EDITOR_TABS');
|
||||
export const fetchEditorTabs = {
|
||||
request: () => action(FETCH_EDITOR_TABS[REQUEST]),
|
||||
success: (editorTabs) => action(FETCH_EDITOR_TABS[SUCCESS], {editorTabs}),
|
||||
failure: () => action(FETCH_EDITOR_TABS[FAILURE])
|
||||
};
|
||||
|
||||
export const ADD_EDITOR_TABS = createRequestTypes('ADD_EDITOR_TABS');
|
||||
export const addEditorTabs = {
|
||||
request: (file) => action(ADD_EDITOR_TABS[REQUEST], {file}),
|
||||
success: () => action(ADD_EDITOR_TABS[SUCCESS]),
|
||||
failure: () => action(ADD_EDITOR_TABS[FAILURE])
|
||||
};
|
||||
|
||||
export const REMOVE_EDITOR_TABS = createRequestTypes('REMOVE_EDITOR_TABS');
|
||||
export const removeEditorTabs = {
|
||||
request: (file) => action(REMOVE_EDITOR_TABS[REQUEST], {file}),
|
||||
success: () => action(REMOVE_EDITOR_TABS[SUCCESS]),
|
||||
failure: () => action(REMOVE_EDITOR_TABS[FAILURE])
|
||||
};
|
||||
|
||||
// Web Socket
|
||||
export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS';
|
||||
export const STOP_NEW_PROCESS_LOGS = 'STOP_NEW_PROCESS_LOGS';
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import ReactJson from "react-json-view";
|
||||
import {Row, Col, Table} from "reactstrap";
|
||||
import {formatContractForDisplay} from '../utils/presentation';
|
||||
import {Row, Col} from "reactstrap";
|
||||
import CopyButton from './CopyButton';
|
||||
|
||||
const ContractDetail = ({contract}) => {
|
||||
const contractDisplay = formatContractForDisplay(contract);
|
||||
return (
|
||||
<Row>
|
||||
<Col>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import * as monaco from 'monaco-editor';
|
||||
import PropTypes from 'prop-types';
|
||||
import FontAwesomeIcon from 'react-fontawesome';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import './TextEditor.css';
|
||||
|
||||
|
@ -40,7 +42,7 @@ class TextEditor extends React.Component {
|
|||
|
||||
editor.onMouseDown((e) => {
|
||||
if (e.target.type === GUTTER_GLYPH_MARGIN){
|
||||
this.props.toggleBreakpoint(this.props.file.name, e.target.position.lineNumber);
|
||||
this.props.toggleBreakpoint(this.props.currentFile.name, e.target.position.lineNumber);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -49,7 +51,10 @@ class TextEditor extends React.Component {
|
|||
|
||||
|
||||
getLanguage() {
|
||||
const extension = this.props.file.name.split('.').pop();
|
||||
if (!this.props.currentFile.name) {
|
||||
return DEFAULT_LANGUAGE;
|
||||
}
|
||||
const extension = this.props.currentFile.name.split('.').pop();
|
||||
return SUPPORTED_LANGUAGES[SUPPORTED_LANGUAGES.indexOf(extension)] || DEFAULT_LANGUAGE;
|
||||
}
|
||||
|
||||
|
@ -112,8 +117,8 @@ class TextEditor extends React.Component {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.file.content !== prevProps.file.content) {
|
||||
editor.setValue(this.props.file.content);
|
||||
if (this.props.currentFile.content && this.props.currentFile.content !== prevProps.currentFile.content) {
|
||||
editor.setValue(this.props.currentFile.content);
|
||||
}
|
||||
|
||||
this.updateMarkers();
|
||||
|
@ -125,9 +130,23 @@ class TextEditor extends React.Component {
|
|||
this.handleResize();
|
||||
}
|
||||
|
||||
renderTabs() {
|
||||
return (
|
||||
<ul className="list-inline m-0 p-2">
|
||||
{this.props.editorTabs.map(file => (
|
||||
<li key={file.name} className={classNames("list-inline-item", "border-right", "p-2", { 'bg-dark': file.name === this.props.currentFile.name })}>
|
||||
<a className="text-white no-underline" href='#switch-tab' onClick={() => this.props.addEditorTabs(file)}>{file.name}</a>
|
||||
<FontAwesomeIcon onClick={() => this.props.removeEditorTabs(file)} className="mx-1" name="close" />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="h-100 d-flex flex-column">
|
||||
{this.renderTabs()}
|
||||
<div style={{height: '100%'}} id={EDITOR_ID} />
|
||||
</div>
|
||||
)
|
||||
|
@ -136,10 +155,13 @@ class TextEditor extends React.Component {
|
|||
|
||||
TextEditor.propTypes = {
|
||||
onFileContentChange: PropTypes.func,
|
||||
file: PropTypes.object,
|
||||
currentFile: PropTypes.object,
|
||||
toggleBreakpoint: PropTypes.func,
|
||||
breakpoints: PropTypes.array,
|
||||
debuggerLine: PropTypes.number
|
||||
debuggerLine: PropTypes.number,
|
||||
editorTabs: PropTypes.array,
|
||||
removeEditorTabs: PropTypes.func,
|
||||
addEditorTabs: PropTypes.func
|
||||
};
|
||||
|
||||
export default TextEditor;
|
||||
|
|
|
@ -13,8 +13,6 @@ const TextEditorToolbar = (props) => (
|
|||
</Label>
|
||||
</Col>
|
||||
<Col sm={4} md={6}>
|
||||
<strong>{props.currentFile.name}</strong>
|
||||
<span className="mx-2">|</span>
|
||||
<Button color="success" size="sm" onClick={props.save}>
|
||||
<FontAwesomeIcon className="mr-2" name="save"/>
|
||||
Save
|
||||
|
@ -55,7 +53,6 @@ const TextEditorToolbar = (props) => (
|
|||
);
|
||||
|
||||
TextEditorToolbar.propTypes = {
|
||||
currentFile: PropTypes.object,
|
||||
isContract: PropTypes.bool,
|
||||
save: PropTypes.func,
|
||||
remove: PropTypes.func,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.editor--grid {
|
||||
margin-left: -30px !important;
|
||||
margin-right: -30px !important;
|
||||
background-color: #1C1C1C;
|
||||
}
|
|
@ -6,13 +6,11 @@ import TextEditorAsideContainer from './TextEditorAsideContainer';
|
|||
import TextEditorContainer from './TextEditorContainer';
|
||||
import FileExplorerContainer from './FileExplorerContainer';
|
||||
import TextEditorToolbarContainer from './TextEditorToolbarContainer';
|
||||
import {currentFile as currentFileAction} from '../actions';
|
||||
import {fetchEditorTabs as fetchEditorTabsAction} from '../actions';
|
||||
import {getCurrentFile} from '../reducers/selectors';
|
||||
|
||||
import './EditorContainer.css';
|
||||
|
||||
const DEFAULT_FILE = {name: 'newContract.sol', content: ''};
|
||||
|
||||
class EditorContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -20,9 +18,7 @@ class EditorContainer extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if(this.props.currentFile.content === '') {
|
||||
this.props.fetchCurrentFile();
|
||||
}
|
||||
this.props.fetchEditorTabs();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
|
@ -32,7 +28,7 @@ class EditorContainer extends React.Component {
|
|||
}
|
||||
|
||||
isContract() {
|
||||
return this.state.currentFile.name.endsWith('.sol');
|
||||
return this.state.currentFile.name && this.state.currentFile.name.endsWith('.sol');
|
||||
}
|
||||
|
||||
onFileContentChange(newContent) {
|
||||
|
@ -84,7 +80,7 @@ class EditorContainer extends React.Component {
|
|||
}
|
||||
|
||||
function mapStateToProps(state, props) {
|
||||
const currentFile = getCurrentFile(state) || DEFAULT_FILE;
|
||||
const currentFile = getCurrentFile(state);
|
||||
|
||||
return {
|
||||
currentFile
|
||||
|
@ -93,11 +89,11 @@ function mapStateToProps(state, props) {
|
|||
|
||||
EditorContainer.propTypes = {
|
||||
currentFile: PropTypes.object,
|
||||
fetchCurrentFile: PropTypes.func
|
||||
fetchEditorTabs: PropTypes.func
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{fetchCurrentFile: currentFileAction.request},
|
||||
{fetchEditorTabs: fetchEditorTabsAction.request},
|
||||
)(EditorContainer);
|
||||
|
||||
|
|
|
@ -3,23 +3,39 @@ import {connect} from 'react-redux';
|
|||
import PropTypes from 'prop-types';
|
||||
import TextEditor from '../components/TextEditor';
|
||||
import {
|
||||
addEditorTabs as addEditorTabsAction,
|
||||
fetchEditorTabs as fetchEditorTabsAction,
|
||||
removeEditorTabs as removeEditorTabsAction,
|
||||
toggleBreakpoint,
|
||||
} from '../actions';
|
||||
|
||||
import {getCurrentFile, getContractCompile, getContractDeploys, getBreakpointsByFilename, getDebuggerLine} from '../reducers/selectors';
|
||||
import {getCurrentFile, getContractCompile, getContractDeploys, getBreakpointsByFilename, getDebuggerLine, getEditorTabs} from '../reducers/selectors';
|
||||
|
||||
const TextEditorContainer = (props) => (
|
||||
<TextEditor file={props.currentFile}
|
||||
breakpoints={props.breakpoints}
|
||||
toggleBreakpoint={props.toggleBreakpoint}
|
||||
debuggerLine={props.debuggerLine}
|
||||
onFileContentChange={props.onFileContentChange} />
|
||||
)
|
||||
class TextEditorContainer extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.fetchEditorTabs();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TextEditor file={this.props.currentFile}
|
||||
currentFile={this.props.currentFile}
|
||||
breakpoints={this.props.breakpoints}
|
||||
toggleBreakpoint={this.props.toggleBreakpoint}
|
||||
editorTabs={this.props.editorTabs}
|
||||
removeEditorTabs={this.props.removeEditorTabs}
|
||||
addEditorTabs={this.props.addEditorTabs}
|
||||
debuggerLine={this.props.debuggerLine}
|
||||
onFileContentChange={this.props.onFileContentChange} />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state, props) {
|
||||
const breakpoints = getBreakpointsByFilename(state, props.currentFile.name);
|
||||
const editorTabs = getEditorTabs(state);
|
||||
const debuggerLine = getDebuggerLine(state);
|
||||
return {breakpoints, debuggerLine};
|
||||
return {breakpoints, editorTabs, debuggerLine};
|
||||
}
|
||||
|
||||
TextEditorContainer.propTypes = {
|
||||
|
@ -27,10 +43,18 @@ TextEditorContainer.propTypes = {
|
|||
onFileContentChange: PropTypes.func,
|
||||
toggleBreakpoints: PropTypes.func,
|
||||
breakpoints: PropTypes.array,
|
||||
toggleBreakpoint: PropTypes.object
|
||||
toggleBreakpoint: PropTypes.object,
|
||||
fetchEditorTabs: PropTypes.func,
|
||||
removeEditorTabs: PropTypes.func,
|
||||
addEditorTabs: PropTypes.func
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{toggleBreakpoint},
|
||||
{
|
||||
toggleBreakpoint,
|
||||
fetchEditorTabs: fetchEditorTabsAction.request,
|
||||
removeEditorTabs: removeEditorTabsAction.request,
|
||||
addEditorTabs: addEditorTabsAction.request
|
||||
},
|
||||
)(TextEditorContainer);
|
||||
|
|
|
@ -73,3 +73,7 @@
|
|||
background-image: url(images/icons.png);
|
||||
}
|
||||
|
||||
.no-underline {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import {combineReducers} from 'redux';
|
|||
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
||||
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH, DEBUGGER_INFO,
|
||||
SIGN_MESSAGE, VERIFY_MESSAGE, TOGGLE_BREAKPOINT,
|
||||
UPDATE_DEPLOYMENT_PIPELINE, WEB3_CONNECT, WEB3_DEPLOY, WEB3_ESTIMAGE_GAS} from "../actions";
|
||||
UPDATE_DEPLOYMENT_PIPELINE, WEB3_CONNECT, WEB3_DEPLOY, WEB3_ESTIMAGE_GAS, FETCH_EDITOR_TABS} from "../actions";
|
||||
import {EMBARK_PROCESS_NAME, DARK_THEME, DEPLOYMENT_PIPELINES, DEFAULT_HOST} from '../constants';
|
||||
|
||||
const BN_FACTOR = 10000;
|
||||
|
@ -31,7 +31,6 @@ const entitiesDefaultState = {
|
|||
ensRecords: [],
|
||||
files: [],
|
||||
gasOracleStats: [],
|
||||
currentFiles: []
|
||||
};
|
||||
|
||||
const sorter = {
|
||||
|
@ -80,7 +79,7 @@ const sorter = {
|
|||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const filtrer = {
|
||||
|
@ -354,6 +353,13 @@ function debuggerInfo(state={}, action) {
|
|||
return state;
|
||||
}
|
||||
|
||||
function editorTabs(state = [], action) {
|
||||
if (action.type === FETCH_EDITOR_TABS[SUCCESS] && action.editorTabs) {
|
||||
return action.editorTabs;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
entities,
|
||||
loading,
|
||||
|
@ -368,9 +374,9 @@ const rootReducer = combineReducers({
|
|||
breakpoints,
|
||||
deploymentPipeline,
|
||||
web3,
|
||||
searchResult,
|
||||
debuggerInfo,
|
||||
theme
|
||||
theme,
|
||||
editorTabs
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
|
|
|
@ -170,7 +170,7 @@ export function getFiles(state) {
|
|||
}
|
||||
|
||||
export function getCurrentFile(state) {
|
||||
return last(state.entities.currentFiles);
|
||||
return state.editorTabs.find(file => file.active) || {};
|
||||
}
|
||||
|
||||
export function getBaseEther(state) {
|
||||
|
@ -234,3 +234,6 @@ export function getDebuggerLine(state) {
|
|||
return state.debuggerInfo.sources.lineColumnPos[0].start.line + 1;
|
||||
}
|
||||
|
||||
export function getEditorTabs(state) {
|
||||
return state.editorTabs
|
||||
}
|
||||
|
|
|
@ -79,9 +79,6 @@ export const debugStepIntoBackward = doRequest.bind(null, actions.debugStepIntoB
|
|||
export const toggleBreakpoint = doRequest.bind(null, actions.toggleBreakpoint, api.toggleBreakpoint);
|
||||
export const authenticate = doRequest.bind(null, actions.authenticate, api.authenticate);
|
||||
|
||||
export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile);
|
||||
export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile);
|
||||
export const deleteCurrentFile = doRequest.bind(null, null, storage.deleteCurrentFile);
|
||||
export const fetchCredentials = doRequest.bind(null, actions.fetchCredentials, storage.fetchCredentials);
|
||||
export const saveCredentials = doRequest.bind(null, actions.saveCredentials, storage.saveCredentials);
|
||||
export const logout = doRequest.bind(null, actions.logout, storage.logout);
|
||||
|
@ -89,6 +86,9 @@ export const changeTheme = doRequest.bind(null, actions.changeTheme, storage.cha
|
|||
export const fetchTheme = doRequest.bind(null, actions.fetchTheme, storage.fetchTheme);
|
||||
export const signMessage = doRequest.bind(null, actions.signMessage, api.signMessage);
|
||||
export const verifyMessage = doRequest.bind(null, actions.verifyMessage, api.verifyMessage);
|
||||
export const fetchEditorTabs = doRequest.bind(null, actions.fetchEditorTabs, storage.fetchEditorTabs);
|
||||
export const addEditorTabs = doRequest.bind(null, actions.addEditorTabs, storage.addEditorTabs);
|
||||
export const removeEditorTabs = doRequest.bind(null, actions.removeEditorTabs, storage.removeEditorTabs);
|
||||
|
||||
export const explorerSearch = searchExplorer.bind(null, actions.explorerSearch);
|
||||
|
||||
|
@ -208,25 +208,17 @@ export function *watchPostFile() {
|
|||
yield takeEvery(actions.SAVE_FILE[actions.REQUEST], postFile);
|
||||
}
|
||||
|
||||
export function *watchPostFileSuccess() {
|
||||
yield takeEvery(actions.SAVE_FILE[actions.SUCCESS], postCurrentFile);
|
||||
}
|
||||
|
||||
export function *watchDeleteFile() {
|
||||
yield takeEvery(actions.REMOVE_FILE[actions.REQUEST], deleteFile);
|
||||
}
|
||||
|
||||
export function *watchDeleteFileSuccess() {
|
||||
yield takeEvery(actions.REMOVE_FILE[actions.SUCCESS], fetchFiles);
|
||||
yield takeEvery(actions.REMOVE_FILE[actions.SUCCESS], deleteCurrentFile);
|
||||
yield takeEvery(actions.REMOVE_FILE[actions.SUCCESS], removeEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchFetchFileSuccess() {
|
||||
yield takeEvery(actions.FILE[actions.SUCCESS], postCurrentFile);
|
||||
}
|
||||
|
||||
export function *watchFetchCurrentFile() {
|
||||
yield takeEvery(actions.CURRENT_FILE[actions.REQUEST], fetchCurrentFile);
|
||||
yield takeEvery(actions.FILE[actions.SUCCESS], addEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchFetchEthGas() {
|
||||
|
@ -313,6 +305,26 @@ export function *watchUpdateDeploymentPipeline() {
|
|||
yield takeEvery(actions.UPDATE_DEPLOYMENT_PIPELINE, web3Connect);
|
||||
}
|
||||
|
||||
export function *watchFetchEditorTabs() {
|
||||
yield takeEvery(actions.FETCH_EDITOR_TABS[actions.REQUEST], fetchEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchAddEditorTabs() {
|
||||
yield takeEvery(actions.ADD_EDITOR_TABS[actions.REQUEST], addEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchRemoveEditorTabs() {
|
||||
yield takeEvery(actions.REMOVE_EDITOR_TABS[actions.REQUEST], removeEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchAddEditorTabsSuccess() {
|
||||
yield takeEvery(actions.ADD_EDITOR_TABS[actions.SUCCESS], fetchEditorTabs);
|
||||
}
|
||||
|
||||
export function *watchRemoveEditorTabsSuccess() {
|
||||
yield takeEvery(actions.REMOVE_EDITOR_TABS[actions.SUCCESS], fetchEditorTabs);
|
||||
}
|
||||
|
||||
function createChannel(socket) {
|
||||
return eventChannel(emit => {
|
||||
socket.onmessage = ((message) => {
|
||||
|
@ -494,8 +506,6 @@ export default function *root() {
|
|||
fork(watchDeleteFile),
|
||||
fork(watchDeleteFileSuccess),
|
||||
fork(watchFetchFileSuccess),
|
||||
fork(watchFetchCurrentFile),
|
||||
fork(watchPostFileSuccess),
|
||||
fork(watchFetchCredentials),
|
||||
fork(watchFetchEthGas),
|
||||
fork(watchStartDebug),
|
||||
|
@ -518,6 +528,11 @@ export default function *root() {
|
|||
fork(watchWeb3EstimateGas),
|
||||
fork(watchWeb3Deploy),
|
||||
fork(watchUpdateDeploymentPipeline),
|
||||
fork(watchListenDebugger)
|
||||
fork(watchListenDebugger),
|
||||
fork(watchFetchEditorTabs),
|
||||
fork(watchAddEditorTabs),
|
||||
fork(watchRemoveEditorTabs),
|
||||
fork(watchAddEditorTabsSuccess),
|
||||
fork(watchRemoveEditorTabsSuccess),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,34 @@
|
|||
export function postCurrentFile(file) {
|
||||
export function addEditorTabs({file}) {
|
||||
return new Promise(resolve => {
|
||||
localStorage.setItem('currentFile', JSON.stringify(file));
|
||||
resolve({response: {data: file}});
|
||||
const editorTabs = findOrCreateEditorTabs();
|
||||
editorTabs.forEach(f => f.active = false);
|
||||
const alreadyAddedFile = editorTabs.find(f => f.name === file.name)
|
||||
if (alreadyAddedFile) {
|
||||
alreadyAddedFile.active = true
|
||||
} else {
|
||||
file.active = true
|
||||
editorTabs.push(file);
|
||||
}
|
||||
localStorage.setItem('editorTabs', JSON.stringify(editorTabs));
|
||||
resolve({response: {data: editorTabs}});
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchCurrentFile() {
|
||||
export function fetchEditorTabs() {
|
||||
return new Promise(resolve => {
|
||||
resolve({response: {data: JSON.parse(localStorage.getItem('currentFile'))}});
|
||||
resolve({response: {data: JSON.parse(localStorage.getItem('editorTabs'))}});
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteCurrentFile() {
|
||||
export function removeEditorTabs({file}) {
|
||||
return new Promise(resolve => {
|
||||
localStorage.removeItem('currentFile');
|
||||
resolve({});
|
||||
const editorTabs = findOrCreateEditorTabs();
|
||||
const filtered = editorTabs.filter(value => value.name !== file.name);
|
||||
if (file.active && filtered.length) {
|
||||
filtered[0].active = true;
|
||||
}
|
||||
localStorage.setItem('editorTabs', JSON.stringify(filtered));
|
||||
resolve({response: {data: filtered}});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -50,3 +64,8 @@ export function changeTheme({theme}) {
|
|||
export function fetchTheme() {
|
||||
return new Promise(resolve => resolve({response: {data: localStorage.getItem('theme')}}));
|
||||
}
|
||||
|
||||
|
||||
function findOrCreateEditorTabs() {
|
||||
return JSON.parse(localStorage.getItem('editorTabs')) || [];
|
||||
}
|
Loading…
Reference in New Issue