fix: move shared browser/napplet strings to :commons to eliminate cross-module duplicate

AGP 9.2.1 treats resources defined in both an app module and a library module
with the same key (qualifiers="") as an error in non-debug builds.

`browser_address_hint`, `browser_console_title_short`, `browser_console_title`,
`browser_console_clear`, and `napplet_untitled` were defined in both
`:amethyst/values/strings.xml` and `:nappletHost/values/strings.xml`.
Both `:amethyst` and `:nappletHost` depend on `:commons`, so the canonical
home for these shared strings is `commons/src/androidMain/res/values/strings.xml`.

Update callers in both modules to use `com.vitorpamplona.amethyst.commons.R as
CommonsR`. Locale translations in amethyst's `values-*/` directories remain as
Android resource overlays (app module overrides library module at merge time).

Fixes: Found item String/browser_console_clear more than one time (packageFdroidBenchmarkResources)
This commit is contained in:
Claude
2026-06-26 00:11:31 +00:00
parent a1732155b1
commit f2a7548434
11 changed files with 34 additions and 29 deletions
@@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.napplet.NappletWebContract
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.util.concurrent.Executor
import com.vitorpamplona.amethyst.commons.R as CommonsR
/**
* Full-screen **direct-WebView** browser for an arbitrary URL, running in the keyless `:napplet`
@@ -578,7 +579,7 @@ class NappletBrowserActivity : ComponentActivity() {
private var title: String = ""
private fun barTitle(): String = title.ifBlank { runCatching { Uri.parse(startUrl).host }.getOrNull() ?: getString(R.string.napplet_untitled) }
private fun barTitle(): String = title.ifBlank { runCatching { Uri.parse(startUrl).host }.getOrNull() ?: getString(CommonsR.string.napplet_untitled) }
/**
* The top pull-down sheet: a small grabber at the top edge (out of the corner where a site shows its
@@ -34,6 +34,7 @@ import android.widget.LinearLayout
import android.widget.ScrollView
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.vitorpamplona.amethyst.commons.R as CommonsR
/**
* The full-screen browser's **bottom pull-up sheet** for JavaScript console output. Collapsed it's
@@ -83,7 +84,7 @@ class NappletConsolePanel(
setPadding(dp(8), 0, dp(4), dp(4))
addView(
TextView(context).apply {
text = context.getString(R.string.browser_console_title_short)
text = context.getString(CommonsR.string.browser_console_title_short)
setTextColor(dimmed)
textSize = 12f
layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f)
@@ -91,7 +92,7 @@ class NappletConsolePanel(
)
addView(
TextView(context).apply {
text = context.getString(R.string.browser_console_clear)
text = context.getString(CommonsR.string.browser_console_clear)
setTextColor(dimmed)
textSize = 12f
setPadding(dp(12), dp(6), dp(12), dp(6))
@@ -210,7 +211,7 @@ class NappletConsolePanel(
setColor(withAlpha(surface, 0.6f))
}
isClickable = true
contentDescription = context.getString(R.string.browser_console_title_short)
contentDescription = context.getString(CommonsR.string.browser_console_title_short)
addView(bar)
var downY = 0f
@@ -37,6 +37,7 @@ import android.widget.LinearLayout
import android.widget.Switch
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.vitorpamplona.amethyst.commons.R as CommonsR
/**
* The full-screen sandbox surfaces' **top pull-down sheet** the native-View twin of the embedded
@@ -131,7 +132,7 @@ class NappletControlSheet(
onConsole?.let { console ->
val label =
TextView(context).apply {
text = context.getString(R.string.browser_console_title_short)
text = context.getString(CommonsR.string.browser_console_title_short)
setTextColor(onSurface)
textSize = 15f
setPadding(dp(8), 0, 0, 0)
@@ -235,8 +236,8 @@ class NappletControlSheet(
setText(initial)
setTextColor(onSurface)
setHintTextColor(dimmed)
hint = context.getString(R.string.browser_address_hint)
contentDescription = context.getString(R.string.browser_address_hint)
hint = context.getString(CommonsR.string.browser_address_hint)
contentDescription = context.getString(CommonsR.string.browser_address_hint)
textSize = 15f
isSingleLine = true
setSelectAllOnFocus(true)
@@ -276,9 +277,9 @@ class NappletControlSheet(
fun updateConsoleCount(count: Int) {
consoleLabel?.text =
if (count > 0) {
context.getString(R.string.browser_console_title, count)
context.getString(CommonsR.string.browser_console_title, count)
} else {
context.getString(R.string.browser_console_title_short)
context.getString(CommonsR.string.browser_console_title_short)
}
}
@@ -79,6 +79,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.util.concurrent.Executor
import com.vitorpamplona.amethyst.commons.R as CommonsR
/**
* Hosts a napplet/nsite WebView in the isolated `:napplet` process a process that holds **no**
@@ -715,7 +716,7 @@ class NappletHostActivity : ComponentActivity() {
// ---- trusted sandbox chrome ----
private fun barTitle(): String = title.ifBlank { getString(R.string.napplet_untitled) }
private fun barTitle(): String = title.ifBlank { getString(CommonsR.string.napplet_untitled) }
/**
* The trusted top pull-down sheet: a small grabber at the top edge (out of the corner where the app
+2 -7
View File
@@ -3,7 +3,7 @@
<!-- Sandbox host (`:napplet` process) UI. Kept here so the sandbox module needs no app resources. -->
<string name="napplet_invalid">Invalid nApplet.</string>
<string name="napplet_webview_too_old">This device\'s WebView is too old to run nApplets safely.</string>
<string name="napplet_untitled">Untitled nApplet</string>
<!-- Trusted chrome (top bar + live action notices) -->
<string name="napplet_chrome_access_title">What “%1$s” can access</string>
@@ -11,12 +11,7 @@
<string name="napplet_chrome_static_site">Static site — it has no special access to your account.</string>
<string name="napplet_chrome_permissions_desc">What this app can access</string>
<string name="napplet_chrome_reload">Reload</string>
<!-- Browser address bar (direct-WebView browser only) -->
<string name="browser_address_hint">Search or enter address</string>
<!-- Browser developer console -->
<string name="browser_console_title_short">Console</string>
<string name="browser_console_title">Console (%1$d)</string>
<string name="browser_console_clear">Clear</string>
<!-- Browser address bar and developer console strings are in :commons -->
<string name="napplet_action_published">“%1$s” published a note as you</string>
<string name="napplet_action_uploaded">“%1$s” uploaded a file</string>
<string name="napplet_action_paid">“%1$s” made a payment</string>