From 92bc5847b8ffc8d8f4797fd9d2f0b0d21ba4de6c Mon Sep 17 00:00:00 2001 From: Vitor Mateus Date: Fri, 8 Feb 2019 17:52:23 -0200 Subject: [PATCH 001/100] package-lock --- bigbluebutton-html5/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json index da1c1873aa..c21548a961 100644 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -5342,9 +5342,9 @@ "dev": true }, "popper.js": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz", - "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA==" + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz", + "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==" }, "posix-character-classes": { "version": "0.1.1", @@ -6820,9 +6820,9 @@ "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" }, "tippy.js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-3.3.0.tgz", - "integrity": "sha512-2gIQg57EFSCBqE97NZbakSkGBJF0GzdOhx/lneGQGMzJiJyvbpyKgNy4l4qofq0nEbXACl7C/jW/ErsdQa21aQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-3.4.1.tgz", + "integrity": "sha512-ZiyGP9WZyCCcjxKM4G88cm4U1r1ytjeMDGa5FSKPaPzwc/3yZJVZsb1ffcmqUMCpryRp5LNxRNGKLzbs11sb/Q==", "requires": { "popper.js": "^1.14.6" } From 7998f46391088b593957a460623a3f6b880fcdfe Mon Sep 17 00:00:00 2001 From: Vitor Mateus Date: Tue, 12 Feb 2019 11:35:52 -0200 Subject: [PATCH 002/100] Modified presentation toolbar styles --- .../ui/components/presentation/component.jsx | 297 ++++++++++++------ .../ui/components/presentation/container.jsx | 4 +- .../presentation-toolbar/component.jsx | 69 ++-- .../presentation-toolbar/container.jsx | 4 + .../presentation-toolbar/styles.scss | 163 ++++++---- .../zoom-tool/component.jsx | 4 +- .../ui/components/presentation/service.js | 3 + .../fullscreen-button/component.jsx | 3 +- .../fullscreen-button/styles.scss | 13 +- 9 files changed, 373 insertions(+), 187 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index a8e8262755..3c57cd4e9c 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -13,7 +13,6 @@ import Slide from './slide/component'; import { styles } from './styles.scss'; import MediaService, { shouldEnableSwapLayout } from '../media/service'; import PresentationCloseButton from './presentation-close-button/component'; -import FullscreenButton from '../video-provider/fullscreen-button/component'; const intlMessages = defineMessages({ presentationLabel: { @@ -22,12 +21,12 @@ const intlMessages = defineMessages({ }, }); -const isFullscreen = () => document.fullscreenElement !== null; +// const isFullscreen = () => document.fullscreenElement !== null; -const renderPresentationClose = () => { - if (!shouldEnableSwapLayout() || isFullscreen()) return null; - return ; -}; +// const renderPresentationClose = () => { +// if (!shouldEnableSwapLayout() || isFullscreen()) return null; +// return ; +// }; class PresentationArea extends Component { constructor() { @@ -62,6 +61,10 @@ class PresentationArea extends Component { this.getInitialPresentationSizes(); } + componentDidUpdate() { + console.log('children', this.props.children); + } + componentWillUnmount() { window.removeEventListener('resize', () => { setTimeout(this.handleResize.bind(this), 0); @@ -75,11 +78,11 @@ class PresentationArea extends Component { } getPresentationSizesAvailable() { + const { userIsPresenter, multiUser } = this.props; const { refPresentationArea, refWhiteboardArea } = this; const presentationSizes = {}; if (refPresentationArea && refWhiteboardArea) { - const { userIsPresenter, multiUser } = this.props; // By default presentation sizes are equal to the sizes of the refPresentationArea // direct parent of the svg wrapper let { clientWidth, clientHeight } = refPresentationArea; @@ -186,15 +189,94 @@ class PresentationArea extends Component { fitToWidthHandler() { const { fitToWidth } = this.state; - this.setState({ fitToWidth: !fitToWidth }); + this.setState({ + fitToWidth: !fitToWidth, + }); } + isPresentationAccessible() { const { currentSlide } = this.props; // sometimes tomcat publishes the slide url, but the actual file is not accessible (why?) return currentSlide && currentSlide.calculatedData; } + renderPresentationClose() { + const { isFullscreen } = this.props; + if (!shouldEnableSwapLayout() || isFullscreen) { + return null; + } + return ; + } + + renderOverlays(slideObj, adjustedSizes) { + const { + userIsPresenter, + multiUser, + podId, + currentSlide, + } = this.props; + + const { + delta, + zoom, + touchZoom, + fitToWidth, + } = this.state; + + if (!userIsPresenter && !multiUser) { + return null; + } + + // retrieving the pre-calculated data from the slide object + const { + x, + y, + width, + height, + viewBoxWidth, + viewBoxHeight, + } = slideObj.calculatedData; + + return ( + + + + ); + } + // renders the whole presentation area renderPresentationArea() { const { fitToWidth } = this.state; @@ -207,8 +289,8 @@ class PresentationArea extends Component { // a reference to the slide object const slideObj = currentSlide; - const presentationCloseButton = renderPresentationClose(); - const presentationFullscreenButton = this.renderPresentationFullscreen(); + const presentationCloseButton = this.renderPresentationClose(); + // const presentationFullscreenButton = this.renderPresentationFullscreen(); // retrieving the pre-calculated data from the slide object const { @@ -220,20 +302,24 @@ class PresentationArea extends Component { viewBoxHeight, imageUri, } = slideObj.calculatedData; - const svgDimensions = fitToWidth ? { - position: 'absolute', - width: 'inherit', - } : { - position: 'absolute', - width: adjustedSizes.width, - height: adjustedSizes.height, - }; + + const svgDimensions = fitToWidth + ? { + position: 'absolute', + width: 'inherit', + } + : { + position: 'absolute', + width: adjustedSizes.width, + height: adjustedSizes.height, + }; + return (
{presentationCloseButton} - {presentationFullscreenButton} + {/* {presentationFullscreenButton} */} this.refPresentationContainer.requestFullscreen(); - // retrieving the pre-calculated data from the slide object - const { - x, - y, - width, - height, - viewBoxWidth, - viewBoxHeight, - } = slideObj.calculatedData; + // // return ; + // // } - return ( - - - - ); - } + // return ( + // + // + // + // ); + // } - renderPresentationFullscreen() { - const { intl } = this.props; - if (isFullscreen()) return null; + // renderPresentationFullscreen() { + // const { intl } = this.props; + // if (isFullscreen()) return null; - const full = () => this.refPresentationContainer.requestFullscreen(); + // const full = () => this.refPresentationContainer.requestFullscreen(); - return ( - - ); - } + // return ( + // + // ); + // } renderPresentationToolbar() { + const { + currentSlide, + podId, + isFullscreen: propIsFullscreen, + } = this.props; + const { zoom } = this.state; - const { currentSlide, podId } = this.props; - if (!currentSlide) return null; + + const fullRef = () => this.refPresentationContainer.requestFullscreen(); + + if (!currentSlide) { + return null; + } return ( @@ -407,8 +502,8 @@ class PresentationArea extends Component { } render() { - const { showSlide } = this.state; const { userIsPresenter, multiUser } = this.props; + const { showSlide } = this.state; return (
{ this.refWhiteboardArea = ref; }} className={styles.whiteboardSizeAvailable} /> - {showSlide ? this.renderPresentationArea() : null } - {userIsPresenter || multiUser ? this.renderWhiteboardToolbar() : null } + {showSlide + ? this.renderPresentationArea() + : null} + {userIsPresenter || multiUser + ? this.renderWhiteboardToolbar() + : null}
{this.renderPresentationToolbar()}
diff --git a/bigbluebutton-html5/imports/ui/components/presentation/container.jsx b/bigbluebutton-html5/imports/ui/components/presentation/container.jsx index ee7e066509..0b6ed6b769 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/container.jsx @@ -13,6 +13,8 @@ export default withTracker(({ podId }) => { return { currentSlide, userIsPresenter: PresentationAreaService.isPresenter(podId) && !getSwapLayout(), - multiUser: PresentationAreaService.getMultiUserStatus(currentSlide && currentSlide.id) && !getSwapLayout(), + multiUser: PresentationAreaService + .getMultiUserStatus(currentSlide && currentSlide.id) && !getSwapLayout(), + isFullscreen: PresentationAreaService.isFullscreen(), }; })(PresentationAreaContainer); diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx index 97dbc4836d..d1ec5af153 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx @@ -7,6 +7,8 @@ import Button from '/imports/ui/components/button/component'; import { HUNDRED_PERCENT, MAX_PERCENT, STEP } from '/imports/utils/slideCalcUtils'; import { styles } from './styles.scss'; import ZoomTool from './zoom-tool/component'; +import FullscreenButton from '../../video-provider/fullscreen-button/component'; +import PresentationArea from '../component'; const intlMessages = defineMessages({ @@ -185,6 +187,8 @@ class PresentationToolbar extends Component { actions, intl, zoom, + isFullscreen, + fullscreenRef, } = this.props; const BROWSER_RESULTS = browser(); @@ -194,7 +198,7 @@ class PresentationToolbar extends Component {
{PresentationToolbar.renderAriaLabelsDescs()} { - +
); diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/fullscreen-button/styles.scss b/bigbluebutton-html5/imports/ui/components/video-provider/fullscreen-button/styles.scss index 644ed81a28..0571dff686 100644 --- a/bigbluebutton-html5/imports/ui/components/video-provider/fullscreen-button/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/video-provider/fullscreen-button/styles.scss @@ -6,7 +6,6 @@ } .wrapper { - position: absolute; right: 0; background-color: var(--color-transparent); cursor: pointer; @@ -32,3 +31,15 @@ .dark .button span i { color: var(--color-black); } + +.fullScreenButton{ + padding: 5px; + + &:hover{ + border: 0; + } + + i{ + font-size: 1rem; + } +} \ No newline at end of file From 61ceab5938b7ecf6ecbbc1cec7f8708871c43c60 Mon Sep 17 00:00:00 2001 From: Vitor Mateus Date: Thu, 14 Feb 2019 10:03:25 -0200 Subject: [PATCH 003/100] Updated the slide control toolbar look. #5191 --- .../ui/components/presentation/component.jsx | 123 +++--------------- .../presentation-toolbar/component.jsx | 6 +- .../presentation-toolbar/container.jsx | 2 +- .../presentation-toolbar/styles.scss | 48 ------- 4 files changed, 26 insertions(+), 153 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index 3c57cd4e9c..3cdfab230a 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -1,33 +1,18 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, intlShape } from 'react-intl'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import WhiteboardOverlayContainer from '/imports/ui/components/whiteboard/whiteboard-overlay/container'; import WhiteboardToolbarContainer from '/imports/ui/components/whiteboard/whiteboard-toolbar/container'; import { HUNDRED_PERCENT, MAX_PERCENT } from '/imports/utils/slideCalcUtils'; +import PresentationToolbarContainer from './presentation-toolbar/container'; import CursorWrapperContainer from './cursor/cursor-wrapper-container/container'; import AnnotationGroupContainer from '../whiteboard/annotation-group/container'; -import PresentationToolbarContainer from './presentation-toolbar/container'; import PresentationOverlayContainer from './presentation-overlay/container'; import Slide from './slide/component'; import { styles } from './styles.scss'; import MediaService, { shouldEnableSwapLayout } from '../media/service'; import PresentationCloseButton from './presentation-close-button/component'; -const intlMessages = defineMessages({ - presentationLabel: { - id: 'app.presentationUploder.title', - description: 'presentation area element label', - }, -}); - -// const isFullscreen = () => document.fullscreenElement !== null; - -// const renderPresentationClose = () => { -// if (!shouldEnableSwapLayout() || isFullscreen()) return null; -// return ; -// }; - class PresentationArea extends Component { constructor() { super(); @@ -61,10 +46,6 @@ class PresentationArea extends Component { this.getInitialPresentationSizes(); } - componentDidUpdate() { - console.log('children', this.props.children); - } - componentWillUnmount() { window.removeEventListener('resize', () => { setTimeout(this.handleResize.bind(this), 0); @@ -77,6 +58,16 @@ class PresentationArea extends Component { return this.svggroup; } + getToolbarHeight() { + const { refPresentationToolbar } = this; + let height = 0; + if (refPresentationToolbar) { + const { clientHeight } = refPresentationToolbar; + height = clientHeight; + } + return height; + } + getPresentationSizesAvailable() { const { userIsPresenter, multiUser } = this.props; const { refPresentationArea, refWhiteboardArea } = this; @@ -94,7 +85,7 @@ class PresentationArea extends Component { ({ clientWidth, clientHeight } = refWhiteboardArea); } - presentationSizes.presentationHeight = clientHeight; + presentationSizes.presentationHeight = clientHeight - this.getToolbarHeight(); presentationSizes.presentationWidth = clientWidth; } return presentationSizes; @@ -155,7 +146,7 @@ class PresentationArea extends Component { } return { width: adjustedWidth, - height: adjustedHeight, + height: adjustedHeight + this.getToolbarHeight(), }; } @@ -283,6 +274,7 @@ class PresentationArea extends Component { const { podId, currentSlide } = this.props; if (!this.isPresentationAccessible()) return null; + // to control the size of the svg wrapper manually // and adjust cursor's thickness, so that svg didn't scale it automatically const adjustedSizes = this.calculateSize(); @@ -290,7 +282,6 @@ class PresentationArea extends Component { const slideObj = currentSlide; const presentationCloseButton = this.renderPresentationClose(); - // const presentationFullscreenButton = this.renderPresentationFullscreen(); // retrieving the pre-calculated data from the slide object const { @@ -319,7 +310,6 @@ class PresentationArea extends Component { style={svgDimensions} > {presentationCloseButton} - {/* {presentationFullscreenButton} */} +
{ this.refPresentationToolbar = ref; }} + > + {this.renderPresentationToolbar()} +
); } - // renderOverlays(slideObj, adjustedSizes) { - // const { - // userIsPresenter, multiUser, podId, currentSlide, - // } = this.props; - // const { - // delta, zoom, touchZoom, fitToWidth, - // } = this.state; - - // if (!userIsPresenter && !multiUser) return null; - // // renderPresentationFullscreen() { - // // if (PresentationArea.isFullscreen()) { - // // return null; - // // } - // // const full = () => this.refPresentationContainer.requestFullscreen(); - - // // return ; - // // } - - // return ( - // - // - // - // ); - // } - - // renderPresentationFullscreen() { - // const { intl } = this.props; - // if (isFullscreen()) return null; - - // const full = () => this.refPresentationContainer.requestFullscreen(); - - // return ( - // - // ); - // } - renderPresentationToolbar() { const { currentSlide, @@ -525,16 +444,14 @@ class PresentationArea extends Component { ? this.renderWhiteboardToolbar() : null} - {this.renderPresentationToolbar()} ); } } -export default injectIntl(PresentationArea); +export default PresentationArea; PresentationArea.propTypes = { - intl: intlShape.isRequired, podId: PropTypes.string.isRequired, // Defines a boolean value to detect whether a current user is a presenter userIsPresenter: PropTypes.bool.isRequired, diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx index d1ec5af153..c970c8453f 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/component.jsx @@ -8,7 +8,6 @@ import { HUNDRED_PERCENT, MAX_PERCENT, STEP } from '/imports/utils/slideCalcUtil import { styles } from './styles.scss'; import ZoomTool from './zoom-tool/component'; import FullscreenButton from '../../video-provider/fullscreen-button/component'; -import PresentationArea from '../component'; const intlMessages = defineMessages({ @@ -28,6 +27,10 @@ const intlMessages = defineMessages({ id: 'app.presentation.presentationToolbar.fitToWidth', description: 'button for fit to width', }, + presentationLabel: { + id: 'app.presentationUploder.title', + description: 'presentation area element label', + }, }); class PresentationToolbar extends Component { @@ -276,6 +279,7 @@ class PresentationToolbar extends Component { && ( ) diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/container.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/container.jsx index 741e88ba35..e3e2748540 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/container.jsx @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import { withTracker } from 'meteor/react-meteor-data'; import PresentationService from '/imports/ui/components/presentation/service'; import MediaService from '/imports/ui/components/media/service'; -import PresentationToolbarService from './service'; import PresentationToolbar from './component'; +import PresentationToolbarService from './service'; const PresentationToolbarContainer = (props) => { const { diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss index ee959fac38..c262073962 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss @@ -8,18 +8,6 @@ margin: -1px; padding: 0; border: 0; } -// .presentationToolbarWrapper, -// .presentationControls, -// .zoomWrapper { -// order: 2; -// display: flex; -// flex-direction: row; -// align-items: center; -// margin-left: .5rem; -// margin-right: .5rem; -// border-radius: var(--toolbar-button-border-radius); -// } - .presentationSlideControls{ flex-basis: 40%; margin-left: 30%; @@ -50,35 +38,6 @@ button{ padding: .5rem; } - - // .zoomPercentageDisplay{ - // border-radius: 0 - // } - // box-shadow: 0 0 10px -2px rgba(0, 0, 0, .25); - - // span:first-of-type button, - // button:first-of-type { - // border-top-left-radius: 5px; - // border-bottom-left-radius: 5px; - // border-top-right-radius: 0; - // border-bottom-right-radius: 0; - // } - - // span:last-of-type button, - // button:last-of-type { - // border-top-left-radius: 0; - // border-bottom-left-radius: 0; - // border-top-right-radius: 5px; - // border-bottom-right-radius: 5px; - // } - - // span:last-of-type button[aria-labelledby~=fitWidthLabel], - // button:last-of-type[aria-labelledby~=fitWidthLabel] { - // border-top-left-radius: 5px; - // border-bottom-left-radius: 5px; - // border-top-right-radius: 5px; - // border-bottom-right-radius: 5px; - // } } .presentationToolbarWrapper { @@ -94,11 +53,6 @@ padding: 0 .2rem; border-top: 1px solid var(--color-blue-lightest); - // @include mq("#{$landscape} and (max-height:#{upper-bound($small-range)}), #{$small-only}") { - // transform: scale(.75); - // transform-origin: bottom; - // } - select{ margin-right: .5rem; margin-left: .5rem; @@ -141,9 +95,7 @@ } .zoomWrapper { - // border-radius: 0 5px 5px 0; justify-content: space-between; - // flex-direction: column; background-color: var(--toolbar-button-bg); } From 2014dd742fc54d2bff6544a6feb51a018d6c5f4c Mon Sep 17 00:00:00 2001 From: Vitor Mateus Date: Tue, 19 Feb 2019 09:27:54 -0300 Subject: [PATCH 004/100] Fixes and improvements --- .../ui/components/presentation/component.jsx | 48 +++++++++++++------ .../presentation-toolbar/styles.scss | 13 ++--- .../ui/components/presentation/styles.scss | 17 +++++++ 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index 3cdfab230a..710a2d383a 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -146,7 +146,7 @@ class PresentationArea extends Component { } return { width: adjustedWidth, - height: adjustedHeight + this.getToolbarHeight(), + height: adjustedHeight, }; } @@ -294,7 +294,7 @@ class PresentationArea extends Component { imageUri, } = slideObj.calculatedData; - const svgDimensions = fitToWidth + const svgAreaDimensions = fitToWidth ? { position: 'absolute', width: 'inherit', @@ -303,11 +303,12 @@ class PresentationArea extends Component { position: 'absolute', width: adjustedSizes.width, height: adjustedSizes.height, + textAlign: 'center', }; return (
{presentationCloseButton} @@ -368,11 +369,6 @@ class PresentationArea extends Component { -
{ this.refPresentationToolbar = ref; }} - > - {this.renderPresentationToolbar()} -
); } @@ -394,7 +390,6 @@ class PresentationArea extends Component { return ( { this.refPresentationContainer = ref; }} @@ -437,12 +438,29 @@ class PresentationArea extends Component { ref={(ref) => { this.refWhiteboardArea = ref; }} className={styles.whiteboardSizeAvailable} /> - {showSlide - ? this.renderPresentationArea() - : null} - {userIsPresenter || multiUser - ? this.renderWhiteboardToolbar() - : null} +
+ {showSlide + ? this.renderPresentationArea() + : null} + {userIsPresenter || multiUser + ? this.renderWhiteboardToolbar() + : null} + {userIsPresenter || multiUser + ? ( +
{ this.refPresentationToolbar = ref; }} + > + {this.renderPresentationToolbar()} +
+ ) + : null} +
); diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss index c262073962..2430c4c67d 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/styles.scss @@ -9,15 +9,12 @@ } .presentationSlideControls{ - flex-basis: 40%; - margin-left: 30%; justify-content: center; - padding-left: 1rem; + padding-left: .5rem; padding-right: .5rem; } .presentationZoomControls{ - flex-basis: 30%; justify-content: flex-end; padding-right: .5rem; } @@ -25,7 +22,6 @@ .presentationSlideControls, .presentationZoomControls, .zoomWrapper { - order: 2; display: flex; flex-direction: row; align-items: center; @@ -40,18 +36,19 @@ } } -.presentationToolbarWrapper { +.presentationToolbarWrapper{ position: relative; bottom: 3px; align-self: center; - justify-content: center; z-index: 1; background-color: var(--color-off-white); display: flex; flex-direction: row; align-items: center; - padding: 0 .2rem; + justify-content: space-between; border-top: 1px solid var(--color-blue-lightest); + min-width: fit-content; + width: 100%; select{ margin-right: .5rem; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/styles.scss b/bigbluebutton-html5/imports/ui/components/presentation/styles.scss index 78783dea7a..adb216809c 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/presentation/styles.scss @@ -38,6 +38,23 @@ z-index: -1; } +.svgContainer{ + width: 100%; + position: relative; + display: flex; + justify-content: center; + align-items: center; +} + +.presentationToolbar{ + display: flex; + overflow-x: auto; + width: 100%; + order: 2; + position: absolute; + bottom: 0; +} + .svgStyles { object-fit: contain; width: 100%; From 4a66dab29f3246ff75f9b5e9c99d552b2b6a95fe Mon Sep 17 00:00:00 2001 From: bobakoftadeh Date: Tue, 19 Feb 2019 22:29:23 +0000 Subject: [PATCH 005/100] Fix links in welcome message --- .../imports/api/meetings/server/modifiers/addMeeting.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js index b9b1c6cc9b..eb0235954e 100644 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js @@ -46,7 +46,7 @@ export default function addMeeting(meeting) { recordProp: Match.ObjectIncluding({ allowStartStopRecording: Boolean, autoStartRecording: Boolean, - record: Boolean + record: Boolean, }), password: { viewerPass: String, @@ -66,6 +66,8 @@ export default function addMeeting(meeting) { metadataProp: Object, }); + const newMeeting = meeting; + const selector = { meetingId, }; @@ -81,10 +83,12 @@ export default function addMeeting(meeting) { setBy: 'temp', }; + newMeeting.welcomeProp.welcomeMsg = newMeeting.welcomeProp.welcomeMsg.replace('event:', ''); + const modifier = { $set: Object.assign( { meetingId }, - flat(meeting, { safe: true }), + flat(newMeeting, { safe: true }), { lockSettingsProp }, ), }; From 2ee75609f9abfbcc9d52ccb713e9712722cc833d Mon Sep 17 00:00:00 2001 From: Maxim Khlobystov Date: Wed, 20 Feb 2019 17:57:35 -0500 Subject: [PATCH 006/100] Use meeting-ended component on logout --- .../nav-bar/settings-dropdown/component.jsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx index 5c4af9769d..4a585a5cb8 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx @@ -4,6 +4,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import { withModalMounter } from '/imports/ui/components/modal/service'; import EndMeetingConfirmationContainer from '/imports/ui/components/end-meeting-confirmation/container'; +import MeetingEndedComponent from '/imports/ui/components/meeting-ended/component'; import AboutContainer from '/imports/ui/components/about/container'; import SettingsMenuContainer from '/imports/ui/components/settings/container'; import Button from '/imports/ui/components/button/component'; @@ -161,6 +162,15 @@ class SettingsDropdown extends PureComponent { ); } + leaveSession() { + const { mountModal } = this.props; + + const LOGOUT_CODE = '430'; + // we don't check askForFeedbackOnLogout here, + // it is checked in meeting-ended component + mountModal(); + } + renderMenuItems() { const { intl, mountModal, amIModerator, @@ -217,7 +227,7 @@ class SettingsDropdown extends PureComponent { icon="logout" label={intl.formatMessage(intlMessages.leaveSessionLabel)} description={intl.formatMessage(intlMessages.leaveSessionDesc)} - onClick={logoutRouteHandler} + onClick={() => this.leaveSession()} />), ]); } From 3f21c823303cc6c167f00891c133f1799a0a4e8b Mon Sep 17 00:00:00 2001 From: Gustavo Trott Date: Thu, 21 Feb 2019 18:01:39 -0300 Subject: [PATCH 007/100] implement quick poll feature --- .../actions-dropdown/component.jsx | 4 +- .../ui/components/actions-bar/component.jsx | 15 ++- .../ui/components/actions-bar/container.jsx | 6 +- .../quick-poll-dropdown/component.jsx | 109 ++++++++++++++++++ .../ui/components/presentation/service.js | 72 ++++++++++++ .../ui/components/presentation/styles.scss | 2 +- bigbluebutton-html5/private/locales/en.json | 5 + 7 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 bigbluebutton-html5/imports/ui/components/actions-bar/quick-poll-dropdown/component.jsx diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx index b69f2f73af..c4c4ced223 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/actions-dropdown/component.jsx @@ -1,7 +1,7 @@ import _ from 'lodash'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, intlShape } from 'react-intl'; +import { defineMessages, intlShape } from 'react-intl'; import Button from '/imports/ui/components/button/component'; import Dropdown from '/imports/ui/components/dropdown/component'; import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component'; @@ -309,4 +309,4 @@ class ActionsDropdown extends Component { ActionsDropdown.propTypes = propTypes; -export default withShortcutHelper(withModalMounter(injectIntl(ActionsDropdown)), 'openActions'); +export default withShortcutHelper(withModalMounter(ActionsDropdown), 'openActions'); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx index 7614f4c115..960e2e99a7 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx @@ -3,6 +3,7 @@ import cx from 'classnames'; import { styles } from './styles.scss'; import DesktopShare from './desktop-share/component'; import ActionsDropdown from './actions-dropdown/component'; +import QuickPollDropdown from './quick-poll-dropdown/component'; import AudioControlsContainer from '../audio/audio-controls/container'; import JoinVideoOptionsContainer from '../video-provider/video-button/container'; @@ -33,6 +34,9 @@ class ActionsBar extends React.PureComponent { sendInvitation, getBreakouts, handleTakePresenter, + intl, + currentSlidHasContent, + parseCurrentSlideContent, } = this.props; const { @@ -67,8 +71,17 @@ class ActionsBar extends React.PureComponent { sendInvitation, getBreakouts, handleTakePresenter, + intl, }} /> +
- { isLayoutSwapped + {isLayoutSwapped ? ( { getBreakouts: Service.getBreakouts, getUsersNotAssigned: Service.getUsersNotAssigned, handleTakePresenter: Service.takePresenterRole, + currentSlidHasContent: PresentationService.currentSlidHasContent(), + parseCurrentSlideContent: PresentationService.parseCurrentSlideContent, }; -})(ActionsBarContainer); +})(injectIntl(ActionsBarContainer)); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/quick-poll-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/quick-poll-dropdown/component.jsx new file mode 100644 index 0000000000..cd484d7fc4 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/quick-poll-dropdown/component.jsx @@ -0,0 +1,109 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { defineMessages, intlShape } from 'react-intl'; +import _ from 'lodash'; +import { makeCall } from '/imports/ui/services/api'; +import Button from '/imports/ui/components/button/component'; +import Dropdown from '/imports/ui/components/dropdown/component'; +import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component'; +import DropdownContent from '/imports/ui/components/dropdown/content/component'; +import DropdownList from '/imports/ui/components/dropdown/list/component'; +import DropdownListItem from '/imports/ui/components/dropdown/list/item/component'; +import { styles } from '../styles'; + +const intlMessages = defineMessages({ + quickPollLabel: { + id: 'app.poll.quickPollTitle', + description: 'Quick poll button title', + }, + trueOptionLabel: { + id: 'app.poll.t', + description: 'Poll true option value', + }, + falseOptionLabel: { + id: 'app.poll.f', + description: 'Poll false option value', + }, + yesOptionLabel: { + id: 'app.poll.y', + description: 'Poll yes option value', + }, + noOptionLabel: { + id: 'app.poll.n', + description: 'Poll no option value', + }, +}); + +const propTypes = { + intl: intlShape.isRequired, + parseCurrentSlideContent: PropTypes.func.isRequired, + isUserPresenter: PropTypes.bool.isRequired, + +}; + +const handleClickQuickPoll = (slideId, poll) => { + const { type } = poll; + Session.set('openPanel', 'poll'); + Session.set('forcePollOpen', true); + + makeCall('startPoll', type, slideId); +}; + + +const getAvailableQuickPolls = (slideId, parsedSlides) => { + return parsedSlides.map((poll) => { + const { poll: label, type } = poll; + let itemLabel = label; + + if (type !== 'YN' && type !== 'TF') { + const { options } = itemLabel; + itemLabel = options.join('/').replace(/[\n.)]/g, ''); + } + + return ( + handleClickQuickPoll(slideId, poll)} + />); + }); +}; + +const QuickPollDropdown = (props) => { + const { isUserPresenter, intl, parseCurrentSlideContent } = props; + const parsedSlide = parseCurrentSlideContent( + intl.formatMessage(intlMessages.yesOptionLabel), + intl.formatMessage(intlMessages.noOptionLabel), + intl.formatMessage(intlMessages.trueOptionLabel), + intl.formatMessage(intlMessages.falseOptionLabel), + ); + + const { slideId, quickPollOptions } = parsedSlide; + + return isUserPresenter && quickPollOptions.length ? ( + + +