Skip to content

Commit

Permalink
feat: add screen for accessibility settings WIP
Browse files Browse the repository at this point in the history
Refs #368
  • Loading branch information
lpezzolla committed Nov 21, 2023
1 parent 9f98786 commit 56bd5a9
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 18 deletions.
12 changes: 12 additions & 0 deletions assets/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
{
"accessibilitySettingsScreen": {
"title": "Accessibility settings",
"customFontTitle": "Custom font",
"customFontAction": "Pick a font",
"customFontPlacement": "Use it for",
"themeCustomizationTitle": "Theme customization",
"customFontSectionTitle": "Accessible font",
"customThemeSectionTitle": "Accessible theme",
"highContrastTitle": "High contrast",
"greyscaleTitle": "Greyscale"
},
"agendaScreen": {
"backToToday": "Back to today",
"dailyLayout": "Daily layout",
Expand Down Expand Up @@ -73,6 +84,7 @@
"yellow": "Yellow"
},
"common": {
"accessibility": "Accessibility",
"actionPotentiallyNotUndoable": "This action may not be undoable",
"activeStatus": {
"false": "Non active",
Expand Down
12 changes: 12 additions & 0 deletions assets/translations/it.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
{
"accessibilitySettingsScreen": {
"title": "Impostazioni di accessibilità",
"customFontTitle": "Font personalizzato",
"customFontDefault": "No custom font",
"customFontAction": "Seleziona un font",
"customFontPlacement": "Usalo per",
"customFontSectionTitle": "Font accessibile",
"customThemeSectionTitle": "Tema accessibile",
"highContrastTitle": "Alto contrasto",
"greyscaleTitle": "Scala di grigi"
},
"agendaScreen": {
"backToToday": "Torna a oggi",
"dailyLayout": "Layout giornaliero",
Expand Down Expand Up @@ -73,6 +84,7 @@
"yellow": "Giallo"
},
"common": {
"accessibility": "Accessibilità",
"actionPotentiallyNotUndoable": "Questa azione potrebbe non essere annullabile",
"activeStatus": {
"false": "Non attiva",
Expand Down
3 changes: 1 addition & 2 deletions lib/ui/components/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
StyleProp,
TextProps,
TextStyle,
TouchableHighlight,
TouchableHighlightProps,
Expand All @@ -20,7 +19,7 @@ import { GlobalStyles } from '../../../src/core/styles/GlobalStyles';
import { resolveLinkTo } from '../../../src/utils/resolveLinkTo';
import { useTheme } from '../hooks/useTheme';
import { DisclosureIndicator } from './DisclosureIndicator';
import { Text } from './Text';
import { Text, TextProps } from './Text';

export interface ListItemProps extends TouchableHighlightProps {
title: string | JSX.Element;
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/components/Metric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { View, ViewProps } from 'react-native';

import { useTheme } from '../hooks/useTheme';
import { CardProps } from './Card';
import { Text, Props as TextProps } from './Text';
import { Text, TextProps } from './Text';

type Props = ViewProps & {
title: string;
Expand Down
10 changes: 7 additions & 3 deletions lib/ui/components/Text.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Text as RNText, StyleSheet, TextProps } from 'react-native';
import {
Text as RNText,
TextProps as RNTextProps,
StyleSheet,
} from 'react-native';

import { useStylesheet } from '../hooks/useStylesheet';
import { useTheme } from '../hooks/useTheme';
import { Theme } from '../types/Theme';

export interface Props extends TextProps {
export interface TextProps extends RNTextProps {
variant?:
| 'heading'
| 'subHeading'
Expand Down Expand Up @@ -45,7 +49,7 @@ export const Text = ({
uppercase,
children,
...rest
}: Props) => {
}: TextProps) => {
const { colors, fontFamilies, fontWeights } = useTheme();
const styles = useStylesheet(createStyles);
const fontFamilyName =
Expand Down
32 changes: 20 additions & 12 deletions src/core/contexts/PreferencesContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,37 @@ import { AgendaTypesFilterState } from '../../features/agenda/types/AgendaTypesF
import { UnreadNotifications } from '../types/notifications';

export const editablePreferenceKeys = [
'lastInstalledVersion',
'username',
'accessibility',
'agendaScreen',
'campusId',
'colorScheme',
'courses',
'emailGuideRead',
'favoriteServices',
'language',
'lastInstalledVersion',
'notifications',
'favoriteServices',
'peopleSearched',
'unreadNotifications',
'onboardingStep',
'emailGuideRead',
'peopleSearched',
'placesSearched',
'agendaScreen',
'unreadNotifications',
'username',
] as const;

export type PreferenceKey = typeof editablePreferenceKeys[number];

// Specify here complex keys, that require serialization/deserialization
export const objectPreferenceKeys = [
'accessibility',
'agendaScreen',
'courses',
'notifications',
'emailGuideRead',
'favoriteServices',
'peopleSearched',
'unreadNotifications',
'notifications',
'onboardingStep',
'emailGuideRead',
'peopleSearched',
'placesSearched',
'agendaScreen',
'unreadNotifications',
];

export type CoursesPreferences = {
Expand Down Expand Up @@ -74,6 +76,12 @@ export interface PreferencesContextBase {
layout: 'weekly' | 'daily';
filters: AgendaTypesFilterState;
};
accessibility?: {
fontFamily?: 'default' | 'open-dyslexic';
fontPlacement?: 'default' | 'bottom';
highContrast?: boolean;
grayscale?: boolean;
};
}

export interface PreferencesContextProps extends PreferencesContextBase {
Expand Down
10 changes: 10 additions & 0 deletions src/features/user/components/UserNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTitlesStyles } from '../../../core/hooks/useTitlesStyles';
import { SharedScreens } from '../../../shared/navigation/SharedScreens';
import { DegreeTopTabsNavigator } from '../../offering/navigation/DegreeTopTabsNavigator';
import { OfferingStackParamList } from '../../services/components/ServicesNavigator';
import { AccessibilitySettingsScreen } from '../screens/AccessibilitySettingsScreen';
import { MessageScreen } from '../screens/MessageScreen';
import { MessagesScreen } from '../screens/MessagesScreen';
import { ProfileScreen } from '../screens/ProfileScreen';
Expand All @@ -17,6 +18,7 @@ import { SettingsScreen } from '../screens/SettingsScreen';
export type UserStackParamList = OfferingStackParamList & {
Profile: undefined;
Settings: undefined;
AccessibilitySettings: undefined;
Messages: undefined;
Message: {
id: number;
Expand Down Expand Up @@ -59,6 +61,14 @@ export const UserNavigator = () => {
headerTitle: t('settingsScreen.title'),
}}
/>
<Stack.Screen
name="AccessibilitySettings"
component={AccessibilitySettingsScreen}
options={{
headerTitle: t('accessibilitySettingsScreen.title'),
headerBackTitleVisible: false,
}}
/>
<Stack.Screen
name="Messages"
component={MessagesScreen}
Expand Down
160 changes: 160 additions & 0 deletions src/features/user/screens/AccessibilitySettingsScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { useMemo } from 'react';
import { TFunction, useTranslation } from 'react-i18next';
import { SafeAreaView, ScrollView } from 'react-native';

import { Col } from '@lib/ui/components/Col';
import { ListItem } from '@lib/ui/components/ListItem';
import { OverviewList } from '@lib/ui/components/OverviewList';
import { Section } from '@lib/ui/components/Section';
import { SectionHeader } from '@lib/ui/components/SectionHeader';
import { SwitchListItem } from '@lib/ui/components/SwitchListItem';
import { MenuAction, MenuView } from '@react-native-menu/menu';

import { BottomBarSpacer } from '../../../core/components/BottomBarSpacer';
import { usePreferencesContext } from '../../../core/contexts/PreferencesContext';

interface AccessibilityItemProps {
t: TFunction;
value?: string;
// onUpdate: (value: string) => void;
}

export const AccessibilitySettingsScreen = () => {
const { t } = useTranslation();
const { accessibility } = usePreferencesContext();

return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<SafeAreaView>
<Col pv={5}>
<Section>
<SectionHeader
title={t('accessibilitySettingsScreen.customFontSectionTitle')}
/>
<OverviewList indented>
<CustomFontListItem t={t} value={accessibility?.fontFamily} />
<CustomFontPlacementListItem
t={t}
value={accessibility?.fontPlacement}
/>
</OverviewList>
</Section>
<Section>
<SectionHeader
title={t('accessibilitySettingsScreen.customThemeSectionTitle')}
/>
<OverviewList indented>
<SwitchListItem
title={t('accessibilitySettingsScreen.highContrastTitle')}
value={accessibility?.highContrast ?? true}
onChange={value => {
// TODO
}}
/>
<SwitchListItem
title={t('accessibilitySettingsScreen.greyscaleTitle')}
value={accessibility?.grayscale ?? false}
onChange={value => {
// TODO
}}
/>
</OverviewList>
</Section>
</Col>
<BottomBarSpacer />
</SafeAreaView>
</ScrollView>
);
};

const CustomFontListItem = ({ t, value }: AccessibilityItemProps) => {
const choices = useMemo(() => {
return [
'Montserrat (default)',
'Open Dyslexic',
'Dyslexie',
'EasyReading',
'Sylexiad',
];
}, []);

const effectiveValue = useMemo(() => {
return value || 'default';
}, [value]);

const actions: MenuAction[] = useMemo(() => {
return choices.map(cc => {
const actionValue = cc.endsWith('(default)') ? 'default' : cc;
return {
id: actionValue,
title: cc,
state: actionValue === effectiveValue ? 'on' : undefined,
};
});
}, [effectiveValue, choices]);

return (
<MenuView
title={t(`accessibilitySettingsScreen.customFontAction`)}
actions={actions}
onPressAction={({ nativeEvent: { event } }) => {
// onUpdate(effectiveValue);
}}
>
<ListItem
isAction
title={t(`accessibilitySettingsScreen.customFontTitle`)}
subtitle="Montserrat (default)"
/* TODO accessibilityLabel={`${t('common.language')}: ${t(
`common.${language}`,
)}. ${t('settingsScreen.openLanguageMenu')}`}*/
/>
</MenuView>
);
};

const CustomFontPlacementListItem = ({ t, value }: AccessibilityItemProps) => {
const choices = useMemo(() => {
// places in which to use the custom font for accessibility
return ['None', 'Long text', 'All text'];
}, []);

const effectiveValue = useMemo(() => {
return value || 'none';
}, [value]);

const effectiveLabel = useMemo(() => {
return effectiveValue.replace('-', ' ');
}, [effectiveValue]);

const actions: MenuAction[] = useMemo(() => {
return choices.map(cc => {
const choiceId = cc.toLowerCase().replace(' ', '-');
return {
id: choiceId,
title: cc,
state: choiceId === effectiveValue ? 'on' : undefined,
};
});
}, [effectiveValue, choices]);

return (
<MenuView
title={t(`accessibilitySettingsScreen.customFontPlacement`)}
actions={actions}
onPressAction={({ nativeEvent: { event } }) => {
// onUpdate(effectiveValue);
}}
>
<ListItem
isAction
title={t(`accessibilitySettingsScreen.customFontPlacement`)}
subtitle={effectiveLabel}
subtitleProps={{ capitalize: true }}
/* TODO accessibilityLabel={`${t('common.language')}: ${t(
`common.${language}`,
)}. ${t('settingsScreen.openLanguageMenu')}`}*/
/>
</MenuView>
);
};
11 changes: 11 additions & 0 deletions src/features/user/screens/SettingsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,17 @@ export const SettingsScreen = () => {
<CleanCacheListItem />
</OverviewList>
</Section>
<Section>
<SectionHeader title={t('common.accessibility')} />
<OverviewList indented>
<ListItem
isAction
title={t('accessibilitySettingsScreen.title')}
accessibilityRole="button"
linkTo={{ screen: 'AccessibilitySettings' }}
/>
</OverviewList>
</Section>
<Col ph={4}>
<Text>{t('settingsScreen.appVersion', { version })}</Text>
</Col>
Expand Down

0 comments on commit 56bd5a9

Please sign in to comment.