PE-71 close (#12)

* fixed expand issues

* removed expand

* can close the file, and min 5 lines are

* removed older file
This commit is contained in:
anandamarsh
2023-09-06 13:28:05 -07:00
committed by GitHub
parent fa04cd9e5c
commit dff146db66
3 changed files with 70 additions and 164 deletions
+12
View File
@@ -279,6 +279,18 @@ input[type="checkbox"] {
.save-disabled:hover {
background-color: #aaaea7;
}
.close-enabled {
color: white;
background-color: #9e0000;
}
.close-disabled {
color: rgb(52, 52, 52);
background-color: #aaaea7;
cursor: default !important;
}
.close-disabled:hover {
background-color: #aaaea7;
}
.message {
color: white;
border-radius: 6px;
+58 -15
View File
@@ -1,7 +1,7 @@
import * as React from "react";
import { RendererContext, RendererOpts, LineStateType } from "../types";
import Editor from "@monaco-editor/react";
import { GlobalModel } from "../model";
import { GlobalModel, GlobalCommandRunner } from "../model";
function renderCmdText(text: string): any {
return <span>&#x2318;{text}</span>;
@@ -34,28 +34,28 @@ class SourceCodeRenderer extends React.Component<
super(props);
this.editorRef = React.createRef();
this.state = {
code: "",
code: null,
language: "",
languages: [],
selectedLanguage: "",
isSave: false,
isClosed: false,
editorHeight: props.savedHeight,
message: null,
};
}
componentDidMount(): void {
console.dir(this.props);
this.filePath = this.props.lineState["prompt:file"];
const { screenId, lineId } = this.props.context;
this.cacheKey = `${screenId}-${lineId}-${this.filePath}`;
const code = SourceCodeRenderer.codeCache.get(this.cacheKey);
if (code) {
this.setState({ code });
this.setState({ code, isClosed: this.props.lineState["prompt:closed"] });
} else
this.props.data.text().then((code) => {
this.originalData = code;
this.setState({ code });
this.setState({ code, isClosed: this.props.lineState["prompt:closed"] });
SourceCodeRenderer.codeCache.set(this.cacheKey, code);
});
}
@@ -79,10 +79,14 @@ class SourceCodeRenderer extends React.Component<
}
this.setEditorHeight();
editor.onKeyDown((e) => {
if (e.code === "KeyS" && (e.ctrlKey || e.metaKey)) {
if (e.code === "KeyS" && (e.ctrlKey || e.metaKey) && this.state.isSave) {
e.preventDefault();
this.doSave();
}
if (e.code === "KeyD" && (e.ctrlKey || e.metaKey) && !this.state.isSave) {
e.preventDefault();
this.doClose();
}
});
};
@@ -99,9 +103,9 @@ class SourceCodeRenderer extends React.Component<
};
doSave = () => {
if (!this.state.isSave) return;
const { screenId, lineId } = this.props.context;
const encodedCode = new TextEncoder().encode(this.state.code);
debugger;
GlobalModel.writeRemoteFile(screenId, lineId, this.filePath, encodedCode, { useTemp: true })
.then(() => {
this.originalData = this.state.code;
@@ -117,6 +121,31 @@ class SourceCodeRenderer extends React.Component<
});
};
doClose = () => {
if (this.state.isSave) return;
const { screenId, lineId } = this.props.context;
GlobalCommandRunner.setLineState(screenId, lineId, { ...this.props.lineState, "prompt:closed": true }, false)
.then(() => {
this.setState({
isClosed: true,
message: { status: "success", text: `Closed. This editor is now read-only` },
});
setTimeout(() => {
this.setEditorHeight();
}, 100);
setTimeout(() => {
this.setState({ message: null });
}, 3000);
})
.catch((e) => {
this.setState({ message: { status: "error", text: e.message } });
setTimeout(() => {
this.setState({ message: null });
}, 3000);
});
};
handleEditorChange = (code) => {
SourceCodeRenderer.codeCache.set(this.cacheKey, code);
this.setState({ code }, () => {
@@ -128,18 +157,18 @@ class SourceCodeRenderer extends React.Component<
setEditorHeight = () => {
const fullWindowHeight = parseInt(this.props.opts.maxSize.height);
let _editorHeight = fullWindowHeight;
if (this.props.readOnly) {
const noOfLines = this.state.code.split("\n").length;
if (this.props.readOnly || this.state.isClosed) {
const noOfLines = Math.max(this.state.code.split("\n").length, 5);
_editorHeight = Math.min(noOfLines * GlobalModel.termFontSize.get() * 1.5 + 10, fullWindowHeight);
}
this.setState({ editorHeight: _editorHeight }, () => this.props.scrollToBringIntoViewport());
};
render() {
const { opts, exitcode } = this.props;
const { lang, code, isSave } = this.state;
const { opts, exitcode, readOnly } = this.props;
const { lang, code, isSave, isClosed } = this.state;
if (!code)
if (code == null)
return <div className="renderer-container code-renderer" style={{ height: this.props.savedHeight }} />;
if (exitcode === 1)
@@ -169,7 +198,7 @@ class SourceCodeRenderer extends React.Component<
scrollBeyondLastLine: false,
fontSize: GlobalModel.termFontSize.get(),
fontFamily: "JetBrains Mono",
readOnly: this.props.readOnly,
readOnly: readOnly || isClosed,
keybindings: [
{
key: "ctrl+s",
@@ -197,13 +226,27 @@ class SourceCodeRenderer extends React.Component<
</option>
))}
</select>
{!this.props.readOnly && (
{!readOnly && !isClosed && (
<div className="cmd-hints" style={{ minWidth: "6rem", maxWidth: "6rem", marginLeft: "-18px" }}>
<div
onClick={this.doSave}
className={`hint-item ${isSave ? "save-enabled" : "save-disabled"}`}
>
{`save`} {renderCmdText("S")}
{`save (`}
{renderCmdText("S")}
{`)`}
</div>
</div>
)}
{!readOnly && !isClosed && (
<div className="cmd-hints" style={{ minWidth: "6rem", maxWidth: "6rem", marginLeft: "-18px" }}>
<div
onClick={this.doClose}
className={`hint-item ${!isSave ? "close-enabled" : "close-disabled"}`}
>
{`close (`}
{renderCmdText("D")}
{`)`}
</div>
</div>
)}
-149
View File
@@ -1,149 +0,0 @@
import * as React from "react";
import * as mobx from "mobx";
import * as mobxReact from "mobx-react";
import { RendererContext, RendererOpts } from "../types";
import Editor from "@monaco-editor/react";
import { GlobalModel } from "../model";
type OV<V> = mobx.IObservableValue<V>;
@mobxReact.observer
class SourceCodeRenderer extends React.Component<
{
data: Blob;
cmdstr: String;
cwd: String;
context: RendererContext;
opts: RendererOpts;
savedHeight: number;
scrollToBringIntoViewport: () => void;
},
{}
> {
code: OV<string> = mobx.observable.box("");
language: OV<string> = mobx.observable.box("");
languages: OV<string[]> = mobx.observable.box([]);
selectedLanguage: OV<string> = mobx.observable.box("");
isFullWindow: OV<boolean> = mobx.observable.box(false); // load this from opts
editorHeight: OV<number> = mobx.observable.box(this.props.savedHeight); // load this from opts
editorRef;
resizeObserver;
constructor(props) {
super(props);
this.editorRef = React.createRef();
console.log(`resetting the code`);
this.props.data.text().then((text) => this.code.set(text));
}
componentDidMount() {}
componentWillUnmount(): void {
console.log(`will unmount`);
}
handleEditorDidMount = (editor, monaco) => {
// Use a regular expression to match a filename with an extension
const extension = this.props.cmdstr.match(/(?:[^\\\/:*?"<>|\r\n]+\.)([a-zA-Z0-9]+)\b/)?.[1] || "";
const detectedLanguage = monaco.languages
.getLanguages()
.find((lang) => lang.extensions && lang.extensions.includes("." + extension));
const languages = monaco.languages.getLanguages().map((lang) => lang.id);
this.languages.set(languages);
if (detectedLanguage) {
this.selectedLanguage.set(detectedLanguage.id);
this.editorRef.current = editor;
const model = editor.getModel();
if (model) {
monaco.editor.setModelLanguage(model, detectedLanguage.id);
this.language.set(detectedLanguage.id);
}
}
this.setEditorHeight();
};
handleLanguageChange = (event) => {
const selectedLanguage = event.target.value;
this.selectedLanguage.set(selectedLanguage);
if (this.editorRef.current) {
const model = this.editorRef.current.getModel();
if (model) {
monaco.editor.setModelLanguage(model, selectedLanguage);
this.language.set(selectedLanguage);
}
}
};
toggleFit = () => {
this.isFullWindow.set(!this.isFullWindow.get());
this.setEditorHeight();
setTimeout(() => this.props.scrollToBringIntoViewport(), 350);
};
handleEditorChange = (value, event) => {
// editing will always be in fullscreen
this.isFullWindow.set(true);
this.code.set(value);
this.setEditorHeight();
setTimeout(() => this.props.scrollToBringIntoViewport(), 350);
};
setEditorHeight = () => {
const fullWindowHeight = parseInt(this.props.opts.maxSize.height);
let _editorHeight = fullWindowHeight;
if (!this.isFullWindow.get()) {
const noOfLines = this.code.get().split("\n").length;
_editorHeight = Math.min(noOfLines * GlobalModel.termFontSize.get() * 1.5 + 10, fullWindowHeight);
}
this.editorHeight.set(_editorHeight);
};
render() {
let opts = this.props.opts;
let lang = this.language.get();
let code = this.code.get();
if (!code) {
return <div className="renderer-container code-renderer" style={{ height: this.props.savedHeight }} />;
}
return (
<div className="renderer-container code-renderer">
<div className="scroller" style={{ maxHeight: opts.maxSize.height, paddingBottom: "15px" }}>
<Editor
theme="hc-black"
height={this.editorHeight.get()}
defaultLanguage={lang}
defaultValue={code}
onMount={this.handleEditorDidMount}
options={{
scrollBeyondLastLine: false,
fontSize: GlobalModel.termFontSize.get(),
fontFamily: "JetBrains Mono",
readOnly: this.props.opts.readOnly,
}}
onChange={this.handleEditorChange}
/>
</div>
<div style={{ position: "absolute", bottom: "-3px", right: 0 }}>
<select
className="dropdown"
value={this.selectedLanguage.get()}
onChange={this.handleLanguageChange}
style={{ minWidth: "6rem", maxWidth: "6rem", marginRight: "8px" }}
>
{this.languages.get().map((lang, index) => (
<option key={index} value={lang}>
{lang}
</option>
))}
</select>
<div className="cmd-hints" style={{ minWidth: "6rem", maxWidth: "6rem" }}>
<div onClick={this.toggleFit} className="hint-item color-white">
{this.isFullWindow.get() ? `shrink` : `expand`}
</div>
</div>
</div>
</div>
);
}
}
export { SourceCodeRenderer };