Skip to content

Commit

Permalink
bug/9210-SMiOSScreenReader (#9509)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Alexander <[email protected]>
  • Loading branch information
Sparowhawk and alexandec authored Sep 27, 2024
1 parent 712d9c0 commit 9fce707
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { NAMESPACE } from 'constants/namespaces'
import { bytesToFinalSizeDisplay, bytesToFinalSizeDisplayA11y } from 'utils/common'
import { getFormattedDateAndTimeZone } from 'utils/formattingUtils'
import { useIsScreenReaderEnabled, useTheme } from 'utils/hooks'
import { useIsScreenReaderEnabled, useOrientation, useTheme } from 'utils/hooks'
import { fixSpecialCharacters } from 'utils/jsonFormatting'
import { getLinkifiedText } from 'utils/secureMessaging'

Expand All @@ -38,6 +38,7 @@ export type ThreadMessageProps = {
function CollapsibleMessage({ message, isInitialMessage, collapsibleMessageRef }: ThreadMessageProps) {
const theme = useTheme()
const isFocused = useIsFocused()
const isPortrait = useOrientation()
const { t } = useTranslation(NAMESPACE.COMMON)
const { t: tFunction } = useTranslation()
const { condensedMarginBetween } = theme.dimensions
Expand Down Expand Up @@ -104,7 +105,7 @@ function CollapsibleMessage({ message, isInitialMessage, collapsibleMessageRef }
/** this does preserve newline characters just not spaces
* TODO: change the mobile body link text views to be clickable and launch the right things */
if (body) {
return getLinkifiedText(fixSpecialCharacters(body), t)
return getLinkifiedText(fixSpecialCharacters(body), t, isPortrait)
}
return <></>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { DemoState } from 'store/slices/demoSlice'
import { logAnalyticsEvent } from 'utils/analytics'
import { bytesToFinalSizeDisplay, bytesToFinalSizeDisplayA11y } from 'utils/common'
import { getFormattedDateAndTimeZone } from 'utils/formattingUtils'
import { useRouteNavigation, useTheme } from 'utils/hooks'
import { useOrientation, useRouteNavigation, useTheme } from 'utils/hooks'
import { fixSpecialCharacters } from 'utils/jsonFormatting'
import { formatSubject, getLinkifiedText } from 'utils/secureMessaging'

Expand All @@ -29,6 +29,7 @@ export type MessageCardProps = {
function MessageCard({ message }: MessageCardProps) {
const theme = useTheme()
const { t: t } = useTranslation(NAMESPACE.COMMON)
const isPortrait = useOrientation()
const { t: tFunction } = useTranslation()
const { hasAttachments, attachment, attachments, senderName, sentDate, body, subject, category } = message
const dateTime = getFormattedDateAndTimeZone(sentDate)
Expand Down Expand Up @@ -73,7 +74,7 @@ function MessageCard({ message }: MessageCardProps) {
/** this does preserve newline characters just not spaces
* TODO: change the mobile body link text views to be clickable and launch the right things */
if (body) {
return getLinkifiedText(fixSpecialCharacters(body), t)
return getLinkifiedText(fixSpecialCharacters(body), t, isPortrait)
}
return <></>
}
Expand Down
99 changes: 74 additions & 25 deletions VAMobile/src/utils/secureMessaging.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { ReactNode } from 'react'
import { Dimensions } from 'react-native'
import DocumentPicker from 'react-native-document-picker'
import { Asset, launchCamera, launchImageLibrary } from 'react-native-image-picker'
import { ImagePickerResponse } from 'react-native-image-picker/src/types'
Expand Down Expand Up @@ -474,7 +475,7 @@ export const saveDraftWithAttachmentAlert = (
}
}

export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
export const getLinkifiedText = (body: string, t: TFunction, isPortrait: boolean): ReactNode => {
const textReconstructedBody: Array<ReactNode> = []
const bodySplit = body.split(/\s/).filter((value) => value !== '')
const whiteSpace = body
Expand All @@ -483,22 +484,31 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
.reverse()
.filter((value) => value !== '')
let dontAddNextString = false
let savedText = ''
_.forEach(bodySplit, (text, index) => {
if (dontAddNextString) {
//if previous entry was a phone number with xxx xxx xxxx format need to not add xxxx again
dontAddNextString = false
return
}

let nonWhiteSpaceCheck = savedText.split(/\s/).filter((value) => value !== '').length > 0
if (index !== 0 && index !== bodySplit.length - 1) {
//phone number with spaces xxx xxx xxxx format
const previousText = bodySplit[index - 1]
const nextText = bodySplit[index + 1]
const testString = previousText + ' ' + text + ' ' + nextText
const phoneMatch = PHONE_REGEX_EXP.exec(testString)
if (phoneMatch) {
textReconstructedBody.pop()
textReconstructedBody.pop()
if (savedText.length > 3) {
savedText = savedText.slice(0, savedText.length - 4)
}
nonWhiteSpaceCheck = savedText.split(/\s/).filter((value) => value !== '').length > 0
textReconstructedBody.push(
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<LinkWithAnalytics
type="call"
Expand All @@ -510,7 +520,7 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
a11yHint={t('openInPhoneMessaging.a11yHint')}
/>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
dontAddNextString = true
return
}
Expand All @@ -523,6 +533,12 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
const url2Match = URL2_REGEX_EXP.exec(text)
if (emailMatch) {
//matches <email address> only
textReconstructedBody.push(
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<LinkWithAnalytics
type="url"
Expand All @@ -534,9 +550,15 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
a11yHint={t('openInEmailMessaging.a11yHint')}
/>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
} else if (mailToMatch) {
// matches mailto:<email address>
textReconstructedBody.push(
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<LinkWithAnalytics
type="url"
Expand All @@ -548,9 +570,15 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
a11yHint={t('openInEmailMessaging.a11yHint')}
/>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
} else if (phoneMatch) {
// matches 8006982411 800-698-2411 1-800-698-2411 (800)698-2411 (800)-698-2411 +8006982411 +18006982411
textReconstructedBody.push(
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<LinkWithAnalytics
type="call"
Expand All @@ -562,25 +590,38 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
a11yHint={t('openInPhoneMessaging.a11yHint')}
/>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
} else if (urlMatch) {
// matches any https, http url
textReconstructedBody.push(<TextView variant="MobileBody">{'\n'}</TextView>)
textReconstructedBody.push(
<LinkWithAnalytics
type="url"
url={text}
text={text}
icon="no icon"
disablePadding={true}
a11yLabel={text}
a11yHint={t('openInBrowser.a11yHint')}
/>,
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<Box minWidth={isPortrait ? Dimensions.get('window').width : Dimensions.get('window').height}>
<LinkWithAnalytics
type="url"
url={text}
text={text}
icon="no icon"
disablePadding={true}
a11yLabel={text}
a11yHint={t('openInBrowser.a11yHint')}
/>
</Box>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
} else if (url2Match) {
// matches links like www.gooog.com or google.com (limit is 2 or 3 characters after the . to turn it
// into a link - may need to update this if we need to include other domains greater than 3 digits)
textReconstructedBody.push(
<TextView accessible={nonWhiteSpaceCheck} selectable={nonWhiteSpaceCheck} variant="MobileBody">
{savedText}
</TextView>,
)
savedText = ''
textReconstructedBody.push(
<LinkWithAnalytics
type="url"
Expand All @@ -592,17 +633,25 @@ export const getLinkifiedText = (body: string, t: TFunction): ReactNode => {
a11yHint={t('openInBrowser.a11yHint')}
/>,
)
textReconstructedBody.push(<TextView variant="MobileBody">{whiteSpace.pop() || ''}</TextView>)
savedText += whiteSpace.pop() || ''
} else {
const spacing = whiteSpace.pop() || ''
textReconstructedBody.push(<TextView variant="MobileBody">{text + spacing}</TextView>)
savedText += text + spacing
}
})

if (savedText.length > 0 && savedText.split(/\s/).filter((value) => value !== '').length > 0) {
//prohibits whitespace only being added to the end after a link
textReconstructedBody.push(
<TextView selectable={true} variant="MobileBody">
{savedText}
</TextView>,
)
}

return (
<Box>
<TextView selectable={true} paragraphSpacing={true}>
{textReconstructedBody}
</TextView>
<Box mb={theme.paragraphSpacing.spacing20FontSize} flexDirection="row" flexWrap="wrap">
{textReconstructedBody}
</Box>
)
}

0 comments on commit 9fce707

Please sign in to comment.