mirror of
https://github.com/urbit/shrub.git
synced 2024-12-22 10:21:31 +03:00
webterm: improve style & dark mode reactivity
Now reacts to changes in light/dark more, uses Landscape font set, covers up container gaps.
This commit is contained in:
parent
81e7808247
commit
d355d3b71c
@ -1,21 +1,21 @@
|
||||
import React, {
|
||||
Component,
|
||||
useState,
|
||||
useEffect,
|
||||
useRef,
|
||||
useCallback
|
||||
} from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import useTermState, { TermState } from '~/logic/state/term';
|
||||
import useTermState from '~/logic/state/term';
|
||||
import useSettingsState from "~/logic/state/settings";
|
||||
import useLocalState from "~/logic/state/local";
|
||||
|
||||
import { Terminal, ITerminalOptions } from 'xterm';
|
||||
import { Terminal, ITerminalOptions, ITheme } from 'xterm';
|
||||
import { FitAddon } from 'xterm-addon-fit';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
import { Box, Col } from '@tlon/indigo-react';
|
||||
|
||||
import './css/custom.css';
|
||||
import '../../../../node_modules/xterm/css/xterm.css'
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { Belt } from '~/logic/api/term';
|
||||
import { Blit, Stye, Stub, Tint, Deco } from '~/types/term-update';
|
||||
@ -28,6 +28,26 @@ type TermAppProps = {
|
||||
notificationsCount: number;
|
||||
}
|
||||
|
||||
const makeTheme = (dark: boolean): ITheme => {
|
||||
let fg, bg: string;
|
||||
if (dark) {
|
||||
fg = 'white';
|
||||
bg = 'black';
|
||||
} else {
|
||||
fg = 'black';
|
||||
bg = 'white';
|
||||
}
|
||||
//TODO indigo colors.
|
||||
// we can't pluck these from ThemeContext because they have transparency.
|
||||
// technically xterm supports transparency, but it degrades performance.
|
||||
return {
|
||||
foreground: fg,
|
||||
background: bg,
|
||||
brightBlack: '#7f7f7f', //NOTE slogs
|
||||
cursor: fg,
|
||||
}
|
||||
}
|
||||
|
||||
const termConfig: ITerminalOptions = {
|
||||
logLevel: 'warn',
|
||||
//
|
||||
@ -37,13 +57,9 @@ const termConfig: ITerminalOptions = {
|
||||
cols: 80,
|
||||
scrollback: 10000,
|
||||
//
|
||||
theme: { //TODO vary with landscape theme?
|
||||
foreground: 'black',
|
||||
background: 'white',
|
||||
cursor: 'black',
|
||||
cursorAccent: 'white',
|
||||
//TODO selection color
|
||||
},
|
||||
fontFamily: '"Source Code Pro","Roboto mono","Courier New",monospace',
|
||||
//NOTE theme colors configured dynamically
|
||||
//
|
||||
bellStyle: 'sound',
|
||||
bellSound: bel,
|
||||
//
|
||||
@ -111,10 +127,13 @@ export default function TermApp(props: TermAppProps) {
|
||||
const { api } = props;
|
||||
|
||||
const container = useRef<HTMLElement>(null);
|
||||
|
||||
//TODO allow switching of selected
|
||||
const { sessions, selected, set } = useTermState();
|
||||
|
||||
const osDark = useLocalState((state) => state.dark);
|
||||
const theme = useSettingsState(s => s.display.theme);
|
||||
const dark = theme === 'dark' || (theme === 'auto' && osDark);
|
||||
|
||||
const onSlog = useCallback((slog) => {
|
||||
if (!sessions['']) {
|
||||
console.log('default session mia!', 'slog:', slog);
|
||||
@ -323,6 +342,20 @@ export default function TermApp(props: TermAppProps) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// on dark mode change, change terminals' theme
|
||||
//
|
||||
useEffect(() => {
|
||||
const theme = makeTheme(dark);
|
||||
for (let ses in sessions) {
|
||||
sessions[ses].term.setOption('theme', theme);
|
||||
}
|
||||
if (container.current) {
|
||||
container.current.style.backgroundColor = theme.background || '';
|
||||
}
|
||||
}, [dark, sessions]);
|
||||
|
||||
// on selected change, maybe setup the term, or put it into the container
|
||||
//
|
||||
useEffect(() => {
|
||||
let ses = sessions[selected];
|
||||
|
||||
@ -332,6 +365,7 @@ export default function TermApp(props: TermAppProps) {
|
||||
// set up terminal
|
||||
//
|
||||
let term = new Terminal(termConfig);
|
||||
term.setOption('theme', makeTheme(dark));
|
||||
const fit = new FitAddon();
|
||||
term.loadAddon(fit);
|
||||
|
||||
|
@ -1,157 +0,0 @@
|
||||
input#term {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation: 4s ease-in-out infinite opacity_blink;
|
||||
}
|
||||
|
||||
@keyframes opacity_blink {
|
||||
0% { opacity: 0; }
|
||||
10% { opacity: 1; }
|
||||
80% { opacity: 1; }
|
||||
90% { opacity: 0; }
|
||||
100% { opacity: 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Default styles for xterm.js
|
||||
* TODO import from xterm in node_modules, but how?
|
||||
*/
|
||||
|
||||
.xterm {
|
||||
font-feature-settings: "liga" 0;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.xterm.focus,
|
||||
.xterm:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-helpers {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/**
|
||||
* The z-index of the helpers must be higher than the canvases in order for
|
||||
* IMEs to appear on top.
|
||||
*/
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -5;
|
||||
/** Prevent wrapping so the IME appears against the textarea at the correct position */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.xterm .composition-view {
|
||||
/* TODO: Composition position got messed up somewhere */
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
display: none;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.xterm .composition-view.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-scroll-area {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.xterm-char-measure-element {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999em;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.xterm {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.xterm.enable-mouse-events {
|
||||
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xterm.column-select.focus {
|
||||
/* Column selection mode */
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility,
|
||||
.xterm .xterm-message {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .live-region {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xterm-dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.xterm-underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user