Skip to content

Commit

Permalink
fix: replace terminal component
Browse files Browse the repository at this point in the history
  • Loading branch information
mvines committed Jul 3, 2019
1 parent 5068c22 commit ff9d8a8
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 186 deletions.
7 changes: 4 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ module.exports = {
ecmaVersion: 8,
},
rules: {
'react/sort-comp': 0,
'arrow-parens': ['error', 'as-needed'],
'import/extensions': 0,
'import/no-extraneous-dependencies': 0,
'import/no-unresolved': [2, {ignore: ['electron']}],
'import/prefer-default-export': 0,
'linebreak-style': ['error', 'unix'],
'no-console': 0,
'object-curly-spacing': ['error', 'never'],
'import/prefer-default-export': 0,
'react/prefer-stateless-function': 0,
'arrow-parens': ['error', 'as-needed'],
'react/sort-comp': 0,
},
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@material-ui/icons": "^4.2.1",
"@material-ui/lab": "^4.0.0-alpha.18",
"@solana/web3.js": "^0.16.10",
"autoscroll-react": "^3.2.0",
"console-feed": "^2.8.8",
"electron-compile": "^6.4.4",
"electron-devtools-installer": "^2.1.0",
"electron-log": "^3.0.6",
Expand All @@ -40,10 +42,10 @@
"node-fetch": "^2.6.0",
"npm-run-all": "^4.1.5",
"promisify-child-process": "^3.1.0",
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hot-loader": "^4.12.0",
"react-terminal-component": "^1.4.1",
"update-electron-app": "solana-labs/update-electron-app#nagUser"
},
"devDependencies": {
Expand Down
125 changes: 53 additions & 72 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,19 @@ import TextField from '@material-ui/core/TextField';
import Typography from '@material-ui/core/Typography';
import log from 'electron-log';
import {Connection, PublicKey} from '@solana/web3.js';
import {EmulatorState, OutputFactory, Outputs} from 'javascript-terminal';
import {ReactThemes, ReactTerminal} from 'react-terminal-component';
import {withStyles} from '@material-ui/core/styles';
import Store from 'electron-store';
import IconButton from '@material-ui/core/IconButton';
import SaveIcon from '@material-ui/icons/Save';
import autoscroll from 'autoscroll-react';
import {Hook, Console, Decode} from 'console-feed';

import {url} from './url';
import {Replicator} from './replicator';

const styles = theme => ({
root: {
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
height: '100%',
},
main: {
marginTop: theme.spacing(2),
Expand Down Expand Up @@ -64,6 +62,28 @@ function isValidPublicKey(publicKey) {
);
}

class LogConsole extends React.Component {
render() {
return (
<div
style={{
backgroundColor: '#242424',
height: '450px',
overflow: 'scroll',
}}
>
<div style={{width: '1000%'}}>
<Console logs={this.props.logs} variant="dark" />
</div>
</div>
);
}
}
LogConsole.propTypes = {
logs: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

// eslint-disable-next-line react/no-multi-comp
class App extends React.Component {
constructor(props) {
super(props);
Expand All @@ -75,28 +95,37 @@ class App extends React.Component {
transactionCount: 0,
totalMined: this.store.get('totalMined', 0),
newMined: 0,
logs: [],
totalSupply: 0,
enabled: this.store.get('enabled', true),
unsavedDepositPublicKey: this.depositPublicKey,
unsavedDepositPublicKeyValid: isValidPublicKey(this.depositPublicKey),
unsavedDepositPublicKeySavePrompt: false,
depositPublicKeyBalance: ' ',
};
}

componentDidMount() {
Hook(console, newLog => {
const logs = [...this.state.logs, Decode(newLog)];
const max = 1024;
if (logs.length > max) {
logs.splice(0, logs.length - max);
}
this.setState({logs});
});
this.connection = new Connection(url);
log.info('connection:', url);

this.clearTerminal();
this.addTerminalText(`Cluster entrypoint: ${url}...`);
log.info(`Cluster entrypoint: ${url}...`);

this.replicator = new Replicator(this.connection, this);
this.replicator = new Replicator(this.connection);
if (this.state.enabled) {
this.replicator.start();
} else {
this.addTerminalText('Mining disabled');
console.warn('Mining disabled');
}
}

componentDidMount() {
this.updateClusterStats();
this.id = setInterval(() => this.updateClusterStats(), 10000);
}
Expand All @@ -105,57 +134,12 @@ class App extends React.Component {
clearInterval(this.id);
}

trimTerminalOutput() {
const count = this.terminalOutputs.count();
if (count > this.terminalHeight) {
this.terminalOutputs = this.terminalOutputs.splice(
0,
count - this.terminalHeight,
);
}
this.setState({});
}

addTerminalCommand(command) {
log.info('term$ ', command);
this.terminalOutputs = Outputs.addRecord(
this.terminalOutputs,
OutputFactory.makeHeaderOutput('', command),
);
this.trimTerminalOutput();
}

addTerminalText(text) {
text.split('\n').forEach(line => {
log.info('term> ', line);
this.terminalOutputs = Outputs.addRecord(
this.terminalOutputs,
OutputFactory.makeTextOutput(line),
);
});
this.trimTerminalOutput();
}

addTerminalError(errorMessage) {
errorMessage.split('\n').forEach(line => {
log.info('TERM> ', line);
this.terminalOutputs = Outputs.addRecord(
this.terminalOutputs,
OutputFactory.makeErrorOutput({source: 'error', type: line}),
);
});
this.trimTerminalOutput();
}

clearTerminal() {
this.terminalOutputs = Outputs.create(
new Array(this.terminalHeight).fill(OutputFactory.makeTextOutput(' ')),
);
this.trimTerminalOutput();
this.setState({logs: []});
}

clusterRestart() {
this.addTerminalText(`Cluster restart detected at ${new Date()}`);
console.warn(`Cluster restart detected at ${new Date()}`);
this.replicator.clusterRestart();
this.setState({
transactionCount: 0,
Expand All @@ -168,7 +152,7 @@ class App extends React.Component {
const transactionCount = await this.connection.getTransactionCount();

if (transactionCount < this.state.transactionCount / 2) {
this.addTerminalText(
console.warn(
`Transaction count decreased from ${this.state.transactionCount} to ${transactionCount}`,
);
this.clusterRestart();
Expand Down Expand Up @@ -212,8 +196,7 @@ class App extends React.Component {
depositPublicKeyBalance,
});
} catch (err) {
log.error('updateClusterStats failed', err);
this.addTerminalError(`updateClusterStats failed: ${err.message}`);
console.warn('updateClusterStats failed', err);
}
}

Expand All @@ -222,6 +205,7 @@ class App extends React.Component {
this.store.set('enabled', enabled);
this.setState({enabled});
if (enabled) {
this.clearTerminal();
this.replicator.start();
} else {
this.replicator.stop();
Expand Down Expand Up @@ -277,15 +261,15 @@ class App extends React.Component {
render() {
const {classes} = this.props;

const AutoscrollLogConsole = autoscroll(LogConsole, {
isScrolledDownThreshold: 0,
});

// eslint-disable-next-line no-restricted-properties
const totalSupplySOL = (this.state.totalSupply / Math.pow(2, 34)).toFixed(
2,
);

const emulatorState = EmulatorState.createEmpty().setOutputs(
this.terminalOutputs,
);

return (
<div className={classes.root}>
<CssBaseline />
Expand Down Expand Up @@ -370,7 +354,7 @@ class App extends React.Component {
</Grid>
</Grid>
</Container>
<footer className={classes.footer}>
<div className={classes.footer}>
<Container className={classes.summary}>
<Grid container spacing={1}>
<Grid item xs>
Expand Down Expand Up @@ -400,16 +384,13 @@ class App extends React.Component {
value={100}
className={classes.progressBar}
/>
<ReactTerminal
theme={{...ReactThemes.default, height: '50'}}
emulatorState={emulatorState}
acceptInput={false}
/>
</footer>
<AutoscrollLogConsole logs={this.state.logs} />
</div>
</div>
);
}
}

App.propTypes = {
classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};
Expand Down
15 changes: 14 additions & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,21 @@
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
html {
height: 100%;
}
body {
height: 100%;
overflow: hidden;
}
#App {
height: 100%;
width: 100%;
}
</style>
</head>
<body style="overflow: hidden; background-color: rgba(0,0,0,0); margin: 0" >
<body>
<div id="App"></div>
</body>

Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ app.on('ready', async () => {
const devModeExtra = isDevMode ? 200 : 0;
mainWindow = new BrowserWindow({
width: 1000 + devModeExtra,
height: 820,
height: 830,
resizable: isDevMode,
webPreferences: {
nodeIntegration: true,
},
});

mainWindow.loadURL(`file://${__dirname}/index.html`);
Expand Down
14 changes: 7 additions & 7 deletions src/replicator.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import {solanaInstallInit} from './solana-install-init';
const airdropAmount = 100000;

export class Replicator {
constructor(connection, terminalOutput) {
constructor(connection) {
const userDataPath = electron.remote.app.getPath('userData');

Object.assign(this, {
connection,
terminalOutput,
running: false,
mainPromise: Promise.resolve(),
cmdCancel: () => undefined,
Expand Down Expand Up @@ -49,7 +48,7 @@ export class Replicator {
return;
}
this.running = false;
this.terminalOutput.addTerminalText('^C');
console.warn('^C');
this.cmdCancel();
await this.mainPromise;
}
Expand Down Expand Up @@ -107,16 +106,17 @@ export class Replicator {
* @private
*/
async cmd(command, args) {
this.terminalOutput.addTerminalCommand(`${command} ${args.join(' ')}`);
console.log(`$ ${command} ${args.join(' ')}`);
log.info(`$ ${command} ${args.join(' ')}`);
const env = Object.assign({}, {RUST_LOG: 'solana=info'}, process.env);
const child = spawn(command, args, {env});
log.info(`pid ${child.pid}`);

child.stdout.on('data', data =>
this.terminalOutput.addTerminalText(data.toString()),
console.log(data.toString().replace(/\n+$/, '')),
);
child.stderr.on('data', data =>
this.terminalOutput.addTerminalText(data.toString()),
console.log(data.toString().replace(/\n+$/, '')),
);
return Promise.race([
child,
Expand Down Expand Up @@ -200,7 +200,7 @@ export class Replicator {
this.replicatorLedgerDir,
]);
} catch (err) {
this.terminalOutput.addTerminalError(err.message);
console.error(err.message);
}

if (!this.running) {
Expand Down
Loading

0 comments on commit ff9d8a8

Please sign in to comment.