Pe 107 global changes (#26)

* chaged background etc. now making font changes

* need to go component by component now
This commit is contained in:
anandamarsh 2023-09-27 15:03:08 -07:00 committed by GitHub
parent a25c7b4286
commit b1820224d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 545 additions and 966 deletions

View File

@ -3,7 +3,7 @@
.info-message {
position: relative;
font-weight: normal;
font-size: 12px;
color: @term-white;
.message-content {
@ -52,7 +52,6 @@
}
.code-div code {
.mono-font(14px);
}
}
@ -68,7 +67,7 @@
flex-grow: 0;
padding: 3px;
border-radius: 3px 0 0 3px;
font-size: 12px;
height: 22px;
width: 22px;
display: flex;
@ -76,7 +75,7 @@
justify-content: center;
align-self: flex-start;
cursor: pointer;
background-color: black;
background-color: @term-black;
&:hover {
background-color: #777;
@ -84,7 +83,7 @@
}
.code-div {
background-color: black;
background-color: @term-black;
display: flex;
flex-direction: row;
min-width: 100px;
@ -94,11 +93,10 @@
code {
flex-shrink: 0;
min-width: 100px;
color: white;
.mono-font(12px);
color: @term-white;
white-space: pre;
padding: 2px 8px 2px 8px;
background-color: black;
background-color: @term-black;
}
}
@ -112,16 +110,16 @@
position: absolute;
bottom: -1px;
right: -20px;
font-size: 9px;
padding: 2px;
padding-left: 4px;
cursor: pointer;
width: 20px;
background-color: black;
background-color: @term-black;
border: 1px solid #333;
color: #777;
&:hover {
color: white;
color: @term-white;
}
}
}
@ -130,7 +128,6 @@
visibility: visible !important;
}
}
.terminal-wrapper {
position: relative;
@ -223,7 +220,7 @@ body .xterm .xterm-viewport {
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
background-color: @term-white;
transition: 0.5s;
border-radius: 50%;
}
@ -277,7 +274,6 @@ body .xterm .xterm-viewport {
}
.cmd-hints {
.mono-font(10px);
display: flex;
flex-direction: row;
@ -292,22 +288,22 @@ body .xterm .xterm-viewport {
}
.hint-item.color-green {
color: black;
color: @term-black;
background-color: @tab-green;
&:hover {
color: white;
color: @term-white;
}
}
.hint-item.color-nohover-green {
color: black;
color: @term-black;
background-color: @tab-green;
cursor: default;
}
.hint-item.color-white {
color: black;
color: @term-black;
background-color: @term-white;
&:hover {
@ -316,22 +312,22 @@ body .xterm .xterm-viewport {
}
.hint-item.color-nohover-white {
color: black;
color: @term-black;
background-color: @term-white;
cursor: default;
}
.hint-item.color-blue {
color: black;
color: @term-black;
background-color: @tab-blue;
&:hover {
color: white;
color: @term-white;
}
}
.hint-item.color-nohover-blue {
color: black;
color: @term-black;
background-color: @tab-blue;
cursor: default;
}
@ -342,9 +338,8 @@ body .xterm .xterm-viewport {
margin-bottom: 10px;
code {
background-color: black;
color: white;
.mono-font();
background-color: @term-black;
color: @term-white;
padding: 5px;
}
@ -354,14 +349,13 @@ body .xterm .xterm-viewport {
}
.title {
color: white;
color: @term-white;
margin-top: 16px;
line-height: 1.25;
margin-bottom: 8px;
}
strong {
color: white;
color: @term-white;
}
a {
@ -370,7 +364,7 @@ body .xterm .xterm-viewport {
table {
tr th {
color: white;
color: @term-white;
}
}
@ -399,26 +393,20 @@ body .xterm .xterm-viewport {
}
.title.is-1 {
font-size: 32px;
border-bottom: 1px solid #777;
padding-bottom: 6px;
}
.title.is-2 {
font-size: 24px;
border-bottom: 1px solid #777;
padding-bottom: 6px;
}
.title.is-3 {
font-size: 20px;
}
.title.is-4 {
font-size: 16px;
}
.title.is-5 {
font-size: 14px;
}
.title.is-6 {
font-size: 14px;
}
}
@ -432,14 +420,13 @@ body .xterm .xterm-viewport {
left: 0;
width: 100%;
height: 100%;
background-color: white;
background-color: @term-white;
opacity: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
pointer-events: none;
.mono-font(12px);
animation-name: fade-in-out;
animation-duration: 0.3s;
}
@ -483,17 +470,12 @@ body .xterm .xterm-viewport {
z-index: -1;
top: -5000px;
.mono {
.mono-font();
}
.pre {
white-space: pre;
}
}
.text-button {
.mono-font(12px, 700);
color: @term-white;
cursor: pointer;
background-color: #171717;
@ -584,8 +566,6 @@ body .xterm .xterm-viewport {
}
#main .term-prompt {
font-size: 14px;
i {
margin-right: 3px;
}
@ -650,7 +630,6 @@ body .xterm .xterm-viewport {
}
.remote-status {
font-size: 8px;
margin-right: 5px;
position: relative;
top: -3px;

View File

@ -0,0 +1,189 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { If } from "tsx-control-statements/components";
import { GlobalModel } from "../../model";
import { termHeightFromRows } from "../../util/textmeasure";
import type { LineType } from "../../types";
import cn from "classnames";
import type { LineContainerModel } from "../../model";
import * as lineutil from "../../main/line/lineutil";
import "./terminal.less";
dayjs.extend(localizedFormat);
type OV<V> = mobx.IObservableValue<V>;
type OArr<V> = mobx.IObservableArray<V>;
type OMap<K, V> = mobx.ObservableMap<K, V>;
@mobxReact.observer
class TerminalRenderer extends React.Component<
{
screen: LineContainerModel;
line: LineType;
width: number;
staticRender: boolean;
visible: OV<boolean>;
onHeightChange: () => void;
collapsed: boolean;
},
{}
> {
termLoaded: mobx.IObservableValue<boolean> = mobx.observable.box(false, {
name: "linecmd-term-loaded",
});
elemRef: React.RefObject<any> = React.createRef();
termRef: React.RefObject<any> = React.createRef();
constructor(props) {
super(props);
}
componentDidMount() {
this.componentDidUpdate(null, null, null);
}
componentWillUnmount() {
if (this.termLoaded.get()) {
this.unloadTerminal(true);
}
}
getSnapshotBeforeUpdate(prevProps, prevState): { height: number } {
let elem = this.elemRef.current;
if (elem == null) {
return { height: 0 };
}
return { height: elem.offsetHeight };
}
componentDidUpdate(prevProps, prevState, snapshot: { height: number }): void {
if (this.props.onHeightChange == null) {
return;
}
let { line } = this.props;
let curHeight = 0;
let elem = this.elemRef.current;
if (elem != null) {
curHeight = elem.offsetHeight;
}
if (snapshot == null) {
snapshot = { height: 0 };
}
if (snapshot.height != curHeight) {
this.props.onHeightChange();
// console.log("term-render height change: ", line.linenum, snapshot.height, "=>", curHeight);
}
this.checkLoad();
}
checkLoad(): void {
let { line, staticRender, visible, collapsed } = this.props;
if (staticRender) {
return;
}
let vis = visible && visible.get() && !collapsed;
let curVis = this.termLoaded.get();
if (vis && !curVis) {
this.loadTerminal();
} else if (!vis && curVis) {
this.unloadTerminal(false);
}
}
loadTerminal(): void {
let { screen, line } = this.props;
let model = GlobalModel;
let cmd = screen.getCmd(line);
if (cmd == null) {
return;
}
let termElem = this.termRef.current;
if (termElem == null) {
console.log("cannot load terminal, no term elem found", line);
return;
}
screen.loadTerminalRenderer(termElem, line, cmd, this.props.width);
mobx.action(() => this.termLoaded.set(true))();
}
unloadTerminal(unmount: boolean): void {
let { screen, line } = this.props;
screen.unloadRenderer(line.lineid);
if (!unmount) {
mobx.action(() => this.termLoaded.set(false))();
let termElem = this.termRef.current;
if (termElem != null) {
termElem.replaceChildren();
}
}
}
@boundMethod
clickTermBlock(e: any) {
let { screen, line } = this.props;
let model = GlobalModel;
let termWrap = screen.getTermWrap(line.lineid);
if (termWrap != null) {
termWrap.giveFocus();
}
}
render() {
let { screen, line, width, staticRender, visible, collapsed } = this.props;
let isVisible = visible.get(); // for reaction
let isPhysicalFocused = mobx
.computed(() => screen.getIsFocused(line.linenum), {
name: "computed-getIsFocused",
})
.get();
let isFocused = mobx
.computed(
() => {
let screenFocusType = screen.getFocusType();
return isPhysicalFocused && screenFocusType == "cmd";
},
{ name: "computed-isFocused" }
)
.get();
let cmd = screen.getCmd(line); // will not be null
let usedRows = screen.getUsedRows(lineutil.getRendererContext(line), line, cmd, width);
let termHeight = termHeightFromRows(usedRows, GlobalModel.termFontSize.get());
let termLoaded = this.termLoaded.get();
return (
<div
ref={this.elemRef}
key="term-wrap"
className={cn(
"terminal-wrapper",
{ focus: isFocused },
{ "cmd-done": !cmd.isRunning() },
{ "zero-height": termHeight == 0 },
{ collapsed: collapsed }
)}
>
<If condition={!isFocused}>
<div key="term-block" className="term-block" onClick={this.clickTermBlock}></div>
</If>
<div
key="term-connectelem"
className="terminal-connectelem"
ref={this.termRef}
data-lineid={line.lineid}
style={{ height: termHeight }}
></div>
<If condition={!termLoaded}>
<div key="term-loading" className="terminal-loading-message">
...
</div>
</If>
</div>
);
}
}
export { TerminalRenderer };

View File

@ -1,5 +1,5 @@
import * as mobx from "mobx";
import { incObs } from "./util";
import { incObs } from "../../util/util";
type OV<V> = mobx.IObservableValue<V>;
type OArr<V> = mobx.IObservableArray<V>;

View File

@ -2,10 +2,17 @@ import * as mobx from "mobx";
import { Terminal } from "xterm";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import { v4 as uuidv4 } from "uuid";
import { termHeightFromRows, windowWidthToCols, windowHeightToRows } from "./textmeasure";
import { boundInt } from "./util";
import type { TermContextUnion, TermOptsType, TermWinSize, RendererContext, WindowSize, PtyDataType } from "./types";
import { windowWidthToCols, windowHeightToRows } from "../../util/textmeasure";
import { boundInt } from "../../util/util";
import type {
TermContextUnion,
TermOptsType,
TermWinSize,
RendererContext,
WindowSize,
PtyDataType,
} from "../../types";
import { getTheme } from "../../themes";
type DataUpdate = {
data: Uint8Array;
@ -77,15 +84,13 @@ class TermWrap {
let cols = windowWidthToCols(opts.winSize.width, opts.fontSize);
this.termSize = { rows: opts.termOpts.rows, cols: cols };
}
let theme = {
foreground: "#d3d7cf",
};
const { terminal } = getTheme();
this.terminal = new Terminal({
rows: this.termSize.rows,
cols: this.termSize.cols,
fontSize: opts.fontSize,
fontFamily: "JetBrains Mono",
theme: theme,
theme: { foreground: terminal.foreground, background: terminal.background },
/*fontFamily: "JetBrains Mono", @check:font */
});
this.terminal._core._inputHandler._parser.setErrorHandler((state) => {
this.numParseErrors++;

View File

@ -1,4 +1,7 @@
@import "../../index.less";
/**
* Adapted from xterm.css
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
@ -79,7 +82,7 @@
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
color: #fff;
display: none;
position: absolute;
white-space: nowrap;
@ -122,7 +125,6 @@
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm.enable-mouse-events {
@ -166,33 +168,53 @@
opacity: 1 !important;
}
.xterm-underline-1 { text-decoration: underline; }
.xterm-underline-2 { text-decoration: double underline; }
.xterm-underline-3 { text-decoration: wavy underline; }
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }
.xterm-underline-1 {
text-decoration: underline;
}
.xterm-underline-2 {
text-decoration: double underline;
}
.xterm-underline-3 {
text-decoration: wavy underline;
}
.xterm-underline-4 {
text-decoration: dotted underline;
}
.xterm-underline-5 {
text-decoration: dashed underline;
}
.xterm-overline {
text-decoration: overline;
}
.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }
.xterm-overline.xterm-underline-1 {
text-decoration: overline underline;
}
.xterm-overline.xterm-underline-2 {
text-decoration: overline double underline;
}
.xterm-overline.xterm-underline-3 {
text-decoration: overline wavy underline;
}
.xterm-overline.xterm-underline-4 {
text-decoration: overline dotted underline;
}
.xterm-overline.xterm-underline-5 {
text-decoration: overline dashed underline;
}
.xterm-strikethrough {
text-decoration: line-through;
}
.xterm-screen .xterm-decoration-container .xterm-decoration {
z-index: 6;
position: absolute;
z-index: 6;
position: absolute;
}
.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
z-index: 7;
z-index: 7;
}
.xterm-decoration-overview-ruler {

View File

@ -4,7 +4,7 @@ import * as fs from "fs";
import fetch from "node-fetch";
import * as child_process from "node:child_process";
import { debounce } from "throttle-debounce";
import { handleJsonFetchResponse } from "./util";
import { handleJsonFetchResponse } from "./util/util";
import * as winston from "winston";
import * as util from "util";
import { sprintf } from "sprintf-js";
@ -201,12 +201,12 @@ function createMainWindow(clientData) {
let win = new electron.BrowserWindow({
x: bounds.x,
y: bounds.y,
titleBarStyle: "hiddenInset",
width: bounds.width,
height: bounds.height,
webPreferences: {
preload: path.join(getAppBasePath(), DistDir, "preload.js"),
},
backgroundColor: "#000",
});
let indexHtml = isDev ? "index-dev.html" : "index.html";
win.loadFile(path.join(getAppBasePath(), "static", indexHtml));

Binary file not shown.

View File

@ -1,3 +1,7 @@
@base-color: #eceeec;
@base-background: rgba(21, 23, 21, 1);
@base-background-dev: rgba(21, 23, 21, 1);
@term-black: #000000;
@term-red: #cc0000;
@term-green: #4e9a06;
@ -34,20 +38,38 @@
@active-menu-color: rgb(0, 71, 171);
@import "utils.less";
// global settings / overrides
@font-face {
font-family: "Martian Mono";
src: url("./fonts/MartianMono-VariableFont_wdth,wght.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
:root {
--fa-style-family: "Font Awesome 6 Sharp";
}
html,
body,
#app,
#main {
background-color: #000;
height: 100vh;
body {
overflow: hidden;
font-family: "Martian Mono", sans-serif;
font-size: 12.5px;
font-weight: 300;
line-height: 20px;
background: @base-background;
color: @base-color;
}
#title-bar {
-webkit-app-region: drag;
height: 30px;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.is-dev #title-bar {
background: @base-background-dev;
}
.content {
@ -56,10 +78,6 @@ body,
}
}
body {
overflow: hidden;
}
body::-webkit-scrollbar {
display: none;
}
@ -78,16 +96,35 @@ input[type="checkbox"] {
cursor: pointer;
}
.display-none {
display: none;
}
.flex-spacer {
flex-grow: 1;
}
.flex-centered-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
a.a-block {
display: block;
}
// main layout
#main {
height: 100vh;
margin-top: 30px;
height: calc(100vh - 30px);
display: flex;
flex-direction: column;
.main-content {
display: flex;
flex-direction: row;
background-color: black;
height: 100%;
.session-view,
@ -120,38 +157,37 @@ input[type="checkbox"] {
top: 0;
right: 0;
background-color: rgba(78, 154, 6, 0.65);
color: black;
color: @term-black;
padding: 2px 8px 2px 4px;
border-bottom-left-radius: 5px;
z-index: 10;
font-size: 12px;
&.is-active {
color: #ccc;
color: @term-white;
}
.render-mode {
padding-top: 2px;
font-size: 16px;
position: relative;
cursor: pointer;
color: #ccc;
color: @term-white;
&:hover {
color: white;
color: @term-white;
}
}
}
.share-tag {
color: #ccc;
color: @term-white;
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;
@ -164,7 +200,6 @@ input[type="checkbox"] {
&:hover {
.share-tag-title {
font-size: 14px;
font-weight: bold;
}
opacity: 1;
@ -189,11 +224,10 @@ input[type="checkbox"] {
width: 100%;
padding: 10px;
height: 100%;
color: #ccc;
.mono-font();
color: @term-white;
code {
background-color: black;
background-color: @term-black;
color: #4e9a06;
}
@ -206,169 +240,19 @@ input[type="checkbox"] {
}
}
.remote-field .remote-status {
top: 4px;
}
.terminal-wrapper {
position: relative;
.term-block {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
z-index: 10;
}
.xterm-screen {
&::-webkit-scrollbar {
display: none;
}
}
&.focus .xterm {
.xterm-screen {
overflow-y: scroll;
overscroll-behavior: contain;
}
.xterm-viewport {
overscroll-behavior: contain;
}
}
&.focus .xterm-viewport {
&::-webkit-scrollbar {
background-color: #777;
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-thumb {
background: white;
}
}
.xterm-viewport {
&::-webkit-scrollbar {
background-color: #222;
width: 5px;
height: 5px;
}
&::-webkit-scrollbar-thumb {
background: #555;
}
}
}
body .xterm .xterm-viewport {
overflow-y: auto;
width: calc(100% + 5px);
}
.checkbox-toggle {
position: relative;
display: inline-block;
width: 40px;
height: 23px;
input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
content: "";
cursor: pointer;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #333;
transition: 0.5s;
border-radius: 33px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.5s;
border-radius: 50%;
}
input:checked + .slider {
background-color: @term-green;
}
input:checked + .slider:before {
transform: translateX(18px);
}
}
.button.is-prompt-green {
background-color: #222;
color: @term-white;
&:hover {
background-color: @term-green;
color: @term-bright-white;
}
}
.button.is-plain,
.button.is-prompt-cancel {
background-color: #222;
color: @term-white;
&:hover {
background-color: #666;
color: @term-bright-white;
}
}
.button.is-prompt-danger {
background-color: #222;
color: @term-white;
&:hover {
background-color: @tab-red;
color: @term-bright-white;
}
}
.button.is-inline-height {
height: 22px;
}
.button input.confirm-checkbox {
margin-right: 5px;
}
.copied-indicator {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
background-color: @term-white;
opacity: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
pointer-events: none;
.mono-font(12px);
animation-name: fade-in-out;
animation-duration: 0.3s;
}
@ -412,17 +296,12 @@ body .xterm .xterm-viewport {
z-index: -1;
top: -5000px;
.mono {
.mono-font();
}
.pre {
white-space: pre;
}
}
.text-button {
.mono-font(12px, 700);
color: @term-white;
cursor: pointer;
background-color: #171717;
@ -513,8 +392,6 @@ body .xterm .xterm-viewport {
}
#main .term-prompt {
font-size: 14px;
i {
margin-right: 3px;
}
@ -579,7 +456,6 @@ body .xterm .xterm-viewport {
}
.remote-status {
font-size: 8px;
margin-right: 5px;
position: relative;
top: -3px;

View File

@ -3,7 +3,7 @@ import * as React from "react";
import { createRoot } from "react-dom/client";
import { sprintf } from "sprintf-js";
import { Main } from "./main/Main";
import { loadFonts } from "./util";
import { loadFonts } from "./util/util";
import * as DOMPurify from "dompurify";
// @ts-ignore
@ -17,14 +17,11 @@ document.addEventListener("DOMContentLoaded", () => {
let reactElem = React.createElement(Main, null, null);
let elem = document.getElementById("app");
let root = createRoot(elem);
let isFontLoaded = document.fonts.check("12px 'JetBrains Mono'");
if (isFontLoaded) {
// @check:font
// let isFontLoaded = document.fonts.check("12px 'JetBrains Mono'");
document.fonts.ready.then(() => {
root.render(reactElem);
} else {
document.fonts.ready.then(() => {
root.render(reactElem);
});
}
});
});
(window as any).mobx = mobx;

View File

@ -7,17 +7,17 @@ import dayjs from "dayjs";
import type { ContextMenuOpts } from "../types";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "../model";
import { isBlank } from "../util";
import { isBlank } from "../util/util";
import { BookmarksView } from "./bookmarks/bookmarks";
import { WebShareView } from "../webshare/webshare-client-view";
import { HistoryView } from "./history/history";
import { ScreenSettingsModal, SessionSettingsModal, LineSettingsModal, ClientSettingsModal } from "./modals/settings";
import { RemotesModal } from "../remotes/remotes";
import { TosModal } from "./modals/Modals";
import { SessionView } from "./sessionview/SessionView";
import { MainSideBar } from "./sidebar/MainSideBar";
import { DisconnectedModal, ClientStopModal, AlertModal, WelcomeModal } from "./modals/Modals";
import "../index.less";
dayjs.extend(localizedFormat);
@ -29,6 +29,7 @@ class Main extends React.Component<{}, {}> {
constructor(props: any) {
super(props);
if (GlobalModel.isDev) document.body.className = "is-dev";
}
@boundMethod

View File

@ -2,7 +2,7 @@
.bookmarks-view {
.bookmarks-list {
color: white;
color: @term-white;
margin: 4px 10px 5px 5px;
.no-bookmarks {
@ -42,19 +42,15 @@
}
label {
color: white;
color: @term-white;
margin-bottom: 4px;
}
textarea {
width: 80%;
min-width: 50%;
color: white;
background-color: black;
&.mono-font {
.mono-font(12px);
}
color: @term-white;
background-color: @term-black;
}
.bookmark-id-div {
@ -63,7 +59,6 @@
color: #666;
right: 5px;
bottom: 2px;
.mono-font(8px);
}
&:hover .bookmark-id-div {
@ -73,7 +68,7 @@
.bookmark-controls {
display: flex;
flex-direction: row;
font-size: 16px;
visibility: hidden;
color: @term-white;

View File

@ -99,7 +99,7 @@ class Bookmark extends React.Component<{ bookmark: BookmarkType }, {}> {
<label className="label">Description (markdown)</label>
<div className="control">
<textarea
className="textarea mono-font"
className="textarea"
rows={6}
value={model.tempDesc.get()}
onChange={this.handleDescChange}
@ -110,7 +110,7 @@ class Bookmark extends React.Component<{ bookmark: BookmarkType }, {}> {
<label className="label">Command</label>
<div className="control">
<textarea
className="textarea mono-font"
className="textarea"
rows={3}
value={model.tempCmd.get()}
onChange={this.handleCmdChange}

View File

@ -1,11 +1,10 @@
@import "../../index.less";
.history-view {
color: #ccc;
color: @term-white;
.close-div {
padding-top: 10px;
font-size: 24px;
i {
padding: 5px 5px 5px 10px;
@ -25,17 +24,16 @@
.history-title {
margin-top: 5px;
.mono-font(1.5rem);
font-weight: bold;
color: white;
color: @term-white;
}
input {
background-color: #333;
color: white;
color: @term-white;
i {
color: white;
color: @term-white;
}
}
}
@ -63,7 +61,7 @@
.session-dropdown,
.remote-dropdown {
.dropdown-item {
color: white;
color: @term-white;
cursor: pointer;
&:hover {
background-color: #666;
@ -84,7 +82,7 @@
margin-left: 15px;
border: 1px solid #777;
padding: 5px 10px 5px 10px;
font-size: 12px;
display: flex;
flex-direction: row;
align-items: center;
@ -105,7 +103,6 @@
}
.fromts {
font-size: 12px;
display: flex;
flex-direction: row;
align-items: center;
@ -118,7 +115,7 @@
.reset-button {
cursor: pointer;
margin-left: 15px;
font-size: 12px;
border: 1px solid #777;
padding: 5px 10px 5px 10px;
@ -150,12 +147,12 @@
.control-checkbox {
cursor: pointer;
color: #777;
font-size: 18px;
width: 24px;
margin-left: 14px;
&:hover {
color: white;
color: @term-white;
}
}
@ -163,7 +160,6 @@
cursor: pointer;
color: #aaa;
margin-left: 10px;
font-size: 14px;
&.is-disabled {
cursor: default;
@ -174,7 +170,7 @@
}
&:hover {
color: white;
color: @term-white;
}
&.delete-button.is-active {
@ -187,14 +183,13 @@
}
.showing-text {
font-size: 16px;
margin-right: 10px;
}
.showing-btn {
padding: 0 5px 0 5px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
&.is-disabled {
@ -213,7 +208,6 @@
display: flex;
flex-direction: row;
justify-content: center;
.mono-font(14px);
padding: 30px 0 30px 0;
border: 1px solid white;
border-radius: 3px;
@ -232,11 +226,10 @@
.line-container {
padding: 0px 10px 10px 10px;
overflow-x: auto;
background-color: black;
background-color: @term-black;
}
.line-context {
.mono-font(12px);
margin-left: 20px;
margin-bottom: 10px;
margin-top: 10px;
@ -245,10 +238,10 @@
.vic-btn {
cursor: pointer;
color: #ccc;
color: @term-white;
&:hover {
color: white;
color: @term-white;
}
}
}
@ -258,7 +251,6 @@
}
.line-container.no-line {
.mono-font(12px);
display: flex;
flex-direction: row;
align-items: center;
@ -299,14 +291,14 @@
td.selectbox {
flex: 0 0 auto;
flex-basis: 24px;
font-size: 14px;
cursor: pointer;
}
td.bookmark {
flex: 0 0 auto;
flex-basis: 20px;
font-size: 14px;
cursor: pointer;
i {
@ -317,21 +309,18 @@
}
td.ts {
font-size: 12px;
flex: 0 0 auto;
flex-basis: 65px;
font-weight: bold;
}
td.session {
font-size: 12px;
flex: 0 0 auto;
flex-basis: 120px;
text-overflow: ellipsis;
}
td.remote {
.mono-font(12px);
flex: 0 0 auto;
flex-basis: 150px;
text-overflow: ellipsis;
@ -341,8 +330,7 @@
}
td.cmdstr {
.mono-font(12px);
color: white;
color: @term-white;
flex: 1 0 0;
padding-left: 20px;
border-radius: 3px;

View File

@ -7,7 +7,7 @@ import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { If } from "tsx-control-statements/components";
import { GlobalModel, GlobalCommandRunner, Cmd, getTermPtyData } from "../../model";
import { termHeightFromRows } from "../../textmeasure";
import { termHeightFromRows } from "../../util/textmeasure";
import type {
LineType,
CmdDataType,
@ -27,7 +27,8 @@ import type { LineContainerModel } from "../../model";
import { renderCmdText } from "../../common/common";
import { SimpleBlobRenderer } from "./renderer/simplerenderer";
import { FullRenderer } from "./renderer/fullrenderer";
import { isBlank } from "../../util";
import { TerminalRenderer } from "../../common/terminal/Terminal";
import { isBlank } from "../../util/util";
import { PluginModel } from "../../plugins/plugins";
import * as lineutil from "./lineutil";
@ -997,170 +998,4 @@ class LineText extends React.Component<
}
}
@mobxReact.observer
class TerminalRenderer extends React.Component<
{
screen: LineContainerModel;
line: LineType;
width: number;
staticRender: boolean;
visible: OV<boolean>;
onHeightChange: () => void;
collapsed: boolean;
},
{}
> {
termLoaded: mobx.IObservableValue<boolean> = mobx.observable.box(false, {
name: "linecmd-term-loaded",
});
elemRef: React.RefObject<any> = React.createRef();
termRef: React.RefObject<any> = React.createRef();
constructor(props) {
super(props);
}
componentDidMount() {
this.componentDidUpdate(null, null, null);
}
componentWillUnmount() {
if (this.termLoaded.get()) {
this.unloadTerminal(true);
}
}
getSnapshotBeforeUpdate(prevProps, prevState): { height: number } {
let elem = this.elemRef.current;
if (elem == null) {
return { height: 0 };
}
return { height: elem.offsetHeight };
}
componentDidUpdate(prevProps, prevState, snapshot: { height: number }): void {
if (this.props.onHeightChange == null) {
return;
}
let { line } = this.props;
let curHeight = 0;
let elem = this.elemRef.current;
if (elem != null) {
curHeight = elem.offsetHeight;
}
if (snapshot == null) {
snapshot = { height: 0 };
}
if (snapshot.height != curHeight) {
this.props.onHeightChange();
// console.log("term-render height change: ", line.linenum, snapshot.height, "=>", curHeight);
}
this.checkLoad();
}
checkLoad(): void {
let { line, staticRender, visible, collapsed } = this.props;
if (staticRender) {
return;
}
let vis = visible && visible.get() && !collapsed;
let curVis = this.termLoaded.get();
if (vis && !curVis) {
this.loadTerminal();
} else if (!vis && curVis) {
this.unloadTerminal(false);
}
}
loadTerminal(): void {
let { screen, line } = this.props;
let model = GlobalModel;
let cmd = screen.getCmd(line);
if (cmd == null) {
return;
}
let termElem = this.termRef.current;
if (termElem == null) {
console.log("cannot load terminal, no term elem found", line);
return;
}
screen.loadTerminalRenderer(termElem, line, cmd, this.props.width);
mobx.action(() => this.termLoaded.set(true))();
}
unloadTerminal(unmount: boolean): void {
let { screen, line } = this.props;
screen.unloadRenderer(line.lineid);
if (!unmount) {
mobx.action(() => this.termLoaded.set(false))();
let termElem = this.termRef.current;
if (termElem != null) {
termElem.replaceChildren();
}
}
}
@boundMethod
clickTermBlock(e: any) {
let { screen, line } = this.props;
let model = GlobalModel;
let termWrap = screen.getTermWrap(line.lineid);
if (termWrap != null) {
termWrap.giveFocus();
}
}
render() {
let { screen, line, width, staticRender, visible, collapsed } = this.props;
let isVisible = visible.get(); // for reaction
let isPhysicalFocused = mobx
.computed(() => screen.getIsFocused(line.linenum), {
name: "computed-getIsFocused",
})
.get();
let isFocused = mobx
.computed(
() => {
let screenFocusType = screen.getFocusType();
return isPhysicalFocused && screenFocusType == "cmd";
},
{ name: "computed-isFocused" }
)
.get();
let cmd = screen.getCmd(line); // will not be null
let usedRows = screen.getUsedRows(lineutil.getRendererContext(line), line, cmd, width);
let termHeight = termHeightFromRows(usedRows, GlobalModel.termFontSize.get());
let termLoaded = this.termLoaded.get();
return (
<div
ref={this.elemRef}
key="term-wrap"
className={cn(
"terminal-wrapper",
{ focus: isFocused },
{ "cmd-done": !cmd.isRunning() },
{ "zero-height": termHeight == 0 },
{ collapsed: collapsed }
)}
>
<If condition={!isFocused}>
<div key="term-block" className="term-block" onClick={this.clickTermBlock}></div>
</If>
<div
key="term-connectelem"
className="terminal-connectelem"
ref={this.termRef}
data-lineid={line.lineid}
style={{ height: termHeight }}
></div>
<If condition={!termLoaded}>
<div key="term-loading" className="terminal-loading-message">
...
</div>
</If>
</div>
);
}
}
export { Line, Prompt };

View File

@ -11,7 +11,6 @@
margin-left: 10px;
.text {
font-size: 1rem;
color: #ddd;
}
}
@ -24,13 +23,11 @@
}
.line .load-error-text {
.mono-font();
color: @term-red;
padding-top: 5px;
}
.line .renderer-loading {
.mono-font();
color: @term-white;
padding-top: 5px;
}
@ -64,7 +61,6 @@
visibility: hidden;
cursor: pointer;
padding: 3px;
font-size: 1.5rem;
}
.line-icon-show {
@ -72,11 +68,11 @@
}
.line-bookmark:hover {
color: white;
color: @term-white;
}
.line-minimise:hover {
color: white;
color: @term-white;
}
.line-icon + .line-icon {
@ -118,15 +114,12 @@
.loading-div {
height: 20px;
margin-left: 50px;
.mono-font();
}
}
.terminal-wrapper {
background-color: #000;
padding: 2px 10px 5px 4px;
margin: 4px 8px 0 -4px;
align-self: flex-start;
&.zero-height {
padding: 0;
@ -151,7 +144,6 @@
top: calc(40% - 8px);
left: 50px;
height: 20px;
.mono-font();
}
}
@ -161,11 +153,11 @@
.cmd-rtnstate-label {
position: relative;
z-index: 2;
.mono-font(9px);
margin-left: 10px;
padding: 2px 5px 2px 5px;
color: #666;
background-color: black;
background-color: @term-black;
display: inline-block;
}
@ -180,7 +172,6 @@
.cmd-rtnstate-diff {
color: @term-white;
.mono-font();
white-space: pre;
margin-left: 15px;
}
@ -191,7 +182,6 @@
margin: 0px 5px 0px 5px;
padding: 5px 5px 0px 12px;
display: flex;
line-height: 1.25;
overflow: hidden;
flex-shrink: 0;
position: relative;
@ -207,12 +197,10 @@
.ts {
display: flex;
color: #aaa;
.mono-font(11px);
}
}
.simple-line-status {
.mono-font(12px);
color: #aaa;
i {
@ -226,7 +214,7 @@
&.has-rtnstate {
.linenum {
color: white;
color: @term-white;
font-weight: bold;
}
}
@ -272,8 +260,8 @@
align-items: center;
justify-content: center;
font-weight: bold;
color: white;
font-size: 16px;
color: @term-white;
border-radius: 5px;
position: relative;
@ -282,29 +270,24 @@
}
.status-icon {
font-size: 8px;
position: absolute;
top: 2px;
right: 2px;
}
.comment-icon {
font-size: 10px;
position: absolute;
top: 0px;
right: -4px;
}
&.num-4 {
font-size: 13px;
}
&.num-5 {
font-size: 11px;
}
&.num-6 {
font-size: 9px;
}
&.status-done {
@ -341,7 +324,7 @@
.status-icon {
top: 3px;
right: 3px;
color: white;
color: @term-white;
}
}
}
@ -357,7 +340,7 @@
.meta {
display: flex;
flex-direction: row;
font-size: 1rem;
margin-top: -4px;
.simple-line-status {
@ -377,17 +360,16 @@
display: flex;
color: #aaa;
margin-top: 5px;
.mono-font(11px);
}
.renderer {
color: #aaa;
margin-left: 3px;
margin-top: 5px;
.mono-font(11px);
i {
display: inline-block;
font-size: 9px;
margin-right: 2px;
margin-top: 2px;
}
@ -396,7 +378,7 @@
.settings {
display: none;
color: #aaa;
font-size: 11px;
margin-left: 5px;
margin-top: 5px;
cursor: pointer;
@ -405,7 +387,7 @@
.termopts {
color: #aaa;
margin-top: 5px;
.mono-font(11px);
display: none;
.resize-button {
@ -420,12 +402,11 @@
margin-left: 8px;
margin-top: 4px;
white-space: nowrap;
.mono-font(14px);
}
.cmdtext {
color: #fff;
font-size: 16px;
font-weight: bold;
overflow: hidden;
margin-left: 0;
@ -434,9 +415,9 @@
.cmdtext-overflow {
flex-shrink: 0;
padding-right: 2px;
color: white;
color: @term-white;
cursor: pointer;
.mono-font(16px);
margin-top: 4px;
}
}
@ -451,8 +432,8 @@
.cmdtext-expanded {
white-space: pre;
.mono-font(14px);
color: white;
color: @term-white;
padding-bottom: 5px;
}
}
@ -494,7 +475,7 @@
.line-sep {
display: flex;
align-items: center;
.mono-font(11px);
color: #aaa;
}
@ -502,7 +483,7 @@
.line-sep::after {
content: "";
height: 2px;
background-color: #ccc;
background-color: @term-white;
flex-grow: 1;
}

View File

@ -9,7 +9,7 @@ import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { debounce, throttle } from "throttle-debounce";
import * as T from "../../types";
import * as util from "../../util";
import * as util from "../../util/util";
import * as lineutil from "./lineutil";
import "./lines.less";

View File

@ -1,6 +1,6 @@
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { isBlank, getDateStr } from "../../util";
import { isBlank, getDateStr } from "../../util/util";
import { LineType, WebLine, RendererContext } from "../../types";
dayjs.extend(localizedFormat);

View File

@ -21,9 +21,9 @@ import type {
RendererContainerType,
} from "../../../types";
import * as T from "../../../types";
import { PacketDataBuffer } from "../../../ptydata";
import { PacketDataBuffer } from "../../../terminal/ptydata";
import { debounce, throttle } from "throttle-debounce";
import * as util from "../../../util";
import * as util from "../../../util/util";
import { GlobalModel } from "../../../model";
type OV<V> = mobx.IObservableValue<V>;

View File

@ -16,7 +16,6 @@
}
.content {
.mono-font(13px);
}
}
@ -24,7 +23,6 @@
.modal-content {
footer {
.footer-text-link {
.mono-font(12px);
color: @term-white;
cursor: pointer;
}
@ -34,12 +32,11 @@
.inner-content {
.ws-log {
padding: 5px;
background-color: black;
background-color: @term-black;
height: 250px;
overflow: auto;
.ws-logline {
.mono-font(12px);
color: @term-white;
}
}
@ -61,7 +58,6 @@
.progress-text {
color: @term-white;
align-self: center;
font-size: 12px;
}
}
}
@ -98,7 +94,7 @@
.dropdown {
.dropdown-menu .dropdown-content {
.dropdown-item {
color: white;
color: @term-white;
cursor: pointer;
&:hover {
background-color: #333;
@ -128,7 +124,6 @@
.modal-title {
color: @prompt-green;
.mono-font(24px);
}
.close-icon {
@ -138,7 +133,6 @@
cursor: pointer;
padding: 3px;
color: #aaa;
font-size: 20px;
&:hover {
color: #fff;
@ -187,8 +181,6 @@
}
.dots {
font-size: 10px;
i {
margin-left: 5px;
}
@ -208,19 +200,17 @@
display: flex;
flex-direction: row;
align-items: center;
font-size: 14px;
&.settings-field.sub-field {
.settings-label {
font-weight: normal;
font-size: 13px;
text-align: right;
padding-right: 20px;
}
}
&.settings-error {
font-size: 14px;
color: @term-red;
margin-top: 20px;
padding: 10px;
@ -273,7 +263,6 @@
input.input {
padding: 0;
height: 20px;
font-size: 12px;
}
.button {
@ -287,7 +276,6 @@
}
.control {
font-size: 12px;
}
.tab-color-icon.color-green {
@ -330,14 +318,12 @@
}
.tab-color-cur {
font-size: 12px;
width: 100px;
}
.tab-color-select {
cursor: pointer;
margin: 5px;
line-height: 1;
&:hover {
outline: 2px solid white;
}
@ -346,7 +332,7 @@
.action-text {
margin-left: 20px;
font-size: 12px;
color: @term-red;
}

View File

@ -8,7 +8,7 @@ import { GlobalModel, GlobalCommandRunner, TabColors } from "../../model";
import { Toggle, InlineSettingsTextEdit, SettingsError, InfoMessage } from "../../common/common";
import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "../../types";
import { PluginModel } from "../../plugins/plugins";
import * as util from "../../util";
import * as util from "../../util/util";
import "./modals.less";

View File

@ -9,7 +9,7 @@ import dayjs from "dayjs";
import type { HistoryItem, HistoryQueryOpts } from "../../types";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "../../model";
import { isBlank } from "../../util";
import { isBlank } from "../../util/util";
import "./sessionview.less";
dayjs.extend(localizedFormat);

View File

@ -5,7 +5,7 @@ import cn from "classnames";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "../../model";
import { makeExternLink } from "../../util";
import { makeExternLink } from "../../util/util";
import "./sessionview.less";
dayjs.extend(localizedFormat);

View File

@ -4,8 +4,8 @@ import * as mobx from "mobx";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
import { GlobalModel, GlobalCommandRunner } from "../../model";
import { getMonoFontSize } from "../../textmeasure";
import { isModKeyPress, hasNoModifiers } from "../../util";
import { getMonoFontSize } from "../../util/textmeasure";
import { isModKeyPress, hasNoModifiers } from "../../util/util";
import "./sessionview.less";
function pageSize(div: any): number {

View File

@ -52,14 +52,12 @@
flex-direction: row;
color: @term-yellow;
align-items: center;
font-size: 14px;
.button {
margin-left: 10px;
}
.remote-name {
.mono-font(14px);
}
}
@ -68,7 +66,7 @@
top: 5px;
right: 5px;
color: @term-white;
font-size: 12px;
padding: 5px;
cursor: pointer;
}
@ -78,7 +76,6 @@
}
.cmd-input-context {
.mono-font();
color: #fff;
white-space: nowrap;
}
@ -86,10 +83,6 @@
.cmd-input-field {
position: relative;
.cmd-input-control {
line-height: 0;
}
.cmd-hints {
position: absolute;
bottom: -14px;
@ -97,9 +90,8 @@
}
textarea {
color: white;
background-color: black;
.mono-font();
color: @term-white;
background-color: @term-black;
padding-bottom: calc(0.5em - 1px);
padding-top: calc(0.5em - 1px);
resize: none;
@ -107,7 +99,7 @@
&:active,
&:focus {
border-color: white !important;
border-color: @term-white !important;
}
&.display-disabled {
@ -122,18 +114,17 @@
}
.cmd-quick-context .button {
.mono-font();
background-color: #000 !important;
color: white;
color: @term-white;
}
&.inputmode-global .cmd-quick-context .button {
color: black;
color: @term-black;
background-color: @tab-green !important;
}
&.inputmode-comment .cmd-quick-context .button {
color: black;
color: @term-black;
background-color: @tab-blue !important;
}
@ -154,8 +145,7 @@
z-index: 102;
top: 5px;
left: 20px;
background-color: black;
.mono-font(12px, 700);
background-color: @term-black;
color: @soft-blue;
padding-bottom: 4px;
display: flex;
@ -184,7 +174,7 @@
.history-items {
margin-top: 24px;
color: @term-white;
.mono-font(12px);
padding-bottom: 6px;
.history-line {
@ -226,7 +216,6 @@
margin-bottom: 5px;
.info-msg {
.mono-font(14px, 400);
color: @soft-blue;
padding-bottom: 2px;
@ -236,13 +225,11 @@
}
.info-title {
.mono-font(14px, 700);
color: @soft-blue;
padding-bottom: 2px;
}
.info-lines {
.mono-font(12px);
color: @term-white;
white-space: pre;
padding-bottom: 6px;
@ -253,7 +240,6 @@
flex-direction: row;
flex-wrap: wrap;
padding-bottom: 5px;
.mono-font(14px, 400);
.info-comp {
min-width: 200px;
@ -271,7 +257,6 @@
}
.info-error {
.mono-font(14px, 700);
color: @term-red;
padding-bottom: 2px;
}
@ -279,7 +264,7 @@
.info-remote-showall {
table.remotes-table {
th {
color: white;
color: @term-white;
font-weight: bold;
}
@ -300,7 +285,6 @@
.info-remote {
color: #d3d7cf;
.mono-font(12px);
.info-remote-title {
font-weight: bold;
@ -356,8 +340,8 @@
input[type="text"],
input[type="number"],
input[type="password"] {
background-color: black;
color: white;
background-color: @term-black;
color: @term-white;
width: 200px;
}
}
@ -372,8 +356,8 @@
&.select-input {
select {
width: 200px;
background-color: black;
color: white;
background-color: @term-black;
color: @term-white;
}
}
}
@ -382,7 +366,6 @@
.info-remote-showall {
color: #d3d7cf;
.mono-font(12px);
}
}
}

View File

@ -8,7 +8,7 @@
background-color: @tab-green;
}
&.is-active {
color: white;
color: @term-white;
background-color: @tab-green;
}
}
@ -20,7 +20,7 @@
background-color: @tab-orange;
}
&.is-active {
color: black;
color: @term-black;
background-color: @tab-orange;
}
}
@ -32,7 +32,7 @@
background-color: @tab-red;
}
&.is-active {
color: white;
color: @term-white;
background-color: @tab-red;
}
}
@ -45,7 +45,7 @@
}
&.is-active {
background-color: @tab-yellow;
color: black;
color: @term-black;
box-shadow: 0 3px 0 #fff inset, 0 4px 0 #000 inset;
}
}
@ -57,7 +57,7 @@
background-color: @tab-blue;
}
&.is-active {
color: white;
color: @term-white;
background-color: @tab-blue;
}
}
@ -69,7 +69,7 @@
background-color: @tab-magenta;
}
&.is-active {
color: white;
color: @term-white;
background-color: @tab-magenta;
}
}
@ -81,7 +81,7 @@
background-color: @tab-cyan;
}
&.is-active {
color: black;
color: @term-black;
background-color: @tab-cyan;
}
}
@ -93,7 +93,7 @@
background-color: @tab-white;
}
&.is-active {
color: black;
color: @term-black;
background-color: @tab-white;
box-shadow: 0 3px 0 #fff inset, 0 4px 0 #000 inset;
}
@ -106,7 +106,7 @@
background-color: @tab-black;
}
&.is-active {
color: white;
color: @term-white;
background-color: @tab-black;
}
}
@ -167,12 +167,11 @@
height: 30px;
min-width: 80px;
width: 150px;
line-height: 1;
flex-shrink: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: 500;
padding-left: 0;
padding-right: 0;
@ -201,7 +200,6 @@
}
.tab-index {
font-size: 11px;
position: absolute;
right: 2px;
top: 4px;
@ -236,7 +234,6 @@
right: 3px;
padding-left: 4px;
i {
font-size: 15px;
}
}
}
@ -254,9 +251,9 @@
.screen-tab.new-screen {
width: 30px;
min-width: 30px;
background-color: black;
background-color: @term-black;
border-right: none;
color: #ccc;
color: @term-white;
cursor: pointer;
&:hover {

View File

@ -10,7 +10,7 @@ import type * as T from "../../types";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel, GlobalCommandRunner, Session } from "../../model";
import { sortAndFilterRemotes, isBlank } from "../../util";
import { sortAndFilterRemotes, isBlank } from "../../util/util";
import { RemoteStatusLight } from "../../common/common";
@ -159,18 +159,6 @@ class MainSideBar extends React.Component<{}, {}> {
let mainView = GlobalModel.activeMainView.get();
return (
<div className={cn("main-sidebar", { collapsed: isCollapsed }, { "is-dev": GlobalModel.isDev })}>
<div className="logo-header">
<h1
className={cn(
"title",
"prompt-logo-small",
{ collapsed: isCollapsed },
{ "is-dev": GlobalModel.isDev }
)}
>
{isCollapsed ? "[p]" : "[prompt]"}
</h1>
</div>
<div className="collapse-container">
<div className="arrow-container" onClick={this.toggleCollapsed}>
<If condition={!isCollapsed}>

View File

@ -7,35 +7,6 @@
border-bottom: 2px solid #ddd;
margin-left: -4px;
margin-right: -5px;
.title.prompt-logo-small {
padding-left: 5px;
padding-top: 8px;
padding-bottom: 8px;
margin-bottom: 0;
.mono-font(1.5rem);
background-color: darken(rgb(0, 177, 10), 30%);
color: rgb(0, 177, 10);
position: relative;
white-space: nowrap;
overflow: hidden;
flex-shrink: 0;
&.is-dev {
background-color: darken(rgb(177, 0, 10), 30%);
}
&.collapsed {
padding-left: 1px;
}
.title-cursor {
position: relative;
bottom: 3px;
left: 3px;
.mono-font(1.2rem);
}
}
}
.main-sidebar {
@ -45,15 +16,9 @@
overflow-x: hidden;
display: flex;
flex-direction: column;
color: #ddd;
position: relative;
background-color: darken(rgb(0, 177, 10), 30%);
flex-shrink: 0;
&.is-dev {
background-color: darken(rgb(177, 0, 10), 30%);
}
.menu {
padding-top: 10px;
display: flex;
@ -69,43 +34,15 @@
}
a:hover {
color: white;
color: @term-white;
}
}
.menu-label {
color: #bbb;
a {
color: #bbb;
}
}
p.menu-label {
margin-bottom: 0px;
color: @base-color;
}
.menu-list {
li.new-session,
li.add-remote {
a {
color: #666;
font-size: 13px;
}
.fa {
font-size: 10px;
}
}
li {
.mono-font();
}
li.menu-loading-message {
.mono-font();
}
li.menu-history,
li.menu-bookmarks,
li.menu-settings,
@ -144,11 +81,11 @@
}
&:hover .session-gear {
color: #ccc;
color: @term-white;
visibility: visible;
&:hover {
color: white;
color: @term-white;
}
}
}
@ -161,7 +98,6 @@
.menu-list li.remote-menu-item {
a {
.mono-font(11px);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -169,12 +105,10 @@
}
.menu-list li a {
color: #bbb;
white-space: nowrap;
padding: 3px 5px 3px 12px;
vertical-align: middle;
position: relative;
font-size: 13px;
.user-status {
position: absolute !important;
@ -189,39 +123,25 @@
vertical-align: middle;
}
.session-num {
color: #777;
font-size: 10px;
}
&.is-active .small-text {
color: white;
}
.small-text {
color: #777;
font-size: 10px;
color: @term-white;
}
&.is-active {
color: #ddd;
font-weight: bold;
background-color: @active-menu-color;
.session-num {
color: #aaa;
font-weight: normal;
}
}
.sub-label {
font-size: 12px;
font-style: italic;
}
&.activity {
font-weight: bold;
color: #ddd;
.tag {
margin-left: 4px;
@ -232,24 +152,15 @@
}
&.is-active:hover {
background-color: #3273dc;
}
&:hover {
background-color: #444;
color: #ddd;
}
.status {
font-size: 8px;
margin-right: 5px;
position: relative;
top: -3px;
color: #4e9a06;
&.offline {
color: #cc0000;
}
}
}
@ -271,20 +182,18 @@
top: 42px;
.arrow-container {
color: #777;
padding: 5px;
cursor: pointer;
&:hover {
color: #ddd;
}
}
}
}
.is-dev .main-sidebar {
background: @base-background-dev;
}
.menu-list .remote-status.status-connecting {
position: relative;
top: 0px;
font-size: 12px;
margin-left: -3px;
}

View File

@ -10,8 +10,8 @@ import {
genMergeSimpleData,
boundInt,
isModKeyPress,
} from "./util";
import { TermWrap } from "./term";
} from "./util/util";
import { TermWrap } from "./common/terminal/term";
import { v4 as uuidv4 } from "uuid";
import type {
SessionDataType,
@ -68,7 +68,7 @@ import {
windowHeightToRows,
termWidthFromCols,
termHeightFromRows,
} from "./textmeasure";
} from "./util/textmeasure";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import customParseFormat from "dayjs/plugin/customParseFormat";

View File

@ -330,7 +330,7 @@ class SourceCodeRenderer extends React.Component<
options={{
scrollBeyondLastLine: false,
fontSize: GlobalModel.termFontSize.get(),
fontFamily: "JetBrains Mono",
/* fontFamily: "JetBrains Mono", @check:font */
readOnly: !this.getAllowEditing(),
}}
onChange={this.handleEditorChange}
@ -405,7 +405,7 @@ class SourceCodeRenderer extends React.Component<
className="message"
style={{
fontSize: GlobalModel.termFontSize.get(),
fontFamily: "JetBrains Mono",
/* fontFamily: "JetBrains Mono", @check:font */
background: `${this.state.message.status === "error" ? "red" : "#4e9a06"}`,
}}
>
@ -432,7 +432,7 @@ class SourceCodeRenderer extends React.Component<
className="renderer-container code-renderer"
style={{
fontSize: GlobalModel.termFontSize.get(),
fontFamily: "JetBrains Mono",
/* fontFamily: "JetBrains Mono", @check:font */
color: "white",
}}
>

View File

@ -6,7 +6,7 @@ import { boundMethod } from "autobind-decorator";
import { If, For, When, Otherwise, Choose } from "tsx-control-statements/components";
import * as T from "../types";
import { sprintf } from "sprintf-js";
import { isBlank } from "../util";
import { isBlank } from "../util/util";
import mustache from "mustache";
import * as DOMPurify from "dompurify";
import { GlobalModel } from "../model";

View File

@ -4,8 +4,7 @@ import * as mobxReact from "mobx-react";
import * as T from "../types";
import { debounce } from "throttle-debounce";
import { boundMethod } from "autobind-decorator";
import { sprintf } from "sprintf-js";
import { PacketDataBuffer } from "../ptydata";
import { PacketDataBuffer } from "../common/terminal/ptydata";
import { Markdown } from "../common/common";
import "./plugins.less";

View File

@ -9,13 +9,12 @@
margin: 20px 10px 0px 5px;
padding-left: 10px;
padding-bottom: 12px;
.mono-font(1.5rem);
color: @term-bright-white;
border-bottom: 1px solid white;
}
.alt-list {
color: white;
color: @term-white;
margin: 4px 10px 5px 5px;
border-bottom: 1px solid white;
}
@ -29,7 +28,7 @@
.close-button {
position: absolute;
padding: 4px;
font-size: 24px;
color: #aaa;
right: 15px;
top: 18px;
@ -46,7 +45,7 @@
display: flex;
flex-direction: row;
align-items: center;
font-size: 12px;
margin-bottom: 10px;
.help-entry {
@ -65,7 +64,7 @@
.renderer-container {
.error-container {
color: @term-red;
font-size: 14px;
padding: 5px;
}
@ -78,9 +77,9 @@
.dropdown {
background: #dbdbdb;
color: black;
color: @term-black;
border-radius: 6px 6px 0 0;
font-size: 10px;
padding: 2px 0 5px 5px;
outline: none;
}
@ -114,7 +113,6 @@
.hint-item {
border-radius: 4px 4px 0 0;
padding: 3px 9px 2px 8px;
line-height: 19px;
text-align: center;
}
section {
@ -125,10 +123,10 @@
background-color: rgb(200, 200, 200);
}
.preview:hover {
background-color: white !important;
background-color: @term-white !important;
}
.save-enabled {
color: white;
color: @term-white;
background-color: #4e9a06;
}
.save-disabled {
@ -140,24 +138,23 @@
background-color: #aaaea7;
}
.close {
color: white;
color: @term-white;
background-color: #9e0000;
}
.message {
color: white;
color: @term-white;
border-radius: 6px;
margin-bottom: 1rem;
padding: 4px 1rem;
max-width: 80vw;
}
.readonly {
.mono-font(12px);
position: absolute;
top: calc(1.5rem + 3px);
right: 10rem;
border-radius: 5px;
background-color: @term-bright-red;
color: white;
color: @term-white;
z-index: 1;
padding: 0 6px 2px;
}
@ -173,7 +170,6 @@
.hint-item {
border-radius: 4px 4px 0 0;
padding: 3px 9px 2px 8px;
line-height: 15px;
text-align: center;
}
.refresh-button {
@ -184,7 +180,6 @@
.renderer-container .content {
padding: 5px;
line-height: 1.5;
width: fit-content;
blockquote {
@ -193,7 +188,6 @@
code {
background-color: #222;
font-size: 14px;
}
pre {
@ -230,11 +224,11 @@
.openai-content-user {
white-space: pre;
color: white;
color: @term-white;
}
.openai-content-assistant {
color: white;
color: @term-white;
}
.openai-role-error {
@ -252,9 +246,8 @@
margin-bottom: 10px;
code {
background-color: black;
color: white;
.mono-font();
background-color: @term-black;
color: @term-white;
padding: 5px;
}
@ -264,14 +257,13 @@
}
.title {
color: white;
color: @term-white;
margin-top: 16px;
line-height: 1.25;
margin-bottom: 8px;
}
strong {
color: white;
color: @term-white;
}
a {
@ -280,7 +272,7 @@
table {
tr th {
color: white;
color: @term-white;
}
}
@ -309,26 +301,20 @@
}
.title.is-1 {
font-size: 32px;
border-bottom: 1px solid #777;
padding-bottom: 6px;
}
.title.is-2 {
font-size: 24px;
border-bottom: 1px solid #777;
padding-bottom: 6px;
}
.title.is-3 {
font-size: 20px;
}
.title.is-4 {
font-size: 16px;
}
.title.is-5 {
font-size: 14px;
}
.title.is-6 {
font-size: 14px;
}
}

View File

@ -4,7 +4,7 @@ import { SimpleMarkdownRenderer } from "./markdown";
import { SourceCodeRenderer } from "./code";
import { SimpleMustacheRenderer } from "./mustache";
import { OpenAIRenderer, OpenAIRendererModel } from "./openai";
import { isBlank } from "../util";
import { isBlank } from "../util/util";
import { sprintf } from "sprintf-js";
const ImagePlugin: RendererPluginType = {

View File

@ -27,7 +27,6 @@
cursor: pointer;
&.add-remote {
font-size: 13px;
padding: 10px 5px 10px 5px;
}
@ -39,7 +38,7 @@
background-color: @active-menu-color;
.remote-name .remote-name-secondary {
color: white;
color: @term-white;
}
}
@ -56,12 +55,10 @@
flex-grow: 1;
.remote-name-primary {
font-size: 12px;
font-weight: bold;
}
.remote-name-secondary {
font-size: 11px;
color: #777;
}
}
@ -71,7 +68,7 @@
.remote-detail {
padding: 10px;
flex-grow: 1;
font-size: 12px;
display: flex;
flex-direction: column;
@ -84,13 +81,12 @@
}
.detail-subtitle {
font-size: 18px;
margin-bottom: 10px;
margin-top: 10px;
}
.title {
color: white;
color: @term-white;
padding-bottom: 8px;
margin-bottom: 0;
border-bottom: 1px solid #777;
@ -183,7 +179,7 @@
.settings-field .settings-input .undo-icon {
cursor: pointer;
font-size: 18px;
margin-left: 5px;
}
@ -201,11 +197,9 @@
}
.dropdown .dropdown-trigger button {
font-size: 12px;
}
.dropdown .dropdown-item {
font-size: 12px;
padding: 5px 5px 5px 12px;
}
@ -239,10 +233,9 @@
top: 0;
right: 0;
background-color: @term-red;
color: white;
color: @term-white;
z-index: 110;
padding: 4px;
.mono-font(10px);
}
}
}

View File

@ -7,8 +7,8 @@ import cn from "classnames";
import { GlobalModel, GlobalCommandRunner, RemotesModalModel } from "../model";
import { Toggle, RemoteStatusLight, InfoMessage } from "../common/common";
import { RemoteType, RemoteEditType } from "../types";
import * as util from "../util";
import * as textmeasure from "../textmeasure";
import * as util from "../util/util";
import * as textmeasure from "../util/textmeasure";
import "./remotes.less";

15
src/themes.ts Normal file
View File

@ -0,0 +1,15 @@
/**
* The file contains barebones of styling to appy themes to Prompt.
* @TODO: Find a way to change the theme system-wide. atm, we are captruing colors in main.less
*/
const themes = [
{
id: "default",
terminal: { foreground: "#eceeec", background: "rgba(21, 23, 21, 1)" },
},
];
const getTheme = (_id = "default") => themes.find(({ id }) => id === _id);
export { getTheme };

View File

@ -2,7 +2,7 @@ import * as mobx from "mobx";
import { sprintf } from "sprintf-js";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import type { RemoteType } from "./types";
import type { RemoteType } from "../types";
dayjs.extend(localizedFormat);
@ -264,6 +264,7 @@ function incObs(inum: mobx.IObservableValue<number>) {
})();
}
// @check:font
function loadFonts() {
let jbmFontNormal = new FontFace("JetBrains Mono", "url('static/fonts/jetbrains-mono-v13-latin-regular.woff2')", {
style: "normal",

View File

@ -1,91 +0,0 @@
.mono-font(@size: inherit, @weight: inherit) {
font-family: "JetBrains Mono", monospace;
font-size: @size;
font-weight: @weight;
}
.monofont-thin {
.mono-font(inherit, 200);
}
.monofont-normal {
.mono-font(inherit, 400);
}
.monofont-bold {
.mono-font(inherit, 700);
}
.display-none {
display: none;
}
.bold {
font-weight: bold;
}
.term-black {
color: @term-black;
}
.term-red {
color: @term-red;
}
.term-green {
color: @term-green;
}
.term-yellow {
color: @term-yellow;
}
.term-blue {
color: @term-blue;
}
.term-magenta {
color: @term-magenta;
}
.term-cyan {
color: @term-cyan;
}
.term-white {
color: @term-white;
}
.term-bright-white {
color: @term-bright-white;
}
.term-bright-green {
color: @term-bright-green;
}
.term-bright-red {
color: @term-bright-red;
}
.flex-spacer {
flex-grow: 1;
}
.flex-centered-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.flex-centered-col {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
a.a-block {
display: block;
}

View File

@ -9,7 +9,7 @@ import { If, For, When, Otherwise, Choose } from "tsx-control-statements/compone
import cn from "classnames";
import { GlobalModel, GlobalCommandRunner, Screen } from "../model";
import { WebStopShareConfirmMarkdown } from "../main/modals/settings";
import * as util from "../util";
import * as util from "../util/util";
import "./webshare.less";

View File

@ -13,15 +13,14 @@ body.prompt-webshare #main {
flex-shrink: 0;
.logo-text {
.mono-font(32px);
a {
color: @prompt-green;
}
}
.screen-name {
color: white;
.mono-font(24px);
color: @term-white;
margin-left: 20px;
}
@ -39,7 +38,7 @@ body.prompt-webshare #main {
padding-left: 20px;
padding-right: 20px;
background-color: darken(@prompt-green, 30%);
color: white;
color: @term-white;
.screen-sharename {
font-weight: bold;
@ -49,7 +48,7 @@ body.prompt-webshare #main {
display: flex;
flex-direction: row;
color: @term-white;
font-size: 13px;
align-items: center;
div:first-child {
@ -92,7 +91,6 @@ body.prompt-webshare #main {
flex-shrink: 0;
.footer-copy {
font-size: 12px;
}
a {
@ -100,10 +98,10 @@ body.prompt-webshare #main {
}
}
color: white;
color: @term-white;
#app {
color: white;
color: @term-white;
}
.lines .line-sep {
@ -114,7 +112,6 @@ body.prompt-webshare #main {
.lines .line.line-cmd {
.line-icon.copy-icon {
color: @term-white;
font-size: 18px;
&:hover {
color: @term-bright-white;

View File

@ -20,6 +20,7 @@ document.addEventListener("DOMContentLoaded", () => {
let elem = document.getElementById("app");
let root = createRoot(elem);
let reactElem = React.createElement(WebShareMain, null, null);
// @check:font
let isFontLoaded = document.fonts.check("12px 'JetBrains Mono'");
if (isFontLoaded) {
root.render(reactElem);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +0,0 @@
/*!
* Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license (Commercial License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-sharp:"Font Awesome 6 Sharp";--fa-font-sharp-regular:normal 400 1em/1 "Font Awesome 6 Sharp"}@font-face{font-family:"Font Awesome 6 Sharp";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-sharp-regular-400.woff2) format("woff2"),url(../webfonts/fa-sharp-regular-400.ttf) format("truetype")}.fa-regular,.fasr{font-weight:400}

View File

@ -1,6 +0,0 @@
/*!
* Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license (Commercial License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-sharp:"Font Awesome 6 Sharp";--fa-font-sharp-solid:normal 900 1em/1 "Font Awesome 6 Sharp"}@font-face{font-family:"Font Awesome 6 Sharp";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-sharp-solid-900.woff2) format("woff2"),url(../webfonts/fa-sharp-solid-900.ttf) format("truetype")}.fa-solid,.fass{font-weight:900}

View File

@ -1,6 +0,0 @@
/*!
* Font Awesome Pro 6.3.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license (Commercial License)
* Copyright 2023 Fonticons, Inc.
*/
:host,:root{--fa-style-family-classic:"Font Awesome 6 Pro";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Pro"}@font-face{font-family:"Font Awesome 6 Pro";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-weight:900}

View File

@ -1,19 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<base href="../">
<script charset="UTF-8" src="dist-dev/prompt.js"></script>
<link rel="stylesheet" href="static/bulma-0.9.4.min.css">
<link rel="stylesheet" href="static/fontawesome/css/fontawesome.min.css">
<link rel="stylesheet" href="static/fontawesome/css/brands.min.css">
<link rel="stylesheet" href="static/fontawesome/css/sharp-solid.min.css">
<link rel="stylesheet" href="static/fontawesome/css/sharp-regular.min.css">
<link rel="stylesheet" href="static/xterm.css" />
<link rel="stylesheet" href="dist-dev/prompt.css" />
</head>
<body>
<div id="measure"></div>
<div id="app"></div>
</body>
<head>
<meta charset="UTF-8" />
<base href="../" />
<script charset="UTF-8" src="dist-dev/prompt.js"></script>
<link rel="stylesheet" href="static/bulma-0.9.4.min.css" />
<link rel="stylesheet" href="static/xterm.css" />
<link rel="stylesheet" href="dist-dev/prompt.css" />
</head>
<body>
<div id="measure"></div>
<div id="title-bar"></div>
<div id="app"></div>
</body>
</html>

View File

@ -1,19 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<base href="../">
<script charset="UTF-8" src="dist/prompt.js"></script>
<link rel="stylesheet" href="static/bulma-0.9.4.min.css">
<link rel="stylesheet" href="static/fontawesome/css/fontawesome.min.css">
<link rel="stylesheet" href="static/fontawesome/css/brands.min.css">
<link rel="stylesheet" href="static/fontawesome/css/sharp-solid.min.css">
<link rel="stylesheet" href="static/fontawesome/css/sharp-regular.min.css">
<link rel="stylesheet" href="static/xterm.css" />
<link rel="stylesheet" href="dist/prompt.css" />
</head>
<body>
<div id="measure"></div>
<div id="app"></div>
</body>
<head>
<meta charset="UTF-8" />
<base href="../" />
<script charset="UTF-8" src="dist/prompt.js"></script>
<link rel="stylesheet" href="static/bulma-0.9.4.min.css" />
<link rel="stylesheet" href="static/xterm.css" />
<link rel="stylesheet" href="dist/prompt.css" />
</head>
<body>
<div id="measure"></div>
<div id="title-bar"></div>
<div id="app"></div>
</body>
</html>

View File

@ -1,22 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>[prompt] Shared Terminal Session</title>
<meta charset="UTF-8">
<base href="/">
<script charset="UTF-8" src="/dist-dev/webshare.js"></script>
<link rel="stylesheet" href="/static/bulma-0.9.4.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/fontawesome.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/brands.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/sharp-solid.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/sharp-regular.min.css">
<link rel="stylesheet" href="/static/xterm.css" />
<link rel="stylesheet" href="/dist-dev/webshare.css" />
</head>
<body class="prompt-webshare">
<div id="measure"></div>
<div id="app"></div>
</body>
<head>
<title>[prompt] Shared Terminal Session</title>
<meta charset="UTF-8" />
<base href="/" />
<script charset="UTF-8" src="/dist-dev/webshare.js"></script>
<link rel="stylesheet" href="/static/bulma-0.9.4.min.css" />
<link rel="stylesheet" href="/static/xterm.css" />
<link rel="stylesheet" href="/dist-dev/webshare.css" />
</head>
<body class="prompt-webshare">
<div id="measure"></div>
<div id="title-bar"></div>
<div id="app"></div>
</body>
</html>

View File

@ -1,22 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>[prompt] Shared Terminal Session</title>
<meta charset="UTF-8">
<base href="/">
<script charset="UTF-8" src="/dist/webshare.js"></script>
<link rel="stylesheet" href="/static/bulma-0.9.4.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/fontawesome.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/brands.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/sharp-solid.min.css">
<link rel="stylesheet" href="/static/fontawesome/css/sharp-regular.min.css">
<link rel="stylesheet" href="/static/xterm.css" />
<link rel="stylesheet" href="/dist/webshare.css" />
</head>
<body class="prompt-webshare">
<div id="measure"></div>
<div id="app"></div>
</body>
<head>
<title>[prompt] Shared Terminal Session</title>
<meta charset="UTF-8" />
<base href="/" />
<script charset="UTF-8" src="/dist/webshare.js"></script>
<link rel="stylesheet" href="/static/bulma-0.9.4.min.css" />
<link rel="stylesheet" href="/static/xterm.css" />
<link rel="stylesheet" href="/dist/webshare.css" />
</head>
<body class="prompt-webshare">
<div id="measure"></div>
<div id="title-bar"></div>
<div id="app"></div>
</body>
</html>