Pe 199 pre rel 0.4.0 (#34)

* Tab bg matches selections

* WIP: need to fix all modals one by one

* ready to pull latest

* history fixed
This commit is contained in:
anandamarsh 2023-10-11 23:43:47 -07:00 committed by GitHub
parent acc4eea74f
commit 474552d732
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 570 additions and 1040 deletions

View File

@ -1,4 +1,4 @@
@import "../index.less";
@import "./common/themes/themes.less";
@font-face {
font-family: "Martian Mono";
@ -94,7 +94,7 @@ svg.icon {
border: none;
border-radius: 5px;
cursor: pointer;
background-color: @button-background;
background-color: @button-background !important;
color: @prompt-green;
.hoverEffect;
&:hover {
@ -169,9 +169,8 @@ a.a-block {
flex-grow: 1;
display: flex;
flex-direction: column;
min-width: 300px;
margin-right: 0.5em;
position: relative;
&.is-hidden {
display: none;
}
@ -395,57 +394,3 @@ a.a-block {
opacity: 0;
}
}
.alt-view {
background-color: #111;
overflow-y: auto;
flex-grow: 1;
.alt-title {
margin: 20px 10px 0px 5px;
padding-left: 10px;
padding-bottom: 12px;
color: @term-bright-white;
border-bottom: 1px solid white;
}
.alt-list {
color: @term-white;
margin: 4px 10px 5px 5px;
border-bottom: 1px solid white;
}
.no-content {
color: @term-white;
padding: 30px 10px 35px 10px;
border-bottom: 1px solid white;
}
.close-button {
position: absolute;
padding: 4px;
color: #aaa;
right: 15px;
top: 18px;
cursor: pointer;
&:hover {
color: #fff;
}
}
.alt-help {
color: @term-white;
margin-top: 20px;
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 10px;
.help-entry {
margin-left: 20px;
}
}
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M352 0l96 96V384H160V0H352zM64 128h64v64H64V448H256V416h64v32 64H256 64 0V448 192 128H64z"/></svg>

After

Width:  |  Height:  |  Size: 337 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 512L32 352 292.7 91.3l128 128L160 480 0 512zM443.3 196.7l-128-128L384 0 512 128l-68.7 68.7z"/></svg>

After

Width:  |  Height:  |  Size: 342 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M144 0L128 32H0V96H448V32H320L304 0H144zM416 128H32L56 512H392l24-384z"/></svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M224 365.3l22.6-22.6 160-160L429.3 160 384 114.7l-22.6 22.6L224 274.7 86.6 137.4 64 114.7 18.7 160l22.6 22.6 160 160L224 365.3z"/></svg>

After

Width:  |  Height:  |  Size: 375 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M2.7 256l22.6 22.6 192 192L240 493.3 285.3 448l-22.6-22.6L93.3 256 262.6 86.6 285.3 64 240 18.7 217.4 41.4l-192 192L2.7 256z"/></svg>

After

Width:  |  Height:  |  Size: 372 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M317.3 256l-22.6 22.6-192 192L80 493.3 34.7 448l22.6-22.6L226.7 256 57.4 86.6 34.7 64 80 18.7l22.6 22.6 192 192L317.3 256z"/></svg>

After

Width:  |  Height:  |  Size: 370 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M352 0l96 96V384H160V0H352zM64 128h64v64H64V448H256V416h64v32 64H256 64 0V448 192 128H64z"/></svg>

After

Width:  |  Height:  |  Size: 337 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M422.6 278.6L445.3 256l-22.6-22.6-144-144L256 66.7 210.8 112l22.6 22.6L322.8 224 32 224 0 224l0 64 32 0 290.7 0-89.4 89.4L210.8 400 256 445.3l22.6-22.6 144-144z"/></svg>

After

Width:  |  Height:  |  Size: 408 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>

After

Width:  |  Height:  |  Size: 594 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm88 200H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24z"/></svg>

After

Width:  |  Height:  |  Size: 441 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"/></svg>

After

Width:  |  Height:  |  Size: 354 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M144 0L128 32H0V96H448V32H320L304 0H144zM416 128H32L56 512H392l24-384z"/></svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -1,6 +1,29 @@
@import "../../index.less";
@import "../../app/app.less";
.bookmarks-view {
background-color: @background-session;
.close-button {
position: absolute;
right: 1em;
top: 0.8em;
cursor: pointer;
width: 1.5em;
height: 1.5em;
border-radius: 50%;
svg {
width: 1.5em;
height: 1.5em;
fill: @base-color;
}
}
.icon {
width: 1em;
height: 1em;
fill: @base-color;
}
.bookmarks-list {
color: @term-white;
margin: 4px 10px 5px 5px;

View File

@ -8,6 +8,12 @@ import type { BookmarkType } from "../../types/types";
import { GlobalModel } from "../../model/model";
import { CmdStrCode, Markdown } from "../common/common";
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
import { ReactComponent as CopyIcon } from "../assets/icons/favourites/copy.svg";
import { ReactComponent as PenIcon } from "../assets/icons/favourites/pen.svg";
import { ReactComponent as TrashIcon } from "../assets/icons/favourites/trash.svg";
import { ReactComponent as FavouritesIcon } from "../assets/icons/favourites.svg";
import "./bookmarks.less";
@mobxReact.observer
@ -157,10 +163,10 @@ class Bookmark extends React.Component<{ bookmark: BookmarkType }, {}> {
</div>
<div className="bookmark-controls">
<div className="bookmark-control" onClick={this.handleEditClick}>
<i className="fa-sharp fa-solid fa-pen" />
<PenIcon className={"icon"} />
</div>
<div className="bookmark-control" onClick={this.handleDeleteClick}>
<i className="fa-sharp fa-solid fa-trash" />
<TrashIcon className={"icon"} />
</div>
</div>
</div>
@ -184,13 +190,13 @@ class BookmarksView extends React.Component<{}, {}> {
let idx: number = 0;
let bookmark: BookmarkType = null;
return (
<div className={cn("bookmarks-view", "alt-view", { "is-hidden": isHidden })}>
<div className="close-button" onClick={this.closeView}>
<i className="fa-sharp fa-solid fa-xmark"></i>
<div className={cn("bookmarks-view", { "is-hidden": isHidden })}>
<div className="close-button hoverEffect" title="Close (Escape)" onClick={this.closeView}>
<XmarkIcon className={"icon"} />
</div>
<div className="alt-title">
<i className="fa-sharp fa-solid fa-bookmark" style={{ marginRight: 10 }} />
BOOKMARKS
<FavouritesIcon className={"icon"} style={{ marginRight: 10 }} />
Favourites
</div>
<div className="bookmarks-list">
<For index="idx" each="bookmark" of={bookmarks}>
@ -200,8 +206,7 @@ class BookmarksView extends React.Component<{}, {}> {
<div className="no-content">
No Bookmarks.
<br />
Use the <i className="fa-sharp fa-solid fa-bookmark" /> icon on commands to add your first
bookmark.
Use the <FavouritesIcon className={"icon"} /> icon on commands to add your first bookmark.
</div>
</If>
</div>
@ -210,13 +215,13 @@ class BookmarksView extends React.Component<{}, {}> {
<div className="help-entry">
[Enter] to Use Bookmark
<br />
[Backspace/Delete]x2 or <i className="fa-sharp fa-solid fa-trash" /> to Delete
[Backspace/Delete]x2 or <TrashIcon className={"icon"} /> to Delete
<br />
[Arrow Up]/[Arrow Down]/[PageUp]/[PageDown] to Move in List
<br />
[e] or <i className="fa-sharp fa-solid fa-pen" /> to Edit
[e] or <PenIcon className={"icon"} /> to Edit
<br />
[c] or <i className="fa-sharp fa-regular fa-copy" /> to Copy
[c] or <CopyIcon className={"icon"} /> to Copy
<br />
</div>
</div>

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.info-message {
position: relative;
@ -67,7 +67,6 @@
flex-grow: 0;
padding: 3px;
border-radius: 3px 0 0 3px;
height: 22px;
width: 22px;
display: flex;
@ -75,11 +74,6 @@
justify-content: center;
align-self: flex-start;
cursor: pointer;
background-color: @term-black;
&:hover {
background-color: #777;
}
}
.code-div {
@ -115,9 +109,7 @@
padding-left: 4px;
cursor: pointer;
width: 20px;
background-color: @term-black;
border: 1px solid #333;
color: #777;
&:hover {
color: @term-white;
}

View File

@ -8,6 +8,9 @@ import cn from "classnames";
import { If } from "tsx-control-statements/components";
import type { RemoteType } from "../../types/types";
import { ReactComponent as CheckIcon } from "../assets/icons/line/check.svg";
import { ReactComponent as CopyIcon } from "../assets/icons/history/copy.svg";
import "./common.less";
type OV<V> = mobx.IObservableValue<V>;
@ -52,15 +55,15 @@ class CmdStrCode extends React.Component<
<div>copied</div>
</div>
</If>
<div key="use" className="use-button" title="Use Command" onClick={this.handleUse}>
<i className="fa-sharp fa-solid fa-check" />
<div key="use" className="use-button hoverEffect" title="Use Command" onClick={this.handleUse}>
<CheckIcon className="icon" />
</div>
<div key="code" className="code-div">
<code>{cmdstr}</code>
</div>
<div key="copy" className="copy-control">
<div className="inner-copy" onClick={this.handleCopy}>
<i title="copy" className="fa-sharp fa-regular fa-copy" />
<div key="copy" className="copy-control hoverEffect">
<div className="inner-copy" onClick={this.handleCopy} title="copy">
<CopyIcon className="icon" />
</div>
</div>
</div>

View File

@ -1,4 +1,4 @@
@import "../../../index.less";
@import "../../../app/app.less";
// modal css (also includes settings-field)
@ -128,14 +128,16 @@
.close-icon {
position: absolute;
right: 10px;
top: 6px;
right: 1em;
top: 0.8em;
cursor: pointer;
padding: 3px;
color: #aaa;
&:hover {
color: #fff;
width: 1.5em;
height: 1.5em;
border-radius: 50%;
svg {
width: 1.5em;
height: 1.5em;
fill: @base-color;
}
}
}
@ -306,7 +308,7 @@
fill: @tab-white;
}
.tab-color-icon.color-black path {
fill: @tab-black
fill: @tab-black;
}
.tab-colors {

View File

@ -9,6 +9,8 @@ import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "../../../model/model";
import { Markdown } from "../common";
import { ReactComponent as XmarkIcon } from "../../assets/icons/line/xmark.svg";
dayjs.extend(localizedFormat);
type OV<V> = mobx.IObservableValue<V>;
@ -176,8 +178,8 @@ class AlertModal extends React.Component<{}, {}> {
<p className="modal-title">
<i className="fa-sharp fa-solid fa-triangle-exclamation" /> {title}
</p>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<If condition={message.markdown}>
@ -259,8 +261,8 @@ class WelcomeModal extends React.Component<{}, {}> {
<div className="modal-content">
<header>
<div className="modal-title">welcome to [prompt]</div>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className={cn("inner-content content", { "is-hidden": pageNum != 1 })}>

View File

@ -10,6 +10,7 @@ import { LineType, RendererPluginType, ClientDataType, CommandRtnType } from "..
import { PluginModel } from "../../../plugins/plugins";
import * as util from "../../../util/util";
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
import { ReactComponent as XmarkIcon } from "../../assets/icons/line/xmark.svg";
import "./modals.less";
@ -214,8 +215,8 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
</If>
<header>
<div className="modal-title">screen settings ({screen.name.get()})</div>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className="inner-content">
@ -241,7 +242,7 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
<div className="settings-input">
<div className="tab-colors">
<div className="tab-color-cur">
<SquareIcon className={cn("tab-color-icon", "color-" + screen.getTabColor())}/>
<SquareIcon className={cn("tab-color-icon", "color-" + screen.getTabColor())} />
<span className="tab-color-name">{screen.getTabColor()}</span>
</div>
<div className="tab-color-sep">|</div>
@ -251,7 +252,7 @@ class ScreenSettingsModal extends React.Component<{ sessionId: string; screenId:
className="tab-color-select"
onClick={() => this.selectTabColor(color)}
>
<SquareIcon className={cn("tab-color-icon", "color-" + color)}/>
<SquareIcon className={cn("tab-color-icon", "color-" + color)} />
</div>
</For>
</div>
@ -378,8 +379,8 @@ class SessionSettingsModal extends React.Component<{ sessionId: string }, {}> {
<div className="modal-content">
<header>
<div className="modal-title">session settings ({session.name.get()})</div>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className="inner-content">
@ -544,8 +545,8 @@ class LineSettingsModal extends React.Component<{ linenum: number }, {}> {
<div className="modal-content">
<header>
<div className="modal-title">line settings ({line.linenum})</div>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className="inner-content">
@ -696,8 +697,8 @@ class ClientSettingsModal extends React.Component<{}, {}> {
<div className="modal-content">
<header>
<div className="modal-title">client settings</div>
<div className="close-icon">
<i onClick={this.closeModal} className="fa-sharp fa-solid fa-times" />
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className="inner-content">

View File

@ -1,4 +1,4 @@
@import "../../../index.less";
@import "../../../app/app.less";
.term-prompt {
font-weight: 300;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.modal.prompt-modal.remotes-modal {
.modal-content {

View File

@ -10,6 +10,8 @@ import { RemoteType, RemoteEditType } from "../../types/types";
import * as util from "../../util/util";
import * as textmeasure from "../../util/textmeasure";
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
import "./connections.less";
type OV<V> = mobx.IObservableValue<V>;
@ -1155,12 +1157,8 @@ class RemotesModal extends React.Component<{ model: RemotesModalModel }, {}> {
<div className="modal-content">
<header>
<div className="modal-title">Connections</div>
<div className="close-icon">
<i
title="Close (Escape)"
onClick={this.closeModal}
className="fa-sharp fa-solid fa-times"
/>
<div className="close-icon hoverEffect" title="Close (Escape)" onClick={this.closeModal}>
<XmarkIcon />
</div>
</header>
<div className="inner-content">

View File

@ -1,47 +1,57 @@
@import "../../index.less";
@import "../../app/app.less";
.history-view {
color: @term-white;
background-color: @background-session;
.icon {
width: 1.3em !important;
height: 1.3em !important;
fill: @base-color;
}
.is-left {
position: absolute;
left: 0.5em;
top: 0.5em;
}
.close-div {
padding-top: 10px;
i {
padding: 5px 5px 5px 10px;
cursor: pointer;
}
i:hover {
color: #fff;
position: absolute;
right: 1em;
top: 0.8em;
cursor: pointer;
width: 1.5em;
height: 1.5em;
border-radius: 50%;
svg {
width: 1.5em;
height: 1.5em;
fill: @base-color;
}
}
.header {
display: flex;
flex-direction: row;
margin: 10px;
align-items: flex-start;
.history-title {
margin-top: 5px;
margin-top: 0.3em;
font-weight: bold;
color: @term-white;
font-size: 1.5em;
}
input {
background-color: #333;
color: @term-white;
i {
color: @term-white;
}
border: none;
border-radius: 4px;
font-size: 1em;
padding: 0.5em 1em;
background-color: @background-session-components;
color: @base-color;
}
}
.history-search {
flex-grow: 1;
margin-top: 5px;
margin-left: 15px;
.main-search {
.field {
@ -58,6 +68,20 @@
flex-direction: row;
align-items: center;
.dropdown {
font-size: 0.8em;
padding: 0.5em 1em;
.label {
display: inline;
vertical-align: middle;
color: @base-color;
}
.icon {
vertical-align: middle;
margin-left: 1em;
}
}
.session-dropdown,
.remote-dropdown {
.dropdown-item {
@ -69,8 +93,8 @@
}
.dropdown-content {
border: 1px solid #333;
border-radius: 3px;
border-radius: 0 0 4px 4px;
width: 16em;
}
}
@ -80,9 +104,9 @@
.search-checkbox {
margin-left: 15px;
border: 1px solid #777;
padding: 5px 10px 5px 10px;
background: @base-border;
border-radius: 4px;
display: flex;
flex-direction: row;
align-items: center;
@ -113,15 +137,9 @@
}
.reset-button {
cursor: pointer;
margin-left: 15px;
border: 1px solid #777;
padding: 5px 10px 5px 10px;
&:hover {
background-color: #666;
}
margin-left: 1em;
color: @base-color;
line-height: 1.75em;
}
}
}
@ -145,15 +163,7 @@
}
.control-checkbox {
cursor: pointer;
color: #777;
width: 24px;
margin-left: 14px;
&:hover {
color: @term-white;
}
margin: 0.3em 1.2em;
}
.control-button {
@ -161,6 +171,10 @@
color: #aaa;
margin-left: 10px;
.icon {
vertical-align: text-bottom;
}
&.is-disabled {
cursor: default;
i,
@ -291,33 +305,29 @@
td.selectbox {
flex: 0 0 auto;
flex-basis: 24px;
margin-right: 1em;
cursor: pointer;
}
td.bookmark {
flex: 0 0 auto;
flex-basis: 20px;
margin-right: 1em;
cursor: pointer;
i {
position: relative;
top: 1px;
display: none;
}
}
td.ts {
flex: 0 0 auto;
flex-basis: 65px;
font-weight: bold;
margin-right: 1em;
}
td.session {
flex: 0 0 auto;
flex-basis: 120px;
text-overflow: ellipsis;
margin-right: 1em;
}
td.remote {
@ -327,6 +337,7 @@
padding-right: 5px;
max-width: 150px;
overflow: hidden;
margin-right: 2em;
}
td.cmdstr {
@ -352,4 +363,8 @@
}
}
}
.help-entry {
margin: 1em 2em;
}
}

View File

@ -1,7 +1,7 @@
import * as React from "react";
import * as mobxReact from "mobx-react";
import * as mobx from "mobx";
import { If, For, When, Otherwise, Choose } from "tsx-control-statements/components";
import { If, For } from "tsx-control-statements/components";
import { sprintf } from "sprintf-js";
import { boundMethod } from "autobind-decorator";
import cn from "classnames";
@ -13,6 +13,18 @@ import customParseFormat from "dayjs/plugin/customParseFormat";
import { Line } from "../line/linecomps";
import { CmdStrCode } from "../common/common";
import { ReactComponent as FavouritesIcon } from "../assets/icons/favourites.svg";
import { ReactComponent as XmarkIcon } from "../assets/icons/line/xmark.svg";
import { ReactComponent as AngleDownIcon } from "../assets/icons/history/angle-down.svg";
import { ReactComponent as ChevronLeftIcon } from "../assets/icons/history/chevron-left.svg";
import { ReactComponent as ChevronRightIcon } from "../assets/icons/history/chevron-right.svg";
import { ReactComponent as RightIcon } from "../assets/icons/history/right.svg";
import { ReactComponent as SearchIcon } from "../assets/icons/history/search.svg";
import { ReactComponent as SquareCheckIcon } from "../assets/icons/history/square-check.svg";
import { ReactComponent as SquareMinusIcon } from "../assets/icons/history/square-minus.svg";
import { ReactComponent as SquareIcon } from "../assets/icons/history/square.svg";
import { ReactComponent as TrashIcon } from "../assets/icons/trash.svg";
import "./history.less";
dayjs.extend(customParseFormat);
@ -315,12 +327,12 @@ class HistoryView extends React.Component<{}, {}> {
let hasMore = hvm.hasMore.get();
let offset = hvm.offset.get();
let numSelected = hvm.selectedItems.size;
let controlCheckboxIcon = "fa-sharp fa-regular fa-square";
let controlCheckboxIcon = <SquareIcon className="icon" />;
if (numSelected > 0) {
controlCheckboxIcon = "fa-sharp fa-regular fa-square-minus";
controlCheckboxIcon = <SquareMinusIcon className="icon" />;
}
if (numSelected > 0 && numSelected == items.length) {
controlCheckboxIcon = "fa-sharp fa-regular fa-square-check";
controlCheckboxIcon = <SquareCheckIcon className="icon" />;
}
let activeItemId = hvm.activeItem.get();
let activeItem = hvm.getHistoryItemById(activeItemId);
@ -333,7 +345,7 @@ class HistoryView extends React.Component<{}, {}> {
let remoteIds = Object.keys(rnames);
let remoteId: string = null;
return (
<div className={cn("history-view", "alt-view", { "is-hidden": isHidden })}>
<div className={cn("history-view", { "is-hidden": isHidden })}>
<div className="header">
<div className="history-title">HISTORY</div>
<div className="history-search">
@ -347,8 +359,8 @@ class HistoryView extends React.Component<{}, {}> {
onChange={this.changeSearchText}
onKeyDown={this.searchKeyDown}
/>
<span className="icon is-small is-left">
<i className="fa-sharp fa-solid fa-search" />
<span className="is-small is-left">
<SearchIcon className="icon" />
</span>
</p>
</div>
@ -358,17 +370,13 @@ class HistoryView extends React.Component<{}, {}> {
"is-active": this.sessionDropdownActive.get(),
})}
>
<div className="dropdown-trigger">
<button onClick={this.toggleSessionDropdown} className="button is-small is-dark">
<span>
{hvm.searchSessionId.get() == null
? "Limit Session"
: formatSessionName(snames, hvm.searchSessionId.get())}
</span>
<span className="icon is-small">
<i className="fa-sharp fa-regular fa-angle-down" aria-hidden="true"></i>
</span>
</button>
<div onClick={this.toggleSessionDropdown}>
<span className="label">
{hvm.searchSessionId.get() == null
? "Limit Session"
: formatSessionName(snames, hvm.searchSessionId.get())}
</span>
<AngleDownIcon className="icon" />
</div>
<div className="dropdown-menu" role="menu">
<div className="dropdown-content has-background-black-ter">
@ -396,17 +404,13 @@ class HistoryView extends React.Component<{}, {}> {
"is-active": this.remoteDropdownActive.get(),
})}
>
<div className="dropdown-trigger">
<button onClick={this.toggleRemoteDropdown} className="button is-small is-dark">
<span>
{hvm.searchRemoteId.get() == null
? "Limit Remote"
: formatRemoteName(rnames, { remoteid: hvm.searchRemoteId.get() })}
</span>
<span className="icon is-small">
<i className="fa-sharp fa-regular fa-angle-down" aria-hidden="true"></i>
</span>
</button>
<div onClick={this.toggleRemoteDropdown}>
<span className="label">
{hvm.searchRemoteId.get() == null
? "Limit Remote"
: formatRemoteName(rnames, { remoteid: hvm.searchRemoteId.get() })}
</span>
<AngleDownIcon className="icon" />
</div>
<div className="dropdown-menu" role="menu">
<div className="dropdown-content has-background-black-ter">
@ -429,7 +433,7 @@ class HistoryView extends React.Component<{}, {}> {
</div>
</div>
</div>
<div className="allow-meta search-checkbox">
<div className="allow-meta search-checkbox hoverEffect">
<div className="checkbox-container">
<input
onChange={this.toggleShowMeta}
@ -445,17 +449,16 @@ class HistoryView extends React.Component<{}, {}> {
<div onClick={this.toggleShowMeta} className="fromts-text">
From:&nbsp;
</div>
<div>
<div className="hoverEffect">
<input
type="date"
onChange={this.handleFromTsChange}
value={this.searchFromTsInputValue()}
className="input is-small"
/>
</div>
</div>
<div
className="filter-cmds search-checkbox"
className="filter-cmds search-checkbox hoverEffect"
title="Filter common commands like 'ls' and 'cd' from the results"
>
<div className="checkbox-container">
@ -469,18 +472,18 @@ class HistoryView extends React.Component<{}, {}> {
Filter Cmds
</div>
</div>
<div onClick={this.resetAllFilters} className="reset-button">
<div onClick={this.resetAllFilters} className="button reset-button hoverEffect">
Reset All
</div>
</div>
</div>
<div className="close-div">
<i onClick={this.clickCloseHandler} className="fa-sharp fa-solid fa-xmark" />
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.clickCloseHandler}>
<XmarkIcon />
</div>
</div>
<div className={cn("control-bar", "is-top", { "is-hidden": items.length == 0 })}>
<div className="control-checkbox" onClick={this.handleControlCheckbox}>
<i className={controlCheckboxIcon} title="Toggle Selection" />
<div className="control-checkbox" onClick={this.handleControlCheckbox} title="Toggle Selection">
{controlCheckboxIcon}
</div>
<div
className={cn(
@ -490,8 +493,10 @@ class HistoryView extends React.Component<{}, {}> {
)}
onClick={this.handleClickDelete}
>
<i className="fa-sharp fa-solid fa-trash" title="Purge Selected Items" />{" "}
<span>Delete Items</span>
<span>
<TrashIcon className="icon" title="Purge Selected Items" />
&nbsp;Delete Items
</span>
</div>
<div className="spacer" />
<div className="showing-text">
@ -501,14 +506,14 @@ class HistoryView extends React.Component<{}, {}> {
className={cn("showing-btn", { "is-disabled": offset == 0 })}
onClick={offset != 0 ? this.handlePrev : null}
>
<i className="fa-sharp fa-solid fa-chevron-left" />
<ChevronLeftIcon className="icon" />
</div>
<div className="btn-spacer" />
<div
className={cn("showing-btn", { "is-disabled": !hasMore })}
onClick={hasMore ? this.handleNext : null}
>
<i className="fa-sharp fa-solid fa-chevron-right" />
<ChevronRightIcon className="icon" />
</div>
</div>
<table className="history-table" cellSpacing="0" cellPadding="0" border={0} ref={this.tableRef}>
@ -520,14 +525,14 @@ class HistoryView extends React.Component<{}, {}> {
>
<td className="selectbox" onClick={() => this.handleSelect(item.historyid)}>
<If condition={hvm.selectedItems.get(item.historyid)}>
<i className="fa-sharp fa-regular fa-square-check"></i>
<SquareCheckIcon className="icon" />
</If>
<If condition={!hvm.selectedItems.get(item.historyid)}>
<i className="fa-sharp fa-regular fa-square"></i>
<SquareIcon className="icon" />
</If>
</td>
<td className="bookmark" style={{ display: "none" }}>
<i className="fa-sharp fa-regular fa-bookmark" />
<FavouritesIcon className="icon" />
</td>
<td className="ts">{getHistoryViewTs(nowDate, item.ts)}</td>
<td className="session">{formatSSName(snames, scrnames, item)}</td>
@ -566,14 +571,14 @@ class HistoryView extends React.Component<{}, {}> {
className={cn("showing-btn", { "is-disabled": offset == 0 })}
onClick={offset != 0 ? this.handlePrev : null}
>
<i className="fa-sharp fa-solid fa-chevron-left" />
<ChevronLeftIcon className="icon" />
</div>
<div className="btn-spacer" />
<div
className={cn("showing-btn", { "is-disabled": !hasMore })}
onClick={hasMore ? this.handleNext : null}
>
<i className="fa-sharp fa-solid fa-chevron-right" />
<ChevronRightIcon className="icon" />
</div>
</div>
<If condition={items.length == 0}>
@ -582,10 +587,7 @@ class HistoryView extends React.Component<{}, {}> {
</div>
</If>
<div className="alt-help">
<div className="help-entry">
[Esc] to Close
<br />
</div>
<div className="help-entry">[Esc] to Close</div>
</div>
</div>
);
@ -655,7 +657,7 @@ class LineContainer extends React.Component<{ historyId: string; width: number }
<If condition={canViewInContext}>
<div className="line-context">
<div title="View in Context" className="vic-btn" onClick={this.viewInContext}>
<i className="fa-sharp fa-solid fa-right" /> {ssStr}
<RightIcon className="icon" /> {ssStr}
</div>
</div>
</If>

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.line.line-text {
flex-direction: row;
@ -97,7 +97,7 @@
.terminal-wrapper {
line-height: normal;
&.zero-height {
padding: 0;
margin: 0;

View File

@ -202,11 +202,11 @@ class MainSideBar extends React.Component<{}, {}> {
</div>
<div className="contents">
<div className="top">
<div className="item hoverEffect">
{/*<div className="item disabled">
<AppsIcon className="icon" />
Apps
<span className="hotkey">&#x2318;A</span>
</div>
</div>*/}
<div className="item hoverEffect" onClick={this.handleHistoryClick}>
<HistoryIcon className="icon" />
History

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.main-sidebar {
padding: 0;
@ -103,6 +103,9 @@
visibility: hidden;
letter-spacing: 6px;
}
.disabled .hotkey {
display: none;
}
&:hover .hotkey {
visibility: visible;
}

View File

@ -1,4 +1,4 @@
@import "../../../index.less";
@import "../../../app/app.less";
.cmd-input {
border-radius: 6px;

View File

@ -1,4 +1,4 @@
@import "../../../index.less";
@import "../../../app/app.less";
.main-content {
.screen-view {

View File

@ -1,19 +1,9 @@
@import "../../../index.less";
@import "../../../app/app.less";
#main .screen-tabs .screen-tab {
border-radius: 12px 0px 0px 0px;
border-top: 1px solid transparent;
&.is-active {
border-color: @prompt-green;
background: linear-gradient(
180deg,
rgba(88, 193, 66, 0.2) 9.34%,
rgba(88, 193, 66, 0.03) 44.16%,
rgba(88, 193, 66, 0) 86.79%
);
}
&.color-default {
svg.left-icon path {
fill: @tab-green;
@ -130,11 +120,13 @@
}
&:hover {
border-color: @prompt-green !important;
.tab-gear {
display: block;
}
}
&:hover:not(.is-active) {
border-color: @disabled-color !important;
}
}
&:hover .screen-tab .tab-index {

View File

@ -8,6 +8,7 @@ import cn from "classnames";
import { debounce } from "throttle-debounce";
import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat";
import { generateBackgroundWithGradient } from "../../../util/util";
import { GlobalModel, GlobalCommandRunner, Session, ScreenLines, Screen } from "../../../model/model";
import { renderCmdText } from "../../common/common";
import { ReactComponent as SquareIcon } from "../../assets/icons/tab/square.svg";
@ -116,6 +117,15 @@ class ScreenTabs extends React.Component<{ session: Session }, {}> {
let webShared = screen.isWebShared() ? (
<i title="shared to web" className="fa-sharp fa-solid fa-share-nodes web-share-icon" />
) : null;
const style = { borderColor: "transparent", background: "none" };
if (screen.isActive()) {
let tabColor = screen.getTabColor();
if (tabColor === "default") tabColor = "rgb(0, 128, 0)"; //TODO: this is the color of @tab-green in index.css. hardcoding since I cant think of an easy way out
style.borderColor = tabColor;
style.background = generateBackgroundWithGradient(tabColor);
}
return (
<div
key={screen.screenId}
@ -125,6 +135,7 @@ class ScreenTabs extends React.Component<{ session: Session }, {}> {
{ "is-active": activeScreenId == screen.screenId, "is-archived": screen.archived.get() },
"color-" + screen.getTabColor()
)}
style={style}
onClick={() => this.handleSwitchScreen(screen.screenId)}
onContextMenu={(event) => this.openScreenSettings(event, screen)}
>

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.session-view {
flex-grow: 1;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.code-renderer {
.monaco-editor {
@ -68,11 +68,11 @@
}
.readonly {
position: absolute;
top: 0;
top: 0.2em;
right: 12rem;
border-radius: 5px;
background-color: @button-background;
color: @prompt-green;
color: @error-red;
z-index: 1;
padding: 0 0.8em;
font-size: 0.8em;

View File

@ -1,10 +1,10 @@
@import "../../index.less";
@import "../../app/app.less";
.csv-renderer {
.cursor-pointer {
cursor: pointer;
}
.select-none {
user-select: none;
}
@ -13,56 +13,59 @@
.flex {
display: flex;
}
.items-center {
align-items: center;
}
.gap-2 {
gap: 8px;
gap: 8px;
}
/* Button styles */
button.border {
border: 1px solid #ccc;
}
button.rounded {
border-radius: 4px;
}
button.p-1 {
padding: 4px;
padding: 4px;
}
/* Disabling styles for buttons */
button[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
/* Input styles */
input.border, select.border {
input.border,
select.border {
border: 1px solid #ccc;
}
input.rounded, select.rounded {
input.rounded,
select.rounded {
border-radius: 4px;
}
input.p-1, select.p-1 {
input.p-1,
select.p-1 {
padding: 4px;
}
input.w-16 {
width: 64px;
width: 64px;
}
/* Text styles */
strong {
font-weight: bold;
}
.global-search-render {
margin-bottom: 10px;
}
@ -70,33 +73,33 @@
table {
border: 1px solid rgb(146, 146, 146);
margin-bottom: 10px;
tbody {
border-bottom: 1px solid rgb(146, 146, 146);
border-bottom: 1px solid rgb(146, 146, 146);
}
th {
color: white;
border-bottom: 1px solid rgb(146, 146, 146);
border-right: 1px solid rgb(146, 146, 146);
padding: 2px 10px 4px 10px;
color: white;
border-bottom: 1px solid rgb(146, 146, 146);
border-right: 1px solid rgb(146, 146, 146);
padding: 2px 10px 4px 10px;
.min-max-renderer {
min-width: 200px;
display: flex;
.min-max-renderer {
min-width: 200px;
display: flex;
.search-renderer {
flex: 1;
.search-renderer {
flex: 1;
input {
width: 99%;
}
input {
width: 99%;
}
}
.search-renderer:first-child {
margin-right: 3px;
}
}
.search-renderer:first-child {
margin-right: 3px;
}
}
}
tr {
@ -106,7 +109,7 @@
}
td:last-child {
border-right: none;
}
}
}
}

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.image-renderer {
padding: 10px;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.markdown-renderer {
color: @term-white;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.mustache-renderer {
color: @term-white;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
.openai-renderer {
.openai-message {

View File

@ -12,7 +12,7 @@ import type {
WindowSize,
PtyDataType,
} from "../../types/types";
import { getTheme } from "../../app/common/themes";
import { getTheme } from "../../app/common/themes/themes";
type DataUpdate = {
data: Uint8Array;

View File

@ -1,4 +1,4 @@
@import "../../index.less";
@import "../../app/app.less";
@import "./xterm.less";
.terminal-wrapper {

View File

@ -376,6 +376,28 @@ function openLink(url: string): void {
window.open(url, "_blank");
}
function getColorRGB(colorInput) {
const tempElement = document.createElement("div");
tempElement.style.color = colorInput;
document.body.appendChild(tempElement);
const computedColorStyle = window.getComputedStyle(tempElement).color;
document.body.removeChild(tempElement);
return computedColorStyle;
}
// usgae witing an element : style={background:generateBackgroundWithGradient('red')}
function generateBackgroundWithGradient(colorName = "white", decay = 3) {
const rgb = getColorRGB(colorName);
const rgba = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
const r = rgba[1];
const g = rgba[2];
const b = rgba[3];
const lambda = -Math.log(0.01 * decay) / (0.1 * decay);
const percentages = [9.34, 44.16, 86.79];
const opacities = percentages.map((p) => Math.exp((-lambda * p) / 100));
return `linear-gradient(180deg, rgba(${r}, ${g}, ${b}, ${opacities[0]}) ${percentages[0]}%, rgba(${r}, ${g}, ${b}, ${opacities[1]}) ${percentages[1]}%, rgba(${r}, ${g}, ${b}, 0) ${percentages[2]}%)`;
}
export {
handleJsonFetchResponse,
base64ToArray,
@ -397,4 +419,6 @@ export {
isBoolEq,
hasNoModifiers,
openLink,
generateBackgroundWithGradient,
getColorRGB,
};

View File

@ -5,7 +5,7 @@ const path = require("path");
module.exports = {
mode: "development",
entry: {
prompt: ["./src/index.ts", "./src/index.less"],
prompt: ["./src/index.ts", "./src/app/app.less"],
},
output: {
path: path.resolve(__dirname, "dist"),

View File

@ -5,7 +5,7 @@ const path = require("path");
module.exports = {
mode: "development",
entry: {
webshare: ["./src/webshare.ts", "./src/index.less"],
webshare: ["./src/webshare.ts", "./src/app/app.less"],
},
output: {
path: path.resolve(__dirname, "webshare/dist"),

988
yarn.lock

File diff suppressed because it is too large Load Diff