From 90fcda350b545a03da37080ba4498fd8088f83e2 Mon Sep 17 00:00:00 2001 From: Alex Risch Date: Fri, 6 Dec 2024 13:13:46 -0500 Subject: [PATCH] feat: Translations Cleaned up most non-translated strings Added French --- .../message-static-attachment.tsx | 3 +- components/DebugButton.tsx | 12 +- components/EphemeralAccountBanner.tsx | 8 +- components/InitialLoad.tsx | 8 +- .../Recommendations/Recommendations.tsx | 23 +- containers/GroupScreenMembersTable.tsx | 23 +- i18n/i18n.ts | 4 +- i18n/translations/en.ts | 83 +++ i18n/translations/fr.ts | 518 ++++++++++++++++++ screens/Accounts/Accounts.tsx | 3 +- screens/ConversationList.tsx | 13 +- .../ConversationRequestsListNav.tsx | 2 +- screens/Navigation/ConverseMatchMakerNav.tsx | 3 +- screens/Navigation/GroupNav.tsx | 3 +- screens/Navigation/Navigation.tsx | 11 +- screens/Navigation/NewConversationNav.tsx | 3 +- screens/Navigation/ShareFrameNav.tsx | 3 +- screens/Navigation/TopUpNav.tsx | 3 +- screens/Navigation/UserProfileNav.tsx | 3 +- screens/Navigation/WebviewPreviewNav.tsx | 3 +- screens/NewConversation/NewConversation.tsx | 9 +- .../NewConversation/NewConversationModal.tsx | 16 +- screens/NewConversation/NewGroupSummary.tsx | 19 +- screens/Profile.tsx | 23 +- screens/TopUp.tsx | 12 +- 25 files changed, 728 insertions(+), 83 deletions(-) create mode 100644 i18n/translations/fr.ts diff --git a/components/Chat/Message/message-content-types/message-static-attachment.tsx b/components/Chat/Message/message-content-types/message-static-attachment.tsx index a0a3ea57e..a9c2b85c4 100644 --- a/components/Chat/Message/message-content-types/message-static-attachment.tsx +++ b/components/Chat/Message/message-content-types/message-static-attachment.tsx @@ -2,6 +2,7 @@ import { AttachmentContainer } from "@/components/Chat/Attachment/attachment-con import { AttachmentLoading } from "@/components/Chat/Attachment/attachment-loading"; import { MessageLayout } from "@/components/Chat/Message/components/message-layout"; import { Text } from "@/design-system/Text"; +import { translate } from "@/i18n"; import { getLocalAttachment } from "@/utils/attachment/handleAttachment"; import { useQuery } from "@tanstack/react-query"; import { @@ -84,7 +85,7 @@ const Content = memo(function Content(props: { if (attachmentError || !attachment) { return ( - Couldn't find attachment + {translate("attachment_not_found")} ); } diff --git a/components/DebugButton.tsx b/components/DebugButton.tsx index b1e44ad62..77f6628b8 100644 --- a/components/DebugButton.tsx +++ b/components/DebugButton.tsx @@ -23,6 +23,7 @@ import config from "../config"; import { showActionSheetWithOptions } from "./StateHandlers/ActionSheetStateHandler"; import { useAccountsList } from "../data/store/accountsStore"; import mmkv from "../utils/mmkv"; +import { translate } from "@/i18n"; export const useDebugEnabled = (address?: string) => { const accounts = useAccountsList(); @@ -103,7 +104,7 @@ const DebugButton = forwardRef((props, ref) => { ...(debugEnabled ? debugMethods : {}), "Share current session logs": async () => { Share.open({ - title: "Converse Log Session", + title: translate("debug.converse_log_session"), url: `file://${loggingFilePath}`, type: "text/plain", }); @@ -111,7 +112,7 @@ const DebugButton = forwardRef((props, ref) => { "Share native logs": async () => { const nativeLogFilePath = await getNativeLogFile(); Share.open({ - title: "LibXMTP Logs", + title: translate("debug.libxmtp_log_session"), url: `file://${nativeLogFilePath}`, type: "text/plain", }); @@ -122,7 +123,7 @@ const DebugButton = forwardRef((props, ref) => { return Alert.alert("No previous session logging file found"); } Share.open({ - title: "Converse Log Session", + title: translate("debug.converse_log_session"), url: `file://${previousLoggingFile}`, type: "text/plain", }); @@ -148,7 +149,10 @@ const DebugButton = forwardRef((props, ref) => { showActionSheetWithOptions( { - title: `Converse v${appVersion} (${buildNumber})`, + title: translate("debug.converse_version", { + version: appVersion, + buildNumber, + }), options, cancelButtonIndex: options.indexOf("Cancel"), }, diff --git a/components/EphemeralAccountBanner.tsx b/components/EphemeralAccountBanner.tsx index 703d7362d..faf90e501 100644 --- a/components/EphemeralAccountBanner.tsx +++ b/components/EphemeralAccountBanner.tsx @@ -1,3 +1,4 @@ +import { translate } from "@/i18n"; import { useDisconnectActionSheet } from "@hooks/useDisconnectActionSheet"; import { itemSeparatorColor, @@ -24,10 +25,11 @@ export default function EphemeralAccountBanner() { style={styles.tempAccountBanner} > - This account is ephemeral + + {translate("ephemeral_account_banner.title")} + - Disconnect to permanently remove your device from these conversations - and ensure deniability. + {translate("ephemeral_account_banner.subtitle")} diff --git a/components/InitialLoad.tsx b/components/InitialLoad.tsx index 4e06cf58b..765c87fb8 100644 --- a/components/InitialLoad.tsx +++ b/components/InitialLoad.tsx @@ -10,6 +10,7 @@ import { } from "react-native"; import ActivityIndicator from "./ActivityIndicator/ActivityIndicator"; +import { translate } from "@/i18n"; export default function InitialLoad() { const headerHeight = useHeaderHeight(); @@ -22,11 +23,8 @@ export default function InitialLoad() { ]} > - Welcome to Converse! - - We’re checking if you already own{"\n"}conversations on the XMTP - network. - + {translate("initial_load.title")} + {translate("initial_load.subtitle")} ); } diff --git a/components/Recommendations/Recommendations.tsx b/components/Recommendations/Recommendations.tsx index fd9e6fc07..009ec819d 100644 --- a/components/Recommendations/Recommendations.tsx +++ b/components/Recommendations/Recommendations.tsx @@ -30,6 +30,7 @@ import { useSelect } from "@data/store/storeHelpers"; import { useRouter } from "@navigation/useNavigation"; import { refreshRecommendationsForAccount } from "@utils/recommendations"; import ActivityIndicator from "@components/ActivityIndicator/ActivityIndicator"; +import { translate } from "@/i18n"; const EXPIRE_AFTER = 86400000; // 1 DAY @@ -130,15 +131,16 @@ export default function Recommendations({ <> 👋 - Find people who have interests in common with you. Start - talking to them. + {translate("recommendations.title")} )} {visibility === "EMBEDDED" && showTitle && ( - RECOMMENDED PROFILES + + {translate("recommendations.section_title")} + )} @@ -188,7 +190,9 @@ export default function Recommendations({ return ( - Loading your recommendations + + {translate("recommendations.loading")} + ); } @@ -198,16 +202,15 @@ export default function Recommendations({ <> 😐 - We did not find people to match you with. We’re still early and we’re - not using that many signals. You can{" "} + {translate("recommendations.no_recommendations")} - find the current list here + {translate("recommendations.signal_list")} - , please feel free to{" "} + {translate("recommendations.please_feel_free_to")} - contact our co-founder Pol + {translate("recommendations.contact_pol")} {" "} - if you want us to add anything.{"\n\n"}Thank you! + {translate("recommendations.if_you_want_us_to_add_anything")} ); diff --git a/containers/GroupScreenMembersTable.tsx b/containers/GroupScreenMembersTable.tsx index 8beeb2698..ab44e5ff0 100644 --- a/containers/GroupScreenMembersTable.tsx +++ b/containers/GroupScreenMembersTable.tsx @@ -15,7 +15,7 @@ import logger from "@utils/logger"; import { navigate } from "@utils/navigation"; import { getPreferredName, getProfile } from "@utils/profile"; import { FC, memo, useMemo } from "react"; -import { Alert, StyleSheet, Text, View, useColorScheme } from "react-native"; +import { StyleSheet, Text, View, useColorScheme } from "react-native"; import { useGroupPermissionPolicyQuery } from "@queries/useGroupPermissionPolicyQuery"; import type { GroupWithCodecsType } from "@utils/xmtpRN/client"; @@ -23,6 +23,7 @@ import type { ConversationTopic } from "@xmtp/react-native-sdk"; import TableView, { TableViewItemType, } from "../components/TableView/TableView"; +import { captureErrorWithFriendlyToast } from "@/utils/capture-error"; type GroupScreenMembersTableProps = { topic: ConversationTopic | undefined; @@ -72,7 +73,7 @@ export const GroupScreenMembersTable: FC = memo( ); items.push({ id: a.inboxId, - title: `${preferredName}${isCurrentUser ? " (you)" : ""}`, + title: `${preferredName}${isCurrentUser ? translate("you_parentheses") : ""}`, action: () => { const { options, @@ -112,7 +113,7 @@ export const GroupScreenMembersTable: FC = memo( await promoteToSuperAdmin(a.inboxId); } catch (e) { logger.error(e); - Alert.alert("An error occurred"); + captureErrorWithFriendlyToast(e); } break; case revokeSuperAdminIndex: @@ -121,7 +122,7 @@ export const GroupScreenMembersTable: FC = memo( await revokeSuperAdmin(a.inboxId); } catch (e) { logger.error(e); - Alert.alert("An error occurred"); + captureErrorWithFriendlyToast(e); } break; case promoteAdminIndex: @@ -130,7 +131,7 @@ export const GroupScreenMembersTable: FC = memo( await promoteToAdmin(a.inboxId); } catch (e) { logger.error(e); - Alert.alert("An error occurred"); + captureErrorWithFriendlyToast(e); } break; case revokeAdminIndex: @@ -139,7 +140,7 @@ export const GroupScreenMembersTable: FC = memo( await revokeAdmin(a.inboxId); } catch (e) { logger.error(e); - Alert.alert("An error occurred"); + captureErrorWithFriendlyToast(e); } break; case removeIndex: @@ -148,7 +149,7 @@ export const GroupScreenMembersTable: FC = memo( await removeMember([a.inboxId]); } catch (e) { logger.error(e); - Alert.alert("An error occurred"); + captureErrorWithFriendlyToast(e); } break; default: @@ -159,10 +160,14 @@ export const GroupScreenMembersTable: FC = memo( rightView: ( {isSuperAdmin && ( - Super Admin + + {translate("group_screen_member_actions.super_admin")} + )} {isAdmin && !isSuperAdmin && ( - Admin + + {translate("group_screen_member_actions.admin")} + )} @@ -67,7 +68,7 @@ export default function Accounts( items={[ { id: "add", - title: "Add an account", + title: translate("add_an_account"), titleColor: primaryColor(colorScheme), action: () => { router.navigate("NewAccountNavigator"); diff --git a/screens/ConversationList.tsx b/screens/ConversationList.tsx index fbef23d72..2492a645e 100644 --- a/screens/ConversationList.tsx +++ b/screens/ConversationList.tsx @@ -47,6 +47,7 @@ import { dmMatchesSearchQuery, groupMatchesSearchQuery, } from "@/features/conversations/utils/search"; +import { translate } from "@/i18n"; type Props = { searchBarRef: @@ -199,20 +200,26 @@ function ConversationList({ navigation, route, searchBarRef }: Props) { if (showSearchTitleHeader) { ListHeaderComponents.push( - Messages + + {translate("conversation_list.messages")} + ); } else if (requestsCount > 0 && !sharingMode) { ListHeaderComponents.push( - Messages + + {translate("conversation_list.messages")} + ); } else if (!sharingMode) { ListHeaderComponents.push( - Messages + + {translate("conversation_list.messages")} + ); } diff --git a/screens/Navigation/ConversationRequestsListNav.tsx b/screens/Navigation/ConversationRequestsListNav.tsx index e8250fe4d..de7e0a735 100644 --- a/screens/Navigation/ConversationRequestsListNav.tsx +++ b/screens/Navigation/ConversationRequestsListNav.tsx @@ -96,7 +96,7 @@ export default function ConversationRequestsListNav() { navigation: any; }) => ({ animation: navigationAnimation as StackAnimationTypes, - headerTitle: clearingAll ? "Clearing..." : "Requests", + headerTitle: clearingAll ? translate("clearing") : translate("requests"), headerLeft: () => , headerRight: () => clearingAll ? undefined : ( diff --git a/screens/Navigation/ConverseMatchMakerNav.tsx b/screens/Navigation/ConverseMatchMakerNav.tsx index a6ef8e143..e5dd43a53 100644 --- a/screens/Navigation/ConverseMatchMakerNav.tsx +++ b/screens/Navigation/ConverseMatchMakerNav.tsx @@ -3,6 +3,7 @@ import { useColorScheme } from "react-native"; import ConverseMatchMaker from "../ConverseMatchMaker"; import { NativeStack, navigationAnimation } from "./Navigation"; +import { translate } from "@/i18n"; export default function ConverseMatchMakerNav() { const colorScheme = useColorScheme(); @@ -11,7 +12,7 @@ export default function ConverseMatchMakerNav() { name="ConverseMatchMaker" component={ConverseMatchMaker} options={{ - headerTitle: "Converse Match Maker", + headerTitle: translate("converse_match_maker"), presentation: "modal", headerStyle: { backgroundColor: navigationSecondaryBackgroundColor(colorScheme), diff --git a/screens/Navigation/GroupNav.tsx b/screens/Navigation/GroupNav.tsx index 1f8143013..0470d4e9c 100644 --- a/screens/Navigation/GroupNav.tsx +++ b/screens/Navigation/GroupNav.tsx @@ -8,6 +8,7 @@ import { Platform, useColorScheme } from "react-native"; import { NativeStack, navigationAnimation } from "./Navigation"; import GroupScreen from "../Group"; import type { ConversationTopic } from "@xmtp/react-native-sdk"; +import { translate } from "@/i18n"; export type GroupNavParams = { topic: ConversationTopic; @@ -24,7 +25,7 @@ export default function GroupNav() { name="Group" component={GroupScreen} options={({ route }) => ({ - headerTitle: "Group info", + headerTitle: translate("group_info"), headerTintColor: Platform.OS === "android" ? textSecondaryColor(colorScheme) diff --git a/screens/Navigation/Navigation.tsx b/screens/Navigation/Navigation.tsx index 480c4c1f9..f819e8e3e 100644 --- a/screens/Navigation/Navigation.tsx +++ b/screens/Navigation/Navigation.tsx @@ -44,6 +44,7 @@ import UserProfileNav from "./UserProfileNav"; import WebviewPreviewNav, { WebviewPreviewNavParams, } from "./WebviewPreviewNav"; +import { translate } from "@/i18n"; export type NavigationParamList = { Idle: undefined; @@ -104,7 +105,7 @@ export type NavigationParamList = { export const authScreensSharedScreenOptions: NativeStackNavigationOptions = { headerTitle: "", - headerBackTitle: "Back", + headerBackTitle: translate("back"), headerBackTitleVisible: false, headerShadowVisible: false, }; @@ -185,7 +186,7 @@ export function SignedInNavigation() { headerLeft: () => ( ), - headerTitle: "Modify profile", + headerTitle: translate("profile.modify_profile"), }} /> @@ -272,10 +273,10 @@ const NewAccountNavigator = memo(function NewAccountNavigator() { name="NewAccount" component={NewAccountScreen} options={{ - headerTitle: "New account", + headerTitle: translate("new_account"), headerLeft: () => ( ), diff --git a/screens/Navigation/NewConversationNav.tsx b/screens/Navigation/NewConversationNav.tsx index deb496bf0..a97369eca 100644 --- a/screens/Navigation/NewConversationNav.tsx +++ b/screens/Navigation/NewConversationNav.tsx @@ -8,6 +8,7 @@ import { useColorScheme } from "react-native"; import { NativeStack, navigationAnimation } from "./Navigation"; import NewConversationModal from "../NewConversation/NewConversationModal"; import type { ConversationTopic } from "@xmtp/react-native-sdk"; +import { translate } from "@/i18n"; export type NewConversationNavParams = { peer?: string; @@ -27,7 +28,7 @@ export const NewConversationScreenConfig = { export default function NewConversationNav() { const colorScheme = useColorScheme(); const options: NativeStackNavigationOptions = { - headerTitle: "New conversation", + headerTitle: translate("new_conversation.new_conversation"), presentation: "modal", headerStyle: { backgroundColor: navigationSecondaryBackgroundColor(colorScheme), diff --git a/screens/Navigation/ShareFrameNav.tsx b/screens/Navigation/ShareFrameNav.tsx index 1941c26c7..b7017a3e4 100644 --- a/screens/Navigation/ShareFrameNav.tsx +++ b/screens/Navigation/ShareFrameNav.tsx @@ -4,6 +4,7 @@ import { Button, Platform, TextInput } from "react-native"; import { NativeStack } from "./Navigation"; import AndroidBackAction from "../../components/AndroidBackAction"; import ConversationList from "../ConversationList"; +import { translate } from "@/i18n"; export type ShareFrameNavParams = { frameURL: string; @@ -15,7 +16,7 @@ export default function ShareFrameNav() { ({ - headerTitle: "Share Frame", + headerTitle: translate("share_frame"), presentation: "modal", headerLeft: (props) => Platform.OS === "ios" ? ( diff --git a/screens/Navigation/TopUpNav.tsx b/screens/Navigation/TopUpNav.tsx index fd6539ebb..a715f65c5 100644 --- a/screens/Navigation/TopUpNav.tsx +++ b/screens/Navigation/TopUpNav.tsx @@ -3,6 +3,7 @@ import { useColorScheme } from "react-native"; import { NativeStack, navigationAnimation } from "./Navigation"; import TopUpScreen from "../TopUp"; +import { translate } from "@/i18n"; export default function TopUpNav() { const colorScheme = useColorScheme(); @@ -11,7 +12,7 @@ export default function TopUpNav() { name="TopUp" component={TopUpScreen} options={{ - headerTitle: "Top up", + headerTitle: translate("top_up.header_title"), presentation: "modal", headerStyle: { backgroundColor: navigationSecondaryBackgroundColor(colorScheme), diff --git a/screens/Navigation/UserProfileNav.tsx b/screens/Navigation/UserProfileNav.tsx index b1647c082..478e7ec42 100644 --- a/screens/Navigation/UserProfileNav.tsx +++ b/screens/Navigation/UserProfileNav.tsx @@ -9,6 +9,7 @@ import { ScreenHeaderModalCloseButton } from "../../components/Screen/ScreenHead import { useRouter } from "../../navigation/useNavigation"; import { UserProfileScreen } from "../UserProfileScreen"; import { NativeStack } from "./Navigation"; +import { translate } from "@/i18n"; export default function UserProfileNav() { const colorScheme = useColorScheme(); @@ -19,7 +20,7 @@ export default function UserProfileNav() { name="UserProfile" component={UserProfileScreen} options={{ - headerTitle: "Modify profile", + headerTitle: translate("profile.modify_profile"), headerTitleStyle: headerTitleStyle(colorScheme), headerLeft: () => ( { if (group.enabled && group.members.length > 0) { if (loading) { @@ -461,7 +462,7 @@ export default function NewConversation({ { id: "inviteToConverse", leftView: , - title: "Invite them to Converse", + title: translate("new_conversation.invite_to_converse"), subtitle: "", action: () => { navigation.goBack(); diff --git a/screens/NewConversation/NewConversationModal.tsx b/screens/NewConversation/NewConversationModal.tsx index 2c134f42e..752cafcd3 100644 --- a/screens/NewConversation/NewConversationModal.tsx +++ b/screens/NewConversation/NewConversationModal.tsx @@ -18,6 +18,7 @@ import { navigationAnimation, } from "../Navigation/Navigation"; import { NewConversationNavParams } from "../Navigation/NewConversationNav"; +import { translate } from "@/i18n"; export type NewConversationModalParams = { NewConversationScreen: NewConversationNavParams; @@ -50,8 +51,8 @@ const NewConversationModal = ({ name="NewConversationScreen" options={{ headerTitle: route.params?.addingToGroupTopic - ? "Add members" - : "New conversation", + ? translate("new_group.add_members") + : translate("new_conversation.new_conversation"), presentation: "modal", }} > @@ -69,9 +70,14 @@ const NewConversationModal = ({ name="NewGroupSummary" component={NewGroupSummary} options={{ - headerBackTitle: "Back", - headerTitle: "New group", - headerRight: () =>