From 28f3329a16d0a162d50ac604e159c42f6e6653df Mon Sep 17 00:00:00 2001 From: Anton Georgiev <anto.georgiev@gmail.com> Date: Tue, 28 May 2019 19:19:08 +0000 Subject: [PATCH] improve mobile view for reader-menu --- .../captions/reader-menu/component.jsx | 314 ++++++++++-------- .../captions/reader-menu/styles.scss | 138 ++++---- bigbluebutton-html5/private/locales/en.json | 6 +- 3 files changed, 240 insertions(+), 218 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/component.jsx index 3557ea0907..361cc0942f 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/component.jsx @@ -5,9 +5,9 @@ import Button from '/imports/ui/components/button/component'; import { GithubPicker } from 'react-color'; import { defineMessages, injectIntl } from 'react-intl'; import { withModalMounter } from '/imports/ui/components/modal/service'; -import { styles } from './styles'; +import { styles } from './styles.scss'; -const DEFAULT_VALUE = "select"; +const DEFAULT_VALUE = 'select'; const DEFAULT_KEY = -1; const DEFAULT_INDEX = 0; const FONT_FAMILIES = ['Arial', 'Calibri', 'Time New Roman', 'Sans-serif']; @@ -53,11 +53,20 @@ const intlMessages = defineMessages({ id: 'app.captions.menu.fontSize', description: 'Select closed captions font size', }, + cancelLabel: { + id: 'app.captions.menu.cancelLabel', + description: 'Cancel button label', + }, + preview: { + id: 'app.captions.menu.previewLabel', + description: 'Preview area label', + }, }); const propTypes = { activateCaptions: PropTypes.func.isRequired, getCaptionsSettings: PropTypes.func.isRequired, + closeModal: PropTypes.func.isRequired, ownedLocales: PropTypes.arrayOf(PropTypes.object).isRequired, intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, @@ -68,7 +77,12 @@ class ReaderMenu extends PureComponent { constructor(props) { super(props); - const { backgroundColor, fontColor, fontFamily, fontSize } = props.getCaptionsSettings(); + const { + backgroundColor, + fontColor, + fontFamily, + fontSize, + } = props.getCaptionsSettings(); this.state = { locale: null, @@ -89,8 +103,25 @@ class ReaderMenu extends PureComponent { this.getPreviewStyle = this.getPreviewStyle.bind(this); } + getPreviewStyle() { + const { + backgroundColor, + fontColor, + fontFamily, + fontSize, + } = this.state; + + return { + fontFamily, + fontSize, + color: fontColor, + background: backgroundColor, + }; + } + handleColorPickerClick(fieldname) { const obj = {}; + // eslint-disable-next-line react/destructuring-assignment obj[fieldname] = !this.state[fieldname]; this.setState(obj); } @@ -113,6 +144,12 @@ class ReaderMenu extends PureComponent { this.setState({ locale: event.target.value }); } + handleSelectChange(fieldname, options, event) { + const obj = {}; + obj[fieldname] = options[event.target.value]; + this.setState(obj); + } + handleStart() { const { closeModal, activateCaptions } = this.props; const { @@ -122,34 +159,14 @@ class ReaderMenu extends PureComponent { fontFamily, fontSize, } = this.state; - const settings = { backgroundColor, fontColor, fontFamily, fontSize }; - activateCaptions(locale, settings); - closeModal(); - } - - getPreviewStyle() { - const { + const settings = { backgroundColor, fontColor, fontFamily, fontSize, - } = this.state; - - return { - position: 'fixed', - bottom: '75px', - left: '75px', - fontFamily, - fontSize, - color: fontColor, - background: backgroundColor, }; - } - - handleSelectChange(fieldname, options, event) { - const obj = {}; - obj[fieldname] = options[event.target.value]; - this.setState(obj); + activateCaptions(locale, settings); + closeModal(); } render() { @@ -177,129 +194,148 @@ class ReaderMenu extends PureComponent { hideBorder contentLabel={intl.formatMessage(intlMessages.title)} > - <header className={styles.header}> - <h3 className={styles.title}>{intl.formatMessage(intlMessages.title)}</h3> + <header className={styles.title}> + {intl.formatMessage(intlMessages.title)} </header> - <div className={styles.content}> - <div className={styles.left}> - <select - className={styles.select} - onChange={this.handleLocaleChange} - defaultValue={DEFAULT_VALUE} + <div className={styles.selectLanguage}> + <select + className={styles.select} + onChange={this.handleLocaleChange} + defaultValue={DEFAULT_VALUE} + > + <option + disabled + key={DEFAULT_KEY} + value={DEFAULT_VALUE} > + {intl.formatMessage(intlMessages.select)} + </option> + {ownedLocales.map(loc => ( <option - disabled - key={DEFAULT_KEY} - value={DEFAULT_VALUE} + key={loc.locale} + value={loc.locale} > - {intl.formatMessage(intlMessages.select)} - </option> - {ownedLocales.map((loc, index) => ( - <option - key={index} - value={loc.locale} + {loc.name} + </option>))} + </select> + </div> + {!locale ? null : ( + <div className={styles.content}> + <div className={styles.col}> + <div className={styles.row}> + <div className={styles.label}>{intl.formatMessage(intlMessages.fontColor)}</div> + <div + tabIndex={DEFAULT_INDEX} + className={styles.swatch} + onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')} > - {loc.name} - </option>))} - </select> - <span style={this.getPreviewStyle()}>AaBbCc</span> - </div> - <div className={styles.right}> - <div className={styles.row}> - <div>{intl.formatMessage(intlMessages.fontColor)}</div> - <div - tabIndex={DEFAULT_INDEX} - className={styles.swatch} - onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')} - > - <div className={styles.swatchInner} style={{ background: fontColor }}/> - </div> - {displayFontColorPicker - ? ( - <div className={styles.colorPickerPopover}> - <div - className={styles.colorPickerOverlay} - onClick={this.handleCloseColorPicker.bind(this)} - /> - <GithubPicker - onChange={this.handleColorChange.bind(this, 'fontColor')} - color={fontColor} - colors={COLORS} - width="140px" - triangle="hide" - /> - </div> - ) : null + <div className={styles.swatchInner} style={{ background: fontColor }} /> + </div> + {displayFontColorPicker + ? ( + <div className={styles.colorPickerPopover}> + <div + className={styles.colorPickerOverlay} + onClick={this.handleCloseColorPicker.bind(this)} + /> + <GithubPicker + onChange={this.handleColorChange.bind(this, 'fontColor')} + color={fontColor} + colors={COLORS} + width="140px" + triangle="hide" + /> + </div> + ) : null } - </div> - <div className={styles.row}> - <div>{intl.formatMessage(intlMessages.backgroundColor)}</div> - <div - tabIndex={DEFAULT_INDEX} - className={styles.swatch} - onClick={this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker')} - > - <div className={styles.swatchInner} style={{ background: backgroundColor }}/> </div> - {displayBackgroundColorPicker - ? ( - <div className={styles.colorPickerPopover}> - <div - className={styles.colorPickerOverlay} - onClick={this.handleCloseColorPicker.bind(this)} - /> - <GithubPicker - onChange={this.handleColorChange.bind(this, 'backgroundColor')} - color={backgroundColor} - colors={COLORS} - width="140px" - triangle="hide" - /> - </div> - ) : null + + <div className={styles.row}> + <div className={styles.label}> + {intl.formatMessage(intlMessages.backgroundColor)} + </div> + <div + tabIndex={DEFAULT_INDEX} + className={styles.swatch} + onClick={this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker')} + > + <div className={styles.swatchInner} style={{ background: backgroundColor }} /> + </div> + {displayBackgroundColorPicker + ? ( + <div className={styles.colorPickerPopover}> + <div + className={styles.colorPickerOverlay} + onClick={this.handleCloseColorPicker.bind(this)} + /> + <GithubPicker + onChange={this.handleColorChange.bind(this, 'backgroundColor')} + color={backgroundColor} + colors={COLORS} + width="140px" + triangle="hide" + /> + </div> + ) : null } + </div> + + <div className={styles.row}> + <div className={styles.label}>{intl.formatMessage(intlMessages.fontFamily)}</div> + <select + className={styles.select} + defaultValue={FONT_FAMILIES.indexOf(fontFamily)} + onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)} + > + {FONT_FAMILIES.map((family, index) => ( + <option + key={family} + value={index} + > + {family} + </option> + ))} + </select> + </div> + + <div className={styles.row}> + <div className={styles.label}>{intl.formatMessage(intlMessages.fontSize)}</div> + <select + className={styles.select} + defaultValue={FONT_SIZES.indexOf(fontSize)} + onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)} + > + {FONT_SIZES.map((size, index) => ( + <option + key={size} + value={index} + > + {size} + </option> + ))} + </select> + </div> + + <div className={styles.row}> + <div className={styles.label}>{intl.formatMessage(intlMessages.preview)}</div> + <span style={this.getPreviewStyle()}>AaBbCc</span> + </div> </div> - <div className={styles.row}> - <div>{intl.formatMessage(intlMessages.fontFamily)}</div> - <select - className={styles.select} - defaultValue={FONT_FAMILIES.indexOf(fontFamily)} - onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)} - > - {FONT_FAMILIES.map((family, index) => ( - <option - key={index} - value={index} - > - {family} - </option> - ))} - </select> - </div> - <div className={styles.row}> - <div>{intl.formatMessage(intlMessages.fontSize)}</div> - <select - className={styles.select} - defaultValue={FONT_SIZES.indexOf(fontSize)} - onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)} - > - {FONT_SIZES.map((size, index) => ( - <option - key={index} - value={index} - > - {size} - </option> - ))} - </select> - </div> </div> - <Button - className={styles.startBtn} - label={intl.formatMessage(intlMessages.start)} - onClick={this.handleStart} - disabled={locale == null} - /> + )} + <div className={styles.footer}> + <div className={styles.actions}> + <Button + label={intl.formatMessage(intlMessages.cancelLabel)} + onClick={closeModal} + /> + <Button + color="primary" + label={intl.formatMessage(intlMessages.start)} + onClick={() => this.handleStart()} + disabled={locale == null} + /> + </div> </div> </Modal> ); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/styles.scss b/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/styles.scss index d6a07f456e..f3d0c74e17 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/captions/reader-menu/styles.scss @@ -3,98 +3,90 @@ @import "/imports/ui/stylesheets/mixins/focus"; .header { - margin: 0; - padding: 0; + display: flex; border: none; - line-height: 2rem; } -.content { - flex-grow: 1; +.footer { display: flex; - justify-content: center; - margin-top: auto; - margin-bottom: auto; - height: 120px; } -.captionsOptions { - margin-top: auto; - margin-bottom: auto; - display: flex; - justify-content: center; +.title { + display: block; + color: var(--color-background); + font-size: 1.4rem; + text-align: center; } -.overlay { - @extend .overlay; -} +.actions { + margin-left: auto; + margin-right: 3px; -.modal { - @extend .modal; - padding: 1.5rem; - min-height: 20rem; -} -.select { - @include elementFocus(var(--color-primary)); - background-color: var(--color-white); - border: var(--border-size) solid var(--color-white); - border-radius: var(--border-size); - border-bottom: 0.1rem solid var(--color-gray-lighter); - color: var(--color-gray-label); - width: auto; - height: 1.75rem; - padding: 1px; - - &:hover { - @include highContrastOutline(); + [dir="rtl"] & { + margin-right: auto; + margin-left: 3px; } - &:focus { - @include highContrastOutline(); - outline-style: solid; + :first-child { + margin-right: 3px; + margin-left: inherit; + + [dir="rtl"] & { + margin-right: inherit; + margin-left: 3px; + } } } +.modal { + @extend .modal; + padding: 1rem; +} -.title { - text-align: center; - font-weight: 400; - font-size: 1.3rem; - color: var(--color-background); - white-space: normal; +.content { +} - @include mq($small-only) { - font-size: 1rem; - padding: 0 1rem; - } +.selectLanguage { + text-align: center; } -.startBtn { +.col { display: flex; - align-self: center; - margin: 0; - width: 40%; - display: block; - position: absolute; - bottom: 20px; - color: var(--color-white) !important; - background-color: var(--color-link) !important; + flex-direction: column; + height: 100%; + margin: 0 1.5rem 0 0; + justify-content: center; - &:focus { - outline: none !important; + [dir="rtl"] & { + margin: 0 0 0 1.5rem; } - i { - color: #3c5764; + @include mq($small-only) { + width: 100%; + height: unset; } } +.select { + background-color: var(--color-white); + border-radius: 0.3rem; + color: var(--color-gray-label); + height: 1.6rem; + margin-top: 0.4rem; + width: 50%; +} + +.label { + flex: 1 0 0; +} + + .colorPickerOverlay { position: fixed; - top: 0px; - right: 0px; - bottom: 0px; - left: 0px; + top: 0; + right: 0; + bottom: 0; + left: 0; } .colorPickerPopover { @@ -103,6 +95,7 @@ } .swatch { + flex: 1 0 0; @include elementFocus(var(--color-primary)); border-radius: var(--border-size); border: var(--border-size) solid var(--color-gray-light); @@ -118,18 +111,9 @@ } .row { - display: grid; - grid-template-columns: 50% 50%; + display: flex; + justify-content: space-between; + padding: .2rem 0 .2rem 0; } -.right, -.left { - padding-left: 20px; - padding-right: 20px; - width: 50%; -} -.right { - display: grid; - grid-template-columns: 100%; -} diff --git a/bigbluebutton-html5/private/locales/en.json b/bigbluebutton-html5/private/locales/en.json index f3fc6acebf..4f91cec2bc 100755 --- a/bigbluebutton-html5/private/locales/en.json +++ b/bigbluebutton-html5/private/locales/en.json @@ -24,9 +24,11 @@ "app.captions.menu.select": "Select available language", "app.captions.menu.title": "Closed captions menu", "app.captions.menu.fontSize": "Size", - "app.captions.menu.fontColor": "Color", + "app.captions.menu.fontColor": "Text color", "app.captions.menu.fontFamily": "Font", - "app.captions.menu.backgroundColor": "Background", + "app.captions.menu.backgroundColor": "Background color", + "app.captions.menu.previewLabel": "Preview", + "app.captions.menu.cancelLabel": "Cancel", "app.captions.pad.hide": "Hide closed captions", "app.captions.pad.tip": "Press Esc to focus editor toolbar", "app.captions.pad.ownership": "Take ownership", -- GitLab