From 76ac6fe59627a9c8551554790e274260330b4ced Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Sun, 23 Jan 2022 16:18:09 +0000 Subject: [PATCH 1/2] add polite screen reader alert --- bigbluebutton-html5/client/main.html | 4 +++- .../imports/ui/components/nav-bar/component.jsx | 4 ++-- bigbluebutton-html5/imports/utils/dom-utils.js | 11 ++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-html5/client/main.html b/bigbluebutton-html5/client/main.html index d3c866c4d1..838050f6e2 100755 --- a/bigbluebutton-html5/client/main.html +++ b/bigbluebutton-html5/client/main.html @@ -127,7 +127,9 @@ with BigBlueButton; if not, see . -
+
+
+
diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index 444caed667..87f0df4211 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -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 })}`) } }); diff --git a/bigbluebutton-html5/imports/utils/dom-utils.js b/bigbluebutton-html5/imports/utils/dom-utils.js index 98a902dd94..5c221215ea 100644 --- a/bigbluebutton-html5/imports/utils/dom-utils.js +++ b/bigbluebutton-html5/imports/utils/dom-utils.js @@ -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 }; From b5f973ee6b6368e16159800dc95e42851e69b5d6 Mon Sep 17 00:00:00 2001 From: KDSBrowne Date: Sun, 23 Jan 2022 17:00:05 +0000 Subject: [PATCH 2/2] add polite SR message for presentation slide change --- .../ui/components/presentation/component.jsx | 16 ++++++++++++++-- bigbluebutton-html5/public/locales/en.json | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx index fcab986df0..4f9a04db73 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx @@ -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({ diff --git a/bigbluebutton-html5/public/locales/en.json b/bigbluebutton-html5/public/locales/en.json index 4d0e15098e..0a416917f5 100755 --- a/bigbluebutton-html5/public/locales/en.json +++ b/bigbluebutton-html5/public/locales/en.json @@ -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",