Skip to content

Commit 1044db5

Browse files
committed
feat(device-logs): add live in-app log viewer
Replaces the export-only "Export Logs" entry in Advanced Features with a live-streaming "Device Logs" screen. Log lines are tee'd from FileTree through a SharedFlow (post PII/RPC filtering) into a new feature module that renders them in a monospace LazyColumn with filter, pause/resume, clear, and share controls. - Selectable text buffer and case-insensitive filter-match highlighting - Auto-scroll to tail, gated by pause state - Bounded 1000-line ring buffer at both the SharedFlow replay cache and the ViewModel state layers Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent c229caf commit 1044db5

16 files changed

Lines changed: 577 additions & 26 deletions

File tree

apps/flipcash/app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ dependencies {
170170
implementation(project(":apps:flipcash:features:menu"))
171171
implementation(project(":apps:flipcash:features:lab"))
172172
implementation(project(":apps:flipcash:features:advanced"))
173+
implementation(project(":apps:flipcash:features:device-logs"))
173174
implementation(project(":apps:flipcash:features:appsettings"))
174175
implementation(project(":apps:flipcash:features:appupdates"))
175176
implementation(project(":apps:flipcash:features:deposit"))

apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import androidx.navigation3.scene.OverlayScene
2020
import androidx.navigation3.scene.SinglePaneSceneStrategy
2121
import com.flipcash.app.advanced.AdvancedFeaturesScreen
2222
import com.flipcash.app.appsettings.AppSettingsScreen
23+
import com.flipcash.app.devicelogs.DeviceLogsScreen
2324
import com.flipcash.app.backupkey.BackupKeyScreen
2425
import com.flipcash.app.balance.BalanceScreen
2526
import com.flipcash.app.cash.CashScreen
@@ -149,6 +150,7 @@ fun appEntryProvider(
149150
annotatedEntry<AppRoute.Menu.Deposit> { key -> DepositScreen(key.mint) }
150151
annotatedEntry<AppRoute.Menu.BackupKey> { BackupKeyScreen() }
151152
annotatedEntry<AppRoute.Menu.AdvancedFeatures> { AdvancedFeaturesScreen() }
153+
annotatedEntry<AppRoute.Menu.DeviceLogs> { DeviceLogsScreen() }
152154

153155
annotatedEntry<AppRoute.UserFlags> { UserFlagsScreen() }
154156
// Transfers

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ sealed interface AppRoute : NavKey, Parcelable {
167167
@Serializable
168168
data object AdvancedFeatures : Menu
169169
@Serializable
170+
data object DeviceLogs : Menu
171+
@Serializable
170172
data object Lab : Menu
171173
}
172174

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,13 @@
364364
<string name="description_noTransactionHistory">Your recent activity will appear here when you send or receive money</string>
365365

366366
<string name="title_billCustomizer">Bill Creator</string>
367-
<string name="title_exportLogs">Export Logs</string>
367+
<string name="title_deviceLogs">Application Logs</string>
368+
<string name="action_clearLogs">Clear</string>
369+
<string name="action_shareLogs">Share</string>
370+
<string name="hint_filterLogs">Filter logs</string>
371+
<string name="label_streamLive">Live</string>
372+
<string name="label_streamPaused">Paused</string>
373+
<string name="label_pausedBacklog">Paused • %1$d new</string>
368374

369375
<string name="error_title_CashReturnedToWallet">Something Went Wrong</string>
370376
<string name="error_description_CashReturnedToWallet">The cash was returned to your wallet</string>

apps/flipcash/features/advanced/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ android {
77
}
88

99
dependencies {
10+
implementation(project(":apps:flipcash:features:device-logs"))
1011
implementation(project(":apps:flipcash:shared:bill-customization"))
1112
implementation(project(":apps:flipcash:shared:featureflags"))
1213
implementation(project(":apps:flipcash:shared:menu"))

apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/AdvancedFeaturesScreen.kt

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,16 @@ import androidx.compose.runtime.Composable
66
import androidx.compose.runtime.LaunchedEffect
77
import androidx.compose.ui.Alignment
88
import androidx.compose.ui.Modifier
9-
import androidx.compose.ui.platform.LocalContext
109
import androidx.compose.ui.res.stringResource
1110
import androidx.hilt.navigation.compose.hiltViewModel
1211
import com.flipcash.app.advanced.internal.AdvancedFeaturesScreen
1312
import com.flipcash.app.advanced.internal.AdvancedFeaturesScreenViewModel
1413
import com.flipcash.app.bill.customization.LocalBillPlaygroundController
15-
import com.flipcash.app.core.android.IntentUtils
1614
import com.flipcash.core.R
1715
import com.getcode.navigation.core.LocalCodeNavigator
1816
import com.getcode.opencode.model.financial.Token
1917
import com.getcode.opencode.model.financial.usdf
2018
import com.getcode.ui.components.AppBarWithTitle
21-
import com.getcode.utils.TraceManager
2219
import kotlinx.coroutines.flow.filterIsInstance
2320
import kotlinx.coroutines.flow.launchIn
2421
import kotlinx.coroutines.flow.onEach
@@ -28,7 +25,6 @@ fun AdvancedFeaturesScreen() {
2825
val navigator = LocalCodeNavigator.current
2926
val billPlayground = LocalBillPlaygroundController.current
3027
val viewModel = hiltViewModel<AdvancedFeaturesScreenViewModel>()
31-
val context = LocalContext.current
3228

3329
Column(
3430
modifier = Modifier.fillMaxSize(),
@@ -61,17 +57,4 @@ fun AdvancedFeaturesScreen() {
6157
}
6258
.launchIn(this)
6359
}
64-
65-
LaunchedEffect(viewModel) {
66-
viewModel.eventFlow
67-
.filterIsInstance<AdvancedFeaturesScreenViewModel.Event.ExportLogs>()
68-
.onEach {
69-
val logFile = TraceManager.getLogFile()
70-
if (logFile != null) {
71-
val intent = IntentUtils.shareFile(context, logFile, "text/plain")
72-
context.startActivity(intent)
73-
}
74-
}
75-
.launchIn(this)
76-
}
7760
}

apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeatureMenuItems.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.flipcash.app.advanced.internal
22

33
import androidx.compose.material.icons.Icons
4+
import androidx.compose.material.icons.outlined.Description
45
import androidx.compose.material.icons.outlined.Palette
5-
import androidx.compose.material.icons.outlined.Share
66
import androidx.compose.runtime.Composable
77
import androidx.compose.ui.graphics.painter.Painter
88
import androidx.compose.ui.graphics.vector.rememberVectorPainter
@@ -31,10 +31,11 @@ internal data object Deposit : FullMenuItem<AdvancedFeaturesScreenViewModel.Even
3131
)
3232
}
3333

34-
internal data object ExportLogs : FullMenuItem<AdvancedFeaturesScreenViewModel.Event>() {
34+
internal data object DeviceLogs : FullMenuItem<AdvancedFeaturesScreenViewModel.Event>() {
3535
override val icon: Painter
36-
@Composable get() = rememberVectorPainter(Icons.Outlined.Share)
36+
@Composable get() = rememberVectorPainter(Icons.Outlined.Description)
3737
override val name: String
38-
@Composable get() = stringResource(R.string.title_exportLogs)
39-
override val action: AdvancedFeaturesScreenViewModel.Event = AdvancedFeaturesScreenViewModel.Event.ExportLogs
38+
@Composable get() = stringResource(R.string.title_deviceLogs)
39+
override val action: AdvancedFeaturesScreenViewModel.Event =
40+
AdvancedFeaturesScreenViewModel.Event.OpenScreen(AppRoute.Menu.DeviceLogs)
4041
}

apps/flipcash/features/advanced/src/main/kotlin/com/flipcash/app/advanced/internal/AdvancedFeaturesScreenViewModel.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import javax.inject.Inject
2020
private val FullMenuList = buildList {
2121
add(BillCustomizer)
2222
add(Deposit)
23-
add(ExportLogs)
23+
add(DeviceLogs)
2424
}
2525

2626
@HiltViewModel
@@ -45,7 +45,6 @@ internal class AdvancedFeaturesScreenViewModel @Inject constructor(
4545
data class OpenScreen(val screen: AppRoute) : Event
4646

4747
data object OpenBillPlayground: Event
48-
data object ExportLogs: Event
4948
}
5049

5150
init {
@@ -85,7 +84,6 @@ internal class AdvancedFeaturesScreenViewModel @Inject constructor(
8584

8685
is Event.OpenScreen -> { state -> state }
8786
is Event.OpenBillPlayground -> { state -> state }
88-
is Event.ExportLogs -> { state -> state }
8987
}
9088
}
9189
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
.gradle/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plugins {
2+
alias(libs.plugins.flipcash.android.feature)
3+
}
4+
5+
android {
6+
namespace = "${Gradle.flipcashNamespace}.features.devicelogs"
7+
}
8+
9+
dependencies {
10+
implementation(project(":libs:logging"))
11+
}

0 commit comments

Comments
 (0)