8000 fix: hide monetary values in activity detail by jvsena42 · Pull Request #752 · synonymdev/bitkit-android · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@jvsena42
Copy link
Member
@jvsena42 jvsena42 commented Jan 29, 2026

Fixes #732

This PR fixes monetary values not being hidden on the activity detail page when the user has enabled balance hiding.

Description

When users swipe to hide their balance, values are hidden throughout the app (home page, confetti sheet, activity list) but the individual activity detail page still displayed bitcoin and fiat amounts. This PR:

  1. Enables the swipe-to-hide gesture on the balance header in activity detail
  2. Hides the payment amount and fee values when balance hiding is active

Preview

Screen_recording_20260129_131012.webm
Screen_recording_20260129_131210.webm

QA Notes

1. Activity detail with hidden balance

  1. Open the wallet
  2. Swipe on the balance to hide it
  3. Tap on any activity in the list
  4. Verify the header balance shows • • • • • • • • •
  5. Verify the payment amount shows • • • • •
  6. Verify the fee amount shows • • • • • (if applicable)

2. Swipe to toggle on activity detail

  1. With balance visible, tap on an activity
  2. Swipe on the balance header to hide
  3. Verify all monetary values are hidden
  4. Swipe again to show
  5. Verify all values are visible again

3. Regression - Balance visible

  1. Ensure balance is visible (not hidden)
  2. Tap on any activity
  3. Verify all amounts display correctly with proper currency formatting

@jvsena42 jvsena42 self-assigned this Jan 29, 2026
@jvsena42 jvsena42 requested a review from ovitrif January 29, 2026 16:18
onCopy: (String) -> Unit,
feeRates: FeeRates? = null,
) {
val settings = settingsViewModel ?: return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLAUDE.md Violation: Parent-Child Composable Pattern

The ActivityDetailContent composable is a private child composable but is accessing settingsViewModel directly instead of receiving state as a parameter from its parent.

CLAUDE.md Rule:

"ALWAYS split screen composables into parent accepting viewmodel + inner private child accepting state and callbacks Content()"

See: https://github.com/synonymdev/bitkit-android/blob/e09ac4c088fb2493e2b64aac531fb20661587fa7/CLAUDE.md#L122

Current pattern:

// ActivityDetailContent (private child)
val settings = settingsViewModel ?: return
val hideBalance by settings.hideBalance.collectAsStateWithLifecycle()

Expected pattern:
The parent ActivityDetailScreen should access the ViewModel and pass state down:

// In ActivityDetailScreen (parent)
val settings = settingsViewModel ?: return
val hideBalance by settings.hideBalance.collectAsStateWithLifecycle()

ActivityDetailContent(
    // ... other params
    hideBalance = hideBalance
)

// In ActivityDetailContent (private child)
@Composable
private fun ActivityDetailContent(
    // ... other params
    hideBalance: Boolean
) {
    // Use hideBalance directly
}

Reference: See SendConfirmScreen.kt for a correct implementation of this pattern:

val settings = settingsViewModel ?: return
val isPinEnabled by settings.isPinEnabled.collectAsStateWithLifecycle()
val pinForPayments by settings.isPinForPaymentsEnabled.collectAsStateWithLifecycle()
val isBiometricEnabled by settings.isBiometricEnabled.collectAsStateWithLifecycle()
val isBiometrySupported = rememberBiometricAuthSupported()
// Handle result from PinCheckScreen
LaunchedEffect(savedStateHandle) {
savedStateHandle.getStateFlow<Boolean?>(PIN_CHECK_RESULT_KEY, null)
.filterNotNull()
.collect { isSuccess ->
isLoading = isSuccess
savedStateHandle.remove<Boolean>(PIN_CHECK_RESULT_KEY)
}
}
// Confirm with pin or bio if required
LaunchedEffect(uiState.shouldConfirmPay) {
if (!uiState.shouldConfirmPay) return@LaunchedEffect
if (isPinEnabled && pinForPayments) {
currentOnEvent(SendEvent.ClearPayConfirmation)
if (isBiometricEnabled && isBiometrySupported) {
showBiometrics = true
} else {
onNavigateToPin()
}
} else {
currentOnEvent(SendEvent.PayConfirmed)
}
}
Content(
uiState = uiState,
isNodeRunning = isNodeRunning,
isLoading = isLoading,
showBiometrics = showBiometrics,
canGoBack = canGoBack,
onBack = onBack,
onEvent = onEvent,
onClickAddTag = onClickAddTag,
onClickTag = onClickTag,
onSwipeToConfirm = {
scope.launch {
isLoading = true
delay(300)
onEvent(SendEvent.SwipeToPay)
}
},
onBiometricsSuccess = {
isLoading = true
showBiometrics = false
onEvent(SendEvent.PayConfirmed)
},
onBiometricsFailure = {
isLoading = false
showBiometrics = false
onNavigateToPin()
},
)
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, it even gives examples now 🥹🔥

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can address after

Copy link
Collaborator
@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude's comments do seem relevant, otherwise LGTM 🥂

@ovitrif ovitrif merged commit 5c57306 into master Jan 30, 2026
20 checks passed
@ovitrif ovitrif deleted the fix/hide-activity-detail-balance branch January 30, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Monetary values not hidden in activity page

3 participants

0