mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-18 21:09:38 +00:00
Resizing working w/ containers!
This commit is contained in:
@@ -38,6 +38,7 @@ class EmeddedTerminal extends React.Component {
|
||||
const nodeId = pipe.get('nodeId');
|
||||
const node = details.get(nodeId);
|
||||
const d = node && node.details;
|
||||
const control = d && d.controls && d.controls[0];
|
||||
const titleBarColor = d && getNodeColorDark(d.rank, d.label, d.pseudo);
|
||||
const statusBarColor = d && brightenColor(titleBarColor);
|
||||
const title = d && d.label;
|
||||
@@ -53,6 +54,7 @@ class EmeddedTerminal extends React.Component {
|
||||
<Terminal
|
||||
key={pipe.get('id')}
|
||||
pipe={pipe}
|
||||
control={control}
|
||||
connect={this.state.animated}
|
||||
titleBarColor={titleBarColor}
|
||||
statusBarColor={statusBarColor}
|
||||
|
||||
@@ -8,7 +8,7 @@ import classNames from 'classnames';
|
||||
import { clickCloseTerminal } from '../actions/app-actions';
|
||||
import { getNeutralColor } from '../utils/color-utils';
|
||||
import { setDocumentTitle } from '../utils/title-utils';
|
||||
import { getPipeStatus, basePath } from '../utils/web-api-utils';
|
||||
import { getPipeStatus, basePath, doResizePipe } from '../utils/web-api-utils';
|
||||
import Term from 'xterm';
|
||||
|
||||
const wsProto = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
@@ -32,27 +32,29 @@ function ab2str(buf) {
|
||||
return decodedString;
|
||||
}
|
||||
|
||||
function terminalCellSize(wrapperNode, rows, cols) {
|
||||
const height = wrapperNode.clientHeight;
|
||||
function terminalCellSize(wrapperNode) {
|
||||
// Badly guess the width/height of the row.
|
||||
let characterWidth = 20;
|
||||
let characterHeight = 20;
|
||||
|
||||
// Guess the width of the row.
|
||||
let width = wrapperNode.clientWidth;
|
||||
// Now try and measure the first row we find.
|
||||
const firstRow = wrapperNode.querySelector('.terminal div');
|
||||
if (!firstRow) {
|
||||
const subjectRow = wrapperNode.querySelector('.terminal .xterm-rows div');
|
||||
if (!subjectRow) {
|
||||
log("ERROR: Couldn't find first row, resizing might not work very well.");
|
||||
} else {
|
||||
const rowDisplay = firstRow.style.display;
|
||||
firstRow.style.display = 'inline';
|
||||
width = firstRow.offsetWidth;
|
||||
firstRow.style.display = rowDisplay;
|
||||
const rowDisplay = subjectRow.style.display;
|
||||
const contentBuffer = subjectRow.innerHTML;
|
||||
|
||||
subjectRow.innerHTML = 'W';
|
||||
subjectRow.style.display = 'inline';
|
||||
characterWidth = subjectRow.getBoundingClientRect().width;
|
||||
subjectRow.style.display = rowDisplay;
|
||||
characterHeight = parseInt(subjectRow.offsetHeight, 10);
|
||||
subjectRow.innerHTML = contentBuffer;
|
||||
}
|
||||
|
||||
const pixelPerCol = width / cols;
|
||||
const pixelPerRow = height / rows;
|
||||
|
||||
log('Caculated (col, row) sizes in px: ', pixelPerCol, pixelPerRow);
|
||||
return {pixelPerCol, pixelPerRow};
|
||||
log('Caculated (charWidth, charHeight) sizes in px: ', characterWidth, characterHeight);
|
||||
return {characterWidth, characterHeight};
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +90,8 @@ class Terminal extends React.Component {
|
||||
connected: false,
|
||||
rows: DEFAULT_ROWS,
|
||||
cols: DEFAULT_COLS,
|
||||
pixelPerCol: 0,
|
||||
pixelPerRow: 0
|
||||
characterWidth: 0,
|
||||
characterHeight: 0
|
||||
};
|
||||
|
||||
this.handleCloseClick = this.handleCloseClick.bind(this);
|
||||
@@ -180,15 +182,14 @@ class Terminal extends React.Component {
|
||||
|
||||
this.createWebsocket(this.term);
|
||||
|
||||
const {pixelPerCol, pixelPerRow} = terminalCellSize(
|
||||
this.term.element, this.state.rows, this.state.cols);
|
||||
const {characterWidth, characterHeight} = terminalCellSize(this.term.element);
|
||||
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
|
||||
this.resizeTimeout = setTimeout(() => {
|
||||
this.setState({
|
||||
pixelPerCol,
|
||||
pixelPerRow
|
||||
characterWidth,
|
||||
characterHeight
|
||||
});
|
||||
this.handleResize();
|
||||
}, 10);
|
||||
@@ -248,17 +249,20 @@ class Terminal extends React.Component {
|
||||
this.props.dispatch(clickCloseTerminal(this.getPipeId()));
|
||||
|
||||
const bcr = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
const minWidth = this.state.pixelPerCol * 80 + (8 * 2);
|
||||
const minWidth = this.state.characterWidth * 80 + (8 * 2);
|
||||
openNewWindow(`terminal.html#!/state/${paramString}`, bcr, minWidth);
|
||||
}
|
||||
|
||||
handleResize() {
|
||||
const innerNode = ReactDOM.findDOMNode(this.innerFlex);
|
||||
// scrollbar === 16px
|
||||
const width = innerNode.clientWidth - (2 * 8) - 16;
|
||||
const height = innerNode.clientHeight - (2 * 8);
|
||||
const cols = DEFAULT_COLS;
|
||||
const rows = Math.floor(height / this.state.pixelPerRow);
|
||||
const cols = Math.floor(width / this.state.characterWidth);
|
||||
const rows = Math.floor(height / this.state.characterHeight);
|
||||
|
||||
this.setState({cols, rows});
|
||||
doResizePipe(this.getPipeId(), this.props.control, cols, rows)
|
||||
.then(() => this.setState({cols, rows}));
|
||||
}
|
||||
|
||||
isEmbedded() {
|
||||
@@ -339,7 +343,7 @@ class Terminal extends React.Component {
|
||||
overflow: 'hidden',
|
||||
};
|
||||
const innerStyle = {
|
||||
width: (this.state.cols + 2) * this.state.pixelPerCol
|
||||
width: (this.state.cols + 2) * this.state.characterWidth
|
||||
};
|
||||
const innerClassName = classNames('terminal-inner hideable', {
|
||||
'terminal-inactive': !this.state.connected
|
||||
|
||||
@@ -248,6 +248,22 @@ export function doControlRequest(nodeId, control, dispatch) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function doResizePipe(pipeId, control, cols, rows) {
|
||||
const url = `api/control/${encodeURIComponent(control.probeId)}/`
|
||||
+ `${encodeURIComponent(control.nodeId)}/docker_resize_exec_tty`;
|
||||
|
||||
return reqwest({
|
||||
method: 'POST',
|
||||
url,
|
||||
data: JSON.stringify({pipeID: pipeId, width: cols.toString(), height: rows.toString()}),
|
||||
})
|
||||
.fail((err) => {
|
||||
log(`Error resizing pipe: ${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function deletePipe(pipeId, dispatch) {
|
||||
const url = `api/pipe/${encodeURIComponent(pipeId)}`;
|
||||
reqwest({
|
||||
@@ -263,6 +279,7 @@ export function deletePipe(pipeId, dispatch) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function getPipeStatus(pipeId, dispatch) {
|
||||
const url = `api/pipe/${encodeURIComponent(pipeId)}/check`;
|
||||
reqwest({
|
||||
|
||||
@@ -44,10 +44,9 @@ module.exports = {
|
||||
'webpack-dev-server/client?http://' + WEBPACK_SERVER_HOST + ':4041',
|
||||
'webpack/hot/only-dev-server'
|
||||
],
|
||||
vendors: ['babel-polyfill', 'classnames', 'd3', 'dagre', 'filesize',
|
||||
'immutable', 'lodash', 'moment', 'page', 'react',
|
||||
'react-dom', 'react-motion', 'react-redux', 'redux', 'redux-thunk',
|
||||
'reqwest']
|
||||
vendors: ['babel-polyfill', 'classnames', 'd3', 'dagre', 'filesize', 'immutable', 'lodash',
|
||||
'moment', 'page', 'react', 'react-dom', 'react-motion', 'react-redux', 'redux',
|
||||
'redux-thunk', 'reqwest', 'xterm']
|
||||
},
|
||||
|
||||
// This will not actually create a app.js file in ./build. It is used
|
||||
|
||||
Reference in New Issue
Block a user