mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-10 06:52:05 +01:00
Simplify bitwisecmm (#16)
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import InputBox from './components/InputBox';
|
||||
import DisplayResultView from './components/DisplayResultView';
|
||||
import AppState from './core/AppState';
|
||||
import AppState, { CommandResultView } from './core/AppState';
|
||||
import cmd from './core/cmd';
|
||||
import CommandResult from './models/CommandResult';
|
||||
import log from 'loglevel';
|
||||
import Indicators from './components/Indicators';
|
||||
import CommandLink from './components/CommandLink';
|
||||
import hash from './core/hash';
|
||||
|
||||
type AppRootProps = {
|
||||
appState: AppState,
|
||||
@@ -15,7 +14,7 @@ type AppRootProps = {
|
||||
type AppRootState = {
|
||||
uiTheme: string,
|
||||
emphasizeBytes: boolean,
|
||||
commandResults: CommandResult[]
|
||||
commandResults: CommandResultView[]
|
||||
}
|
||||
|
||||
export default class AppRoot extends React.Component<AppRootProps, AppRootState> {
|
||||
@@ -35,7 +34,10 @@ export default class AppRoot extends React.Component<AppRootProps, AppRootState>
|
||||
|
||||
getResultViews() : JSX.Element[] {
|
||||
log.debug('getting result views')
|
||||
var results = this.state.commandResults.map((r, i) => <DisplayResultView key={i} content={r} input={r.input} inputHash={r.inputHash} appState={this.props.appState} />);
|
||||
var results = this.state.commandResults.map((r, i) =>
|
||||
<DisplayResultView key={r.key} input={r.input} inputHash={hash.encodeHash(r.input)} appState={this.props.appState}>
|
||||
{r.view}
|
||||
</DisplayResultView>);
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -66,7 +68,7 @@ export default class AppRoot extends React.Component<AppRootProps, AppRootState>
|
||||
<InputBox onCommandEntered={(input) => cmd.execute(input)} />
|
||||
|
||||
<span className="configPnl">
|
||||
<span id="emphasizeBytes" data-cmd="em" className={"indicator " + this.getIndicator(this.state.emphasizeBytes)} title="Toggle Emphasize Bytes" onClick={e => this.toggleEmphasizeBytes()}>[em]</span>
|
||||
<span id="emphasizeBytes" data-cmd="em" className={"indicator " + this.getIndicator(this.state.emphasizeBytes)} title="Toggle Emphasize Bytes" onClick={() => this.toggleEmphasizeBytes()}>[em]</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import HelpResult from './models/HelpResult';
|
||||
import AboutResult from './models/AboutResult';
|
||||
import UnknownCommandResult from './models/UnknownCommandResult';
|
||||
import ExpressionResult from './models/ExpressionResult';
|
||||
import {UnhandledErrorResult, ErrorResult} from './models/ErrorResults';
|
||||
import WahtsnewResult from './models/WhatsnewResult';
|
||||
import StringResult from './models/StringResult';
|
||||
import * as expression from './expression/expression';
|
||||
import React from 'react';
|
||||
import uuid from 'uuid/v4';
|
||||
import { CommandInput, CmdShell } from './core/cmd';
|
||||
import { ExpressionInput } from './expression/expression-interfaces';
|
||||
import AppState from './core/AppState';
|
||||
import {ParsingError, IpAddress, ipAddressParser, IpAddressWithSubnetMask, ParsedIpObject} from './ipaddress/ip'
|
||||
import IpAddressResult from './models/IpAddressResult';
|
||||
import { isGetAccessor, isPrefixUnaryExpression } from 'typescript';
|
||||
import ErrorResultView from './components/results/ErrorResultView';
|
||||
import HelpResultView from './components/results/HelpResultView';
|
||||
import AboutResultView from './components/results/AboutResultView';
|
||||
import WhatsnewResultView from './components/results/WhatsNewResultView';
|
||||
import TextResultView from './components/results/TextResultView';
|
||||
import IpAddressView from './components/results/IpAddressView';
|
||||
import UnknownInputResultView from './components/results/UnknownInputResultView';
|
||||
import BitwiseOperationExpressionView from './components/results/expressions/BitwiseOperationExpressionView';
|
||||
|
||||
export default {
|
||||
initialize (cmd: CmdShell, appState: AppState) {
|
||||
@@ -20,19 +19,19 @@ export default {
|
||||
cmd.debugMode = appState.debugMode;
|
||||
appState.onChange(() => cmd.debugMode = appState.debugMode);
|
||||
|
||||
cmd.command("help", (c: CommandInput) => appState.addCommandResult(new HelpResult(c.input)));
|
||||
cmd.command("clear", (c: CommandInput) => appState.clearCommandResults());
|
||||
cmd.command("em", (c: CommandInput) => appState.toggleEmphasizeBytes());
|
||||
cmd.command("dark", (c: CommandInput) => appState.setUiTheme('dark'));
|
||||
cmd.command("light", (c: CommandInput) => appState.setUiTheme('light'));
|
||||
cmd.command("midnight", (c: CommandInput) => appState.setUiTheme('midnight'));
|
||||
cmd.command("about", (c: CommandInput) => appState.addCommandResult(new AboutResult(c.input)));
|
||||
cmd.command("whatsnew", (c: CommandInput) => appState.addCommandResult(new WahtsnewResult(c.input)));
|
||||
cmd.command("guid", (c: CommandInput) => appState.addCommandResult(new StringResult(c.input, uuid())));
|
||||
cmd.command("-notrack", (c: CommandInput) => {});
|
||||
cmd.command("help", (c: CommandInput) => appState.addCommandResult(c.input, <HelpResultView />));
|
||||
cmd.command("clear", () => appState.clearCommandResults());
|
||||
cmd.command("em", () => appState.toggleEmphasizeBytes());
|
||||
cmd.command("dark", () => appState.setUiTheme('dark'));
|
||||
cmd.command("light", () => appState.setUiTheme('light'));
|
||||
cmd.command("midnight", () => appState.setUiTheme('midnight'));
|
||||
cmd.command("about", (c: CommandInput) => appState.addCommandResult(c.input, <AboutResultView />));
|
||||
cmd.command("whatsnew", (c: CommandInput) => appState.addCommandResult(c.input, <WhatsnewResultView />));
|
||||
cmd.command("guid", (c: CommandInput) => appState.addCommandResult(c.input, <TextResultView text={uuid()} />));
|
||||
cmd.command("-notrack", () => {});
|
||||
cmd.command("-debug", (c: CommandInput) => {
|
||||
appState.toggleDebugMode();
|
||||
appState.addCommandResult(new StringResult(c.input, `Debug Mode: ${appState.debugMode}`))
|
||||
appState.addCommandResult(c.input, <TextResultView text={`Debug Mode: ${appState.debugMode}`}/>);
|
||||
});
|
||||
|
||||
|
||||
@@ -46,7 +45,7 @@ export default {
|
||||
return;
|
||||
|
||||
if(result instanceof ParsingError) {
|
||||
appState.addCommandResult(new ErrorResult(c.input, result.errorMessage));
|
||||
appState.addCommandResult(c.input, <ErrorResultView errorMessage={result.errorMessage} />);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,7 +62,7 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
appState.addCommandResult(new IpAddressResult(c.input, ipAddresses));
|
||||
appState.addCommandResult(c.input, <IpAddressView ipAddresses={ipAddresses} />);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -72,16 +71,16 @@ export default {
|
||||
canHandle: (input:string) => expression.parser.canParse(input),
|
||||
handle: function(c: CommandInput) {
|
||||
var expr = expression.parser.parse(c.input);
|
||||
appState.addCommandResult(new ExpressionResult(c.input, expr as ExpressionInput));
|
||||
appState.addCommandResult(c.input, <BitwiseOperationExpressionView expression={expr!} emphasizeBytes={appState.emphasizeBytes} />);
|
||||
}
|
||||
})
|
||||
|
||||
// Last command handler reports that input is unknown
|
||||
cmd.command({
|
||||
canHandle: () => true,
|
||||
handle: (c: CommandInput) => appState.addCommandResult(new UnknownCommandResult(c.input))
|
||||
handle: (c: CommandInput) => appState.addCommandResult(c.input, <UnknownInputResultView input={c.input}/>)
|
||||
});
|
||||
|
||||
cmd.onError((input: string, err: Error) => appState.addCommandResult(new UnhandledErrorResult(input, err)));
|
||||
cmd.onError((input: string, err: Error) => appState.addCommandResult(input, <ErrorResultView errorMessage={err.toString()} />));
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,23 @@
|
||||
import React from 'react';
|
||||
import HelpResult from '../models/HelpResult';
|
||||
import AboutResult from '../models/AboutResult';
|
||||
import HelpResultView from './results/HelpResultView';
|
||||
import AboutResultView from './results/AboutResultView';
|
||||
import ExpressionResult from '../models/ExpressionResult';
|
||||
import BitwiseOperationExpressionView from './results/expressions/BitwiseOperationExpressionView';
|
||||
import WhatsnewResult from '../models/WhatsnewResult';
|
||||
import WhatsnewResultView from './results/WhatsNewResultView';
|
||||
import {UnhandledErrorResult, ErrorResult} from '../models/ErrorResults';
|
||||
import StringResult from '../models/StringResult';
|
||||
import IpAddressView from './results/IpAddressView';
|
||||
|
||||
import CommandResult from '../models/CommandResult';
|
||||
import AppState from '../core/AppState';
|
||||
import IpAddressResult from '../models/IpAddressResult';
|
||||
|
||||
|
||||
type DisplayResultProps = {
|
||||
content : CommandResult,
|
||||
appState: AppState,
|
||||
inputHash: string,
|
||||
input: string,
|
||||
key: number
|
||||
}
|
||||
|
||||
export default class DisplayResult extends React.Component<DisplayResultProps> {
|
||||
export default class DisplayResultView extends React.Component<DisplayResultProps> {
|
||||
render() {
|
||||
|
||||
return <div className="result">
|
||||
<div className="input mono"><span className="cur">></span>{this.props.content.input}<a className="hashLink" title="Link for this expression" href={window.location.pathname + '#' + this.props.inputHash}>#</a></div>
|
||||
<div className="input mono"><span className="cur">></span>{this.props.input}<a className="hashLink" title="Link for this expression" href={window.location.pathname + '#' + this.props.inputHash}>#</a></div>
|
||||
<div className="content">
|
||||
{this.findResultComponent(this.props.content)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
findResultComponent(result: CommandResult) : JSX.Element {
|
||||
|
||||
if(result instanceof HelpResult) {
|
||||
return <HelpResultView />
|
||||
}
|
||||
|
||||
if(result instanceof AboutResult) {
|
||||
return <AboutResultView />
|
||||
}
|
||||
|
||||
if(result instanceof ExpressionResult) {
|
||||
return <BitwiseOperationExpressionView expression={result.expression} emphasizeBytes={this.props.appState.emphasizeBytes} />
|
||||
}
|
||||
|
||||
if(result instanceof WhatsnewResult) {
|
||||
return <WhatsnewResultView />
|
||||
}
|
||||
|
||||
if(result instanceof StringResult) {
|
||||
return <p>{result.value}</p>
|
||||
}
|
||||
|
||||
if (result instanceof UnhandledErrorResult) {
|
||||
return <div className="result">
|
||||
<div className="error">(X_X) Ooops.. Something ain' right: <strong>{result.error.message}</strong></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
if (result instanceof ErrorResult) {
|
||||
return <div className="result">
|
||||
<div className="error">{result.errorMessage}</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
if(result instanceof IpAddressResult) {
|
||||
const ipResult = result as IpAddressResult;
|
||||
|
||||
return <IpAddressView ipAddresses={ipResult.ipAddresses} />
|
||||
}
|
||||
|
||||
return <div className="result">
|
||||
<div className="error">¯\_(ツ)_/¯ Sorry, i don′t know what <strong>{this.props.content.input}</strong> is</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
10
src/components/results/ErrorResultView.tsx
Normal file
10
src/components/results/ErrorResultView.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
function ErrorResultView(props : {errorMessage:string}) {
|
||||
|
||||
return <div className="result">
|
||||
<div className="error">{props.errorMessage}</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
export default ErrorResultView;
|
||||
7
src/components/results/TextResultView.tsx
Normal file
7
src/components/results/TextResultView.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
function TextResultView(props : { text: string }) {
|
||||
return <p>{props.text}</p>;
|
||||
}
|
||||
|
||||
export default TextResultView;
|
||||
10
src/components/results/UnknownInputResultView.tsx
Normal file
10
src/components/results/UnknownInputResultView.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
function UnknownInputResultView(props : {input:string}) {
|
||||
|
||||
return <div className="result">
|
||||
<div className="error">¯\_(ツ)_/¯ Sorry, i don′t know what <strong>{props.input}</strong> is</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
export default UnknownInputResultView;
|
||||
@@ -9,6 +9,12 @@ export type PersistedAppData = {
|
||||
debugMode: boolean | null;
|
||||
}
|
||||
|
||||
export type CommandResultView = {
|
||||
key: number,
|
||||
input: string,
|
||||
view: JSX.Element
|
||||
};
|
||||
|
||||
export type AppStateChangeHandler = (state: AppState) => void;
|
||||
|
||||
export default class AppState {
|
||||
@@ -17,15 +23,15 @@ export default class AppState {
|
||||
emphasizeBytes: boolean;
|
||||
debugMode: boolean = false;
|
||||
uiTheme: string;
|
||||
handlers: AppStateChangeHandler[];
|
||||
commandResults: any[];
|
||||
changeHandlers: AppStateChangeHandler[];
|
||||
commandResults: CommandResultView[];
|
||||
persistedVersion: number;
|
||||
wasOldVersion: boolean;
|
||||
env: string;
|
||||
|
||||
constructor(persistData : PersistedAppData, env: string) {
|
||||
this.commandResults = [];
|
||||
this.handlers = [];
|
||||
this.changeHandlers = [];
|
||||
this.uiTheme = persistData.uiTheme || 'midnight';
|
||||
this.env = env;
|
||||
|
||||
@@ -35,9 +41,10 @@ export default class AppState {
|
||||
this.debugMode = env !== 'prod' || persistData.debugMode === true;
|
||||
}
|
||||
|
||||
addCommandResult(result : any) {
|
||||
this.commandResults.unshift(result);
|
||||
log.debug("result added", result);
|
||||
addCommandResult(input : string, view : JSX.Element) {
|
||||
const key = generateKey();
|
||||
this.commandResults.unshift({key, input, view});
|
||||
log.debug(`command result added: ${input}`);
|
||||
this.triggerChanged();
|
||||
}
|
||||
|
||||
@@ -52,11 +59,11 @@ export default class AppState {
|
||||
}
|
||||
|
||||
onChange(handler : AppStateChangeHandler) {
|
||||
this.handlers.push(handler);
|
||||
this.changeHandlers.push(handler);
|
||||
}
|
||||
|
||||
triggerChanged() {
|
||||
this.handlers.forEach(h => h(this));
|
||||
this.changeHandlers.forEach(h => h(this));
|
||||
}
|
||||
|
||||
setUiTheme(theme: string) {
|
||||
@@ -77,4 +84,8 @@ export default class AppState {
|
||||
debugMode: this.debugMode
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function generateKey() : number {
|
||||
return Math.ceil(Math.random()*10000000) ^ Date.now(); // Because why the hell not...
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class AboutResult extends CommandResult {
|
||||
constructor(input:string) {
|
||||
super(input);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
export default class CommandResult {
|
||||
input: string;
|
||||
inputHash: string;
|
||||
|
||||
constructor(input: string) {
|
||||
this.input = input;
|
||||
this.inputHash = this.encodeHash(input);
|
||||
}
|
||||
|
||||
encodeHash (input: string) {
|
||||
return encodeURI(input.trim().replace(/\s/g,','));
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export class UnhandledErrorResult extends CommandResult {
|
||||
error: Error;
|
||||
constructor(input: string, error : Error) {
|
||||
super(input);
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResult extends CommandResult {
|
||||
errorMessage: string;
|
||||
constructor(input: string, errorMessage : string) {
|
||||
super(input);
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
import { ExpressionInput } from '../expression/expression-interfaces';
|
||||
|
||||
export default class ExpressionResult extends CommandResult {
|
||||
expression: ExpressionInput;
|
||||
constructor(input: string, expression: ExpressionInput) {
|
||||
super(input);
|
||||
this.expression = expression;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class HelpResult extends CommandResult {
|
||||
constructor(input: string) {
|
||||
super(input);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { IpAddress, ipAddressParser, IpAddressWithSubnetMask } from '../ipaddress/ip';
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class IpAddressResult extends CommandResult {
|
||||
ipAddresses: IpAddress[];
|
||||
constructor(input: string, ipAddresses: IpAddress[]) {
|
||||
super(input);
|
||||
this.ipAddresses = ipAddresses;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class StringResult extends CommandResult {
|
||||
value:string;
|
||||
constructor(input: string, value : string) {
|
||||
super(input);
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class UnknownCommandResult extends CommandResult {
|
||||
message:string;
|
||||
constructor(input : string) {
|
||||
super(input);
|
||||
this.message = `Sorry, i don''t know what ${input} is :(`;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import CommandResult from './CommandResult';
|
||||
|
||||
export default class WhatsnewResult extends CommandResult {
|
||||
constructor(input: string) {
|
||||
super(input);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user