Skip to content

Commit 0acc2a3

Browse files
Merge pull request #267 from iteratehq/matt/translations
feat: Handle translations for prompt message and button text
2 parents 3a94c05 + 72b111e commit 0acc2a3

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

src/components/Prompt/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Iterate from '../../iterate';
2323
import markdown from '../../markdown';
2424
import { InteractionEvents } from '../../interaction-events';
2525
import type { InteractionEventSource } from '../../interaction-events';
26+
import { useTranslation } from '../../language';
2627

2728
type Props = {
2829
dispatchShowSurvey: (Survey: Survey) => void;
@@ -147,6 +148,11 @@ const Prompt: (Props: Props) => JSX.Element = ({
147148
: null,
148149
];
149150

151+
const promptText =
152+
useTranslation('survey.prompt.text') ?? survey?.prompt?.message;
153+
const promptButtonText =
154+
useTranslation('survey.prompt.buttonText') ?? survey?.prompt?.button_text;
155+
150156
return (
151157
<Animated.View
152158
style={{
@@ -170,7 +176,7 @@ const Prompt: (Props: Props) => JSX.Element = ({
170176
>
171177
<View style={{ paddingBottom }}>
172178
<CloseButton onPress={onDismissAnimated} survey={survey} />
173-
{markdown.Render(survey?.prompt?.message ?? '', {
179+
{markdown.Render(promptText ?? '', {
174180
body: [
175181
promptTextStyle,
176182
{
@@ -186,11 +192,9 @@ const Prompt: (Props: Props) => JSX.Element = ({
186192
textDecorationLine: 'none',
187193
color: survey?.color ?? '#7457be',
188194
},
189-
}) || (
190-
<Text style={promptTextStyle}>{survey?.prompt?.message ?? ''}</Text>
191-
)}
195+
}) || <Text style={promptTextStyle}>{promptText ?? ''}</Text>}
192196
<PromptButton
193-
text={`${survey?.prompt?.button_text || ''}`}
197+
text={`${promptButtonText || ''}`}
194198
color={`${survey?.color || '#7457be'}`}
195199
colorDark={survey?.color_dark}
196200
onPress={showSurveyButtonClicked}

src/language.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { NativeModules, Platform } from 'react-native';
2+
import type {
3+
Language,
4+
Survey,
5+
TranslationItemKey,
6+
UserTraitsContext,
7+
} from './types';
8+
import { useSelector } from 'react-redux';
9+
import type { State } from './redux';
10+
11+
const availableLanguages = (survey: Survey): Language[] => {
12+
const languages = survey.translations?.map((t) => t.language) ?? [];
13+
if (survey.primary_language) {
14+
languages.unshift(survey.primary_language);
15+
}
16+
17+
return languages;
18+
};
19+
20+
const getPreferredLanguage = (
21+
survey: Survey,
22+
userTraits?: UserTraitsContext
23+
): Language => {
24+
const deviceLanguageWithRegion =
25+
Platform.OS === 'ios'
26+
? NativeModules.SettingsManager.settings.AppleLocale ??
27+
NativeModules.SettingsManager.settings.AppleLanguages[0] // iOS 13
28+
: NativeModules.I18nManager.localeIdentifier;
29+
const deviceLanguage = deviceLanguageWithRegion.substring(0, 2);
30+
31+
const userTraitLanguage = userTraits?.language as Language;
32+
33+
if (
34+
userTraitLanguage != null &&
35+
availableLanguages(survey).includes(userTraitLanguage)
36+
) {
37+
return userTraitLanguage;
38+
}
39+
40+
if (availableLanguages(survey).includes(deviceLanguage)) {
41+
return deviceLanguage;
42+
}
43+
44+
return 'en';
45+
};
46+
47+
const getTranslationForKey = (
48+
key: TranslationItemKey,
49+
survey: Survey,
50+
userTraits?: UserTraitsContext
51+
): string | undefined => {
52+
const language = getPreferredLanguage(survey, userTraits);
53+
const translation = survey.translations?.find((t) => t.language === language);
54+
55+
return translation?.items?.[key]?.text;
56+
};
57+
58+
export const useTranslation = (key: TranslationItemKey) => {
59+
const survey = useSelector((state: State) => state.survey);
60+
const userTraits = useSelector((state: State) => state.userTraits);
61+
if (survey == null) {
62+
return undefined;
63+
}
64+
65+
return getTranslationForKey(key, survey, userTraits);
66+
};

src/types.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,10 @@ export type Survey = {
8989
color_dark?: string;
9090
company_id: string;
9191
id: string;
92+
primary_language?: Language;
9293
prompt?: Prompt;
9394
title: string;
95+
translations?: Translation[];
9496
};
9597

9698
export type Prompt = {
@@ -171,3 +173,20 @@ export type Question = {
171173
id: string;
172174
prompt: string;
173175
};
176+
177+
export type Translation = {
178+
language: Language;
179+
items?: TranslationItems;
180+
};
181+
182+
export type TranslationItems = { [K in TranslationItemKey]: TranslationItem };
183+
184+
export type TranslationItem = {
185+
text?: string;
186+
};
187+
188+
export type TranslationItemKey =
189+
| 'survey.prompt.text'
190+
| 'survey.prompt.buttonText';
191+
192+
export type Language = string;

0 commit comments

Comments
 (0)