Complete client UI i18n migration
Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { View, Text } from "react-native";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import { RotateCw } from "lucide-react-native";
|
||||
@@ -9,6 +10,7 @@ import { settingsStyles } from "@/styles/settings";
|
||||
import { SettingsSection } from "@/screens/settings/settings-section";
|
||||
|
||||
export function DesktopPermissionsSection() {
|
||||
const { t } = useTranslation();
|
||||
const { theme } = useUnistyles();
|
||||
const {
|
||||
isDesktopApp,
|
||||
@@ -59,12 +61,22 @@ export function DesktopPermissionsSection() {
|
||||
leftIcon={refreshIcon}
|
||||
onPress={handleRefreshPress}
|
||||
disabled={isBusy}
|
||||
accessibilityLabel="Refresh desktop permissions"
|
||||
accessibilityLabel={t("settings.permissions.refreshAccessibility")}
|
||||
>
|
||||
{isRefreshing ? "Refreshing..." : "Refresh"}
|
||||
{isRefreshing ? t("settings.permissions.refreshing") : t("settings.permissions.refresh")}
|
||||
</Button>
|
||||
),
|
||||
[refreshIcon, handleRefreshPress, isBusy, isRefreshing],
|
||||
[refreshIcon, handleRefreshPress, isBusy, isRefreshing, t],
|
||||
);
|
||||
|
||||
const permissionLabels = useMemo(
|
||||
() => ({
|
||||
granted: t("settings.permissions.actions.granted"),
|
||||
request: t("settings.permissions.actions.request"),
|
||||
requesting: t("settings.permissions.actions.requesting"),
|
||||
busyExtraAction: (label: string) => t("settings.permissions.actions.busySuffix", { label }),
|
||||
}),
|
||||
[t],
|
||||
);
|
||||
|
||||
if (!isDesktopApp) {
|
||||
@@ -72,25 +84,27 @@ export function DesktopPermissionsSection() {
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsSection title="Permissions" trailing={refreshButton}>
|
||||
<SettingsSection title={t("settings.permissions.title")} trailing={refreshButton}>
|
||||
<View style={settingsStyles.card}>
|
||||
<DesktopPermissionRow
|
||||
title="Notifications"
|
||||
title={t("settings.permissions.notifications")}
|
||||
status={snapshot?.notifications ?? null}
|
||||
isRequesting={requestingPermission === "notifications"}
|
||||
onRequest={handleRequestNotifications}
|
||||
extraActionLabel="Test"
|
||||
labels={permissionLabels}
|
||||
extraActionLabel={t("settings.permissions.test")}
|
||||
isExtraActionBusy={isSendingTestNotification}
|
||||
isExtraActionDisabled={!notificationsGranted || isBusy}
|
||||
onExtraAction={handleSendTestNotification}
|
||||
/>
|
||||
{testNotificationError ? <Text style={errorTextStyle}>{testNotificationError}</Text> : null}
|
||||
<DesktopPermissionRow
|
||||
title="Microphone"
|
||||
title={t("settings.permissions.microphone")}
|
||||
showBorder
|
||||
status={snapshot?.microphone ?? null}
|
||||
isRequesting={requestingPermission === "microphone"}
|
||||
onRequest={handleRequestMicrophone}
|
||||
labels={permissionLabels}
|
||||
/>
|
||||
</View>
|
||||
</SettingsSection>
|
||||
|
||||
Reference in New Issue
Block a user