From 525b91f370854ea9321e2990a425109b41521cb4 Mon Sep 17 00:00:00 2001 From: Liuxinyu176 <1041316040@qq.com> Date: Sat, 10 Oct 2026 01:17:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(login):=20Trae/WorkBuddy=20INTL=20?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E6=89=8B=E6=9C=BA=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=B9=B6=E8=87=AA=E5=8A=A8=E5=9B=9E=E5=A1=AB?= =?UTF-8?q?=EF=BC=9BTrae=20CN=20=E4=BF=9D=E7=95=99=E8=BD=AF=E4=BB=B6?= =?UTF-8?q?=E5=86=85=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 +- .../ui/servicedetail/ServiceDetailScreen.kt | 14 +++++ .../token/ui/settings/CredentialEditScreen.kt | 62 +++++++++++-------- .../token/ui/webview/WebViewLoginScreen.kt | 13 ++++ app/src/main/res/values-b+zh+Hans/strings.xml | 1 + app/src/main/res/values-b+zh+Hant/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 7 files changed, 69 insertions(+), 27 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 45d7e94..ae369d6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,8 @@ android { applicationId = "com.rainy.token" minSdk = 31 targetSdk = 35 - versionCode = 41 - versionName = "1.7.21" + versionCode = 42 + versionName = "1.7.22" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt index c48e1a5..b68dadc 100644 --- a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt @@ -319,6 +319,7 @@ fun ServiceDetailScreen( hasCredential = uiState.hasCredential, isManualMode = isManualMode, service = service, + region = uiState.region, triggerState = triggerState, models = models, selectedModel = selectedModel, @@ -2105,6 +2106,7 @@ private fun ActionButtons( hasCredential: Boolean, isManualMode: Boolean, service: ServiceType, + region: String?, triggerState: TriggerState, models: List, selectedModel: String?, @@ -2225,6 +2227,18 @@ private fun ActionButtons( Spacer(modifier = Modifier.height(4.dp)) } + // Trae/WorkBuddy 国际版:直接应用内登录(回调解析凭据) + if ((service == ServiceType.TRAE || service == ServiceType.WORKBUDDY) && + region != null && region.equals("INTL", ignoreCase = true) + ) { + OutlinedButton( + onClick = onStartWebViewLogin, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.action_mobile_browser_login)) + } + } + if (hasCredential && !isManualMode) { Button( onClick = onRefresh, diff --git a/app/src/main/java/com/rainy/token/ui/settings/CredentialEditScreen.kt b/app/src/main/java/com/rainy/token/ui/settings/CredentialEditScreen.kt index 7448125..eb5ffba 100644 --- a/app/src/main/java/com/rainy/token/ui/settings/CredentialEditScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/settings/CredentialEditScreen.kt @@ -816,27 +816,37 @@ private fun TraeCredentialForm( style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.outline ) - OutlinedButton( - onClick = onStartInAppLogin, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_login_in_app)) + if (region.uppercase() != "INTL") { + OutlinedButton( + onClick = onStartInAppLogin, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.action_login_in_app)) + } } - OutlinedTextField( - value = callbackUrl, - onValueChange = onCallbackUrlChange, - label = { Text(stringResource(R.string.field_trae_callback_url)) }, - supportingText = { Text(stringResource(R.string.field_trae_callback_hint)) }, - minLines = 1, - maxLines = 3, - modifier = Modifier.fillMaxWidth() - ) - OutlinedButton( - onClick = { onImportCallback(callbackUrl) }, - enabled = callbackUrl.isNotBlank(), - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_parse_callback)) + if (region.uppercase() == "INTL") { + OutlinedButton( + onClick = onStartInAppLogin, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.action_mobile_browser_login)) + } + OutlinedTextField( + value = callbackUrl, + onValueChange = onCallbackUrlChange, + label = { Text(stringResource(R.string.field_trae_callback_url)) }, + supportingText = { Text(stringResource(R.string.field_trae_callback_hint)) }, + minLines = 1, + maxLines = 3, + modifier = Modifier.fillMaxWidth() + ) + OutlinedButton( + onClick = { onImportCallback(callbackUrl) }, + enabled = callbackUrl.isNotBlank(), + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.action_parse_callback)) + } } OutlinedTextField( value = jwt, @@ -976,11 +986,13 @@ private fun WorkBuddyCredentialForm( style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.outline ) - OutlinedButton( - onClick = onStartInAppLogin, - modifier = Modifier.fillMaxWidth() - ) { - Text(stringResource(R.string.action_login_in_app)) + if (region.uppercase() == "INTL") { + OutlinedButton( + onClick = onStartInAppLogin, + modifier = Modifier.fillMaxWidth() + ) { + Text(stringResource(R.string.action_mobile_browser_login)) + } } Text( text = stringResource(R.string.field_trae_region), diff --git a/app/src/main/java/com/rainy/token/ui/webview/WebViewLoginScreen.kt b/app/src/main/java/com/rainy/token/ui/webview/WebViewLoginScreen.kt index 19102cc..cf039a6 100644 --- a/app/src/main/java/com/rainy/token/ui/webview/WebViewLoginScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/webview/WebViewLoginScreen.kt @@ -37,6 +37,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.key import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.platform.LocalContext @@ -77,6 +78,18 @@ fun WebViewLoginScreen( val uiState by viewModel.uiState.collectAsStateWithLifecycle() val snackbarHostState = remember { SnackbarHostState() } val context = LocalContext.current + // Trae/WorkBuddy 国际版:进入即用手机浏览器登录,回调/轮询结果自动回填到应用 + val browserLoginService = service == ServiceType.TRAE || service == ServiceType.WORKBUDDY + val browserLoginRegion = region != null && region.equals("INTL", ignoreCase = true) + var autoBrowserStarted by rememberSaveable { mutableStateOf(false) } + LaunchedEffect(uiState.loginUrl, uiState.externalBrowserWaiting, uiState.loginSucceeded, autoBrowserStarted) { + if (browserLoginService && browserLoginRegion && !autoBrowserStarted && + uiState.loginUrl.isNotBlank() && !uiState.externalBrowserWaiting && !uiState.loginSucceeded + ) { + autoBrowserStarted = true + viewModel.openExternalBrowser() + } + } var webViewGeneration by remember { mutableStateOf(0) } var pageLoading by remember { mutableStateOf(true) } var pageError by remember { mutableStateOf(null) } diff --git a/app/src/main/res/values-b+zh+Hans/strings.xml b/app/src/main/res/values-b+zh+Hans/strings.xml index 1fa83c9..d996177 100644 --- a/app/src/main/res/values-b+zh+Hans/strings.xml +++ b/app/src/main/res/values-b+zh+Hans/strings.xml @@ -19,6 +19,7 @@ 清除 保存 软件内登录 + 手机浏览器登录 跳转 ◀ 上一页 下一页 ▶ diff --git a/app/src/main/res/values-b+zh+Hant/strings.xml b/app/src/main/res/values-b+zh+Hant/strings.xml index 8f6dedd..40e61b3 100644 --- a/app/src/main/res/values-b+zh+Hant/strings.xml +++ b/app/src/main/res/values-b+zh+Hant/strings.xml @@ -19,6 +19,7 @@ 清除 儲存 軟體內登入 + 手機瀏覽器登入 跳轉 ◀ 上一頁 下一頁 ▶ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd8f264..59f6e38 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,7 @@ Clear Save Sign in within app + Sign in via mobile browser Go ◀ Prev Next ▶