From 4cd8cb21279ce92e138e9b98395d7139efc969fa Mon Sep 17 00:00:00 2001 From: JonathanTGold Date: Wed, 27 Mar 2024 16:41:45 +0100 Subject: [PATCH 1/4] feat(FEC-13728): Add aptions language selector in bottom bar --- .../advanced-audio-desc-toggle.tsx | 2 + .../captions-control/captions-control.tsx | 104 ++++++++++++++++++ src/components/captions-control/index.ts | 1 + .../captions-menu/captions-menu.tsx | 82 +++++++++++--- .../closed-captions/closed-captions.tsx | 4 - src/components/cvaa-overlay/cvaa-overlay.tsx | 3 +- src/components/index.ts | 1 + src/components/settings/settings.tsx | 32 ++---- src/components/smart-container/index.ts | 1 + .../smart-container-item-type.ts | 5 + .../smart-container/smart-container-item.tsx | 26 +++-- src/reducers/config.ts | 1 + src/reducers/shell.ts | 11 +- src/types/reducers/shell.ts | 1 + src/types/ui-options.ts | 1 + src/ui-presets/playback.tsx | 5 +- 16 files changed, 223 insertions(+), 57 deletions(-) create mode 100644 src/components/captions-control/captions-control.tsx create mode 100644 src/components/captions-control/index.ts create mode 100644 src/components/smart-container/smart-container-item-type.ts diff --git a/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx b/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx index 5b26a10b9..893fb077f 100644 --- a/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx +++ b/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx @@ -6,6 +6,7 @@ import {actions} from '../../reducers/settings'; import {SmartContainerItem} from '../../components'; import {IconType} from '../icon'; import {withEventDispatcher} from '../../components/event-dispatcher'; +import {SmartContainerItemType} from '../smart-container'; /** * mapping state to props @@ -60,6 +61,7 @@ class AdvancedAudioDescToggle extends Component { label={props.advancedAudioText} isChecked={props.isAdvancedAudioDescChecked} onMenuChosen={this.onAdvancedAudioClick} + type={SmartContainerItemType.ToggleSwitch} /> ); } diff --git a/src/components/captions-control/captions-control.tsx b/src/components/captions-control/captions-control.tsx new file mode 100644 index 000000000..2f0acca37 --- /dev/null +++ b/src/components/captions-control/captions-control.tsx @@ -0,0 +1,104 @@ +import {h} from 'preact'; +import {connect, useSelector} from 'react-redux'; +import {ClosedCaptions} from '../closed-captions'; +import {CaptionsMenu} from '../captions-menu'; +import {ButtonControl} from '../button-control'; +import {Tooltip} from '../tooltip'; +import {Button} from '../button'; +import style from '../../styles/style.scss'; +import {Icon, IconType} from '../icon'; +import {SmartContainer} from '../smart-container'; +import {Text, withText} from 'preact-i18n'; +import {useRef, useState, useEffect, useCallback} from 'preact/hooks'; +import {focusElement} from '../../utils'; + +/** + * mapping state to props + * @param {*} state - redux store state + * @returns {Object} - mapped state to this component + */ +const mapStateToProps = state => ({ + textTracks: state.engine.textTracks, + showCCButton: state.config.showCCButton, + openMenuFromCCCButton: state.config.openMenuFromCCCButton, + isMobile: state.shell.isMobile, + isSmallSize: state.shell.isSmallSize, + isCVAAOverlayOpen: state.shell.isCVAAOverlayOpen +}); + +const COMPONENT_NAME = 'CaptionsControl'; + +/** + * CaptionsControl component + * + * @class CaptionsControl + * @example + * @extends {Component} + */ +const CaptionsControl = connect(mapStateToProps)( + withText({ + captionsLabelText: 'captions.captions', + advancedCaptionsSettingsText: 'captions.advanced_captions_settings' + })((props, context) => { + const [smartContainerOpen, setSmartContainerOpen] = useState(false); + const [ccOn, setCCOn] = useState(false); + const buttonRef = useRef(null); + const controlCaptionsElement = useRef(null); + + const {player} = context; + const {isSmallSize, isMobile, textTracks} = props; + const activeTextTrack = textTracks.find(textTrack => textTrack.active); + + const onControlButtonClick = (e?: KeyboardEvent, byKeyboard?: boolean): void => { + setSmartContainerOpen(smartContainerOpen => !smartContainerOpen); + if (byKeyboard && smartContainerOpen) { + focusElement(buttonRef.current); + } + }; + + const handleClickOutside = (e: any) => { + if (!isMobile && !isSmallSize && !!controlCaptionsElement.current && !controlCaptionsElement.current.contains(e.target)) { + setSmartContainerOpen(false); + } + }; + + useEffect(() => { + document.addEventListener('click', handleClickOutside); + return () => document.removeEventListener('click', handleClickOutside); + }, [isSmallSize, isMobile]); + + useEffect(() => { + setCCOn(activeTextTrack?.language !== 'off'); + }, [activeTextTrack]); + + const shouldRender = !!textTracks?.length && props.showCCButton; + props.onToggle(COMPONENT_NAME, shouldRender); + if (!shouldRender) return undefined; + + return props.openMenuFromCCCButton ? ( + + + + + {smartContainerOpen && ( + setSmartContainerOpen(false)} title={}> + setSmartContainerOpen(false)} /> + + )} + + ) : ( + + ); + }) +); + +CaptionsControl.displayName = COMPONENT_NAME; +export {CaptionsControl}; diff --git a/src/components/captions-control/index.ts b/src/components/captions-control/index.ts new file mode 100644 index 000000000..285216a53 --- /dev/null +++ b/src/components/captions-control/index.ts @@ -0,0 +1 @@ +export {CaptionsControl} from './captions-control' diff --git a/src/components/captions-menu/captions-menu.tsx b/src/components/captions-menu/captions-menu.tsx index c7ab1ce5a..1afe67330 100644 --- a/src/components/captions-menu/captions-menu.tsx +++ b/src/components/captions-menu/captions-menu.tsx @@ -1,8 +1,9 @@ import {h, Component, Fragment, VNode} from 'preact'; -import {withText} from 'preact-i18n'; +import {Text, withText} from 'preact-i18n'; import {connect} from 'react-redux'; import {bindActions} from '../../utils'; -import {actions} from '../../reducers/cvaa'; +import {actions as cvaaActions} from '../../reducers/cvaa'; +import {actions as shellActions} from '../../reducers/shell'; import {SmartContainerItem} from '../smart-container/smart-container-item'; import {IconType} from '../icon'; import {withPlayer} from '../player'; @@ -12,6 +13,9 @@ import {withEventDispatcher} from '../event-dispatcher'; import {KeyMap} from '../../utils'; import {withKeyboardEvent} from '../../components/keyboard'; import {KeyboardEventHandlers} from '../../types'; +import {createPortal} from 'react'; +import {CVAAOverlay} from '../cvaa-overlay'; +import {Menu} from '../menu'; /** * mapping state to props @@ -34,7 +38,7 @@ const COMPONENT_NAME = 'CaptionsMenu'; * @example * @extends {Component} */ -@connect(mapStateToProps, bindActions(actions)) +@connect(mapStateToProps, bindActions({...cvaaActions, ...shellActions})) @withPlayer @withEventManager @withKeyboardEvent(COMPONENT_NAME) @@ -69,6 +73,44 @@ class CaptionsMenu extends Component { } ]; + /** + * before component mounted, set initial state + * + * @returns {void} + * @memberof Settings + */ + componentWillMount(): void { + this.setState({cvaaOverlay: false}); + } + + // componentDidUpdate(previousProps: Readonly, previousState: Readonly, snapshot: any) { + // if (previousState.cvaaOverlay !== this.state.cvaaOverlay) { + // this.props.updateIsCVAAOverlayOpen(this.state.cvaaOverlay); + // } + // } + + toggleCVAAOverlay = (): void => { + this.setState(prevState => { + return {cvaaOverlay: !prevState.cvaaOverlay}; + }); + this.props.updateIsCVAAOverlayOpen(this.state.cvaaOverlay); + }; + + /** + * handle the closure of cvaa overlay + * + * @param {KeyboardEvent} e - keyboard event + * @param {boolean} byKeyboard - is keydown + * @returns {void} + * @memberof Settings + */ + onCVAAOverlayClose = (e?: KeyboardEvent, byKeyboard?: boolean): void => { + this.toggleCVAAOverlay(); + this.setState({cvaaOverlay: false}); + this.props.onCVAAOverlayClose(); + // this.props.updateIsCVAAOverlayOpen(false); + }; + /** * We update the last language selected here upon trackTracks props change. This is done to make sure we update the * last text track lanague upon language menu selection and using the (C) keyboard key. @@ -94,7 +136,7 @@ class CaptionsMenu extends Component { */ onCaptionsChange(textTrack: any | string): void { if (textTrack === this.props.advancedCaptionsSettingsText) { - this.props.onAdvancedCaptionsClick(); + this.toggleCVAAOverlay(); return; } this.props.player.selectTrack(textTrack); @@ -122,16 +164,30 @@ class CaptionsMenu extends Component { textOptions.push({label: props.advancedCaptionsSettingsText, value: props.advancedCaptionsSettingsText, active: false}); } + const targetId: HTMLDivElement | Document = (document.getElementById(this.props.player.config.targetId) as HTMLDivElement) || document; + const portalSelector = `.overlay-portal`; + return ( - { - props.pushRef(el); - }} - icon={IconType.Captions} - label={this.props.captionsLabelText} - options={textOptions} - onMenuChosen={textTrack => this.onCaptionsChange(textTrack)} - /> + <> + {!this.state.cvaaOverlay && ( + <> + {this.props.asDropdown ? ( + { + props.pushRef(el); + }} + icon={IconType.Captions} + label={this.props.captionsLabelText} + options={textOptions} + onMenuChosen={textTrack => this.onCaptionsChange(textTrack)} + /> + ) : ( + this.onCaptionsChange(textTrack)} onClose={() => {}} /> + )} + + )} + {this.state.cvaaOverlay ? createPortal(, targetId.querySelector(portalSelector)!) :
} + ); } } diff --git a/src/components/closed-captions/closed-captions.tsx b/src/components/closed-captions/closed-captions.tsx index c5181bc7b..e42b6d41f 100644 --- a/src/components/closed-captions/closed-captions.tsx +++ b/src/components/closed-captions/closed-captions.tsx @@ -16,7 +16,6 @@ import {ButtonControl} from '../button-control'; */ const mapStateToProps = state => ({ textTracks: state.engine.textTracks, - showCCButton: state.config.showCCButton }); const COMPONENT_NAME = 'ClosedCaptions'; @@ -44,9 +43,6 @@ const ClosedCaptions = connect(mapStateToProps)( setCCOn(activeTextTrack?.language !== 'off'); }, [activeTextTrack]); - const shouldRender = !!(props.textTracks?.length && props.showCCButton); - props.onToggle(COMPONENT_NAME, shouldRender); - if (!shouldRender) return undefined; return ( {ccOn ? ( diff --git a/src/components/cvaa-overlay/cvaa-overlay.tsx b/src/components/cvaa-overlay/cvaa-overlay.tsx index 4e9eb0833..cd16aa68a 100644 --- a/src/components/cvaa-overlay/cvaa-overlay.tsx +++ b/src/components/cvaa-overlay/cvaa-overlay.tsx @@ -138,8 +138,7 @@ class CVAAOverlay extends Component { addAccessibleChild={this.props.addAccessibleChild} onClose={props.onClose} type="cvaa" - label={props.cvvaDialogText} - > + label={props.cvvaDialogText}> {this.state.activeWindow === cvaaOverlayState.Main ? ( ({ videoTracks: state.engine.videoTracks, isMobile: state.shell.isMobile, isSmallSize: state.shell.isSmallSize, + isCVAAOverlayOpen: state.shell.isCVAAOverlayOpen, isLive: state.engine.isLive, isAudio: state.engine.isAudio, showQualityMenu: state.config.settings.showQualityMenu, showAudioMenu: state.config.settings.showAudioMenu, showCaptionsMenu: state.config.settings.showCaptionsMenu, showSpeedMenu: state.config.settings.showSpeedMenu, - showAdvancedAudioDescToggle: state.config.settings.showAdvancedAudioDescToggle + showAdvancedAudioDescToggle: state.config.settings.showAdvancedAudioDescToggle, }); const COMPONENT_NAME = 'Settings'; @@ -69,7 +70,7 @@ class Settings extends Component { * @memberof Settings */ componentWillMount() { - this.setState({smartContainerOpen: false, cvaaOverlay: false}); + this.setState({smartContainerOpen: false}); } /** @@ -81,6 +82,7 @@ class Settings extends Component { componentDidMount() { const {eventManager} = this.props; eventManager.listen(document, 'click', e => this.handleClickOutside(e)); + console.error(this.state.smartContainerOpen, 'settings => ', false); } /** @@ -92,7 +94,7 @@ class Settings extends Component { */ handleClickOutside(e: any) { if ( - !this.state.cvaaOverlay && + !this.props.isCVAAOverlayOpen && !this.props.isMobile && !this.props.isSmallSize && !!this._controlSettingsElement && @@ -131,25 +133,6 @@ class Settings extends Component { this._buttonRef = ref; }; - toggleCVAAOverlay = (): void => { - this.setState(prevState => { - return {cvaaOverlay: !prevState.cvaaOverlay}; - }); - }; - - /** - * handle the closure of cvaa overlay - * - * @param {KeyboardEvent} e - keyboard event - * @param {boolean} byKeyboard - is keydown - * @returns {void} - * @memberof Settings - */ - onCVAAOverlayClose = (e?: KeyboardEvent, byKeyboard?: boolean): void => { - this.toggleCVAAOverlay(); - this.onControlButtonClick(e, byKeyboard); - }; - /** * returns The badge icon type of the active quality option based on the height of the resolution * @@ -199,16 +182,15 @@ class Settings extends Component { - {this.state.smartContainerOpen && !this.state.cvaaOverlay && ( + {this.state.smartContainerOpen && !this.props.isCVAAOverlayOpen && ( } onClose={this.onControlButtonClick}> {showAdvancedAudioDescToggle && } {showAudioMenu && } - {showCaptionsMenu && } + {showCaptionsMenu && this.setState({smartContainerOpen: false})} />} {showQualityMenu && } {showSpeedMenu && } )} - {this.state.cvaaOverlay ? createPortal(, targetId.querySelector(portalSelector)!) :
} ); } diff --git a/src/components/smart-container/index.ts b/src/components/smart-container/index.ts index 96d0487da..1f79ce897 100644 --- a/src/components/smart-container/index.ts +++ b/src/components/smart-container/index.ts @@ -1,2 +1,3 @@ export {SmartContainer} from './smart-container'; export {SmartContainerItem} from './smart-container-item'; +export {SmartContainerItemType} from './smart-container-item-type'; diff --git a/src/components/smart-container/smart-container-item-type.ts b/src/components/smart-container/smart-container-item-type.ts new file mode 100644 index 000000000..e120ec3e6 --- /dev/null +++ b/src/components/smart-container/smart-container-item-type.ts @@ -0,0 +1,5 @@ +export enum SmartContainerItemType { + DropDown, + Menu, + ToggleSwitch +} diff --git a/src/components/smart-container/smart-container-item.tsx b/src/components/smart-container/smart-container-item.tsx index ab812e75e..b5bcd3c5f 100644 --- a/src/components/smart-container/smart-container-item.tsx +++ b/src/components/smart-container/smart-container-item.tsx @@ -1,8 +1,9 @@ import style from '../../styles/style.scss'; import {h, Component, VNode} from 'preact'; import {DropDown} from '../dropdown'; -import {default as Icon} from '../icon'; +import {default as Icon, IconType} from '../icon'; import {ToggleSwitch} from '../../components'; +import {SmartContainerItemType} from './smart-container-item-type'; const COMPONENT_NAME = 'SmartContainerItem'; @@ -43,14 +44,21 @@ class SmartContainerItem extends Component { /> ) : (
- { - props.pushRef(el); - }} - name={label} - isChecked={props.isChecked} - onMenuChosen={o => props.onMenuChosen(o)} - /> + {props.type === SmartContainerItemType.ToggleSwitch && ( + { + props.pushRef(el); + }} + name={label} + isChecked={props.isChecked} + onMenuChosen={o => props.onMenuChosen(o)} + /> + )} + {props.type === SmartContainerItemType.Menu && ( + + + + )}
)}
diff --git a/src/reducers/config.ts b/src/reducers/config.ts index b857438ff..d504bdb1b 100644 --- a/src/reducers/config.ts +++ b/src/reducers/config.ts @@ -13,6 +13,7 @@ export const initialState = { targetId: undefined as unknown as string, forceTouchUI: false, showCCButton: true, + openMenuFromCCCButton: false, settings: { showAudioMenu: true, showCaptionsMenu: true, diff --git a/src/reducers/shell.ts b/src/reducers/shell.ts index 1566905f2..81545e204 100644 --- a/src/reducers/shell.ts +++ b/src/reducers/shell.ts @@ -19,7 +19,8 @@ export const types = { UPDATE_SIDE_PANEL_MODE: 'shell/UPDATE_SIDE_PANEL_MODE', UPDATE_SIDE_PANEL_SIZE: 'shell/UPDATE_SIDE_PANEL_SIZE', UPDATE_PRESET_SETTINGS: 'shell/UPDATE_PRESET_SETTINGS', - UPDATE_LAYOUT_STYLES: 'shell/UPDATE_LAYOUT_STYLES' + UPDATE_LAYOUT_STYLES: 'shell/UPDATE_LAYOUT_STYLES', + UPDATE_IS_CVAA_OVERLAY_OPEN: 'shell/UPDATE_IS_CVAA_OVERLAY_OPEN' }; export const SidePanelOrientation = { @@ -102,6 +103,7 @@ export const initialState = { playerHover: false, playerNav: false, smartContainerOpen: false, + isCVAAOverlayOpen: false, activePresetName: '', sidePanelsModes: { [SidePanelPositions.LEFT]: SidePanelModes.HIDDEN, @@ -217,6 +219,12 @@ export default (state: ShellState = initialState, action: any) => { smartContainerOpen: action.open }; + case types.UPDATE_IS_CVAA_OVERLAY_OPEN: + return { + ...state, + isCVAAOverlayOpen: action.open + }; + case types.UPDATE_ACTIVE_PRESET_NAME: return { ...state, @@ -276,6 +284,7 @@ export const actions = { updatePlayerHoverState: (hover: boolean) => ({type: types.UPDATE_PLAYER_HOVER_STATE, hover}), updatePlayerNavState: (nav: boolean) => ({type: types.UPDATE_PLAYER_NAV_STATE, nav}), updateSmartContainerOpen: (open: boolean) => ({type: types.UPDATE_SMART_CONTAINER_OPEN, open}), + updateIsCVAAOverlayOpen: (open: boolean) => ({type: types.UPDATE_IS_CVAA_OVERLAY_OPEN, open}), updateActivePresetName: (activePresetName: string) => ({type: types.UPDATE_ACTIVE_PRESET_NAME, activePresetName}), updateSidePanelMode: (position: string, sidePanelMode: string) => ({ type: types.UPDATE_SIDE_PANEL_MODE, diff --git a/src/types/reducers/shell.ts b/src/types/reducers/shell.ts index 3a6628fbe..6550dd436 100644 --- a/src/types/reducers/shell.ts +++ b/src/types/reducers/shell.ts @@ -31,4 +31,5 @@ export interface ShellState { sidePanelsSizes: {[key: string]: any}; // Consider defining a more specific type presetSettings: PresetSettings; documentWidth?: number; + isCVAAOverlayOpen: boolean; } diff --git a/src/types/ui-options.ts b/src/types/ui-options.ts index cfe636363..4f8250d54 100644 --- a/src/types/ui-options.ts +++ b/src/types/ui-options.ts @@ -8,6 +8,7 @@ export interface UIOptionsObject { debugActions?: boolean; forceTouchUI?: boolean; showCCButton?: boolean; + openMenuFromCCCButton?: boolean; settings?: { showAudioMenu?: boolean; showCaptionsMenu?: boolean; diff --git a/src/ui-presets/playback.tsx b/src/ui-presets/playback.tsx index e4255f67a..f8e8d2495 100644 --- a/src/ui-presets/playback.tsx +++ b/src/ui-presets/playback.tsx @@ -1,6 +1,6 @@ import style from '../styles/style.scss'; import {Fragment, h, Component, VNode} from 'preact'; -import {PlayerArea, withPlayerPreset} from '../components'; +import {CaptionsControl, PlayerArea, withPlayerPreset} from '../components'; import {OverlayAction} from '../components'; import {PrePlaybackPlayOverlay} from '../components'; import {Loading} from '../components'; @@ -89,8 +89,7 @@ class PlaybackUI extends Component { + rightControls={[VrStereo, Volume, CaptionsControl, Settings, Cast, PictureInPicture, Fullscreen, Logo]}> From c341a35d0c26552ddc8c8f925e0f076ecc52a1f4 Mon Sep 17 00:00:00 2001 From: JonathanTGold Date: Wed, 27 Mar 2024 17:05:09 +0100 Subject: [PATCH 2/4] fix state issue --- .../captions-control/captions-control.tsx | 20 ++++- .../captions-menu/captions-menu.tsx | 80 ++++--------------- src/components/settings/settings.tsx | 32 ++++++-- 3 files changed, 59 insertions(+), 73 deletions(-) diff --git a/src/components/captions-control/captions-control.tsx b/src/components/captions-control/captions-control.tsx index 2f0acca37..9c1f0e68d 100644 --- a/src/components/captions-control/captions-control.tsx +++ b/src/components/captions-control/captions-control.tsx @@ -11,6 +11,8 @@ import {SmartContainer} from '../smart-container'; import {Text, withText} from 'preact-i18n'; import {useRef, useState, useEffect, useCallback} from 'preact/hooks'; import {focusElement} from '../../utils'; +import {createPortal} from 'preact/compat'; +import {CVAAOverlay} from '../cvaa-overlay'; /** * mapping state to props @@ -41,6 +43,7 @@ const CaptionsControl = connect(mapStateToProps)( advancedCaptionsSettingsText: 'captions.advanced_captions_settings' })((props, context) => { const [smartContainerOpen, setSmartContainerOpen] = useState(false); + const [cvaaOverlay, setCVAAOverlay] = useState(false); const [ccOn, setCCOn] = useState(false); const buttonRef = useRef(null); const controlCaptionsElement = useRef(null); @@ -56,6 +59,15 @@ const CaptionsControl = connect(mapStateToProps)( } }; + const toggleCVAAOverlay = (): void => { + setCVAAOverlay(cvaaOverlay => !cvaaOverlay); + }; + + const onCVAAOverlayClose = (e?: KeyboardEvent, byKeyboard?: boolean): void => { + toggleCVAAOverlay(); + onControlButtonClick(e, byKeyboard); + }; + const handleClickOutside = (e: any) => { if (!isMobile && !isSmallSize && !!controlCaptionsElement.current && !controlCaptionsElement.current.contains(e.target)) { setSmartContainerOpen(false); @@ -75,6 +87,9 @@ const CaptionsControl = connect(mapStateToProps)( props.onToggle(COMPONENT_NAME, shouldRender); if (!shouldRender) return undefined; + const targetId: HTMLDivElement | Document = (document.getElementById(player.config.targetId) as HTMLDivElement) || document; + const portalSelector = `.overlay-portal`; + return props.openMenuFromCCCButton ? ( @@ -88,11 +103,12 @@ const CaptionsControl = connect(mapStateToProps)( - {smartContainerOpen && ( + {smartContainerOpen && !cvaaOverlay && ( setSmartContainerOpen(false)} title={}> - setSmartContainerOpen(false)} /> + )} + {cvaaOverlay ? createPortal(, targetId.querySelector(portalSelector)!) :
} ) : ( diff --git a/src/components/captions-menu/captions-menu.tsx b/src/components/captions-menu/captions-menu.tsx index 1afe67330..f9e6b5615 100644 --- a/src/components/captions-menu/captions-menu.tsx +++ b/src/components/captions-menu/captions-menu.tsx @@ -73,44 +73,6 @@ class CaptionsMenu extends Component { } ]; - /** - * before component mounted, set initial state - * - * @returns {void} - * @memberof Settings - */ - componentWillMount(): void { - this.setState({cvaaOverlay: false}); - } - - // componentDidUpdate(previousProps: Readonly, previousState: Readonly, snapshot: any) { - // if (previousState.cvaaOverlay !== this.state.cvaaOverlay) { - // this.props.updateIsCVAAOverlayOpen(this.state.cvaaOverlay); - // } - // } - - toggleCVAAOverlay = (): void => { - this.setState(prevState => { - return {cvaaOverlay: !prevState.cvaaOverlay}; - }); - this.props.updateIsCVAAOverlayOpen(this.state.cvaaOverlay); - }; - - /** - * handle the closure of cvaa overlay - * - * @param {KeyboardEvent} e - keyboard event - * @param {boolean} byKeyboard - is keydown - * @returns {void} - * @memberof Settings - */ - onCVAAOverlayClose = (e?: KeyboardEvent, byKeyboard?: boolean): void => { - this.toggleCVAAOverlay(); - this.setState({cvaaOverlay: false}); - this.props.onCVAAOverlayClose(); - // this.props.updateIsCVAAOverlayOpen(false); - }; - /** * We update the last language selected here upon trackTracks props change. This is done to make sure we update the * last text track lanague upon language menu selection and using the (C) keyboard key. @@ -136,7 +98,7 @@ class CaptionsMenu extends Component { */ onCaptionsChange(textTrack: any | string): void { if (textTrack === this.props.advancedCaptionsSettingsText) { - this.toggleCVAAOverlay(); + this.props.onAdvancedCaptionsClick(); return; } this.props.player.selectTrack(textTrack); @@ -164,31 +126,21 @@ class CaptionsMenu extends Component { textOptions.push({label: props.advancedCaptionsSettingsText, value: props.advancedCaptionsSettingsText, active: false}); } - const targetId: HTMLDivElement | Document = (document.getElementById(this.props.player.config.targetId) as HTMLDivElement) || document; - const portalSelector = `.overlay-portal`; - - return ( - <> - {!this.state.cvaaOverlay && ( - <> - {this.props.asDropdown ? ( - { - props.pushRef(el); - }} - icon={IconType.Captions} - label={this.props.captionsLabelText} - options={textOptions} - onMenuChosen={textTrack => this.onCaptionsChange(textTrack)} - /> - ) : ( - this.onCaptionsChange(textTrack)} onClose={() => {}} /> - )} - - )} - {this.state.cvaaOverlay ? createPortal(, targetId.querySelector(portalSelector)!) :
} - - ); + if (this.props.asDropdown) { + return ( + { + props.pushRef(el); + }} + icon={IconType.Captions} + label={this.props.captionsLabelText} + options={textOptions} + onMenuChosen={textTrack => this.onCaptionsChange(textTrack)} + /> + ); + } else { + return this.onCaptionsChange(textTrack)} onClose={() => {}} />; + } } } diff --git a/src/components/settings/settings.tsx b/src/components/settings/settings.tsx index 0a46d0352..aeb350e6a 100644 --- a/src/components/settings/settings.tsx +++ b/src/components/settings/settings.tsx @@ -35,14 +35,13 @@ const mapStateToProps = state => ({ videoTracks: state.engine.videoTracks, isMobile: state.shell.isMobile, isSmallSize: state.shell.isSmallSize, - isCVAAOverlayOpen: state.shell.isCVAAOverlayOpen, isLive: state.engine.isLive, isAudio: state.engine.isAudio, showQualityMenu: state.config.settings.showQualityMenu, showAudioMenu: state.config.settings.showAudioMenu, showCaptionsMenu: state.config.settings.showCaptionsMenu, showSpeedMenu: state.config.settings.showSpeedMenu, - showAdvancedAudioDescToggle: state.config.settings.showAdvancedAudioDescToggle, + showAdvancedAudioDescToggle: state.config.settings.showAdvancedAudioDescToggle }); const COMPONENT_NAME = 'Settings'; @@ -70,7 +69,7 @@ class Settings extends Component { * @memberof Settings */ componentWillMount() { - this.setState({smartContainerOpen: false}); + this.setState({smartContainerOpen: false, cvaaOverlay: false}); } /** @@ -82,7 +81,6 @@ class Settings extends Component { componentDidMount() { const {eventManager} = this.props; eventManager.listen(document, 'click', e => this.handleClickOutside(e)); - console.error(this.state.smartContainerOpen, 'settings => ', false); } /** @@ -94,7 +92,7 @@ class Settings extends Component { */ handleClickOutside(e: any) { if ( - !this.props.isCVAAOverlayOpen && + !this.state.cvaaOverlay && !this.props.isMobile && !this.props.isSmallSize && !!this._controlSettingsElement && @@ -133,6 +131,25 @@ class Settings extends Component { this._buttonRef = ref; }; + toggleCVAAOverlay = (): void => { + this.setState(prevState => { + return {cvaaOverlay: !prevState.cvaaOverlay}; + }); + }; + + /** + * handle the closure of cvaa overlay + * + * @param {KeyboardEvent} e - keyboard event + * @param {boolean} byKeyboard - is keydown + * @returns {void} + * @memberof Settings + */ + onCVAAOverlayClose = (e?: KeyboardEvent, byKeyboard?: boolean): void => { + this.toggleCVAAOverlay(); + this.onControlButtonClick(e, byKeyboard); + }; + /** * returns The badge icon type of the active quality option based on the height of the resolution * @@ -182,15 +199,16 @@ class Settings extends Component { - {this.state.smartContainerOpen && !this.props.isCVAAOverlayOpen && ( + {this.state.smartContainerOpen && !this.state.cvaaOverlay && ( } onClose={this.onControlButtonClick}> {showAdvancedAudioDescToggle && } {showAudioMenu && } - {showCaptionsMenu && this.setState({smartContainerOpen: false})} />} + {showCaptionsMenu && } {showQualityMenu && } {showSpeedMenu && } )} + {this.state.cvaaOverlay ? createPortal(, targetId.querySelector(portalSelector)!) :
} ); } From cc353027d9833b6ed4bf7ba0e3883fd975f2d793 Mon Sep 17 00:00:00 2001 From: JonathanTGold Date: Thu, 28 Mar 2024 11:02:10 +0100 Subject: [PATCH 3/4] revert --- .../advanced-audio-desc-toggle.tsx | 2 -- .../captions-control/captions-control.tsx | 2 +- .../captions-menu/captions-menu.tsx | 9 +++---- src/components/smart-container/index.ts | 1 - .../smart-container/smart-container-item.tsx | 26 +++++++------------ src/reducers/config.ts | 2 +- src/reducers/shell.ts | 11 +------- src/types/reducers/shell.ts | 1 - src/types/ui-options.ts | 2 +- src/ui-presets/playback.tsx | 3 ++- 10 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx b/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx index 893fb077f..5b26a10b9 100644 --- a/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx +++ b/src/components/advanced-audio-desc-toggle/advanced-audio-desc-toggle.tsx @@ -6,7 +6,6 @@ import {actions} from '../../reducers/settings'; import {SmartContainerItem} from '../../components'; import {IconType} from '../icon'; import {withEventDispatcher} from '../../components/event-dispatcher'; -import {SmartContainerItemType} from '../smart-container'; /** * mapping state to props @@ -61,7 +60,6 @@ class AdvancedAudioDescToggle extends Component { label={props.advancedAudioText} isChecked={props.isAdvancedAudioDescChecked} onMenuChosen={this.onAdvancedAudioClick} - type={SmartContainerItemType.ToggleSwitch} /> ); } diff --git a/src/components/captions-control/captions-control.tsx b/src/components/captions-control/captions-control.tsx index 9c1f0e68d..9c86aa66b 100644 --- a/src/components/captions-control/captions-control.tsx +++ b/src/components/captions-control/captions-control.tsx @@ -22,7 +22,7 @@ import {CVAAOverlay} from '../cvaa-overlay'; const mapStateToProps = state => ({ textTracks: state.engine.textTracks, showCCButton: state.config.showCCButton, - openMenuFromCCCButton: state.config.openMenuFromCCCButton, + openMenuFromCCCButton: state.config.openMenuFromCCButton, isMobile: state.shell.isMobile, isSmallSize: state.shell.isSmallSize, isCVAAOverlayOpen: state.shell.isCVAAOverlayOpen diff --git a/src/components/captions-menu/captions-menu.tsx b/src/components/captions-menu/captions-menu.tsx index f9e6b5615..03273b81b 100644 --- a/src/components/captions-menu/captions-menu.tsx +++ b/src/components/captions-menu/captions-menu.tsx @@ -1,9 +1,8 @@ import {h, Component, Fragment, VNode} from 'preact'; -import {Text, withText} from 'preact-i18n'; +import {withText} from 'preact-i18n'; import {connect} from 'react-redux'; import {bindActions} from '../../utils'; -import {actions as cvaaActions} from '../../reducers/cvaa'; -import {actions as shellActions} from '../../reducers/shell'; +import {actions} from '../../reducers/cvaa'; import {SmartContainerItem} from '../smart-container/smart-container-item'; import {IconType} from '../icon'; import {withPlayer} from '../player'; @@ -13,8 +12,6 @@ import {withEventDispatcher} from '../event-dispatcher'; import {KeyMap} from '../../utils'; import {withKeyboardEvent} from '../../components/keyboard'; import {KeyboardEventHandlers} from '../../types'; -import {createPortal} from 'react'; -import {CVAAOverlay} from '../cvaa-overlay'; import {Menu} from '../menu'; /** @@ -38,7 +35,7 @@ const COMPONENT_NAME = 'CaptionsMenu'; * @example * @extends {Component} */ -@connect(mapStateToProps, bindActions({...cvaaActions, ...shellActions})) +@connect(mapStateToProps, bindActions(actions)) @withPlayer @withEventManager @withKeyboardEvent(COMPONENT_NAME) diff --git a/src/components/smart-container/index.ts b/src/components/smart-container/index.ts index 1f79ce897..96d0487da 100644 --- a/src/components/smart-container/index.ts +++ b/src/components/smart-container/index.ts @@ -1,3 +1,2 @@ export {SmartContainer} from './smart-container'; export {SmartContainerItem} from './smart-container-item'; -export {SmartContainerItemType} from './smart-container-item-type'; diff --git a/src/components/smart-container/smart-container-item.tsx b/src/components/smart-container/smart-container-item.tsx index b5bcd3c5f..ab812e75e 100644 --- a/src/components/smart-container/smart-container-item.tsx +++ b/src/components/smart-container/smart-container-item.tsx @@ -1,9 +1,8 @@ import style from '../../styles/style.scss'; import {h, Component, VNode} from 'preact'; import {DropDown} from '../dropdown'; -import {default as Icon, IconType} from '../icon'; +import {default as Icon} from '../icon'; import {ToggleSwitch} from '../../components'; -import {SmartContainerItemType} from './smart-container-item-type'; const COMPONENT_NAME = 'SmartContainerItem'; @@ -44,21 +43,14 @@ class SmartContainerItem extends Component { /> ) : (
- {props.type === SmartContainerItemType.ToggleSwitch && ( - { - props.pushRef(el); - }} - name={label} - isChecked={props.isChecked} - onMenuChosen={o => props.onMenuChosen(o)} - /> - )} - {props.type === SmartContainerItemType.Menu && ( - - - - )} + { + props.pushRef(el); + }} + name={label} + isChecked={props.isChecked} + onMenuChosen={o => props.onMenuChosen(o)} + />
)}
diff --git a/src/reducers/config.ts b/src/reducers/config.ts index d504bdb1b..6adfcc3c9 100644 --- a/src/reducers/config.ts +++ b/src/reducers/config.ts @@ -13,7 +13,7 @@ export const initialState = { targetId: undefined as unknown as string, forceTouchUI: false, showCCButton: true, - openMenuFromCCCButton: false, + openMenuFromCCButton: false, settings: { showAudioMenu: true, showCaptionsMenu: true, diff --git a/src/reducers/shell.ts b/src/reducers/shell.ts index 81545e204..1566905f2 100644 --- a/src/reducers/shell.ts +++ b/src/reducers/shell.ts @@ -19,8 +19,7 @@ export const types = { UPDATE_SIDE_PANEL_MODE: 'shell/UPDATE_SIDE_PANEL_MODE', UPDATE_SIDE_PANEL_SIZE: 'shell/UPDATE_SIDE_PANEL_SIZE', UPDATE_PRESET_SETTINGS: 'shell/UPDATE_PRESET_SETTINGS', - UPDATE_LAYOUT_STYLES: 'shell/UPDATE_LAYOUT_STYLES', - UPDATE_IS_CVAA_OVERLAY_OPEN: 'shell/UPDATE_IS_CVAA_OVERLAY_OPEN' + UPDATE_LAYOUT_STYLES: 'shell/UPDATE_LAYOUT_STYLES' }; export const SidePanelOrientation = { @@ -103,7 +102,6 @@ export const initialState = { playerHover: false, playerNav: false, smartContainerOpen: false, - isCVAAOverlayOpen: false, activePresetName: '', sidePanelsModes: { [SidePanelPositions.LEFT]: SidePanelModes.HIDDEN, @@ -219,12 +217,6 @@ export default (state: ShellState = initialState, action: any) => { smartContainerOpen: action.open }; - case types.UPDATE_IS_CVAA_OVERLAY_OPEN: - return { - ...state, - isCVAAOverlayOpen: action.open - }; - case types.UPDATE_ACTIVE_PRESET_NAME: return { ...state, @@ -284,7 +276,6 @@ export const actions = { updatePlayerHoverState: (hover: boolean) => ({type: types.UPDATE_PLAYER_HOVER_STATE, hover}), updatePlayerNavState: (nav: boolean) => ({type: types.UPDATE_PLAYER_NAV_STATE, nav}), updateSmartContainerOpen: (open: boolean) => ({type: types.UPDATE_SMART_CONTAINER_OPEN, open}), - updateIsCVAAOverlayOpen: (open: boolean) => ({type: types.UPDATE_IS_CVAA_OVERLAY_OPEN, open}), updateActivePresetName: (activePresetName: string) => ({type: types.UPDATE_ACTIVE_PRESET_NAME, activePresetName}), updateSidePanelMode: (position: string, sidePanelMode: string) => ({ type: types.UPDATE_SIDE_PANEL_MODE, diff --git a/src/types/reducers/shell.ts b/src/types/reducers/shell.ts index 6550dd436..3a6628fbe 100644 --- a/src/types/reducers/shell.ts +++ b/src/types/reducers/shell.ts @@ -31,5 +31,4 @@ export interface ShellState { sidePanelsSizes: {[key: string]: any}; // Consider defining a more specific type presetSettings: PresetSettings; documentWidth?: number; - isCVAAOverlayOpen: boolean; } diff --git a/src/types/ui-options.ts b/src/types/ui-options.ts index 4f8250d54..9f1d8c4c9 100644 --- a/src/types/ui-options.ts +++ b/src/types/ui-options.ts @@ -8,7 +8,7 @@ export interface UIOptionsObject { debugActions?: boolean; forceTouchUI?: boolean; showCCButton?: boolean; - openMenuFromCCCButton?: boolean; + openMenuFromCCButton?: boolean; settings?: { showAudioMenu?: boolean; showCaptionsMenu?: boolean; diff --git a/src/ui-presets/playback.tsx b/src/ui-presets/playback.tsx index f8e8d2495..0fc09dba3 100644 --- a/src/ui-presets/playback.tsx +++ b/src/ui-presets/playback.tsx @@ -1,11 +1,12 @@ import style from '../styles/style.scss'; import {Fragment, h, Component, VNode} from 'preact'; -import {CaptionsControl, PlayerArea, withPlayerPreset} from '../components'; +import {PlayerArea, withPlayerPreset} from '../components'; import {OverlayAction} from '../components'; import {PrePlaybackPlayOverlay} from '../components'; import {Loading} from '../components'; import {Rewind} from '../components'; import {Forward} from '../components'; +import {CaptionsControl} from '../components'; import {SeekBarPlaybackContainer} from '../components'; import {Volume} from '../components'; import {Settings} from '../components'; From cfb48891b772dd1fe5e359e783518e593be175c5 Mon Sep 17 00:00:00 2001 From: JonathanTGold Date: Thu, 28 Mar 2024 11:04:26 +0100 Subject: [PATCH 4/4] lint fix --- src/components/captions-control/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/captions-control/index.ts b/src/components/captions-control/index.ts index 285216a53..de9a877af 100644 --- a/src/components/captions-control/index.ts +++ b/src/components/captions-control/index.ts @@ -1 +1 @@ -export {CaptionsControl} from './captions-control' +export {CaptionsControl} from './captions-control';