Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlinify I18nManagerModule #44537

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -3329,21 +3329,26 @@ public class com/facebook/react/modules/fresco/SystraceRequestListener : com/fac
public fun requiresExtraMap (Ljava/lang/String;)Z
}

public class com/facebook/react/modules/i18nmanager/I18nManagerModule : com/facebook/fbreact/specs/NativeI18nManagerSpec {
public final class com/facebook/react/modules/i18nmanager/I18nManagerModule : com/facebook/fbreact/specs/NativeI18nManagerSpec {
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun allowRTL (Z)V
public fun forceRTL (Z)V
public fun getTypedExportedConstants ()Ljava/util/Map;
public fun swapLeftAndRightInRTL (Z)V
}

public class com/facebook/react/modules/i18nmanager/I18nUtil {
public fun allowRTL (Landroid/content/Context;Z)V
public fun doLeftAndRightSwapInRTL (Landroid/content/Context;)Z
public fun forceRTL (Landroid/content/Context;Z)V
public static fun getInstance ()Lcom/facebook/react/modules/i18nmanager/I18nUtil;
public fun isRTL (Landroid/content/Context;)Z
public fun swapLeftAndRightInRTL (Landroid/content/Context;Z)V
public final class com/facebook/react/modules/i18nmanager/I18nUtil {
public static final field Companion Lcom/facebook/react/modules/i18nmanager/I18nUtil$Companion;
public final fun allowRTL (Landroid/content/Context;Z)V
public final fun doLeftAndRightSwapInRTL (Landroid/content/Context;)Z
public final fun forceRTL (Landroid/content/Context;Z)V
public static final fun getInstance ()Lcom/facebook/react/modules/i18nmanager/I18nUtil;
public final fun isRTL (Landroid/content/Context;)Z
public final fun swapLeftAndRightInRTL (Landroid/content/Context;Z)V
}

public final class com/facebook/react/modules/i18nmanager/I18nUtil$Companion {
public final fun getInstance ()Lcom/facebook/react/modules/i18nmanager/I18nUtil;
}

public final class com/facebook/react/modules/image/ImageLoaderModule : com/facebook/fbreact/specs/NativeImageLoaderAndroidSpec, com/facebook/react/bridge/LifecycleEventListener {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.modules.i18nmanager

import android.os.Build
import com.facebook.fbreact.specs.NativeI18nManagerSpec
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule

/** [NativeModule] that allows JS to set allowRTL and get isRTL status. */
@ReactModule(name = NativeI18nManagerSpec.NAME)
public class I18nManagerModule(context: ReactApplicationContext?) : NativeI18nManagerSpec(context) {
override public fun getTypedExportedConstants(): Map<String, Any> {
val context = getReactApplicationContext()
val locale =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
context.resources.configuration.locales[0]
} else {
@Suppress("DEPRECATION")
context.resources.configuration.locale
}
return mapOf(
"isRTL" to I18nUtil.instance.isRTL(context),
"doLeftAndRightSwapInRTL" to I18nUtil.instance.doLeftAndRightSwapInRTL(context),
"localeIdentifier" to locale.toString())
}

override fun allowRTL(value: Boolean) {
I18nUtil.instance.allowRTL(getReactApplicationContext(), value)
}

override fun forceRTL(value: Boolean) {
I18nUtil.instance.forceRTL(getReactApplicationContext(), value)
}

override fun swapLeftAndRightInRTL(value: Boolean) {
I18nUtil.instance.swapLeftAndRightInRTL(getReactApplicationContext(), value)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.modules.i18nmanager

import android.content.Context
import androidx.core.text.TextUtilsCompat
import androidx.core.view.ViewCompat
import java.util.Locale

public class I18nUtil private constructor() {
/**
* Check if the device is currently running on an RTL locale. This only happens when the app:
* * is forcing RTL layout, regardless of the active language (for development purpose)
* * allows RTL layout when using RTL locale
*/
public fun isRTL(context: Context): Boolean =
if (isRTLForced(context)) {
true
} else isRTLAllowed(context) && isDevicePreferredLanguageRTL

/**
* Should be used very early during app start up Before the bridge is initialized
*
* @return whether the app allows RTL layout, default is true
*/
private fun isRTLAllowed(context: Context): Boolean =
isPrefSet(context, KEY_FOR_PREFS_ALLOWRTL, true)

public fun allowRTL(context: Context, allowRTL: Boolean) {
setPref(context, KEY_FOR_PREFS_ALLOWRTL, allowRTL)
}

public fun doLeftAndRightSwapInRTL(context: Context): Boolean =
isPrefSet(context, KEY_FOR_PERFS_MAKE_RTL_FLIP_LEFT_AND_RIGHT_STYLES, true)

public fun swapLeftAndRightInRTL(context: Context, flip: Boolean) {
setPref(context, KEY_FOR_PERFS_MAKE_RTL_FLIP_LEFT_AND_RIGHT_STYLES, flip)
}

/** Could be used to test RTL layout with English Used for development and testing purpose */
private fun isRTLForced(context: Context): Boolean =
isPrefSet(context, KEY_FOR_PREFS_FORCERTL, false)

public fun forceRTL(context: Context, forceRTL: Boolean) {
setPref(context, KEY_FOR_PREFS_FORCERTL, forceRTL)
}

private val isDevicePreferredLanguageRTL: Boolean
// Check if the current device language is RTL
get() {
val directionality = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault())
return directionality == ViewCompat.LAYOUT_DIRECTION_RTL
}

private fun isPrefSet(context: Context, key: String, defaultValue: Boolean): Boolean =
context
.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)
.getBoolean(key, defaultValue)

private fun setPref(context: Context, key: String, value: Boolean) {
val editor = context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE).edit()
editor.putBoolean(key, value)
editor.apply()
}

public companion object {
@JvmStatic public val instance: I18nUtil = I18nUtil()

private const val SHARED_PREFS_NAME = "com.facebook.react.modules.i18nmanager.I18nUtil"
private const val KEY_FOR_PREFS_ALLOWRTL = "RCTI18nUtil_allowRTL"
private const val KEY_FOR_PREFS_FORCERTL = "RCTI18nUtil_forceRTL"
private const val KEY_FOR_PERFS_MAKE_RTL_FLIP_LEFT_AND_RIGHT_STYLES =
"RCTI18nUtil_makeRTLFlipLeftAndRightStyles"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public data class BorderRadiusStyle(
bottomRight = bottomRight?.resolve(width, height) ?: 0f,
)
LayoutDirection.RTL ->
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(context)) {
if (I18nUtil.instance.doLeftAndRightSwapInRTL(context)) {
ComputedBorderRadius(
topLeft = topRight?.resolve(width, height) ?: 0f,
topRight = topLeft?.resolve(width, height) ?: 0f,
Expand Down
Loading