mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
finish up basic line settings
This commit is contained in:
parent
b1535b9b9d
commit
920a327f70
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Prompt",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"main": "dist/emain.js",
|
||||
"license": "Proprietary",
|
||||
"dependencies": {
|
||||
|
@ -2798,7 +2798,6 @@ class Main extends React.Component<{}, {}> {
|
||||
|
||||
@boundMethod
|
||||
handleContextMenu(e : any) {
|
||||
console.log("main contextmenu");
|
||||
let isInNonTermInput = false;
|
||||
let activeElem = document.activeElement;
|
||||
if (activeElem != null && activeElem.nodeName == "TEXTAREA") {
|
||||
|
@ -26,13 +26,25 @@ function CodeRenderer(props : any) : any {
|
||||
);
|
||||
}
|
||||
|
||||
const MaxMarkdownSize = 50000;
|
||||
|
||||
@mobxReact.observer
|
||||
class SimpleMarkdownRenderer extends React.Component<{data : Blob, context : RendererContext, opts : RendererOpts, savedHeight : number}, {}> {
|
||||
markdownText : OV<string> = mobx.observable.box(null, {name: "markdownText"});
|
||||
markdownError : OV<string> = mobx.observable.box(null, {name: "markdownError"});
|
||||
|
||||
componentDidMount() {
|
||||
let prtn = this.props.data.text()
|
||||
let dataBlob = this.props.data;
|
||||
if (dataBlob.size > 50000) {
|
||||
this.markdownError.set(sprintf("error: markdown too large to render size=%d", dataBlob.size));
|
||||
return;
|
||||
}
|
||||
let prtn = dataBlob.text()
|
||||
prtn.then((text) => {
|
||||
if (/[\x00-\x08]/.test(text)) {
|
||||
this.markdownError.set(sprintf("error: not rendering markdown, binary characters detected"));
|
||||
return;
|
||||
}
|
||||
mobx.action(() => {
|
||||
this.markdownText.set(text);
|
||||
})();
|
||||
@ -40,6 +52,9 @@ class SimpleMarkdownRenderer extends React.Component<{data : Blob, context : Ren
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.markdownError.get() != null) {
|
||||
return <div className="markdown-renderer"><div className="markdown-error">{this.markdownError.get()}</div></div>;
|
||||
}
|
||||
if (this.markdownText.get() == null) {
|
||||
return <div className="markdown-renderer" style={{height: this.props.savedHeight}}/>
|
||||
}
|
||||
@ -53,10 +68,11 @@ class SimpleMarkdownRenderer extends React.Component<{data : Blob, context : Ren
|
||||
h6: (props) => HeaderRenderer(props, 6),
|
||||
code: CodeRenderer,
|
||||
};
|
||||
let opts = this.props.opts;
|
||||
let markdownText = this.markdownText.get();
|
||||
return (
|
||||
<div className="markdown-renderer">
|
||||
<div className="markdown content">
|
||||
<div className="markdown content" style={{maxHeight: opts.maxSize.height, maxWidth: opts.maxSize.width, overflow: "auto"}}>
|
||||
<ReactMarkdown children={this.markdownText.get()} remarkPlugins={[remarkGfm]} components={markdownComponents}/>
|
||||
</div>
|
||||
</div>
|
||||
|
17
src/model.ts
17
src/model.ts
@ -2409,6 +2409,9 @@ class Model {
|
||||
if (isBlank(plugin.name)) {
|
||||
throw new Error("invalid plugin, no name");
|
||||
}
|
||||
if (plugin.name == "terminal" || plugin.name == "none") {
|
||||
throw new Error(sprintf("invalid plugin, name '%s' is reserved", plugin.name));
|
||||
}
|
||||
let existingPlugin = this.getRendererPluginByName(plugin.name);
|
||||
if (existingPlugin != null) {
|
||||
throw new Error(sprintf("plugin with name %s already registered", plugin.name));
|
||||
@ -3213,6 +3216,20 @@ class CommandRunner {
|
||||
GlobalModel.submitCommand("line", "view", [sessionId, screenId, String(lineNum)], {"nohist": "1"}, false);
|
||||
}
|
||||
|
||||
lineArchive(lineArg : string, archive : boolean) {
|
||||
let kwargs = {"nohist": "1"};
|
||||
let archiveStr = (archive ? "1" : "0");
|
||||
GlobalModel.submitCommand("line", "archive", [lineArg, archiveStr], kwargs, false);
|
||||
}
|
||||
|
||||
lineSet(lineArg : string, opts : {renderer? : string}) {
|
||||
let kwargs = {"nohist": "1"};
|
||||
if ("renderer" in opts) {
|
||||
kwargs["renderer"] = opts.renderer ?? "";
|
||||
}
|
||||
GlobalModel.submitCommand("line", "set", [lineArg], kwargs, false);
|
||||
}
|
||||
|
||||
createNewSession() {
|
||||
GlobalModel.submitCommand("session", "open", null, {"nohist": "1"}, false);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import {If, For, When, Otherwise, Choose} from "tsx-control-statements/component
|
||||
import cn from "classnames";
|
||||
import {GlobalModel, GlobalCommandRunner, TabColors} from "./model";
|
||||
import {Toggle} from "./elements";
|
||||
import {LineType} from "./types";
|
||||
import {LineType, RendererPluginType} from "./types";
|
||||
|
||||
type OV<V> = mobx.IObservableValue<V>;
|
||||
type OArr<V> = mobx.IObservableArray<V>;
|
||||
@ -232,8 +232,18 @@ class SessionSettingsModal extends React.Component<{sessionId : string}, {}> {
|
||||
|
||||
@mobxReact.observer
|
||||
class LineSettingsModal extends React.Component<{line : LineType}, {}> {
|
||||
tempArchived : OV<boolean>;
|
||||
tempRenderer : OV<string>;
|
||||
rendererDropdownActive : OV<boolean> = mobx.observable.box(false, {name: "lineSettings-rendererDropdownActive"});
|
||||
|
||||
constructor(props : any) {
|
||||
super(props);
|
||||
let {line} = props;
|
||||
if (line == null) {
|
||||
return;
|
||||
}
|
||||
this.tempArchived = mobx.observable.box(!!line.archived, {name: "lineSettings-tempArchived"});
|
||||
this.tempRenderer = mobx.observable.box(line.renderer, {name: "lineSettings-renderer"});
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
@ -245,9 +255,68 @@ class LineSettingsModal extends React.Component<{line : LineType}, {}> {
|
||||
|
||||
@boundMethod
|
||||
handleOK() : void {
|
||||
let {line} = this.props;
|
||||
mobx.action(() => {
|
||||
GlobalModel.lineSettingsModal.set(null);
|
||||
})();
|
||||
if (this.tempRenderer.get() != line.renderer) {
|
||||
GlobalCommandRunner.lineSet(line.lineid, {
|
||||
"renderer": this.tempRenderer.get(),
|
||||
});
|
||||
}
|
||||
if (this.tempArchived.get() != !!line.archived) {
|
||||
GlobalCommandRunner.lineArchive(line.lineid, this.tempArchived.get());
|
||||
}
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
handleChangeArchived(val : boolean) : void {
|
||||
mobx.action(() => {
|
||||
this.tempArchived.set(val);
|
||||
})();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
toggleRendererDropdown() : void {
|
||||
mobx.action(() => {
|
||||
this.rendererDropdownActive.set(!this.rendererDropdownActive.get());
|
||||
})();
|
||||
}
|
||||
|
||||
@boundMethod
|
||||
clickSetRenderer(renderer : string) : void {
|
||||
mobx.action(() => {
|
||||
this.tempRenderer.set(renderer);
|
||||
this.rendererDropdownActive.set(false);
|
||||
})();
|
||||
}
|
||||
|
||||
renderRendererDropdown() : any {
|
||||
let {line} = this.props;
|
||||
let renderer = this.tempRenderer.get() ?? "terminal";
|
||||
let plugins = GlobalModel.rendererPlugins;
|
||||
let plugin : RendererPluginType = null;
|
||||
return (
|
||||
<div className={cn("dropdown", "renderer-dropdown", {"is-active": this.rendererDropdownActive.get()})}>
|
||||
<div className="dropdown-trigger">
|
||||
<button onClick={this.toggleRendererDropdown} className="button is-small is-dark">
|
||||
<span><i className="fa-sharp fa-solid fa-fill"/> {renderer}</span>
|
||||
<span className="icon is-small">
|
||||
<i className="fa-sharp fa-regular fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="dropdown-menu" role="menu">
|
||||
<div className="dropdown-content has-background-black">
|
||||
<div onClick={() => this.clickSetRenderer("none") } key="none" className="dropdown-item">none</div>
|
||||
<div onClick={() => this.clickSetRenderer(null) } key="terminal" className="dropdown-item">terminal</div>
|
||||
<For each="plugin" of={plugins}>
|
||||
<div onClick={() => this.clickSetRenderer(plugin.name) } key={plugin.name} className="dropdown-item">{plugin.name}</div>
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -271,9 +340,22 @@ class LineSettingsModal extends React.Component<{line : LineType}, {}> {
|
||||
Renderer
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
xxx
|
||||
{this.renderRendererDropdown()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-field">
|
||||
<div className="settings-label">
|
||||
Archived
|
||||
</div>
|
||||
<div className="settings-input">
|
||||
<Toggle checked={this.tempArchived.get()} onChange={this.handleChangeArchived}/>
|
||||
<div className="action-text">
|
||||
<If condition={this.tempArchived.get() && this.tempArchived.get() != !!line.archived}>will be archived</If>
|
||||
<If condition={!this.tempArchived.get() && this.tempArchived.get() != !!line.archived}>will be un-archived</If>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{height: 50}}/>
|
||||
</div>
|
||||
<footer>
|
||||
<div onClick={this.closeModal} className="button is-prompt-cancel is-outlined is-small">Cancel</div>
|
||||
|
27
src/sh2.less
27
src/sh2.less
@ -2633,6 +2633,23 @@ input[type=checkbox] {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
.dropdown-menu .dropdown-content {
|
||||
.dropdown-item {
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
max-height: 120px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal.prompt-modal {
|
||||
@ -3006,10 +3023,18 @@ input[type=checkbox] {
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-renderer {
|
||||
.markdown-error {
|
||||
color: @term-red;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-renderer .markdown {
|
||||
padding: 5px;
|
||||
line-height: 1.5;
|
||||
|
||||
|
||||
blockquote {
|
||||
background-color: #222;
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
const VERSION = "v0.1.6";
|
||||
const VERSION = "v0.1.7";
|
||||
module.exports = VERSION;
|
||||
|
Loading…
Reference in New Issue
Block a user