Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 17 additions & 27 deletions app/containers/RoomHeader/RoomHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { AccessibilityInfo, findNodeHandle, StyleSheet, Text, useWindowDimensions, View } from 'react-native';
import { StyleSheet, Text, useWindowDimensions, View } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { KeyboardFocusView } from 'react-native-external-keyboard';

import { useResponsiveLayout } from '../../lib/hooks/useResponsiveLayout/useResponsiveLayout';
import { useIsAccessibilityNavigationEnabled } from '../../lib/hooks/useIsAccessibilityNavigationEnabled';
import I18n from '../../i18n';
import sharedStyles from '../../views/Styles';
import { MarkdownPreview } from '../markdown';
Expand Down Expand Up @@ -83,13 +85,7 @@ interface IRoomHeader {
abacAttributes?: ISubscription['abacAttributes'];
}

type IRoomHeaderProps = IRoomHeader & {
ref?: React.Ref<IRoomHeaderRef>;
};

export interface IRoomHeaderRef {
focus: () => void;
}
type IRoomHeaderProps = IRoomHeader;

const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => {
const { colors } = useTheme();
Expand Down Expand Up @@ -157,25 +153,10 @@ const Header = ({
usersTyping = [],
sourceType,
disabled,
abacAttributes,
ref
abacAttributes
}: IRoomHeaderProps) => {
'use memo';

const headerRef = React.useRef<View | null>(null);
React.useImperativeHandle(
ref,
() => ({
focus: () => {
const nodeHandle = headerRef.current ? findNodeHandle(headerRef.current) : null;
if (nodeHandle) {
AccessibilityInfo.setAccessibilityFocus(nodeHandle);
}
}
}),
[]
);

const statusAccessibilityLabel = useStatusAccessibilityLabel({
isGroupChat,
prid,
Expand All @@ -189,6 +170,9 @@ const Header = ({
const portrait = height > width;
let scale = 1;
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
// Only move focus to the header for accessibility navigation (screen reader or physical
// keyboard); regular touch users shouldn't have focus yanked onto the header on room open.
const autoFocusHeader = useIsAccessibilityNavigationEnabled();
const subtitleAccessibilityLabel = tmid ? parentTitle : subtitle;
const accessibilityLabel = `${statusAccessibilityLabel} ${title} ${subtitleAccessibilityLabel || ''}.`;

Expand Down Expand Up @@ -220,8 +204,14 @@ const Header = ({
const handleOnPress = () => onPress();

return (
<View
ref={headerRef}
<KeyboardFocusView
// Grab focus natively as soon as the header mounts. This handles master-detail,
// where the room list and room share the screen and focus would otherwise stay on
// the room item, as well as moving screen-reader focus via enableA11yFocus.
autoFocus={autoFocusHeader}
enableA11yFocus={autoFocusHeader}
focusable={!disabled}
canBeFocused={!disabled}
style={[styles.container, { opacity: disabled ? 0.5 : 1, height: 36.9 * fontScale }]}
accessible
accessibilityLabel={accessibilityLabel}
Expand All @@ -243,7 +233,7 @@ const Header = ({
</View>
<SubTitle usersTyping={tmid ? [] : usersTyping} subtitle={subtitle} renderFunc={renderFunc} scale={scale} />
</TouchableOpacity>
</View>
</KeyboardFocusView>
);
};

Expand Down
Loading
Loading