mirror of
https://github.com/urbit/shrub.git
synced 2024-12-01 06:35:32 +03:00
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:
parent
65f9f904c7
commit
2d3e803704
@ -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%'
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user