Skip to content

Commit ab5a845

Browse files
feat: add logs screen and custom logger
1 parent bdd8b99 commit ab5a845

File tree

7 files changed

+131
-3
lines changed

7 files changed

+131
-3
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.bitcoindevkit.devkitwallet.domain
2+
3+
object DwLogger {
4+
private const val MAX_LOGS = 5000
5+
private val logEntries = ArrayDeque<String>(MAX_LOGS)
6+
private val lock = Any()
7+
8+
fun log(tag: String, message: String) {
9+
synchronized(lock) {
10+
if (logEntries.size >= MAX_LOGS) {
11+
logEntries.removeLast()
12+
}
13+
logEntries.addFirst("${System.currentTimeMillis()} [$tag]: $message")
14+
}
15+
}
16+
17+
fun getLogs(): List<String> {
18+
synchronized(lock) {
19+
return logEntries.toList()
20+
}
21+
}
22+
}

app/src/main/java/org/bitcoindevkit/devkitwallet/presentation/DevkitWalletActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import org.bitcoindevkit.devkitwallet.data.RecoverWalletConfig
2020
import org.bitcoindevkit.devkitwallet.data.SingleWallet
2121
import org.bitcoindevkit.devkitwallet.data.UserPreferences
2222
import org.bitcoindevkit.devkitwallet.data.UserPreferencesSerializer
23+
import org.bitcoindevkit.devkitwallet.domain.DwLogger
2324
import org.bitcoindevkit.devkitwallet.domain.UserPreferencesRepository
2425
import org.bitcoindevkit.devkitwallet.domain.Wallet
2526
import org.bitcoindevkit.devkitwallet.presentation.navigation.HomeNavigation
@@ -36,6 +37,10 @@ private val Context.userPreferencesStore: DataStore<UserPreferences> by dataStor
3637
class DevkitWalletActivity : AppCompatActivity() {
3738
override fun onCreate(savedInstanceState: Bundle?) {
3839
super.onCreate(savedInstanceState)
40+
41+
// Initialize Devkit Wallet Logger (used in the LogsScreen)
42+
DwLogger.log("INFO", "Devkit Wallet app started")
43+
3944
val userPreferencesRepository = UserPreferencesRepository(userPreferencesStore)
4045
val onBuildWalletButtonClicked: (WalletCreateType) -> Unit = { walletCreateType ->
4146
try {
@@ -86,6 +91,7 @@ class DevkitWalletActivity : AppCompatActivity() {
8691

8792
setContent {
8893
if (!onboardingDone) {
94+
DwLogger.log("INFO", "First time opening the app, triggering onboarding screen")
8995
OnboardingScreen(onFinishOnboarding)
9096
} else {
9197
DevkitTheme {

app/src/main/java/org/bitcoindevkit/devkitwallet/presentation/navigation/Destinations.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ object AboutScreen
2626
object RecoveryPhraseScreen
2727
@Serializable
2828
object BlockchainClientScreen
29+
@Serializable
30+
object LogsScreen
2931

3032
// Wallet navigation destinations
3133
@Serializable

app/src/main/java/org/bitcoindevkit/devkitwallet/presentation/navigation/HomeNavigation.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import org.bitcoindevkit.devkitwallet.domain.Wallet
1616
import org.bitcoindevkit.devkitwallet.presentation.ui.screens.WalletRoot
1717
import org.bitcoindevkit.devkitwallet.presentation.ui.screens.drawer.AboutScreen
1818
import org.bitcoindevkit.devkitwallet.presentation.ui.screens.drawer.BlockchainClientScreen
19+
import org.bitcoindevkit.devkitwallet.presentation.ui.screens.drawer.LogsScreen
1920
import org.bitcoindevkit.devkitwallet.presentation.ui.screens.drawer.RecoveryPhraseScreen
2021
import org.bitcoindevkit.devkitwallet.presentation.viewmodels.WalletViewModel
2122

@@ -89,5 +90,20 @@ fun HomeNavigation(
8990
state = walletViewModel.state,
9091
navController = navController
9192
) }
93+
94+
composable<LogsScreen>(
95+
enterTransition = {
96+
slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(ANIMATION_DURATION))
97+
},
98+
popEnterTransition = {
99+
slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(ANIMATION_DURATION))
100+
},
101+
exitTransition = {
102+
slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(ANIMATION_DURATION))
103+
},
104+
popExitTransition = {
105+
slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(ANIMATION_DURATION))
106+
}
107+
) { LogsScreen(navController = navController) }
92108
}
93109
}

app/src/main/java/org/bitcoindevkit/devkitwallet/presentation/ui/screens/WalletRoot.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ import com.composables.icons.lucide.History
4242
import com.composables.icons.lucide.Info
4343
import com.composables.icons.lucide.Lucide
4444
import com.composables.icons.lucide.SatelliteDish
45+
import com.composables.icons.lucide.ScrollText
4546
import org.bitcoindevkit.devkitwallet.presentation.theme.DevkitWalletColors
4647
import org.bitcoindevkit.devkitwallet.presentation.navigation.WalletNavigation
4748
import org.bitcoindevkit.devkitwallet.R
4849
import org.bitcoindevkit.devkitwallet.domain.Wallet
4950
import org.bitcoindevkit.devkitwallet.presentation.navigation.AboutScreen
5051
import org.bitcoindevkit.devkitwallet.presentation.navigation.BlockchainClientScreen
52+
import org.bitcoindevkit.devkitwallet.presentation.navigation.LogsScreen
5153
import org.bitcoindevkit.devkitwallet.presentation.navigation.RecoveryPhraseScreen
5254
import org.bitcoindevkit.devkitwallet.presentation.theme.quattroRegular
5355
import org.bitcoindevkit.devkitwallet.presentation.viewmodels.WalletViewModel
@@ -144,6 +146,14 @@ internal fun WalletRoot(
144146
colors = navigationItemColors,
145147
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding),
146148
)
149+
NavigationDrawerItem(
150+
icon = { Icon(Lucide.ScrollText, contentDescription = "Logs", tint = DevkitWalletColors.white) },
151+
label = { DrawerItemLabel("Logs") },
152+
selected = items[3] == selectedItem.value,
153+
onClick = { navController.navigate(LogsScreen) },
154+
colors = navigationItemColors,
155+
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding),
156+
)
147157
}
148158
}
149159
},
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2021-2025 thunderbiscuit and contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the ./LICENSE file.
4+
*/
5+
6+
package org.bitcoindevkit.devkitwallet.presentation.ui.screens.drawer
7+
8+
import androidx.compose.foundation.horizontalScroll
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.lazy.LazyColumn
13+
import androidx.compose.foundation.lazy.items
14+
import androidx.compose.foundation.rememberScrollState
15+
import androidx.compose.material3.Scaffold
16+
import androidx.compose.runtime.remember
17+
import androidx.compose.ui.unit.sp
18+
import org.bitcoindevkit.devkitwallet.domain.DwLogger
19+
import androidx.compose.material3.Text
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.ui.Modifier
22+
import androidx.compose.ui.text.style.TextOverflow
23+
import androidx.compose.ui.unit.dp
24+
import androidx.navigation.NavController
25+
import org.bitcoindevkit.devkitwallet.presentation.navigation.WalletScreen
26+
import org.bitcoindevkit.devkitwallet.presentation.theme.DevkitWalletColors
27+
import org.bitcoindevkit.devkitwallet.presentation.theme.quattroRegular
28+
import org.bitcoindevkit.devkitwallet.presentation.ui.components.SecondaryScreensAppBar
29+
30+
@Composable
31+
fun LogsScreen(
32+
navController: NavController
33+
) {
34+
val logs: List<String> = remember { DwLogger.getLogs() }
35+
36+
Scaffold(
37+
topBar = {
38+
SecondaryScreensAppBar(
39+
title = "Logs",
40+
navigation = { navController.navigate(WalletScreen) }
41+
)
42+
},
43+
containerColor = DevkitWalletColors.primary
44+
) { paddingValues ->
45+
LazyColumn(
46+
modifier = Modifier
47+
.fillMaxSize()
48+
.padding(paddingValues)
49+
.padding(16.dp)
50+
) {
51+
items(logs) { logLine ->
52+
Text(
53+
text = logLine,
54+
fontSize = 14.sp,
55+
fontFamily = quattroRegular,
56+
color = DevkitWalletColors.white,
57+
maxLines = 1,
58+
overflow = TextOverflow.Visible,
59+
modifier = Modifier
60+
.fillMaxWidth()
61+
.horizontalScroll(rememberScrollState())
62+
)
63+
}
64+
}
65+
}
66+
}

app/src/main/java/org/bitcoindevkit/devkitwallet/presentation/ui/screens/intro/ActiveWalletsScreen.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package org.bitcoindevkit.devkitwallet.presentation.ui.screens.intro
77

8-
import android.util.Log
98
import androidx.compose.foundation.background
109
import androidx.compose.foundation.clickable
1110
import androidx.compose.foundation.layout.Arrangement
@@ -39,8 +38,6 @@ internal fun ActiveWalletsScreen(
3938
navController: NavController,
4039
onBuildWalletButtonClicked: (WalletCreateType) -> Unit
4140
) {
42-
Log.i(TAG, "Active wallets = $activeWallets")
43-
Log.i(TAG, "Active wallets script types = ${activeWallets.first().scriptType}")
4441
Scaffold(
4542
topBar = {
4643
SecondaryScreensAppBar(title = "Choose a Wallet", navigation = { navController.navigateUp() })
@@ -56,6 +53,15 @@ internal fun ActiveWalletsScreen(
5653
activeWallets.forEach {
5754
ActiveWalletCard(wallet = it, onBuildWalletButtonClicked)
5855
}
56+
if (activeWallets.isEmpty()) {
57+
Text(
58+
text = "No active wallets.",
59+
fontSize = 16.sp,
60+
fontFamily = quattroRegular,
61+
color = DevkitWalletColors.white,
62+
modifier = Modifier.padding(16.dp).align(Alignment.CenterHorizontally)
63+
)
64+
}
5965
Spacer(modifier = Modifier.height(12.dp))
6066
}
6167
}

0 commit comments

Comments
 (0)