Merge pull request #14184 from KDSBrowne/BBB-14141
Add Polite Presentation Slide Change Announcement (Screen Reader)
This commit is contained in:
commit
7a733b7382
@ -127,7 +127,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<!-- fonts -->
|
||||
</head>
|
||||
<body style="background-color: #06172A">
|
||||
<div id="app" role="document"></div>
|
||||
<div id="aria-polite-alert" aria-live="polite" aria-atomic="false" class="sr-only"></div>
|
||||
<div id="app" role="document">
|
||||
</div>
|
||||
<span id="destination"></span>
|
||||
<audio id="remote-media" autoplay>
|
||||
</audio>
|
||||
|
@ -16,7 +16,7 @@ import SettingsDropdownContainer from './settings-dropdown/container';
|
||||
import browserInfo from '/imports/utils/browserInfo';
|
||||
import deviceInfo from '/imports/utils/deviceInfo';
|
||||
import _ from "lodash";
|
||||
import {alertScreenReader} from '/imports/utils/dom-utils';
|
||||
import { politeSRAlert } from '/imports/utils/dom-utils';
|
||||
import { PANELS, ACTIONS } from '../layout/enums';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
@ -193,7 +193,7 @@ class NavBar extends Component {
|
||||
|
||||
activeChats.map((c, i) => {
|
||||
if (c?.unreadCounter > 0 && c?.unreadCounter !== acs[i]?.unreadCounter) {
|
||||
alertScreenReader(`${intl.formatMessage(intlMessages.newMsgAria, { 0: c.name })}`)
|
||||
politeSRAlert(`${intl.formatMessage(intlMessages.newMsgAria, { 0: c.name })}`)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,7 @@ import WhiteboardToolbarContainer from '/imports/ui/components/whiteboard/whiteb
|
||||
import { HUNDRED_PERCENT, MAX_PERCENT } from '/imports/utils/slideCalcUtils';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { toast } from 'react-toastify';
|
||||
import { politeSRAlert } from '/imports/utils/dom-utils';
|
||||
import PresentationToolbarContainer from './presentation-toolbar/container';
|
||||
import PresentationPlaceholder from './presentation-placeholder/component';
|
||||
import CursorWrapperContainer from './cursor/cursor-wrapper-container/container';
|
||||
@ -45,6 +46,10 @@ const intlMessages = defineMessages({
|
||||
id: 'app.presentation.endSlideContent',
|
||||
description: 'Indicate the slide content end',
|
||||
},
|
||||
slideContentChanged: {
|
||||
id: 'app.presentation.changedSlideContent',
|
||||
description: 'Indicate the slide content has changed',
|
||||
},
|
||||
noSlideContent: {
|
||||
id: 'app.presentation.emptySlideContent',
|
||||
description: 'No content available for slide',
|
||||
@ -112,7 +117,8 @@ class Presentation extends PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
this.getInitialPresentationSizes();
|
||||
this.refPresentationContainer.addEventListener(FULLSCREEN_CHANGE_EVENT, this.onFullscreenChange);
|
||||
this.refPresentationContainer
|
||||
.addEventListener(FULLSCREEN_CHANGE_EVENT, this.onFullscreenChange);
|
||||
window.addEventListener('resize', this.onResize, false);
|
||||
|
||||
const {
|
||||
@ -148,6 +154,7 @@ class Presentation extends PureComponent {
|
||||
userIsPresenter,
|
||||
presentationBounds,
|
||||
numCameras,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@ -159,6 +166,10 @@ class Presentation extends PureComponent {
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
if (currentSlide.num !== prevProps.currentSlide.num) {
|
||||
politeSRAlert(intl.formatMessage(intlMessages.slideContentChanged, { 0: currentSlide.num }));
|
||||
}
|
||||
|
||||
if (prevProps?.slidePosition && slidePosition) {
|
||||
const { width: prevWidth, height: prevHeight } = prevProps.slidePosition;
|
||||
const { width: currWidth, height: currHeight } = slidePosition;
|
||||
@ -225,7 +236,8 @@ class Presentation extends PureComponent {
|
||||
const { fullscreenContext, layoutContextDispatch } = this.props;
|
||||
|
||||
window.removeEventListener('resize', this.onResize, false);
|
||||
this.refPresentationContainer.removeEventListener(FULLSCREEN_CHANGE_EVENT, this.onFullscreenChange);
|
||||
this.refPresentationContainer
|
||||
.removeEventListener(FULLSCREEN_CHANGE_EVENT, this.onFullscreenChange);
|
||||
|
||||
if (fullscreenContext) {
|
||||
layoutContextDispatch({
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
const TITLE_WITH_VIEW = 3;
|
||||
const ARIA_ALERT_TIMEOUT = 3000;
|
||||
const ARIA_ALERT_EXT_TIMEOUT = 15000;
|
||||
|
||||
const getTitleData = () => {
|
||||
const title = document.getElementsByTagName('title')[0];
|
||||
@ -37,4 +38,12 @@ export const alertScreenReader = (s = '') => {
|
||||
}, ARIA_ALERT_TIMEOUT);
|
||||
};
|
||||
|
||||
export default { registerTitleView, unregisterTitleView, alertScreenReader };
|
||||
export const politeSRAlert = (s = '') => {
|
||||
const liveArea = document.getElementById('aria-polite-alert')
|
||||
if (liveArea) liveArea.innerHTML = s;
|
||||
setTimeout(() => {
|
||||
if (liveArea) liveArea.innerHTML = '';
|
||||
}, ARIA_ALERT_EXT_TIMEOUT);
|
||||
};
|
||||
|
||||
export default { registerTitleView, unregisterTitleView, alertScreenReader, politeSRAlert };
|
||||
|
@ -164,6 +164,7 @@
|
||||
"app.presentation.slideContent": "Slide Content",
|
||||
"app.presentation.startSlideContent": "Slide content start",
|
||||
"app.presentation.endSlideContent": "Slide content end",
|
||||
"app.presentation.changedSlideContent": "Presentation changed to slide: {0}",
|
||||
"app.presentation.emptySlideContent": "No content for current slide",
|
||||
"app.presentation.presentationToolbar.noNextSlideDesc": "End of presentation",
|
||||
"app.presentation.presentationToolbar.noPrevSlideDesc": "Start of presentation",
|
||||
|
Loading…
Reference in New Issue
Block a user