Skip to content

Commit bf721ee

Browse files
committed
v4.3.2: Fix smushed UI — FlowRow wrapping, proper text field sizing
- Source category chips: FlowRow wrapping (was single Row, overflowed on 8 cats) - Category chip padding increased (8x5 -> 10x6), text bumped 10sp -> 11sp - Custom upstream DNS field: defaultMinSize(52dp) instead of fixed height(44dp) - Search bar: defaultMinSize(52dp) instead of fixed height(48dp), text 14sp - DoH provider selector: single FlowRow replacing split two-Row layout - Feature pills (DoH, DNS Trap, etc): FlowRow wrapping for narrow screens - ExperimentalLayoutApi opt-in for FlowRow usage
1 parent f27c190 commit bf721ee

4 files changed

Lines changed: 28 additions & 44 deletions

File tree

CLAUDE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# HostShield
22

33
## Overview
4-
Modern, AMOLED-dark hosts-based ad blocker app for Android. Inspired by AdAway. v4.3.1.
4+
Modern, AMOLED-dark hosts-based ad blocker app for Android. Inspired by AdAway. v4.3.2.
55

66
## Tech Stack
77
- Kotlin, Jetpack Compose, Material 3
@@ -70,6 +70,7 @@ cd app
7070
- Secrets configured: `KEYSTORE_BASE64`, `KEY_ALIAS`, `KEY_PASSWORD`, `STORE_PASSWORD`
7171

7272
## Version History
73+
- v4.3.2: UI fixes — FlowRow wrapping for category chips (was smushed in single Row), larger text fields (search bar, custom DNS), FlowRow for DoH provider selector and feature pills, removed fixed heights that clipped text
7374
- v4.3.1: Bug audit — fix AutomationReceiver rate limiting (static companion state), GeoIpLookup atomic CAS window reset, SourceHealthWorker ensures alert channel exists, pauseResumeJob @Volatile, baselineRates synchronized list
7475
- v4.3.0: Notification pause/resume action (5-min pause from notification), CNAME CLOAK badge in log detail sheet, pretty upstream server labels (DoH:Cloudflare), source health DEAD notifications (push alert), alerts notification channel, pause state bypasses blocking
7576
- v4.2.0: Fix DNS log data starvation (CNAME chains, resolved IPs, latency, upstream server now written to DB), CNAME-blocked domains now logged, fd error tracking + auto-restart on TUN error, IPv6 DoH support (honours useDoH flag), IPv6 DNS cache lookup, DohBypassUpdater uses shared OkHttpClient, app context threaded through all forward methods

app/app/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// HostShield v4.3.1
1+
// HostShield v4.3.2
22
plugins {
33
id("com.android.application")
44
id("org.jetbrains.kotlin.android")
@@ -15,8 +15,8 @@ android {
1515
applicationId = "com.hostshield"
1616
minSdk = 26
1717
targetSdk = 35
18-
versionCode = 44
19-
versionName = "4.3.1"
18+
versionCode = 45
19+
versionName = "4.3.2"
2020

2121
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2222

app/app/src/main/java/com/hostshield/ui/screens/home/HomeScreen.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import kotlin.math.sin
4141

4242
// HostShield v1.6.0 — Premium Home Dashboard
4343

44+
@OptIn(androidx.compose.foundation.layout.ExperimentalLayoutApi::class)
4445
@Composable
4546
fun HomeScreen(
4647
viewModel: HomeViewModel = hiltViewModel(),
@@ -105,9 +106,9 @@ fun HomeScreen(
105106
}
106107
}
107108
},
108-
modifier = Modifier.fillMaxWidth().padding(horizontal = 20.dp).height(48.dp),
109+
modifier = Modifier.fillMaxWidth().padding(horizontal = 20.dp).defaultMinSize(minHeight = 52.dp),
109110
singleLine = true, shape = RoundedCornerShape(12.dp),
110-
textStyle = LocalTextStyle.current.copy(fontSize = 13.sp),
111+
textStyle = LocalTextStyle.current.copy(fontSize = 14.sp),
111112
colors = OutlinedTextFieldDefaults.colors(
112113
focusedBorderColor = Teal, unfocusedBorderColor = Surface3,
113114
cursorColor = Teal, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary
@@ -384,9 +385,10 @@ fun HomeScreen(
384385
// Feature status pills (VPN mode only)
385386
if (state.isEnabled && state.blockMethod == com.hostshield.data.model.BlockMethod.VPN) {
386387
Spacer(Modifier.height(8.dp))
387-
Row(
388+
androidx.compose.foundation.layout.FlowRow(
388389
modifier = Modifier.fillMaxWidth().padding(horizontal = 20.dp),
389-
horizontalArrangement = Arrangement.spacedBy(6.dp)
390+
horizontalArrangement = Arrangement.spacedBy(6.dp),
391+
verticalArrangement = Arrangement.spacedBy(6.dp)
390392
) {
391393
if (state.dohEnabled) {
392394
FeaturePill("DoH", Blue)
@@ -534,11 +536,12 @@ fun HomeScreen(
534536
"ADULT" to Flamingo, "SOCIAL" to Mauve, "CRYPTO" to Peach,
535537
"ALLOWLIST" to Green, "CUSTOM" to Yellow
536538
)
537-
// Use FlowRow-like wrapping with multiple Rows
538539
val cats = state.categoryCounts.entries.sortedBy { it.key }
539-
Row(
540+
// Wrap chips across multiple rows using FlowRow
541+
androidx.compose.foundation.layout.FlowRow(
540542
modifier = Modifier.fillMaxWidth(),
541-
horizontalArrangement = Arrangement.spacedBy(6.dp)
543+
horizontalArrangement = Arrangement.spacedBy(6.dp),
544+
verticalArrangement = Arrangement.spacedBy(6.dp)
542545
) {
543546
cats.forEach { (cat, counts) ->
544547
val (enabled, total) = counts
@@ -550,16 +553,16 @@ fun HomeScreen(
550553
color = if (allEnabled) color.copy(alpha = 0.12f) else Surface2
551554
) {
552555
Row(
553-
modifier = Modifier.padding(horizontal = 8.dp, vertical = 5.dp),
556+
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
554557
verticalAlignment = Alignment.CenterVertically
555558
) {
556559
Text(
557560
cat.lowercase().replaceFirstChar { it.uppercase() },
558561
color = if (allEnabled) color else TextDim,
559-
fontSize = 10.sp, fontWeight = FontWeight.SemiBold
562+
fontSize = 11.sp, fontWeight = FontWeight.SemiBold
560563
)
561564
Spacer(Modifier.width(4.dp))
562-
Text("$enabled/$total", color = TextDim, fontSize = 8.sp)
565+
Text("$enabled/$total", color = TextDim, fontSize = 9.sp)
563566
}
564567
}
565568
}

app/app/src/main/java/com/hostshield/ui/screens/settings/SettingsScreen.kt

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -129,18 +129,18 @@ fun SettingsScreen(
129129
value = customDns,
130130
onValueChange = { customDns = it },
131131
placeholder = { Text("e.g. 1.1.1.1, 9.9.9.9", color = TextDim, fontSize = 12.sp) },
132-
modifier = Modifier.fillMaxWidth().height(44.dp),
132+
modifier = Modifier.fillMaxWidth().defaultMinSize(minHeight = 52.dp),
133133
singleLine = true,
134-
textStyle = LocalTextStyle.current.copy(fontSize = 12.sp),
135-
shape = RoundedCornerShape(8.dp),
134+
textStyle = LocalTextStyle.current.copy(fontSize = 13.sp),
135+
shape = RoundedCornerShape(10.dp),
136136
colors = OutlinedTextFieldDefaults.colors(
137137
focusedBorderColor = Blue, unfocusedBorderColor = Surface3,
138138
cursorColor = Blue, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary
139139
),
140140
trailingIcon = {
141141
if (customDns != state.customUpstreamDns) {
142142
IconButton(onClick = { viewModel.setCustomUpstreamDns(customDns) }) {
143-
Icon(Icons.Filled.Check, null, tint = Green, modifier = Modifier.size(16.dp))
143+
Icon(Icons.Filled.Check, null, tint = Green, modifier = Modifier.size(18.dp))
144144
}
145145
}
146146
}
@@ -745,6 +745,7 @@ private fun SettingsRow(
745745
}
746746
}
747747

748+
@OptIn(androidx.compose.foundation.layout.ExperimentalLayoutApi::class)
748749
@Composable
749750
private fun DohProviderSelector(current: String, onSelect: (String) -> Unit) {
750751
val providers = listOf(
@@ -754,33 +755,12 @@ private fun DohProviderSelector(current: String, onSelect: (String) -> Unit) {
754755
"nextdns" to "NextDNS",
755756
"adguard" to "AdGuard"
756757
)
757-
Row(
758-
horizontalArrangement = Arrangement.spacedBy(6.dp),
759-
modifier = Modifier.fillMaxWidth()
760-
) {
761-
providers.take(3).forEach { (key, label) ->
762-
val selected = current == key
763-
Surface(
764-
onClick = { onSelect(key) },
765-
shape = RoundedCornerShape(8.dp),
766-
color = if (selected) Blue.copy(alpha = 0.12f) else Surface2
767-
) {
768-
Text(
769-
label,
770-
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
771-
color = if (selected) Blue else TextDim,
772-
fontSize = 11.sp,
773-
fontWeight = FontWeight.SemiBold
774-
)
775-
}
776-
}
777-
}
778-
Spacer(Modifier.height(4.dp))
779-
Row(
758+
androidx.compose.foundation.layout.FlowRow(
780759
horizontalArrangement = Arrangement.spacedBy(6.dp),
760+
verticalArrangement = Arrangement.spacedBy(6.dp),
781761
modifier = Modifier.fillMaxWidth()
782762
) {
783-
providers.drop(3).forEach { (key, label) ->
763+
providers.forEach { (key, label) ->
784764
val selected = current == key
785765
Surface(
786766
onClick = { onSelect(key) },
@@ -789,9 +769,9 @@ private fun DohProviderSelector(current: String, onSelect: (String) -> Unit) {
789769
) {
790770
Text(
791771
label,
792-
modifier = Modifier.padding(horizontal = 10.dp, vertical = 6.dp),
772+
modifier = Modifier.padding(horizontal = 12.dp, vertical = 7.dp),
793773
color = if (selected) Blue else TextDim,
794-
fontSize = 11.sp,
774+
fontSize = 12.sp,
795775
fontWeight = FontWeight.SemiBold
796776
)
797777
}

0 commit comments

Comments
 (0)