-
Notifications
You must be signed in to change notification settings - Fork 1.6k
fix: announce sending status to screen readers via live region #5781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
isherstneva
wants to merge
21
commits into
microsoft:main
Choose a base branch
from
isherstneva:fix/sending-live-region-announcement
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
385f011
fix: announce sending status to screen readers via live region
isherstneva 6523036
fix: use React.Fragment instead of fragment shorthand
isherstneva 98695bb
test: advance clock past live region fade before final snapshot
isherstneva 6b936e5
revert: restore original test, snapshot needs regeneration
isherstneva a37c870
test: update snapshots to include sending live region announcement
isherstneva c4a883b
test: update snapshots for sending live region announcement
isherstneva 0e46c91
test: fix assertion tests for sending live region announcement
isherstneva 6c24bc6
test: wait for async telemetry exception event in unknownActivity test
isherstneva 41bd39b
test: stabilize snapshot tests with missing image/scroll waits
isherstneva 533fe17
fix: delay sending announcement to 3 seconds to avoid noise on fast s…
isherstneva a48a1b5
test: regenerate snapshots after 3s sending announcement delay
isherstneva 9c84327
fix: add required curly braces to if statements (curly lint rule)
isherstneva 66cee21
refactor: rename SendSending to LongSend; revert unrelated test changes
isherstneva fb9fb48
test: rename sendSending test to longSend
isherstneva b274a28
ci: retrigger
isherstneva ae3cfd3
ci: retrigger
isherstneva 0f23db2
ci: retrigger
isherstneva 5fc301c
ci: retrigger
isherstneva 26e9a2d
refactor: extract useActivityKeysOfSendStatus hook to eliminate dupli…
isherstneva a7d57db
refactor: return readonly tuple from useActivityKeysOfSendStatus per …
isherstneva 36f7844
Add `useIsSending`
compulim File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
__tests__/html2/accessibility/liveRegion/activityStatus.longSend.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en-US"> | ||
| <head> | ||
| <link href="/assets/index.css" rel="stylesheet" type="text/css" /> | ||
| <script crossorigin="anonymous" src="/test-harness.js"></script> | ||
| <script crossorigin="anonymous" src="/test-page-object.js"></script> | ||
| <script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script> | ||
| </head> | ||
| <body> | ||
| <main id="webchat"></main> | ||
| <script> | ||
| run( | ||
| async function () { | ||
| const { directLine, store } = testHelpers.createDirectLineEmulator(); | ||
|
|
||
| WebChat.renderWebChat( | ||
| { | ||
| directLine, | ||
| store, | ||
| styleOptions: { | ||
| sendTimeout: 20000 | ||
| } | ||
| }, | ||
| document.getElementById('webchat') | ||
| ); | ||
|
|
||
| await pageConditions.uiConnected(); | ||
|
|
||
| const { disconnect, flush } = pageObjects.observeLiveRegion(); | ||
|
|
||
| try { | ||
| // Emulate outgoing activity but do not acknowledge it, keeping it in "sending" state. | ||
| await directLine.emulateOutgoingActivity('Hello, World!'); | ||
|
|
||
| const liveRegionText = []; | ||
|
|
||
| await pageConditions.became( | ||
| 'live region narrated sending message', | ||
| () => { | ||
| try { | ||
| liveRegionText.push(...flush()); | ||
|
|
||
| expect(liveRegionText).toContain('Sending message.'); | ||
|
|
||
| return true; | ||
| } catch (err) { | ||
| return false; | ||
| } | ||
| }, | ||
| 4000 | ||
| ); | ||
| } finally { | ||
| disconnect(); | ||
| } | ||
| }, | ||
| { ignoreErrors: true } | ||
| ); | ||
| </script> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { default as useIsSending } from '../providers/ActivitySendStatus/useIsSending'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
packages/api/src/providers/ActivitySendStatus/private/SubContext.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import { createContext, useContext } from 'react'; | ||
|
|
||
| // Smaller context for lesser chance of update. | ||
| type ActivitySendStatusSubContextType = { | ||
| readonly isSendingState: readonly [boolean]; | ||
| }; | ||
|
|
||
| const ActivitySendStatusSubContext = createContext<ActivitySendStatusSubContextType>( | ||
| new Proxy({} as ActivitySendStatusSubContextType, { | ||
| get() { | ||
| throw new Error('botframework-webchat internal: This hook can only be used under <ActivitySendStatusComposer>.'); | ||
| } | ||
| }) | ||
| ); | ||
|
|
||
| function useActivitySendStatusSubContext(): ActivitySendStatusSubContextType { | ||
| return useContext(ActivitySendStatusSubContext); | ||
| } | ||
|
|
||
| export default ActivitySendStatusSubContext; | ||
|
|
||
| export { useActivitySendStatusSubContext, type ActivitySendStatusSubContextType }; |
10 changes: 10 additions & 0 deletions
10
packages/api/src/providers/ActivitySendStatus/useIsSending.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { useActivitySendStatusSubContext } from './private/SubContext'; | ||
|
|
||
| /** | ||
| * Returns `true` if there is at least one outgoing activity currently in the `"sending"` state, otherwise `false`. | ||
| * | ||
| * Note: presentational activities (e.g. event activity or message activity without visible contents) are excluded. | ||
| */ | ||
| export default function useIsSending(): readonly [boolean] { | ||
| return useActivitySendStatusSubContext().isSendingState; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { hooks } from 'botframework-webchat-api'; | ||
| import { memo, useEffect, useState } from 'react'; | ||
|
|
||
| import { useLiveRegion } from '../../providers/LiveRegionTwin'; | ||
|
|
||
| const { useIsSending, useLocalizer, usePonyfill } = hooks; | ||
|
|
||
| const SENDING_ANNOUNCEMENT_INTERVAL = 3_000; | ||
|
|
||
| /** | ||
| * React component to narrate "Sending message." into the live region repeatedly every 3 seconds, | ||
| * but only while there are outgoing activities stuck in the `sending` state with none timed out. | ||
| * | ||
| * Fast sends (acknowledged by the server within 3 seconds) stay silent to avoid noisy | ||
| * announcements. Slow or stalled sends get narrated so the user knows what is happening. | ||
| */ | ||
| const LiveRegionLongSend = () => { | ||
| const [{ clearInterval, setInterval }] = usePonyfill(); | ||
| const [isSending] = useIsSending(); | ||
| const localize = useLocalizer(); | ||
|
|
||
| const liveRegionSendSendingAlt = localize('TRANSCRIPT_LIVE_REGION_SEND_SENDING_ALT'); | ||
|
|
||
| // Invalidate will queue the announcement. | ||
| const [tick, setTick] = useState<object | undefined>(); | ||
|
|
||
| useEffect(() => { | ||
| if (!isSending) { | ||
| return; | ||
| } | ||
|
|
||
| const interval = setInterval(() => setTick({}), SENDING_ANNOUNCEMENT_INTERVAL); | ||
|
|
||
| return () => clearInterval(interval); | ||
| }, [clearInterval, isSending, setInterval]); | ||
|
|
||
| useLiveRegion(() => (tick ? liveRegionSendSendingAlt : false), [liveRegionSendSendingAlt, tick]); | ||
|
|
||
| return null; | ||
| }; | ||
|
|
||
| LiveRegionLongSend.displayName = 'LiveRegionLongSend'; | ||
|
|
||
| export default memo(LiveRegionLongSend); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...Transcript/LiveRegion/isPresentational.ts → packages/core/src/utils/isPresentational.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the wording “screen reader” → “screen readers” for grammatical correctness in the translator comment.