Skip to content

Commit e41e0ea

Browse files
committed
Improve compose setup & styling further, and convert QR code too
1 parent efd5c5f commit e41e0ea

File tree

11 files changed

+125
-111
lines changed

11 files changed

+125
-111
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ dependencies {
7070
implementation(libs.compose.material.icons.extended)
7171
implementation(libs.activity.compose)
7272
implementation(libs.accompanist.drawablepainter)
73+
implementation(libs.foundation)
7374
debugImplementation(libs.compose.ui.tooling)
7475
implementation(libs.core.ktx)
7576
implementation(libs.constraintlayout)

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
</intent-filter>
102102
</activity-alias>
103103

104-
<activity android:name=".QRScanActivity" android:parentActivityName=".MainActivity">
104+
<activity android:name=".qrscan.QRScanActivity" android:parentActivityName=".MainActivity">
105105
<meta-data
106106
android:name="android.support.PARENT_ACTIVITY"
107107
android:value=".MainActivity" />

app/src/main/java/tech/httptoolkit/android/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import androidx.core.view.isVisible
4343
import androidx.core.net.toUri
4444
import tech.httptoolkit.android.appselection.ApplicationListActivity
4545
import tech.httptoolkit.android.portfilter.PortListActivity
46+
import tech.httptoolkit.android.qrscan.QRScanActivity
4647

4748

4849
const val START_VPN_REQUEST = 123

app/src/main/java/tech/httptoolkit/android/QRScanActivity.kt

Lines changed: 0 additions & 63 deletions
This file was deleted.

app/src/main/java/tech/httptoolkit/android/appselection/AppListScreen.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import androidx.compose.ui.platform.LocalContext
1717
import androidx.compose.ui.res.stringResource
1818
import androidx.compose.ui.text.style.TextOverflow
1919
import androidx.compose.ui.unit.dp
20+
import androidx.compose.ui.zIndex
2021
import com.google.accompanist.drawablepainter.rememberDrawablePainter
2122
import kotlinx.coroutines.Dispatchers
2223
import kotlinx.coroutines.withContext
@@ -76,8 +77,10 @@ fun AppListScreen(
7677
Card(
7778
modifier = Modifier
7879
.fillMaxWidth()
79-
.padding(vertical = 8.dp),
80-
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
80+
.padding(top = 8.dp)
81+
.zIndex(1f),
82+
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
83+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
8184
) {
8285
Row(
8386
modifier = Modifier
@@ -94,8 +97,8 @@ fun AppListScreen(
9497
.padding(vertical = 8.dp),
9598
singleLine = true,
9699
colors = TextFieldDefaults.colors(
97-
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
98-
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
100+
focusedContainerColor = MaterialTheme.colorScheme.surface,
101+
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
99102
focusedIndicatorColor = androidx.compose.ui.graphics.Color.Transparent,
100103
unfocusedIndicatorColor = androidx.compose.ui.graphics.Color.Transparent
101104
)
@@ -224,12 +227,13 @@ fun AppListItem(
224227
Card(
225228
modifier = modifier
226229
.fillMaxWidth()
227-
.padding(vertical = 4.dp, horizontal = 8.dp)
230+
.padding(vertical = 4.dp, horizontal = 8.dp),
231+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
228232
) {
229233
Row(
230234
modifier = Modifier
231235
.fillMaxWidth()
232-
.padding(8.dp),
236+
.padding(vertical = 8.dp, horizontal = 16.dp),
233237
verticalAlignment = Alignment.CenterVertically
234238
) {
235239
// App icon
@@ -238,14 +242,14 @@ fun AppListItem(
238242
contentDescription = "App icon for $appLabel",
239243
modifier = Modifier
240244
.size(72.dp)
241-
.padding(8.dp)
245+
.padding(vertical = 8.dp)
242246
)
243247

244248
// App name and package
245249
Column(
246250
modifier = Modifier
247251
.weight(1f)
248-
.padding(horizontal = 16.dp)
252+
.padding(horizontal = 8.dp)
249253
) {
250254
Text(
251255
text = appLabel,
@@ -264,7 +268,9 @@ fun AppListItem(
264268
// Enable/disable switch
265269
Switch(
266270
checked = isEnabled,
267-
onCheckedChange = onEnabledChange
271+
onCheckedChange = onEnabledChange,
272+
modifier = Modifier
273+
.padding(end = 8.dp)
268274
)
269275
}
270276
}

app/src/main/java/tech/httptoolkit/android/portfilter/PortListScreen.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package tech.httptoolkit.android.portfilter
22

3+
import androidx.compose.foundation.background
34
import androidx.compose.foundation.layout.*
45
import androidx.compose.foundation.lazy.LazyColumn
56
import androidx.compose.foundation.lazy.items
@@ -18,6 +19,7 @@ import androidx.compose.ui.text.input.ImeAction
1819
import androidx.compose.ui.text.input.KeyboardType
1920
import androidx.compose.ui.text.style.TextOverflow
2021
import androidx.compose.ui.unit.dp
22+
import androidx.compose.ui.zIndex
2123
import tech.httptoolkit.android.R
2224

2325
@Composable
@@ -58,6 +60,7 @@ fun PortListScreen(
5860
.fillMaxSize()
5961
.windowInsetsPadding(WindowInsets.statusBars.only(WindowInsetsSides.Top))
6062
.padding(horizontal = 16.dp)
63+
.background(MaterialTheme.colorScheme.background),
6164
) {
6265
// Explanation text
6366
Text(
@@ -71,8 +74,10 @@ fun PortListScreen(
7174
Card(
7275
modifier = Modifier
7376
.fillMaxWidth()
74-
.padding(vertical = 8.dp),
75-
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
77+
.padding(top = 8.dp)
78+
.zIndex(1f),
79+
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
80+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
7681
) {
7782
Row(
7883
modifier = Modifier
@@ -96,8 +101,8 @@ fun PortListScreen(
96101
.padding(vertical = 8.dp),
97102
singleLine = true,
98103
colors = TextFieldDefaults.colors(
99-
focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
100-
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant,
104+
focusedContainerColor = MaterialTheme.colorScheme.surface,
105+
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
101106
focusedIndicatorColor = androidx.compose.ui.graphics.Color.Transparent,
102107
unfocusedIndicatorColor = androidx.compose.ui.graphics.Color.Transparent
103108
)
@@ -169,7 +174,8 @@ fun PortItem(
169174
Card(
170175
modifier = modifier
171176
.fillMaxWidth()
172-
.padding(vertical = 4.dp, horizontal = 8.dp)
177+
.padding(vertical = 4.dp, horizontal = 8.dp),
178+
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
173179
) {
174180
Row(
175181
modifier = Modifier
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package tech.httptoolkit.android.qrscan
2+
3+
import android.content.Intent
4+
import android.os.Bundle
5+
import androidx.activity.ComponentActivity
6+
import androidx.activity.compose.setContent
7+
import androidx.activity.enableEdgeToEdge
8+
import tech.httptoolkit.android.IntentExtras
9+
import tech.httptoolkit.android.ui.HttpToolkitTheme
10+
11+
class QRScanActivity : ComponentActivity() {
12+
13+
override fun onCreate(savedInstanceState: Bundle?) {
14+
super.onCreate(savedInstanceState)
15+
enableEdgeToEdge()
16+
17+
setContent {
18+
HttpToolkitTheme {
19+
QRScanScreen(
20+
onQRCodeScanned = { scannedUrl ->
21+
setResult(RESULT_OK, Intent().putExtra(
22+
IntentExtras.SCANNED_URL_EXTRA,
23+
scannedUrl
24+
))
25+
finish()
26+
}
27+
)
28+
}
29+
}
30+
}
31+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package tech.httptoolkit.android.qrscan
2+
3+
import android.util.Log
4+
import androidx.compose.foundation.layout.*
5+
import androidx.compose.runtime.*
6+
import androidx.compose.ui.Modifier
7+
import androidx.compose.ui.viewinterop.AndroidView
8+
import com.google.zxing.BarcodeFormat
9+
import com.google.zxing.ResultPoint
10+
import com.journeyapps.barcodescanner.BarcodeCallback
11+
import com.journeyapps.barcodescanner.BarcodeResult
12+
import com.journeyapps.barcodescanner.DecoratedBarcodeView
13+
import com.journeyapps.barcodescanner.DefaultDecoderFactory
14+
15+
@Composable
16+
fun QRScanScreen(
17+
onQRCodeScanned: (String) -> Unit,
18+
modifier: Modifier = Modifier
19+
) {
20+
AndroidView(
21+
factory = { context ->
22+
var lastScannedText: String? = null
23+
24+
DecoratedBarcodeView(context).apply {
25+
barcodeView.decoderFactory = DefaultDecoderFactory(listOf(BarcodeFormat.QR_CODE))
26+
setStatusText("Scan HTTP Toolkit QR code to connect")
27+
28+
val callback = object : BarcodeCallback {
29+
override fun barcodeResult(result: BarcodeResult) {
30+
val resultText = result.text
31+
if (resultText == null || resultText == lastScannedText) {
32+
// Prevent duplicate scans
33+
return
34+
}
35+
36+
lastScannedText = resultText
37+
Log.i("QRScanScreen", "Scanned: $resultText")
38+
39+
if (resultText.startsWith("https://android.httptoolkit.tech/connect/")) {
40+
onQRCodeScanned(resultText)
41+
}
42+
}
43+
44+
override fun possibleResultPoints(resultPoints: MutableList<ResultPoint?>?) {
45+
// Not needed
46+
}
47+
}
48+
49+
decodeContinuous(callback)
50+
resume()
51+
}
52+
},
53+
modifier = modifier.fillMaxSize(),
54+
onRelease = { barcodeView ->
55+
barcodeView.pause()
56+
}
57+
)
58+
}

app/src/main/java/tech/httptoolkit/android/ui/AppTheme.kt

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,33 @@
11
package tech.httptoolkit.android.ui
22

3-
import android.os.Build
43
import androidx.compose.foundation.isSystemInDarkTheme
54
import androidx.compose.material3.*
65
import androidx.compose.runtime.Composable
76
import androidx.compose.ui.graphics.Color
8-
import androidx.compose.ui.platform.LocalContext
97

10-
// Light theme colors from values/colors.xml
118
private val LightColors = lightColorScheme(
129
primary = Color(0xFF2D4CBD),
1310
onPrimary = Color(0xFFFFFFFF),
1411
secondary = Color(0xFFE1421F),
1512
onSecondary = Color(0xFFFFFFFF),
16-
background = Color(0xFFFAFAFA),
13+
background = Color(0xFFE4E8ED), // Background = 'container' in UI themes
1714
onBackground = Color(0xFF1E2028),
18-
surface = Color(0xFFE4E8ED),
15+
surface = Color(0xFFFAFAFA), // Surface = 'main' in UI themes
1916
onSurface = Color(0xFF1E2028),
20-
surfaceVariant = Color(0xFFFAFAFA),
21-
onSurfaceVariant = Color(0xFF1E2028),
2217
outline = Color(0xFF818490),
2318
error = Color(0xFFE1421F),
2419
onError = Color(0xFFFFFFFF)
2520
)
2621

27-
// Dark theme colors from values-night/colors.xml
2822
private val DarkColors = darkColorScheme(
2923
primary = Color(0xFF2D4CBD),
3024
onPrimary = Color(0xFFFFFFFF),
3125
secondary = Color(0xFFE1421F),
3226
onSecondary = Color(0xFFFFFFFF),
33-
background = Color(0xFF32343B),
27+
background = Color(0xFF1E2028),
3428
onBackground = Color(0xFFFFFFFF),
35-
surface = Color(0xFF1E2028),
29+
surface = Color(0xFF32343B),
3630
onSurface = Color(0xFFFFFFFF),
37-
surfaceVariant = Color(0xFF32343B),
38-
onSurfaceVariant = Color(0xFFFFFFFF),
3931
outline = Color(0xFF9A9DA8),
4032
error = Color(0xFFE1421F),
4133
onError = Color(0xFFFFFFFF)
@@ -48,20 +40,8 @@ fun HttpToolkitTheme(
4840
) {
4941
val colorScheme = if (darkTheme) DarkColors else LightColors
5042

51-
// Use dynamic color on Android 12+ if desired, but fallback to our custom colors
52-
val finalColorScheme = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
53-
val context = LocalContext.current
54-
if (darkTheme) {
55-
dynamicDarkColorScheme(context)
56-
} else {
57-
dynamicLightColorScheme(context)
58-
}
59-
} else {
60-
colorScheme
61-
}
62-
6343
MaterialTheme(
64-
colorScheme = colorScheme, // Use our custom colors, not dynamic
44+
colorScheme = colorScheme,
6545
typography = Typography(),
6646
content = content
6747
)

app/src/main/res/layout/qr_scan_activity.xml

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)