Skip to content

Commit

Permalink
first translations (AR, FA, TR) (#86)
Browse files Browse the repository at this point in the history
* add initial translations: ar, fa, tr

* fix fa strings missing variables

* Don't need to specify RTL orientation, system handles it

* onboarding in RTL

* use Paragraph text for Orb text

* useMemo for orb text Paragraph
  • Loading branch information
tmgrask authored Dec 13, 2024
1 parent 0c5aa9f commit 6b63477
Show file tree
Hide file tree
Showing 13 changed files with 644 additions and 119 deletions.
26 changes: 26 additions & 0 deletions android/app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<resources>
<string name="app_name">Conduit</string>
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
<string name="expo_system_ui_user_interface_style" translatable="false">automatic</string>
<!-- Label for the stop action in the Conduit service notification -->
<string name="conduit_service_stop_label_text">قف</string>
<!-- Short notification text (notification collapsed) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_short_text">%1$d / %2$d \u00B7 %3$s</string>
<!-- Long notification text (notification expanded) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_long_text">المستخدمين: %1$dمتصل / %2$dمتصلين\nالبيانات: %3$s تم نقلها</string>
<!-- Notification text for the Conduit service when it is waiting for network connectivity -->
<string name="conduit_service_no_internet_notification_text">في انتظار اتصال الشبكة</string>
<!-- Notification channel description for the Conduit service -->
<string name="conduit_service_channel_description">إشعار بشأن خدمة Conduit</string>
<!-- Notification text for when the Conduit app detects an that the app must be updated to continue working -->
<string name="notification_conduit_inproxy_must_upgrade_text">التحديث مطلوب: يرجى تنزيل أحدث إصدار من التطبيق لمواصلة استخدامه.</string>
<!-- Notification text for when the Conduit service fails to start -->
<string name="notification_conduit_failed_to_start_text">فشلت خدمة Conduit في البدء التشغيل. انقر فوق الإشعار للحصول على مزيد من المعلومات</string>
<!-- Notification text for when the Conduit service fails to restart -->
<string name="notification_conduit_failed_to_restart_text">فشلت خدمة Conduit في إعادة التشغيل. انقر فوق الإشعار للحصول على مزيد من المعلومات</string>
<!-- Notification text for Conduit starting notification -->
<string name="conduit_service_starting_notification_text">بدأت خدمة Conduit…</string>
<!-- Added by expo-localiztion -->
<string name="ExpoLocalization_supportsRTL" translatable="false">true</string>
</resources>
26 changes: 26 additions & 0 deletions android/app/src/main/res/values-fa/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<resources>
<string name="app_name">Conduit</string>
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
<string name="expo_system_ui_user_interface_style" translatable="false">automatic</string>
<!-- Label for the stop action in the Conduit service notification -->
<string name="conduit_service_stop_label_text">توقف</string>
<!-- Short notification text (notification collapsed) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_short_text">۱\n۲\n۳</string>
<!-- Long notification text (notification expanded) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_long_text">اتصال فعال \nدر حال اتصال \nانتقال داده شد</string>
<!-- Notification text for the Conduit service when it is waiting for network connectivity -->
<string name="conduit_service_no_internet_notification_text">منتظر اتصال به شبکه</string>
<!-- Notification channel description for the Conduit service -->
<string name="conduit_service_channel_description">اعلان‌های Conduit</string>
<!-- Notification text for when the Conduit app detects an that the app must be updated to continue working -->
<string name="notification_conduit_inproxy_must_upgrade_text">آپدیت کنید: برای استفاده از این برنامه، آخرین نسخه را دانلود کنید.</string>
<!-- Notification text for when the Conduit service fails to start -->
<string name="notification_conduit_failed_to_start_text">Conduit راه نیفتاد. برای اطلاعات بیشتر اینجا کلیک کنید. </string>
<!-- Notification text for when the Conduit service fails to restart -->
<string name="notification_conduit_failed_to_restart_text">Conduit راه نیفتاد. برای اطلاعات بیشتر اینجا کلیک کنید. </string>
<!-- Notification text for Conduit starting notification -->
<string name="conduit_service_starting_notification_text">Conduit در حال شروع است...</string>
<!-- Added by expo-localiztion -->
<string name="ExpoLocalization_supportsRTL" translatable="false">true</string>
</resources>
26 changes: 26 additions & 0 deletions android/app/src/main/res/values-tr/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<resources>
<string name="app_name">Conduit</string>
<string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
<string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
<string name="expo_system_ui_user_interface_style" translatable="false">automatic</string>
<!-- Label for the stop action in the Conduit service notification -->
<string name="conduit_service_stop_label_text">Durdur</string>
<!-- Short notification text (notification collapsed) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_short_text">%1$d / %2$d \u00B7 %3$s</string>
<!-- Long notification text (notification expanded) for the Conduit service when it is active showing the number of clients connected, connecting, and total bytes transferred -->
<string name="conduit_service_running_notification_long_text">İstemciler: %1$d bağlı / %2$d bağlanıyor\nVeri: %3$s aktarıldı</string>
<!-- Notification text for the Conduit service when it is waiting for network connectivity -->
<string name="conduit_service_no_internet_notification_text">Ağ bağlantısı bekleniyor</string>
<!-- Notification channel description for the Conduit service -->
<string name="conduit_service_channel_description">Conduit hizmeti bildirimi</string>
<!-- Notification text for when the Conduit app detects an that the app must be updated to continue working -->
<string name="notification_conduit_inproxy_must_upgrade_text">Güncelleme gerekiyor: kullanmaya devam etmek için lütfen uygulamanın son sürümünü indirin.</string>
<!-- Notification text for when the Conduit service fails to start -->
<string name="notification_conduit_failed_to_start_text">Conduit hizmeti başlatılamadı. Daha fazla bilgi için bildirime tıklayın.</string>
<!-- Notification text for when the Conduit service fails to restart -->
<string name="notification_conduit_failed_to_restart_text">Conduit hizmeti yeniden başlatılamadı. Daha fazla bilgi için bildirime tıklayın.</string>
<!-- Notification text for Conduit starting notification -->
<string name="conduit_service_starting_notification_text">Conduit hizmeti başlatılıyor…</string>
<!-- Added by expo-localiztion -->
<string name="ExpoLocalization_supportsRTL" translatable="false">true</string>
</resources>
19 changes: 15 additions & 4 deletions src/app/(app)/onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
SkTextStyle,
Skia,
TextAlign,
TextDirection,
useFonts,
vec,
} from "@shopify/react-native-skia";
Expand Down Expand Up @@ -72,7 +73,8 @@ import { fonts, palette, sharedStyles as ss } from "@/src/styles";
export default function OnboardingScreen() {
const win = useWindowDimensions();
const insets = useSafeAreaInsets();
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl" ? true : false;
const notificationPermissions = useNotificationsPermissions();
const router = useRouter();

Expand Down Expand Up @@ -228,9 +230,12 @@ export default function OnboardingScreen() {
if (!fontMgr) {
return null;
}
const paragraphStyle = {
const paragraphStyle: SkParagraphStyle = {
textAlign: TextAlign.Center,
};
if (isRTL) {
paragraphStyle.textDirection = TextDirection.RTL;
}
const textStyle: SkTextStyle = {
color: Skia.Color(palette.white),
fontFamilies: ["Jura"],
Expand All @@ -252,8 +257,11 @@ export default function OnboardingScreen() {
return null;
}
const paragraphStyle: SkParagraphStyle = {
textAlign: TextAlign.Left,
textAlign: isRTL ? TextAlign.Right : TextAlign.Left,
};
if (isRTL) {
paragraphStyle.textDirection = TextDirection.RTL;
}
const textStyle: SkTextStyle = {
color: Skia.Color(palette.white),
fontFamilies: ["Rajdhani"],
Expand All @@ -275,9 +283,12 @@ export default function OnboardingScreen() {
if (!fontMgr) {
return null;
}
const paragraphStyle = {
const paragraphStyle: SkParagraphStyle = {
textAlign: TextAlign.Center,
};
if (isRTL) {
paragraphStyle.textDirection = TextDirection.RTL;
}

const textStyle: SkTextStyle = {
color: Skia.Color(palette.blueTint2),
Expand Down
4 changes: 3 additions & 1 deletion src/components/ConduitName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export function ConduitName() {

// The Conduit Name is purely cosmetic, it is optional and only stored locally
export function EditableConduitName({ initialName }: { initialName: string }) {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl" ? true : false;

const queryClient = useQueryClient();

Expand Down Expand Up @@ -126,6 +127,7 @@ export function EditableConduitName({ initialName }: { initialName: string }) {
maxLength={maxLength}
autoCorrect={false}
autoComplete={"off"}
textAlign={isRTL ? "right" : "left"}
/>
{showCharsUsed && (
<View style={[ss.absoluteBottomRight]}>
Expand Down
120 changes: 79 additions & 41 deletions src/components/ConduitOrbToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,26 @@ import {
Canvas,
Circle,
ColorMatrix,
ColorShader,
Group,
Image,
Paint,
Paragraph,
RadialGradient,
Shadow,
Text,
SkParagraphStyle,
SkTextStyle,
Skia,
TextAlign,
TextDirection,
interpolateColors,
useFont,
useFonts,
useImage,
vec,
} from "@shopify/react-native-skia";
import * as Haptics from "expo-haptics";
import React from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { View, useWindowDimensions } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, {
Easing,
Expand All @@ -54,7 +58,7 @@ import Animated, {
import { z } from "zod";

import { useAnimatedImageValue } from "@/src/animationHooks";
import { timedLog } from "@/src/common/utils";
import { drawBigFont, timedLog } from "@/src/common/utils";
import { ConduitConnectionLight } from "@/src/components/canvas/ConduitConnectionLight";
import {
INPROXY_MAX_CLIENTS_MAX,
Expand All @@ -67,6 +71,7 @@ import {
useInproxyStatus,
} from "@/src/inproxy/hooks";
import { fonts, palette, sharedStyles as ss } from "@/src/styles";
import { FaderGroup } from "./canvas/FaderGroup";

export function ConduitOrbToggle({
width,
Expand All @@ -75,7 +80,10 @@ export function ConduitOrbToggle({
width: number;
height: number;
}) {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl" ? true : false;
const win = useWindowDimensions();

const { toggleInproxy } = useInproxyContext();
const { data: inproxyStatus } = useInproxyStatus();
const { data: inproxyCurrentConnectedClients } =
Expand Down Expand Up @@ -116,15 +124,43 @@ export function ConduitOrbToggle({
// The "Turn On" text also uses interpolation to appear to fade in by going
// from transparent to it's final color.
const orbText = t("TAP_TO_TURN_ON_I18N.string");
const orbTextColors = [palette.transparent, palette.midGrey];
const orbTextColorIndex = useSharedValue(0);
const orbTextColor = useDerivedValue(() => {
return interpolateColors(
orbTextColorIndex.value,
[0, 1],
orbTextColors,
);
});
const orbTextOpacity = useSharedValue(0);

const fontMgr = useFonts({ Jura: [fonts.JuraRegular] });
const fontSize = drawBigFont(win) ? 20 : 16;
const orbTextParagraph = React.useMemo(() => {
if (!fontMgr) {
return null;
}
let paragraphStyle: SkParagraphStyle = {
textAlign: TextAlign.Center,
};
if (isRTL) {
paragraphStyle.textDirection = TextDirection.RTL;
}

const mainTextStyle: SkTextStyle = {
fontFamilies: ["Jura"],
fontSize: fontSize,
fontStyle: {
weight: 300,
},
letterSpacing: 1, // 5% of 20
};

return Skia.ParagraphBuilder.Make(paragraphStyle, fontMgr)
.pushStyle(mainTextStyle)
.addText(orbText)
.build();
}, [fontMgr]);

const orbTextXOffset = orbTextParagraph
? -orbTextParagraph.getMaxWidth() / 2
: 0;
const orbTextYOffset = orbTextParagraph
? -orbTextParagraph.getHeight() / 2
: 0;

// The orb will pop into existence at the start, animating from radius 0 up
const orbRadius = useSharedValue(0);
const orbDiameter = useDerivedValue(() => orbRadius.value * 2);
Expand All @@ -141,6 +177,17 @@ export function ConduitOrbToggle({
},
];

// The overlay is rendered in a regular view, while the orb itself is within
// Skia, so we need to accomodate RTL in the regular view.
const orbOverlayTransform = [
{
translateY: orbCenterY,
},
{
translateX: isRTL ? (-1 * width) / 2 : width / 2,
},
];

function animateProxyAnnouncing() {
timedLog("animateProxyAnnouncing()");
orbColorsIndex.value = withRepeat(
Expand All @@ -151,7 +198,7 @@ export function ConduitOrbToggle({
-1,
true,
);
orbTextColorIndex.value = withTiming(0, { duration: 500 });
orbTextOpacity.value = withTiming(0, { duration: 500 });
dotsOpacity.value = withTiming(1, { duration: 1000 });
}

Expand All @@ -166,7 +213,7 @@ export function ConduitOrbToggle({
timedLog("animateTurnOffProxy()");
cancelAnimation(orbColorsIndex);
orbColorsIndex.value = withTiming(0, { duration: 500 });
orbTextColorIndex.value = withTiming(1, { duration: 500 });
orbTextOpacity.value = withTiming(1, { duration: 500 });
dotsOpacity.value = withTiming(0.2, { duration: 1000 });
}

Expand All @@ -186,14 +233,10 @@ export function ConduitOrbToggle({
delay,
withTiming(0.2, { duration: 1000 }),
);
if (delay > 0) {
// if we're introing with a delay, it means the Inproxy is stopped,
// so we will fade in our button text.
orbTextColorIndex.value = withDelay(
delay,
withTiming(1, { duration: 1000 }),
);
}
orbTextOpacity.value = withDelay(
delay,
withTiming(1, { duration: 1000 }),
);
}

// We have 4 animation states that depend on the state of the Inproxy:
Expand Down Expand Up @@ -301,11 +344,6 @@ export function ConduitOrbToggle({
);
}, []);

// TODO: switch to the newer Paragraph model
const font = useFont(fonts.JuraRegular, 20);
const orbTextXOffset = font ? -font.measureText(orbText).width / 2 : 0;
const orbTextYOffset = font ? font.measureText(orbText).height / 2 : 0;

// Orb Gesture
// Since turning off the proxy will disconnect any connected users, require
// a long press to turn off. When the user clicks the orb and a toggle would
Expand Down Expand Up @@ -393,10 +431,10 @@ export function ConduitOrbToggle({
<Group>
{/* Intro particle swirl animation */}
<Image
y={finalOrbRadius / 2}
y={0}
image={particleSwirlGif}
width={width}
height={width}
height={height}
opacity={particleSwirlOpacity}
/>
</Group>
Expand Down Expand Up @@ -480,14 +518,14 @@ export function ConduitOrbToggle({
</Group>
<Group>
{/* Turn ON text displayed when Conduit is off */}
<Text
x={orbTextXOffset}
y={orbTextYOffset}
text={orbText}
font={font}
>
<ColorShader color={orbTextColor} />
</Text>
<FaderGroup opacity={orbTextOpacity}>
<Paragraph
paragraph={orbTextParagraph}
x={orbTextXOffset}
y={orbTextYOffset}
width={width}
/>
</FaderGroup>
</Group>
</Group>
</Group>
Expand Down Expand Up @@ -519,7 +557,7 @@ export function ConduitOrbToggle({
width: orbDiameter,
height: orbDiameter,
borderRadius: orbRadius,
transform: orbCenteringTransform,
transform: orbOverlayTransform,
},
]}
/>
Expand Down
Loading

0 comments on commit 6b63477

Please sign in to comment.