Skip to content

Commit e0aebb5

Browse files
feat(#138): Improve Unlock Screen UI and add dark mode toggle (#122)
1 parent e25e9e1 commit e0aebb5

32 files changed

+1429
-430
lines changed

app/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ dependencies {
220220
implementation(libs.bundles.google.play.feature.delivery)
221221
implementation(libs.bundles.google.play.review)
222222
implementation(libs.kotlinx.serialization.json)
223+
implementation(libs.kotlinx.coroutines.android)
223224
implementation (libs.airbnb.lottie.compose)
224225
implementation(platform(libs.koin.bom))
225226
implementation(libs.bundles.koin)
@@ -243,6 +244,8 @@ dependencies {
243244

244245
testImplementation(libs.junit)
245246
testImplementation(libs.mockk)
247+
testImplementation(libs.turbine)
248+
testImplementation(libs.kotlinx.coroutines.tests)
246249

247250
androidTestImplementation(platform(libs.androidx.compose.bom))
248251
androidTestImplementation(libs.bundles.androidx.compose.ui.test)

app/src/main/java/com/brainwallet/navigation/UiEffect.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ sealed class UiEffect {
1919
}
2020

2121
data class ShowDialog(val name: String): UiEffect()
22+
data object ShowMoonPayDialog: UiEffect()
2223

2324
data class ShowMessage(
2425
val message: String,

app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.content.Context;
88
import android.content.Intent;
99
import android.graphics.Bitmap;
10+
import android.graphics.Color;
1011
import android.graphics.Point;
1112
import android.view.Display;
1213
import android.view.WindowManager;
@@ -66,6 +67,51 @@ public static Bitmap encodeAsBitmap(String content, int dimension) {
6667
return bitmap;
6768
}
6869

70+
public static Bitmap encodeAsTransparentBitmap(String content, int dimension) {
71+
if (content == null) {
72+
return null;
73+
}
74+
75+
Map<EncodeHintType, Object> hints = new EnumMap<>(EncodeHintType.class);
76+
String encoding = guessAppropriateEncoding(content);
77+
if (encoding != null) {
78+
hints.put(EncodeHintType.CHARACTER_SET, encoding);
79+
}
80+
hints.put(EncodeHintType.MARGIN, 1);
81+
82+
BitMatrix result;
83+
try {
84+
result = new MultiFormatWriter().encode(
85+
content,
86+
BarcodeFormat.QR_CODE,
87+
dimension,
88+
dimension,
89+
hints
90+
);
91+
} catch (IllegalArgumentException | WriterException e) {
92+
Timber.e(e);
93+
return null;
94+
}
95+
96+
if (result == null) return null;
97+
98+
int width = result.getWidth();
99+
int height = result.getHeight();
100+
int[] pixels = new int[width * height];
101+
102+
for (int y = 0; y < height; y++) {
103+
int offset = y * width;
104+
for (int x = 0; x < width; x++) {
105+
// Black pixels stay black, white becomes transparent
106+
pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT;
107+
}
108+
}
109+
110+
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
111+
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
112+
return bitmap;
113+
}
114+
69115
public static boolean generateQR(Context ctx, String bitcoinURL, ImageView qrcode) {
70116
if (qrcode == null || bitcoinURL == null || bitcoinURL.isEmpty()) return false;
71117
WindowManager manager = (WindowManager) ctx.getSystemService(Activity.WINDOW_SERVICE);
@@ -94,7 +140,7 @@ public static Bitmap generateQR(Context ctx, String litecoinUrl) {
94140
int smallerDimension = Math.min(width, height);
95141
smallerDimension = (int) (smallerDimension * 0.45f);
96142
Bitmap bitmap = null;
97-
bitmap = QRUtils.encodeAsBitmap(litecoinUrl, smallerDimension);
143+
bitmap = QRUtils.encodeAsTransparentBitmap(litecoinUrl, smallerDimension);
98144
return bitmap;
99145
}
100146

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.brainwallet.ui.composable
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.isSystemInDarkTheme
6+
import androidx.compose.foundation.layout.Box
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.res.painterResource
10+
import androidx.compose.ui.tooling.preview.PreviewLightDark
11+
import com.brainwallet.R
12+
import com.brainwallet.data.model.AppSetting
13+
import com.brainwallet.ui.theme.BrainwalletAppTheme
14+
import com.brainwallet.ui.theme.BrainwalletTheme
15+
import com.brainwallet.ui.theme.LocalDarkModeFlag
16+
17+
@Composable
18+
fun BrainWalletLogo(modifier: Modifier = Modifier) {
19+
val iconLogo = if (LocalDarkModeFlag.current) {
20+
R.drawable.brainwallet_logotype_white
21+
} else {
22+
R.drawable.brainwallet_logotype_color
23+
}
24+
Image(
25+
painterResource(iconLogo),
26+
contentDescription = "brainwallet_logo",
27+
modifier = modifier
28+
)
29+
}
30+
31+
@PreviewLightDark
32+
@Composable
33+
private fun BrainWalletLogoPreview() {
34+
BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) {
35+
Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) {
36+
BrainWalletLogo()
37+
}
38+
}
39+
}
Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.brainwallet.ui.composable
2+
23
import androidx.compose.foundation.background
34
import androidx.compose.foundation.border
5+
import androidx.compose.foundation.isSystemInDarkTheme
46
import androidx.compose.foundation.layout.Box
57
import androidx.compose.foundation.layout.aspectRatio
68
import androidx.compose.foundation.layout.fillMaxSize
7-
import androidx.compose.foundation.layout.width
9+
import androidx.compose.foundation.layout.size
810
import androidx.compose.foundation.shape.CircleShape
911
import androidx.compose.material3.Icon
1012
import androidx.compose.material3.IconToggleButton
@@ -14,27 +16,29 @@ import androidx.compose.ui.Modifier
1416
import androidx.compose.ui.draw.clip
1517
import androidx.compose.ui.res.painterResource
1618
import androidx.compose.ui.res.stringResource
19+
import androidx.compose.ui.tooling.preview.PreviewLightDark
1720
import androidx.compose.ui.unit.dp
1821
import com.brainwallet.R
22+
import com.brainwallet.data.model.AppSetting
23+
import com.brainwallet.ui.theme.BrainwalletAppTheme
1924
import com.brainwallet.ui.theme.BrainwalletTheme
2025

2126
@Composable
2227
fun DarkModeToggleButton(
2328
checked: Boolean,
2429
onCheckedChange: (Boolean) -> Unit,
2530
modifier: Modifier = Modifier,
31+
iconButtonSizeInDp: Int = 32
2632
) {
27-
val iconButtonSize = 32
28-
2933
IconToggleButton(
3034
checked = checked,
3135
onCheckedChange = onCheckedChange,
32-
modifier = modifier,
36+
modifier = modifier.size(iconButtonSizeInDp.dp),
3337
) {
3438
Box(
3539
modifier = Modifier
3640
.fillMaxSize()
37-
.width(iconButtonSize.dp)
41+
.size(iconButtonSizeInDp.dp)
3842
.aspectRatio(1f)
3943
.clip(CircleShape)
4044
.border(
@@ -47,12 +51,21 @@ fun DarkModeToggleButton(
4751
Icon(
4852
modifier = Modifier
4953
.align(Alignment.Center)
50-
.width(iconButtonSize.dp)
51-
.aspectRatio(1f),
54+
.size((iconButtonSizeInDp * 0.6).dp),
5255
tint = if (checked) BrainwalletTheme.colors.warn else BrainwalletTheme.colors.surface,
5356
painter = painterResource(if (checked) R.drawable.ic_light_mode else R.drawable.ic_dark_mode),
5457
contentDescription = stringResource(R.string.toggle_dark_mode),
5558
)
5659
}
5760
}
58-
}
61+
}
62+
63+
@PreviewLightDark
64+
@Composable
65+
private fun DarkModeToggleButtonPreview() {
66+
BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) {
67+
Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) {
68+
DarkModeToggleButton(checked = isSystemInDarkTheme(), onCheckedChange = {}, )
69+
}
70+
}
71+
}

app/src/main/java/com/brainwallet/ui/composable/Foundation.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.brainwallet.ui.theme.BrainwalletTheme
2727
fun BrainwalletScaffold(
2828
modifier: Modifier = Modifier,
2929
topBar: @Composable () -> Unit = {},
30+
bottomBar: @Composable () -> Unit = {},
3031
floatingActionButton: @Composable () -> Unit = {},
3132
content: @Composable (PaddingValues) -> Unit
3233
) {
@@ -35,6 +36,7 @@ fun BrainwalletScaffold(
3536
containerColor = BrainwalletTheme.colors.surface,
3637
contentColor = BrainwalletTheme.colors.content,
3738
topBar = topBar,
39+
bottomBar = bottomBar,
3840
floatingActionButton = floatingActionButton,
3941
content = content
4042
)

app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ package com.brainwallet.ui.composable
33
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.Row
55
import androidx.compose.runtime.Composable
6+
import androidx.compose.ui.Modifier
67
import androidx.compose.ui.unit.dp
78

89
@Composable
910
fun PasscodeIndicator(
10-
passcode: List<Int>
11+
passcode: List<Int>,
12+
modifier: Modifier = Modifier,
1113
) {
1214
Row(
15+
modifier = modifier,
1316
horizontalArrangement = Arrangement.spacedBy(12.dp)
1417
) {
1518
passcode.forEach { digit ->
1619
PinDotItem(checked = digit > -1)
1720
}
1821
}
19-
}
22+
}

0 commit comments

Comments
 (0)