Complete client UI i18n migration

Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
This commit is contained in:
chyendongnhanh338
2026-06-11 14:15:35 +08:00
committed by GitHub
parent 41cf070fd8
commit 08ebe5e7e1
199 changed files with 16426 additions and 1821 deletions
@@ -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>