Skip to content
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

2173: Send language to iOS VoiceOver #2910

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
7 changes: 6 additions & 1 deletion native/src/components/Caption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ const H1 = styled(Text)`
`
type CaptionProps = {
title: string
language?: string
}

const Caption = ({ title }: CaptionProps): ReactElement => <H1 android_hyphenationFrequency='full'>{title}</H1>
const Caption = ({ title, language }: CaptionProps): ReactElement => (
<H1 android_hyphenationFrequency='full' accessibilityLanguage={language}>
{title}
</H1>
)

export default Caption
2 changes: 1 addition & 1 deletion native/src/components/CategoryListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const CategoryListItem = ({
onItemPress,
}: CategoryListItemProps): ReactElement => (
<>
<FlexStyledLink role='link' onPress={() => onItemPress({ path: category.path })}>
<FlexStyledLink role='link' onPress={() => onItemPress({ path: category.path })} accessibilityLanguage={language}>
<DirectionContainer language={language}>
<CategoryEntryContainer>
<TitleDirectionContainer language={language}>
Expand Down
10 changes: 8 additions & 2 deletions native/src/components/CityEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { Fragment, memo, ReactElement } from 'react'
import React, { Fragment, memo, ReactElement, useContext } from 'react'
import { Text } from 'react-native'
import Highlighter from 'react-native-highlight-words'
import styled from 'styled-components/native'

import { normalizeString } from 'shared'
import { CityModel } from 'shared/api'

import { AppContext } from '../contexts/AppContextProvider'
import testID from '../testing/testID'
import Pressable from './base/Pressable'

Expand Down Expand Up @@ -52,6 +53,7 @@ const CityEntry = ({ city, query, navigateToDashboard }: CityEntryProps): ReactE
? Object.keys(city.aliases).filter(alias => normalizeString(alias).includes(normalizedQuery))
: []
const aliases = matchingAliases.slice(0, MAX_NUMBER_OF_ALIASES_SHOWN)
const { languageCode } = useContext(AppContext)

const Aliases =
aliases.length > 0 ? (
Expand Down Expand Up @@ -86,7 +88,11 @@ const CityEntry = ({ city, query, navigateToDashboard }: CityEntryProps): ReactE
) : null

return (
<CityListItem role='link' {...testID('City-Entry')} onPress={() => navigateToDashboard(city)}>
<CityListItem
role='link'
{...testID('City-Entry')}
onPress={() => navigateToDashboard(city)}
accessibilityLanguage={languageCode}>
<>
<Label
searchWords={[normalizedQuery]}
Expand Down
30 changes: 24 additions & 6 deletions native/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactElement, useContext, useState } from 'react'

Check warning on line 1 in native/src/components/Header.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Overall Code Complexity

This module has a mean cyclomatic complexity of 4.11 across 9 functions. The mean complexity threshold is 4. This file has many conditional statements (e.g. if, for, while) across its implementation, leading to lower code health. Avoid adding more conditionals.
import { useTranslation } from 'react-i18next'
import { Share } from 'react-native'
import { HiddenItem, Item } from 'react-navigation-header-buttons'
Expand All @@ -20,6 +20,7 @@
SETTINGS_ROUTE,
} from 'shared'
import { LanguageModel, FeedbackRouteType } from 'shared/api'
import { config } from 'translations'

import { NavigationProps, RouteProps, RoutesParamsType, RoutesType } from '../constants/NavigationTypes'
import buildConfig from '../constants/buildConfig'
Expand Down Expand Up @@ -199,32 +200,49 @@
]
: []

const getHeaderText = (): string => {
const getHeaderText = (): { text: string; language?: string } => {
const currentTitle = (route.params as { title?: string } | undefined)?.title
if (!previousRoute) {
// Home/Dashboard: Show current route title, i.e. city name
return currentTitle ?? ''
return { text: currentTitle ?? '', language: config.sourceLanguage }
}

const previousParams = previousRoute.params

const currentRouteIsPoi = route.name === POIS_ROUTE
const notFromDeepLink = previousRoute.name === POIS_ROUTE
if (currentRouteIsPoi && notFromDeepLink) {
const poisRouteParams = route.params as RoutesParamsType[PoisRouteType]
if (poisRouteParams.slug || poisRouteParams.multipoi !== undefined) {
return t('locations')
return { text: t('locations'), language: undefined } // system language
}
}

const previousRouteTitle = (previousParams as { title?: string } | undefined)?.title
return previousRouteTitle ?? t(previousRoute.name === 'categories' ? 'localInformation' : previousRoute.name)
const previousRouteTitle = (previousParams as { path?: string } | undefined)?.path

if (previousRouteTitle) {
return { text: previousRouteTitle, language: languageCode }
}

if (previousRoute.name === CATEGORIES_ROUTE) {
return {
text: t('localInformation'),
language: previousRouteTitle === undefined ? config.sourceLanguage : languageCode,
}
}

return { text: previousRoute.name, language: undefined } // system language

Check warning on line 234 in native/src/components/Header.tsx

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Complex Method

Header.getHeaderText has a cyclomatic complexity of 11, threshold = 10. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Feel free to fix this CodeScene issue, if you are motivated.

}

return (
<BoxShadow>
<Horizontal>
<HeaderBox goBack={navigation.goBack} canGoBack={canGoBack} text={getHeaderText()} />
<HeaderBox
goBack={navigation.goBack}
canGoBack={canGoBack}
text={getHeaderText().text}
language={getHeaderText().language}
/>
<CustomHeaderButtons cancelLabel={t('cancel')} items={items} overflowItems={overflowItems} />
</Horizontal>
</BoxShadow>
Expand Down
9 changes: 7 additions & 2 deletions native/src/components/HeaderBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ type HeaderBoxProps = {
goBack?: () => void
canGoBack?: boolean
text?: string
language?: string
}

const HeaderBox = ({ goBack, canGoBack = true, text }: HeaderBoxProps): ReactElement => {
const HeaderBox = ({ goBack, canGoBack = true, text, language }: HeaderBoxProps): ReactElement => {
const deviceWidth = useWindowDimensions().width
const theme = useTheme()
const { t } = useTranslation('common')
Expand All @@ -49,10 +50,14 @@ const HeaderBox = ({ goBack, canGoBack = true, text }: HeaderBoxProps): ReactEle
) : (
<StyledIcon Icon={AppIcon} />
)

return (
<HorizontalLeft>
{HeaderIcon}
<HeaderText allowFontScaling={false} fontSize={deviceWidth * dimensions.fontScaling}>
<HeaderText
allowFontScaling={false}
fontSize={deviceWidth * dimensions.fontScaling}
accessibilityLanguage={language}>
{text}
</HeaderText>
</HorizontalLeft>
Expand Down
2 changes: 1 addition & 1 deletion native/src/components/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type ListItemProps = {
}

const ListItem = ({ language, title, thumbnail, children, Icon, navigateTo }: ListItemProps): ReactElement => (
<StyledPressable onPress={navigateTo} role='link'>
<StyledPressable onPress={navigateTo} accessibilityLanguage={language} role='link'>
<ListItemView language={language}>
<Thumbnail source={thumbnail} />
<Description>
Expand Down
8 changes: 6 additions & 2 deletions native/src/components/NewsListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { LocalNewsModel, TunewsModel } from 'shared/api'
import { ArrowBackIcon } from '../assets'
import { EXCERPT_MAX_LINES } from '../constants'
import { contentDirection } from '../constants/contentDirection'
import { useAppContext } from '../hooks/useCityAppContext'
import TimeStamp from './TimeStamp'
import Icon from './base/Icon'
import Pressable from './base/Pressable'
Expand Down Expand Up @@ -81,12 +82,13 @@ export const ReadMore = styled(Text)<{ isTunews: boolean }>`
const NewsListItem = ({ index, newsItem, navigateToNews, isTunews }: NewsListItemProps): ReactElement => {
const { t, i18n } = useTranslation('news')
const timestamp = newsItem instanceof LocalNewsModel ? newsItem.timestamp : null
const { languageCode } = useAppContext()

return (
<>
<Divider firstItem={index === 0} />
<ListItemWrapper>
<StyledPressable onPress={navigateToNews} role='link'>
<StyledPressable onPress={navigateToNews} accessibilityLanguage={languageCode} role='link'>
<Description>
<Title>{newsItem.title}</Title>
<Content numberOfLines={EXCERPT_MAX_LINES}>{newsItem.content}</Content>
Expand All @@ -96,11 +98,13 @@ const NewsListItem = ({ index, newsItem, navigateToNews, isTunews }: NewsListIte
</TimeStampContent>
)}
</Description>
</StyledPressable>
<Pressable role='link' onPress={navigateToNews}>
<ReadMoreWrapper language={i18n.language}>
<ReadMore isTunews={isTunews} onPress={navigateToNews}>{`${t('readMore')}`}</ReadMore>
<StyledIcon Icon={ArrowBackIcon} directionDependent reverse isTunews={isTunews} />
</ReadMoreWrapper>
</StyledPressable>
</Pressable>
</ListItemWrapper>
</>
)
Expand Down
2 changes: 1 addition & 1 deletion native/src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const Page = ({

return (
<Container $padding={padding}>
{!loading && title ? <Caption title={title} /> : null}
{!loading && title ? <Caption title={title} language={language} /> : null}
{!loading && BeforeContent}
<RemoteContent
content={content}
Expand Down
6 changes: 5 additions & 1 deletion native/src/components/SearchListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ const SearchListItem = ({
)

return (
<FlexStyledLink onPress={navigateToSearchResult} role='link' accessibilityHint={t('itemHint')}>
<FlexStyledLink
onPress={navigateToSearchResult}
role='link'
accessibilityHint={t('itemHint')}
accessibilityLanguage={language}>
<DirectionContainer language={language}>
<SearchEntryContainer>
<TitleDirectionContainer language={language}>
Expand Down
6 changes: 5 additions & 1 deletion native/src/components/SubCategoryListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ const SubCategoryListItem = ({
onItemPress,
language,
}: SubCategoryListItemProps): ReactElement => (
<FlexStyledLink onPress={() => onItemPress(subCategory)} language={language} role='link'>
<FlexStyledLink
onPress={() => onItemPress(subCategory)}
language={language}
role='link'
accessibilityLanguage={language}>
<SubCategoryTitleContainer language={language}>
{!!subCategory.thumbnail && (
<CategoryThumbnail language={language} source={subCategory.thumbnail} resourceCache={resourceCache} />
Expand Down
5 changes: 3 additions & 2 deletions native/src/components/Tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ type TileProps = {
tile: TileModel
onTilePress: (tile: TileModel) => void
resourceCache: PageResourceCacheStateType | undefined
language: string
}

const Tile = ({ onTilePress, tile, resourceCache }: TileProps): ReactElement => {
const Tile = ({ onTilePress, tile, resourceCache, language }: TileProps): ReactElement => {
const showSnackbar = useSnackbar()
const openTile = () =>
tile.isExternalUrl ? openExternalUrl(tile.path, showSnackbar).catch(reportError) : onTilePress(tile)

return (
<TileContainer onPress={openTile} role='link'>
<TileContainer onPress={openTile} role='link' accessibilityLanguage={language}>
<Thumbnail source={tile.thumbnail} resourceCache={resourceCache} />
<TileTitle android_hyphenationFrequency='full'>{tile.title}</TileTitle>
</TileContainer>
Expand Down
2 changes: 1 addition & 1 deletion native/src/components/Tiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const Tiles = ({ title, language, tiles, onTilePress, resourceCache }: TilesProp
{!!title && <Caption title={title} />}
<TilesRow language={language}>
{tiles.map(tile => (
<Tile key={tile.path} tile={tile} onTilePress={onTilePress} resourceCache={resourceCache} />
<Tile key={tile.path} tile={tile} onTilePress={onTilePress} resourceCache={resourceCache} language={language} />
))}
</TilesRow>
</>
Expand Down
4 changes: 2 additions & 2 deletions native/src/components/__tests__/Tile.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('Tile', () => {
thumbnail: null,
isExternalUrl: false,
})
const { getByText } = render(<Tile tile={tile} onTilePress={onTilePress} resourceCache={{}} />)
const { getByText } = render(<Tile tile={tile} onTilePress={onTilePress} resourceCache={{}} language='' />)
fireEvent.press(getByText(tile.title))

expect(onTilePress).toHaveBeenCalledTimes(1)
Expand All @@ -38,7 +38,7 @@ describe('Tile', () => {
thumbnail: null,
isExternalUrl: true,
})
const { getByText } = render(<Tile tile={tile} onTilePress={onTilePress} resourceCache={{}} />)
const { getByText } = render(<Tile tile={tile} onTilePress={onTilePress} resourceCache={{}} language='' />)
fireEvent.press(getByText(tile.title))

expect(openExternalUrl).toHaveBeenCalledTimes(1)
Expand Down
Loading