diff --git a/src/AppRoot.tsx b/src/AppRoot.tsx index 989fa0b..d471bca 100644 --- a/src/AppRoot.tsx +++ b/src/AppRoot.tsx @@ -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 { @@ -35,7 +34,10 @@ export default class AppRoot extends React.Component getResultViews() : JSX.Element[] { log.debug('getting result views') - var results = this.state.commandResults.map((r, i) => ); + var results = this.state.commandResults.map((r, i) => + + {r.view} + ); return results; } @@ -66,7 +68,7 @@ export default class AppRoot extends React.Component cmd.execute(input)} /> - this.toggleEmphasizeBytes()}>[em] + this.toggleEmphasizeBytes()}>[em] diff --git a/src/commands.ts b/src/commands.tsx similarity index 56% rename from src/commands.ts rename to src/commands.tsx index 39958f3..7923b38 100644 --- a/src/commands.ts +++ b/src/commands.tsx @@ -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, )); + 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, )); + cmd.command("whatsnew", (c: CommandInput) => appState.addCommandResult(c.input, )); + cmd.command("guid", (c: CommandInput) => appState.addCommandResult(c.input, )); + cmd.command("-notrack", () => {}); cmd.command("-debug", (c: CommandInput) => { appState.toggleDebugMode(); - appState.addCommandResult(new StringResult(c.input, `Debug Mode: ${appState.debugMode}`)) + appState.addCommandResult(c.input, ); }); @@ -46,7 +45,7 @@ export default { return; if(result instanceof ParsingError) { - appState.addCommandResult(new ErrorResult(c.input, result.errorMessage)); + appState.addCommandResult(c.input, ); return; } @@ -63,7 +62,7 @@ export default { } }); - appState.addCommandResult(new IpAddressResult(c.input, ipAddresses)); + appState.addCommandResult(c.input, ); } }) @@ -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, ); } }) // 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, ) }); - cmd.onError((input: string, err: Error) => appState.addCommandResult(new UnhandledErrorResult(input, err))); + cmd.onError((input: string, err: Error) => appState.addCommandResult(input, )); } } \ No newline at end of file diff --git a/src/components/DisplayResultView.tsx b/src/components/DisplayResultView.tsx index de6d268..fd06d95 100644 --- a/src/components/DisplayResultView.tsx +++ b/src/components/DisplayResultView.tsx @@ -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 { +export default class DisplayResultView extends React.Component { render() { return
-
>{this.props.content.input}#
+
>{this.props.input}#
- {this.findResultComponent(this.props.content)} + {this.props.children}
; } +} - findResultComponent(result: CommandResult) : JSX.Element { - - if(result instanceof HelpResult) { - return - } - - if(result instanceof AboutResult) { - return - } - - if(result instanceof ExpressionResult) { - return - } - - if(result instanceof WhatsnewResult) { - return - } - - if(result instanceof StringResult) { - return

{result.value}

- } - - if (result instanceof UnhandledErrorResult) { - return
-
(X_X) Ooops.. Something ain' right: {result.error.message}
-
- } - - if (result instanceof ErrorResult) { - return
-
{result.errorMessage}
-
- } - - if(result instanceof IpAddressResult) { - const ipResult = result as IpAddressResult; - - return - } - - return
-
¯\_(ツ)_/¯ Sorry, i don′t know what {this.props.content.input} is
-
- } -} \ No newline at end of file diff --git a/src/components/results/ErrorResultView.tsx b/src/components/results/ErrorResultView.tsx new file mode 100644 index 0000000..5b4883c --- /dev/null +++ b/src/components/results/ErrorResultView.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +function ErrorResultView(props : {errorMessage:string}) { + + return
+
{props.errorMessage}
+
; +} + +export default ErrorResultView; diff --git a/src/components/results/TextResultView.tsx b/src/components/results/TextResultView.tsx new file mode 100644 index 0000000..b3da8a3 --- /dev/null +++ b/src/components/results/TextResultView.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +function TextResultView(props : { text: string }) { + return

{props.text}

; +} + +export default TextResultView; \ No newline at end of file diff --git a/src/components/results/UnknownInputResultView.tsx b/src/components/results/UnknownInputResultView.tsx new file mode 100644 index 0000000..a651ae7 --- /dev/null +++ b/src/components/results/UnknownInputResultView.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +function UnknownInputResultView(props : {input:string}) { + + return
+
¯\_(ツ)_/¯ Sorry, i don′t know what {props.input} is
+
; +} + +export default UnknownInputResultView; diff --git a/src/core/AppState.ts b/src/core/AppState.ts index 9585594..935ed76 100644 --- a/src/core/AppState.ts +++ b/src/core/AppState.ts @@ -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 } } -}; \ No newline at end of file +}; + +function generateKey() : number { + return Math.ceil(Math.random()*10000000) ^ Date.now(); // Because why the hell not... +} \ No newline at end of file diff --git a/src/models/AboutResult.ts b/src/models/AboutResult.ts deleted file mode 100644 index 4ef1c07..0000000 --- a/src/models/AboutResult.ts +++ /dev/null @@ -1,7 +0,0 @@ -import CommandResult from './CommandResult'; - -export default class AboutResult extends CommandResult { - constructor(input:string) { - super(input); - } -} \ No newline at end of file diff --git a/src/models/CommandResult.ts b/src/models/CommandResult.ts deleted file mode 100644 index e46220f..0000000 --- a/src/models/CommandResult.ts +++ /dev/null @@ -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,',')); - } -} \ No newline at end of file diff --git a/src/models/ErrorResults.ts b/src/models/ErrorResults.ts deleted file mode 100644 index a9b9842..0000000 --- a/src/models/ErrorResults.ts +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/models/ExpressionResult.ts b/src/models/ExpressionResult.ts deleted file mode 100644 index 123c50a..0000000 --- a/src/models/ExpressionResult.ts +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/models/HelpResult.ts b/src/models/HelpResult.ts deleted file mode 100644 index af6d880..0000000 --- a/src/models/HelpResult.ts +++ /dev/null @@ -1,7 +0,0 @@ -import CommandResult from './CommandResult'; - -export default class HelpResult extends CommandResult { - constructor(input: string) { - super(input); - } -} \ No newline at end of file diff --git a/src/models/IpAddressResult.ts b/src/models/IpAddressResult.ts deleted file mode 100644 index 06a5df2..0000000 --- a/src/models/IpAddressResult.ts +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/models/StringResult.ts b/src/models/StringResult.ts deleted file mode 100644 index b68d62e..0000000 --- a/src/models/StringResult.ts +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/src/models/UnknownCommandResult.ts b/src/models/UnknownCommandResult.ts deleted file mode 100644 index 33651ae..0000000 --- a/src/models/UnknownCommandResult.ts +++ /dev/null @@ -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 :(`; - } -} \ No newline at end of file diff --git a/src/models/WhatsnewResult.ts b/src/models/WhatsnewResult.ts deleted file mode 100644 index f1d0b7d..0000000 --- a/src/models/WhatsnewResult.ts +++ /dev/null @@ -1,7 +0,0 @@ -import CommandResult from './CommandResult'; - -export default class WhatsnewResult extends CommandResult { - constructor(input: string) { - super(input); - } -} \ No newline at end of file