Skip to content

Commit dab230c

Browse files
authored
fix: compose passive sitekey (#165)
* fix: infinite loading on hideDialog=true * feat: update compose example to add hideDialog checkbox * chore: bump to 4.0.2
1 parent e920635 commit dab230c

File tree

6 files changed

+92
-15
lines changed

6 files changed

+92
-15
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
# 4.0.2
4+
5+
- Fix: passive site keys (hideDialog=true) broken for `compose-sdk`
6+
37
# 4.0.1
48

59
- Feat: release of `compose-sdk`

compose-sdk/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ android {
2020
// See https://developer.android.com/studio/publish/versioning
2121
// versionCode must be integer and be incremented by one for every new update
2222
// android system uses this to prevent downgrades
23-
versionCode 40
23+
versionCode 41
2424

2525
// version number visible to the user
2626
// should follow semantic versioning (See https://semver.org)
27-
versionName "4.0.1"
27+
versionName "4.0.2"
2828

2929
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
3030
consumerProguardFiles "consumer-rules.pro"

compose-sdk/src/main/java/com/hcaptcha/sdk/HCaptchaCompose.kt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,29 @@ import android.app.Activity
44
import android.os.Handler
55
import android.os.Looper
66
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.foundation.layout.size
78
import androidx.compose.runtime.Composable
89
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.unit.dp
911
import androidx.compose.ui.viewinterop.AndroidView
1012
import androidx.compose.ui.window.Dialog
1113
import androidx.compose.ui.window.DialogProperties
1214

1315
@Composable
1416
public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse) -> Unit) {
1517
val handler = Handler(Looper.getMainLooper())
18+
var helper: HCaptchaWebViewHelper? = null
1619
val verifier = object : IHCaptchaVerifier {
1720
override fun onLoaded() {
1821
onResult(HCaptchaResponse.Event(HCaptchaEvent.Loaded))
22+
if (config.hideDialog) {
23+
helper?.let {
24+
it.resetAndExecute()
25+
} ?: run {
26+
HCaptchaLog.w("HCaptchaWebViewHelper wasn't created, report but to developer")
27+
onResult(HCaptchaResponse.Failure(HCaptchaError.INTERNAL_ERROR))
28+
}
29+
}
1930
}
2031

2132
override fun onOpen() {
@@ -39,13 +50,16 @@ public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse)
3950
}
4051
}
4152
val internalConfig = HCaptchaInternalConfig(com.hcaptcha.sdk.HCaptchaHtml())
53+
HCaptchaLog.sDiagnosticsLogEnabled = config.diagnosticLog
54+
55+
HCaptchaLog.d("HCaptchaCompose($config)")
4256

43-
Dialog(onDismissRequest = {}, properties = DialogProperties(usePlatformDefaultWidth = false)) {
57+
if (config.hideDialog) {
4458
AndroidView(
45-
modifier = Modifier.fillMaxSize(),
59+
modifier = Modifier.size(0.dp),
4660
factory = { context ->
4761
HCaptchaWebView(context).apply {
48-
HCaptchaWebViewHelper(
62+
helper = HCaptchaWebViewHelper(
4963
handler,
5064
context,
5165
config,
@@ -56,5 +70,26 @@ public fun HCaptchaCompose(config: HCaptchaConfig, onResult: (HCaptchaResponse)
5670
}
5771
}
5872
)
73+
} else {
74+
Dialog(
75+
onDismissRequest = {},
76+
properties = DialogProperties(usePlatformDefaultWidth = false)
77+
) {
78+
AndroidView(
79+
modifier = Modifier.fillMaxSize(),
80+
factory = { context ->
81+
HCaptchaWebView(context).apply {
82+
helper = HCaptchaWebViewHelper(
83+
handler,
84+
context,
85+
config,
86+
internalConfig,
87+
verifier,
88+
this
89+
)
90+
}
91+
}
92+
)
93+
}
5994
}
6095
}

example-compose-app/src/main/java/com/hcaptcha/example/compose/ComposeActivity.kt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.*
88
import androidx.compose.foundation.layout.Arrangement
99
import androidx.compose.runtime.*
1010
import androidx.compose.material3.Button
11+
import androidx.compose.material3.Checkbox
1112
import androidx.compose.material3.CircularProgressIndicator
1213
import androidx.compose.material3.MaterialTheme
1314
import androidx.compose.material3.Text
@@ -28,31 +29,49 @@ class ComposeActivity : ComponentActivity() {
2829
setContent {
2930
var hCaptchaStarted by remember { mutableStateOf(false) }
3031
var hCaptchaLoaded by remember { mutableStateOf(false) }
32+
var hideDialog by remember { mutableStateOf(false) }
3133
var text by remember { mutableStateOf("") }
3234

3335
Column(
3436
modifier = Modifier.fillMaxSize().padding(16.dp),
3537
verticalArrangement = Arrangement.Bottom
3638
) {
37-
// Multiline Text
3839
TextField(
3940
value = text,
41+
placeholder = { Text("Verification result will be here...") },
4042
onValueChange = { newText -> text = newText },
4143
modifier = Modifier
4244
.fillMaxWidth()
4345
.height(200.dp)
4446
.background(Color.Gray)
4547
)
4648

49+
Spacer(modifier = Modifier.weight(1f))
50+
51+
Row(
52+
verticalAlignment = Alignment.CenterVertically
53+
) {
54+
Checkbox(
55+
checked = hideDialog,
56+
onCheckedChange = { isChecked ->
57+
hideDialog = isChecked
58+
}
59+
)
60+
61+
Text(
62+
text = "Hide Dialog (Passive Site Key)",
63+
)
64+
}
65+
4766
Button(
4867
onClick = {
4968
hCaptchaStarted = !hCaptchaStarted
5069
},
5170
modifier = Modifier
5271
.fillMaxWidth()
53-
.padding(top = 16.dp)
72+
.padding(vertical = 16.dp)
5473
) {
55-
Text(text = "Toggle WebView")
74+
Text(text = "Verify with HCaptcha")
5675
}
5776

5877
if (hCaptchaStarted && !hCaptchaLoaded) {
@@ -68,11 +87,12 @@ class ComposeActivity : ComponentActivity() {
6887
}
6988
}
7089

71-
// WebView Dialog
7290
if (hCaptchaStarted) {
7391
HCaptchaCompose(HCaptchaConfig
7492
.builder()
7593
.siteKey("10000000-ffff-ffff-ffff-000000000001")
94+
.hideDialog(hideDialog)
95+
.diagnosticLog(true)
7696
.build()) { result ->
7797
when (result) {
7898
is HCaptchaResponse.Success -> {
@@ -89,7 +109,7 @@ class ComposeActivity : ComponentActivity() {
89109
}
90110
is HCaptchaResponse.Event -> {
91111
if (result.event == HCaptchaEvent.Opened) {
92-
hCaptchaLoaded = true;
112+
hCaptchaLoaded = true
93113
}
94114
println("Event: ${result.event}")
95115
}

sdk/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ android {
2828
// See https://developer.android.com/studio/publish/versioning
2929
// versionCode must be integer and be incremented by one for every new update
3030
// android system uses this to prevent downgrades
31-
versionCode 40
31+
versionCode 41
3232

3333
// version number visible to the user
3434
// should follow semantic versioning (See https://semver.org)
35-
versionName "4.0.1"
35+
versionName "4.0.2"
3636

3737
buildConfigField 'String', 'VERSION_NAME', "\"${defaultConfig.versionName}_${defaultConfig.versionCode}\""
3838

test/src/androidTest/java/com/hcaptcha/sdk/compose/HCaptchaComposeTest.kt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.hcaptcha.sdk.HCaptchaCompose
1616
import com.hcaptcha.sdk.HCaptchaConfig
1717
import com.hcaptcha.sdk.HCaptchaError
1818
import com.hcaptcha.sdk.HCaptchaResponse
19+
import com.hcaptcha.sdk.HCaptchaSize
1920
import kotlinx.coroutines.delay
2021
import kotlinx.coroutines.runBlocking
2122
import org.junit.Rule
@@ -25,22 +26,29 @@ import java.util.concurrent.TimeUnit
2526

2627
@RunWith(AndroidJUnit4::class)
2728
class HCaptchaComposeTest {
29+
companion object {
30+
const val SITE_KEY = "10000000-ffff-ffff-ffff-000000000001"
31+
const val TEST_TOKEN = "10000000-aaaa-bbbb-cccc-000000000001"
32+
}
33+
2834
private val resultContentDescription = "HCaptchaResultString"
2935
private val timeout = TimeUnit.SECONDS.toMillis(4)
3036

3137
@get:Rule
3238
val composeTestRule = createComposeRule()
3339

34-
fun setContent(token: String = "10000000-ffff-ffff-ffff-000000000001") {
40+
fun setContent(siteKey: String = SITE_KEY, passiveSiteKey: Boolean = false) {
3541
composeTestRule.setContent {
3642
var text by remember { mutableStateOf("<init>") }
3743
Column {
3844
Text(text = text, modifier = Modifier.semantics { contentDescription = resultContentDescription })
3945

4046
HCaptchaCompose(HCaptchaConfig
4147
.builder()
42-
.siteKey(token)
48+
.siteKey(siteKey)
4349
.diagnosticLog(true)
50+
.size(HCaptchaSize.INVISIBLE)
51+
.hideDialog(passiveSiteKey)
4452
.build()) { result ->
4553
when (result) {
4654
is HCaptchaResponse.Success -> {
@@ -63,7 +71,7 @@ class HCaptchaComposeTest {
6371
runBlocking { delay(timeout) }
6472

6573
composeTestRule.onNodeWithContentDescription(resultContentDescription)
66-
.assertTextEquals("10000000-aaaa-bbbb-cccc-000000000001")
74+
.assertTextEquals(TEST_TOKEN)
6775
}
6876

6977
@Test
@@ -75,4 +83,14 @@ class HCaptchaComposeTest {
7583
composeTestRule.onNodeWithContentDescription(resultContentDescription)
7684
.assertTextContains(HCaptchaError.ERROR.name)
7785
}
86+
87+
@Test
88+
fun passiveSiteKey() {
89+
setContent(SITE_KEY, true)
90+
91+
runBlocking { delay(timeout) }
92+
93+
composeTestRule.onNodeWithContentDescription(resultContentDescription)
94+
.assertTextEquals(TEST_TOKEN)
95+
}
7896
}

0 commit comments

Comments
 (0)