diff --git a/src/prompt.less b/src/prompt.less index 36581b78..d21fd16b 100644 --- a/src/prompt.less +++ b/src/prompt.less @@ -302,18 +302,10 @@ input[type="checkbox"] { .save-disabled:hover { background-color: #aaaea7; } - .close-enabled { + .close { 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; diff --git a/src/view/code.tsx b/src/view/code.tsx index 518c60a2..73aeed68 100644 --- a/src/view/code.tsx +++ b/src/view/code.tsx @@ -1,13 +1,11 @@ import * as React from "react"; import { RendererContext, RendererOpts, LineStateType, RendererModelContainerApi } from "../types"; import Editor from "@monaco-editor/react"; -import cn from "classnames"; import { Markdown } from "../elements"; import { GlobalModel, GlobalCommandRunner } from "../model"; import Split from "react-split-it"; import "./split.css"; import loader from "@monaco-editor/loader"; -import { editor } from "monaco-editor"; loader.config({ paths: { vs: "./node_modules/monaco-editor/min/vs" } }); function renderCmdText(text: string): any { @@ -57,7 +55,7 @@ class SourceCodeRenderer extends React.Component< languagesWithPreviewer = ["markdown"]; filePath; cacheKey; - originalData; + originalCode; monacoEditor: any; // reference to mounted monaco editor. TODO need the correct type markdownRef; syncing; @@ -67,7 +65,7 @@ class SourceCodeRenderer extends React.Component< this.monacoEditor = null; const editorHeight = Math.max(props.savedHeight - 25, 0); // must subtract the padding/margin to get the real editorHeight this.markdownRef = React.createRef(); - this.syncing = false; // to avoid recursive calls between the two scroll listeners + this.syncing = false; this.state = { code: null, languages: [], @@ -91,7 +89,7 @@ class SourceCodeRenderer extends React.Component< this.setState({ code, isClosed: this.props.lineState["prompt:closed"] }); } else { this.props.data.text().then((code) => { - this.originalData = code; + this.originalCode = code; this.setState({ code, isClosed: this.props.lineState["prompt:closed"] }); SourceCodeRenderer.codeCache.set(this.cacheKey, code); }); @@ -150,7 +148,7 @@ class SourceCodeRenderer extends React.Component< e.preventDefault(); this.doSave(); } - if (e.code === "KeyD" && (e.ctrlKey || e.metaKey) && !this.state.isSave) { + if (e.code === "KeyD" && (e.ctrlKey || e.metaKey)) { e.preventDefault(); this.doClose(); } @@ -181,13 +179,9 @@ class SourceCodeRenderer extends React.Component< }; handleEditorScrollChange(e) { - // Get the maximum scrollable height for the editor + if (!this.state.showPreview) return; const scrollableHeightEditor = this.monacoEditor.getScrollHeight() - this.monacoEditor.getLayoutInfo().height; - - // Calculate the scroll percentage const verticalScrollPercentage = e.scrollTop / scrollableHeightEditor; - - // Apply the same percentage to the markdown div const markdownDiv = this.markdownRef.current; if (markdownDiv) { const scrollableHeightMarkdown = markdownDiv.scrollHeight - markdownDiv.clientHeight; @@ -227,17 +221,20 @@ class SourceCodeRenderer extends React.Component< } }; - doSave = () => { + doSave = (onSave = () => {}) => { if (!this.state.isSave) return; const { screenId, lineId } = this.props.context; const encodedCode = new TextEncoder().encode(this.state.code); GlobalModel.writeRemoteFile(screenId, lineId, this.filePath, encodedCode, { useTemp: true }) .then(() => { - this.originalData = this.state.code; - this.setState({ - isSave: false, - message: { status: "success", text: `Saved to ${this.props.cwd}/${this.filePath}` }, - }); + this.originalCode = this.state.code; + this.setState( + { + isSave: false, + message: { status: "success", text: `Saved to ${this.props.cwd}/${this.filePath}` }, + }, + onSave + ); setTimeout(() => this.setState({ message: null }), 3000); }) .catch((e) => { @@ -247,7 +244,15 @@ class SourceCodeRenderer extends React.Component< }; doClose = () => { - if (this.state.isSave) return; + // if there is unsaved data + if (this.state.isSave) + return GlobalModel.showAlert({ + message: "Do you want to Save your changes before closing?", + confirm: true, + }).then((result) => { + if (result) return this.doSave(this.doClose); + this.setState({ code: this.originalCode, isSave: false }, this.doClose); + }); const { screenId, lineId } = this.props.context; GlobalCommandRunner.setLineState(screenId, lineId, { ...this.props.lineState, "prompt:closed": true }, false) .then(() => { @@ -278,7 +283,7 @@ class SourceCodeRenderer extends React.Component< SourceCodeRenderer.codeCache.set(this.cacheKey, code); this.setState({ code }, () => { this.setEditorHeight(); - this.props.data.text().then((originalCode) => this.setState({ isSave: code !== originalCode })); + this.setState({ isSave: code !== this.originalCode }); }); }; @@ -313,7 +318,7 @@ class SourceCodeRenderer extends React.Component< theme="hc-black" height={this.state.editorHeight} defaultLanguage={this.state.selectedLanguage} - defaultValue={this.state.code} + value={this.state.code} onMount={this.handleEditorDidMount} options={{ scrollBeyondLastLine: false, @@ -334,7 +339,7 @@ class SourceCodeRenderer extends React.Component< ref={this.markdownRef} onScroll={() => this.handleDivScroll()} > - + ); }; @@ -376,10 +381,7 @@ class SourceCodeRenderer extends React.Component< )} {allowEditing && (
-
+
{`close (`} {renderCmdText("D")} {`)`}