details-card.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import React from 'react';
  2. import { connect } from 'react-redux';
  3. import NodeDetails from './node-details';
  4. import EmbeddedTerminal from './embedded-terminal';
  5. import {
  6. DETAILS_PANEL_WIDTH as WIDTH,
  7. DETAILS_PANEL_OFFSET as OFFSET,
  8. DETAILS_PANEL_MARGINS as MARGINS
  9. } from '../constants/styles';
  10. class DetailsCard extends React.Component {
  11. constructor(props, context) {
  12. super(props, context);
  13. this.state = {
  14. mounted: null
  15. };
  16. }
  17. componentDidMount() {
  18. setTimeout(() => {
  19. this.setState({mounted: true});
  20. });
  21. }
  22. render() {
  23. let transform;
  24. const { origin, showingTerminal } = this.props;
  25. const panelHeight = window.innerHeight - MARGINS.bottom - MARGINS.top;
  26. if (origin && !this.state.mounted) {
  27. // render small panel near origin, will transition into normal panel after being mounted
  28. const scaleY = origin.height / (window.innerHeight - MARGINS.bottom - MARGINS.top) / 2;
  29. const scaleX = origin.width / WIDTH / 2;
  30. const centerX = window.innerWidth - MARGINS.right - (WIDTH / 2);
  31. const centerY = (panelHeight / 2) + MARGINS.top;
  32. const dx = (origin.left + (origin.width / 2)) - centerX;
  33. const dy = (origin.top + (origin.height / 2)) - centerY;
  34. transform = `translate(${dx}px, ${dy}px) scale(${scaleX},${scaleY})`;
  35. } else {
  36. // stack effect: shift top cards to the left, shrink lower cards vertically
  37. const shiftX = -1 * this.props.index * OFFSET;
  38. const position = this.props.cardCount - this.props.index - 1; // reverse index
  39. const scaleY = (position === 0) ? 1 : (panelHeight - (2 * OFFSET * position)) / panelHeight;
  40. if (scaleY !== 1) {
  41. transform = `translateX(${shiftX}px) scaleY(${scaleY})`;
  42. } else {
  43. // scale(1) is sometimes blurry
  44. transform = `translateX(${shiftX}px)`;
  45. }
  46. }
  47. const style = {
  48. left: showingTerminal ? MARGINS.right : null,
  49. transform,
  50. width: showingTerminal ? null : WIDTH
  51. };
  52. return (
  53. <div className="details-wrapper" style={style}>
  54. {showingTerminal && <EmbeddedTerminal />}
  55. <NodeDetails
  56. key={this.props.id}
  57. nodeId={this.props.id}
  58. mounted={this.state.mounted}
  59. renderNodeDetailsExtras={this.props.renderNodeDetailsExtras}
  60. {...this.props}
  61. />
  62. </div>
  63. );
  64. }
  65. }
  66. function mapStateToProps(state, props) {
  67. const pipe = state.get('controlPipes').last();
  68. return {
  69. showingTerminal: pipe && pipe.get('nodeId') === props.id,
  70. };
  71. }
  72. export default connect(mapStateToProps)(DetailsCard);