openethereum/js/packages/dapp-console/Snippets/snippets.store.js

250 lines
4.6 KiB
JavaScript
Raw Normal View History

// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import keycode from 'keycode';
import { action, computed, map, observable, transaction } from 'mobx';
import store from 'store';
import { evaluate } from '../utils';
const LS_SNIPPETS_KEY = '_console::snippets';
let instance;
export default class SnippetsStore {
@observable files = map();
@observable nextName = null;
@observable renaming = null;
@observable selected = null;
codeMirror = null;
constructor () {
this.load();
}
static get () {
if (!instance) {
instance = new SnippetsStore();
}
return instance;
}
@computed
get code () {
if (!this.selected) {
return '';
}
return this.files.get(this.selected).content;
}
@action
cancelRename () {
if (!this.renaming || !this.nextName) {
return;
}
this.renaming = null;
this.nextName = null;
}
clearCodeHistory () {
if (this.codeMirror) {
this.codeMirror.doc.clearHistory();
}
}
@action
create () {
const id = this.getNewId();
const file = {
content: '',
isPristine: false,
name: `Snippet #${id}`,
id
};
transaction(() => {
this.files.set(id, file);
this.select(id);
});
}
edit (value) {
if (!this.selected) {
this.create();
}
const file = this.files.get(this.selected);
file.content = value;
this.updateFile(file);
}
evaluate () {
const code = this.code;
if (!code) {
return;
}
const { result, error } = evaluate(code);
if (error) {
console.error(error);
} else {
console.log(result);
}
}
getFromStorage () {
return store.get(LS_SNIPPETS_KEY) || [];
}
getNewId () {
if (this.files.size === 0) {
return 1;
}
const ids = this.files.values().map((file) => file.id);
return Math.max(...ids) + 1;
}
load () {
const files = this.getFromStorage();
transaction(() => {
files.forEach((file) => {
this.files.set(file.id, file);
});
});
}
@action
remove (id) {
transaction(() => {
if (id === this.selected) {
this.selected = null;
}
this.files.delete(id);
const files = this.getFromStorage()
.filter((f) => f.id !== id);
return store.set(LS_SNIPPETS_KEY, files);
});
}
save (_file) {
let file;
if (!_file) {
if (!this.selected) {
return false;
}
file = this.files.get(this.selected);
} else {
file = _file;
}
file.savedContent = file.content;
this.updateFile(file);
this.saveToStorage(file);
}
saveName () {
if (!this.renaming || !this.nextName) {
return;
}
const file = this.files.get(this.renaming);
file.name = this.nextName;
this.save(file);
this.cancelRename();
}
saveToStorage (file) {
const files = this.getFromStorage();
const index = files.findIndex((f) => file.id === f.id);
if (index === -1) {
files.push(file);
} else {
files[index] = file;
}
return store.set(LS_SNIPPETS_KEY, files);
}
@action
select (id) {
this.selected = id;
// Wait for the file content to be loaded
setTimeout(() => {
this.clearCodeHistory();
}, 50);
}
setCodeMirror (codeMirror) {
this.codeMirror = codeMirror;
if (!codeMirror) {
return;
}
this.codeMirror
.on('keydown', (_, event) => {
const codeName = keycode(event);
if (codeName === 'enter' && event.ctrlKey) {
event.preventDefault();
event.stopPropagation();
return this.evaluate();
}
});
}
@action
startRename (id) {
const file = this.files.get(id);
transaction(() => {
this.renaming = id;
this.nextName = file.name;
});
}
@action
updateFile (file) {
file.isPristine = (file.content === file.savedContent);
this.files.set(file.id, file);
}
@action
updateName (value) {
this.nextName = value;
}
}