From cd613d23ea9e9c759ad9c7aa3844fb00927c9f15 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 16 Sep 2025 10:24:23 +0200 Subject: [PATCH 1/5] fix: simplify activity state checks in ReactNativeAlertModule --- .../blazejkustra/reactnativealert/ReactNativeAlertModule.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt index 9dfeb35..c8766b0 100644 --- a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt +++ b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt @@ -46,10 +46,10 @@ class ReactNativeAlertModule( } val activity = currentActivity ?: return - if (activity.isFinishing || (Build.VERSION.SDK_INT >= 17 && activity.isDestroyed)) return + if (activity.isFinishing || activity.isDestroyed) return UiThreadUtil.runOnUiThread { - if (activity.isFinishing || (Build.VERSION.SDK_INT >= 17 && activity.isDestroyed)) return@runOnUiThread + if (activity.isFinishing || activity.isDestroyed) return @runOnUiThread val themed: Context = if (Build.VERSION.SDK_INT >= 29) { // Use system theme on Android 10+ (API 29+) From ca14a55c930c766e8c16b2e0d6d75ed64c6e69d7 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 16 Sep 2025 10:24:29 +0200 Subject: [PATCH 2/5] refactor: streamline module retrieval logic in ReactNativeAlertPackage --- .../reactnativealert/ReactNativeAlertPackage.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertPackage.kt b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertPackage.kt index 55eaf1d..14e3b5d 100644 --- a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertPackage.kt +++ b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertPackage.kt @@ -9,10 +9,9 @@ import java.util.HashMap class ReactNativeAlertPackage : BaseReactPackage() { override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { - return if (name == ReactNativeAlertModule.NAME) { - ReactNativeAlertModule(reactContext) - } else { - null + return when (name) { + ReactNativeAlertModule.NAME -> ReactNativeAlertModule(reactContext) + else -> null } } From ecc04d50982d219444d56fa54031f9808843c7e6 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 16 Sep 2025 10:31:26 +0200 Subject: [PATCH 3/5] refactor: enhance input handling and theme color retrieval in ReactNativeAlertModule --- .../ReactNativeAlertModule.kt | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt index c8766b0..c68c8f4 100644 --- a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt +++ b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt @@ -125,12 +125,25 @@ class ReactNativeAlertModule( } // ----- Helpers ----- + private fun Context.getThemeColor(attr: Int): Int { + val typedArray = obtainStyledAttributes(intArrayOf(attr)) + val color = typedArray.getColor(0, 0xFF000000.toInt()) + typedArray.recycle() + return color + } + + private data class InputViews( + val contentView: LinearLayout?, + val usernameInput: EditText?, + val mainInput: EditText? + ) + private fun buildInputs( ctx: Context, type: String, config: ReadableMap - ): Triple { - if (type == "default") return Triple(null, null, null) + ): InputViews { + if (type == "default") return InputViews(null, null, null) val layout = LinearLayout(ctx).apply { orientation = LinearLayout.VERTICAL @@ -148,9 +161,7 @@ class ReactNativeAlertModule( config.getIntOrNull("usernameMaxLength")?.takeIf { it > 0 }?.let { filters = arrayOf(InputFilter.LengthFilter(it)) } - val typedArray = ctx.obtainStyledAttributes(intArrayOf(android.R.attr.colorControlNormal)) - val tintColor = typedArray.getColor(0, 0xFF000000.toInt()) - typedArray.recycle() + val tintColor = ctx.getThemeColor(android.R.attr.colorControlNormal) backgroundTintList = android.content.res.ColorStateList.valueOf(tintColor) val margin = (ctx.resources.displayMetrics.density * 4).toInt() val params = LinearLayout.LayoutParams( @@ -174,9 +185,7 @@ class ReactNativeAlertModule( filters = arrayOf(InputFilter.LengthFilter(it)) } // Apply theme-aware background tint - val typedArray = ctx.obtainStyledAttributes(intArrayOf(android.R.attr.colorControlNormal)) - val tintColor = typedArray.getColor(0, 0xFF000000.toInt()) - typedArray.recycle() + val tintColor = ctx.getThemeColor(android.R.attr.colorControlNormal) backgroundTintList = android.content.res.ColorStateList.valueOf(tintColor) layoutParams = LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, @@ -188,7 +197,7 @@ class ReactNativeAlertModule( applyKeyboardType(username ?: main, config.getStringOrNull("keyboardType")) layout.addView(main) - return Triple(layout, username, main) + return InputViews(layout, username, main) } private fun applyKeyboardType(target: EditText, keyboardType: String?) { From 40827b884239341b0f4864abced0a80d29767b9b Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 16 Sep 2025 10:33:18 +0200 Subject: [PATCH 4/5] refactor: introduce extension property for density conversion in ReactNativeAlertModule --- .../reactnativealert/ReactNativeAlertModule.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt index c68c8f4..5af340d 100644 --- a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt +++ b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt @@ -125,6 +125,9 @@ class ReactNativeAlertModule( } // ----- Helpers ----- + private val Int.dp: Int + get() = (this * android.content.res.Resources.getSystem().displayMetrics.density).toInt() + private fun Context.getThemeColor(attr: Int): Int { val typedArray = obtainStyledAttributes(intArrayOf(attr)) val color = typedArray.getColor(0, 0xFF000000.toInt()) @@ -147,8 +150,8 @@ class ReactNativeAlertModule( val layout = LinearLayout(ctx).apply { orientation = LinearLayout.VERTICAL - val horizontalPad = (ctx.resources.displayMetrics.density * 20).toInt() - val verticalPad = (ctx.resources.displayMetrics.density * 12).toInt() + val horizontalPad = 20.dp + val verticalPad = 12.dp setPadding(horizontalPad, verticalPad, horizontalPad, verticalPad) layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) } @@ -163,7 +166,7 @@ class ReactNativeAlertModule( } val tintColor = ctx.getThemeColor(android.R.attr.colorControlNormal) backgroundTintList = android.content.res.ColorStateList.valueOf(tintColor) - val margin = (ctx.resources.displayMetrics.density * 4).toInt() + val margin = 4.dp val params = LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT From 7540af933f2163d911d2b2d924151805756259b9 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Tue, 16 Sep 2025 10:38:47 +0200 Subject: [PATCH 5/5] fix: correct return statement formatting in ReactNativeAlertModule --- .../ReactNativeAlertModule.kt | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt index 5af340d..ceeb405 100644 --- a/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt +++ b/android/src/main/java/com/blazejkustra/reactnativealert/ReactNativeAlertModule.kt @@ -44,12 +44,12 @@ class ReactNativeAlertModule( if (dialogRef.get()?.isShowing == true) { return } - + val activity = currentActivity ?: return if (activity.isFinishing || activity.isDestroyed) return UiThreadUtil.runOnUiThread { - if (activity.isFinishing || activity.isDestroyed) return @runOnUiThread + if (activity.isFinishing || activity.isDestroyed) return@runOnUiThread val themed: Context = if (Build.VERSION.SDK_INT >= 29) { // Use system theme on Android 10+ (API 29+) @@ -75,19 +75,34 @@ class ReactNativeAlertModule( labels.getOrNull(0)?.let { text -> builder.setNeutralButton(text) { _, _ -> dialogRef.clear() - onAction.invoke(0 /*buttonClicked*/, 0 /*neutral*/, mainInput?.text?.toString(), usernameInput?.text?.toString()) + onAction.invoke( + 0 /*buttonClicked*/, + 0 /*neutral*/, + mainInput?.text?.toString(), + usernameInput?.text?.toString() + ) } } labels.getOrNull(1)?.let { text -> builder.setNegativeButton(text) { _, _ -> dialogRef.clear() - onAction.invoke(0, 1 /*negative*/, mainInput?.text?.toString(), usernameInput?.text?.toString()) + onAction.invoke( + 0, + 1 /*negative*/, + mainInput?.text?.toString(), + usernameInput?.text?.toString() + ) } } labels.getOrNull(2)?.let { text -> builder.setPositiveButton(text) { _, _ -> dialogRef.clear() - onAction.invoke(0, 2 /*positive*/, mainInput?.text?.toString(), usernameInput?.text?.toString()) + onAction.invoke( + 0, + 2 /*positive*/, + mainInput?.text?.toString(), + usernameInput?.text?.toString() + ) } } @@ -98,12 +113,12 @@ class ReactNativeAlertModule( val dialog = builder.create() dialogRef = WeakReference(dialog) - + // Set window soft input mode to show keyboard dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) - + dialog.show() - + // Show keyboard after dialog is shown val firstInput = usernameInput ?: mainInput firstInput?.let { input -> @@ -153,7 +168,10 @@ class ReactNativeAlertModule( val horizontalPad = 20.dp val verticalPad = 12.dp setPadding(horizontalPad, verticalPad, horizontalPad, verticalPad) - layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) } val isLogin = type == "login-password" @@ -205,12 +223,18 @@ class ReactNativeAlertModule( private fun applyKeyboardType(target: EditText, keyboardType: String?) { when (keyboardType) { - "email-address" -> target.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + "email-address" -> target.inputType = + InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + "numeric", "number-pad" -> target.inputType = InputType.TYPE_CLASS_NUMBER "phone-pad" -> target.inputType = InputType.TYPE_CLASS_PHONE - "decimal-pad" -> target.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + "decimal-pad" -> target.inputType = + InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + "url" -> target.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI - "web-search", "twitter" -> target.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD + "web-search", "twitter" -> target.inputType = + InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD + else -> Unit } } @@ -226,7 +250,8 @@ class ReactNativeAlertModule( if (hasKey(key) && !isNull(key)) getInt(key) else null private fun ReadableMap.getArrayOrEmpty(key: String): ReadableArray = - if (hasKey(key) && !isNull(key)) getArray(key) ?: Arguments.createArray() else Arguments.createArray() + if (hasKey(key) && !isNull(key)) getArray(key) + ?: Arguments.createArray() else Arguments.createArray() private fun ReadableArray.collectButtonLabels(max: Int): List { val out = ArrayList(max)