mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
first cut ready ... requires discussion with Mike
This commit is contained in:
parent
2ab0f4af4c
commit
81be0d4b38
2065
src/linecomps.tsx
2065
src/linecomps.tsx
File diff suppressed because it is too large
Load Diff
7378
src/model.ts
7378
src/model.ts
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@ import { RendererPluginType } from "./types";
|
||||
import { SimpleImageRenderer } from "./view/image";
|
||||
import { SimpleMarkdownRenderer } from "./view/markdown";
|
||||
import { SimpleJsonRenderer } from "./view/json";
|
||||
import { CodeRenderer } from "./view/code";
|
||||
import { SourceCodeRenderer } from "./view/code";
|
||||
import { OpenAIRenderer, OpenAIRendererModel } from "./view/openai";
|
||||
import { isBlank } from "./util";
|
||||
import { sprintf } from "sprintf-js";
|
||||
@ -48,7 +48,7 @@ const CodePlugin: RendererPluginType = {
|
||||
collapseType: "hide",
|
||||
globalCss: null,
|
||||
mimeTypes: ["text/plain"],
|
||||
simpleComponent: CodeRenderer,
|
||||
simpleComponent: SourceCodeRenderer,
|
||||
};
|
||||
|
||||
const OpenAIPlugin: RendererPluginType = {
|
||||
|
402
src/prompt.less
402
src/prompt.less
@ -39,7 +39,7 @@
|
||||
@import "views.less";
|
||||
@import "sidebar.less";
|
||||
@import "modals.less"; // includes settings
|
||||
@import "comps.less"; // includes terminal
|
||||
@import "comps.less"; // includes terminal
|
||||
@import "tabs.less";
|
||||
@import "cmdinput.less";
|
||||
@import "lines.less";
|
||||
@ -47,251 +47,259 @@
|
||||
// global settings / overrides
|
||||
|
||||
:root {
|
||||
--fa-style-family: "Font Awesome 6 Sharp";
|
||||
--fa-style-family: "Font Awesome 6 Sharp";
|
||||
}
|
||||
|
||||
html, body, #app, #main {
|
||||
background-color: #000;
|
||||
height: 100vh;
|
||||
html,
|
||||
body,
|
||||
#app,
|
||||
#main {
|
||||
background-color: #000;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.content {
|
||||
a:hover {
|
||||
color: #485fc7;
|
||||
}
|
||||
a:hover {
|
||||
color: #485fc7;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
background-color: #777;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #777;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: white;
|
||||
background: white;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
cursor: pointer;
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
// main layout
|
||||
#main {
|
||||
height: 100vh;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
background-color: black;
|
||||
height: 100%;
|
||||
|
||||
.main-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: black;
|
||||
height: 100%;
|
||||
.session-view,
|
||||
.history-view,
|
||||
.bookmarks-view {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 300px;
|
||||
position: relative;
|
||||
|
||||
.session-view, .history-view, .bookmarks-view {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 300px;
|
||||
position: relative;
|
||||
|
||||
&.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.screen-view {
|
||||
flex-grow: 1;
|
||||
border-right: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.window-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.rendermode-tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: rgba(78, 154, 6, 0.65);
|
||||
color: black;
|
||||
padding: 2px 8px 2px 4px;
|
||||
border-bottom-left-radius: 5px;
|
||||
z-index: 10;
|
||||
font-size: 12px;
|
||||
|
||||
&.is-active {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.render-mode {
|
||||
padding-top: 2px;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: #ccc;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-tag {
|
||||
color: #ccc;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 40%;
|
||||
background-color: darken(rgb(0, 177, 10), 20%);
|
||||
padding: 2px 8px 2px 4px;
|
||||
z-index: 11;
|
||||
font-size: 12px;
|
||||
/* border-radius: 0 0 5px 5px; */
|
||||
opacity: 0.8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.share-tag-link {
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.share-tag-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
opacity: 1.0;
|
||||
padding: 20px;
|
||||
width: 250px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: 0;
|
||||
|
||||
.share-tag-link {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.window-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
color: #ccc;
|
||||
.mono-font();
|
||||
|
||||
code {
|
||||
background-color: black;
|
||||
color: #4e9a06;
|
||||
}
|
||||
|
||||
&.should-fade {
|
||||
opacity: 1.0;
|
||||
animation: fade-in 2.5s;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.screen-view {
|
||||
flex-grow: 1;
|
||||
border-right: 1px solid #ccc;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.window-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
.rendermode-tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: rgba(78, 154, 6, 0.65);
|
||||
color: black;
|
||||
padding: 2px 8px 2px 4px;
|
||||
border-bottom-left-radius: 5px;
|
||||
z-index: 10;
|
||||
font-size: 12px;
|
||||
|
||||
&.is-active {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.render-mode {
|
||||
padding-top: 2px;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: #ccc;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-tag {
|
||||
color: #ccc;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 40%;
|
||||
background-color: darken(rgb(0, 177, 10), 20%);
|
||||
padding: 2px 8px 2px 4px;
|
||||
z-index: 11;
|
||||
font-size: 12px;
|
||||
/* border-radius: 0 0 5px 5px; */
|
||||
opacity: 0.8;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.share-tag-link {
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.share-tag-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
opacity: 1;
|
||||
padding: 20px;
|
||||
width: 250px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: 0;
|
||||
|
||||
.share-tag-link {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.window-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
color: #ccc;
|
||||
.mono-font();
|
||||
|
||||
code {
|
||||
background-color: black;
|
||||
color: #4e9a06;
|
||||
}
|
||||
|
||||
&.should-fade {
|
||||
opacity: 1;
|
||||
animation: fade-in 2.5s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remote-field .remote-status {
|
||||
top: 4px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.image-renderer {
|
||||
padding: 10px;
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
padding: 10px;
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.renderer-container {
|
||||
.error-container {
|
||||
color: @term-red;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
}
|
||||
.error-container {
|
||||
color: @term-red;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.scroller {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.scroller {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.renderer-container.code-renderer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.renderer-container.json-renderer {
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown-renderer .markdown {
|
||||
padding: 5px;
|
||||
line-height: 1.5;
|
||||
width: fit-content;
|
||||
padding: 5px;
|
||||
line-height: 1.5;
|
||||
width: fit-content;
|
||||
|
||||
blockquote {
|
||||
background-color: #222;
|
||||
}
|
||||
blockquote {
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #222;
|
||||
font-size: 14px;
|
||||
}
|
||||
code {
|
||||
background-color: #222;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #222;
|
||||
margin: 2px 10px 6px 10px;
|
||||
padding: 4px 4px 4px 6px;
|
||||
}
|
||||
pre {
|
||||
background-color: #222;
|
||||
margin: 2px 10px 6px 10px;
|
||||
padding: 4px 4px 4px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.openai-renderer {
|
||||
.openai-message {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
|
||||
.openai-role {
|
||||
color: @term-bright-green;
|
||||
font-weight: bold;
|
||||
width: 100px;
|
||||
}
|
||||
.openai-message {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
|
||||
.openai-role.openai-role-assistant {
|
||||
color: @term-bright-white;
|
||||
}
|
||||
|
||||
.openai-content-user {
|
||||
white-space: pre;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.openai-content-assistant {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.openai-role-error {
|
||||
color: @term-bright-red;
|
||||
}
|
||||
|
||||
.openai-content-error {
|
||||
color: @term-bright-red;
|
||||
}
|
||||
.openai-role {
|
||||
color: @term-bright-green;
|
||||
font-weight: bold;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.openai-role.openai-role-assistant {
|
||||
color: @term-bright-white;
|
||||
}
|
||||
|
||||
.openai-content-user {
|
||||
white-space: pre;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.openai-content-assistant {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.openai-role-error {
|
||||
color: @term-bright-red;
|
||||
}
|
||||
|
||||
.openai-content-error {
|
||||
color: @term-bright-red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,182 +1,229 @@
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
import {sprintf} from "sprintf-js";
|
||||
import {boundMethod} from "autobind-decorator";
|
||||
import {If, For, When, Otherwise, Choose} from "tsx-control-statements/components";
|
||||
import type {RendererModelInitializeParams, TermOptsType, RendererContext, RendererOpts, SimpleBlobRendererComponent, RendererModelContainerApi, RendererPluginType, PtyDataType, RendererModel, RendererOptsUpdate, LineType, TermContextUnion, RendererContainerType} from "./types";
|
||||
import {PacketDataBuffer} from "./ptydata";
|
||||
import {debounce, throttle} from "throttle-debounce";
|
||||
import { sprintf } from "sprintf-js";
|
||||
import { boundMethod } from "autobind-decorator";
|
||||
import {
|
||||
If,
|
||||
For,
|
||||
When,
|
||||
Otherwise,
|
||||
Choose,
|
||||
} from "tsx-control-statements/components";
|
||||
import type {
|
||||
RendererModelInitializeParams,
|
||||
TermOptsType,
|
||||
RendererContext,
|
||||
RendererOpts,
|
||||
SimpleBlobRendererComponent,
|
||||
RendererModelContainerApi,
|
||||
RendererPluginType,
|
||||
PtyDataType,
|
||||
RendererModel,
|
||||
RendererOptsUpdate,
|
||||
LineType,
|
||||
TermContextUnion,
|
||||
RendererContainerType,
|
||||
} from "./types";
|
||||
import { PacketDataBuffer } from "./ptydata";
|
||||
import { debounce, throttle } from "throttle-debounce";
|
||||
|
||||
type OV<V> = mobx.IObservableValue<V>;
|
||||
type CV<V> = mobx.IComputedValue<V>;
|
||||
|
||||
class SimpleBlobRendererModel {
|
||||
context : RendererContext;
|
||||
opts : RendererOpts;
|
||||
isDone : OV<boolean>;
|
||||
api : RendererModelContainerApi;
|
||||
savedHeight : number;
|
||||
loading : OV<boolean>;
|
||||
loadError : OV<string> = mobx.observable.box(null, {name: "renderer-loadError"});
|
||||
ptyData : PtyDataType;
|
||||
ptyDataSource : (termContext : TermContextUnion) => Promise<PtyDataType>;
|
||||
|
||||
initialize(params : RendererModelInitializeParams) : void {
|
||||
this.loading = mobx.observable.box(true, {name: "renderer-loading"});
|
||||
this.isDone = mobx.observable.box(params.isDone, {name: "renderer-isDone"});
|
||||
this.context = params.context;
|
||||
this.opts = params.opts;
|
||||
this.api = params.api;
|
||||
this.savedHeight = params.savedHeight;
|
||||
this.ptyDataSource = params.ptyDataSource;
|
||||
if (this.isDone.get()) {
|
||||
setTimeout(() => this.reload(0), 10);
|
||||
}
|
||||
}
|
||||
context: RendererContext;
|
||||
opts: RendererOpts;
|
||||
isDone: OV<boolean>;
|
||||
api: RendererModelContainerApi;
|
||||
savedHeight: number;
|
||||
loading: OV<boolean>;
|
||||
loadError: OV<string> = mobx.observable.box(null, {
|
||||
name: "renderer-loadError",
|
||||
});
|
||||
ptyData: PtyDataType;
|
||||
ptyDataSource: (termContext: TermContextUnion) => Promise<PtyDataType>;
|
||||
|
||||
dispose() : void {
|
||||
return;
|
||||
}
|
||||
|
||||
giveFocus() : void {
|
||||
return;
|
||||
initialize(params: RendererModelInitializeParams): void {
|
||||
this.loading = mobx.observable.box(true, { name: "renderer-loading" });
|
||||
this.isDone = mobx.observable.box(params.isDone, {
|
||||
name: "renderer-isDone",
|
||||
});
|
||||
this.context = params.context;
|
||||
this.opts = params.opts;
|
||||
this.api = params.api;
|
||||
this.savedHeight = params.savedHeight;
|
||||
this.ptyDataSource = params.ptyDataSource;
|
||||
if (this.isDone.get()) {
|
||||
setTimeout(() => this.reload(0), 10);
|
||||
}
|
||||
}
|
||||
|
||||
updateOpts(update : RendererOptsUpdate) : void {
|
||||
Object.assign(this.opts, update);
|
||||
}
|
||||
dispose(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
updateHeight(newHeight : number) : void {
|
||||
if (this.savedHeight != newHeight) {
|
||||
this.savedHeight = newHeight;
|
||||
this.api.saveHeight(newHeight);
|
||||
}
|
||||
giveFocus(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
updateOpts(update: RendererOptsUpdate): void {
|
||||
Object.assign(this.opts, update);
|
||||
}
|
||||
|
||||
updateHeight(newHeight: number): void {
|
||||
if (this.savedHeight != newHeight) {
|
||||
this.savedHeight = newHeight;
|
||||
this.api.saveHeight(newHeight);
|
||||
}
|
||||
|
||||
setIsDone() : void {
|
||||
if (this.isDone.get()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setIsDone(): void {
|
||||
if (this.isDone.get()) {
|
||||
return;
|
||||
}
|
||||
mobx.action(() => {
|
||||
this.isDone.set(true);
|
||||
})();
|
||||
this.reload(0);
|
||||
}
|
||||
|
||||
reload(delayMs: number): void {
|
||||
mobx.action(() => {
|
||||
this.loading.set(true);
|
||||
})();
|
||||
let rtnp = this.ptyDataSource(this.context);
|
||||
if (rtnp == null) {
|
||||
console.log(
|
||||
"no promise returned from ptyDataSource (simplerenderer)",
|
||||
this.context
|
||||
);
|
||||
return;
|
||||
}
|
||||
rtnp
|
||||
.then((ptydata) => {
|
||||
setTimeout(() => {
|
||||
this.ptyData = ptydata;
|
||||
mobx.action(() => {
|
||||
this.loading.set(false);
|
||||
this.loadError.set(null);
|
||||
})();
|
||||
}, delayMs);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("error loading data", e);
|
||||
mobx.action(() => {
|
||||
this.isDone.set(true);
|
||||
this.loadError.set("error loading data: " + e);
|
||||
})();
|
||||
this.reload(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reload(delayMs : number) : void {
|
||||
mobx.action(() => {
|
||||
this.loading.set(true);
|
||||
})();
|
||||
let rtnp = this.ptyDataSource(this.context);
|
||||
if (rtnp == null) {
|
||||
console.log("no promise returned from ptyDataSource (simplerenderer)", this.context);
|
||||
return;
|
||||
}
|
||||
rtnp.then((ptydata) => {
|
||||
setTimeout(() => {
|
||||
this.ptyData = ptydata;
|
||||
mobx.action(() => {
|
||||
this.loading.set(false);
|
||||
this.loadError.set(null);
|
||||
})();
|
||||
}, delayMs);
|
||||
}).catch((e) => {
|
||||
console.log("error loading data", e);
|
||||
mobx.action(() => {
|
||||
this.loadError.set("error loading data: " + e);
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
receiveData(pos : number, data : Uint8Array, reason? : string) : void {
|
||||
// this.dataBuf.receiveData(pos, data, reason);
|
||||
}
|
||||
receiveData(pos: number, data: Uint8Array, reason?: string): void {
|
||||
// this.dataBuf.receiveData(pos, data, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@mobxReact.observer
|
||||
class SimpleBlobRenderer extends React.Component<{rendererContainer : RendererContainerType, lineId : string, plugin : RendererPluginType, onHeightChange : () => void, initParams : RendererModelInitializeParams}, {}> {
|
||||
model : SimpleBlobRendererModel;
|
||||
wrapperDivRef : React.RefObject<any> = React.createRef();
|
||||
rszObs : ResizeObserver;
|
||||
updateHeight_debounced : (newHeight : number) => void;
|
||||
class SimpleBlobRenderer extends React.Component<
|
||||
{
|
||||
rendererContainer: RendererContainerType;
|
||||
lineId: string;
|
||||
plugin: RendererPluginType;
|
||||
onHeightChange: () => void;
|
||||
initParams: RendererModelInitializeParams;
|
||||
},
|
||||
{}
|
||||
> {
|
||||
model: SimpleBlobRendererModel;
|
||||
wrapperDivRef: React.RefObject<any> = React.createRef();
|
||||
rszObs: ResizeObserver;
|
||||
updateHeight_debounced: (newHeight: number) => void;
|
||||
|
||||
constructor(props : any) {
|
||||
super(props);
|
||||
let {rendererContainer, lineId, plugin, initParams} = this.props;
|
||||
this.model = new SimpleBlobRendererModel();
|
||||
this.model.initialize(initParams);
|
||||
rendererContainer.registerRenderer(lineId, this.model);
|
||||
this.updateHeight_debounced = debounce(1000, this.updateHeight.bind(this));
|
||||
}
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
let { rendererContainer, lineId, plugin, initParams } = this.props;
|
||||
this.model = new SimpleBlobRendererModel();
|
||||
this.model.initialize(initParams);
|
||||
rendererContainer.registerRenderer(lineId, this.model);
|
||||
this.updateHeight_debounced = debounce(1000, this.updateHeight.bind(this));
|
||||
}
|
||||
|
||||
updateHeight(newHeight : number) : void {
|
||||
this.model.updateHeight(newHeight);
|
||||
}
|
||||
updateHeight(newHeight: number): void {
|
||||
this.model.updateHeight(newHeight);
|
||||
}
|
||||
|
||||
handleResize(entries : ResizeObserverEntry[]) : void {
|
||||
if (this.model.loading.get()) {
|
||||
return;
|
||||
}
|
||||
if (this.props.onHeightChange) {
|
||||
this.props.onHeightChange();
|
||||
}
|
||||
if (!this.model.loading.get() && this.wrapperDivRef.current != null) {
|
||||
let height = this.wrapperDivRef.current.offsetHeight;
|
||||
this.updateHeight_debounced(height);
|
||||
}
|
||||
handleResize(entries: ResizeObserverEntry[]): void {
|
||||
if (this.model.loading.get()) {
|
||||
return;
|
||||
}
|
||||
if (this.props.onHeightChange) {
|
||||
this.props.onHeightChange();
|
||||
}
|
||||
if (!this.model.loading.get() && this.wrapperDivRef.current != null) {
|
||||
let height = this.wrapperDivRef.current.offsetHeight;
|
||||
this.updateHeight_debounced(height);
|
||||
}
|
||||
}
|
||||
|
||||
checkRszObs() {
|
||||
if (this.rszObs != null) {
|
||||
return;
|
||||
}
|
||||
if (this.wrapperDivRef.current == null) {
|
||||
return;
|
||||
}
|
||||
this.rszObs = new ResizeObserver(this.handleResize.bind(this));
|
||||
this.rszObs.observe(this.wrapperDivRef.current);
|
||||
checkRszObs() {
|
||||
if (this.rszObs != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.checkRszObs();
|
||||
if (this.wrapperDivRef.current == null) {
|
||||
return;
|
||||
}
|
||||
this.rszObs = new ResizeObserver(this.handleResize.bind(this));
|
||||
this.rszObs.observe(this.wrapperDivRef.current);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
let {rendererContainer, lineId} = this.props;
|
||||
rendererContainer.unloadRenderer(lineId);
|
||||
if (this.rszObs != null) {
|
||||
this.rszObs.disconnect();
|
||||
this.rszObs = null;
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
this.checkRszObs();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.checkRszObs();
|
||||
componentWillUnmount() {
|
||||
let { rendererContainer, lineId } = this.props;
|
||||
rendererContainer.unloadRenderer(lineId);
|
||||
if (this.rszObs != null) {
|
||||
this.rszObs.disconnect();
|
||||
this.rszObs = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let {plugin} = this.props;
|
||||
let model = this.model;
|
||||
if (model.loading.get()) {
|
||||
let height = this.model.savedHeight;
|
||||
return (<div ref={this.wrapperDivRef} style={{minHeight: height}}>...</div>);
|
||||
}
|
||||
let Comp = plugin.simpleComponent;
|
||||
if (Comp == null) {
|
||||
<div ref={this.wrapperDivRef}>
|
||||
(no component found in plugin)
|
||||
</div>
|
||||
}
|
||||
let dataBlob = new Blob([model.ptyData.data]);
|
||||
let simpleModel = (model as SimpleBlobRendererModel);
|
||||
return (
|
||||
<div ref={this.wrapperDivRef}>
|
||||
<Comp data={dataBlob} context={simpleModel.context} opts={simpleModel.opts} savedHeight={simpleModel.savedHeight}/>
|
||||
</div>
|
||||
);
|
||||
componentDidUpdate() {
|
||||
this.checkRszObs();
|
||||
}
|
||||
|
||||
render() {
|
||||
let { plugin } = this.props;
|
||||
let model = this.model;
|
||||
if (model.loading.get()) {
|
||||
let height = this.model.savedHeight;
|
||||
return (
|
||||
<div ref={this.wrapperDivRef} style={{ minHeight: height }}>
|
||||
...
|
||||
</div>
|
||||
);
|
||||
}
|
||||
let Comp = plugin.simpleComponent;
|
||||
if (Comp == null) {
|
||||
<div ref={this.wrapperDivRef}>(no component found in plugin)</div>;
|
||||
}
|
||||
let dataBlob = new Blob([model.ptyData.data]);
|
||||
let simpleModel = model as SimpleBlobRendererModel;
|
||||
let { festate, cmdstr } = this.props.initParams.rawCmd;
|
||||
return (
|
||||
<div ref={this.wrapperDivRef}>
|
||||
<Comp
|
||||
cwd={festate.cwd}
|
||||
cmdstr={cmdstr}
|
||||
data={dataBlob}
|
||||
context={simpleModel.context}
|
||||
opts={simpleModel.opts}
|
||||
savedHeight={simpleModel.savedHeight}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export {SimpleBlobRendererModel, SimpleBlobRenderer};
|
||||
|
||||
export { SimpleBlobRendererModel, SimpleBlobRenderer };
|
||||
|
@ -409,23 +409,19 @@ type RendererModel = {
|
||||
};
|
||||
|
||||
type SimpleBlobRendererComponent = React.ComponentType<{
|
||||
path: String;
|
||||
data: Blob;
|
||||
context: RendererContext;
|
||||
opts: RendererOpts;
|
||||
savedHeight: number;
|
||||
}>;
|
||||
// @mike - I guess we can remove SimpleJsonRendererComponent - its doesnt have any references
|
||||
type SimpleJsonRendererComponent = React.ComponentType<{
|
||||
data: any;
|
||||
context: RendererContext;
|
||||
opts: RendererOpts;
|
||||
savedHeight: number;
|
||||
}>;
|
||||
type SimpleCodeRendererComponent = React.ComponentType<{
|
||||
data: any;
|
||||
context: RendererContext;
|
||||
opts: RendererOpts;
|
||||
savedHeight: number;
|
||||
}>;
|
||||
type FullRendererComponent = React.ComponentType<{ model: any }>;
|
||||
|
||||
type WindowSize = {
|
||||
|
@ -15,9 +15,10 @@ type OV<V> = mobx.IObservableValue<V>;
|
||||
const MaxJsonSize = 50000;
|
||||
|
||||
@mobxReact.observer
|
||||
class CodeRenderer extends React.Component<
|
||||
class SourceCodeRenderer extends React.Component<
|
||||
{
|
||||
data: Blob;
|
||||
path: String;
|
||||
context: RendererContext;
|
||||
opts: RendererOpts;
|
||||
savedHeight: number;
|
||||
@ -33,17 +34,34 @@ class CodeRenderer extends React.Component<
|
||||
deep: false,
|
||||
});
|
||||
|
||||
componentDidMount() {
|
||||
let dataBlob = this.props.data;
|
||||
let prtn = dataBlob.text();
|
||||
prtn.then((text) => {
|
||||
this.code.set(text);
|
||||
const detectedLanguage = `javascript`;
|
||||
this.language.set(detectedLanguage);
|
||||
console.log(`1. ${detectedLanguage}\n\n${text}\n\n`);
|
||||
});
|
||||
editorRef;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.editorRef = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let prtn = this.props.data.text();
|
||||
prtn.then((text) => this.code.set(text));
|
||||
}
|
||||
|
||||
handleEditorDidMount = (editor, monaco) => {
|
||||
const extension = this.props.cmdstr.split(".").pop();
|
||||
const detectedLanguage = monaco.languages
|
||||
.getLanguages()
|
||||
.find(
|
||||
(lang) => lang.extensions && lang.extensions.includes("." + extension)
|
||||
);
|
||||
if (detectedLanguage) {
|
||||
this.editorRef.current = editor;
|
||||
const model = editor.getModel();
|
||||
if (model) {
|
||||
monaco.editor.setModelLanguage(model, detectedLanguage.id);
|
||||
this.language.set(detectedLanguage.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
let opts = this.props.opts;
|
||||
let maxWidth = opts.maxSize.width;
|
||||
@ -53,16 +71,20 @@ class CodeRenderer extends React.Component<
|
||||
}
|
||||
let lang = this.language.get();
|
||||
let code = this.code.get();
|
||||
console.log(`2. ${lang}\n\n${code}\n\n`);
|
||||
if (!lang) return <></>;
|
||||
if (!code) return <></>;
|
||||
return (
|
||||
<div className="renderer-container json-renderer">
|
||||
<div className="renderer-container code-renderer">
|
||||
<div className="scroller" style={{ maxHeight: opts.maxSize.height }}>
|
||||
<Editor
|
||||
height="30vh"
|
||||
theme="vs-dark"
|
||||
theme="hc-black"
|
||||
defaultLanguage={lang}
|
||||
defaultValue={code}
|
||||
onMount={this.handleEditorDidMount}
|
||||
options={{
|
||||
scrollBeyondLastLine: false,
|
||||
fontSize: "14px",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -70,4 +92,4 @@ class CodeRenderer extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
export { CodeRenderer };
|
||||
export { SourceCodeRenderer };
|
||||
|
Loading…
Reference in New Issue
Block a user