Skip to content

Commit

Permalink
feat: create and expose android API to react-native thread
Browse files Browse the repository at this point in the history
  • Loading branch information
jakex7 committed Apr 8, 2023
1 parent a14067c commit b2c2f0d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
3 changes: 3 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

implementation "androidx.appcompat:appcompat:1.6.0-rc01"
implementation "androidx.appcompat:appcompat-resources:1.6.0-rc01"
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package com.localizationsettings

import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import java.util.*


class LocalizationSettingsModule internal constructor(context: ReactApplicationContext) :
LocalizationSettingsSpec(context) {
Expand All @@ -11,11 +18,99 @@ class LocalizationSettingsModule internal constructor(context: ReactApplicationC
return NAME
}

// Example method
// See https://reactnative.dev/docs/native-modules-android
/**
* Get IETF BCP 47 (language-COUNTRY "pl-PL")
* if country is not available in locale, then use system defaults (even if it's not 100% correct, like "pl-US")
**/
private fun getLanguageTag(language: String): String {
// if language have format language_COUNTRY, then return it
if (Locale(language).country != "") return Locale(language).toLanguageTag()
// fallback for system country
return "$language-${Locale.getDefault().country}"
}


/**
* Get current language
* returns string in IETF BCP 47 (language-COUNTRY "pl-PL")
* If API version >= 33, use native per-app language feature
* else, fallback to SharedPreferences
**/
private fun getCurrentLanguage(): String? {
// If API version is >= 33, then use per-app language settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val currentLocaleName = if (!AppCompatDelegate.getApplicationLocales().isEmpty) {
// get per-app language
AppCompatDelegate.getApplicationLocales()[0]?.toLanguageTag()
} else {
// Fallback to the default System Locale
Locale.getDefault().toLanguageTag()
}
return currentLocaleName
}
// if API is < 33, then use SharedPreferences with fallback to default System Locale
if (getPreferences().getString("languageFrom", null) == Locale.getDefault().language) {
return getPreferences().getString("language", Locale.getDefault().toLanguageTag())
}
return Locale.getDefault().toLanguageTag()
}


/**
* Set current language
* passed language can be in ISO 639-1 (language "pl")
* or IETF BCP 47 (language-COUNTRY "pl-PL")
* If API version >= 33, use native per-app language feature
* else, fallback to SharedPreferences
**/
private fun setCurrentLanguage(language: String) {
// If API version is >= 33, then use per-app language settings
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val localeList = LocaleListCompat.forLanguageTags(getLanguageTag(language))
AppCompatDelegate.setApplicationLocales(localeList)
} else {
// if API is < 33, then set SharedPreferences language
val editor = getEditor();
editor.putString("languageFrom", Locale.getDefault().language)
editor.putString("language", getLanguageTag(language))
editor.apply()
}
}


/**
* Expose functions to react-native
**/
@ReactMethod
override fun multiply(a: Double, b: Double, promise: Promise) {
promise.resolve(a * b)
override fun getLanguage(promise: Promise) {
promise.resolve(getCurrentLanguage())
}

@ReactMethod
override fun setLanguage(language: String) {
setCurrentLanguage(language)
}

/**
* Expose constants to react-native
**/
override fun getConstants(): MutableMap<String, String?>? {
val constants: MutableMap<String, String?> = HashMap()
constants["language"] = getCurrentLanguage()
return constants
}

/**
* SharedPreferences (only used when API version is below 33)
**/
private fun getPreferences(): SharedPreferences {
return reactApplicationContext.getSharedPreferences(
"LocalizationSettings", Context.MODE_PRIVATE
)
}

private fun getEditor(): SharedPreferences.Editor {
return getPreferences().edit()
}

companion object {
Expand Down
3 changes: 2 additions & 1 deletion android/src/oldarch/LocalizationSettingsSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import com.facebook.react.bridge.Promise
abstract class LocalizationSettingsSpec internal constructor(context: ReactApplicationContext) :
ReactContextBaseJavaModule(context) {

abstract fun multiply(a: Double, b: Double, promise: Promise)
abstract fun getLanguage(promise: Promise)
abstract fun setLanguage(language: String)
}

0 comments on commit b2c2f0d

Please sign in to comment.