diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2020-04-27 22:08:56 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2020-04-27 22:08:56 -0400 |
commit | 1f0d326a6c8735f67c6e37b19f4656e645e38c43 (patch) | |
tree | 65605e4183c7d79f1d193b9c7d6b32940d7ee8db /src/client/views/nodes/ScriptingBox.tsx | |
parent | 26e683056cddcbe8f90547c77519daa15c37518d (diff) | |
parent | 2f371a09f7305cbc44e9358af310078ce0cb4b3c (diff) |
Merge branch 'master' into richTextSchemaS
Diffstat (limited to 'src/client/views/nodes/ScriptingBox.tsx')
-rw-r--r-- | src/client/views/nodes/ScriptingBox.tsx | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx new file mode 100644 index 000000000..c607d6614 --- /dev/null +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -0,0 +1,98 @@ +import { action, observable, computed } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; +import { documentSchema } from "../../../new_fields/documentSchemas"; +import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema"; +import { ScriptField } from "../../../new_fields/ScriptField"; +import { StrCast, ScriptCast, Cast } from "../../../new_fields/Types"; +import { InteractionUtils } from "../../util/InteractionUtils"; +import { CompileScript, isCompileError, ScriptParam } from "../../util/Scripting"; +import { ViewBoxAnnotatableComponent } from "../DocComponent"; +import { EditableView } from "../EditableView"; +import { FieldView, FieldViewProps } from "../nodes/FieldView"; +import "./ScriptingBox.scss"; +import { OverlayView } from "../OverlayView"; +import { DocumentIconContainer } from "./DocumentIcon"; +import { List } from "../../../new_fields/List"; + +const ScriptingSchema = createSchema({}); +type ScriptingDocument = makeInterface<[typeof ScriptingSchema, typeof documentSchema]>; +const ScriptingDocument = makeInterface(ScriptingSchema, documentSchema); + +@observer +export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, ScriptingDocument>(ScriptingDocument) { + protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer | undefined; + public static LayoutString(fieldStr: string) { return FieldView.LayoutString(ScriptingBox, fieldStr); } + + _overlayDisposer?: () => void; + + @observable private _errorMessage: string = ""; + + @computed get rawScript() { return StrCast(this.dataDoc[this.props.fieldKey + "-rawScript"], StrCast(this.layoutDoc[this.props.fieldKey + "-rawScript"])); } + @computed get compileParams() { return Cast(this.dataDoc[this.props.fieldKey + "-params"], listSpec("string"), Cast(this.layoutDoc[this.props.fieldKey + "-params"], listSpec("string"), [])); } + set rawScript(value) { this.dataDoc[this.props.fieldKey + "-rawScript"] = value; } + set compileParams(value) { this.dataDoc[this.props.fieldKey + "-params"] = value; } + + @action + componentDidMount() { + this.rawScript = ScriptCast(this.dataDoc[this.props.fieldKey])?.script?.originalScript || this.rawScript; + } + + componentWillUnmount() { this._overlayDisposer?.(); } + + @action + onCompile = () => { + const params = this.compileParams.reduce((o: ScriptParam, p: string) => { o[p] = "any"; return o; }, {} as ScriptParam); + const result = CompileScript(this.rawScript, { + editable: true, + transformer: DocumentIconContainer.getTransformer(), + params, + typecheck: false + }); + this._errorMessage = isCompileError(result) ? result.errors.map(e => e.messageText).join("\n") : ""; + return this.dataDoc[this.props.fieldKey] = result.compiled ? new ScriptField(result) : undefined; + } + + @action + onRun = () => { + this.onCompile()?.script.run({}, err => this._errorMessage = err.map((e: any) => e.messageText).join("\n")); + } + + onFocus = () => { + this._overlayDisposer?.(); + this._overlayDisposer = OverlayView.Instance.addElement(<DocumentIconContainer />, { x: 0, y: 0 }); + } + + render() { + const params = <EditableView + contents={this.compileParams.join(" ")} + display={"block"} + maxHeight={72} + height={35} + fontSize={28} + GetValue={() => ""} + SetValue={value => { this.compileParams = new List<string>(value.split(" ").filter(s => s !== " ")); return true; }} + />; + return ( + <div className="scriptingBox-outerDiv" + onWheel={e => this.props.isSelected(true) && e.stopPropagation()}> + <div className="scriptingBox-inputDiv" + onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} > + <textarea className="scriptingBox-textarea" + placeholder="write your script here" + onChange={e => this.rawScript = e.target.value} + value={this.rawScript} + onFocus={this.onFocus} + onBlur={e => this._overlayDisposer?.()} /> + <div className="scriptingBox-errorMessage" style={{ background: this._errorMessage ? "red" : "" }}>{this._errorMessage}</div> + <div className="scriptingBox-params" >{params}</div> + </div> + {this.rootDoc.layout === "layout" ? <div></div> : (null)} + <div className="scriptingBox-toolbar"> + <button className="scriptingBox-button" onPointerDown={e => { this.onCompile(); e.stopPropagation(); }}>Compile</button> + <button className="scriptingBox-button" onPointerDown={e => { this.onRun(); e.stopPropagation(); }}>Run</button> + </div> + </div> + ); + } +} |