fix: payment detail not loading on filter or search when not in memory
This commit is contained in:
@@ -72,7 +72,7 @@ sealed class TabItem(val route: String, val label: String, val icon: ImageVector
|
||||
private const val ROUTE_HOME = "home"
|
||||
private const val ROUTE_SCANNER = "scanner"
|
||||
private const val ROUTE_HISTORY = "history"
|
||||
private const val ROUTE_PAYMENT_DETAIL = "payment_detail/{paymentHash}"
|
||||
private const val ROUTE_PAYMENT_DETAIL = "payment_detail/{checkingId}"
|
||||
|
||||
@Composable
|
||||
fun WalletScreen(
|
||||
@@ -317,7 +317,7 @@ fun WalletScreen(
|
||||
navController.popBackStack(ROUTE_HOME, inclusive = false)
|
||||
},
|
||||
onPaymentClick = { payment ->
|
||||
navController.navigate("payment_detail/${payment.paymentHash}")
|
||||
navController.navigate("payment_detail/${payment.checkingId}")
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -325,13 +325,12 @@ fun WalletScreen(
|
||||
// Payment detail — back → history (natural back stack)
|
||||
composable(
|
||||
route = ROUTE_PAYMENT_DETAIL,
|
||||
arguments = listOf(navArgument("paymentHash") { type = NavType.StringType })
|
||||
arguments = listOf(navArgument("checkingId") { type = NavType.StringType })
|
||||
) { backStackEntry ->
|
||||
val paymentHash = backStackEntry.arguments?.getString("paymentHash") ?: ""
|
||||
val historyState by historyVm.state.collectAsState()
|
||||
val payment = (historyState as? HistoryState.Success)
|
||||
?.payments
|
||||
?.firstOrNull { it.paymentHash == paymentHash }
|
||||
val checkingId = backStackEntry.arguments?.getString("checkingId") ?: ""
|
||||
// val historyState by historyVm.state.collectAsState()
|
||||
val historyState by historyVm.filteredState.collectAsState()
|
||||
val payment = historyVm.findPayment(checkingId)
|
||||
|
||||
if (payment != null) {
|
||||
PaymentDetailScreen(
|
||||
@@ -340,7 +339,7 @@ fun WalletScreen(
|
||||
onBack = { navController.popBackStack() }
|
||||
)
|
||||
} else {
|
||||
LaunchedEffect(paymentHash) { historyVm.refresh() }
|
||||
LaunchedEffect(checkingId) { historyVm.refresh() }
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.bitcointxoko.gudariwallet.api.LnurlScanResponse
|
||||
import com.bitcointxoko.gudariwallet.data.NodeAliasRepository
|
||||
import com.bitcointxoko.gudariwallet.data.PaymentCacheRepository
|
||||
import com.bitcointxoko.gudariwallet.data.WalletRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -57,17 +57,10 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bitcointxoko.gudariwallet.api.PaymentRecord
|
||||
import com.bitcointxoko.gudariwallet.ui.history.DatePreset
|
||||
import com.bitcointxoko.gudariwallet.ui.history.DirectionFilter
|
||||
import com.bitcointxoko.gudariwallet.ui.HistoryState
|
||||
import com.bitcointxoko.gudariwallet.ui.history.HistoryViewModel
|
||||
import com.bitcointxoko.gudariwallet.ui.history.PaymentFilter
|
||||
import com.bitcointxoko.gudariwallet.ui.history.StatusFilter
|
||||
import com.bitcointxoko.gudariwallet.ui.history.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
// ── List screen ──────────────────────────────────────────────────────────────
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun HistoryScreen(
|
||||
@@ -265,7 +258,6 @@ fun HistoryScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Sheets (outside Scaffold so they overlay correctly) ──────────────────
|
||||
if (filterSheetVisible) {
|
||||
FilterBottomSheet(
|
||||
@@ -292,7 +284,6 @@ fun HistoryScreen(
|
||||
}
|
||||
|
||||
// ── Search bar ───────────────────────────────────────────────────────────────
|
||||
|
||||
@Composable
|
||||
private fun SearchBar(
|
||||
query : String,
|
||||
@@ -357,7 +348,6 @@ private fun SearchBar(
|
||||
}
|
||||
|
||||
// ── Active filter chips ──────────────────────────────────────────────────────
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun ActiveFilterChips(
|
||||
|
||||
@@ -22,6 +22,8 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val TAG = "HistoryViewModel"
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
class HistoryViewModel(
|
||||
private val repo : WalletRepository,
|
||||
@@ -30,7 +32,6 @@ class HistoryViewModel(
|
||||
val fiatCurrency : StateFlow<String?>,
|
||||
val fiatSatsPerUnit : StateFlow<Double?>
|
||||
) : ViewModel() {
|
||||
|
||||
// ── Sync manager (owns _state, currentOffset, loadJob, sync loop) ─────────
|
||||
private val syncManager: PaymentSyncManager = PaymentSyncManager(
|
||||
repo = repo,
|
||||
@@ -38,7 +39,6 @@ class HistoryViewModel(
|
||||
scope = viewModelScope,
|
||||
onNewPayments = { payments -> enricher.enrich(payments) }
|
||||
)
|
||||
|
||||
private val enricher: PaymentEnricher = PaymentEnricher(
|
||||
repo = repo,
|
||||
aliasRepo = aliasRepo,
|
||||
@@ -48,9 +48,7 @@ class HistoryViewModel(
|
||||
syncManager.updateEnrichedPayment(paymentHash, pubkey, alias)
|
||||
}
|
||||
)
|
||||
|
||||
val state: StateFlow<HistoryState> = syncManager.state
|
||||
|
||||
fun refresh() = syncManager.refresh()
|
||||
fun loadMore() = syncManager.loadMore(
|
||||
filteredCanLoadMore = { (filteredState.value as? HistoryState.Success)?.canLoadMore == true }
|
||||
@@ -63,10 +61,8 @@ class HistoryViewModel(
|
||||
scope = viewModelScope
|
||||
)
|
||||
val detailState: StateFlow<DetailState> = detailDelegate.state
|
||||
|
||||
fun loadDetail(checkingId: String, record: PaymentRecord? = null) =
|
||||
detailDelegate.load(checkingId, record)
|
||||
|
||||
fun clearDetail() = detailDelegate.clear()
|
||||
|
||||
// ── Filter state ──────────────────────────────────────────────────────────
|
||||
@@ -101,11 +97,18 @@ class HistoryViewModel(
|
||||
val (min, max) = preset.toEpochSecondRange() // ← delegate to PaymentFilter.kt
|
||||
setDateFilter(min, max, preset)
|
||||
}
|
||||
|
||||
fun clearDateFilter() {
|
||||
_filter.update { it.copy(minCreatedAt = null, maxCreatedAt = null, datePreset = null) }
|
||||
}
|
||||
|
||||
fun findPayment(checkingId: String): PaymentRecord? {
|
||||
val fromFiltered = (filteredState.value as? HistoryState.Success)
|
||||
?.payments?.firstOrNull { it.checkingId == checkingId }
|
||||
if (fromFiltered != null) return fromFiltered
|
||||
return (state.value as? HistoryState.Success)
|
||||
?.payments?.firstOrNull { it.checkingId == checkingId }
|
||||
}
|
||||
|
||||
// ── Room-backed query results ──────────────────────────────────────────────
|
||||
private val _roomResults = MutableStateFlow<List<PaymentRecord>?>(null)
|
||||
|
||||
@@ -165,7 +168,6 @@ class HistoryViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
WalletNotificationService.paymentEvents.collect { event ->
|
||||
Log.d(TAG, "PAYMENTS [WS EVENT ] incoming event ${event.paymentHash} — refreshing list")
|
||||
@@ -173,10 +175,6 @@ class HistoryViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "HistoryViewModel"
|
||||
}
|
||||
}
|
||||
|
||||
// ── Factory ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -55,6 +55,5 @@ class PaymentDetailDelegate(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() { _state.value = DetailState.Idle }
|
||||
}
|
||||
@@ -33,9 +33,8 @@ internal fun PaymentRow(
|
||||
fiatSatsPerUnit : Double?,
|
||||
onClick : () -> Unit
|
||||
) {
|
||||
val semantic = semanticColors()
|
||||
|
||||
val isPending = isPendingStatus(payment.status)
|
||||
val semantic = semanticColors()
|
||||
val amountColor = paymentAmountColor(payment.status, payment.isOutgoing)
|
||||
val icon = if (payment.isOutgoing) Icons.Default.ArrowUpward
|
||||
else Icons.Default.ArrowDownward
|
||||
|
||||
Reference in New Issue
Block a user