devex: improved resize behavior

- only resize when necessary (check the container's height)
- refactor CSS: use position relative / absolute to stack Buffers instead of display:none; this affects the calcuations used by fit()
- fix dark mode styles, tweak viewport height (100vh --> 99vh) to prevent overflow scroller
This commit is contained in:
tomholford 2022-04-19 03:41:40 -07:00
parent 65f9f904c7
commit 2d3e803704
3 changed files with 32 additions and 10 deletions

View File

@ -14,7 +14,7 @@ import React from 'react';
import { Box, Col } from '@tlon/indigo-react';
import { makeTheme } from './lib/theme';
import { showBlit, csi, hasBell } from './lib/blit';
import { DEFAULT_SESSION, RESIZE_DEBOUNCE_MS } from './constants';
import { DEFAULT_SESSION, RESIZE_DEBOUNCE_MS, RESIZE_THRESHOLD_PX } from './constants';
import { retry } from './lib/retry';
const termConfig: ITerminalOptions = {
@ -124,6 +124,7 @@ const readInput = (term: Terminal, e: string): Belt[] => {
const onResize = async (name: string, session: Session) => {
if (session) {
session.fit.fit();
api.poke(pokeTask(name, { blew: { w: session.term.cols, h: session.term.rows } }));
}
};
@ -171,9 +172,6 @@ export default function Buffer({ name, selected, dark }: BufferProps) {
//
term.onData(e => onInput(name, ses, e));
term.onBinary(e => onInput(name, ses, e));
term.onResize((e) => {
api.poke(pokeTask(name, { blew: { w: e.cols, h: e.rows } }));
});
// open subscription
//
@ -218,11 +216,22 @@ export default function Buffer({ name, selected, dark }: BufferProps) {
});
}, []);
const shouldResize = useCallback(() => {
if(!session) {
return false;
}
const containerHeight = document.querySelector('.buffer-container')?.clientHeight || Infinity;
const terminalHeight = session.term.element?.clientHeight || 0;
return (containerHeight - terminalHeight) >= RESIZE_THRESHOLD_PX;
}, [session]);
const onSelect = useCallback(async () => {
if (session && selected) {
if (session && selected && shouldResize()) {
session.fit.fit();
session.term.focus();
await api.poke(pokeTask(name, { blew: { w: session.term.cols, h: session.term.rows } }));
session.term.focus();
}
}, [session, selected]);
@ -243,13 +252,14 @@ export default function Buffer({ name, selected, dark }: BufferProps) {
}
}, [session, containerRef]);
// on-init, open slogstream and fetch existing sessions
// initialize resize listeners
//
useEffect(() => {
if(!session) {
return;
}
// TODO: use ResizeObserver for improved performance?
const debouncedResize = debounce(() => onResize(name, session), RESIZE_DEBOUNCE_MS);
window.addEventListener('resize', debouncedResize);
@ -285,7 +295,8 @@ export default function Buffer({ name, selected, dark }: BufferProps) {
bg='white'
fontFamily='mono'
overflow='hidden'
style={selected ? {} : { display: 'none' }}
className="terminal-container"
style={selected ? { zIndex: 999 } : {}}
>
<Col
width='100%'

View File

@ -1,6 +1,7 @@
export const DEFAULT_SESSION = '';
export const DEFAULT_HANDLER = 'hood';
export const RESIZE_DEBOUNCE_MS = 100;
export const RESIZE_THRESHOLD_PX = 15;
/**
* Session ID validity:

View File

@ -23,13 +23,19 @@
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
<style>
body, #root {
height: 100vh;
height: 99vh; /* prevent scrollbar on outer frame */
margin: 0;
padding: 0;
}
.buffer-container {
height: calc(100% - 40px);
position: relative;
}
.terminal-container {
position: absolute;
top: 0;
}
div.header {
@ -93,6 +99,10 @@
}
@media (prefers-color-scheme: dark) {
html {
background-color: rgb(26,26,26);
}
div.tabs {
background-color: rgb(26, 26, 26);
color: rgba(255, 255, 255, 0.9);
@ -112,7 +122,7 @@
}
div.tabs > div.selected {
border-bottom: black solid 1px;
border-bottom: rgb(26,26,26) solid 1px;
}
button.info-btn {