diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml
index 6e5d27b14..8584fc7fd 100644
--- a/app/detekt-baseline.xml
+++ b/app/detekt-baseline.xml
@@ -2,21 +2,6 @@
- AnnotationSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend
- ArgumentListWrapping:vss_rust_client_ffi.kt$(FfiConverterOptionalString.lower(`prefix`),)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(FfiConverterSequenceTypeKeyValue.lower(`items`),)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(FfiConverterString.lower(`baseUrl`),FfiConverterString.lower(`storeId`),)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(FfiConverterString.lower(`key`),FfiConverterByteArray.lower(`value`),)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`baseUrl`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`items`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`key`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`prefix`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`storeId`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(`value`)
- ArgumentListWrapping:vss_rust_client_ffi.kt$(future, continuation)
- ChainWrapping:vss_rust_client_ffi.kt$FfiConverterTypeVssError$+
- ClassNaming:vss_rust_client_ffi.kt$_UniFFILib : Library
- ClassNaming:vss_rust_client_ffi.kt$uniffiRustFutureContinuationCallback : UniFffiRustFutureContinuationCallbackType
ComplexCondition:AuthCheckView.kt$(showBio && isBiometrySupported && !requirePin) || requireBiometrics
ComplexCondition:ElectrumConfigViewModel.kt$ElectrumConfigViewModel$currentState.host.isBlank() || port == null || port <= 0 || protocol == null
ComplexCondition:HomeViewModel.kt$HomeViewModel$thresholdReached && isTimeOutOver && belowMaxWarnings && !_uiState.value.highBalanceSheetVisible
@@ -26,7 +11,6 @@
ComposableParamOrder:ActivityExploreScreen.kt$ActivityExploreScreen
ComposableParamOrder:ActivityIcon.kt$ActivityIcon
ComposableParamOrder:ActivityIcon.kt$CircularIcon
- ComposableParamOrder:AddTagScreen.kt$AddTagScreen
ComposableParamOrder:AmountInput.kt$AmountInput
ComposableParamOrder:AppStatus.kt$AppStatus
ComposableParamOrder:AuthCheckView.kt$AuthCheckView
@@ -44,7 +28,7 @@
ComposableParamOrder:HeadlineCard.kt$HeadlineCard
ComposableParamOrder:HomeScreen.kt$Content
ComposableParamOrder:InfoScreenContent.kt$InfoScreenContent
- ComposableParamOrder:LightningChannel.kt$LightningChannel
+ ComposableParamOrder:Keyboard.kt$KeyTextButton
ComposableParamOrder:Money.kt$MoneyCaptionB
ComposableParamOrder:NumberPadTextField.kt$MoneyAmount
ComposableParamOrder:OnboardingSlidesScreen.kt$OnboardingSlidesScreen
@@ -87,26 +71,28 @@
ConstructorParameterNaming:AddressChecker.kt$TxStatus$val block_hash: String? = null
ConstructorParameterNaming:AddressChecker.kt$TxStatus$val block_height: Int? = null
ConstructorParameterNaming:AddressChecker.kt$TxStatus$val block_time: Long? = null
- CyclomaticComplexMethod:ActivityDetailScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable private fun ActivityDetailContent( item: Activity, tags: List<String>, onRemoveTag: (String) -> Unit, onAddTagClick: () -> Unit, onClickBoost: () -> Unit, onExploreClick: (String) -> Unit, onCopy: (String) -> Unit, )
+ CyclomaticComplexMethod:ActivityDetailScreen.kt$@Composable private fun ActivityDetailContent( item: Activity, tags: List<String>, onRemoveTag: (String) -> Unit, onAddTagClick: () -> Unit, onClickBoost: () -> Unit, onExploreClick: (String) -> Unit, onCopy: (String) -> Unit, )
+ CyclomaticComplexMethod:ActivityIcon.kt$@Composable fun ActivityIcon( activity: Activity, size: Dp = 32.dp, modifier: Modifier = Modifier, )
CyclomaticComplexMethod:ActivityListGrouped.kt$private fun groupActivityItems(activityItems: List<Activity>): List<Any>
- CyclomaticComplexMethod:ActivityRow.kt$@Composable fun ActivityRow( item: Activity, onClick: (String) -> Unit, )
+ CyclomaticComplexMethod:ActivityRow.kt$@Composable fun ActivityRow( item: Activity, onClick: (String) -> Unit, testTag: String, )
CyclomaticComplexMethod:ActivityRow.kt$@Composable private fun TransactionStatusText( txType: PaymentType, isLightning: Boolean, status: PaymentState?, isTransfer: Boolean, )
- CyclomaticComplexMethod:AmountInput.kt$@Composable fun AmountInput( defaultValue: Long = 0, primaryDisplay: PrimaryDisplay, showConversion: Boolean = false, overrideSats: Long? = null, onSatsChange: (Long) -> Unit, )
+ CyclomaticComplexMethod:AmountInput.kt$@Composable fun AmountInput( modifier: Modifier = Modifier, defaultValue: Long = 0, primaryDisplay: PrimaryDisplay, showConversion: Boolean = false, overrideSats: Long? = null, onSatsChange: (Long) -> Unit, )
CyclomaticComplexMethod:AppStatusScreen.kt$@Composable private fun Content( uiState: AppStatusUiState = AppStatusUiState(), onBack: () -> Unit = {}, onClose: () -> Unit = {}, onInternetClick: () -> Unit = {}, onElectrumClick: () -> Unit = {}, onNodeClick: () -> Unit = {}, onChannelsClick: () -> Unit = {}, onBackupClick: () -> Unit = {}, )
CyclomaticComplexMethod:AppViewModel.kt$AppViewModel$private fun observeSendEvents()
CyclomaticComplexMethod:BlocktankRegtestScreen.kt$@Composable fun BlocktankRegtestScreen( navController: NavController, viewModel: BlocktankRegtestViewModel = hiltViewModel(), )
CyclomaticComplexMethod:ChannelDetailScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable private fun Content( channel: ChannelUi, blocktankOrders: List<IBtOrder> = emptyList(), cjitEntries: List<IcJitEntry> = emptyList(), txDetails: TxDetails? = null, isRefreshing: Boolean = false, onBack: () -> Unit = {}, onClose: () -> Unit = {}, onRefresh: () -> Unit = {}, onCopyText: (String) -> Unit = {}, onOpenUrl: (String) -> Unit = {}, onSupport: (Any) -> Unit = {}, onCloseConnection: () -> Unit = {}, )
- CyclomaticComplexMethod:ConfirmMnemonicScreen.kt$@OptIn(ExperimentalLayoutApi::class) @Composable fun ConfirmMnemonicScreen( uiState: BackupContract.UiState, onContinue: () -> Unit, onBack: () -> Unit, )
+ CyclomaticComplexMethod:ConfirmMnemonicScreen.kt$@Composable fun ConfirmMnemonicScreen( uiState: BackupContract.UiState, onContinue: () -> Unit, onBack: () -> Unit, )
CyclomaticComplexMethod:ContentView.kt$@Composable fun ContentView( appViewModel: AppViewModel, walletViewModel: WalletViewModel, blocktankViewModel: BlocktankViewModel, currencyViewModel: CurrencyViewModel, activityListViewModel: ActivityListViewModel, transferViewModel: TransferViewModel, settingsViewModel: SettingsViewModel, backupsViewModel: BackupsViewModel, )
CyclomaticComplexMethod:CoreService.kt$ActivityService$suspend fun syncLdkNodePayments(payments: List<PaymentDetails>, forceUpdate: Boolean = false)
CyclomaticComplexMethod:HealthRepo.kt$HealthRepo$private fun collectState()
CyclomaticComplexMethod:HomeScreen.kt$@Composable fun HomeScreen( mainUiState: MainUiState, drawerState: DrawerState, rootNavController: NavController, walletNavController: NavHostController, settingsViewModel: SettingsViewModel, walletViewModel: WalletViewModel, appViewModel: AppViewModel, activityListViewModel: ActivityListViewModel, homeViewModel: HomeViewModel = hiltViewModel(), )
- CyclomaticComplexMethod:HomeScreen.kt$@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class) @Composable private fun Content( mainUiState: MainUiState, homeUiState: HomeUiState, rootNavController: NavController, walletNavController: NavController, drawerState: DrawerState, hazeState: HazeState = rememberHazeState(), latestActivities: List<Activity>?, onClickProfile: () -> Unit = {}, onRefresh: () -> Unit = {}, onRemoveSuggestion: (Suggestion) -> Unit = {}, onClickSuggestion: (Suggestion) -> Unit = {}, onClickAddWidget: () -> Unit = {}, onClickEnableEdit: () -> Unit = {}, onClickConfirmEdit: () -> Unit = {}, onClickEditWidget: (WidgetType) -> Unit = {}, onClickDeleteWidget: (WidgetType) -> Unit = {}, onMoveWidget: (Int, Int) -> Unit = { _, _ -> }, onDismissEmptyState: () -> Unit = {}, onDismissHighBalanceSheet: () -> Unit = {}, onClickEmptyActivityRow: () -> Unit = {}, )
+ CyclomaticComplexMethod:HomeScreen.kt$@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class) @Composable private fun Content( mainUiState: MainUiState, homeUiState: HomeUiState, rootNavController: NavController, walletNavController: NavController, drawerState: DrawerState, hazeState: HazeState = rememberHazeState(), latestActivities: List<Activity>?, onClickProfile: () -> Unit = {}, onRefresh: () -> Unit = {}, onRemoveSuggestion: (Suggestion) -> Unit = {}, onClickSuggestion: (Suggestion) -> Unit = {}, onClickAddWidget: () -> Unit = {}, onClickEnableEdit: () -> Unit = {}, onClickConfirmEdit: () -> Unit = {}, onClickEditWidget: (WidgetType) -> Unit = {}, onClickDeleteWidget: (WidgetType) -> Unit = {}, onMoveWidget: (Int, Int) -> Unit = { _, _ -> }, onDismissEmptyState: () -> Unit = {}, onDismissHighBalanceSheet: () -> Unit = {}, onClickEmptyActivityRow: () -> Unit = {}, balances: BalanceState = LocalBalances.current, )
CyclomaticComplexMethod:InactivityTracker.kt$@Composable fun InactivityTracker( app: AppViewModel, settings: SettingsViewModel, modifier: Modifier = Modifier, content: @Composable () -> Unit, )
CyclomaticComplexMethod:LightningService.kt$LightningService$private fun logEvent(event: Event)
CyclomaticComplexMethod:NumberPadTextField.kt$@Composable fun AmountInputHandler( input: String, primaryDisplay: PrimaryDisplay, displayUnit: BitcoinDisplayUnit, onInputChanged: (String) -> Unit, onAmountCalculated: (String) -> Unit, currencyVM: CurrencyViewModel, overrideSats: Long? = null, )
CyclomaticComplexMethod:NumberPadTextField.kt$@Composable fun NumberPadTextField( input: String, displayUnit: BitcoinDisplayUnit, primaryDisplay: PrimaryDisplay, modifier: Modifier = Modifier, )
- CyclomaticComplexMethod:RestoreWalletScreen.kt$@OptIn(ExperimentalMaterial3Api::class) @Composable fun RestoreWalletView( onBackClick: () -> Unit, onRestoreClick: (mnemonic: String, passphrase: String?) -> Unit, )
+ CyclomaticComplexMethod:ReceiveQrScreen.kt$@Composable fun ReceiveQrScreen( cjitInvoice: MutableState<String?>, cjitActive: MutableState<Boolean>, walletState: MainUiState, onCjitToggle: (Boolean) -> Unit, onClickEditInvoice: () -> Unit, onClickReceiveOnSpending: () -> Unit, modifier: Modifier = Modifier, )
+ CyclomaticComplexMethod:RestoreWalletScreen.kt$@Composable fun RestoreWalletView( onBackClick: () -> Unit, onRestoreClick: (mnemonic: String, passphrase: String?) -> Unit, )
CyclomaticComplexMethod:SendSheet.kt$@Composable fun SendSheet( appViewModel: AppViewModel, walletViewModel: WalletViewModel, startDestination: SendRoute = SendRoute.Recipient, onComplete: (NewTransactionSheetDetails?) -> Unit, )
CyclomaticComplexMethod:SettingsButtonRow.kt$@Composable fun SettingsButtonRow( title: String, modifier: Modifier = Modifier, subtitle: String? = null, value: SettingsButtonValue = SettingsButtonValue.None, description: String? = null, iconRes: Int? = null, iconTint: Color = Color.Unspecified, iconSize: Dp = 32.dp, maxLinesSubtitle: Int = Int.MAX_VALUE, enabled: Boolean = true, loading: Boolean = false, onClick: () -> Unit, )
CyclomaticComplexMethod:Slider.kt$@Composable fun StepSlider( value: Int, steps: List<Int>, onValueChange: (Int) -> Unit, modifier: Modifier = Modifier, )
@@ -126,9 +112,7 @@
EnumNaming:BlocktankNotificationType.kt$BlocktankNotificationType$mutualClose
EnumNaming:BlocktankNotificationType.kt$BlocktankNotificationType$orderPaymentConfirmed
EnumNaming:BlocktankNotificationType.kt$BlocktankNotificationType$wakeToTimeout
- Filename:vss_rust_client_ffi.kt$uniffi.vss_rust_client_ffi.vss_rust_client_ffi.kt
ForbiddenComment:ActivityDetailScreen.kt$/* TODO: Implement assign functionality */
- ForbiddenComment:ActivityDetailScreen.kt$// TODO: handle isTransfer
ForbiddenComment:ActivityListViewModel.kt$ActivityListViewModel$// TODO: sync only on specific events for better performance
ForbiddenComment:ActivityRow.kt$// TODO: calculate confirmsIn text
ForbiddenComment:AppViewModel.kt$AppViewModel$// TODO: fee is not the sats sent. Need to get this amount from elsewhere like send flow or something.
@@ -137,6 +121,7 @@
ForbiddenComment:BackupRepo.kt$BackupRepo$// TODO: Add other backup categories as they get implemented:
ForbiddenComment:BoostTransactionViewModel.kt$BoostTransactionUiState$// TODO: Implement dynamic time estimation
ForbiddenComment:ChannelStatusView.kt$// TODO: handle closed channels marking & detection
+ ForbiddenComment:ContentView.kt$// TODO: display as sheet
ForbiddenComment:CoreService.kt$ActivityService$// TODO: find address
ForbiddenComment:CoreService.kt$ActivityService$// TODO: get from linked order
ForbiddenComment:CoreService.kt$ActivityService$// TODO: get from somewhere
@@ -149,143 +134,14 @@
ForbiddenComment:SuccessScreen.kt$// TODO: verify backup
ForbiddenComment:TransferIntroScreen.kt$// TODO: show on first LN suggestion card click
ForbiddenComment:TransferViewModel.kt$TransferViewModel$// TODO: showBottomSheet: forceTransfer
- ForbiddenComment:vss_rust_client_ffi.kt$UniFfiHandleMap$// TODO: refactor callbacks to use this class
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssDelete`(`key`: String) : Boolean
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssGet`(`key`: String) : VssItem?
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssListKeys`(`prefix`: String?) : List<KeyVersion>
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssList`(`prefix`: String?) : List<VssItem>
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssNewClient`(`baseUrl`: String, `storeId`: String)
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssPutWithKeyPrefix`(`items`: List<KeyValue>) : List<VssItem>
- FunctionNaming:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssStore`(`key`: String, `value`: ByteArray) : VssItem
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_f32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_f64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_i16(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_i32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_i64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_i8(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_pointer(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_rust_buffer(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_u16(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_u32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_u64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_u8(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_cancel_void(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_f32(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Float
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_f64(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Double
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_i16(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_i32(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Int
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_i64(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Long
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_i8(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Byte
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_pointer(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_rust_buffer(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): RustBuffer.ByValue
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_u16(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_u32(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Int
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_u64(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Long
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_u8(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Byte
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_complete_void(`handle`: Pointer,_uniffi_out_err: RustCallStatus, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_continuation_callback_set(`callback`: UniFffiRustFutureContinuationCallbackType, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_f32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_f64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_i16(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_i32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_i64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_i8(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_pointer(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_rust_buffer(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_u16(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_u32(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_u64(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_u8(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_free_void(`handle`: Pointer, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_f32(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_f64(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_i16(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_i32(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_i64(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_i8(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_pointer(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_rust_buffer(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_u16(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_u32(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_u64(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_u8(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rust_future_poll_void(`handle`: Pointer,`uniffiCallback`: USize, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rustbuffer_alloc(`size`: Int,_uniffi_out_err: RustCallStatus, ): RustBuffer.ByValue
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rustbuffer_free(`buf`: RustBuffer.ByValue,_uniffi_out_err: RustCallStatus, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rustbuffer_from_bytes(`bytes`: ForeignBytes.ByValue,_uniffi_out_err: RustCallStatus, ): RustBuffer.ByValue
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_rustbuffer_reserve(`buf`: RustBuffer.ByValue,`additional`: Int,_uniffi_out_err: RustCallStatus, ): RustBuffer.ByValue
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun ffi_vss_rust_client_ffi_uniffi_contract_version( ): Int
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_delete( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_get( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_list( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_list_keys( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_new_client( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_put_with_key_prefix( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_shutdown_client( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_checksum_func_vss_store( ): Short
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_delete(`key`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_get(`key`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_list(`prefix`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_list_keys(`prefix`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_new_client(`baseUrl`: RustBuffer.ByValue,`storeId`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_put_with_key_prefix(`items`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_shutdown_client(_uniffi_out_err: RustCallStatus, ): Unit
- FunctionNaming:vss_rust_client_ffi.kt$_UniFFILib$fun uniffi_vss_rust_client_ffi_fn_func_vss_store(`key`: RustBuffer.ByValue,`value`: RustBuffer.ByValue, ): Pointer
- FunctionNaming:vss_rust_client_ffi.kt$fun `vssShutdownClient`()
FunctionOnlyReturningConstant:RepoModule.kt$RepoModule$@Provides @Named("enablePolling") fun provideEnablePolling(): Boolean
FunctionOnlyReturningConstant:ShopWebViewInterface.kt$ShopWebViewInterface$@JavascriptInterface fun isReady(): Boolean
- FunctionParameterNaming:vss_rust_client_ffi.kt$CallStatusErrorHandler$error_buf: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$_uniffi_out_err: RustCallStatus
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`additional`: Int
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`baseUrl`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`buf`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`bytes`: ForeignBytes.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`callback`: UniFffiRustFutureContinuationCallbackType
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`handle`: Pointer
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`items`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`key`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`prefix`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`size`: Int
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`storeId`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`uniffiCallback`: USize
- FunctionParameterNaming:vss_rust_client_ffi.kt$_UniFFILib$`value`: RustBuffer.ByValue
- FunctionParameterNaming:vss_rust_client_ffi.kt$`baseUrl`: String
- FunctionParameterNaming:vss_rust_client_ffi.kt$`items`: List<KeyValue>
- FunctionParameterNaming:vss_rust_client_ffi.kt$`key`: String
- FunctionParameterNaming:vss_rust_client_ffi.kt$`prefix`: String?
- FunctionParameterNaming:vss_rust_client_ffi.kt$`storeId`: String
- FunctionParameterNaming:vss_rust_client_ffi.kt$`value`: ByteArray
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssDelete`(`key`: String) : Boolean
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssGet`(`key`: String) : VssItem?
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssListKeys`(`prefix`: String?) : List<KeyVersion>
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssList`(`prefix`: String?) : List<VssItem>
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssPutWithKeyPrefix`(`items`: List<KeyValue>) : List<VssItem>
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssStore`(`key`: String, `value`: ByteArray) : VssItem
- FunctionReturnTypeSpacing:vss_rust_client_ffi.kt$USize.Companion$fun readFromBuffer(buf: ByteBuffer) : USize
ImplicitDefaultLocale:BlocksService.kt$BlocksService$String.format("%.2f", blockInfo.difficulty / 1_000_000_000_000.0)
ImplicitDefaultLocale:PriceService.kt$PriceService$String.format("%.2f", price)
- ImportOrdering:vss_rust_client_ffi.kt$import com.sun.jna.Library import com.sun.jna.IntegerType import com.sun.jna.Native import com.sun.jna.Pointer import com.sun.jna.Structure import com.sun.jna.Callback import com.sun.jna.ptr.* import java.nio.ByteBuffer import java.nio.ByteOrder import java.nio.CharBuffer import java.nio.charset.CodingErrorAction import java.util.concurrent.ConcurrentHashMap import kotlin.coroutines.resume import kotlinx.coroutines.CancellableContinuation import kotlinx.coroutines.suspendCancellableCoroutine
- Indentation:vss_rust_client_ffi.kt$
- Indentation:vss_rust_client_ffi.kt$FfiConverter$
- Indentation:vss_rust_client_ffi.kt$FfiConverterTypeKeyValue$
- Indentation:vss_rust_client_ffi.kt$FfiConverterTypeKeyVersion$
- Indentation:vss_rust_client_ffi.kt$FfiConverterTypeListKeyVersionsResponse$
- Indentation:vss_rust_client_ffi.kt$FfiConverterTypeVssError$
- Indentation:vss_rust_client_ffi.kt$FfiConverterTypeVssItem$
- Indentation:vss_rust_client_ffi.kt$RustBuffer.Companion$
- Indentation:vss_rust_client_ffi.kt$VssException.AuthException$
- Indentation:vss_rust_client_ffi.kt$VssException.ConnectionException$
- Indentation:vss_rust_client_ffi.kt$VssException.DeleteException$
- Indentation:vss_rust_client_ffi.kt$VssException.GetException$
- Indentation:vss_rust_client_ffi.kt$VssException.InvalidData$
- Indentation:vss_rust_client_ffi.kt$VssException.ListException$
- Indentation:vss_rust_client_ffi.kt$VssException.NetworkException$
- Indentation:vss_rust_client_ffi.kt$VssException.PutException$
- Indentation:vss_rust_client_ffi.kt$VssException.StoreException$
- Indentation:vss_rust_client_ffi.kt$VssException.UnknownException$
- Indentation:vss_rust_client_ffi.kt$_UniFFILib.Companion$
InstanceOfCheckForException:LightningService.kt$LightningService$e is NodeException
+ LambdaParameterEventTrailing:AmountInput.kt$onSatsChange
LambdaParameterEventTrailing:CalculatorCard.kt$onFiatChange
+ LambdaParameterEventTrailing:QrScanningScreen.kt$onSubmitDebug
LambdaParameterEventTrailing:ReceiveQrScreen.kt$onClickEditInvoice
LambdaParameterEventTrailing:SettingsButtonRow.kt$onClick
LambdaParameterEventTrailing:SuggestionCard.kt$onClick
@@ -349,7 +205,6 @@
LongParameterList:TransferViewModel.kt$TransferViewModel$( @ApplicationContext private val context: Context, private val lightningRepo: LightningRepo, private val blocktankRepo: BlocktankRepo, private val walletRepo: WalletRepo, private val currencyRepo: CurrencyRepo, private val settingsStore: SettingsStore, private val cacheStore: CacheStore, )
LongParameterList:WalletRepo.kt$WalletRepo$( @BgDispatcher private val bgDispatcher: CoroutineDispatcher, private val db: AppDb, private val keychain: Keychain, private val coreService: CoreService, private val settingsStore: SettingsStore, private val addressChecker: AddressChecker, private val lightningRepo: LightningRepo, private val cacheStore: CacheStore, )
LongParameterList:WidgetsRepo.kt$WidgetsRepo$( @BgDispatcher private val bgDispatcher: CoroutineDispatcher, private val newsService: NewsService, private val factsService: FactsService, private val blocksService: BlocksService, private val weatherService: WeatherService, private val priceService: PriceService, private val widgetsStore: WidgetsStore, private val settingsStore: SettingsStore, )
- LongParameterList:vss_rust_client_ffi.kt$( rustFuture: Pointer, pollFunc: (Pointer, USize) -> Unit, completeFunc: (Pointer, RustCallStatus) -> F, freeFunc: (Pointer) -> Unit, liftFunc: (F) -> T, errorHandler: CallStatusErrorHandler<E> )
LoopWithTooManyJumpStatements:CoreService.kt$ActivityService$for
LoopWithTooManyJumpStatements:MonetaryVisualTransformation.kt$MonetaryVisualTransformation.<no name provided>$for
LoopWithTooManyJumpStatements:TransferViewModel.kt$TransferViewModel$while
@@ -421,7 +276,6 @@
MagicNumber:ConfirmMnemonicScreen.kt$12
MagicNumber:ConfirmMnemonicScreen.kt$24
MagicNumber:ConfirmMnemonicScreen.kt$300
- MagicNumber:ConfirmMnemonicScreen.kt$6
MagicNumber:ContentView.kt$100
MagicNumber:ContentView.kt$500
MagicNumber:Context.kt$1024
@@ -454,7 +308,6 @@
MagicNumber:InitializingWalletView.kt$500
MagicNumber:InitializingWalletView.kt$99.9
MagicNumber:Keyboard.kt$0.2f
- MagicNumber:Keyboard.kt$3
MagicNumber:LightningChannel.kt$0.5f
MagicNumber:LightningConnectionsViewModel.kt$LightningConnectionsViewModel$10
MagicNumber:LightningConnectionsViewModel.kt$LightningConnectionsViewModel$500
@@ -535,31 +388,7 @@
MagicNumber:TransferViewModel.kt$TransferViewModel$450
MagicNumber:TransferViewModel.kt$TransferViewModel$495
MagicNumber:WalletRepo.kt$WalletRepo$0.9
- MagicNumber:vss_rust_client_ffi.kt$24
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterByteArray$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterSequenceTypeKeyValue$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterSequenceTypeKeyVersion$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterSequenceTypeVssItem$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterString$3
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterString$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$10
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$3
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$4
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$5
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$6
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$7
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$8
- MagicNumber:vss_rust_client_ffi.kt$FfiConverterTypeVssError$9
- MagicNumber:vss_rust_client_ffi.kt$RustBufferByReference$16
- MagicNumber:vss_rust_client_ffi.kt$RustBufferByReference$4
- MagicNumber:vss_rust_client_ffi.kt$RustBufferByReference$8
- MagicNumber:vss_rust_client_ffi.kt$USize$4
- MagicNumber:vss_rust_client_ffi.kt$USize$8
- MagicNumber:vss_rust_client_ffi.kt$USize.Companion$4
- MagicNumber:vss_rust_client_ffi.kt$USize.Companion$8
MatchingDeclarationName:AddressType.kt$AddressTypeInfo
- MatchingDeclarationName:AdvancedSettingsScreen.kt$AdvancedSettingsTestTags
- MatchingDeclarationName:BackupSettingsScreen.kt$BackupSettingsTestTags
MatchingDeclarationName:Button.kt$ButtonSize
MatchingDeclarationName:CoinSelectPreferenceScreen.kt$CoinSelectPreferenceTestTags
MatchingDeclarationName:LightningChannel.kt$ChannelStatusUi
@@ -568,7 +397,6 @@
MatchingDeclarationName:ReportIssueScreen.kt$ReportIssueTestTags
MatchingDeclarationName:ResetAndRestoreScreen.kt$ResetAndRestoreTestTags
MatchingDeclarationName:SavingsProgressScreen.kt$SavingsProgressState
- MatchingDeclarationName:SecuritySettingsScreen.kt$SecuritySettingsTestTags
MatchingDeclarationName:SettingsButtonRow.kt$SettingsButtonValue
MaxLineLength:ActivityDetailScreen.kt$description = "Unable to increase the fee any further. Otherwise, it will exceed half the current input balance"
MaxLineLength:AppViewModel.kt$AppViewModel$// TODO: fee is not the sats sent. Need to get this amount from elsewhere like send flow or something.
@@ -612,18 +440,6 @@
MaxLineLength:SettingsScreen.kt$if (newValue) R.string.settings__dev_enabled_message else R.string.settings__dev_disabled_message
MaxLineLength:VssStoreIdProvider.kt$VssStoreIdProvider$"Do not run this on mainnet until VSS auth is implemented. Below hack is a temporary fix and not safe for mainnet."
MaxLineLength:WeatherService.kt$WeatherService$val avgFeeUsd = currencyRepo.convertSatsToFiat(avgFeeSats.toLong(), currency = USD_CURRENCY).getOrNull() ?: return FeeCondition.AVERAGE
- MaxLineLength:vss_rust_client_ffi.kt$_UniFFILib$fun
- MaxLineLength:vss_rust_client_ffi.kt$_UniFFILib.INSTANCE.uniffi_vss_rust_client_ffi_fn_func_vss_list_keys(FfiConverterOptionalString.lower(`prefix`),)
- MaxLineLength:vss_rust_client_ffi.kt$_UniFFILib.INSTANCE.uniffi_vss_rust_client_ffi_fn_func_vss_new_client(FfiConverterString.lower(`baseUrl`),FfiConverterString.lower(`storeId`),)
- MaxLineLength:vss_rust_client_ffi.kt$_UniFFILib.INSTANCE.uniffi_vss_rust_client_ffi_fn_func_vss_put_with_key_prefix(FfiConverterSequenceTypeKeyValue.lower(`items`),)
- MaxLineLength:vss_rust_client_ffi.kt$_UniFFILib.INSTANCE.uniffi_vss_rust_client_ffi_fn_func_vss_store(FfiConverterString.lower(`key`),FfiConverterByteArray.lower(`value`),)
- MaxLineLength:vss_rust_client_ffi.kt$private inline
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_complete_i8(future, continuation) }
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_complete_rust_buffer(future, continuation) }
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_complete_void(future, continuation) }
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_poll_i8(future, continuation) }
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_poll_rust_buffer(future, continuation) }
- MaxLineLength:vss_rust_client_ffi.kt${ future, continuation -> _UniFFILib.INSTANCE.ffi_vss_rust_client_ffi_rust_future_poll_void(future, continuation) }
MaximumLineLength:ActivityDetailScreen.kt$
MaximumLineLength:Bip39Test.kt$Bip39Test$
MaximumLineLength:Bip39Utils.kt$
@@ -643,9 +459,6 @@
MaximumLineLength:SettingsScreen.kt$
MaximumLineLength:VssStoreIdProvider.kt$VssStoreIdProvider$
MaximumLineLength:WeatherService.kt$WeatherService$
- MaximumLineLength:vss_rust_client_ffi.kt$
- MaximumLineLength:vss_rust_client_ffi.kt$_UniFFILib$
- MaximumLineLength:vss_rust_client_ffi.kt$private
MayBeConst:Env.kt$Env$val walletSyncIntervalSecs = 10_uL // TODO review
MayBeConst:Env.kt$Env.TransactionDefaults$/** * Minimum value in sats for an output. Outputs below the dust limit may not be processed because the fees * required to include them in a block would be greater than the value of the transaction itself. * */ val dustLimit = 546u
MayBeConst:Env.kt$Env.TransactionDefaults$/** Total recommended tx base fee in sats */ val recommendedBaseFee = 256u
@@ -653,20 +466,13 @@
ModifierComposed:AllActivityScreen.kt$swipeToChangeTab
ModifierComposed:Modifiers.kt$clickableAlpha
ModifierComposed:SheetHeight.kt$sheetHeight
- ModifierListSpacing:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend
ModifierMissing:AboutScreen.kt$AboutScreen
ModifierMissing:ActivityAddTagSheet.kt$ActivityAddTagSheet
ModifierMissing:ActivityDetailScreen.kt$ActivityDetailScreen
ModifierMissing:ActivityListSimple.kt$ActivityListSimple
ModifierMissing:ActivityRow.kt$ActivityRow
ModifierMissing:AddWidgetsScreen.kt$AddWidgetsScreen
- ModifierMissing:AmountInput.kt$AmountInput
- ModifierMissing:AppTopBar.kt$AppTopBar
- ModifierMissing:AppTopBar.kt$BackNavIcon
- ModifierMissing:AppTopBar.kt$CloseNavIcon
- ModifierMissing:AppTopBar.kt$ScanNavIcon
ModifierMissing:BackupSheet.kt$BackupSheet
- ModifierMissing:BalanceHeaderView.kt$LargeRow
ModifierMissing:BiometricsView.kt$BiometricsView
ModifierMissing:BlocksEditScreen.kt$BlocksEditContent
ModifierMissing:BlocksPreviewScreen.kt$BlocksPreviewContent
@@ -736,16 +542,13 @@
ModifierMissing:WeatherEditScreen.kt$WeatherEditContent
ModifierMissing:WeatherPreviewScreen.kt$WeatherPreviewContent
ModifierMissing:WidgetsIntroScreen.kt$WidgetsIntroScreen
- ModifierNotUsedAtRoot:QrScanningScreen.kt$modifier = modifier .fillMaxWidth() .clip(RoundedCornerShape(16.dp)) .weight(1f)
+ ModifierNotUsedAtRoot:AmountInput.kt$modifier = modifier.clickableAlpha { currency.togglePrimaryDisplay() }
ModifierNotUsedAtRoot:SettingsTextButtonRow.kt$modifier = modifier.then(if (!enabled) Modifier.alpha(0.5f) else Modifier)
- ModifierReused:QrScanningScreen.kt$Box( modifier = modifier .fillMaxWidth() .clip(RoundedCornerShape(16.dp)) .weight(1f) ) { AndroidView( modifier = Modifier .fillMaxSize() .clipToBounds(), factory = { previewView.apply { setLayerType(LAYER_TYPE_HARDWARE, null) } } ) IconButton( onClick = onClickGallery, modifier = Modifier .padding(16.dp) .clip(CircleShape) .background(Colors.White64) .size(48.dp) .align(Alignment.TopStart) ) { Icon( painter = painterResource(R.drawable.ic_image_square), contentDescription = null, tint = Colors.White ) } IconButton( onClick = onClickFlashlight, modifier = Modifier .padding(16.dp) .clip(CircleShape) .background(Colors.White64) .size(48.dp) .align(Alignment.TopEnd) ) { Icon( painter = painterResource(R.drawable.ic_flashlight), contentDescription = null, tint = Colors.White ) } }
- ModifierReused:QrScanningScreen.kt$Column( modifier = modifier .fillMaxSize() .padding(horizontal = 16.dp) ) { Box( modifier = modifier .fillMaxWidth() .clip(RoundedCornerShape(16.dp)) .weight(1f) ) { AndroidView( modifier = Modifier .fillMaxSize() .clipToBounds(), factory = { previewView.apply { setLayerType(LAYER_TYPE_HARDWARE, null) } } ) IconButton( onClick = onClickGallery, modifier = Modifier .padding(16.dp) .clip(CircleShape) .background(Colors.White64) .size(48.dp) .align(Alignment.TopStart) ) { Icon( painter = painterResource(R.drawable.ic_image_square), contentDescription = null, tint = Colors.White ) } IconButton( onClick = onClickFlashlight, modifier = Modifier .padding(16.dp) .clip(CircleShape) .background(Colors.White64) .size(48.dp) .align(Alignment.TopEnd) ) { Icon( painter = painterResource(R.drawable.ic_flashlight), contentDescription = null, tint = Colors.White ) } } Spacer(modifier = Modifier.height(16.dp)) PrimaryButton( icon = { Icon( painterResource(R.drawable.ic_clipboard_text_simple), contentDescription = stringResource(R.string.other__qr_paste), ) }, text = stringResource(R.string.other__qr_paste), onClick = onPasteFromClipboard ) Spacer(modifier = Modifier.height(16.dp)) }
ModifierWithoutDefault:ReceiveQrScreen.kt$modifier
ModifierWithoutDefault:SyncNodeView.kt$modifier
ModifierWithoutDefault:WalletBalanceView.kt$modifier
MultipleEmitters:ActivityExploreScreen.kt$LightningDetails
MultipleEmitters:DrawerMenu.kt$DrawerMenu
- MultipleEmitters:OnboardingSlidesScreen.kt$OnboardingSlidesScreen
MultipleEmitters:SendConfirmScreen.kt$LnurlCommentSection
MultipleEmitters:SendConfirmScreen.kt$TagsSection
MutableStateAutoboxing:DragDropColumn.kt$mutableStateOf(0f)
@@ -755,44 +558,7 @@
NestedBlockDepth:LogsRepo.kt$LogsRepo$private fun createZipBase64(logFiles: List<LogFile>): String
NestedBlockDepth:MonetaryVisualTransformation.kt$MonetaryVisualTransformation$private fun createOffsetMapping(original: String, transformed: String): OffsetMapping
NestedBlockDepth:ShopWebViewInterface.kt$ShopWebViewInterface$@JavascriptInterface fun postMessage(message: String)
- NoBlankLineBeforeRbrace:vss_rust_client_ffi.kt$FfiConverterTypeVssError$
- NoBlankLineBeforeRbrace:vss_rust_client_ffi.kt$VssException$
- NoBlankLineBeforeRbrace:vss_rust_client_ffi.kt$_UniFFILib$
- NoConsecutiveBlankLines:vss_rust_client_ffi.kt$
- NoConsecutiveBlankLines:vss_rust_client_ffi.kt$FfiConverterTypeVssError$
- NoConsecutiveBlankLines:vss_rust_client_ffi.kt$VssException$
- NoEmptyFirstLineInMethodBlock:vss_rust_client_ffi.kt$FfiConverterTypeVssError$
- NoSemicolons:vss_rust_client_ffi.kt$;
- NoSemicolons:vss_rust_client_ffi.kt$CallStatusErrorHandler$;
- NoSemicolons:vss_rust_client_ffi.kt$UniFffiRustFutureContinuationCallbackType$;
- NoTrailingSpaces:vss_rust_client_ffi.kt$
- NoTrailingSpaces:vss_rust_client_ffi.kt$FfiConverterTypeVssError$
- NoTrailingSpaces:vss_rust_client_ffi.kt$KeyValue$
- NoTrailingSpaces:vss_rust_client_ffi.kt$KeyVersion$
- NoTrailingSpaces:vss_rust_client_ffi.kt$ListKeyVersionsResponse$
- NoTrailingSpaces:vss_rust_client_ffi.kt$VssException$
- NoTrailingSpaces:vss_rust_client_ffi.kt$VssItem$
- NoTrailingSpaces:vss_rust_client_ffi.kt$_UniFFILib$
NoWildcardImports:LightningChannel.kt$import androidx.compose.foundation.layout.*
- NoWildcardImports:vss_rust_client_ffi.kt$import com.sun.jna.ptr.*
- PackageName:vss_rust_client_ffi.kt$package uniffi.vss_rust_client_ffi;
- PackageNaming:vss_rust_client_ffi.kt$package uniffi.vss_rust_client_ffi;
- ParameterListWrapping:vss_rust_client_ffi.kt$(RustCallStatus)
- ParameterListWrapping:vss_rust_client_ffi.kt$(errorHandler: CallStatusErrorHandler<E>, callback: (RustCallStatus) -> U)
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(_uniffi_out_err: RustCallStatus, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`baseUrl`: RustBuffer.ByValue,`storeId`: RustBuffer.ByValue, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`buf`: RustBuffer.ByValue,_uniffi_out_err: RustCallStatus, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`buf`: RustBuffer.ByValue,`additional`: Int,_uniffi_out_err: RustCallStatus, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`bytes`: ForeignBytes.ByValue,_uniffi_out_err: RustCallStatus, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`callback`: UniFffiRustFutureContinuationCallbackType, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`handle`: Pointer, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`handle`: Pointer,_uniffi_out_err: RustCallStatus, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`handle`: Pointer,`uniffiCallback`: USize, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`items`: RustBuffer.ByValue, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`key`: RustBuffer.ByValue, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`key`: RustBuffer.ByValue,`value`: RustBuffer.ByValue, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`prefix`: RustBuffer.ByValue, )
- ParameterListWrapping:vss_rust_client_ffi.kt$_UniFFILib$(`size`: Int,_uniffi_out_err: RustCallStatus, )
ParameterNaming:AddTagScreen.kt$onInputUpdated
ParameterNaming:AddTagScreen.kt$onTagConfirmed
ParameterNaming:AddTagScreen.kt$onTagSelected
@@ -842,62 +608,10 @@
ReturnCount:ChannelStatusView.kt$@Composable private fun getStatusInfo( channel: ChannelUi, blocktankOrder: IBtOrder?, ): StatusInfo
ReturnCount:FcmService.kt$FcmService$private fun decryptPayload(response: EncryptedNotification)
ReturnCount:LightningConnectionsViewModel.kt$LightningConnectionsViewModel$private fun findUpdatedChannel( currentChannel: ChannelDetails, allChannels: List<ChannelDetails>, ): ChannelDetails?
- SpacingAroundColon:vss_rust_client_ffi.kt$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterBoolean$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterByteArray$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterLong$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterOptionalString$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterOptionalTypeVssItem$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterRustBuffer$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterSequenceTypeKeyValue$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterSequenceTypeKeyVersion$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterSequenceTypeVssItem$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterString$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterTypeKeyValue$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterTypeKeyVersion$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterTypeListKeyVersionsResponse$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterTypeVssFilterType$:
- SpacingAroundColon:vss_rust_client_ffi.kt$FfiConverterTypeVssItem$:
- SpacingAroundColon:vss_rust_client_ffi.kt$NullCallStatusErrorHandler$:
- SpacingAroundColon:vss_rust_client_ffi.kt$RustBuffer.ByReference$:
- SpacingAroundColon:vss_rust_client_ffi.kt$RustBuffer.ByValue$:
- SpacingAroundColon:vss_rust_client_ffi.kt$RustCallStatus.ByValue$:
- SpacingAroundColon:vss_rust_client_ffi.kt$USize.Companion$:
- SpacingAroundColon:vss_rust_client_ffi.kt$UniFfiHandleMap$:
- SpacingAroundColon:vss_rust_client_ffi.kt$VssException$:
- SpacingAroundColon:vss_rust_client_ffi.kt$uniffiRustFutureContinuationCallback$:
- SpacingAroundComma:vss_rust_client_ffi.kt$,
- SpacingAroundComma:vss_rust_client_ffi.kt$VssFilterType.PREFIX$,
- SpacingAroundComma:vss_rust_client_ffi.kt$_UniFFILib$,
- SpacingAroundKeyword:vss_rust_client_ffi.kt$FfiConverterTypeVssError$when
- SpacingAroundKeyword:vss_rust_client_ffi.kt$RustBuffer.Companion$if
- SpacingAroundParens:vss_rust_client_ffi.kt$KeyValue$(
- SpacingAroundParens:vss_rust_client_ffi.kt$KeyVersion$(
- SpacingAroundParens:vss_rust_client_ffi.kt$ListKeyVersionsResponse$(
- SpacingAroundParens:vss_rust_client_ffi.kt$VssItem$(
- SpacingAroundParens:vss_rust_client_ffi.kt$_UniFFILib$(
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssGet`(`key`: String) : VssItem?
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssListKeys`(`prefix`: String?) : List<KeyVersion>
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssList`(`prefix`: String?) : List<VssItem>
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssNewClient`(`baseUrl`: String, `storeId`: String)
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$@Throws(VssException::class) @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") suspend fun `vssPutWithKeyPrefix`(`items`: List<KeyValue>) : List<VssItem>
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$ForeignBytes$@JvmField var data: Pointer? = null
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$RustBuffer$@JvmField var data: Pointer? = null
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$RustBuffer$@JvmField var len: Int = 0
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$RustCallStatus : Structure
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$RustCallStatus$@JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue()
- SpacingBetweenDeclarationsWithAnnotations:vss_rust_client_ffi.kt$USize$@Deprecated("`toInt().toChar()` is deprecated") override fun toChar()
- SpacingBetweenDeclarationsWithComments:vss_rust_client_ffi.kt$FfiConverter$// The FfiConverter interface handles converter types to and from the FFI
- SpacingBetweenDeclarationsWithComments:vss_rust_client_ffi.kt$RustCallStatus$// A handful of classes and functions to support the generated data structures.
- SpacingBetweenDeclarationsWithComments:vss_rust_client_ffi.kt$USize$// Needed until https://youtrack.jetbrains.com/issue/KT-47902 is fixed.
- SpacingBetweenDeclarationsWithComments:vss_rust_client_ffi.kt$UniFfiHandleMap$// Use AtomicInteger for our counter, since we may be on a 32-bit system. 4 billion possible
SpreadOperator:RestoreWalletScreen.kt$(*Array(24) { "" })
- StringTemplate:vss_rust_client_ffi.kt$RustBuffer.Companion$${size}
SwallowedException:Crypto.kt$Crypto$e: Exception
SwallowedException:FcmService.kt$FcmService$e: SerializationException
ThrowingExceptionsWithoutMessageOrCause:ActivityRepo.kt$ActivityRepo$Exception()
- ThrowsCount:vss_rust_client_ffi.kt$@Suppress("UNUSED_PARAMETER") private fun uniffiCheckApiChecksums(lib: _UniFFILib)
- ThrowsCount:vss_rust_client_ffi.kt$private fun<E: Exception> checkCallStatus(errorHandler: CallStatusErrorHandler<E>, status: RustCallStatus)
TooGenericExceptionCaught:ActivityDetailViewModel.kt$ActivityDetailViewModel$e: Exception
TooGenericExceptionCaught:ActivityDetailViewModel.kt$ActivityDetailViewModel$e: Throwable
TooGenericExceptionCaught:ActivityListViewModel.kt$ActivityListViewModel$e: Exception
@@ -943,21 +657,11 @@
TooGenericExceptionCaught:WakeNodeWorker.kt$WakeNodeWorker$e: Exception
TooGenericExceptionCaught:WalletRepo.kt$WalletRepo$e: Exception
TooGenericExceptionCaught:WalletRepo.kt$WalletRepo$e: Throwable
- TooGenericExceptionCaught:vss_rust_client_ffi.kt$FfiConverter$e: Throwable
- TooGenericExceptionCaught:vss_rust_client_ffi.kt$FfiConverterTypeVssFilterType$e: IndexOutOfBoundsException
TooGenericExceptionThrown:BlocktankHttpClient.kt$BlocktankHttpClient$throw Exception("Http error: ${response.status}")
TooGenericExceptionThrown:FileSystem.kt$throw Error("Cannot create path: $this")
TooGenericExceptionThrown:LnurlService.kt$LnurlService$throw Exception("HTTP error: ${response.status}")
TooGenericExceptionThrown:LnurlService.kt$LnurlService$throw Exception("LNURL channel error: ${parsedResponse.reason}")
TooGenericExceptionThrown:LnurlService.kt$LnurlService$throw Exception("LNURL error: ${withdrawResponse.reason}")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$FfiConverter$throw RuntimeException("junk remaining in buffer after lifting, something is very wrong!!")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$FfiConverterTypeVssError$throw RuntimeException("invalid error enum value, something is very wrong!!")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$FfiConverterTypeVssFilterType$throw RuntimeException("invalid enum value, something is very wrong!!", e)
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$RustBuffer.Companion$throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=${size})")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$USize$throw RuntimeException("Invalid SIZE_T_SIZE: ${Native.SIZE_T_SIZE}")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$USize.Companion$throw RuntimeException("Invalid SIZE_T_SIZE: ${Native.SIZE_T_SIZE}")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
- TooGenericExceptionThrown:vss_rust_client_ffi.kt$throw RuntimeException("UniFFI contract version mismatch: try cleaning and rebuilding your project")
TooManyFunctions:ActivityListViewModel.kt$ActivityListViewModel : ViewModel
TooManyFunctions:ActivityRepo.kt$ActivityRepo
TooManyFunctions:AppViewModel.kt$AppViewModel : ViewModel
@@ -983,6 +687,7 @@
TooManyFunctions:Logger.kt$Logger
TooManyFunctions:NodeInfoScreen.kt$to.bitkit.ui.NodeInfoScreen.kt
TooManyFunctions:NumberPadTextField.kt$to.bitkit.ui.components.NumberPadTextField.kt
+ TooManyFunctions:SendAmountScreen.kt$to.bitkit.ui.screens.wallets.send.SendAmountScreen.kt
TooManyFunctions:SendConfirmScreen.kt$to.bitkit.ui.screens.wallets.send.SendConfirmScreen.kt
TooManyFunctions:SettingsViewModel.kt$SettingsViewModel : ViewModel
TooManyFunctions:TOS.kt$to.bitkit.ui.onboarding.TOS.kt
@@ -993,20 +698,13 @@
TooManyFunctions:WalletViewModel.kt$WalletViewModel : ViewModel
TooManyFunctions:WidgetsRepo.kt$WidgetsRepo
TooManyFunctions:WidgetsStore.kt$WidgetsStore
- TooManyFunctions:vss_rust_client_ffi.kt$_UniFFILib : Library
- TooManyFunctions:vss_rust_client_ffi.kt$uniffi.vss_rust_client_ffi.vss_rust_client_ffi.kt
TopLevelPropertyNaming:DrawerMenu.kt$private const val zIndexMenu = 11f
TopLevelPropertyNaming:DrawerMenu.kt$private const val zIndexScrim = 10f
- UnnecessaryParenthesesBeforeTrailingLambda:vss_rust_client_ffi.kt$()
- UnnecessaryParenthesesBeforeTrailingLambda:vss_rust_client_ffi.kt$RustBuffer.Companion$()
+ UnusedParameter:HomeScreen.kt$onClickEnableEdit: () -> Unit = {}
UnusedPrivateProperty:ActivityListViewModel.kt$ActivityListViewModel$private val lightningRepo: LightningRepo
UnusedPrivateProperty:ActivityRepoTest.kt$ActivityRepoTest$private val testOnChainActivity = mock<Activity.Onchain> { on { v1 } doReturn testOnChainActivityV1 }
UnusedPrivateProperty:CurrencyRepoTest.kt$CurrencyRepoTest$private val toastEventBus: ToastEventBus = mock()
UseCheckOrError:CurrencyRepo.kt$CurrencyRepo$throw IllegalStateException( "Rate not found for currency: $targetCurrency. Available currencies: ${ _currencyState.value.rates.joinToString { it.quote } }" )
- VariableNaming:vss_rust_client_ffi.kt$RustCallStatus$@JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue()
- VariableNaming:vss_rust_client_ffi.kt$val bindings_contract_version = 24
- VariableNaming:vss_rust_client_ffi.kt$val return_value = callback(status)
- VariableNaming:vss_rust_client_ffi.kt$val scaffolding_contract_version = lib.ffi_vss_rust_client_ffi_uniffi_contract_version()
ViewModelForwarding:ActivityDetailScreen.kt$ActivityAddTagSheet( listViewModel = listViewModel, activityViewModel = detailViewModel, onDismiss = { showAddTagSheet = false }, )
ViewModelForwarding:ContentView.kt$BackupSheet(sheet, appViewModel)
ViewModelForwarding:ContentView.kt$LnurlAuthSheet(sheet, appViewModel)
@@ -1022,7 +720,5 @@
ViewModelForwarding:HomeNav.kt$NavContent( walletNavController = walletNavController, rootNavController = rootNavController, mainUiState = uiState, drawerState = drawerState, settingsViewModel = settingsViewModel, appViewModel = appViewModel, walletViewModel = walletViewModel, activityListViewModel = activityListViewModel, )
ViewModelForwarding:HomeScreen.kt$DeleteWidgetAlert(type, homeViewModel)
WildcardImport:LightningChannel.kt$import androidx.compose.foundation.layout.*
- WildcardImport:vss_rust_client_ffi.kt$import com.sun.jna.ptr.*
- Wrapping:vss_rust_client_ffi.kt$_UniFFILib$(
diff --git a/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt b/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt
index 16effaf6e..493e63bd9 100644
--- a/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt
@@ -28,18 +28,18 @@ class KeyboardTest {
Keyboard(onClick = {}, onClickBackspace = {})
}
- composeTestRule.onNodeWithTag("KeyboardButton_1").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_2").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_3").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_4").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_5").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_6").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_7").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_8").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_9").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_.").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_0").assertIsDisplayed()
- composeTestRule.onNodeWithTag("KeyboardButton_backspace").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N1").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N2").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N3").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N4").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N5").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N6").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N7").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N8").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N9").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N.").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N0").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("NRemove").assertIsDisplayed()
}
@Test
@@ -47,7 +47,7 @@ class KeyboardTest {
composeTestRule.setContent {
Keyboard(onClick = {}, isDecimal = false, onClickBackspace = {})
}
- composeTestRule.onNodeWithTag("KeyboardButton_000").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N000").assertIsDisplayed()
}
@Test
@@ -55,7 +55,7 @@ class KeyboardTest {
composeTestRule.setContent {
Keyboard(onClick = {}, isDecimal = true, onClickBackspace = {})
}
- composeTestRule.onNodeWithTag("KeyboardButton_.").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("N.").assertIsDisplayed()
}
@Test
@@ -65,13 +65,13 @@ class KeyboardTest {
Keyboard(onClick = { clickedValue = it }, onClickBackspace = {})
}
- composeTestRule.onNodeWithTag("KeyboardButton_5").performClick()
+ composeTestRule.onNodeWithTag("N5").performClick()
assert(clickedValue == "5")
- composeTestRule.onNodeWithTag("KeyboardButton_.").performClick()
+ composeTestRule.onNodeWithTag("N.").performClick()
assert(clickedValue == ".")
- composeTestRule.onNodeWithTag("KeyboardButton_0").performClick()
+ composeTestRule.onNodeWithTag("N0").performClick()
assert(clickedValue == "0")
}
@@ -83,7 +83,7 @@ class KeyboardTest {
Keyboard(onClick = { clickedValue = it }, onClickBackspace = {}, isDecimal = false)
}
- composeTestRule.onNodeWithTag("KeyboardButton_000").performClick()
+ composeTestRule.onNodeWithTag("N000").performClick()
assert(clickedValue == "000")
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/wallets/send/SendAmountContentTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/wallets/send/SendAmountContentTest.kt
index 448dda1c4..759ce22e5 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/wallets/send/SendAmountContentTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/wallets/send/SendAmountContentTest.kt
@@ -50,7 +50,7 @@ class SendAmountContentTest {
composeTestRule.onNodeWithTag("send_amount_screen").assertExists()
// composeTestRule.onNodeWithTag("amount_input_field").assertExists() doesn't displayed because of viewmodel injection
composeTestRule.onNodeWithTag("available_balance").assertExists()
- composeTestRule.onNodeWithTag("payment_method_button").assertExists()
+ composeTestRule.onNodeWithTag("AssetButton-switch").assertExists()
composeTestRule.onNodeWithTag("continue_button").assertExists()
composeTestRule.onNodeWithTag("amount_keyboard").assertExists()
}
@@ -98,7 +98,7 @@ class SendAmountContentTest {
)
}
- composeTestRule.onNodeWithTag("payment_method_button")
+ composeTestRule.onNodeWithTag("AssetButton-switch")
.performClick()
assert(eventTriggered)
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt
index 2cc9ec216..e9d6d043e 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreenTest.kt
@@ -63,7 +63,7 @@ class BlocksEditScreenTest {
// Assert main elements exist
composeTestRule.onNodeWithTag("blocks_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
// Verify description
composeTestRule.onNodeWithTag("edit_description").assertExists()
@@ -82,18 +82,18 @@ class BlocksEditScreenTest {
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
// Test button clicks
composeTestRule.onNodeWithTag("block_toggle_button").performClick()
assert(blockClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
// Reset button should be disabled with default preferences
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -128,10 +128,10 @@ class BlocksEditScreenTest {
}
// Assert reset button should be enabled when preferences are customized
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
// Test reset button click
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -159,7 +159,7 @@ class BlocksEditScreenTest {
}
}
- composeTestRule.onNodeWithTag("preview_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertIsEnabled()
}
@Test
@@ -193,7 +193,7 @@ class BlocksEditScreenTest {
}
}
- composeTestRule.onNodeWithTag("preview_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertIsNotEnabled()
}
@Test
@@ -255,10 +255,10 @@ class BlocksEditScreenTest {
composeTestRule.onNodeWithTag("source_toggle_button").performClick()
assert(sourceClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -330,7 +330,7 @@ class BlocksEditScreenTest {
// Assert all tagged elements exist
composeTestRule.onNodeWithTag("blocks_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
composeTestRule.onNodeWithTag("edit_description").assertExists()
listOf("block", "time", "date", "transactions", "size", "source").forEach { prefix ->
@@ -342,8 +342,8 @@ class BlocksEditScreenTest {
}
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt
index 6b8920906..5f2f0aca8 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreenTest.kt
@@ -62,23 +62,23 @@ class BlocksPreviewContentTest {
composeTestRule.onNodeWithTag("widget_description").assertExists()
// Verify settings and preview section
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("block_card").assertExists()
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test button clicks
- composeTestRule.onNodeWithTag("edit_settings_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEdit").performClick()
assert(editClicked)
- composeTestRule.onNodeWithTag("delete_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetDelete").performClick()
assert(deleteClicked)
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -113,11 +113,11 @@ class BlocksPreviewContentTest {
composeTestRule.onNodeWithTag("buttons_row").assertExists()
// Delete button should not exist when widget is disabled
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test save button click
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -152,7 +152,7 @@ class BlocksPreviewContentTest {
// Assert that all elements still exist with custom preferences
composeTestRule.onNodeWithTag("blocks_preview_screen").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("block_card").assertExists()
}
@@ -183,12 +183,12 @@ class BlocksPreviewContentTest {
composeTestRule.onNodeWithTag("widget_icon").assertExists()
composeTestRule.onNodeWithTag("widget_description").assertExists()
composeTestRule.onNodeWithTag("divider").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("block_card").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
}
@Test
@@ -248,8 +248,8 @@ class BlocksPreviewContentTest {
// Assert core elements still exist
composeTestRule.onNodeWithTag("blocks_preview_screen").assertExists()
composeTestRule.onNodeWithTag("block_card").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
}
@Test
@@ -305,7 +305,7 @@ class BlocksPreviewContentTest {
}
// Assert edit button shows custom state
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
}
@Test
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt
index fe44d59d0..ab799b484 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreenTest.kt
@@ -44,7 +44,7 @@ class FactsEditContentTest {
// Assert main elements exist
composeTestRule.onNodeWithTag("facts_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
// Verify description
composeTestRule.onNodeWithTag("edit_description").assertExists()
@@ -68,18 +68,18 @@ class FactsEditContentTest {
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
// Test button clicks
composeTestRule.onNodeWithTag("source_toggle_button").performClick()
assert(sourceClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
// Reset button should be disabled when source is enabled (default state)
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -105,10 +105,10 @@ class FactsEditContentTest {
}
// Assert reset button should be enabled when source is enabled
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
// Test reset button click
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -152,7 +152,7 @@ class FactsEditContentTest {
// Assert all tagged elements exist
composeTestRule.onNodeWithTag("facts_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
composeTestRule.onNodeWithTag("edit_description").assertExists()
composeTestRule.onNodeWithTag("title_setting_row").assertExists()
composeTestRule.onNodeWithTag("title_text").assertExists()
@@ -166,8 +166,8 @@ class FactsEditContentTest {
composeTestRule.onNodeWithTag("source_toggle_icon", useUnmergedTree = true).assertExists()
composeTestRule.onNodeWithTag("source_divider").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
}
@Test
@@ -189,7 +189,7 @@ class FactsEditContentTest {
}
}
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
}
@Test
@@ -211,7 +211,7 @@ class FactsEditContentTest {
}
}
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -243,10 +243,10 @@ class FactsEditContentTest {
composeTestRule.onNodeWithTag("source_toggle_button").performClick()
assert(sourceClicked)
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt
index 30a37f851..960638e33 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreenTest.kt
@@ -54,23 +54,23 @@ class FactsPreviewContentTest {
composeTestRule.onNodeWithTag("widget_description").assertExists()
// Verify settings and preview section
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("fact_card").assertExists()
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test button clicks
- composeTestRule.onNodeWithTag("edit_settings_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEdit").performClick()
assert(editClicked)
- composeTestRule.onNodeWithTag("delete_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetDelete").performClick()
assert(deleteClicked)
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -105,11 +105,11 @@ class FactsPreviewContentTest {
composeTestRule.onNodeWithTag("buttons_row").assertExists()
// Delete button should not exist when widget is disabled
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test save button click
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -137,7 +137,7 @@ class FactsPreviewContentTest {
// Assert that all elements still exist with custom preferences
composeTestRule.onNodeWithTag("facts_preview_screen").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("fact_card").assertExists()
}
@@ -168,12 +168,12 @@ class FactsPreviewContentTest {
composeTestRule.onNodeWithTag("widget_icon").assertExists()
composeTestRule.onNodeWithTag("widget_description").assertExists()
composeTestRule.onNodeWithTag("divider").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("fact_card").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
}
@Test
@@ -226,8 +226,8 @@ class FactsPreviewContentTest {
// Assert core elements still exist
composeTestRule.onNodeWithTag("facts_preview_screen").assertExists()
composeTestRule.onNodeWithTag("fact_card").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
}
@Test
@@ -276,6 +276,6 @@ class FactsPreviewContentTest {
}
// Assert edit button shows custom state
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt
index dcc76bcdd..f78d729a8 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditContentTest.kt
@@ -56,7 +56,7 @@ class HeadlinesEditContentTest {
// Assert main elements exist
composeTestRule.onNodeWithTag("headlines_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
// Verify description
composeTestRule.onNodeWithTag("edit_description").assertExists()
@@ -87,8 +87,8 @@ class HeadlinesEditContentTest {
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
// Test button clicks
composeTestRule.onNodeWithTag("time_toggle_button").performClick()
@@ -97,11 +97,11 @@ class HeadlinesEditContentTest {
composeTestRule.onNodeWithTag("source_toggle_button").performClick()
assert(sourceClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
// Reset button should be disabled when both options are enabled (default state)
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -131,10 +131,10 @@ class HeadlinesEditContentTest {
}
// Assert reset button should be enabled when not all options are enabled
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
// Test reset button click
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -163,7 +163,7 @@ class HeadlinesEditContentTest {
}
// Assert reset button should be enabled when not all options are enabled
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
// Verify all elements still exist
composeTestRule.onNodeWithTag("headlines_edit_screen").assertExists()
@@ -213,7 +213,7 @@ class HeadlinesEditContentTest {
// Assert all tagged elements exist
composeTestRule.onNodeWithTag("headlines_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
composeTestRule.onNodeWithTag("edit_description").assertExists()
composeTestRule.onNodeWithTag("time_setting_row").assertExists()
composeTestRule.onNodeWithTag("time_text").assertExists()
@@ -231,8 +231,8 @@ class HeadlinesEditContentTest {
composeTestRule.onNodeWithTag("source_toggle_icon").assertExists()
composeTestRule.onNodeWithTag("source_divider").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
}
@Test
@@ -258,7 +258,7 @@ class HeadlinesEditContentTest {
}
}
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
}
@Test
@@ -284,7 +284,7 @@ class HeadlinesEditContentTest {
}
}
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -324,10 +324,10 @@ class HeadlinesEditContentTest {
composeTestRule.onNodeWithTag("source_toggle_button").performClick()
assert(sourceClicked)
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt
index 3bc5e8010..e037640b7 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewContentTest.kt
@@ -63,23 +63,23 @@ class HeadlinesPreviewContentTest {
composeTestRule.onNodeWithTag("widget_description").assertExists()
// Verify settings and preview section
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("headline_card").assertExists()
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test button clicks
- composeTestRule.onNodeWithTag("edit_settings_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEdit").performClick()
assert(editClicked)
- composeTestRule.onNodeWithTag("delete_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetDelete").performClick()
assert(deleteClicked)
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -114,11 +114,11 @@ class HeadlinesPreviewContentTest {
composeTestRule.onNodeWithTag("buttons_row").assertExists()
// Delete button should not exist when headlines are not implemented
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test save button click
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -149,7 +149,7 @@ class HeadlinesPreviewContentTest {
// Assert that all elements still exist with custom preferences
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("headline_card").assertExists()
}
@@ -180,12 +180,12 @@ class HeadlinesPreviewContentTest {
composeTestRule.onNodeWithTag("widget_icon").assertExists()
composeTestRule.onNodeWithTag("widget_description").assertExists()
composeTestRule.onNodeWithTag("divider").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("headline_card").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
}
@Test
@@ -239,7 +239,7 @@ class HeadlinesPreviewContentTest {
// Assert core elements still exist
composeTestRule.onNodeWithTag("headlines_preview_screen").assertExists()
composeTestRule.onNodeWithTag("headline_card").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt
index b1f13e444..df07f2497 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreenTest.kt
@@ -60,7 +60,7 @@ class WeatherEditScreenTest {
// Assert main elements exist
composeTestRule.onNodeWithTag("weather_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
// Verify description
composeTestRule.onNodeWithTag("edit_description").assertExists()
@@ -76,18 +76,18 @@ class WeatherEditScreenTest {
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
// Test button clicks
composeTestRule.onNodeWithTag("title_toggle_button").performClick()
assert(titleClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
// Reset button should be disabled with default preferences
- composeTestRule.onNodeWithTag("reset_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsNotEnabled()
}
@Test
@@ -121,10 +121,10 @@ class WeatherEditScreenTest {
}
// Assert reset button should be enabled when preferences are customized
- composeTestRule.onNodeWithTag("reset_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertIsEnabled()
// Test reset button click
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -150,7 +150,7 @@ class WeatherEditScreenTest {
}
}
- composeTestRule.onNodeWithTag("preview_button").assertIsEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertIsEnabled()
}
@Test
@@ -180,7 +180,7 @@ class WeatherEditScreenTest {
}
}
- composeTestRule.onNodeWithTag("preview_button").assertIsNotEnabled()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertIsNotEnabled()
}
@Test
@@ -230,10 +230,10 @@ class WeatherEditScreenTest {
composeTestRule.onNodeWithTag("next_block_fee_toggle_button").performClick()
assert(nextBlockFeeClicked)
- composeTestRule.onNodeWithTag("preview_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").performClick()
assert(previewClicked)
- composeTestRule.onNodeWithTag("reset_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEditReset").performClick()
assert(resetClicked)
}
@@ -298,7 +298,7 @@ class WeatherEditScreenTest {
// Assert all tagged elements exist
composeTestRule.onNodeWithTag("weather_edit_screen").assertExists()
- composeTestRule.onNodeWithTag("main_content").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditScrollView").assertExists()
composeTestRule.onNodeWithTag("edit_description").assertExists()
listOf("title", "description", "current_fee", "next_block_fee").forEach { prefix ->
@@ -309,8 +309,8 @@ class WeatherEditScreenTest {
}
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("reset_button").assertExists()
- composeTestRule.onNodeWithTag("preview_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditReset").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEditPreview").assertExists()
}
@Test
diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt
index 1280da716..8c1de2847 100644
--- a/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreenTest.kt
@@ -64,23 +64,23 @@ class WeatherPreviewContentTest {
composeTestRule.onNodeWithTag("widget_description").assertExists()
// Verify settings and preview section
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("weather_card").assertExists()
// Verify buttons
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test button clicks
- composeTestRule.onNodeWithTag("edit_settings_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetEdit").performClick()
assert(editClicked)
- composeTestRule.onNodeWithTag("delete_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetDelete").performClick()
assert(deleteClicked)
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -115,11 +115,11 @@ class WeatherPreviewContentTest {
composeTestRule.onNodeWithTag("buttons_row").assertExists()
// Delete button should not exist when widget is disabled
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
// Test save button click
- composeTestRule.onNodeWithTag("save_button").performClick()
+ composeTestRule.onNodeWithTag("WidgetSave").performClick()
assert(saveClicked)
}
@@ -152,7 +152,7 @@ class WeatherPreviewContentTest {
// Assert that all elements still exist with custom preferences
composeTestRule.onNodeWithTag("weather_preview_screen").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("weather_card").assertExists()
}
@@ -183,12 +183,12 @@ class WeatherPreviewContentTest {
composeTestRule.onNodeWithTag("widget_icon").assertExists()
composeTestRule.onNodeWithTag("widget_description").assertExists()
composeTestRule.onNodeWithTag("divider").assertExists()
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
composeTestRule.onNodeWithTag("preview_label").assertExists()
composeTestRule.onNodeWithTag("weather_card").assertExists()
composeTestRule.onNodeWithTag("buttons_row").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertExists()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
}
@Test
@@ -246,8 +246,8 @@ class WeatherPreviewContentTest {
// Assert core elements still exist
composeTestRule.onNodeWithTag("weather_preview_screen").assertExists()
composeTestRule.onNodeWithTag("weather_card").assertExists()
- composeTestRule.onNodeWithTag("save_button").assertExists()
- composeTestRule.onNodeWithTag("delete_button").assertDoesNotExist()
+ composeTestRule.onNodeWithTag("WidgetSave").assertExists()
+ composeTestRule.onNodeWithTag("WidgetDelete").assertDoesNotExist()
}
@Test
@@ -301,7 +301,7 @@ class WeatherPreviewContentTest {
}
// Assert edit button shows custom state
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
}
@Test
@@ -347,6 +347,6 @@ class WeatherPreviewContentTest {
}
// Assert edit button shows default state
- composeTestRule.onNodeWithTag("edit_settings_button").assertExists()
+ composeTestRule.onNodeWithTag("WidgetEdit").assertExists()
}
}
diff --git a/app/src/androidTest/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreenTest.kt b/app/src/androidTest/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreenTest.kt
index 7b98c7350..39fa168f2 100644
--- a/app/src/androidTest/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreenTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreenTest.kt
@@ -36,7 +36,7 @@ class QuickPaySettingsScreenTest {
}
}
- composeTestRule.onNodeWithTag("quickpay_toggle_switch").assertIsDisplayed()
+ composeTestRule.onNodeWithTag("QuickpayToggle").assertIsDisplayed()
composeTestRule.onNodeWithTag("quickpay_amount_slider").assertIsDisplayed()
}
@@ -58,7 +58,7 @@ class QuickPaySettingsScreenTest {
}
}
- composeTestRule.onNodeWithTag("quickpay_toggle_switch")
+ composeTestRule.onNodeWithTag("QuickpayToggle")
.performClick()
assert(toggleCalled)
diff --git a/app/src/androidTest/java/to/bitkit/ui/sheets/NewTransactionSheetViewTest.kt b/app/src/androidTest/java/to/bitkit/ui/sheets/NewTransactionSheetViewTest.kt
index 3ee4a8ff7..5a7769d36 100644
--- a/app/src/androidTest/java/to/bitkit/ui/sheets/NewTransactionSheetViewTest.kt
+++ b/app/src/androidTest/java/to/bitkit/ui/sheets/NewTransactionSheetViewTest.kt
@@ -110,7 +110,7 @@ class NewTransactionSheetViewTest {
composeTestRule.onNodeWithTag("sent_buttons_row").assertDoesNotExist()
// Verify only OK button exists for received transactions
- composeTestRule.onNodeWithTag("ok_button").assertExists().performClick()
+ composeTestRule.onNodeWithTag("ReceivedTransactionButton").assertExists().performClick()
composeTestRule.waitForIdle()
assert(closeClicked)
}
diff --git a/app/src/main/java/to/bitkit/ext/Activities.kt b/app/src/main/java/to/bitkit/ext/Activities.kt
index e51c610c8..15338da9c 100644
--- a/app/src/main/java/to/bitkit/ext/Activities.kt
+++ b/app/src/main/java/to/bitkit/ext/Activities.kt
@@ -43,7 +43,21 @@ fun Activity.isFinished() = when (this) {
is Activity.Lightning -> v1.status != PaymentState.PENDING
}
+fun Activity.isSent() = when (this) {
+ is Activity.Lightning -> v1.txType == PaymentType.SENT
+ is Activity.Onchain -> v1.txType == PaymentType.SENT
+}
+
fun Activity.matchesPaymentId(paymentHashOrTxId: String): Boolean = when (this) {
is Activity.Lightning -> paymentHashOrTxId == v1.id
is Activity.Onchain -> paymentHashOrTxId == v1.txId
}
+
+fun Activity.isTransfer() = this is Activity.Onchain && this.v1.isTransfer
+
+fun Activity.Onchain.boostType() = when (this.v1.txType) {
+ PaymentType.SENT -> BoostType.RBF
+ PaymentType.RECEIVED -> BoostType.CPFP
+}
+
+enum class BoostType { RBF, CPFP }
diff --git a/app/src/main/java/to/bitkit/models/Suggestion.kt b/app/src/main/java/to/bitkit/models/Suggestion.kt
index 2d465c5f0..7786b4beb 100644
--- a/app/src/main/java/to/bitkit/models/Suggestion.kt
+++ b/app/src/main/java/to/bitkit/models/Suggestion.kt
@@ -18,7 +18,7 @@ enum class Suggestion(
color = Colors.Brand,
icon = R.drawable.b_emboss
),
- SPEND(
+ LIGHTNING(
title = R.string.cards__lightning__title,
description = R.string.cards__lightning__description,
color = Colors.Purple,
diff --git a/app/src/main/java/to/bitkit/ui/ContentView.kt b/app/src/main/java/to/bitkit/ui/ContentView.kt
index 34f31bcba..433940c34 100644
--- a/app/src/main/java/to/bitkit/ui/ContentView.kt
+++ b/app/src/main/java/to/bitkit/ui/ContentView.kt
@@ -649,6 +649,7 @@ private fun NavGraphBuilder.settings(
composableWithDefaultTransitions {
SettingsScreen(navController)
}
+ // TODO: display as sheet
composableWithDefaultTransitions {
QuickPayIntroScreen(
onBack = { navController.popBackStack() },
diff --git a/app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt b/app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt
index 867f114f5..a72559602 100644
--- a/app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -171,11 +172,13 @@ private fun NodeIdSection(
SectionHeader(stringResource(R.string.lightning__node_id))
Subtitle(
text = nodeId,
- modifier = Modifier.clickableAlpha(
- onClick = copyToClipboard(nodeId) {
- onCopy(nodeId)
- }
- )
+ modifier = Modifier
+ .clickableAlpha(
+ onClick = copyToClipboard(nodeId) {
+ onCopy(nodeId)
+ }
+ )
+ .testTag("LDKNodeID")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/AmountInput.kt b/app/src/main/java/to/bitkit/ui/components/AmountInput.kt
index 7ae9211e1..93aef3b0a 100644
--- a/app/src/main/java/to/bitkit/ui/components/AmountInput.kt
+++ b/app/src/main/java/to/bitkit/ui/components/AmountInput.kt
@@ -34,6 +34,7 @@ import to.bitkit.ui.utils.withAccent
@Composable
fun AmountInput(
+ modifier: Modifier = Modifier,
defaultValue: Long = 0,
primaryDisplay: PrimaryDisplay,
showConversion: Boolean = false,
@@ -191,7 +192,9 @@ fun AmountInput(
// Visible balance display
currency.convert(sats)?.let { converted ->
- Column(modifier = Modifier.clickableAlpha { currency.togglePrimaryDisplay() }) {
+ Column(
+ modifier = modifier.clickableAlpha { currency.togglePrimaryDisplay() }
+ ) {
if (showConversion) {
val captionText = if (primaryDisplay == PrimaryDisplay.BITCOIN) {
"${converted.symbol} ${converted.formatted}"
diff --git a/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt b/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt
index 543e9f999..a1dda3687 100644
--- a/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt
+++ b/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@@ -138,8 +139,9 @@ private fun PinPad(
Column(
horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.testTag("PinPad")
) {
- AppTopBar(titleText = " ", onBackClick = onBack)
+ AppTopBar(titleText = null, onBackClick = onBack)
Box(
contentAlignment = Alignment.BottomCenter,
modifier = Modifier.weight(1f)
@@ -161,7 +163,9 @@ private fun PinPad(
text = stringResource(R.string.security__pin_last_attempt),
color = Colors.Brand,
textAlign = TextAlign.Center,
- modifier = Modifier.padding(horizontal = 16.dp)
+ modifier = Modifier
+ .padding(horizontal = 16.dp)
+ .testTag("LastAttempt")
)
} else {
BodyS(
@@ -169,7 +173,9 @@ private fun PinPad(
.replace("{attemptsRemaining}", "$attemptsRemaining"),
color = Colors.Brand,
textAlign = TextAlign.Center,
- modifier = Modifier.clickableAlpha { onClickForgotPin() }
+ modifier = Modifier
+ .clickableAlpha { onClickForgotPin() }
+ .testTag("AttemptsRemaining")
)
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt
index 496c3048c..3c01d24ca 100644
--- a/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt
+++ b/app/src/main/java/to/bitkit/ui/components/BalanceHeaderView.kt
@@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
@@ -15,6 +14,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalInspectionMode
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -38,10 +38,12 @@ import to.bitkit.ui.theme.Colors
fun BalanceHeaderView(
sats: Long,
modifier: Modifier = Modifier,
+ onClick: (() -> Unit)? = null,
prefix: String? = null,
showBitcoinSymbol: Boolean = true,
- forceShowBalance: Boolean = false,
+ useSwipeToHide: Boolean = true,
showEyeIcon: Boolean = false,
+ testTag: String = "",
) {
val isPreview = LocalInspectionMode.current
@@ -59,6 +61,7 @@ fun BalanceHeaderView(
showEyeIcon = showEyeIcon,
onClick = {},
onToggleHideBalance = {},
+ testTag = testTag,
)
return
}
@@ -70,7 +73,8 @@ fun BalanceHeaderView(
val isSwipeToHideEnabled by settings.enableSwipeToHideBalance.collectAsStateWithLifecycle()
val hideBalance by settings.hideBalance.collectAsStateWithLifecycle()
- val shouldHideBalance = hideBalance && !forceShowBalance
+ val shouldHideBalance = useSwipeToHide && hideBalance
+ val allowSwipeToHide = useSwipeToHide && isSwipeToHideEnabled
converted?.let { converted ->
val btcComponents = converted.bitcoinDisplay(displayUnit)
@@ -80,15 +84,18 @@ fun BalanceHeaderView(
modifier = modifier,
smallRowSymbol = converted.symbol,
smallRowText = converted.formatted,
+ smallRowModifier = Modifier.testTag("$testTag-secondary"),
largeRowPrefix = prefix,
largeRowText = btcComponents.value,
largeRowSymbol = btcComponents.symbol,
+ largeRowModifier = Modifier.testTag("$testTag-primary"),
showSymbol = showBitcoinSymbol,
hideBalance = shouldHideBalance,
- isSwipeToHideEnabled = isSwipeToHideEnabled,
+ isSwipeToHideEnabled = allowSwipeToHide,
showEyeIcon = showEyeIcon,
- onClick = { currency.togglePrimaryDisplay() },
+ onClick = onClick ?: { currency.togglePrimaryDisplay() },
onToggleHideBalance = { settings.setHideBalance(!hideBalance) },
+ testTag = testTag,
)
} else {
BalanceHeader(
@@ -100,10 +107,11 @@ fun BalanceHeaderView(
largeRowSymbol = converted.symbol,
showSymbol = true,
hideBalance = shouldHideBalance,
- isSwipeToHideEnabled = isSwipeToHideEnabled,
+ isSwipeToHideEnabled = allowSwipeToHide,
showEyeIcon = showEyeIcon,
onClick = { currency.togglePrimaryDisplay() },
onToggleHideBalance = { settings.setHideBalance(!hideBalance) },
+ testTag = testTag,
)
}
}
@@ -114,15 +122,18 @@ fun BalanceHeader(
modifier: Modifier = Modifier,
smallRowSymbol: String? = null,
smallRowText: String,
+ smallRowModifier: Modifier = Modifier,
largeRowPrefix: String? = null,
largeRowText: String,
largeRowSymbol: String,
+ largeRowModifier: Modifier = Modifier,
showSymbol: Boolean,
hideBalance: Boolean = false,
isSwipeToHideEnabled: Boolean = false,
showEyeIcon: Boolean = false,
onClick: () -> Unit,
onToggleHideBalance: () -> Unit = {},
+ testTag: String? = null,
) {
Column(
verticalArrangement = Arrangement.Center,
@@ -133,14 +144,16 @@ fun BalanceHeader(
onSwipe = onToggleHideBalance,
)
.clickableAlpha { onClick() }
+ .then(testTag?.let { Modifier.testTag(it) } ?: Modifier)
) {
SmallRow(
symbol = smallRowSymbol,
text = smallRowText,
- hideBalance = hideBalance
+ hideBalance = hideBalance,
+ modifier = smallRowModifier,
)
- Spacer(modifier = Modifier.height(12.dp))
+ VerticalSpacer(12.dp)
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -150,7 +163,8 @@ fun BalanceHeader(
text = largeRowText,
symbol = largeRowSymbol,
showSymbol = showSymbol,
- hideBalance = hideBalance
+ hideBalance = hideBalance,
+ modifier = largeRowModifier,
)
if (showEyeIcon) {
@@ -169,6 +183,7 @@ fun BalanceHeader(
modifier = Modifier
.size(24.dp)
.clickableAlpha { onToggleHideBalance() }
+ .testTag("ShowBalance")
)
}
}
@@ -183,55 +198,72 @@ fun LargeRow(
text: String,
symbol: String,
showSymbol: Boolean,
- hideBalance: Boolean = false
+ modifier: Modifier = Modifier,
+ hideBalance: Boolean = false,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
+ modifier = modifier,
) {
if (!hideBalance && prefix != null) {
Display(
text = prefix,
color = Colors.White64,
- modifier = Modifier.padding(end = 8.dp)
+ modifier = Modifier
+ .padding(end = 8.dp)
+ .testTag("MoneySign")
)
}
if (showSymbol) {
Display(
text = symbol,
color = Colors.White64,
- modifier = Modifier.padding(end = 8.dp)
+ modifier = Modifier
+ .padding(end = 8.dp)
+ .testTag("MoneyFiatSymbol")
)
}
AnimatedContent(
targetState = hideBalance,
transitionSpec = { BalanceAnimations.mainBalanceTransition },
- label = "largeRowTextAnimation"
+ label = "largeRowTextAnimation",
) { isHidden ->
- Display(text = if (isHidden) UiConstants.HIDE_BALANCE_LONG else text)
+ Display(
+ text = if (isHidden) UiConstants.HIDE_BALANCE_LONG else text,
+ modifier = Modifier.testTag("MoneyText")
+ )
}
}
}
@Composable
-private fun SmallRow(symbol: String?, text: String, hideBalance: Boolean = false) {
+private fun SmallRow(
+ symbol: String?,
+ text: String,
+ modifier: Modifier = Modifier,
+ hideBalance: Boolean = false,
+) {
Row(
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier,
) {
if (symbol != null) {
Caption13Up(
text = symbol,
color = Colors.White64,
+ modifier = Modifier.testTag("MoneyFiatSymbol")
)
}
AnimatedContent(
targetState = hideBalance,
transitionSpec = { BalanceAnimations.secondaryBalanceTransition },
- label = "smallRowTextAnimation"
+ label = "smallRowTextAnimation",
) { isHidden ->
Caption13Up(
text = if (isHidden) UiConstants.HIDE_BALANCE_SHORT else text,
color = Colors.White64,
+ modifier = Modifier.testTag("MoneyText")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/BiometricsView.kt b/app/src/main/java/to/bitkit/ui/components/BiometricsView.kt
index 9603c36c0..8211643d4 100644
--- a/app/src/main/java/to/bitkit/ui/components/BiometricsView.kt
+++ b/app/src/main/java/to/bitkit/ui/components/BiometricsView.kt
@@ -15,6 +15,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -47,6 +48,7 @@ fun BiometricsView(
shouldShowPrompt = true
}
}
+ .testTag("Biometrics")
) {
if (shouldShowPrompt) {
BiometricPrompt(
diff --git a/app/src/main/java/to/bitkit/ui/components/DrawerMenu.kt b/app/src/main/java/to/bitkit/ui/components/DrawerMenu.kt
index 8d03b73bc..048df91da 100644
--- a/app/src/main/java/to/bitkit/ui/components/DrawerMenu.kt
+++ b/app/src/main/java/to/bitkit/ui/components/DrawerMenu.kt
@@ -29,6 +29,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
@@ -141,6 +142,7 @@ private fun Menu(
onClick = {
scope.launch { drawerState.close() }
},
+ modifier = Modifier.testTag("DrawerWallet")
)
DrawerItem(
@@ -150,18 +152,21 @@ private fun Menu(
walletNavController.navigate(HomeRoutes.AllActivity)
scope.launch { drawerState.close() }
},
+ modifier = Modifier.testTag("DrawerActivity")
)
DrawerItem(
label = stringResource(R.string.wallet__drawer__contacts),
iconRes = R.drawable.ic_users,
onClick = null, // TODO IMPLEMENT CONTACTS
+ modifier = Modifier.testTag("DrawerContacts")
)
DrawerItem(
label = stringResource(R.string.wallet__drawer__profile),
iconRes = R.drawable.ic_user_square,
onClick = null, // TODO IMPLEMENT PROFILE
+ modifier = Modifier.testTag("DrawerProfile")
)
DrawerItem(
@@ -170,7 +175,8 @@ private fun Menu(
onClick = {
onClickAddWidget()
scope.launch { drawerState.close() }
- }
+ },
+ modifier = Modifier.testTag("DrawerWidgets")
)
DrawerItem(
@@ -179,7 +185,8 @@ private fun Menu(
onClick = {
onClickShop()
scope.launch { drawerState.close() }
- }
+ },
+ modifier = Modifier.testTag("DrawerShop")
)
DrawerItem(
@@ -189,6 +196,7 @@ private fun Menu(
rootNavController.navigateToSettings()
scope.launch { drawerState.close() }
},
+ modifier = Modifier.testTag("DrawerSettings")
)
FillHeight()
@@ -206,7 +214,7 @@ private fun Menu(
showText = true,
showReady = true,
color = Colors.Black,
- modifier = Modifier.padding(vertical = 16.dp)
+ modifier = Modifier.padding(vertical = 16.dp).testTag("DrawerAppStatus")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/EmptyWalletView.kt b/app/src/main/java/to/bitkit/ui/components/EmptyWalletView.kt
index 96567784b..13877de92 100644
--- a/app/src/main/java/to/bitkit/ui/components/EmptyWalletView.kt
+++ b/app/src/main/java/to/bitkit/ui/components/EmptyWalletView.kt
@@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@@ -71,6 +72,7 @@ fun EmptyStateView(
modifier = Modifier
.size(40.dp)
.align(Alignment.TopEnd)
+ .testTag("WalletOnboardingClose")
) {
Icon(
imageVector = Icons.Default.Close,
diff --git a/app/src/main/java/to/bitkit/ui/components/InfoScreenContent.kt b/app/src/main/java/to/bitkit/ui/components/InfoScreenContent.kt
index 639bf4d91..9aaf4d03e 100644
--- a/app/src/main/java/to/bitkit/ui/components/InfoScreenContent.kt
+++ b/app/src/main/java/to/bitkit/ui/components/InfoScreenContent.kt
@@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@@ -37,6 +38,7 @@ fun InfoScreenContent(
buttonText: String,
onButtonClick: () -> Unit,
onCloseClick: () -> Unit,
+ testTag: String,
) {
ScreenColumn {
AppTopBar(
@@ -52,6 +54,7 @@ fun InfoScreenContent(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
+ .testTag(testTag)
) {
Spacer(modifier = Modifier.height(16.dp))
Display(text = title)
@@ -79,6 +82,7 @@ fun InfoScreenContent(
PrimaryButton(
text = buttonText,
onClick = onButtonClick,
+ modifier = Modifier.testTag("$testTag-button")
)
Spacer(modifier = Modifier.height(16.dp))
}
@@ -97,6 +101,7 @@ private fun Preview() {
buttonText = stringResource(R.string.common__ok),
onButtonClick = {},
onCloseClick = {},
+ testTag = "",
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/Keyboard.kt b/app/src/main/java/to/bitkit/ui/components/Keyboard.kt
index b473d6d24..3ae652c12 100644
--- a/app/src/main/java/to/bitkit/ui/components/Keyboard.kt
+++ b/app/src/main/java/to/bitkit/ui/components/Keyboard.kt
@@ -80,7 +80,14 @@ fun Keyboard(
item { KeyTextButton(text = "7", onClick = onClick, buttonHeight = buttonHeight) }
item { KeyTextButton(text = "8", onClick = onClick, buttonHeight = buttonHeight) }
item { KeyTextButton(text = "9", onClick = onClick, buttonHeight = buttonHeight) }
- item { KeyTextButton(text = if (isDecimal) "." else "000", onClick = onClick, buttonHeight = buttonHeight) }
+ item {
+ KeyTextButton(
+ text = if (isDecimal) "." else "000",
+ onClick = onClick,
+ buttonHeight = buttonHeight,
+ testTag = if (isDecimal) "NDecimal" else "N000",
+ )
+ }
item { KeyTextButton(text = "0", onClick = onClick, buttonHeight = buttonHeight) }
item {
KeyIconButton(
@@ -88,7 +95,7 @@ fun Keyboard(
contentDescription = stringResource(R.string.common__delete),
onClick = onClickBackspace,
buttonHeight = buttonHeight,
- modifier = Modifier.testTag("KeyboardButton_backspace"),
+ modifier = Modifier.testTag("NRemove"),
)
}
}
@@ -100,8 +107,8 @@ fun KeyIconButton(
@DrawableRes icon: Int,
contentDescription: String?,
onClick: () -> Unit,
- buttonHeight: Dp = idealButtonHeight,
modifier: Modifier = Modifier,
+ buttonHeight: Dp = idealButtonHeight,
) {
KeyButtonBox(
onClick = onClick,
@@ -121,11 +128,12 @@ fun KeyTextButton(
onClick: (String) -> Unit,
buttonHeight: Dp = idealButtonHeight,
modifier: Modifier = Modifier,
+ testTag: String = "N$text",
) {
KeyButtonBox(
onClick = { onClick(text) },
buttonHeight = buttonHeight,
- modifier = modifier.testTag("KeyboardButton_$text"),
+ modifier = modifier.testTag(testTag)
) {
Text(
text = text,
diff --git a/app/src/main/java/to/bitkit/ui/components/LightningChannel.kt b/app/src/main/java/to/bitkit/ui/components/LightningChannel.kt
index a296e7570..80770af4e 100644
--- a/app/src/main/java/to/bitkit/ui/components/LightningChannel.kt
+++ b/app/src/main/java/to/bitkit/ui/components/LightningChannel.kt
@@ -26,9 +26,9 @@ fun LightningChannel(
capacity: Long,
localBalance: Long,
remoteBalance: Long,
+ modifier: Modifier = Modifier,
status: ChannelStatusUi = ChannelStatusUi.PENDING,
showLabels: Boolean = false,
- modifier: Modifier = Modifier,
) {
val spendingColor = if (status == ChannelStatusUi.CLOSED) Colors.Gray5 else Colors.Purple50
val spendingAvailableColor = if (status == ChannelStatusUi.CLOSED) Colors.Gray3 else Colors.Purple
diff --git a/app/src/main/java/to/bitkit/ui/components/Money.kt b/app/src/main/java/to/bitkit/ui/components/Money.kt
index 52ab194b5..ce2b0cd04 100644
--- a/app/src/main/java/to/bitkit/ui/components/Money.kt
+++ b/app/src/main/java/to/bitkit/ui/components/Money.kt
@@ -6,6 +6,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
+import androidx.compose.ui.platform.testTag
import to.bitkit.models.BITCOIN_SYMBOL
import to.bitkit.models.PrimaryDisplay
import to.bitkit.models.formatToModernDisplay
@@ -24,7 +25,9 @@ fun MoneyDisplay(
rememberMoneyText(sats)?.let { text ->
Display(
text = text.withAccent(accentColor = Colors.White64),
- modifier = Modifier.clickableAlpha(onClick = onClick)
+ modifier = Modifier
+ .clickableAlpha(onClick = onClick)
+ .testTag("MoneyText")
)
}
}
@@ -36,12 +39,13 @@ fun MoneySSB(
unit: PrimaryDisplay = LocalCurrencies.current.primaryDisplay,
color: Color = MaterialTheme.colorScheme.primary,
accent: Color = Colors.White64,
+ showSymbol: Boolean = false,
) {
- rememberMoneyText(sats = sats, unit = unit)?.let { text ->
+ rememberMoneyText(sats = sats, unit = unit, showSymbol = showSymbol)?.let { text ->
BodySSB(
text = text.withAccent(accentColor = accent),
color = color,
- modifier = modifier,
+ modifier = modifier.testTag("MoneyText")
)
}
}
@@ -58,7 +62,7 @@ fun MoneyMSB(
BodyMSB(
text = text.withAccent(accentColor = accent),
color = color,
- modifier = modifier,
+ modifier = modifier.testTag("MoneyText")
)
}
}
@@ -96,7 +100,7 @@ fun MoneyCaptionB(
CaptionB(
text = text.withAccent(accentColor = symbolColor),
color = color,
- modifier = modifier,
+ modifier = modifier.testTag("MoneyText")
)
}
}
@@ -107,23 +111,33 @@ fun rememberMoneyText(
reversed: Boolean = false,
currencies: CurrencyUiState = LocalCurrencies.current,
unit: PrimaryDisplay = if (reversed) currencies.primaryDisplay.not() else currencies.primaryDisplay,
+ showSymbol: Boolean = unit == PrimaryDisplay.FIAT,
): String? {
val isPreview = LocalInspectionMode.current
if (isPreview) {
val symbol = if (unit == PrimaryDisplay.BITCOIN) BITCOIN_SYMBOL else "$"
- return "$symbol ${sats.formatToModernDisplay()}"
+ return buildString {
+ if (showSymbol) append("$symbol ")
+ append(sats.formatToModernDisplay())
+ }
}
val currency = currencyViewModel ?: return null
- return remember(currencies, sats, reversed) {
+ return remember(currencies, sats, unit) {
val converted = currency.convert(sats) ?: return@remember null
if (unit == PrimaryDisplay.BITCOIN) {
val btcComponents = converted.bitcoinDisplay(currencies.displayUnit)
- "${btcComponents.symbol} ${btcComponents.value}"
+ buildString {
+ if (showSymbol) append("${btcComponents.symbol} ")
+ append(btcComponents.value)
+ }
} else {
- "${converted.symbol} ${converted.formatted}"
+ buildString {
+ if (showSymbol) append("${converted.symbol} ")
+ append(converted.formatted)
+ }
}
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/NumberPadSimple.kt b/app/src/main/java/to/bitkit/ui/components/NumberPadSimple.kt
index b8cef207d..4ac7bacf6 100644
--- a/app/src/main/java/to/bitkit/ui/components/NumberPadSimple.kt
+++ b/app/src/main/java/to/bitkit/ui/components/NumberPadSimple.kt
@@ -68,7 +68,7 @@ fun NumberPadSimple(
onClick = { onPress(KEY_DELETE) },
modifier = Modifier
.weight(1f)
- .testTag("KeyboardButton_backspace")
+ .testTag("NRemove")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/PagerWithIndicator.kt b/app/src/main/java/to/bitkit/ui/components/PagerWithIndicator.kt
deleted file mode 100644
index 397bd8bdb..000000000
--- a/app/src/main/java/to/bitkit/ui/components/PagerWithIndicator.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package to.bitkit.ui.components
-
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.pager.HorizontalPager
-import androidx.compose.foundation.pager.PagerScope
-import androidx.compose.foundation.pager.PagerState
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-import com.google.accompanist.pager.HorizontalPagerIndicator
-import to.bitkit.ui.theme.Colors
-
-@Composable
-fun PagerWithIndicator(
- pagerState: PagerState,
- modifier: Modifier = Modifier,
- pageContent: @Composable (PagerScope.(page: Int) -> Unit),
-) {
- Column(
- modifier = modifier.fillMaxSize(),
- ) {
- HorizontalPager(
- state = pagerState,
- pageContent = pageContent,
- pageSpacing = 20.dp,
- verticalAlignment = Alignment.Top,
- modifier = Modifier.weight(1f)
- )
- @Suppress("DEPRECATION")
- HorizontalPagerIndicator(
- pagerState = pagerState,
- pageCount = pagerState.pageCount,
- indicatorWidth = 8.dp,
- spacing = 8.dp,
- activeColor = Colors.White,
- inactiveColor = Colors.White32,
- modifier = Modifier
- .align(Alignment.CenterHorizontally)
- )
- }
-}
diff --git a/app/src/main/java/to/bitkit/ui/components/QrCodeImage.kt b/app/src/main/java/to/bitkit/ui/components/QrCodeImage.kt
index 522d25a3a..133cb8e96 100644
--- a/app/src/main/java/to/bitkit/ui/components/QrCodeImage.kt
+++ b/app/src/main/java/to/bitkit/ui/components/QrCodeImage.kt
@@ -26,11 +26,11 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@@ -42,6 +42,7 @@ import com.google.zxing.qrcode.QRCodeWriter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import to.bitkit.R
+import to.bitkit.ext.setClipboardText
import to.bitkit.ui.theme.AppShapes
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
@@ -54,9 +55,10 @@ fun QrCodeImage(
logoPainter: Painter? = null,
tipMessage: String = "",
size: Dp = LocalConfiguration.current.screenWidthDp.dp,
- onBitmapGenerated: (Bitmap?) -> Unit = {}
+ onBitmapGenerated: (Bitmap?) -> Unit = {},
+ testTag: String? = null,
) {
- val clipboard = LocalClipboardManager.current
+ val context = LocalContext.current
val tooltipState = rememberTooltipState()
val coroutineScope = rememberCoroutineScope()
@@ -79,16 +81,14 @@ fun QrCodeImage(
painter = remember(bitmap) { BitmapPainter(bitmap.asImageBitmap()) },
contentDescription = null,
contentScale = ContentScale.Inside,
- modifier = if (tipMessage.isNotBlank()) {
- Modifier.clickable {
+ modifier = Modifier
+ .clickable(enabled = tipMessage.isNotBlank()) {
coroutineScope.launch {
- clipboard.setText(AnnotatedString(content))
+ context.setClipboardText(content)
tooltipState.show()
}
}
- } else {
- Modifier
- }
+ .then(testTag?.let { Modifier.testTag(it) } ?: Modifier)
)
}
diff --git a/app/src/main/java/to/bitkit/ui/components/SuggestionCard.kt b/app/src/main/java/to/bitkit/ui/components/SuggestionCard.kt
index fa4506ea2..77267a181 100644
--- a/app/src/main/java/to/bitkit/ui/components/SuggestionCard.kt
+++ b/app/src/main/java/to/bitkit/ui/components/SuggestionCard.kt
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@@ -68,7 +69,9 @@ fun SuggestionCard(
onClose?.let {
IconButton(
onClick = it,
- modifier = Modifier.size(16.dp)
+ modifier = Modifier
+ .size(16.dp)
+ .testTag("SuggestionDismiss")
) {
Icon(
painter = painterResource(R.drawable.ic_x),
diff --git a/app/src/main/java/to/bitkit/ui/components/SwipeToConfirm.kt b/app/src/main/java/to/bitkit/ui/components/SwipeToConfirm.kt
index 54b9b17a5..1a04fb227 100644
--- a/app/src/main/java/to/bitkit/ui/components/SwipeToConfirm.kt
+++ b/app/src/main/java/to/bitkit/ui/components/SwipeToConfirm.kt
@@ -8,14 +8,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
@@ -40,6 +38,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@@ -49,6 +48,7 @@ import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import to.bitkit.R
+import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import kotlin.math.roundToInt
@@ -154,6 +154,7 @@ fun SwipeToConfirm(
)
}
}
+ .testTag("GRAB")
) {
Box(
modifier = Modifier
@@ -212,20 +213,14 @@ fun SwipeToConfirm(
@Preview(showSystemUi = true)
@Composable
-private fun SwipeToConfirmPreview() {
+private fun Preview() {
var isLoading by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
AppThemeSurface {
- Column(
+ ScreenColumn(
verticalArrangement = Arrangement.Bottom,
- modifier = Modifier
- .fillMaxSize()
- .padding(horizontal = 16.dp)
- .systemBarsPadding()
+ modifier = Modifier.padding(horizontal = 16.dp)
) {
- Box(
- modifier = Modifier.fillMaxSize()
- )
SwipeToConfirm(
text = stringResource(R.string.wallet__send_swipe),
color = Colors.Green,
diff --git a/app/src/main/java/to/bitkit/ui/components/TabBar.kt b/app/src/main/java/to/bitkit/ui/components/TabBar.kt
index 1ef9ebb45..088fc06ae 100644
--- a/app/src/main/java/to/bitkit/ui/components/TabBar.kt
+++ b/app/src/main/java/to/bitkit/ui/components/TabBar.kt
@@ -25,6 +25,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -51,11 +52,11 @@ private val buttonRightShape = RoundedCornerShape(topEndPercent = 50, bottomEndP
@OptIn(ExperimentalHazeMaterialsApi::class)
@Composable
fun TabBar(
- hazeState: HazeState,
- onSendClick: () -> Unit,
- onReceiveClick: () -> Unit,
- onScanClick: () -> Unit,
modifier: Modifier = Modifier,
+ hazeState: HazeState = rememberHazeState(),
+ onSendClick: () -> Unit = {},
+ onReceiveClick: () -> Unit = {},
+ onScanClick: () -> Unit = {},
) {
Box(
contentAlignment = Alignment.Center,
@@ -93,6 +94,7 @@ fun TabBar(
)
)
.clickable { onSendClick() }
+ .testTag("Send")
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
@@ -119,6 +121,7 @@ fun TabBar(
)
.background(buttonBgOverlay)
.clickable { onReceiveClick() }
+ .testTag("Receive")
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
@@ -151,6 +154,7 @@ fun TabBar(
)
.clickable { onScanClick() }
.padding(2.dp)
+ .testTag("Scan")
)
// Inner Content
Box(
diff --git a/app/src/main/java/to/bitkit/ui/components/Tag.kt b/app/src/main/java/to/bitkit/ui/components/Tag.kt
index cfe42dac5..50c12db3a 100644
--- a/app/src/main/java/to/bitkit/ui/components/Tag.kt
+++ b/app/src/main/java/to/bitkit/ui/components/Tag.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -46,6 +47,7 @@ fun TagButton(
BodySSB(
text = text,
color = textColor,
+ modifier = Modifier.testTag("Tag-$text")
)
if (displayIconClose) {
@@ -53,7 +55,9 @@ fun TagButton(
painter = icon,
contentDescription = null,
tint = Colors.White64,
- modifier = Modifier.size(16.dp)
+ modifier = Modifier
+ .size(16.dp)
+ .testTag("Tag-$text-delete")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/Text.kt b/app/src/main/java/to/bitkit/ui/components/Text.kt
index 7342cf278..a82ebee59 100644
--- a/app/src/main/java/to/bitkit/ui/components/Text.kt
+++ b/app/src/main/java/to/bitkit/ui/components/Text.kt
@@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@@ -15,7 +14,6 @@ import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import to.bitkit.ui.theme.AppTextStyles
import to.bitkit.ui.theme.Colors
-import to.bitkit.ui.theme.InterFontFamily
@Composable
fun Display(
@@ -23,17 +21,13 @@ fun Display(
modifier: Modifier = Modifier,
fontWeight: FontWeight = FontWeight.Black,
fontSize: TextUnit = 44.sp,
- lineHeight: TextUnit = 44.sp,
color: Color = MaterialTheme.colorScheme.primary,
) {
Text(
text = text.uppercase(),
- style = TextStyle(
+ style = AppTextStyles.Display.merge(
fontWeight = fontWeight,
fontSize = fontSize,
- lineHeight = lineHeight,
- letterSpacing = (-1).sp,
- fontFamily = InterFontFamily,
color = color,
),
modifier = modifier,
@@ -44,19 +38,11 @@ fun Display(
fun Display(
text: AnnotatedString,
modifier: Modifier = Modifier,
- fontWeight: FontWeight = FontWeight.Black,
- fontSize: TextUnit = 44.sp,
- lineHeight: TextUnit = 44.sp,
color: Color = MaterialTheme.colorScheme.primary,
) {
Text(
text = text.toUpperCase(),
- style = TextStyle(
- fontWeight = fontWeight,
- fontSize = fontSize,
- lineHeight = lineHeight,
- letterSpacing = (-1).sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.Display.merge(
color = color,
),
modifier = modifier,
@@ -67,17 +53,11 @@ fun Display(
fun Headline(
text: AnnotatedString,
modifier: Modifier = Modifier,
- lineHeight: TextUnit = 30.sp,
color: Color = MaterialTheme.colorScheme.primary,
) {
Text(
text = text.toUpperCase(),
- style = TextStyle(
- fontWeight = FontWeight.Black,
- fontSize = 30.sp,
- lineHeight = lineHeight,
- letterSpacing = (-1).sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.Headline.merge(
color = color,
),
modifier = modifier,
@@ -88,17 +68,14 @@ fun Headline(
fun Headline20(
text: AnnotatedString,
modifier: Modifier = Modifier,
- lineHeight: TextUnit = 20.sp,
- color: Color = Colors.White,
+ color: Color = MaterialTheme.colorScheme.primary,
) {
Text(
text = text.toUpperCase(),
- style = TextStyle(
- fontWeight = FontWeight.Black,
+ style = AppTextStyles.Headline.merge(
fontSize = 20.sp,
- lineHeight = lineHeight,
+ lineHeight = 20.sp,
letterSpacing = (-.5).sp,
- fontFamily = InterFontFamily,
color = color,
),
modifier = modifier,
@@ -173,12 +150,7 @@ fun BodyM(
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.Normal,
- fontSize = 17.sp,
- lineHeight = 22.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.BodyM.merge(
color = color,
textAlign = textAlign,
),
@@ -239,12 +211,7 @@ fun BodyMB(
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.Bold,
- fontSize = 17.sp,
- lineHeight = 22.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.BodyMB.merge(
color = color,
textAlign = textAlign,
),
@@ -327,17 +294,13 @@ fun BodySB(
text: String,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colorScheme.primary,
+ textAlign: TextAlign = TextAlign.Start,
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.Bold,
- fontSize = 15.sp,
- lineHeight = 20.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.BodySB.merge(
color = color,
- textAlign = TextAlign.Start,
+ textAlign = textAlign,
),
modifier = modifier,
)
@@ -348,17 +311,13 @@ fun Text13Up(
text: String,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colorScheme.primary,
+ textAlign: TextAlign = TextAlign.Start,
) {
Text(
text = text.uppercase(),
- style = TextStyle(
- fontWeight = FontWeight.Medium,
- fontSize = 13.sp,
- lineHeight = 18.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.CaptionM.merge(
color = color,
- textAlign = TextAlign.Start,
+ textAlign = textAlign,
),
modifier = modifier,
)
@@ -375,12 +334,7 @@ fun Caption(
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.Normal,
- fontSize = 13.sp,
- lineHeight = 18.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.Caption.merge(
color = color,
textAlign = textAlign,
),
@@ -420,12 +374,7 @@ fun CaptionB(
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.SemiBold,
- fontSize = 13.sp,
- lineHeight = 18.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.CaptionB.merge(
color = color,
textAlign = textAlign,
),
@@ -444,12 +393,7 @@ fun Caption13Up(
) {
Text(
text = text.uppercase(),
- style = TextStyle(
- fontWeight = FontWeight.Medium,
- fontSize = 13.sp,
- lineHeight = 18.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.CaptionM.merge(
color = color,
textAlign = textAlign,
),
@@ -468,12 +412,7 @@ fun Footnote(
) {
Text(
text = text,
- style = TextStyle(
- fontWeight = FontWeight.Medium,
- fontSize = 12.sp,
- lineHeight = 16.sp,
- letterSpacing = 0.4.sp,
- fontFamily = InterFontFamily,
+ style = AppTextStyles.FootnoteM.merge(
color = color,
textAlign = textAlign,
),
diff --git a/app/src/main/java/to/bitkit/ui/components/WalletBalanceView.kt b/app/src/main/java/to/bitkit/ui/components/WalletBalanceView.kt
index ff503ed32..dafbf7bcf 100644
--- a/app/src/main/java/to/bitkit/ui/components/WalletBalanceView.kt
+++ b/app/src/main/java/to/bitkit/ui/components/WalletBalanceView.kt
@@ -16,10 +16,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import to.bitkit.models.BITCOIN_SYMBOL
+import to.bitkit.models.BitcoinDisplayUnit
import to.bitkit.models.ConvertedAmount
import to.bitkit.models.PrimaryDisplay
+import to.bitkit.models.formatToModernDisplay
import to.bitkit.ui.LocalCurrencies
import to.bitkit.ui.currencyViewModel
import to.bitkit.ui.settingsViewModel
@@ -34,6 +38,26 @@ fun RowScope.WalletBalanceView(
icon: Painter,
modifier: Modifier,
) {
+ val isPreview = LocalInspectionMode.current
+ if (isPreview) {
+ Content(
+ modifier = modifier,
+ title = title,
+ converted = ConvertedAmount(
+ value = sats.toBigDecimal(),
+ formatted = sats.formatToModernDisplay(),
+ symbol = BITCOIN_SYMBOL,
+ currency = "USD",
+ flag = "",
+ sats = sats,
+ ),
+ icon = icon,
+ primaryDisplay = PrimaryDisplay.BITCOIN,
+ displayUnit = BitcoinDisplayUnit.MODERN,
+ hideBalance = false,
+ )
+ }
+
val settings = settingsViewModel ?: return
val currency = currencyViewModel ?: return
val (_, _, _, _, _, displayUnit, primaryDisplay) = LocalCurrencies.current
@@ -41,6 +65,27 @@ fun RowScope.WalletBalanceView(
val hideBalance by settings.hideBalance.collectAsStateWithLifecycle()
+ Content(
+ modifier = modifier,
+ title = title,
+ converted = converted,
+ icon = icon,
+ primaryDisplay = primaryDisplay,
+ displayUnit = displayUnit,
+ hideBalance = hideBalance,
+ )
+}
+
+@Composable
+private fun RowScope.Content(
+ modifier: Modifier,
+ title: String,
+ converted: ConvertedAmount?,
+ icon: Painter,
+ primaryDisplay: PrimaryDisplay,
+ displayUnit: BitcoinDisplayUnit,
+ hideBalance: Boolean,
+) {
Column(
modifier = Modifier
.weight(1f)
diff --git a/app/src/main/java/to/bitkit/ui/components/settings/SectionHeader.kt b/app/src/main/java/to/bitkit/ui/components/settings/SectionHeader.kt
index 0d6ef7e67..3042f682f 100644
--- a/app/src/main/java/to/bitkit/ui/components/settings/SectionHeader.kt
+++ b/app/src/main/java/to/bitkit/ui/components/settings/SectionHeader.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import to.bitkit.ui.components.Caption13Up
@@ -17,6 +18,7 @@ import to.bitkit.ui.theme.Colors
fun SectionHeader(
title: String,
modifier: Modifier = Modifier,
+ color: Color = Colors.White64,
) {
Column(
verticalArrangement = Arrangement.Center,
@@ -25,7 +27,7 @@ fun SectionHeader(
.padding(top = 16.dp)
.height(50.dp)
) {
- Caption13Up(text = title, color = Colors.White64)
+ Caption13Up(text = title, color = color)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/components/settings/SettingsButtonRow.kt b/app/src/main/java/to/bitkit/ui/components/settings/SettingsButtonRow.kt
index ed594e14c..ae6cbd5d7 100644
--- a/app/src/main/java/to/bitkit/ui/components/settings/SettingsButtonRow.kt
+++ b/app/src/main/java/to/bitkit/ui/components/settings/SettingsButtonRow.kt
@@ -19,6 +19,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -123,7 +124,7 @@ fun SettingsButtonRow(
}
is SettingsButtonValue.StringValue -> {
- BodyM(text = value.value)
+ BodyM(text = value.value, modifier = Modifier.testTag("Value"))
Spacer(modifier = Modifier.width(8.dp))
Icon(
painter = painterResource(R.drawable.ic_chevron_right),
diff --git a/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletWithPassphraseScreen.kt b/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletWithPassphraseScreen.kt
index 75faf4ff9..cfcc01de3 100644
--- a/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletWithPassphraseScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/onboarding/CreateWalletWithPassphraseScreen.kt
@@ -10,20 +10,12 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
-import androidx.compose.material3.TopAppBar
-import androidx.compose.material3.TopAppBarDefaults.MediumAppBarCollapsedHeight
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -44,13 +36,15 @@ import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.HighlightLabel
import to.bitkit.ui.components.PrimaryButton
+import to.bitkit.ui.components.TopBarSpacer
import to.bitkit.ui.components.mainRectHeight
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.theme.AppTextFieldDefaults
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
+import to.bitkit.ui.theme.TopBarHeight
import to.bitkit.ui.utils.withAccent
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateWalletWithPassphraseScreen(
onBackClick: () -> Unit,
@@ -62,27 +56,18 @@ fun CreateWalletWithPassphraseScreen(
modifier = Modifier.fillMaxSize(),
) {
Row(
- modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.Bottom
+ verticalAlignment = Alignment.Bottom,
+ modifier = Modifier.fillMaxWidth()
) {
- TopAppBar(
- title = {},
- navigationIcon = {
- IconButton(onClick = onBackClick) {
- Icon(
- imageVector = Icons.AutoMirrored.Default.ArrowBack,
- contentDescription = stringResource(R.string.common__back),
- modifier = Modifier.size(24.dp)
- )
- }
- },
+ AppTopBar(
+ titleText = null,
+ onBackClick = onBackClick,
modifier = Modifier.weight(1f)
)
HighlightLabel(
stringResource(R.string.onboarding__advanced).uppercase(),
- Modifier
- .padding(top = MediumAppBarCollapsedHeight / 2 - (mainRectHeight / 2))
+ Modifier.padding(top = TopBarHeight / 2 - (mainRectHeight / 2))
)
}
Column(
@@ -93,7 +78,7 @@ fun CreateWalletWithPassphraseScreen(
.imePadding()
.verticalScroll(rememberScrollState())
) {
- Spacer(modifier = Modifier.height(MediumAppBarCollapsedHeight))
+ TopBarSpacer()
Image(
painter = painterResource(id = R.drawable.padlock2),
contentDescription = null,
@@ -139,7 +124,7 @@ fun CreateWalletWithPassphraseScreen(
@Preview(showSystemUi = true)
@Composable
-private fun CreateWalletWithPassphraseScreenPreview() {
+private fun Preview() {
AppThemeSurface {
CreateWalletWithPassphraseScreen(
onBackClick = {},
diff --git a/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt b/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt
index 4551e122c..357b6be4a 100644
--- a/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/onboarding/OnboardingSlidesScreen.kt
@@ -21,10 +21,8 @@ import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
-import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
@@ -46,11 +44,11 @@ import to.bitkit.R
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.Footnote
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.ui.utils.withAccent
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OnboardingSlidesScreen(
currentTab: Int = 0,
@@ -155,9 +153,9 @@ fun OnboardingSlidesScreen(
}
}
- // Toolbar (Skip and Advanced Setup buttons)
- TopAppBar(
- title = { },
+ AppTopBar(
+ onBackClick = null,
+ titleText = null,
actions = {
if (pagerState.currentPage == 4) {
TextButton(
diff --git a/app/src/main/java/to/bitkit/ui/onboarding/RestoreWalletScreen.kt b/app/src/main/java/to/bitkit/ui/onboarding/RestoreWalletScreen.kt
index a32cfa86a..a206e7a45 100644
--- a/app/src/main/java/to/bitkit/ui/onboarding/RestoreWalletScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/onboarding/RestoreWalletScreen.kt
@@ -16,20 +16,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
-import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -59,6 +52,7 @@ import to.bitkit.ui.components.ButtonSize
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.PrimaryButton
import to.bitkit.ui.components.SecondaryButton
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.theme.AppTextFieldDefaults
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
@@ -67,7 +61,6 @@ import to.bitkit.utils.bip39Words
import to.bitkit.utils.isBip39
import to.bitkit.utils.validBip39Checksum
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RestoreWalletView(
onBackClick: () -> Unit,
@@ -121,19 +114,10 @@ fun RestoreWalletView(
}
Scaffold(
- modifier = Modifier.fillMaxSize(),
topBar = {
- TopAppBar(
- title = {},
- navigationIcon = {
- IconButton(onClick = onBackClick) {
- Icon(
- imageVector = Icons.AutoMirrored.Default.ArrowBack,
- contentDescription = stringResource(R.string.common__back),
- modifier = Modifier.size(24.dp)
- )
- }
- },
+ AppTopBar(
+ titleText = null,
+ onBackClick = onBackClick,
)
}
) { paddingValues ->
@@ -430,7 +414,7 @@ fun MnemonicInputField(
value: String,
onValueChanged: (String) -> Unit,
onFocusChanged: (Boolean) -> Unit,
- onPositionChanged: (Int) -> Unit
+ onPositionChanged: (Int) -> Unit,
) {
OutlinedTextField(
value = value,
@@ -466,7 +450,7 @@ private fun handlePastedWords(
words: SnapshotStateList,
onWordCountChanged: (Boolean) -> Unit,
onFirstWordChanged: (String) -> Unit,
- onInvalidWords: (List) -> Unit
+ onInvalidWords: (List) -> Unit,
) {
val pastedWords = pastedText.trim().split("\\s+".toRegex()).filter { it.isNotEmpty() }
if (pastedWords.size == 12 || pastedWords.size == 24) {
@@ -494,7 +478,7 @@ private fun updateWordValidity(
index: Int,
words: SnapshotStateList,
invalidWordIndices: SnapshotStateList,
- onWordUpdate: ((String) -> Unit)? = null
+ onWordUpdate: ((String) -> Unit)? = null,
) {
words[index] = newValue
onWordUpdate?.invoke(newValue)
diff --git a/app/src/main/java/to/bitkit/ui/scaffold/AppAlertDialog.kt b/app/src/main/java/to/bitkit/ui/scaffold/AppAlertDialog.kt
index d13b09f3f..427632ef7 100644
--- a/app/src/main/java/to/bitkit/ui/scaffold/AppAlertDialog.kt
+++ b/app/src/main/java/to/bitkit/ui/scaffold/AppAlertDialog.kt
@@ -32,13 +32,41 @@ fun AppAlertDialog(
dismissOnClickOutside = false,
dismissOnBackPress = false,
),
+) {
+ AppAlertDialog(
+ title = title,
+ onConfirm = onConfirm,
+ onDismiss = onDismiss,
+ modifier = modifier,
+ confirmText = confirmText,
+ dismissText = dismissText,
+ onDismissRequest = onDismissRequest,
+ properties = properties,
+ textContent = { BodyM(text = text, color = Colors.White64) },
+ )
+}
+
+@Composable
+fun AppAlertDialog(
+ title: String,
+ onConfirm: () -> Unit,
+ onDismiss: () -> Unit,
+ modifier: Modifier = Modifier,
+ confirmText: String = stringResource(R.string.common__ok),
+ dismissText: String = stringResource(R.string.common__dialog_cancel),
+ onDismissRequest: () -> Unit = onDismiss,
+ properties: DialogProperties = DialogProperties(
+ dismissOnClickOutside = false,
+ dismissOnBackPress = false,
+ ),
+ textContent: @Composable () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(
onClick = onConfirm,
- modifier = Modifier.testTag("dialog_confirm"),
+ modifier = Modifier.testTag("DialogConfirm")
) {
BodyMSB(text = confirmText)
}
@@ -46,13 +74,13 @@ fun AppAlertDialog(
dismissButton = {
TextButton(
onClick = onDismiss,
- modifier = Modifier.testTag("dialog_cancel"),
+ modifier = Modifier.testTag("DialogCancel")
) {
BodyMSB(text = dismissText, color = Colors.White64)
}
},
title = { Title(text = title) },
- text = { BodyM(text = text, color = Colors.White64) },
+ text = textContent,
shape = MaterialTheme.shapes.medium,
properties = properties,
containerColor = Colors.Gray5,
diff --git a/app/src/main/java/to/bitkit/ui/scaffold/AppTopBar.kt b/app/src/main/java/to/bitkit/ui/scaffold/AppTopBar.kt
index fc1a4e15f..e82a5f430 100644
--- a/app/src/main/java/to/bitkit/ui/scaffold/AppTopBar.kt
+++ b/app/src/main/java/to/bitkit/ui/scaffold/AppTopBar.kt
@@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -31,6 +32,7 @@ import to.bitkit.ui.theme.AppThemeSurface
fun AppTopBar(
titleText: String?,
onBackClick: (() -> Unit)?,
+ modifier: Modifier = Modifier,
icon: Painter? = null,
actions: @Composable (RowScope.() -> Unit) = {},
) {
@@ -44,7 +46,7 @@ fun AppTopBar(
if (titleText != null) {
Row(
verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(12.dp),
+ horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
icon?.let { painter ->
Icon(
@@ -65,33 +67,53 @@ fun AppTopBar(
containerColor = Color.Transparent,
scrolledContainerColor = Color.Transparent,
),
+ modifier = modifier,
)
}
-// TODO use everywhere
@Composable
-fun BackNavIcon(onClick: () -> Unit) {
- IconButton(onClick = onClick) {
+fun BackNavIcon(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ IconButton(
+ onClick = onClick,
+ modifier = modifier.testTag("NavigationBack")
+ ) {
Icon(
imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = stringResource(R.string.common__back),
+ modifier = Modifier.size(24.dp)
)
}
}
@Composable
-fun CloseNavIcon(onClick: () -> Unit) {
- IconButton(onClick = onClick) {
+fun CloseNavIcon(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ IconButton(
+ onClick = onClick,
+ modifier = modifier.testTag("NavigationClose")
+ ) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(R.string.common__close),
+ modifier = Modifier.size(24.dp)
)
}
}
@Composable
-fun ScanNavIcon(onClick: () -> Unit) {
- IconButton(onClick = onClick) {
+fun ScanNavIcon(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ IconButton(
+ onClick = onClick,
+ modifier = modifier.testTag("NavigationAction")
+ ) {
Icon(
painter = painterResource(id = R.drawable.ic_scan),
contentDescription = stringResource(R.string.other__qr_scan),
diff --git a/app/src/main/java/to/bitkit/ui/scaffold/SheetTopBar.kt b/app/src/main/java/to/bitkit/ui/scaffold/SheetTopBar.kt
index d14f98bf4..5f5bc5398 100644
--- a/app/src/main/java/to/bitkit/ui/scaffold/SheetTopBar.kt
+++ b/app/src/main/java/to/bitkit/ui/scaffold/SheetTopBar.kt
@@ -7,22 +7,15 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.windowInsetsPadding
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import to.bitkit.R
import to.bitkit.ui.components.Subtitle
import to.bitkit.ui.theme.AppThemeSurface
@@ -49,22 +42,13 @@ fun SheetTopBar(
.align(Alignment.Center)
)
}
-
onBack?.let { callback ->
- IconButton(
+ BackNavIcon(
onClick = callback,
- modifier = Modifier.align(Alignment.CenterStart)
- ) {
- Icon(
- imageVector = Icons.AutoMirrored.Default.ArrowBack,
- contentDescription = stringResource(R.string.common__back),
- modifier = Modifier
- .size(24.dp)
- .windowInsetsPadding(
- WindowInsets.statusBars.only(WindowInsetsSides.Horizontal)
- )
- )
- }
+ modifier = Modifier
+ .align(Alignment.CenterStart)
+ .windowInsetsPadding(WindowInsets.statusBars.only(WindowInsetsSides.Horizontal))
+ )
}
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/scanner/QrScanningScreen.kt b/app/src/main/java/to/bitkit/ui/screens/scanner/QrScanningScreen.kt
index 36f4db11e..b576f474e 100644
--- a/app/src/main/java/to/bitkit/ui/screens/scanner/QrScanningScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/scanner/QrScanningScreen.kt
@@ -21,10 +21,8 @@ import androidx.camera.view.PreviewView
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -46,6 +44,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -65,10 +64,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import to.bitkit.R
+import to.bitkit.env.Env
import to.bitkit.ext.getClipboardText
import to.bitkit.models.Toast
import to.bitkit.ui.appViewModel
import to.bitkit.ui.components.PrimaryButton
+import to.bitkit.ui.components.SecondaryButton
+import to.bitkit.ui.components.TextInput
+import to.bitkit.ui.components.VerticalSpacer
+import to.bitkit.ui.scaffold.AppAlertDialog
import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.SheetTopBar
import to.bitkit.ui.shared.util.gradientBackground
@@ -89,10 +93,6 @@ fun QrScanningScreen(
) {
val app = appViewModel ?: return
- // Check if this scanner was opened for result
- val backStackEntry = navController.previousBackStackEntry
- val isCalledForResult = backStackEntry?.savedStateHandle?.contains(SCAN_REQUEST_KEY) == true
-
val (scanResult, setScanResult) = remember { mutableStateOf(null) }
// Handle scan result
@@ -100,10 +100,12 @@ fun QrScanningScreen(
scanResult?.let { qrCode ->
delay(100) // wait to prevent navigation result race conditions
- if (isCalledForResult) {
- backStackEntry.savedStateHandle[SCAN_RESULT_KEY] = qrCode
+ val prev = navController.previousBackStackEntry
+ val wasCalledForResult = prev?.savedStateHandle?.contains(SCAN_REQUEST_KEY) == true
+ if (wasCalledForResult) {
+ prev.savedStateHandle[SCAN_RESULT_KEY] = qrCode
onBack()
- backStackEntry.savedStateHandle.remove(SCAN_REQUEST_KEY)
+ prev.savedStateHandle.remove(SCAN_REQUEST_KEY)
} else {
onBack()
onScanSuccess(qrCode)
@@ -233,7 +235,8 @@ fun QrScanningScreen(
galleryLauncher.launch("image/*")
}
},
- onPasteFromClipboard = handlePaste(context, app, setScanResult)
+ onPasteFromClipboard = handlePaste(context, app, setScanResult),
+ onSubmitDebug = setScanResult,
)
}
}
@@ -264,6 +267,7 @@ private fun Content(
onClickGallery: () -> Unit,
onPasteFromClipboard: () -> Unit,
modifier: Modifier = Modifier,
+ onSubmitDebug: (String?) -> Unit,
) {
Column(
modifier = modifier
@@ -271,7 +275,7 @@ private fun Content(
.padding(horizontal = 16.dp)
) {
Box(
- modifier = modifier
+ modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(16.dp))
.weight(1f)
@@ -315,7 +319,7 @@ private fun Content(
)
}
}
- Spacer(modifier = Modifier.height(16.dp))
+ VerticalSpacer(16.dp)
PrimaryButton(
icon = {
Icon(
@@ -324,9 +328,37 @@ private fun Content(
)
},
text = stringResource(R.string.other__qr_paste),
- onClick = onPasteFromClipboard
+ onClick = onPasteFromClipboard,
)
- Spacer(modifier = Modifier.height(16.dp))
+
+ @Suppress("KotlinConstantConditions")
+ if (Env.isE2eTest) {
+ var showDialog by remember { mutableStateOf(false) }
+ var debugValue by remember { mutableStateOf("") }
+ VerticalSpacer(16.dp)
+ SecondaryButton(
+ text = "Enter QRCode String",
+ onClick = { showDialog = true },
+ modifier = Modifier.testTag("ScanPrompt")
+ )
+ if (showDialog) {
+ AppAlertDialog(
+ title = "",
+ confirmText = stringResource(R.string.common__yes_proceed),
+ onConfirm = { onSubmitDebug(debugValue) },
+ onDismiss = { showDialog = false },
+ modifier = Modifier.testTag("QRDialog")
+ ) {
+ TextInput(
+ value = debugValue,
+ onValueChange = { debugValue = it },
+ modifier = Modifier.testTag("QRInput")
+ )
+ }
+ }
+ }
+
+ VerticalSpacer(16.dp)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/FundingScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/FundingScreen.kt
index e2c061a47..a133f521d 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/FundingScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/FundingScreen.kt
@@ -20,6 +20,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -94,6 +95,7 @@ fun FundingScreen(
},
enabled = canTransfer && !isGeoBlocked,
onClick = onTransfer,
+ modifier = Modifier.testTag("FundTransfer")
)
if (balances.totalOnchainSats == 0uL) {
Box(
@@ -103,10 +105,9 @@ fun FundingScreen(
enabled = balances.totalOnchainSats == 0uL,
interactionSource = null,
indication = null,
- onClick = {
- showNoFundsAlert = true
- }
+ onClick = { showNoFundsAlert = true }
)
+ .testTag("FundTransfer")
)
}
}
@@ -122,6 +123,7 @@ fun FundingScreen(
},
enabled = !isGeoBlocked,
onClick = onFund,
+ modifier = Modifier.testTag("FundReceive")
)
RectangleButton(
label = stringResource(R.string.lightning__funding__button3),
@@ -134,12 +136,13 @@ fun FundingScreen(
)
},
onClick = onAdvanced,
+ modifier = Modifier.testTag("FundCustom")
)
}
}
if (showNoFundsAlert) {
AlertDialog(
- onDismissRequest = { showNoFundsAlert = false }, // Dismiss the alert
+ onDismissRequest = { showNoFundsAlert = false },
confirmButton = {
TextButton(onClick = { showNoFundsAlert = false }) {
BodyM(text = stringResource(R.string.common__ok), color = Colors.Purple)
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/LiquidityScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/LiquidityScreen.kt
index e70acb89f..e078f1e14 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/LiquidityScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/LiquidityScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -93,6 +94,7 @@ private fun LiquidityScreen(
PrimaryButton(
text = stringResource(R.string.common__understood),
onClick = onContinueClick,
+ modifier = Modifier.testTag("LiquidityContinue")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsAvailabilityScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsAvailabilityScreen.kt
index 627898499..622cca939 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsAvailabilityScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsAvailabilityScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -82,18 +83,19 @@ fun SavingsAvailabilityScreen(
PrimaryButton(
text = stringResource(R.string.common__continue),
onClick = onContinueClick,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("AvailabilityContinue")
)
}
-
Spacer(modifier = Modifier.height(16.dp))
}
}
}
-@Preview(showSystemUi = true, showBackground = true)
+@Preview(showSystemUi = true)
@Composable
-private fun SavingsAvailabilityScreenPreview() {
+private fun Preview() {
AppThemeSurface {
SavingsAvailabilityScreen()
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsIntroScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsIntroScreen.kt
index 04d61f441..befda6405 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsIntroScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsIntroScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -68,6 +69,7 @@ fun SavingsIntroScreen(
PrimaryButton(
text = stringResource(R.string.lightning__savings_intro__button),
onClick = onContinueClick,
+ modifier = Modifier.testTag("SavingsIntro-button")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt
index 6f0678b6b..d482bd457 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt
@@ -10,8 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
-import androidx.compose.material3.CenterAlignedTopAppBar
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -31,7 +29,7 @@ import to.bitkit.R
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.PrimaryButton
-import to.bitkit.ui.components.Title
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.CloseNavIcon
import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.screens.transfer.components.TransferAnimationView
@@ -87,7 +85,6 @@ fun SavingsProgressScreen(
)
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun SavingsProgressScreen(
progressState: SavingsProgressState,
@@ -95,25 +92,17 @@ private fun SavingsProgressScreen(
onCloseClick: () -> Unit = {},
) {
val inProgress = progressState == SavingsProgressState.PROGRESS
-
ScreenColumn {
- CenterAlignedTopAppBar(
- title = {
- Title(
- text = when (progressState) {
- SavingsProgressState.PROGRESS -> stringResource(R.string.lightning__transfer__nav_title)
- SavingsProgressState.SUCCESS -> stringResource(R.string.lightning__transfer_success__nav_title)
- SavingsProgressState.INTERRUPTED -> stringResource(
- R.string.lightning__savings_interrupted__nav_title
- )
- .removeAccentTags().replace("\n", " ")
- }
- )
+ AppTopBar(
+ titleText = when (progressState) {
+ SavingsProgressState.PROGRESS -> stringResource(R.string.lightning__transfer__nav_title)
+ SavingsProgressState.SUCCESS -> stringResource(R.string.lightning__transfer_success__nav_title)
+ SavingsProgressState.INTERRUPTED -> stringResource(R.string.lightning__savings_interrupted__nav_title)
+ .removeAccentTags().replace("\n", " ")
},
+ onBackClick = null,
actions = {
- if (inProgress) {
- CloseNavIcon(onCloseClick)
- }
+ if (inProgress) CloseNavIcon(onCloseClick)
},
)
Column(
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SettingUpScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SettingUpScreen.kt
index 6eaec5049..846d7c37d 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SettingUpScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SettingUpScreen.kt
@@ -6,8 +6,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.CenterAlignedTopAppBar
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -16,6 +14,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices.NEXUS_5
@@ -30,7 +29,7 @@ import to.bitkit.ui.appViewModel
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.PrimaryButton
-import to.bitkit.ui.components.Title
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.CloseNavIcon
import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.screens.transfer.components.ProgressSteps
@@ -87,7 +86,6 @@ fun SettingUpScreen(
)
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun SettingUpScreen(
lightningSetupStep: Int,
@@ -95,18 +93,16 @@ private fun SettingUpScreen(
onCloseClick: () -> Unit = {},
) {
val inProgress = lightningSetupStep < 3
- ScreenColumn {
- CenterAlignedTopAppBar(
- title = {
- Title(
- text = if (inProgress) {
- stringResource(R.string.lightning__transfer__nav_title)
- } else {
- stringResource(R.string.lightning__transfer_success__nav_title)
- }
- )
+ ScreenColumn(
+ modifier = Modifier.testTag(if (inProgress) "LightningSettingUp" else "TransferSuccess")
+ ) {
+ AppTopBar(
+ titleText = when {
+ inProgress -> stringResource(R.string.lightning__transfer__nav_title)
+ else -> stringResource(R.string.lightning__transfer_success__nav_title)
},
- actions = { CloseNavIcon(onCloseClick) },
+ onBackClick = null,
+ actions = { if (inProgress) CloseNavIcon(onCloseClick) },
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -178,6 +174,7 @@ private fun SettingUpScreen(
randomOkText
},
onClick = onContinueClick,
+ modifier = Modifier.testTag("TransferSuccess-button")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt
index 79df1e67a..e6ae2b4d8 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAdvancedScreen.kt
@@ -24,6 +24,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -70,6 +71,7 @@ fun SpendingAdvancedScreen(
.padding(horizontal = 16.dp)
.fillMaxSize()
.imePadding()
+ .testTag("SpendingAdvanced")
) {
var receivingSatsAmount by rememberSaveable { mutableLongStateOf(0) }
var overrideSats: Long? by remember { mutableStateOf(null) }
@@ -117,6 +119,7 @@ fun SpendingAdvancedScreen(
receivingSatsAmount = sats
overrideSats = null
},
+ modifier = Modifier.testTag("SpendingAdvancedNumberField")
)
Spacer(modifier = Modifier.height(10.dp))
@@ -153,6 +156,7 @@ fun SpendingAdvancedScreen(
onClick = {
overrideSats = transferValues.minLspBalance.toLong()
},
+ modifier = Modifier.testTag("SpendingAdvancedMin")
)
// Default Button
NumberPadActionButton(
@@ -161,6 +165,7 @@ fun SpendingAdvancedScreen(
onClick = {
overrideSats = transferValues.defaultLspBalance.toLong()
},
+ modifier = Modifier.testTag("SpendingAdvancedDefault")
)
// Max Button
NumberPadActionButton(
@@ -169,6 +174,7 @@ fun SpendingAdvancedScreen(
onClick = {
overrideSats = transferValues.maxLspBalance.toLong()
},
+ modifier = Modifier.testTag("SpendingAdvancedMax")
)
}
HorizontalDivider()
@@ -195,6 +201,7 @@ fun SpendingAdvancedScreen(
},
enabled = !isLoading && isValid,
isLoading = isLoading,
+ modifier = Modifier.testTag("SpendingAdvancedContinue")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt
index 04b58c306..8db335193 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingAmountScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -101,6 +102,7 @@ private fun Content(
.padding(horizontal = 16.dp)
.fillMaxSize()
.imePadding()
+ .testTag("SpendingAmount")
) {
VerticalSpacer(32.dp)
Display(
@@ -138,12 +140,14 @@ private fun Content(
text = stringResource(R.string.lightning__spending_amount__quarter),
color = Colors.Purple,
onClick = onClickQuarter,
+ modifier = Modifier.testTag("SpendingAmountQuarter")
)
// Max Button
NumberPadActionButton(
text = stringResource(R.string.common__max),
color = Colors.Purple,
onClick = onClickMaxAmount,
+ modifier = Modifier.testTag("SpendingAmountMax")
)
}
HorizontalDivider()
@@ -154,6 +158,7 @@ private fun Content(
onClick = onConfirmAmount,
enabled = uiState.satsAmount != 0L && uiState.satsAmount <= uiState.maxAllowedToSend,
isLoading = uiState.isLoading,
+ modifier = Modifier.testTag("SpendingAmountContinue")
)
VerticalSpacer(16.dp)
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingConfirmScreen.kt
index 14fc66778..6c099c230 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingConfirmScreen.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -171,6 +172,7 @@ private fun Content(
remoteBalance = lspBalance.toLong(),
status = ChannelStatusUi.OPEN,
showLabels = true,
+ modifier = Modifier.testTag("SpendingConfirmChannel")
)
}
@@ -181,6 +183,7 @@ private fun Content(
size = ButtonSize.Small,
fullWidth = false,
onClick = onLearnMoreClick,
+ modifier = Modifier.testTag("SpendingConfirmMore")
)
PrimaryButton(
text = stringResource(
@@ -195,6 +198,9 @@ private fun Content(
onAdvancedClick()
}
},
+ modifier = Modifier.testTag(
+ if (isAdvanced) "SpendingConfirmDefault" else "SpendingConfirmAdvanced"
+ )
)
}
VerticalSpacer(16.dp)
@@ -213,7 +219,7 @@ private fun Content(
onTransferToSpendingConfirm(order)
onConfirm()
}
- }
+ },
)
VerticalSpacer(16.dp)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingIntroScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingIntroScreen.kt
index 7ad1f7adb..59ab1d20c 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingIntroScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/SpendingIntroScreen.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -66,6 +67,7 @@ fun SpendingIntroScreen(
PrimaryButton(
text = stringResource(R.string.lightning__spending_intro__button),
onClick = onContinueClick,
+ modifier = Modifier.testTag("SpendingIntro-button")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/TransferIntroScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/TransferIntroScreen.kt
index 86821b915..d7298744d 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/TransferIntroScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/TransferIntroScreen.kt
@@ -9,12 +9,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -23,13 +22,13 @@ import to.bitkit.R
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.Display
import to.bitkit.ui.components.PrimaryButton
+import to.bitkit.ui.scaffold.AppTopBar
import to.bitkit.ui.scaffold.CloseNavIcon
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.ui.utils.withAccent
// TODO: show on first LN suggestion card click
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TransferIntroScreen(
onContinueClick: () -> Unit = {},
@@ -49,8 +48,9 @@ fun TransferIntroScreen(
.padding(top = 130.dp)
.fillMaxWidth()
)
- TopAppBar(
- title = { },
+ AppTopBar(
+ titleText = null,
+ onBackClick = null,
actions = { CloseNavIcon(onCloseClick) },
)
Column(
@@ -67,6 +67,7 @@ fun TransferIntroScreen(
PrimaryButton(
text = stringResource(R.string.lightning__transfer_intro__button),
onClick = onContinueClick,
+ modifier = Modifier.testTag("TransferIntro-button")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalAmountScreen.kt
index 664be8b01..354c07a27 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalAmountScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalAmountScreen.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -78,6 +79,7 @@ private fun Content(
.padding(horizontal = 16.dp)
.fillMaxSize()
.imePadding()
+ .testTag("ExternalAmount")
) {
val totalOnchainSats = LocalBalances.current.totalOnchainSats
@@ -136,6 +138,7 @@ private fun Content(
text = stringResource(R.string.common__continue),
onClick = { onContinueClick() },
enabled = amountState.sats != 0L,
+ modifier = Modifier.testTag("ExternalAmountContinue")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConfirmScreen.kt
index 7079618c4..b715be696 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConfirmScreen.kt
@@ -26,6 +26,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -113,6 +114,7 @@ private fun Content(
.weight(1f)
.padding(top = 16.dp)
.clickableAlpha(onClick = onNetworkFeeClick)
+ .testTag("SetCustomFee")
) {
Caption13Up(
text = stringResource(R.string.lightning__spending_confirm__network_fee),
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConnectionScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConnectionScreen.kt
index c7175c0fa..c1e5128c7 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConnectionScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalConnectionScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
@@ -148,7 +149,9 @@ private fun ExternalConnectionContent(
imeAction = ImeAction.Done,
capitalization = KeyboardCapitalization.None,
),
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("NodeIdInput")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -164,7 +167,9 @@ private fun ExternalConnectionContent(
imeAction = ImeAction.Done,
capitalization = KeyboardCapitalization.None,
),
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("HostInput")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -181,7 +186,9 @@ private fun ExternalConnectionContent(
imeAction = ImeAction.Done,
capitalization = KeyboardCapitalization.None,
),
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("PortInput")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -216,7 +223,7 @@ private fun ExternalConnectionContent(
onClick = { onContinueClick(LnPeer(nodeId = nodeId, host = host, port = port)) },
enabled = isValid,
isLoading = uiState.isLoading,
- modifier = Modifier.weight(1f)
+ modifier = Modifier.weight(1f).testTag("ExternalContinue")
)
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalFeeCustomScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalFeeCustomScreen.kt
index 1a08958e8..92c7d06b9 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalFeeCustomScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalFeeCustomScreen.kt
@@ -17,6 +17,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -160,12 +161,15 @@ private fun Content(
NumberPadSimple(
onPress = onKeyPress,
- modifier = Modifier.height(350.dp)
+ modifier = Modifier
+ .height(350.dp)
+ .testTag("FeeCustomNumberPad")
)
PrimaryButton(
onClick = onContinue,
- text = stringResource(R.string.common__continue)
+ text = stringResource(R.string.common__continue),
+ modifier = Modifier.testTag("FeeCustomContinue")
)
VerticalSpacer(16.dp)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalSuccessScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalSuccessScreen.kt
index 110a5de54..11f7fae9b 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalSuccessScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalSuccessScreen.kt
@@ -25,6 +25,7 @@ fun ExternalSuccessScreen(
buttonText = localizedRandom(R.string.common__ok_random),
onButtonClick = onContinue,
onCloseClick = onClose,
+ testTag = "ExternalSuccess",
)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/transfer/external/LnurlChannelScreen.kt b/app/src/main/java/to/bitkit/ui/screens/transfer/external/LnurlChannelScreen.kt
index 5e980c546..f8abe21ef 100644
--- a/app/src/main/java/to/bitkit/ui/screens/transfer/external/LnurlChannelScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/transfer/external/LnurlChannelScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@@ -119,26 +120,28 @@ private fun Content(
VerticalSpacer(32.dp)
Row(
- modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.fillMaxWidth()
) {
SecondaryButton(
text = stringResource(R.string.common__cancel),
onClick = onCancel,
- modifier = Modifier.weight(1f),
+ modifier = Modifier.weight(1f)
)
PrimaryButton(
text = stringResource(R.string.common__connect),
onClick = onConnect,
- modifier = Modifier.weight(1f),
isLoading = uiState.isConnecting,
enabled = !uiState.isConnecting,
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ConnectButton")
)
}
} else {
Box(
contentAlignment = Alignment.Center,
- modifier = Modifier.fillMaxSize(),
+ modifier = Modifier.fillMaxSize()
) {
CircularProgressIndicator()
}
@@ -165,7 +168,7 @@ private fun InfoRow(
HorizontalDivider()
}
-@Preview(showBackground = true)
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
@@ -181,7 +184,7 @@ private fun Preview() {
}
}
-@Preview(showBackground = true)
+@Preview(showSystemUi = true)
@Composable
private fun PreviewLoading() {
AppThemeSurface {
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt
index 9ac735d2d..c39e55b94 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt
@@ -69,6 +69,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import to.bitkit.R
import to.bitkit.env.Env
+import to.bitkit.models.BalanceState
import to.bitkit.models.Suggestion
import to.bitkit.models.WidgetType
import to.bitkit.ui.LocalBalances
@@ -80,6 +81,7 @@ import to.bitkit.ui.components.HorizontalSpacer
import to.bitkit.ui.components.Sheet
import to.bitkit.ui.components.StatusBarSpacer
import to.bitkit.ui.components.SuggestionCard
+import to.bitkit.ui.components.TabBar
import to.bitkit.ui.components.TertiaryButton
import to.bitkit.ui.components.Text13Up
import to.bitkit.ui.components.Title
@@ -169,7 +171,7 @@ fun HomeScreen(
rootNavController.navigate(Routes.BuyIntro)
}
- Suggestion.SPEND -> {
+ Suggestion.LIGHTNING -> {
if (!hasSeenTransferIntro) {
rootNavController.navigateToTransferIntro()
} else {
@@ -277,9 +279,9 @@ private fun Content(
onDismissEmptyState: () -> Unit = {},
onDismissHighBalanceSheet: () -> Unit = {},
onClickEmptyActivityRow: () -> Unit = {},
+ balances: BalanceState = LocalBalances.current,
) {
val scope = rememberCoroutineScope()
- val balances = LocalBalances.current
Box {
val heightStatusBar = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
@@ -314,6 +316,7 @@ private fun Content(
.padding(horizontal = 16.dp)
.fillMaxSize()
.verticalScroll(rememberScrollState())
+ .testTag("HomeScrollView")
) {
StatusBarSpacer()
TopBarSpacer()
@@ -321,7 +324,9 @@ private fun Content(
BalanceHeaderView(
sats = balances.totalSats.toLong(),
showEyeIcon = true,
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("TotalBalance")
)
if (!homeUiState.showEmptyState) {
Spacer(modifier = Modifier.height(32.dp))
@@ -337,6 +342,7 @@ private fun Content(
modifier = Modifier
.clickableAlpha { walletNavController.navigate(HomeRoutes.Savings) }
.padding(vertical = 4.dp)
+ .testTag("ActivitySavings")
)
VerticalDivider()
WalletBalanceView(
@@ -347,6 +353,7 @@ private fun Content(
.clickableAlpha { walletNavController.navigate(HomeRoutes.Spending) }
.padding(vertical = 4.dp)
.padding(start = 16.dp)
+ .testTag("ActivitySpending")
)
}
@@ -362,10 +369,10 @@ private fun Content(
Text13Up(stringResource(R.string.cards__suggestions), color = Colors.White64)
Spacer(modifier = Modifier.height(16.dp))
LazyRow(
- modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp),
state = state,
- flingBehavior = snapBehavior
+ flingBehavior = snapBehavior,
+ modifier = Modifier.fillMaxWidth().testTag("Suggestions")
) {
items(homeUiState.suggestions, key = { it.name }) { item ->
SuggestionCard(
@@ -375,7 +382,7 @@ private fun Content(
icon = item.icon,
onClose = { onRemoveSuggestion(item) },
onClick = { onClickSuggestion(item) },
- modifier = Modifier.testTag("SUGGESTION_${item.name}")
+ modifier = Modifier.testTag("Suggestion-${item.name.lowercase()}")
)
}
}
@@ -394,24 +401,17 @@ private fun Content(
color = Colors.White64
)
- if (homeUiState.isEditingWidgets) {
- IconButton(
- onClick = onClickConfirmEdit
- ) {
- Icon(
- painter = painterResource(R.drawable.ic_check),
- contentDescription = null
- )
- }
- } else {
- IconButton(
- onClick = onClickEnableEdit
- ) {
- Icon(
- painter = painterResource(R.drawable.ic_sort_ascending),
- contentDescription = null
- )
- }
+ IconButton(
+ onClick = onClickConfirmEdit,
+ modifier = Modifier.testTag("WidgetsEdit")
+ ) {
+ Icon(
+ painter = when (homeUiState.isEditingWidgets) {
+ true -> painterResource(R.drawable.ic_check)
+ else -> painterResource(R.drawable.ic_sort_ascending)
+ },
+ contentDescription = null,
+ )
}
}
@@ -445,7 +445,6 @@ private fun Content(
WidgetType.BLOCK -> {
homeUiState.currentBlock?.run {
BlockCard(
- modifier = Modifier.fillMaxWidth(),
showWidgetTitle = homeUiState.showWidgetTitles,
showBlock = homeUiState.blocksPreferences.showBlock,
showTime = homeUiState.blocksPreferences.showTime,
@@ -458,7 +457,10 @@ private fun Content(
transactions = transactionCount,
size = size,
source = source,
- block = height
+ block = height,
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("BlocksWidget")
)
}
}
@@ -467,8 +469,8 @@ private fun Content(
currencyViewModel?.let {
CalculatorCard(
currencyViewModel = it,
- modifier = Modifier.fillMaxWidth(),
- showWidgetTitle = homeUiState.showWidgetTitles
+ showWidgetTitle = homeUiState.showWidgetTitles,
+ modifier = Modifier.fillMaxWidth()
)
}
}
@@ -476,10 +478,10 @@ private fun Content(
WidgetType.FACTS -> {
homeUiState.currentFact?.run {
FactsCard(
- modifier = Modifier.fillMaxWidth(),
showWidgetTitle = homeUiState.showWidgetTitles,
showSource = homeUiState.factsPreferences.showSource,
headline = homeUiState.currentFact,
+ modifier = Modifier.fillMaxWidth()
)
}
}
@@ -487,14 +489,16 @@ private fun Content(
WidgetType.NEWS -> {
homeUiState.currentArticle?.run {
HeadlineCard(
- modifier = Modifier.fillMaxWidth(),
showWidgetTitle = homeUiState.showWidgetTitles,
showTime = homeUiState.headlinePreferences.showTime,
showSource = homeUiState.headlinePreferences.showSource,
headline = title,
time = timeAgo,
source = publisher,
- link = link
+ link = link,
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("NewsWidget")
)
}
}
@@ -502,10 +506,12 @@ private fun Content(
WidgetType.PRICE -> {
homeUiState.currentPrice?.run {
PriceCard(
- modifier = Modifier.fillMaxWidth(),
showWidgetTitle = homeUiState.showWidgetTitles,
pricePreferences = homeUiState.pricePreferences,
priceDTO = homeUiState.currentPrice,
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("PriceWidget")
)
}
}
@@ -513,10 +519,10 @@ private fun Content(
WidgetType.WEATHER -> {
homeUiState.currentWeather?.run {
WeatherCard(
- modifier = Modifier.fillMaxWidth(),
showWidgetTitle = homeUiState.showWidgetTitles,
weatherModel = this,
- preferences = homeUiState.weatherPreferences
+ preferences = homeUiState.weatherPreferences,
+ modifier = Modifier.fillMaxWidth()
)
}
}
@@ -532,10 +538,11 @@ private fun Content(
Icon(
painter = painterResource(R.drawable.ic_plus),
contentDescription = null,
- tint = Colors.White80
+ tint = Colors.White80,
)
},
onClick = onClickAddWidget,
+ modifier = Modifier.testTag("WidgetsAdd")
)
}
Spacer(modifier = Modifier.height(32.dp))
@@ -605,7 +612,9 @@ private fun TopBar(
title = {
Row(
verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.clickableAlpha(onClick = onClickProfile)
+ modifier = Modifier
+ .clickableAlpha(onClick = onClickProfile)
+ .testTag("Header")
) {
Icon(
imageVector = Icons.Filled.AccountCircle,
@@ -614,13 +623,19 @@ private fun TopBar(
modifier = Modifier.size(32.dp)
)
HorizontalSpacer(16.dp)
- Title(text = stringResource(R.string.slashtags__your_name_capital))
+ Title(
+ text = stringResource(R.string.slashtags__your_name_capital),
+ Modifier.testTag("EmptyProfileHeader")
+ )
}
},
actions = {
AppStatus(onClick = { rootNavController.navigate(Routes.AppStatus) })
HorizontalSpacer(4.dp)
- IconButton(onClick = { scope.launch { drawerState.open() } }) {
+ IconButton(
+ onClick = { scope.launch { drawerState.open() } },
+ modifier = Modifier.testTag("HeaderMenu")
+ ) {
Icon(
painter = painterResource(R.drawable.ic_list),
contentDescription = stringResource(R.string.settings__settings),
@@ -658,12 +673,45 @@ private fun Preview() {
Box {
Content(
mainUiState = MainUiState(),
- homeUiState = HomeUiState(),
+ homeUiState = HomeUiState(
+ showWidgets = true,
+ ),
+ rootNavController = rememberNavController(),
+ walletNavController = rememberNavController(),
+ drawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
+ latestActivities = previewActivityItems.take(3),
+ balances = BalanceState(
+ totalOnchainSats = 165_000u,
+ totalLightningSats = 45_000u,
+ totalSats = 200_000u,
+ ),
+ )
+ TabBar(modifier = Modifier.align(Alignment.BottomCenter))
+ }
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun PreviewEmpty() {
+ AppThemeSurface {
+ Box {
+ Content(
+ mainUiState = MainUiState(),
+ homeUiState = HomeUiState(
+ showEmptyState = true,
+ ),
rootNavController = rememberNavController(),
walletNavController = rememberNavController(),
drawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
latestActivities = previewActivityItems.take(3),
+ balances = BalanceState(
+ totalOnchainSats = 165_000u,
+ totalLightningSats = 45_000u,
+ totalSats = 200_000u,
+ )
)
+ TabBar(modifier = Modifier.align(Alignment.BottomCenter))
}
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeViewModel.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeViewModel.kt
index f66d8d8e2..2a52abfa6 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/HomeViewModel.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/HomeViewModel.kt
@@ -273,7 +273,7 @@ class HomeViewModel @Inject constructor(
balanceState.totalOnchainSats > 0uL -> { // Only on chain balance
listOfNotNull(
Suggestion.BACK_UP.takeIf { !settings.backupVerified },
- Suggestion.SPEND,
+ Suggestion.LIGHTNING,
Suggestion.SECURE.takeIf { !settings.isPinEnabled },
Suggestion.BUY,
Suggestion.SUPPORT,
@@ -286,7 +286,7 @@ class HomeViewModel @Inject constructor(
else -> { // Empty wallet
listOfNotNull(
Suggestion.BUY,
- Suggestion.SPEND,
+ Suggestion.LIGHTNING,
Suggestion.BACK_UP.takeIf { !settings.backupVerified },
Suggestion.SECURE.takeIf { !settings.isPinEnabled },
Suggestion.SUPPORT,
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt
index 5678da07c..be83a91de 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/SavingsWalletScreen.kt
@@ -21,11 +21,13 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import to.bitkit.R
+import to.bitkit.models.BalanceState
import to.bitkit.ui.LocalBalances
import to.bitkit.ui.activityListViewModel
import to.bitkit.ui.components.BalanceHeaderView
@@ -45,8 +47,8 @@ fun SavingsWalletScreen(
onActivityItemClick: (String) -> Unit,
onTransferToSpendingClick: () -> Unit,
onBackClick: () -> Unit,
+ balances: BalanceState = LocalBalances.current,
) {
- val balances = LocalBalances.current
val showEmptyState by remember(balances.totalOnchainSats) {
mutableStateOf(balances.totalOnchainSats == 0uL) // TODO use && hasOnchainActivity
}
@@ -74,7 +76,12 @@ fun SavingsWalletScreen(
Column(
modifier = Modifier.padding(horizontal = 16.dp)
) {
- BalanceHeaderView(sats = balances.totalOnchainSats.toLong(), modifier = Modifier.fillMaxWidth())
+ BalanceHeaderView(
+ sats = balances.totalOnchainSats.toLong(),
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("TotalBalance")
+ )
if (!showEmptyState) {
Spacer(modifier = Modifier.height(32.dp))
SecondaryButton(
@@ -86,7 +93,8 @@ fun SavingsWalletScreen(
contentDescription = null,
modifier = Modifier.size(16.dp),
)
- }
+ },
+ modifier = Modifier.testTag("TransferToSpending")
)
val activity = activityListViewModel ?: return@Column
@@ -114,7 +122,22 @@ fun SavingsWalletScreen(
@Preview(showSystemUi = true)
@Composable
-private fun SavingsWalletScreenPreview() {
+private fun Preview() {
+ AppThemeSurface {
+ SavingsWalletScreen(
+ onAllActivityButtonClick = {},
+ onActivityItemClick = {},
+ onEmptyActivityRowClick = {},
+ onTransferToSpendingClick = {},
+ onBackClick = {},
+ balances = BalanceState(totalOnchainSats = 50_000u),
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun PreviewEmpty() {
AppThemeSurface {
SavingsWalletScreen(
onAllActivityButtonClick = {},
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt
index 5659ec7b0..1a31d5c02 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/SpendingWalletScreen.kt
@@ -21,11 +21,14 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import to.bitkit.R
+import to.bitkit.ext.createChannelDetails
+import to.bitkit.models.BalanceState
import to.bitkit.ui.LocalBalances
import to.bitkit.ui.activityListViewModel
import to.bitkit.ui.components.BalanceHeaderView
@@ -47,8 +50,8 @@ fun SpendingWalletScreen(
onEmptyActivityRowClick: () -> Unit,
onTransferToSavingsClick: () -> Unit,
onBackClick: () -> Unit,
+ balances: BalanceState = LocalBalances.current,
) {
- val balances = LocalBalances.current
val showEmptyState by remember(balances.totalLightningSats) {
// TODO use && hasLnActivity + LN spendingSats
mutableStateOf(balances.totalLightningSats == 0uL)
@@ -83,22 +86,27 @@ fun SpendingWalletScreen(
Column(
modifier = Modifier.padding(horizontal = 16.dp)
) {
- BalanceHeaderView(sats = balances.totalLightningSats.toLong(), modifier = Modifier.fillMaxWidth())
-
+ BalanceHeaderView(
+ sats = balances.totalLightningSats.toLong(),
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("TotalBalance")
+ )
if (!showEmptyState) {
Spacer(modifier = Modifier.height(32.dp))
if (canTransfer) {
SecondaryButton(
onClick = onTransferToSavingsClick,
- text = stringResource(R.string.lightning__savings_confirm__label),
+ text = "Transfer To Savings", // TODO add missing localized text
icon = {
Icon(
painter = painterResource(R.drawable.ic_transfer),
contentDescription = null,
modifier = Modifier.size(16.dp),
)
- }
+ },
+ modifier = Modifier.testTag("TransferToSavings")
)
}
@@ -127,7 +135,25 @@ fun SpendingWalletScreen(
@Preview(showSystemUi = true)
@Composable
-private fun SpendingWalletScreenPreview() {
+private fun Preview() {
+ AppThemeSurface {
+ SpendingWalletScreen(
+ uiState = MainUiState(
+ channels = listOf(createChannelDetails())
+ ),
+ onAllActivityButtonClick = {},
+ onActivityItemClick = {},
+ onEmptyActivityRowClick = {},
+ onTransferToSavingsClick = {},
+ onBackClick = {},
+ balances = BalanceState(totalLightningSats = 50_000u),
+ )
+ }
+}
+
+@Preview(showSystemUi = true)
+@Composable
+private fun PreviewEmpty() {
AppThemeSurface {
SpendingWalletScreen(
uiState = MainUiState(),
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityDetailScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityDetailScreen.kt
index 1037d0919..4bee5bb3d 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityDetailScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityDetailScreen.kt
@@ -5,7 +5,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -29,6 +28,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -44,6 +44,8 @@ import to.bitkit.R
import to.bitkit.ext.canBeBoosted
import to.bitkit.ext.ellipsisMiddle
import to.bitkit.ext.isBoosted
+import to.bitkit.ext.isSent
+import to.bitkit.ext.isTransfer
import to.bitkit.ext.rawId
import to.bitkit.ext.toActivityItemDate
import to.bitkit.ext.toActivityItemTime
@@ -55,6 +57,7 @@ import to.bitkit.ui.components.BalanceHeaderView
import to.bitkit.ui.components.BodySSB
import to.bitkit.ui.components.ButtonSize
import to.bitkit.ui.components.Caption13Up
+import to.bitkit.ui.components.MoneySSB
import to.bitkit.ui.components.PrimaryButton
import to.bitkit.ui.components.TagButton
import to.bitkit.ui.components.Title
@@ -173,7 +176,6 @@ fun ActivityDetailScreen(
}
}
-@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun ActivityDetailContent(
item: Activity,
@@ -186,10 +188,7 @@ private fun ActivityDetailContent(
) {
val isLightning = item is Activity.Lightning
val accentColor = if (isLightning) Colors.Purple else Colors.Brand
- val isSent = when (item) {
- is Activity.Lightning -> item.v1.txType == PaymentType.SENT
- is Activity.Onchain -> item.v1.txType == PaymentType.SENT
- }
+ val isSent = item.isSent()
val amountPrefix = if (isSent) "-" else "+"
val timestamp = when (item) {
is Activity.Lightning -> item.v1.timestamp
@@ -207,13 +206,13 @@ private fun ActivityDetailContent(
is Activity.Onchain -> item.v1.fee
}
val isSelfSend = isSent && paymentValue == 0uL
+ val isTransfer = item.isTransfer()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
- // header section: amount + icon
Row(
verticalAlignment = Alignment.Bottom,
modifier = Modifier
@@ -224,10 +223,10 @@ private fun ActivityDetailContent(
sats = item.totalValue().toLong(),
prefix = amountPrefix,
showBitcoinSymbol = false,
- forceShowBalance = true,
+ useSwipeToHide = false,
modifier = Modifier.weight(1f)
)
- ActivityIcon(activity = item, size = 48.dp) // TODO Display the user avatar when selfsend
+ ActivityIcon(activity = item, size = 48.dp) // TODO Display the user avatar when selfSend
}
Spacer(modifier = Modifier.height(16.dp))
@@ -281,8 +280,6 @@ private fun ActivityDetailContent(
HorizontalDivider()
}
}
-
- // Fee section for sent transactions
if (isSent) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
@@ -290,29 +287,33 @@ private fun ActivityDetailContent(
) {
Column(modifier = Modifier.weight(1f)) {
Caption13Up(
- text = if (isSelfSend) {
- "Sent to myself" // TODO translation
- } else {
- stringResource(R.string.wallet__activity_payment)
+ text = when {
+ isTransfer -> stringResource(R.string.wallet__activity_transfer_to_spending)
+ isSelfSend -> "Sent to myself" // TODO add missing localized text
+ else -> stringResource(R.string.wallet__activity_payment)
},
color = Colors.White64,
modifier = Modifier.padding(top = 16.dp, bottom = 8.dp)
)
- Row(verticalAlignment = Alignment.CenterVertically) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.testTag("ActivityAmount")
+ ) {
Icon(
- painter = painterResource(R.drawable.ic_user),
+ painter = when {
+ isTransfer -> painterResource(R.drawable.ic_lightning)
+ else -> painterResource(R.drawable.ic_user)
+ },
contentDescription = null,
tint = accentColor,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
- BodySSB(text = "$paymentValue")
+ MoneySSB(sats = paymentValue.toLong())
}
Spacer(modifier = Modifier.height(16.dp))
HorizontalDivider()
}
-
- // Fee column if fee exists
if (fee != null) {
Column(modifier = Modifier.weight(1f)) {
Caption13Up(
@@ -320,7 +321,10 @@ private fun ActivityDetailContent(
color = Colors.White64,
modifier = Modifier.padding(top = 16.dp, bottom = 8.dp)
)
- Row(verticalAlignment = Alignment.CenterVertically) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.testTag("ActivityFee")
+ ) {
Icon(
painter = painterResource(R.drawable.ic_speed_normal),
contentDescription = null,
@@ -328,7 +332,7 @@ private fun ActivityDetailContent(
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
- BodySSB(text = fee.toString())
+ MoneySSB(sats = fee.toLong())
}
Spacer(modifier = Modifier.height(16.dp))
HorizontalDivider()
@@ -348,6 +352,7 @@ private fun ActivityDetailContent(
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
+ modifier = Modifier.testTag("ActivityTags")
) {
tags.forEach { tag ->
TagButton(
@@ -391,7 +396,9 @@ private fun ActivityDetailContent(
Title(
text = message,
color = Colors.White,
- modifier = Modifier.padding(24.dp),
+ modifier = Modifier
+ .padding(24.dp)
+ .testTag("InvoiceNote")
)
}
}
@@ -436,7 +443,9 @@ private fun ActivityDetailContent(
modifier = Modifier.size(16.dp)
)
},
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ActivityTag")
)
}
Row(
@@ -462,7 +471,15 @@ private fun ActivityDetailContent(
modifier = Modifier.size(16.dp)
)
},
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag(
+ when {
+ item.isBoosted() -> "BoostedButton"
+ item.canBeBoosted() -> "BoostButton"
+ else -> "BoostDisabled"
+ }
+ )
)
PrimaryButton(
text = stringResource(R.string.wallet__activity_explore),
@@ -476,7 +493,9 @@ private fun ActivityDetailContent(
modifier = Modifier.size(16.dp)
)
},
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ActivityTxDetails")
)
}
}
@@ -496,18 +515,27 @@ private fun StatusSection(item: Activity) {
is Activity.Lightning -> {
when (item.v1.status) {
PaymentState.PENDING -> {
- StatusIcon(painterResource(R.drawable.ic_hourglass_simple), Colors.Purple)
- StatusText(stringResource(R.string.wallet__activity_pending), Colors.Purple)
+ StatusRow(
+ painterResource(R.drawable.ic_hourglass_simple),
+ stringResource(R.string.wallet__activity_pending),
+ Colors.Purple,
+ )
}
PaymentState.SUCCEEDED -> {
- StatusIcon(painterResource(R.drawable.ic_lightning_alt), Colors.Purple)
- StatusText(stringResource(R.string.wallet__activity_successful), Colors.Purple)
+ StatusRow(
+ painterResource(R.drawable.ic_lightning_alt),
+ stringResource(R.string.wallet__activity_successful),
+ Colors.Purple,
+ )
}
PaymentState.FAILED -> {
- StatusIcon(painterResource(R.drawable.ic_x), Colors.Purple)
- StatusText(stringResource(R.string.wallet__activity_failed), Colors.Purple)
+ StatusRow(
+ painterResource(R.drawable.ic_x),
+ stringResource(R.string.wallet__activity_failed),
+ Colors.Purple,
+ )
}
}
}
@@ -517,19 +545,27 @@ private fun StatusSection(item: Activity) {
var statusIcon = painterResource(R.drawable.ic_hourglass_simple)
var statusColor = Colors.Brand
var statusText = stringResource(R.string.wallet__activity_confirming)
+ var statusTestTag: String? = null
- // TODO: handle isTransfer
+ if (item.v1.isTransfer) {
+ val duration = 0 // TODO get transfer duration
+ statusText = stringResource(R.string.wallet__activity_transfer_pending)
+ .replace("{duration}", "$duration")
+ statusTestTag = "StatusTransfer"
+ }
if (item.v1.isBoosted) {
statusIcon = painterResource(R.drawable.ic_timer_alt)
statusColor = Colors.Yellow
statusText = stringResource(R.string.wallet__activity_boosting)
+ statusTestTag = "StatusBoosting"
}
if (item.v1.confirmed) {
statusIcon = painterResource(R.drawable.ic_check_circle)
statusColor = Colors.Green
statusText = stringResource(R.string.wallet__activity_confirmed)
+ statusTestTag = "StatusConfirmed"
}
if (!item.v1.doesExist) {
@@ -538,8 +574,7 @@ private fun StatusSection(item: Activity) {
statusText = stringResource(R.string.wallet__activity_removed)
}
- StatusIcon(statusIcon, statusColor)
- StatusText(statusText, statusColor)
+ StatusRow(statusIcon, statusText, statusColor, statusTestTag)
}
}
}
@@ -547,28 +582,27 @@ private fun StatusSection(item: Activity) {
}
@Composable
-private fun StatusIcon(
+private fun StatusRow(
icon: Painter,
- tint: Color,
-) {
- Icon(
- painter = icon,
- contentDescription = null,
- tint = tint,
- modifier = Modifier.size(16.dp)
- )
-}
-
-@Composable
-private fun StatusText(
text: String,
color: Color,
+ testTag: String? = null,
) {
- BodySSB(
- text = text,
- color = color,
- modifier = Modifier.padding(start = 4.dp)
- )
+ Row {
+ Icon(
+ painter = icon,
+ contentDescription = null,
+ tint = color,
+ modifier = Modifier.size(16.dp)
+ )
+ BodySSB(
+ text = text,
+ color = color,
+ modifier = Modifier
+ .padding(start = 4.dp)
+ .then(testTag?.let { Modifier.testTag(it) } ?: Modifier)
+ )
+ }
}
@Composable
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityExploreScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityExploreScreen.kt
index 991fbf5be..8eefa7c23 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityExploreScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/ActivityExploreScreen.kt
@@ -22,6 +22,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -35,7 +36,11 @@ import com.synonym.bitkitcore.OnchainActivity
import com.synonym.bitkitcore.PaymentState
import com.synonym.bitkitcore.PaymentType
import to.bitkit.R
+import to.bitkit.ext.BoostType
+import to.bitkit.ext.boostType
import to.bitkit.ext.ellipsisMiddle
+import to.bitkit.ext.isBoosted
+import to.bitkit.ext.isSent
import to.bitkit.ext.rawId
import to.bitkit.ext.totalValue
import to.bitkit.models.Toast
@@ -69,8 +74,7 @@ fun ActivityExploreScreen(
onCloseClick: () -> Unit,
) {
val activities by listViewModel.filteredActivities.collectAsStateWithLifecycle()
- val item = activities?.find { it.rawId() == route.id }
- ?: return
+ val item = activities?.find { it.rawId() == route.id } ?: return
val app = appViewModel ?: return
val context = LocalContext.current
@@ -112,6 +116,13 @@ fun ActivityExploreScreen(
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
context.startActivity(intent)
},
+ onClickParent = { id ->
+ app.toast(
+ type = Toast.ToastType.WARNING,
+ title = "TODO",
+ description = "Navigate to Activity Detail for: $id",
+ )
+ },
)
}
}
@@ -122,6 +133,7 @@ private fun ActivityExploreContent(
txDetails: TxDetails? = null,
onCopy: (String) -> Unit = {},
onClickExplore: (String) -> Unit = {},
+ onClickParent: (String) -> Unit = {},
) {
Column(
modifier = Modifier
@@ -129,21 +141,15 @@ private fun ActivityExploreContent(
.padding(16.dp)
.verticalScroll(rememberScrollState())
) {
- // Header
Row(
verticalAlignment = Alignment.Bottom,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp)
) {
- val isSent = when (item) {
- is Activity.Lightning -> item.v1.txType == PaymentType.SENT
- is Activity.Onchain -> item.v1.txType == PaymentType.SENT
- }
- val amountPrefix = if (isSent) "-" else "+"
BalanceHeaderView(
sats = item.totalValue().toLong(),
- prefix = amountPrefix,
+ prefix = if (item.isSent()) "-" else "+",
showBitcoinSymbol = false,
modifier = Modifier.weight(1f),
)
@@ -154,7 +160,12 @@ private fun ActivityExploreContent(
when (item) {
is Activity.Onchain -> {
- OnchainDetails(onchain = item, onCopy = onCopy, txDetails = txDetails)
+ OnchainDetails(
+ onchain = item,
+ onCopy = onCopy,
+ txDetails = txDetails,
+ onClickParent = onClickParent,
+ )
Spacer(modifier = Modifier.weight(1f))
PrimaryButton(
text = stringResource(R.string.wallet__activity_explorer),
@@ -215,16 +226,19 @@ private fun ColumnScope.OnchainDetails(
onchain: Activity.Onchain,
onCopy: (String) -> Unit,
txDetails: TxDetails?,
+ onClickParent: (String) -> Unit,
) {
val txId = onchain.v1.txId
Section(
title = stringResource(R.string.wallet__activity_tx_id),
value = txId,
- modifier = Modifier.clickableAlpha(
- onClick = copyToClipboard(txId) {
- onCopy(txId)
- }
- ),
+ modifier = Modifier
+ .clickableAlpha(
+ onClick = copyToClipboard(txId) {
+ onCopy(txId)
+ }
+ )
+ .testTag("TXID")
)
if (txDetails != null) {
Section(
@@ -253,12 +267,34 @@ private fun ColumnScope.OnchainDetails(
CircularProgressIndicator(
strokeWidth = 2.dp,
modifier = Modifier
- .size(16.dp)
.padding(vertical = 16.dp)
- .align(Alignment.CenterHorizontally),
+ .size(16.dp)
+ .align(Alignment.CenterHorizontally)
+ )
+ } // TODO use real boosted parents from bitkit-core/ldk-node when available
+ val boostedParents = listOfNotNull(
+ "todo_first_parent_txid".takeIf { onchain.isBoosted() && !onchain.v1.confirmed },
+ "todo_second_parent_txid".takeIf { onchain.isBoosted() && onchain.v1.confirmed },
+ )
+
+ boostedParents.forEachIndexed { index, parent ->
+ val isRbf = onchain.boostType() == BoostType.RBF
+ Section(
+ title = stringResource(
+ if (isRbf) R.string.wallet__activity_boosted_rbf else R.string.wallet__activity_boosted_cpfp
+ ).replace("{num}", "${index + 1}"),
+ valueContent = {
+ Column {
+ BodySSB(text = parent, maxLines = 1, overflow = TextOverflow.MiddleEllipsis)
+ }
+ },
+ modifier = Modifier
+ .clickableAlpha {
+ onClickParent(parent)
+ }
+ .testTag(if (isRbf) "RBFBoosted" else "CPFPBoosted")
)
}
- // TODO add boosted parents info if boosted
}
@Composable
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/AllActivityScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/AllActivityScreen.kt
index 1df711994..2c4c6d685 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/AllActivityScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/AllActivityScreen.kt
@@ -26,6 +26,7 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -168,6 +169,7 @@ private fun AllActivityScreenContent(
onTabChange = onTabChange,
)
.padding(horizontal = 16.dp)
+ .testTag("ActivityList")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/DateRangeSelectorSheet.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/DateRangeSelectorSheet.kt
index 9ec46b725..72b41f612 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/DateRangeSelectorSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/DateRangeSelectorSheet.kt
@@ -18,6 +18,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -103,13 +104,17 @@ private fun Content(
onClick = onClearClick,
text = stringResource(R.string.wallet__filter_clear),
enabled = hasSelection,
- modifier = Modifier.weight(1f),
+ modifier = Modifier
+ .weight(1f)
+ .testTag("CalendarClearButton")
)
PrimaryButton(
onClick = onApplyClick,
text = stringResource(R.string.wallet__filter_apply),
enabled = hasSelection,
- modifier = Modifier.weight(1f),
+ modifier = Modifier
+ .weight(1f)
+ .testTag("CalendarApplyButton")
)
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityAddTagSheet.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityAddTagSheet.kt
index bb64e8a20..e8cadb708 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityAddTagSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityAddTagSheet.kt
@@ -62,6 +62,8 @@ fun ActivityAddTagSheet(
onInputUpdated = { newText -> tagsViewModel.onInputUpdated(newText) },
onBack = onDismiss,
focusOnShow = true,
+ tagInputTestTag = "TagInput",
+ addButtonTestTag = "ActivityTagsSubmit",
modifier = Modifier
.sheetHeight(SheetSize.SMALL, isModal = true)
.gradientBackground()
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityIcon.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityIcon.kt
index b7b699a98..dc8fb6d48 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityIcon.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityIcon.kt
@@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
@@ -25,6 +26,7 @@ import com.synonym.bitkitcore.PaymentType
import to.bitkit.R
import to.bitkit.ext.isBoosted
import to.bitkit.ext.isFinished
+import to.bitkit.ext.isTransfer
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
@@ -52,7 +54,7 @@ fun ActivityIcon(
iconColor = Colors.Yellow,
backgroundColor = Colors.Yellow16,
size = size,
- modifier = modifier,
+ modifier = modifier.testTag("BoostingIcon"),
)
}
@@ -91,15 +93,12 @@ fun ActivityIcon(
}
else -> {
- val isTransfer = (activity as? Activity.Onchain)?.v1?.isTransfer == true
- val onChainIcon = if (isTransfer) painterResource(R.drawable.ic_transfer) else arrowIcon
-
CircularIcon(
- icon = onChainIcon,
+ icon = if (activity.isTransfer()) painterResource(R.drawable.ic_transfer) else arrowIcon,
iconColor = Colors.Brand,
backgroundColor = Colors.Brand16,
size = size,
- modifier = modifier,
+ modifier = modifier.testTag(if (activity.isTransfer()) "TransferIcon" else "ActivityIcon"),
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListFilter.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListFilter.kt
index fb17de7d0..a126746fa 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListFilter.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListFilter.kt
@@ -6,13 +6,17 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
+import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
+import androidx.compose.material3.TabRowDefaults
+import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -20,6 +24,7 @@ import to.bitkit.R
import to.bitkit.ui.components.SearchInput
import to.bitkit.ui.components.SearchInputIconButton
import to.bitkit.ui.theme.AppThemeSurface
+import to.bitkit.ui.theme.Colors
@Composable
fun ActivityListFilter(
@@ -48,7 +53,8 @@ fun ActivityListFilter(
onClick = {
focusManager.clearFocus()
onTagClick()
- }
+ },
+ modifier = Modifier.testTag("TagsPrompt")
)
Spacer(modifier = Modifier.width(12.dp))
SearchInputIconButton(
@@ -57,7 +63,8 @@ fun ActivityListFilter(
onClick = {
focusManager.clearFocus()
onDateRangeClick()
- }
+ },
+ modifier = Modifier.testTag("DatePicker")
)
}
)
@@ -68,12 +75,26 @@ fun ActivityListFilter(
TabRow(
selectedTabIndex = currentTabIndex,
containerColor = Color.Transparent,
+ indicator = { tabPositions ->
+ if (currentTabIndex < tabPositions.size) {
+ TabRowDefaults.SecondaryIndicator(
+ color = Colors.Brand,
+ modifier = Modifier.tabIndicatorOffset(tabPositions[currentTabIndex])
+ )
+ }
+ },
+ divider = {
+ HorizontalDivider(thickness = 3.0.dp)
+ }
) {
tabs.map { tab ->
Tab(
text = { Text(tab.uiText) },
selected = tabs[currentTabIndex] == tab,
onClick = { onTabChange(tab) },
+ unselectedContentColor = Colors.White64,
+ modifier = Modifier
+ .testTag("Tab-${tab.name.lowercase()}")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListGrouped.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListGrouped.kt
index 8bf00150b..1d928668e 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListGrouped.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListGrouped.kt
@@ -67,7 +67,7 @@ fun ActivityListGrouped(
}
is Activity -> {
- ActivityRow(item, onActivityItemClick)
+ ActivityRow(item, onActivityItemClick, testTag = "Activity-$index")
val hasNextItem =
index < groupedItems.size - 1 && groupedItems[index + 1] !is String
if (hasNextItem) {
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListSimple.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListSimple.kt
index eec90568e..0d62e704b 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListSimple.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityListSimple.kt
@@ -8,6 +8,7 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -29,8 +30,8 @@ fun ActivityListSimple(
modifier = Modifier.fillMaxWidth()
) {
if (items != null && items.isNotEmpty()) {
- items.forEach { item ->
- ActivityRow(item, onActivityItemClick)
+ items.forEachIndexed { index, item ->
+ ActivityRow(item, onActivityItemClick, testTag = "ActivityShort-$index")
HorizontalDivider()
}
TertiaryButton(
@@ -39,6 +40,7 @@ fun ActivityListSimple(
modifier = Modifier
.wrapContentWidth()
.padding(top = 8.dp)
+ .testTag("ActivityShowAll")
)
} else {
EmptyActivityRow(onClick = onEmptyActivityRowClick)
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityRow.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityRow.kt
index 8ede434d1..c9ac35163 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityRow.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/activity/components/ActivityRow.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalInspectionMode
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -25,6 +26,8 @@ import com.synonym.bitkitcore.PaymentType
import to.bitkit.R
import to.bitkit.ext.DatePattern
import to.bitkit.ext.formatted
+import to.bitkit.ext.isSent
+import to.bitkit.ext.isTransfer
import to.bitkit.ext.rawId
import to.bitkit.ext.totalValue
import to.bitkit.models.PrimaryDisplay
@@ -48,6 +51,7 @@ import java.time.ZoneId
fun ActivityRow(
item: Activity,
onClick: (String) -> Unit,
+ testTag: String,
) {
val status: PaymentState? = when (item) {
is Activity.Lightning -> item.v1.status
@@ -62,16 +66,13 @@ fun ActivityRow(
is Activity.Lightning -> item.v1.txType
is Activity.Onchain -> item.v1.txType
}
- val isSent = txType == PaymentType.SENT
+ val isSent = item.isSent()
val amountPrefix = if (isSent) "-" else "+"
val confirmed: Boolean? = when (item) {
is Activity.Lightning -> null
is Activity.Onchain -> item.v1.confirmed
}
- val isTransfer = when (item) {
- is Activity.Lightning -> false
- is Activity.Onchain -> item.v1.isTransfer
- }
+ val isTransfer = item.isTransfer()
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -79,6 +80,7 @@ fun ActivityRow(
.fillMaxWidth()
.clickableAlpha { onClick(item.rawId()) }
.padding(vertical = 16.dp)
+ .testTag(testTag)
) {
ActivityIcon(activity = item, size = 32.dp)
Spacer(modifier = Modifier.width(16.dp))
@@ -306,6 +308,7 @@ private fun Preview(@PreviewParameter(ActivityItemsPreviewProvider::class) item:
ActivityRow(
item = item,
onClick = {},
+ testTag = "Activity-",
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/EditInvoiceScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/EditInvoiceScreen.kt
index e7b16cc0a..445b12c78 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/EditInvoiceScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/EditInvoiceScreen.kt
@@ -217,7 +217,7 @@ fun EditInvoiceContent(
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
- .testTag("edit_invoice_content")
+ .testTag("ReceiveAmount")
) {
Spacer(Modifier.height(32.dp))
@@ -228,7 +228,7 @@ fun EditInvoiceContent(
modifier = Modifier
.fillMaxWidth()
.clickableAlpha(onClick = onClickBalance)
- .testTag("amount_input_field")
+ .testTag("ReceiveNumberPadTextField")
)
// Animated visibility for keyboard section
@@ -244,7 +244,7 @@ fun EditInvoiceContent(
) + fadeOut()
) {
Column(
- modifier = Modifier.testTag("keyboard_section")
+ modifier = Modifier.testTag("ReceiveNumberPad")
) {
Spacer(modifier = Modifier.weight(1f))
@@ -253,7 +253,11 @@ fun EditInvoiceContent(
horizontalArrangement = Arrangement.End,
modifier = Modifier.fillMaxWidth()
) {
- UnitButton(modifier = Modifier.height(28.dp))
+ UnitButton(
+ modifier = Modifier
+ .height(28.dp)
+ .testTag("ReceiveNumberPadUnit")
+ )
}
HorizontalDivider(modifier = Modifier.padding(top = 24.dp))
@@ -269,7 +273,7 @@ fun EditInvoiceContent(
availableHeight = maxHeight,
modifier = Modifier
.fillMaxWidth()
- .testTag("amount_keyboard"),
+ .testTag("amount_keyboard")
)
Spacer(
@@ -281,7 +285,7 @@ fun EditInvoiceContent(
PrimaryButton(
text = stringResource(R.string.common__continue),
onClick = onContinueKeyboard,
- modifier = Modifier.testTag("keyboard_continue_button")
+ modifier = Modifier.testTag("ReceiveNumberPadSubmit")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -294,9 +298,7 @@ fun EditInvoiceContent(
enter = fadeIn(animationSpec = tween(durationMillis = 300)),
exit = fadeOut(animationSpec = tween(durationMillis = 300))
) {
- Column(
- modifier = Modifier.testTag("note_section")
- ) {
+ Column {
Spacer(modifier = Modifier.height(44.dp))
Caption13Up(text = stringResource(R.string.wallet__note), color = Colors.White64)
@@ -320,8 +322,7 @@ fun EditInvoiceContent(
shape = MaterialTheme.shapes.medium,
modifier = Modifier
.fillMaxWidth()
- .testTag("note_input_field")
-
+ .testTag("ReceiveNote")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -354,7 +355,8 @@ fun EditInvoiceContent(
tint = Colors.Brand
)
},
- fullWidth = false
+ fullWidth = false,
+ modifier = Modifier.testTag("TagsAdd")
)
Spacer(modifier = Modifier.weight(1f))
@@ -362,7 +364,7 @@ fun EditInvoiceContent(
PrimaryButton(
text = stringResource(R.string.wallet__receive_show_qr),
onClick = onContinueGeneral,
- modifier = Modifier.testTag("general_continue_button")
+ modifier = Modifier.testTag("ShowQrReceive")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveAmountScreen.kt
index 7ccabdaa5..d17e6b1ec 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveAmountScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveAmountScreen.kt
@@ -22,6 +22,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -105,13 +106,14 @@ fun ReceiveAmountScreen(
Caption13Up(
text = stringResource(R.string.wallet__minimum),
color = Colors.White64,
+ modifier = Modifier.testTag("ReceiveAmountMinimum")
)
Spacer(modifier = Modifier.height(8.dp))
MoneySSB(sats = minCjitSats.toLong())
}
} ?: CircularProgressIndicator(modifier = Modifier.size(18.dp))
Spacer(modifier = Modifier.weight(1f))
- UnitButton()
+ UnitButton(modifier = Modifier.testTag("ReceiveNumberPadUnit"))
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveLiquidityScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveLiquidityScreen.kt
index 80cfbc0f3..7f9cfe3e0 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveLiquidityScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveLiquidityScreen.kt
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -86,6 +87,7 @@ fun ReceiveLiquidityScreen(
PrimaryButton(
text = stringResource(R.string.common__understood),
onClick = onContinue,
+ modifier = Modifier.testTag("LiquidityContinue")
)
Spacer(modifier = Modifier.height(32.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt
index 6f1b5b89f..980ecb833 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveQrScreen.kt
@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
@@ -36,12 +37,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Devices.NEXUS_5
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import com.google.accompanist.pager.HorizontalPagerIndicator
import kotlinx.coroutines.launch
import to.bitkit.R
import to.bitkit.ext.setClipboardText
@@ -53,7 +56,6 @@ import to.bitkit.ui.components.BottomSheetPreview
import to.bitkit.ui.components.ButtonSize
import to.bitkit.ui.components.Caption13Up
import to.bitkit.ui.components.Headline
-import to.bitkit.ui.components.PagerWithIndicator
import to.bitkit.ui.components.PrimaryButton
import to.bitkit.ui.components.QrCodeImage
import to.bitkit.ui.components.Tooltip
@@ -87,15 +89,21 @@ fun ReceiveQrScreen(
val originalBrightness = window?.attributes?.screenBrightness
val originalFlags = window?.attributes?.flags
- window?.attributes = window.attributes.apply {
- screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
- flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ window?.let { win ->
+ win.attributes?.let { attrs ->
+ attrs.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
+ attrs.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ win.attributes = attrs
+ }
}
onDispose {
- window?.attributes = window.attributes.apply {
- originalBrightness?.let { screenBrightness = originalBrightness }
- originalFlags?.let { flags = originalFlags }
+ window?.let { win ->
+ win.attributes?.let { attrs ->
+ if (originalBrightness != null) attrs.screenBrightness = originalBrightness
+ if (originalFlags != null) attrs.flags = originalFlags
+ win.attributes = attrs
+ }
}
}
}
@@ -128,7 +136,14 @@ fun ReceiveQrScreen(
modifier = Modifier.weight(1f)
) {
val pagerState = rememberPagerState(initialPage = 0) { 2 }
- PagerWithIndicator(pagerState) {
+ HorizontalPager(
+ state = pagerState,
+ pageSpacing = 20.dp,
+ verticalAlignment = Alignment.Top,
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ReceiveSlider")
+ ) {
when (it) {
0 -> ReceiveQrSlide(
uri = uri,
@@ -145,6 +160,17 @@ fun ReceiveQrScreen(
)
}
}
+ @Suppress("DEPRECATION")
+ HorizontalPagerIndicator(
+ pagerState = pagerState,
+ pageCount = pagerState.pageCount,
+ indicatorWidth = 8.dp,
+ spacing = 8.dp,
+ activeColor = Colors.White,
+ inactiveColor = Colors.White32,
+ modifier = Modifier
+ .align(Alignment.CenterHorizontally)
+ )
}
Spacer(modifier = Modifier.height(24.dp))
AnimatedVisibility(walletState.nodeLifecycleState.isRunning() && walletState.channels.isEmpty()) {
@@ -180,6 +206,7 @@ fun ReceiveQrScreen(
checked = walletState.receiveOnSpendingBalance,
onCheckedChange = { onClickReceiveOnSpending() },
colors = AppSwitchDefaults.colorsPurple,
+ modifier = Modifier.testTag("ReceiveInstantlySwitch")
)
}
}
@@ -250,6 +277,7 @@ private fun ReceiveQrSlide(
logoPainter = qrLogoPainter,
tipMessage = stringResource(R.string.wallet__receive_copied),
modifier = Modifier.weight(1f, fill = false),
+ testTag = "QRCode",
onBitmapGenerated = { bitmap ->
qrBitmap = bitmap
}
@@ -273,7 +301,8 @@ private fun ReceiveQrSlide(
tint = Colors.Brand,
modifier = Modifier.size(18.dp)
)
- }
+ },
+ modifier = Modifier.testTag("SpecifyInvoiceButton")
)
Tooltip(
text = stringResource(R.string.wallet__receive_copied),
@@ -295,7 +324,8 @@ private fun ReceiveQrSlide(
tint = Colors.Brand,
modifier = Modifier.size(18.dp)
)
- }
+ },
+ modifier = Modifier.testTag("ReceiveCopyQR")
)
}
PrimaryButton(
@@ -315,7 +345,7 @@ private fun ReceiveQrSlide(
tint = Colors.Brand,
modifier = Modifier.size(18.dp)
)
- }
+ },
)
}
Spacer(modifier = Modifier.height(16.dp))
@@ -339,6 +369,7 @@ private fun CopyValuesSlide(
title = stringResource(R.string.wallet__receive_bitcoin_invoice),
address = onchainAddress,
type = CopyAddressType.ONCHAIN,
+ testTag = "ReceiveOnchainAddress",
)
}
if (bolt11.isNotEmpty() && receiveOnSpendingBalance) {
@@ -346,12 +377,14 @@ private fun CopyValuesSlide(
title = stringResource(R.string.wallet__receive_lightning_invoice),
address = bolt11,
type = CopyAddressType.LIGHTNING,
+ testTag = "ReceiveLightningAddress",
)
} else if (cjitInvoice != null) {
CopyAddressCard(
title = stringResource(R.string.wallet__receive_lightning_invoice),
address = cjitInvoice,
type = CopyAddressType.LIGHTNING,
+ testTag = "ReceiveLightningAddress",
)
}
}
@@ -366,6 +399,7 @@ private fun CopyAddressCard(
title: String,
address: String,
type: CopyAddressType,
+ testTag: String? = null,
) {
val context = LocalContext.current
@@ -386,7 +420,10 @@ private fun CopyAddressCard(
Icon(painter = painterResource(iconRes), contentDescription = null, tint = Colors.White64)
}
Spacer(modifier = Modifier.height(16.dp))
- BodyS(text = address.truncate(32).uppercase())
+ BodyS(
+ text = address.truncate(32).uppercase(),
+ modifier = testTag?.let { Modifier.testTag(it) } ?: Modifier
+ )
Spacer(modifier = Modifier.height(16.dp))
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
@@ -411,7 +448,7 @@ private fun CopyAddressCard(
tint = if (type == CopyAddressType.ONCHAIN) Colors.Brand else Colors.Purple,
modifier = Modifier.size(18.dp)
)
- }
+ },
)
}
PrimaryButton(
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveSheet.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveSheet.kt
index 1d3a9ce5a..db8e98188 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/receive/ReceiveSheet.kt
@@ -9,6 +9,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
@@ -54,6 +55,7 @@ fun ReceiveSheet(
.fillMaxWidth()
.sheetHeight()
.imePadding()
+ .testTag("ReceiveScreen")
) {
NavHost(
navController = navController,
@@ -194,7 +196,9 @@ fun ReceiveSheet(
onTagSelected = { tag ->
wallet.addTagToSelected(tag)
navController.popBackStack()
- }
+ },
+ tqgInputTestTag = "TagInputReceive",
+ addButtonTestTag = "ReceiveTagsSubmit",
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/AddTagScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/AddTagScreen.kt
index ab651dbc4..719039b16 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/AddTagScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/AddTagScreen.kt
@@ -17,6 +17,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
@@ -36,15 +37,17 @@ import to.bitkit.ui.shared.modifiers.sheetHeight
import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
-import to.bitkit.ui.theme.ScreenTransitionMs
+import to.bitkit.ui.theme.TRANSITION_SCREEN_MS
import to.bitkit.viewmodels.AddTagUiState
import to.bitkit.viewmodels.TagsViewModel
@Composable
fun AddTagScreen(
- viewModel: TagsViewModel = hiltViewModel(),
onBack: () -> Unit,
onTagSelected: (String) -> Unit,
+ tqgInputTestTag: String,
+ addButtonTestTag: String? = null,
+ viewModel: TagsViewModel = hiltViewModel(),
) {
val uiState: AddTagUiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -58,6 +61,8 @@ fun AddTagScreen(
onTagConfirmed = { tag -> onTagSelected(tag) },
onInputUpdated = { newText -> viewModel.onInputUpdated(newText) },
onBack = onBack,
+ tagInputTestTag = tqgInputTestTag,
+ addButtonTestTag = addButtonTestTag,
)
}
@@ -70,11 +75,13 @@ fun AddTagContent(
onBack: () -> Unit,
modifier: Modifier = Modifier,
focusOnShow: Boolean = false,
+ tagInputTestTag: String? = null,
+ addButtonTestTag: String? = null,
) {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(focusOnShow) {
if (focusOnShow) {
- delay(ScreenTransitionMs)
+ delay(TRANSITION_SCREEN_MS)
focusRequester.requestFocus()
}
}
@@ -125,6 +132,7 @@ fun AddTagContent(
modifier = Modifier
.focusRequester(focusRequester)
.fillMaxWidth()
+ .then(tagInputTestTag?.let { Modifier.testTag(it) } ?: Modifier)
)
Spacer(modifier = Modifier.height(16.dp))
@@ -133,6 +141,8 @@ fun AddTagContent(
text = stringResource(R.string.wallet__tags_add_button),
onClick = { onTagConfirmed(uiState.tagInput) },
enabled = uiState.tagInput.isNotBlank(),
+ modifier = Modifier
+ .then(addButtonTestTag?.let { Modifier.testTag(it) } ?: Modifier)
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAddressScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAddressScreen.kt
index 5d475583b..7437cdc94 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAddressScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAddressScreen.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -29,7 +30,7 @@ import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppTextStyles
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
-import to.bitkit.ui.theme.ScreenTransitionMs
+import to.bitkit.ui.theme.TRANSITION_SCREEN_MS
import to.bitkit.viewmodels.SendEvent
import to.bitkit.viewmodels.SendUiState
@@ -42,7 +43,7 @@ fun SendAddressScreen(
) {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
- delay(ScreenTransitionMs)
+ delay(TRANSITION_SCREEN_MS)
focusRequester.requestFocus()
}
Column(
@@ -59,7 +60,10 @@ fun SendAddressScreen(
modifier = Modifier.padding(horizontal = 16.dp)
) {
VerticalSpacer(16.dp)
- Caption13Up(stringResource(R.string.wallet__send_to), color = Colors.White64)
+ Caption13Up(
+ stringResource(R.string.wallet__send_to),
+ color = Colors.White64,
+ )
VerticalSpacer(8.dp)
TextInput(
placeholder = stringResource(R.string.wallet__send_address_placeholder),
@@ -71,12 +75,14 @@ fun SendAddressScreen(
.fillMaxWidth()
.focusRequester(focusRequester)
.weight(1f)
+ .testTag("RecipientInput")
)
VerticalSpacer(16.dp)
PrimaryButton(
text = stringResource(R.string.common__continue),
enabled = uiState.isAddressInputValid,
onClick = { onEvent(SendEvent.AddressContinue(uiState.addressInput)) },
+ modifier = Modifier.testTag("AddressContinue")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt
index 758a31c64..3de678222 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt
@@ -18,6 +18,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Devices.NEXUS_5
@@ -32,8 +33,10 @@ import to.bitkit.models.BalanceState
import to.bitkit.models.BitcoinDisplayUnit
import to.bitkit.models.NodeLifecycleState
import to.bitkit.models.PrimaryDisplay
+import to.bitkit.models.Toast
import to.bitkit.ui.LocalBalances
import to.bitkit.ui.LocalCurrencies
+import to.bitkit.ui.appViewModel
import to.bitkit.ui.components.AmountInputHandler
import to.bitkit.ui.components.BottomSheetPreview
import to.bitkit.ui.components.FillHeight
@@ -51,6 +54,7 @@ import to.bitkit.ui.components.VerticalSpacer
import to.bitkit.ui.currencyViewModel
import to.bitkit.ui.scaffold.SheetTopBar
import to.bitkit.ui.shared.modifiers.sheetHeight
+import to.bitkit.ui.shared.util.clickableAlpha
import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
@@ -70,6 +74,8 @@ fun SendAmountScreen(
onEvent: (SendEvent) -> Unit,
) {
val currencyVM = currencyViewModel ?: return
+ val app = appViewModel
+ val context = LocalContext.current
var input: String by remember { mutableStateOf(uiState.amountInput) }
var overrideSats: Long? by remember { mutableStateOf(null) }
@@ -96,7 +102,16 @@ fun SendAmountScreen(
onInputChanged = { input = it },
onEvent = onEvent,
onBack = onBack,
- onClickMax = { maxSats -> overrideSats = maxSats },
+ onClickMax = { maxSats ->
+ if (uiState.payMethod == SendMethod.LIGHTNING && uiState.lnurl == null) {
+ app?.toast(
+ type = Toast.ToastType.WARNING,
+ title = context.getString(R.string.wallet__send_max_spending__title),
+ description = context.getString(R.string.wallet__send_max_spending__description)
+ )
+ }
+ overrideSats = maxSats
+ },
)
}
@@ -144,7 +159,7 @@ fun SendAmountContent(
displayUnit = displayUnit,
primaryDisplay = primaryDisplay,
onEvent = onEvent,
- onMaxClick = onClickMax,
+ onClickMax = onClickMax,
)
}
@@ -170,7 +185,7 @@ private fun SendAmountNodeRunning(
currencyUiState: CurrencyUiState,
onInputChanged: (String) -> Unit,
onEvent: (SendEvent) -> Unit,
- onMaxClick: (Long) -> Unit,
+ onClickMax: (Long) -> Unit,
) {
BoxWithConstraints {
val maxHeight = this.maxHeight
@@ -193,7 +208,7 @@ private fun SendAmountNodeRunning(
primaryDisplay = primaryDisplay,
modifier = Modifier
.fillMaxWidth()
- .testTag("amount_input_field")
+ .testTag("SendNumberField")
)
FillHeight(min = 12.dp)
@@ -206,18 +221,25 @@ private fun SendAmountNodeRunning(
else -> R.string.wallet__send_available
}
- Text13Up(
- text = stringResource(textAvailable),
- color = Colors.White64,
- modifier = Modifier.testTag("available_balance")
- )
- VerticalSpacer(4.dp)
-
Row(
- verticalAlignment = Alignment.CenterVertically,
+ verticalAlignment = Alignment.Bottom,
) {
- // TODO add onClick -> override to max amount
- MoneySSB(sats = availableAmount)
+ Column(
+ modifier = Modifier
+ .clickableAlpha {
+ // TODO port the RN sendMax logic
+ onClickMax(availableAmount)
+ }
+ .testTag("AvailableAmount")
+ ) {
+ Text13Up(
+ text = stringResource(textAvailable),
+ color = Colors.White64,
+ modifier = Modifier.testTag("available_balance")
+ )
+ VerticalSpacer(4.dp)
+ MoneySSB(sats = availableAmount, showSymbol = true)
+ }
FillWidth()
@@ -232,14 +254,18 @@ private fun SendAmountNodeRunning(
)
NumberPadActionButton(
text = stringResource(R.string.common__max),
- onClick = { onMaxClick(max) },
+ onClick = { onClickMax(max) },
modifier = Modifier
.height(28.dp)
.testTag("max_amount_button")
)
}
HorizontalSpacer(8.dp)
- UnitButton(modifier = Modifier.height(28.dp))
+ UnitButton(
+ modifier = Modifier
+ .height(28.dp)
+ .testTag("SendNumberPadUnit")
+ )
}
HorizontalDivider(modifier = Modifier.padding(top = 24.dp))
@@ -255,7 +281,7 @@ private fun SendAmountNodeRunning(
availableHeight = maxHeight,
modifier = Modifier
.fillMaxWidth()
- .testTag("amount_keyboard"),
+ .testTag("SendAmountNumberPad")
)
Spacer(
@@ -268,7 +294,7 @@ private fun SendAmountNodeRunning(
text = stringResource(R.string.common__continue),
enabled = uiState.isAmountInputValid,
onClick = { onEvent(SendEvent.AmountContinue(uiState.amountInput)) },
- modifier = Modifier.testTag("continue_button")
+ modifier = Modifier.testTag("ContinueAmount")
)
VerticalSpacer(16.dp)
@@ -281,6 +307,11 @@ private fun PaymentMethodButton(
uiState: SendUiState,
onEvent: (SendEvent) -> Unit,
) {
+ val testId = when {
+ uiState.isUnified -> "switch"
+ uiState.payMethod == SendMethod.ONCHAIN -> "savings"
+ else -> "spending"
+ }
NumberPadActionButton(
text = when (uiState.payMethod) {
SendMethod.ONCHAIN -> stringResource(R.string.wallet__savings__title)
@@ -295,7 +326,7 @@ private fun PaymentMethodButton(
enabled = uiState.isUnified,
modifier = Modifier
.height(28.dp)
- .testTag("payment_method_button")
+ .testTag("AssetButton-$testId")
)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendConfirmScreen.kt
index 27f535af8..664a299ed 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendConfirmScreen.kt
@@ -29,6 +29,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
@@ -191,13 +192,20 @@ private fun Content(
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
- BalanceHeaderView(sats = uiState.amount.toLong(), modifier = Modifier.fillMaxWidth())
+ BalanceHeaderView(
+ sats = uiState.amount.toLong(),
+ useSwipeToHide = false,
+ onClick = { onEvent(SendEvent.BackToAmount) },
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("ReviewAmount")
+ )
Spacer(modifier = Modifier.height(16.dp))
when (uiState.payMethod) {
SendMethod.ONCHAIN -> OnChainDescription(uiState = uiState, onEvent = onEvent)
- SendMethod.LIGHTNING -> LightningDescription(uiState = uiState)
+ SendMethod.LIGHTNING -> LightningDescription(uiState = uiState, onEvent = onEvent)
}
if (isLnurlPay) {
@@ -239,6 +247,7 @@ private fun Content(
onEvent(SendEvent.DismissAmountWarning)
onBack()
},
+ modifier = Modifier.testTag(dialog.testTag),
)
}
}
@@ -259,7 +268,7 @@ private fun LnurlCommentSection(
onValueChange = { onEvent(SendEvent.CommentChange(it)) },
minLines = 3,
maxLines = 3,
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier.fillMaxWidth().testTag("CommentInput")
)
}
@@ -299,6 +308,7 @@ private fun TagsSection(
)
},
fullWidth = false,
+ modifier = Modifier.testTag("TagsAddSend")
)
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
}
@@ -312,7 +322,14 @@ private fun OnChainDescription(
Column(modifier = Modifier.fillMaxWidth()) {
Caption13Up(text = stringResource(R.string.wallet__send_to), color = Colors.White64)
Spacer(modifier = Modifier.height(8.dp))
- BodySSB(text = uiState.address, maxLines = 1, overflow = TextOverflow.MiddleEllipsis)
+ BodySSB(
+ text = uiState.address,
+ maxLines = 1,
+ overflow = TextOverflow.MiddleEllipsis,
+ modifier = Modifier
+ .clickableAlpha { onEvent(SendEvent.NavToAddress) }
+ .testTag("ReviewUri")
+ )
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
Row(
@@ -400,6 +417,7 @@ private fun OnChainDescription(
@Composable
private fun LightningDescription(
uiState: SendUiState,
+ onEvent: (SendEvent) -> Unit,
) {
val isLnurlPay = uiState.lnurl is LnurlParams.LnurlPay
val expirySeconds = uiState.decodedInvoice?.expirySeconds
@@ -416,7 +434,14 @@ private fun LightningDescription(
}
Spacer(modifier = Modifier.height(8.dp))
- BodySSB(text = destination, maxLines = 1, overflow = TextOverflow.MiddleEllipsis)
+ BodySSB(
+ text = destination,
+ maxLines = 1,
+ overflow = TextOverflow.MiddleEllipsis,
+ modifier = Modifier
+ .clickableAlpha { onEvent(SendEvent.NavToAddress) }
+ .testTag("ReviewUri")
+ )
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
Row(
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendErrorScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendErrorScreen.kt
index e70d35d69..9ee8437f9 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendErrorScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendErrorScreen.kt
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -82,7 +83,9 @@ private fun Content(
SecondaryButton(
text = stringResource(R.string.common__cancel),
onClick = onClose,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("Close")
)
PrimaryButton(
text = stringResource(R.string.common__try_again),
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendPinCheckScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendPinCheckScreen.kt
index c173bdf0f..c9fabeab9 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendPinCheckScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendPinCheckScreen.kt
@@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -112,7 +113,9 @@ private fun PinCheckContent(
text = stringResource(R.string.security__pin_last_attempt),
color = Colors.Brand,
textAlign = TextAlign.Center,
- modifier = Modifier.padding(horizontal = 32.dp)
+ modifier = Modifier
+ .padding(horizontal = 32.dp)
+ .testTag("LastAttempt")
)
} else {
BodyS(
@@ -123,6 +126,7 @@ private fun PinCheckContent(
modifier = Modifier
.padding(horizontal = 32.dp)
.clickableAlpha { onClickForgotPin() }
+ .testTag("AttemptsRemaining")
)
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendRecipientScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendRecipientScreen.kt
index 1e082875b..a964df902 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendRecipientScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendRecipientScreen.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -62,7 +63,7 @@ fun SendRecipientScreen(
modifier = Modifier.size(28.dp),
)
},
- modifier = Modifier.padding(bottom = 4.dp)
+ modifier = Modifier.padding(bottom = 4.dp).testTag("RecipientContact")
) {
scope.launch {
app?.toast(Exception("Coming soon: Contact"))
@@ -79,7 +80,7 @@ fun SendRecipientScreen(
modifier = Modifier.size(28.dp),
)
},
- modifier = Modifier.padding(bottom = 4.dp)
+ modifier = Modifier.padding(bottom = 4.dp).testTag("RecipientInvoice")
) {
onEvent(SendEvent.Paste)
}
@@ -94,7 +95,7 @@ fun SendRecipientScreen(
modifier = Modifier.size(28.dp),
)
},
- modifier = Modifier.padding(bottom = 4.dp)
+ modifier = Modifier.padding(bottom = 4.dp).testTag("RecipientManual")
) {
onEvent(SendEvent.EnterManually)
}
@@ -109,6 +110,7 @@ fun SendRecipientScreen(
modifier = Modifier.size(28.dp),
)
},
+ modifier = Modifier.testTag("RecipientScan")
) {
onEvent(SendEvent.Scan)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/withdraw/WithdrawConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/withdraw/WithdrawConfirmScreen.kt
index 3f368b45c..b380dfb2e 100644
--- a/app/src/main/java/to/bitkit/ui/screens/wallets/withdraw/WithdrawConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/wallets/withdraw/WithdrawConfirmScreen.kt
@@ -69,7 +69,7 @@ fun WithdrawConfirmScreen(
text = stringResource(R.string.wallet__lnurl_w_button),
onClick = onConfirm,
isLoading = uiState.isLoading,
- modifier = Modifier.testTag("continue_button")
+ modifier = Modifier.testTag("WithdrawConfirmButton")
)
VerticalSpacer(16.dp)
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/AddWidgetsScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/AddWidgetsScreen.kt
index 5bbc1ae0d..ec34b39e1 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/AddWidgetsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/AddWidgetsScreen.kt
@@ -39,7 +39,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.PRICE) },
- modifier = Modifier.testTag("Button_${WidgetType.PRICE}")
+ modifier = Modifier.testTag("WidgetListItem-price")
)
SettingsButtonRow(
title = stringResource(R.string.widgets__news__name),
@@ -48,7 +48,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.NEWS) },
- modifier = Modifier.testTag("Button_${WidgetType.NEWS}")
+ modifier = Modifier.testTag("WidgetListItem-news")
)
SettingsButtonRow(
@@ -58,7 +58,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.BLOCK) },
- modifier = Modifier.testTag("Button_${WidgetType.BLOCK}")
+ modifier = Modifier.testTag("WidgetListItem-blocks")
)
SettingsButtonRow(
title = stringResource(R.string.widgets__facts__name),
@@ -67,7 +67,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.FACTS) },
- modifier = Modifier.testTag("Button_${WidgetType.FACTS}")
+ modifier = Modifier.testTag("WidgetListItem-facts")
)
SettingsButtonRow(
title = stringResource(R.string.widgets__weather__name),
@@ -76,7 +76,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.WEATHER) },
- modifier = Modifier.testTag("Button_${WidgetType.WEATHER}")
+ modifier = Modifier.testTag("WidgetListItem-weather")
)
SettingsButtonRow(
title = stringResource(R.string.widgets__calculator__name),
@@ -88,7 +88,7 @@ fun AddWidgetsScreen(
iconSize = 48.dp,
maxLinesSubtitle = 1,
onClick = { onWidgetSelected(WidgetType.CALCULATOR) },
- modifier = Modifier.testTag("Button_${WidgetType.CALCULATOR}")
+ modifier = Modifier.testTag("WidgetListItem-calculator")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/DragAndDropWidget.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/DragAndDropWidget.kt
index f3dac70dc..155e12dda 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/DragAndDropWidget.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/DragAndDropWidget.kt
@@ -63,7 +63,7 @@ fun DragAndDropWidget(
IconButton(
onClick = onClickDelete,
- modifier = Modifier.testTag("${title}_drag_and_drop_delete")
+ modifier = Modifier.testTag("WidgetActionDelete")
) {
Icon(
modifier = Modifier.size(24.dp),
@@ -74,7 +74,7 @@ fun DragAndDropWidget(
IconButton(
onClick = onClickSettings,
- modifier = Modifier.testTag("${title}_drag_and_drop_edit")
+ modifier = Modifier.testTag("WidgetActionEdit")
) {
Icon(
modifier = Modifier.size(24.dp),
@@ -85,7 +85,7 @@ fun DragAndDropWidget(
IconButton(
onClick = onClickDelete,
- modifier = Modifier.testTag("${title}_drag_and_drop_move")
+ modifier = Modifier.testTag("WidgetActionDrag")
) {
Icon(
modifier = Modifier.size(24.dp),
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/WidgetsIntroScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/WidgetsIntroScreen.kt
index 05d339945..ba7f26f44 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/WidgetsIntroScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/WidgetsIntroScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -55,14 +56,15 @@ fun WidgetsIntroScreen(
Spacer(Modifier.height(32.dp))
PrimaryButton(
text = stringResource(R.string.common__continue),
- onClick = onContinue
+ onClick = onContinue,
+ modifier = Modifier.testTag("WidgetsOnboarding-button")
)
Spacer(Modifier.height(16.dp))
}
}
}
-@Preview(showBackground = true)
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreen.kt
index 86d23677c..66817c08d 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksEditScreen.kt
@@ -100,7 +100,7 @@ fun BlocksEditContent(
.padding(horizontal = 16.dp)
.weight(1f)
.verticalScroll(rememberScrollState())
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -181,7 +181,7 @@ fun BlocksEditContent(
text = stringResource(R.string.common__reset),
modifier = Modifier
.weight(1f)
- .testTag("reset_button"),
+ .testTag("WidgetEditReset"),
enabled = blocksPreferences != BlocksPreferences(),
fullWidth = false,
onClick = onClickReset
@@ -192,7 +192,7 @@ fun BlocksEditContent(
enabled = blocksPreferences.run { showBlock || showTime || showDate || showTransactions || showSize || showSource },
modifier = Modifier
.weight(1f)
- .testTag("preview_button"),
+ .testTag("WidgetEditPreview"),
fullWidth = false,
onClick = onClickPreview
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreen.kt
index 38dee86ea..6f09d8bae 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/blocks/BlocksPreviewScreen.kt
@@ -143,7 +143,7 @@ fun BlocksPreviewContent(
}
),
onClick = onClickEdit,
- modifier = Modifier.testTag("edit_settings_button")
+ modifier = Modifier.testTag("WidgetEdit")
)
Spacer(modifier = Modifier.weight(1f))
@@ -189,7 +189,7 @@ fun BlocksPreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -199,7 +199,7 @@ fun BlocksPreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
onClick = onClickSave
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/calculator/CalculatorPreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/calculator/CalculatorPreviewScreen.kt
index 338aaef45..4dab1b8f1 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/calculator/CalculatorPreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/calculator/CalculatorPreviewScreen.kt
@@ -156,7 +156,7 @@ fun CalculatorPreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -166,7 +166,7 @@ fun CalculatorPreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
onClick = onClickSave
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreen.kt
index 01440c203..74baa709a 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsEditScreen.kt
@@ -81,7 +81,7 @@ fun FactsEditContent(
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -185,7 +185,7 @@ fun FactsEditContent(
text = stringResource(R.string.common__reset),
modifier = Modifier
.weight(1f)
- .testTag("reset_button"),
+ .testTag("WidgetEditReset"),
enabled = factsPreferences != FactsPreferences(),
fullWidth = false,
onClick = onClickReset
@@ -195,7 +195,7 @@ fun FactsEditContent(
text = stringResource(R.string.common__preview),
modifier = Modifier
.weight(1f)
- .testTag("preview_button"),
+ .testTag("WidgetEditPreview"),
fullWidth = false,
onClick = onClickPreview
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreen.kt
index e305e6cbe..ab1d18216 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/facts/FactsPreviewScreen.kt
@@ -142,7 +142,7 @@ fun FactsPreviewContent(
}
),
onClick = onClickEdit,
- modifier = Modifier.testTag("edit_settings_button")
+ modifier = Modifier.testTag("WidgetEdit")
)
Spacer(modifier = Modifier.weight(1f))
@@ -176,7 +176,7 @@ fun FactsPreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -186,7 +186,7 @@ fun FactsPreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
onClick = onClickSave
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditScreen.kt
index a2ae0d558..967e6ad52 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesEditScreen.kt
@@ -88,7 +88,7 @@ fun HeadlinesEditContent(
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -224,7 +224,7 @@ fun HeadlinesEditContent(
text = stringResource(R.string.common__reset),
modifier = Modifier
.weight(1f)
- .testTag("reset_button"),
+ .testTag("WidgetEditReset"),
enabled = !headlinePreferences.showSource || !headlinePreferences.showTime,
fullWidth = false,
onClick = onClickReset
@@ -234,7 +234,7 @@ fun HeadlinesEditContent(
text = stringResource(R.string.common__preview),
modifier = Modifier
.weight(1f)
- .testTag("preview_button"),
+ .testTag("WidgetEditPreview"),
fullWidth = false,
onClick = onClickPreview
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewScreen.kt
index 2f9a1ac0b..9c219793f 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/headlines/HeadlinesPreviewScreen.kt
@@ -143,7 +143,7 @@ fun HeadlinesPreviewContent(
}
),
onClick = onClickEdit,
- modifier = Modifier.testTag("edit_settings_button")
+ modifier = Modifier.testTag("WidgetEdit")
)
Spacer(modifier = Modifier.weight(1f))
@@ -181,7 +181,7 @@ fun HeadlinesPreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -191,7 +191,7 @@ fun HeadlinesPreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
onClick = onClickSave
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceCard.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceCard.kt
index 4b31d8ab9..3fb365b2a 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceCard.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceCard.kt
@@ -107,7 +107,7 @@ fun PriceCard(
color = Colors.White64,
modifier = Modifier
.weight(1f)
- .testTag("price_card_pair_label_${widgetData.pair}")
+ .testTag("PriceWidgetRow-${widgetData.pair.displayName}")
)
BodySB(
@@ -144,10 +144,10 @@ fun PriceCard(
Spacer(modifier = Modifier.height(8.dp))
Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
- .testTag("source_row"),
- horizontalArrangement = Arrangement.SpaceBetween
+ .testTag("PriceWidgetSource")
) {
CaptionB(
text = stringResource(R.string.widgets__widget__source),
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceEditScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceEditScreen.kt
index bb6005afd..ae3cfe85f 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceEditScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PriceEditScreen.kt
@@ -101,7 +101,7 @@ fun PriceEditContent(
.padding(horizontal = 16.dp)
.weight(1f)
.verticalScroll(rememberScrollState())
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -124,7 +124,7 @@ fun PriceEditContent(
onClick = {
onClickTradingPair(data.pair)
},
- testTagPrefix = data.pair.displayName
+ testTagPrefix = data.pair.displayName,
)
}
@@ -133,7 +133,7 @@ fun PriceEditContent(
widgetData = priceData,
isEnabled = priceData.period == preferences.period,
onClick = onClickGraph,
- testTagPrefix = priceData.period.name
+ testTagPrefix = priceData.period.value,
)
}
@@ -142,35 +142,35 @@ fun PriceEditContent(
value = priceModel.source,
isEnabled = preferences.showSource,
onClick = onClickSource,
- testTagPrefix = "source"
+ testTagPrefix = "showSource",
)
}
Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
.padding(vertical = 21.dp, horizontal = 16.dp)
.fillMaxWidth()
- .testTag("buttons_row"),
- horizontalArrangement = Arrangement.spacedBy(16.dp)
+ .testTag("buttons_row")
) {
SecondaryButton(
text = stringResource(R.string.common__reset),
- modifier = Modifier
- .weight(1f)
- .testTag("reset_button"),
enabled = preferences != PricePreferences(),
fullWidth = false,
- onClick = onClickReset
+ onClick = onClickReset,
+ modifier = Modifier
+ .weight(1f)
+ .testTag("WidgetEditReset")
)
PrimaryButton(
text = stringResource(R.string.common__preview),
- modifier = Modifier
- .weight(1f)
- .testTag("preview_button"),
fullWidth = false,
isLoading = isLoading,
- onClick = onClickPreview
+ onClick = onClickPreview,
+ modifier = Modifier
+ .weight(1f)
+ .testTag("WidgetEditPreview")
)
}
}
@@ -211,7 +211,7 @@ private fun PriceEditOptionRow(
IconButton(
onClick = onClick,
- modifier = Modifier.testTag("${testTagPrefix}_toggle_button")
+ modifier = Modifier.testTag("WidgetEditField-$testTagPrefix")
) {
Icon(
painter = painterResource(R.drawable.ic_checkmark),
@@ -219,7 +219,7 @@ private fun PriceEditOptionRow(
tint = if (isEnabled) Colors.Brand else Colors.White50,
modifier = Modifier
.size(32.dp)
- .testTag("${testTagPrefix}_toggle_icon"),
+ .testTag("${testTagPrefix}_toggle_icon")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PricePreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PricePreviewScreen.kt
index cdd77ef6e..2b7ce8bc7 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/price/PricePreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/price/PricePreviewScreen.kt
@@ -114,7 +114,7 @@ fun PricePreviewContent(
.padding(horizontal = 16.dp)
.weight(1f)
.verticalScroll(rememberScrollState())
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -163,7 +163,7 @@ fun PricePreviewContent(
}
),
onClick = onClickEdit,
- modifier = Modifier.testTag("edit_settings_button")
+ modifier = Modifier.testTag("WidgetEdit")
)
Spacer(modifier = Modifier.weight(1f))
@@ -200,7 +200,7 @@ fun PricePreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -210,7 +210,7 @@ fun PricePreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
isLoading = isLoading,
onClick = onClickSave
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreen.kt
index 4dd447ad0..3239c9a96 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherEditScreen.kt
@@ -94,7 +94,7 @@ fun WeatherEditContent(
.padding(horizontal = 16.dp)
.weight(1f)
.verticalScroll(rememberScrollState())
- .testTag("main_content")
+ .testTag("WidgetEditScrollView")
) {
Spacer(modifier = Modifier.height(26.dp))
@@ -228,7 +228,7 @@ fun WeatherEditContent(
text = stringResource(R.string.common__reset),
modifier = Modifier
.weight(1f)
- .testTag("reset_button"),
+ .testTag("WidgetEditReset"),
enabled = weatherPreferences != WeatherPreferences(),
fullWidth = false,
onClick = onClickReset
@@ -241,7 +241,7 @@ fun WeatherEditContent(
},
modifier = Modifier
.weight(1f)
- .testTag("preview_button"),
+ .testTag("WidgetEditPreview"),
fullWidth = false,
onClick = onClickPreview
)
diff --git a/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreen.kt b/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreen.kt
index b31b0ab86..cff65e70a 100644
--- a/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/screens/widgets/weather/WeatherPreviewScreen.kt
@@ -147,7 +147,7 @@ fun WeatherPreviewContent(
}
),
onClick = onClickEdit,
- modifier = Modifier.testTag("edit_settings_button")
+ modifier = Modifier.testTag("WidgetEdit")
)
Spacer(modifier = Modifier.weight(1f))
@@ -184,7 +184,7 @@ fun WeatherPreviewContent(
text = stringResource(R.string.common__delete),
modifier = Modifier
.weight(1f)
- .testTag("delete_button"),
+ .testTag("WidgetDelete"),
fullWidth = false,
onClick = onClickDelete
)
@@ -194,7 +194,7 @@ fun WeatherPreviewContent(
text = stringResource(R.string.common__save),
modifier = Modifier
.weight(1f)
- .testTag("save_button"),
+ .testTag("WidgetSave"),
fullWidth = false,
onClick = onClickSave
)
diff --git a/app/src/main/java/to/bitkit/ui/settings/AboutScreen.kt b/app/src/main/java/to/bitkit/ui/settings/AboutScreen.kt
index cd658c74e..8e57ba882 100644
--- a/app/src/main/java/to/bitkit/ui/settings/AboutScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/AboutScreen.kt
@@ -11,6 +11,7 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -88,6 +89,7 @@ fun AboutScreen(
.fillMaxWidth()
.padding(horizontal = 32.dp)
.weight(1f)
+ .testTag("AboutLogo")
)
Links(modifier = Modifier.fillMaxWidth())
diff --git a/app/src/main/java/to/bitkit/ui/settings/AdvancedSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/AdvancedSettingsScreen.kt
index 7d7f20227..378034d18 100644
--- a/app/src/main/java/to/bitkit/ui/settings/AdvancedSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/AdvancedSettingsScreen.kt
@@ -29,18 +29,6 @@ import to.bitkit.ui.scaffold.CloseNavIcon
import to.bitkit.ui.scaffold.ScreenColumn
import to.bitkit.ui.theme.AppThemeSurface
-object AdvancedSettingsTestTags {
- const val SCREEN = "advanced_settings_screen"
- const val COIN_SELECTION_BUTTON = "coin_selection_button"
- const val LIGHTNING_CONNECTIONS_BUTTON = "lightning_connections_button"
- const val LIGHTNING_NODE_BUTTON = "lightning_node_button"
- const val ELECTRUM_SERVER_BUTTON = "electrum_server_button"
- const val RGS_SERVER_BUTTON = "rgs_server_button"
- const val ADDRESS_VIEWER_BUTTON = "address_viewer_button"
- const val SUGGESTIONS_RESET_BUTTON = "suggestions_reset_button"
- const val RESET_SUGGESTIONS_DIALOG = "reset_suggestions_dialog"
-}
-
@Composable
fun AdvancedSettingsScreen(
navController: NavController,
@@ -106,7 +94,7 @@ private fun Content(
.padding(horizontal = 16.dp)
.fillMaxSize()
.verticalScroll(rememberScrollState())
- .testTag(AdvancedSettingsTestTags.SCREEN)
+ .testTag("advanced_settings_screen")
) {
// Payments Section
SectionHeader(title = stringResource(R.string.settings__adv__section_payments))
@@ -114,7 +102,7 @@ private fun Content(
SettingsButtonRow(
title = stringResource(R.string.settings__adv__coin_selection),
onClick = onCoinSelectionClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.COIN_SELECTION_BUTTON),
+ modifier = Modifier.testTag("CoinSelectPreference"),
)
// Networks Section
@@ -123,25 +111,25 @@ private fun Content(
SettingsButtonRow(
title = stringResource(R.string.settings__adv__lightning_connections),
onClick = onLightningConnectionsClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.LIGHTNING_CONNECTIONS_BUTTON),
+ modifier = Modifier.testTag("Channels"),
)
SettingsButtonRow(
title = stringResource(R.string.settings__adv__lightning_node),
onClick = onLightningNodeClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.LIGHTNING_NODE_BUTTON),
+ modifier = Modifier.testTag("LightningNodeInfo"),
)
SettingsButtonRow(
title = stringResource(R.string.settings__adv__electrum_server),
onClick = onElectrumServerClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.ELECTRUM_SERVER_BUTTON),
+ modifier = Modifier.testTag("ElectrumConfig"),
)
SettingsButtonRow(
title = stringResource(R.string.settings__adv__rgs_server),
onClick = onRgsServerClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.RGS_SERVER_BUTTON),
+ modifier = Modifier.testTag("RGSServer"),
)
// Other Section
@@ -150,13 +138,13 @@ private fun Content(
SettingsButtonRow(
title = stringResource(R.string.settings__adv__address_viewer),
onClick = onAddressViewerClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.ADDRESS_VIEWER_BUTTON),
+ modifier = Modifier.testTag("AddressViewer"),
)
SettingsButtonRow(
title = stringResource(R.string.settings__adv__suggestions_reset),
onClick = onSuggestionsResetClick,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.SUGGESTIONS_RESET_BUTTON),
+ modifier = Modifier.testTag("ResetSuggestions"),
)
VerticalSpacer(32.dp)
@@ -169,7 +157,7 @@ private fun Content(
confirmText = stringResource(R.string.settings__adv__reset_confirm),
onConfirm = onResetSuggestionsDialogConfirm,
onDismiss = onResetSuggestionsDialogCancel,
- modifier = Modifier.testTag(AdvancedSettingsTestTags.RESET_SUGGESTIONS_DIALOG),
+ modifier = Modifier.testTag("reset_suggestions_dialog"),
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/BackupSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/BackupSettingsScreen.kt
index d19b71c94..80c009225 100644
--- a/app/src/main/java/to/bitkit/ui/settings/BackupSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/BackupSettingsScreen.kt
@@ -27,6 +27,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import to.bitkit.R
+import to.bitkit.env.Env
import to.bitkit.ext.toLocalizedTimestamp
import to.bitkit.models.BackupCategory
import to.bitkit.models.BackupItemStatus
@@ -37,9 +38,11 @@ import to.bitkit.ui.appViewModel
import to.bitkit.ui.backupsViewModel
import to.bitkit.ui.components.AuthCheckAction
import to.bitkit.ui.components.BodyMSB
+import to.bitkit.ui.components.Caption13Up
import to.bitkit.ui.components.CaptionB
+import to.bitkit.ui.components.FillWidth
import to.bitkit.ui.components.Sheet
-import to.bitkit.ui.components.settings.SectionHeader
+import to.bitkit.ui.components.VerticalSpacer
import to.bitkit.ui.components.settings.SettingsButtonRow
import to.bitkit.ui.navigateToAuthCheck
import to.bitkit.ui.navigateToHome
@@ -54,12 +57,6 @@ import to.bitkit.viewmodels.BackupCategoryUiState
import to.bitkit.viewmodels.BackupStatusUiState
import to.bitkit.viewmodels.toUiState
-object BackupSettingsTestTags {
- const val SCREEN = "backup_settings_screen"
- const val BACKUP_BUTTON = "backup_settings_backup_button"
- const val RESTORE_BUTTON = "backup_settings_restore_button"
-}
-
@Composable
fun BackupSettingsScreen(
navController: NavController,
@@ -96,6 +93,7 @@ private fun BackupSettingsScreenContent(
onBack: () -> Unit,
onClose: () -> Unit,
) {
+ val allSynced = uiState.categories.all { it.status.synced >= it.status.required }
ScreenColumn {
AppTopBar(
titleText = stringResource(R.string.settings__backup__title),
@@ -106,20 +104,40 @@ private fun BackupSettingsScreenContent(
modifier = Modifier
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState())
- .testTag(BackupSettingsTestTags.SCREEN)
+ .testTag("BackupScrollView")
) {
SettingsButtonRow(
title = stringResource(R.string.settings__backup__wallet),
onClick = onBackupClick,
- modifier = Modifier.testTag(BackupSettingsTestTags.BACKUP_BUTTON),
+ modifier = Modifier.testTag("BackupWallet"),
)
SettingsButtonRow(
title = stringResource(R.string.settings__backup__reset),
onClick = onResetAndRestoreClick,
- modifier = Modifier.testTag(BackupSettingsTestTags.RESTORE_BUTTON),
+ modifier = Modifier.testTag("ResetAndRestore"),
)
+ VerticalSpacer(28.dp)
- SectionHeader(title = stringResource(R.string.settings__backup__latest))
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Caption13Up(
+ text = stringResource(R.string.settings__backup__latest),
+ color = Colors.White64,
+ )
+ FillWidth()
+ @Suppress("SimplifyBooleanWithConstants", "KotlinConstantConditions")
+ if (Env.isE2eTest && allSynced) {
+ Icon(
+ painter = painterResource(R.drawable.ic_check_circle),
+ contentDescription = "All Synced",
+ tint = Colors.Green,
+ modifier = Modifier
+ .padding(end = 4.dp)
+ .size(16.dp)
+ .testTag("AllSynced")
+ )
+ }
+ }
+ VerticalSpacer(12.dp)
uiState.categories.map { categoryUiState ->
BackupStatusItem(
diff --git a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt
index a02f90465..51fa26597 100644
--- a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt
@@ -33,20 +33,6 @@ import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.ui.utils.rememberBiometricAuthSupported
-object SecuritySettingsTestTags {
- const val SCREEN_CONTENT = "security_settings_content"
- const val SWIPE_TO_HIDE_BALANCE = "security_settings_swipe_to_hide_balance"
- const val HIDE_BALANCE_ON_OPEN = "security_settings_hide_balance_on_open"
- const val AUTO_READ_CLIPBOARD = "security_settings_auto_read_clipboard"
- const val SEND_AMOUNT_WARNING = "security_settings_send_amount_warning"
- const val PIN_SETUP = "security_settings_pin_setup"
- const val PIN_CHANGE = "security_settings_pin_change"
- const val PIN_ON_LAUNCH = "security_settings_pin_on_launch"
- const val PIN_ON_IDLE = "security_settings_pin_on_idle"
- const val PIN_FOR_PAYMENTS = "security_settings_pin_for_payments"
- const val USE_BIOMETRICS = "security_settings_use_biometrics"
-}
-
@Composable
fun SecuritySettingsScreen(
navController: NavController,
@@ -151,7 +137,6 @@ private fun Content(
ScreenColumn(
modifier = Modifier
.verticalScroll(rememberScrollState())
- .testTag(SecuritySettingsTestTags.SCREEN_CONTENT)
) {
AppTopBar(
titleText = stringResource(R.string.settings__security_title),
@@ -165,7 +150,7 @@ private fun Content(
title = stringResource(R.string.settings__security__swipe_balance_to_hide),
isChecked = enableSwipeToHideBalance,
onClick = onSwipeToHideBalanceClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.SWIPE_TO_HIDE_BALANCE),
+ modifier = Modifier.testTag("SwipeBalanceToHide"),
)
if (enableSwipeToHideBalance) {
@@ -173,7 +158,7 @@ private fun Content(
title = stringResource(R.string.settings__security__hide_balance_on_open),
isChecked = hideBalanceOnOpen,
onClick = onHideBalanceOnOpenClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.HIDE_BALANCE_ON_OPEN),
+ modifier = Modifier.testTag("HideBalanceOnOpen"),
)
}
@@ -181,14 +166,14 @@ private fun Content(
title = stringResource(R.string.settings__security__clipboard),
isChecked = enableAutoReadClipboard,
onClick = onAutoReadClipboardClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.AUTO_READ_CLIPBOARD),
+ modifier = Modifier.testTag("AutoReadClipboard"),
)
SettingsSwitchRow(
title = stringResource(R.string.settings__security__warn_100),
isChecked = enableSendAmountWarning,
onClick = onSendAmountWarningClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.SEND_AMOUNT_WARNING),
+ modifier = Modifier.testTag("SendAmountWarning"),
)
SettingsButtonRow(
@@ -199,31 +184,31 @@ private fun Content(
)
),
onClick = onPinClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.PIN_SETUP),
+ modifier = Modifier.testTag("PINCode"),
)
if (isPinEnabled) {
SettingsButtonRow(
title = stringResource(R.string.settings__security__pin_change),
onClick = onChangePinClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.PIN_CHANGE),
+ modifier = Modifier.testTag("PINChange"),
)
SettingsSwitchRow(
title = stringResource(R.string.settings__security__pin_launch),
isChecked = isPinOnLaunchEnabled,
onClick = onPinOnLaunchClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.PIN_ON_LAUNCH),
+ modifier = Modifier.testTag("EnablePinOnLaunch"),
)
SettingsSwitchRow(
title = stringResource(R.string.settings__security__pin_idle),
isChecked = isPinOnIdleEnabled,
onClick = onPinOnIdleClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.PIN_ON_IDLE),
+ modifier = Modifier.testTag("EnablePinOnIdle"),
)
SettingsSwitchRow(
title = stringResource(R.string.settings__security__pin_payments),
isChecked = isPinForPaymentsEnabled,
onClick = onPinForPaymentsClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.PIN_FOR_PAYMENTS),
+ modifier = Modifier.testTag("EnablePinForPayments"),
)
}
if (isPinEnabled && isBiometrySupported) {
@@ -234,7 +219,7 @@ private fun Content(
},
isChecked = isBiometricEnabled,
onClick = onUseBiometricsClick,
- modifier = Modifier.testTag(SecuritySettingsTestTags.USE_BIOMETRICS),
+ modifier = Modifier.testTag("UseBiometryInstead"),
)
}
if (isPinEnabled && isBiometrySupported) {
diff --git a/app/src/main/java/to/bitkit/ui/settings/SettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/SettingsScreen.kt
index 33567f010..4a4b857b3 100644
--- a/app/src/main/java/to/bitkit/ui/settings/SettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/SettingsScreen.kt
@@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -118,37 +119,44 @@ fun SettingsScreenContent(
title = stringResource(R.string.settings__general_title),
iconRes = R.drawable.ic_settings_general,
onClick = onGeneralClick,
+ modifier = Modifier.testTag("GeneralSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__security_title),
iconRes = R.drawable.ic_settings_security,
onClick = onSecurityClick,
+ modifier = Modifier.testTag("SecuritySettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__backup_title),
iconRes = R.drawable.ic_settings_backup,
onClick = onBackupClick,
+ modifier = Modifier.testTag("BackupSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__advanced_title),
iconRes = R.drawable.ic_settings_advanced,
onClick = onAdvancedClick,
+ modifier = Modifier.testTag("AdvancedSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__support_title),
iconRes = R.drawable.ic_settings_support,
onClick = onSupportClick,
+ modifier = Modifier.testTag("Support")
)
SettingsButtonRow(
title = stringResource(R.string.settings__about_title),
iconRes = R.drawable.ic_settings_about,
onClick = onAboutClick,
+ modifier = Modifier.testTag("About")
)
if (isDevModeEnabled) {
SettingsButtonRow(
title = stringResource(R.string.settings__dev_title),
iconRes = R.drawable.ic_settings_dev,
onClick = onDevClick,
+ modifier = Modifier.testTag("DevSettings")
)
}
Spacer(Modifier.weight(1f))
@@ -159,6 +167,7 @@ fun SettingsScreenContent(
.fillMaxWidth()
.height(256.dp)
.clickableAlpha(1f) { onCogTap() }
+ .testTag("DevOptions")
)
Spacer(Modifier.weight(1f))
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt b/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt
index f9af2c0ad..302084d41 100644
--- a/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/advanced/AddressViewerScreen.kt
@@ -17,6 +17,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@@ -137,7 +138,8 @@ private fun AddressViewerContent(
BodyS(
text = stringResource(R.string.settings__addr__path)
.replace("{path}", uiState.selectedAddress?.path.orEmpty()),
- color = Colors.White80
+ color = Colors.White80,
+ modifier = Modifier.testTag("Path")
)
BodyS(
text = stringResource(R.string.wallet__activity_explorer),
@@ -279,14 +281,14 @@ private fun AddressItem(
.clickableAlpha { onClick() }
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
- Caption(text = "$index:", color = textColorAlt)
-
Caption(
- text = address,
+ text = "$index: $address",
color = textColor,
maxLines = 1,
overflow = TextOverflow.MiddleEllipsis,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("Address-$index")
)
CaptionB(text = balance.formatToModernDisplay(), color = textColorAlt)
diff --git a/app/src/main/java/to/bitkit/ui/settings/advanced/ElectrumConfigScreen.kt b/app/src/main/java/to/bitkit/ui/settings/advanced/ElectrumConfigScreen.kt
index c002ace73..1361b55f8 100644
--- a/app/src/main/java/to/bitkit/ui/settings/advanced/ElectrumConfigScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/advanced/ElectrumConfigScreen.kt
@@ -1,6 +1,7 @@
package to.bitkit.ui.settings.advanced
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
@@ -15,6 +16,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
@@ -128,14 +130,19 @@ private fun Content(
BodyM(stringResource(R.string.settings__es__connected_to), color = Colors.White64)
VerticalSpacer(4.dp)
- BodyM(
- text = if (uiState.isConnected && uiState.connectedPeer != null) {
- "${uiState.connectedPeer.host}:${uiState.connectedPeer.port}"
- } else {
- stringResource(R.string.settings__es__disconnected)
- },
- color = if (uiState.isConnected) Colors.Green else Colors.Red,
- )
+ Box(
+ modifier = Modifier.testTag("ElectrumStatus")
+ ) {
+ BodyM(
+ text = if (uiState.isConnected && uiState.connectedPeer != null) {
+ "${uiState.connectedPeer.host}:${uiState.connectedPeer.port}"
+ } else {
+ stringResource(R.string.settings__es__disconnected)
+ },
+ color = if (uiState.isConnected) Colors.Green else Colors.Red,
+ modifier = Modifier.testTag(if (uiState.isConnected) "Connected" else "Disconnected")
+ )
+ }
VerticalSpacer(32.dp)
@@ -146,7 +153,9 @@ private fun Content(
value = uiState.host,
onValueChange = onChangeHost,
placeholder = "127.0.0.1",
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("HostInput")
)
VerticalSpacer(16.dp)
@@ -159,7 +168,9 @@ private fun Content(
onValueChange = onChangePort,
placeholder = "50001",
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("PortInput")
)
VerticalSpacer(28.dp)
@@ -171,13 +182,14 @@ private fun Content(
title = "TCP",
value = SettingsButtonValue.BooleanValue(uiState.protocol == ElectrumProtocol.TCP),
enabled = !uiState.isLoading,
- onClick = { onChangeProtocol(ElectrumProtocol.TCP) }
+ onClick = { onChangeProtocol(ElectrumProtocol.TCP) },
)
SettingsButtonRow(
title = "TLS",
value = SettingsButtonValue.BooleanValue(uiState.protocol == ElectrumProtocol.SSL),
enabled = !uiState.isLoading,
- onClick = { onChangeProtocol(ElectrumProtocol.SSL) }
+ onClick = { onChangeProtocol(ElectrumProtocol.SSL) },
+ modifier = Modifier.testTag("ElectrumProtocol")
)
FillHeight()
@@ -191,7 +203,9 @@ private fun Content(
text = stringResource(R.string.settings__es__button_reset),
onClick = onClickReset,
enabled = !uiState.isLoading,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ResetToDefault")
)
PrimaryButton(
@@ -199,7 +213,9 @@ private fun Content(
onClick = onClickConnect,
enabled = !uiState.isLoading && uiState.hasEdited || !uiState.isConnected,
isLoading = uiState.isLoading,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("ConnectToHost")
)
}
VerticalSpacer(16.dp)
diff --git a/app/src/main/java/to/bitkit/ui/settings/advanced/RgsServerScreen.kt b/app/src/main/java/to/bitkit/ui/settings/advanced/RgsServerScreen.kt
index 5667c9975..5e666e01f 100644
--- a/app/src/main/java/to/bitkit/ui/settings/advanced/RgsServerScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/advanced/RgsServerScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -119,6 +120,7 @@ private fun Content(
BodyM(
text = uiState.connectedRgsUrl ?: "P2P",
color = if (uiState.connectedRgsUrl != null) Colors.Green else Colors.White,
+ modifier = Modifier.testTag("ConnectedUrl")
)
VerticalSpacer(32.dp)
@@ -129,7 +131,7 @@ private fun Content(
TextInput(
value = uiState.rgsUrl,
onValueChange = onChangeUrl,
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier.fillMaxWidth().testTag("RGSUrl")
)
FillHeight()
diff --git a/app/src/main/java/to/bitkit/ui/settings/appStatus/AppStatusScreen.kt b/app/src/main/java/to/bitkit/ui/settings/appStatus/AppStatusScreen.kt
index 5b2556b2f..eb33dc817 100644
--- a/app/src/main/java/to/bitkit/ui/settings/appStatus/AppStatusScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/appStatus/AppStatusScreen.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -98,6 +99,7 @@ private fun Content(
StatusItem(
statusUi = StatusUi(
+ id = "internet",
title = stringResource(R.string.settings__status__internet__title),
subtitle = when (uiState.health.internet) {
HealthState.READY -> stringResource(R.string.settings__status__internet__ready)
@@ -112,6 +114,7 @@ private fun Content(
StatusItem(
statusUi = StatusUi(
+ id = "electrum",
title = stringResource(R.string.settings__status__electrum__title),
subtitle = when (uiState.health.electrum) {
HealthState.READY -> stringResource(R.string.settings__status__electrum__ready)
@@ -126,6 +129,7 @@ private fun Content(
StatusItem(
statusUi = StatusUi(
+ id = "lightning_node",
title = stringResource(R.string.settings__status__lightning_node__title),
subtitle = uiState.nodeSubtitle.ifEmpty {
when (uiState.health.node) {
@@ -142,6 +146,7 @@ private fun Content(
StatusItem(
statusUi = StatusUi(
+ id = "lightning_connection",
title = stringResource(R.string.settings__status__lightning_connection__title),
subtitle = when (uiState.health.channels) {
HealthState.READY -> stringResource(R.string.settings__status__lightning_connection__ready)
@@ -156,6 +161,7 @@ private fun Content(
StatusItem(
statusUi = StatusUi(
+ id = "backup",
title = stringResource(R.string.settings__status__backup__title),
subtitle = uiState.backupSubtitle.ifEmpty {
when (uiState.health.backups) {
@@ -200,6 +206,7 @@ private fun StatusItem(
.fillMaxWidth()
.height(72.dp)
.clickableAlpha { onClick() }
+ .testTag("Status-${statusUi.id}")
) {
Box(
contentAlignment = Alignment.Center,
@@ -238,6 +245,7 @@ private fun StatusItem(
}
private data class StatusUi(
+ val id: String,
val title: String,
val subtitle: String,
@DrawableRes val iconRes: Int,
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt
index 3185a4fbe..1abf43da4 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/ConfirmMnemonicScreen.kt
@@ -2,7 +2,6 @@ package to.bitkit.ui.settings.backups
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -40,7 +39,6 @@ import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
import to.bitkit.utils.bip39Words
-@OptIn(ExperimentalLayoutApi::class)
@Composable
fun ConfirmMnemonicScreen(
uiState: BackupContract.UiState,
@@ -102,7 +100,6 @@ fun ConfirmMnemonicScreen(
)
}
-@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun ConfirmMnemonicContent(
originalSeed: List,
@@ -165,7 +162,7 @@ private fun ConfirmMnemonicContent(
fullWidth = false,
size = ButtonSize.Small,
onClick = { onWordPress(word, index) },
- modifier = Modifier.testTag("backup_shuffled_word_button_$index")
+ modifier = Modifier.testTag("Word-$word")
)
}
}
@@ -211,7 +208,7 @@ private fun ConfirmMnemonicContent(
text = stringResource(R.string.common__continue),
onClick = onContinue,
enabled = isComplete,
- modifier = Modifier.testTag("backup_confirm_mnemonic_continue_button")
+ modifier = Modifier.testTag("ContinueConfirmMnemonic")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -235,17 +232,16 @@ private fun SelectedWordItem(
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
- val testWords = bip39Words.take(24)
-
+ val testWords = bip39Words.take(12)
AppThemeSurface {
ConfirmMnemonicContent(
originalSeed = testWords,
shuffledWords = testWords.shuffled(),
- selectedWords = arrayOfNulls(24),
- pressedStates = BooleanArray(24) { false },
+ selectedWords = arrayOfNulls(testWords.size),
+ pressedStates = BooleanArray(testWords.size) { false },
isComplete = false,
onWordPress = { _, _ -> },
onContinue = {},
@@ -254,17 +250,17 @@ private fun Preview() {
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
private fun Preview2() {
- val testWords = bip39Words.take(24)
-
+ val testWords = bip39Words.take(12)
+ val half = testWords.size / 2
AppThemeSurface {
ConfirmMnemonicContent(
originalSeed = testWords,
shuffledWords = testWords.shuffled(),
- selectedWords = testWords.take(12).toTypedArray() + arrayOfNulls(12),
- pressedStates = BooleanArray(24) { it < 12 },
+ selectedWords = testWords.take(half).toTypedArray() + arrayOfNulls(half),
+ pressedStates = BooleanArray(testWords.size) { it < half },
isComplete = false,
onWordPress = { _, _ -> },
onContinue = {},
@@ -273,17 +269,17 @@ private fun Preview2() {
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
-private fun Preview12Words() {
- val testWords = bip39Words.take(12)
-
+private fun Preview24Words() {
+ val testWords = bip39Words.take(24)
+ val half = testWords.size / 2
AppThemeSurface {
ConfirmMnemonicContent(
originalSeed = testWords,
shuffledWords = testWords.shuffled(),
- selectedWords = testWords.take(6).toTypedArray() + arrayOfNulls(6),
- pressedStates = BooleanArray(6) { it < 6 },
+ selectedWords = testWords.take(half).toTypedArray() + arrayOfNulls(half),
+ pressedStates = BooleanArray(testWords.size) { it < half },
isComplete = false,
onWordPress = { _, _ -> },
onContinue = {},
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/MetadataScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/MetadataScreen.kt
index e1c1d59e1..75f56d78f 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/MetadataScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/MetadataScreen.kt
@@ -91,7 +91,7 @@ private fun MetadataContent(
PrimaryButton(
text = stringResource(R.string.common__ok),
onClick = onDismiss,
- modifier = Modifier.testTag("backup_metadata_ok_button")
+ modifier = Modifier.testTag("OK")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/MultipleDevicesScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/MultipleDevicesScreen.kt
index 75798f51d..af0714f43 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/MultipleDevicesScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/MultipleDevicesScreen.kt
@@ -73,7 +73,7 @@ private fun MultipleDevicesContent(
PrimaryButton(
text = stringResource(R.string.common__ok),
onClick = onContinue,
- modifier = Modifier.testTag("multiple_devices_ok_button")
+ modifier = Modifier.testTag("OK")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt
index 7bfaae303..858ef1d87 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/ShowMnemonicScreen.kt
@@ -35,20 +35,25 @@ import androidx.compose.ui.draw.BlurredEdgeTreatment
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.blur
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.platform.LocalClipboardManager
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import to.bitkit.R
+import to.bitkit.ext.setClipboardText
import to.bitkit.ui.components.BodyM
import to.bitkit.ui.components.BodyMSB
import to.bitkit.ui.components.BodyS
+import to.bitkit.ui.components.BottomSheetPreview
import to.bitkit.ui.components.PrimaryButton
+import to.bitkit.ui.components.SheetSize
import to.bitkit.ui.scaffold.SheetTopBar
+import to.bitkit.ui.shared.modifiers.sheetHeight
import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.theme.Colors
@@ -61,7 +66,7 @@ fun ShowMnemonicScreen(
onRevealClick: () -> Unit,
onContinueClick: () -> Unit,
) {
- val clipboard = LocalClipboardManager.current
+ val context = LocalContext.current
val mnemonicWords = remember(uiState.bip39Mnemonic) {
uiState.bip39Mnemonic.split(" ").filter { it.isNotBlank() }
}
@@ -72,7 +77,7 @@ fun ShowMnemonicScreen(
showMnemonic = uiState.showMnemonic,
onRevealClick = onRevealClick,
onCopyClick = {
- clipboard.setText(AnnotatedString(uiState.bip39Mnemonic))
+ context.setClipboardText(uiState.bip39Mnemonic)
},
onContinueClick = onContinueClick,
)
@@ -86,6 +91,7 @@ private fun ShowMnemonicContent(
onRevealClick: () -> Unit,
onCopyClick: () -> Unit,
onContinueClick: () -> Unit,
+ modifier: Modifier = Modifier,
) {
val blurRadius by animateFloatAsState(
targetValue = if (showMnemonic) 0f else 10f,
@@ -115,7 +121,7 @@ private fun ShowMnemonicContent(
}
Column(
- modifier = Modifier
+ modifier = modifier
.fillMaxSize()
.gradientBackground()
.navigationBarsPadding()
@@ -169,8 +175,11 @@ private fun ShowMnemonicContent(
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
- .fillMaxWidth()
.matchParentSize()
+ .testTag("SeedContainer")
+ .semantics {
+ contentDescription = mnemonic
+ }
) {
PrimaryButton(
text = stringResource(R.string.security__mnemonic_reveal),
@@ -179,7 +188,7 @@ private fun ShowMnemonicContent(
color = Colors.Black50,
modifier = Modifier
.alpha(buttonAlpha)
- .testTag("backup_reveal_mnemonic_button")
+ .testTag("TapToReveal")
)
}
}
@@ -199,7 +208,7 @@ private fun ShowMnemonicContent(
text = stringResource(R.string.common__continue),
onClick = onContinueClick,
enabled = showMnemonic,
- modifier = Modifier.testTag("backup_show_mnemonic_continue_button")
+ modifier = Modifier.testTag("ContinueShowMnemonic")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -273,47 +282,56 @@ private fun WordItem(
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
- ShowMnemonicContent(
- mnemonic = bip39Words.take(24).joinToString(" "),
- mnemonicWords = bip39Words.take(24),
- showMnemonic = false,
- onRevealClick = {},
- onCopyClick = {},
- onContinueClick = {},
- )
+ BottomSheetPreview {
+ ShowMnemonicContent(
+ mnemonic = bip39Words.take(12).joinToString(" "),
+ mnemonicWords = bip39Words.take(12),
+ showMnemonic = false,
+ onRevealClick = {},
+ onCopyClick = {},
+ onContinueClick = {},
+ modifier = Modifier.sheetHeight(SheetSize.MEDIUM, isModal = true)
+ )
+ }
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
private fun PreviewShown() {
AppThemeSurface {
- ShowMnemonicContent(
- mnemonic = bip39Words.take(24).joinToString(" "),
- mnemonicWords = bip39Words.take(24),
- showMnemonic = true,
- onRevealClick = {},
- onCopyClick = {},
- onContinueClick = {},
- )
+ BottomSheetPreview {
+ ShowMnemonicContent(
+ mnemonic = bip39Words.take(12).joinToString(" "),
+ mnemonicWords = bip39Words.take(12),
+ showMnemonic = true,
+ onRevealClick = {},
+ onCopyClick = {},
+ onContinueClick = {},
+ modifier = Modifier.sheetHeight(SheetSize.MEDIUM, isModal = true)
+ )
+ }
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
-private fun Preview12Words() {
+private fun Preview24Words() {
AppThemeSurface {
- ShowMnemonicContent(
- mnemonic = bip39Words.take(12).joinToString(" "),
- mnemonicWords = bip39Words.take(12),
- showMnemonic = true,
- onRevealClick = {},
- onCopyClick = {},
- onContinueClick = {},
- )
+ BottomSheetPreview {
+ ShowMnemonicContent(
+ mnemonic = bip39Words.take(24).joinToString(" "),
+ mnemonicWords = bip39Words.take(24),
+ showMnemonic = true,
+ onRevealClick = {},
+ onCopyClick = {},
+ onContinueClick = {},
+ modifier = Modifier.sheetHeight(SheetSize.MEDIUM, isModal = true)
+ )
+ }
}
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/SuccessScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/SuccessScreen.kt
index 0aa9fc966..7d6948412 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/SuccessScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/SuccessScreen.kt
@@ -77,7 +77,7 @@ private fun SuccessContent(
PrimaryButton(
text = stringResource(R.string.common__ok),
onClick = onContinue,
- modifier = Modifier.testTag("backup_success_ok_button")
+ modifier = Modifier.testTag("OK")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/backups/WarningScreen.kt b/app/src/main/java/to/bitkit/ui/settings/backups/WarningScreen.kt
index 0e57c4c40..1849a7458 100644
--- a/app/src/main/java/to/bitkit/ui/settings/backups/WarningScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/backups/WarningScreen.kt
@@ -75,7 +75,7 @@ private fun WarningContent(
PrimaryButton(
text = stringResource(R.string.common__ok),
onClick = onContinue,
- modifier = Modifier.testTag("backup_warning_ok_button")
+ modifier = Modifier.testTag("OK")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/general/DefaultUnitSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/general/DefaultUnitSettingsScreen.kt
index 74869c33f..9c46591a4 100644
--- a/app/src/main/java/to/bitkit/ui/settings/general/DefaultUnitSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/general/DefaultUnitSettingsScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -74,6 +75,7 @@ fun DefaultUnitSettingsScreenContent(
iconRes = R.drawable.ic_unit_bitcoin,
value = SettingsButtonValue.BooleanValue(primaryDisplay == PrimaryDisplay.BITCOIN),
onClick = { onPrimaryUnitClick(PrimaryDisplay.BITCOIN) },
+ modifier = Modifier.testTag(stringResource(R.string.settings__general__unit_bitcoin))
)
SettingsButtonRow(
@@ -81,6 +83,7 @@ fun DefaultUnitSettingsScreenContent(
iconRes = R.drawable.ic_unit_fiat,
value = SettingsButtonValue.BooleanValue(primaryDisplay == PrimaryDisplay.FIAT),
onClick = { onPrimaryUnitClick(PrimaryDisplay.FIAT) },
+ modifier = Modifier.testTag(selectedCurrency)
)
SectionFooter(stringResource(R.string.settings__general__unit_note).replace("{currency}", selectedCurrency))
@@ -98,6 +101,9 @@ fun DefaultUnitSettingsScreenContent(
),
value = SettingsButtonValue.BooleanValue(displayUnit == unit),
onClick = { onBitcoinUnitClick(unit) },
+ modifier = Modifier.testTag(
+ if (unit == BitcoinDisplayUnit.MODERN) "DenominationModern" else "DenominationClassic"
+ )
)
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt
index be07c2b8b..6aedd7668 100644
--- a/app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -87,6 +88,7 @@ private fun GeneralSettingsContent(
title = stringResource(R.string.settings__general__currency_local),
value = SettingsButtonValue.StringValue(selectedCurrency),
onClick = onLocalCurrencyClick,
+ modifier = Modifier.testTag("CurrenciesSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__general__unit),
@@ -97,24 +99,29 @@ private fun GeneralSettingsContent(
}
),
onClick = onDefaultUnitClick,
+ modifier = Modifier.testTag("UnitSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__general__speed),
value = SettingsButtonValue.StringValue(defaultTransactionSpeed.transactionSpeedUiText()),
onClick = onTransactionSpeedClick,
+ modifier = Modifier.testTag("TransactionSpeedSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__widgets__nav_title),
onClick = onWidgetsClick,
+ modifier = Modifier.testTag("WidgetsSettings")
)
SettingsButtonRow(
title = stringResource(R.string.settings__quickpay__nav_title),
onClick = onQuickPayClick,
+ modifier = Modifier.testTag("QuickpaySettings")
)
if (showTagsButton) {
SettingsButtonRow(
title = stringResource(R.string.settings__general__tags),
onClick = onTagsClick,
+ modifier = Modifier.testTag("TagsSettings")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt b/app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt
index 4ae5f7336..cde26d5a2 100644
--- a/app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
@@ -192,6 +193,7 @@ private fun Content(
.fillMaxSize()
.verticalScroll(rememberScrollState())
.navigationBarsPadding()
+ .testTag("ChannelScrollView")
) {
// Channel Display Section
VerticalSpacer(16.dp)
@@ -328,7 +330,8 @@ private fun Content(
name = stringResource(R.string.lightning__total_size),
valueContent = {
MoneyCaptionB(sats = capacity, symbol = true)
- }
+ },
+ modifier = Modifier.testTag("TotalSize")
)
// Fees Section
@@ -360,6 +363,9 @@ private fun Content(
CaptionB(
text = stringResource(
if (channel.details.isUsable) R.string.common__yes else R.string.common__no
+ ),
+ modifier = Modifier.testTag(
+ if (channel.details.isUsable) "IsUsableYes" else "IsUsableNo"
)
)
}
@@ -469,7 +475,9 @@ private fun Content(
PrimaryButton(
text = stringResource(R.string.lightning__close_conn),
onClick = onCloseConnection,
- modifier = Modifier.weight(1f)
+ modifier = Modifier
+ .weight(1f)
+ .testTag("CloseConnection")
)
}
}
@@ -490,12 +498,13 @@ private fun SectionTitle(text: String) {
private fun SectionRow(
name: String,
valueContent: @Composable () -> Unit,
+ modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
+ modifier = modifier
.fillMaxWidth()
.height(50.dp)
.clickableAlpha(onClick = onClick)
diff --git a/app/src/main/java/to/bitkit/ui/settings/lightning/CloseConnectionScreen.kt b/app/src/main/java/to/bitkit/ui/settings/lightning/CloseConnectionScreen.kt
index 8ef104393..116c531f9 100644
--- a/app/src/main/java/to/bitkit/ui/settings/lightning/CloseConnectionScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/lightning/CloseConnectionScreen.kt
@@ -109,7 +109,7 @@ private fun Content(
onClick = onBack,
modifier = Modifier
.weight(1f)
- .testTag("cancel_button")
+ .testTag("CloseConnectionCancel")
)
PrimaryButton(
@@ -118,7 +118,7 @@ private fun Content(
isLoading = isLoading,
modifier = Modifier
.weight(1f)
- .testTag("close_button")
+ .testTag("CloseConnectionButton")
)
}
VerticalSpacer(16.dp)
diff --git a/app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt
index 18b340df4..4d7df641e 100644
--- a/app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/lightning/LightningConnectionsScreen.kt
@@ -65,7 +65,6 @@ import to.bitkit.ui.theme.Colors
object LightningConnectionsTestTags {
const val SCREEN = "lightning_connections_screen"
- const val ADD_CONNECTION_ICON = "add_connection_icon"
const val ADD_CONNECTION_BUTTON = "add_connection_button"
const val EXPORT_LOGS_BUTTON = "export_logs_button"
const val SHOW_CLOSED_BUTTON = "show_closed_button"
@@ -123,7 +122,7 @@ private fun Content(
actions = {
IconButton(
onClick = onClickAddConnection,
- modifier = Modifier.testTag(LightningConnectionsTestTags.ADD_CONNECTION_ICON)
+ modifier = Modifier.testTag("NavigationAction")
) {
Icon(
imageVector = Icons.Default.Add,
@@ -198,7 +197,7 @@ private fun Content(
onClick = { showClosed = !showClosed },
modifier = Modifier
.wrapContentWidth()
- .testTag(LightningConnectionsTestTags.SHOW_CLOSED_BUTTON)
+ .testTag("ChannelsClosed")
)
}
@@ -294,7 +293,7 @@ private fun ChannelItem(
modifier = Modifier
.fillMaxWidth()
.clickableAlpha { onClick() }
- .testTag("${LightningConnectionsTestTags.CHANNEL_ITEM_PREFIX}_${channelUi.details.channelId}")
+ .testTag("Channel")
) {
VerticalSpacer(16.dp)
Row(
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt
index 5493e238a..00d62841c 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -83,7 +84,9 @@ private fun ChangePinConfirmContent(
onBackClick: () -> Unit,
onCloseClick: () -> Unit,
) {
- ScreenColumn {
+ ScreenColumn(
+ modifier = Modifier.testTag("ChangePIN2")
+ ) {
AppTopBar(
titleText = stringResource(R.string.security__cp_retype_title),
onBackClick = onBackClick,
@@ -103,10 +106,12 @@ private fun ChangePinConfirmContent(
AnimatedVisibility(visible = showError) {
BodyS(
- text = stringResource(R.string.security__pin_not_match),
+ text = stringResource(R.string.security__cp_try_again),
textAlign = TextAlign.Center,
color = Colors.Brand,
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
+ .testTag("WrongPIN")
)
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt
index cc9e43968..ff171181d 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt
@@ -12,6 +12,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -65,7 +66,9 @@ private fun ChangePinNewContent(
onBackClick: () -> Unit,
onCloseClick: () -> Unit,
) {
- ScreenColumn {
+ ScreenColumn(
+ modifier = Modifier.testTag("ChangePIN2")
+ ) {
AppTopBar(
titleText = stringResource(R.string.security__cp_setnew_title),
onBackClick = onBackClick,
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt
index 8fe2b2ce9..455dc8d32 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt
@@ -13,6 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -83,7 +84,9 @@ private fun ChangePinContent(
) {
val isLastAttempt = attemptsRemaining == 1
- ScreenColumn {
+ ScreenColumn(
+ modifier = Modifier.testTag("ChangePIN")
+ ) {
AppTopBar(
titleText = stringResource(R.string.security__cp_title),
onBackClick = onBackClick,
@@ -107,16 +110,17 @@ private fun ChangePinContent(
text = stringResource(R.string.security__pin_last_attempt),
color = Colors.Brand,
textAlign = TextAlign.Center,
+ modifier = Modifier.testTag("LastAttempt")
)
} else {
BodyS(
- text = stringResource(R.string.security__pin_attempts).replace(
- "{attemptsRemaining}",
- "$attemptsRemaining"
- ),
+ text = stringResource(R.string.security__pin_attempts)
+ .replace("{attemptsRemaining}", "$attemptsRemaining"),
color = Colors.Brand,
textAlign = TextAlign.Center,
- modifier = Modifier.clickableAlpha { onClickForgotPin() }
+ modifier = Modifier
+ .clickableAlpha { onClickForgotPin() }
+ .testTag("AttemptsRemaining")
)
}
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt
index d2e1e8d9c..6f6617a9b 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -83,6 +84,7 @@ private fun DisablePinContent(
PrimaryButton(
text = stringResource(R.string.security__pin_disable_button),
onClick = onDisableClick,
+ modifier = Modifier.testTag("DisablePin")
)
Spacer(modifier = Modifier.height(16.dp))
@@ -90,7 +92,7 @@ private fun DisablePinContent(
}
}
-@Preview
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/PinBiometricsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/PinBiometricsScreen.kt
index 620407255..c8345e6c2 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/PinBiometricsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/PinBiometricsScreen.kt
@@ -26,6 +26,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -136,6 +137,7 @@ private fun AskForBiometricsContent(
modifier = Modifier
.fillMaxWidth()
.clickableAlpha { shouldEnableBiometrics = !shouldEnableBiometrics }
+ .testTag("ToggleBiometrics")
) {
BodyMSB(
text = run {
@@ -157,6 +159,7 @@ private fun AskForBiometricsContent(
onClick = {
onContinue(shouldEnableBiometrics)
},
+ modifier = Modifier.testTag("ContinueButton")
)
}
}
@@ -201,16 +204,17 @@ private fun ColumnScope.BioNotAvailableView(
SecondaryButton(
text = stringResource(R.string.common__skip),
onClick = onSkip,
- modifier = Modifier.weight(1f),
+ modifier = Modifier
+ .weight(1f)
+ .testTag("SkipButton")
)
PrimaryButton(
text = stringResource(R.string.security__bio_phone_settings),
onClick = {
- val intent = Intent(Settings.ACTION_SETTINGS)
- context.startActivity(intent)
+ context.startActivity(Intent(Settings.ACTION_SETTINGS))
},
- modifier = Modifier.weight(1f),
+ modifier = Modifier.weight(1f)
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/PinConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/PinConfirmScreen.kt
index 590010657..de3b7d2fa 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/PinConfirmScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/PinConfirmScreen.kt
@@ -15,6 +15,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -110,6 +111,7 @@ private fun ConfirmPinContent(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 32.dp)
+ .testTag("WrongPIN")
)
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/PinPromptScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/PinPromptScreen.kt
index 08a8ca5ab..4022f43de 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/PinPromptScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/PinPromptScreen.kt
@@ -16,6 +16,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -47,6 +48,7 @@ fun PinPromptScreen(
.gradientBackground()
.padding(horizontal = 16.dp)
.navigationBarsPadding()
+ .testTag("SecureWallet")
) {
SheetTopBar(stringResource(R.string.security__pin_security_header))
@@ -89,7 +91,9 @@ fun PinPromptScreen(
SecondaryButton(
text = stringResource(R.string.common__later),
onClick = onLater,
- modifier = Modifier.weight(1f),
+ modifier = Modifier
+ .weight(1f)
+ .testTag("SecureWallet-button-continue")
)
Spacer(modifier = Modifier.width(16.dp))
@@ -98,7 +102,9 @@ fun PinPromptScreen(
PrimaryButton(
text = stringResource(R.string.security__pin_security_button),
onClick = onContinue,
- modifier = Modifier.weight(1f),
+ modifier = Modifier
+ .weight(1f)
+ .testTag("SecureWallet-button-continue")
)
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/PinResultScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/PinResultScreen.kt
index db390238f..4e2c58247 100644
--- a/app/src/main/java/to/bitkit/ui/settings/pin/PinResultScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/pin/PinResultScreen.kt
@@ -17,6 +17,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -104,6 +105,7 @@ private fun PinResultContent(
modifier = Modifier
.fillMaxWidth()
.clickableAlpha { onTogglePinForPayments() }
+ .testTag("ToggleBioForPayments")
) {
BodyMSB(text = stringResource(R.string.security__success_payments))
Switch(
@@ -118,6 +120,7 @@ private fun PinResultContent(
PrimaryButton(
text = stringResource(R.string.common__ok),
onClick = onContinueClick,
+ modifier = Modifier.testTag("OK")
)
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPayIntroScreen.kt b/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPayIntroScreen.kt
index 9cbb62f7c..686b955bc 100644
--- a/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPayIntroScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPayIntroScreen.kt
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -56,14 +57,15 @@ fun QuickPayIntroScreen(
Spacer(Modifier.height(32.dp))
PrimaryButton(
text = stringResource(R.string.common__continue),
- onClick = onContinue
+ onClick = onContinue,
+ modifier = Modifier.testTag("QuickpayIntro-button")
)
Spacer(Modifier.height(16.dp))
}
}
}
-@Preview(showBackground = true)
+@Preview(showSystemUi = true)
@Composable
private fun Preview() {
AppThemeSurface {
diff --git a/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreen.kt
index 1c685a447..27b596f1b 100644
--- a/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/quickPay/QuickPaySettingsScreen.kt
@@ -76,7 +76,7 @@ fun QuickPaySettingsScreenContent(
title = stringResource(R.string.settings__quickpay__settings__toggle),
isChecked = isQuickPayEnabled,
onClick = { onToggleQuickPay(!isQuickPayEnabled) },
- modifier = Modifier.testTag("quickpay_toggle_switch")
+ modifier = Modifier.testTag("QuickpayToggle")
)
Spacer(modifier = Modifier.height(16.dp))
diff --git a/app/src/main/java/to/bitkit/ui/settings/support/SupportScreen.kt b/app/src/main/java/to/bitkit/ui/settings/support/SupportScreen.kt
index 42c1084e6..68bf36059 100644
--- a/app/src/main/java/to/bitkit/ui/settings/support/SupportScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/support/SupportScreen.kt
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -73,7 +74,11 @@ private fun Content(
SettingsButtonRow(title = stringResource(R.string.settings__support__report), onClick = onClickReportIssue)
SettingsButtonRow(title = stringResource(R.string.settings__support__help), onClick = onClickHelpCenter)
- SettingsButtonRow(title = stringResource(R.string.settings__support__status), onClick = onClickAppStatus)
+ SettingsButtonRow(
+ title = stringResource(R.string.settings__support__status),
+ onClick = onClickAppStatus,
+ modifier = Modifier.testTag("AppStatus")
+ )
Image(
painter = painterResource(R.drawable.question_mark),
diff --git a/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/CustomFeeSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/CustomFeeSettingsScreen.kt
index f6062c921..9f63ba48a 100644
--- a/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/CustomFeeSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/CustomFeeSettingsScreen.kt
@@ -12,6 +12,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -110,6 +111,7 @@ private fun CustomFeeSettingsContent(
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxSize()
+ .testTag("CustomFee")
) {
Caption13Up(text = stringResource(R.string.common__sat_vbyte), color = Colors.White64)
@@ -136,6 +138,7 @@ private fun CustomFeeSettingsContent(
onClick = onContinue,
enabled = isValid,
text = stringResource(R.string.common__continue),
+ modifier = Modifier.testTag("Continue")
)
Spacer(modifier = Modifier.height(16.dp))
}
diff --git a/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/TransactionSpeedSettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/TransactionSpeedSettingsScreen.kt
index 3f3c33f91..819e33773 100644
--- a/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/TransactionSpeedSettingsScreen.kt
+++ b/app/src/main/java/to/bitkit/ui/settings/transactionSpeed/TransactionSpeedSettingsScreen.kt
@@ -6,6 +6,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -72,6 +73,7 @@ private fun TransactionSpeedSettingsContent(
iconTint = Colors.Brand,
value = SettingsButtonValue.BooleanValue(selectedSpeed is TransactionSpeed.Fast),
onClick = { onSpeedSelected(TransactionSpeed.Fast) },
+ modifier = Modifier.testTag("fast")
)
SettingsButtonRow(
title = stringResource(R.string.settings__fee__normal__label),
@@ -80,6 +82,7 @@ private fun TransactionSpeedSettingsContent(
iconTint = Colors.Brand,
value = SettingsButtonValue.BooleanValue(selectedSpeed is TransactionSpeed.Medium),
onClick = { onSpeedSelected(TransactionSpeed.Medium) },
+ modifier = Modifier.testTag("normal")
)
SettingsButtonRow(
title = stringResource(R.string.settings__fee__slow__label),
@@ -88,6 +91,7 @@ private fun TransactionSpeedSettingsContent(
iconTint = Colors.Brand,
value = SettingsButtonValue.BooleanValue(selectedSpeed is TransactionSpeed.Slow),
onClick = { onSpeedSelected(TransactionSpeed.Slow) },
+ modifier = Modifier.testTag("slow")
)
SettingsButtonRow(
title = stringResource(R.string.settings__fee__custom__label),
@@ -96,6 +100,7 @@ private fun TransactionSpeedSettingsContent(
iconTint = Colors.White,
value = SettingsButtonValue.BooleanValue(selectedSpeed is TransactionSpeed.Custom),
onClick = onCustomFeeClick,
+ modifier = Modifier.testTag("custom")
)
}
}
diff --git a/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionSheet.kt b/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionSheet.kt
index e0ad721a0..04863a048 100644
--- a/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionSheet.kt
@@ -28,8 +28,6 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.semantics.contentDescription
-import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
@@ -153,22 +151,18 @@ fun BoostTransactionContent(
)
VerticalSpacer(24.dp)
-
- when {
- uiState.loading -> {
- LoadingState()
- }
-
- uiState.isDefaultMode -> {
- DefaultModeContent(
+ Column(
+ modifier = Modifier.testTag(if (uiState.isRbf) "RBFBoost" else "CPFPBoost")
+ ) {
+ when {
+ uiState.loading -> LoadingState()
+ uiState.isDefaultMode -> DefaultModeContent(
uiState = uiState,
onClickEdit = onClickEdit,
onSwipe = onSwipe,
)
- }
- else -> {
- CustomModeContent(
+ else -> CustomModeContent(
uiState = uiState,
onChangeAmount = onChangeAmount,
onClickUseSuggestedFee = onClickUseSuggestedFee,
@@ -209,9 +203,6 @@ private fun DefaultModeContent(
.fillMaxWidth()
.clickableAlpha { onClickEdit() }
.testTag(BoostTransactionTestTags.EDIT_FEE_ROW)
- .semantics {
- contentDescription = "Edit fee settings"
- },
) {
Image(
painter = painterResource(R.drawable.ic_timer_alt_yellow),
@@ -243,10 +234,9 @@ private fun DefaultModeContent(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
- val feeText = rememberMoneyText(sats = uiState.totalFeeSats.toLong())
- ?.withAccent(defaultColor = Colors.White)
- ?.toString()
- .orEmpty()
+ val feeText =
+ rememberMoneyText(sats = uiState.totalFeeSats.toLong())?.withAccent(defaultColor = Colors.White)
+ ?.toString().orEmpty()
BodyMSB(
text = feeText,
@@ -266,9 +256,7 @@ private fun DefaultModeContent(
val feeTextSecondary = rememberMoneyText(
sats = uiState.totalFeeSats.toLong(),
reversed = true
- )?.withAccent(defaultColor = Colors.White64)
- ?.toString()
- .orEmpty()
+ )?.withAccent(defaultColor = Colors.White64)?.toString().orEmpty()
BodySSB(
text = feeTextSecondary,
@@ -323,10 +311,9 @@ private fun CustomModeContent(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
- val rateText = rememberMoneyText(sats = uiState.feeRate.toLong())
- ?.withAccent(defaultColor = Colors.White)
- ?.toString()
- .orEmpty()
+ val rateText =
+ rememberMoneyText(sats = uiState.feeRate.toLong())?.withAccent(defaultColor = Colors.White)
+ ?.toString().orEmpty()
BodyMSB(
text = "$rateText/vbyte ($BITCOIN_SYMBOL ${uiState.totalFeeSats})",
@@ -340,9 +327,7 @@ private fun CustomModeContent(
val feeTextSecondary = rememberMoneyText(
sats = uiState.totalFeeSats.toLong(),
reversed = true
- )?.withAccent(defaultColor = Colors.White64)
- ?.toString()
- .orEmpty()
+ )?.withAccent(defaultColor = Colors.White64)?.toString().orEmpty()
BodySSB(
text = feeTextSecondary,
@@ -439,7 +424,7 @@ object BoostTransactionTestTags {
const val DESCRIPTION_TEXT = "description_text"
const val LOADING_INDICATOR = "loading_indicator"
const val CUSTOM_MODE_CONTENT = "custom_mode_content"
- const val EDIT_FEE_ROW = "edit_fee_row"
+ const val EDIT_FEE_ROW = "CustomFeeButton"
const val EDIT_FEE_ICON = "edit_fee_icon"
const val TIMER_ICON = "timer_icon"
const val BOOST_TITLE = "boost_title"
@@ -447,10 +432,12 @@ object BoostTransactionTestTags {
const val TOTAL_FEE_PRIMARY = "total_fee_primary"
const val TOTAL_FEE_SECONDARY = "total_fee_secondary"
const val SWIPE_TO_CONFIRM = "swipe_to_confirm"
- const val DECREASE_FEE_BUTTON = "decrease_fee_button"
- const val INCREASE_FEE_BUTTON = "increase_fee_button"
+ const val DECREASE_FEE_BUTTON = "Minus"
+ const val INCREASE_FEE_BUTTON = "Plus"
const val FEE_RATE_TEXT = "fee_rate_text"
- const val USE_SUGGESTED_FEE_BUTTON = "use_suggested_fee_button"
+
+ @Suppress("SpellCheckingInspection")
+ const val USE_SUGGESTED_FEE_BUTTON = "RecomendedFeeButton"
}
@Preview(showSystemUi = true, name = "Default mode")
diff --git a/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionViewModel.kt b/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionViewModel.kt
index d4e0cb448..248293ee3 100644
--- a/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionViewModel.kt
+++ b/app/src/main/java/to/bitkit/ui/sheets/BoostTransactionViewModel.kt
@@ -15,6 +15,8 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.lightningdevkit.ldknode.Txid
import to.bitkit.data.dto.PendingBoostActivity
+import to.bitkit.ext.BoostType
+import to.bitkit.ext.boostType
import to.bitkit.ext.nowTimestamp
import to.bitkit.models.TransactionSpeed
import to.bitkit.repositories.ActivityRepo
@@ -56,7 +58,12 @@ class BoostTransactionViewModel @Inject constructor(
Logger.debug("Setup activity $activity", context = TAG)
this.activity = activity
- _uiState.update { it.copy(loading = true) }
+ _uiState.update {
+ it.copy(
+ loading = true,
+ isRbf = activity.boostType() == BoostType.RBF,
+ )
+ }
initializeFeeEstimates()
}
@@ -437,4 +444,5 @@ data class BoostTransactionUiState(
val boosting: Boolean = false,
val loading: Boolean = false,
val estimateTime: String = "±10-20 minutes", // TODO: Implement dynamic time estimation
+ val isRbf: Boolean = false,
)
diff --git a/app/src/main/java/to/bitkit/ui/sheets/ForgotPinSheet.kt b/app/src/main/java/to/bitkit/ui/sheets/ForgotPinSheet.kt
index 1a7e7a597..5f534cbde 100644
--- a/app/src/main/java/to/bitkit/ui/sheets/ForgotPinSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/sheets/ForgotPinSheet.kt
@@ -9,6 +9,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -61,6 +62,7 @@ private fun Content(
BodyM(
text = stringResource(R.string.security__pin_forgot_text),
color = Colors.White64,
+ modifier = Modifier.testTag("ForgotPIN")
)
FillHeight()
diff --git a/app/src/main/java/to/bitkit/ui/sheets/NewTransactionSheet.kt b/app/src/main/java/to/bitkit/ui/sheets/NewTransactionSheet.kt
index b4d385377..3cd9415cd 100644
--- a/app/src/main/java/to/bitkit/ui/sheets/NewTransactionSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/sheets/NewTransactionSheet.kt
@@ -40,7 +40,6 @@ import to.bitkit.ui.components.PrimaryButton
import to.bitkit.ui.components.SecondaryButton
import to.bitkit.ui.scaffold.SheetTopBar
import to.bitkit.ui.shared.modifiers.sheetHeight
-import to.bitkit.ui.shared.util.clickableAlpha
import to.bitkit.ui.shared.util.gradientBackground
import to.bitkit.ui.theme.AppThemeSurface
import to.bitkit.ui.utils.localizedRandom
@@ -153,10 +152,10 @@ fun NewTransactionSheetView(
BalanceHeaderView(
sats = details.sats,
+ onClick = { onDetailClick },
modifier = Modifier
.fillMaxWidth()
- .clickableAlpha { onDetailClick() }
- .testTag("balance_header")
+ .testTag("ReceivedTransaction")
)
Spacer(modifier = Modifier.weight(1f))
@@ -187,7 +186,7 @@ fun NewTransactionSheetView(
PrimaryButton(
text = localizedRandom(R.string.common__ok_random),
onClick = onCloseClick,
- modifier = Modifier.testTag("ok_button")
+ modifier = Modifier.testTag("ReceivedTransactionButton")
)
}
Spacer(modifier = Modifier.height(8.dp))
diff --git a/app/src/main/java/to/bitkit/ui/sheets/SendSheet.kt b/app/src/main/java/to/bitkit/ui/sheets/SendSheet.kt
index c20f133f3..c35e9aa28 100644
--- a/app/src/main/java/to/bitkit/ui/sheets/SendSheet.kt
+++ b/app/src/main/java/to/bitkit/ui/sheets/SendSheet.kt
@@ -8,6 +8,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
@@ -59,6 +60,7 @@ fun SendSheet(
.fillMaxWidth()
.sheetHeight()
.imePadding()
+ .testTag("SendSheet")
) {
val navController = rememberNavController()
LaunchedEffect(appViewModel, navController) {
@@ -69,7 +71,7 @@ fun SendSheet(
is SendEffect.NavigateToScan -> navController.navigate(SendRoute.QrScanner)
is SendEffect.NavigateToCoinSelection -> navController.navigate(SendRoute.CoinSelection)
is SendEffect.NavigateToConfirm -> navController.navigate(SendRoute.Confirm)
- is SendEffect.PopBackToConfirm -> navController.popBackStack(SendRoute.Confirm, inclusive = false)
+ is SendEffect.PopBack -> navController.popBackStack(it.route, inclusive = false)
is SendEffect.PaymentSuccess -> onComplete(it.sheet)
is SendEffect.NavigateToQuickPay -> navController.navigate(SendRoute.QuickPay)
is SendEffect.NavigateToWithdrawConfirm -> navController.navigate(SendRoute.WithdrawConfirm)
@@ -188,6 +190,7 @@ fun SendSheet(
appViewModel.addTagToSelected(tag)
navController.popBackStack()
},
+ tqgInputTestTag = "TagInputSend",
)
}
composableWithDefaultTransitions {
diff --git a/app/src/main/java/to/bitkit/ui/theme/Defaults.kt b/app/src/main/java/to/bitkit/ui/theme/Defaults.kt
index 588687fe0..d7252c73e 100644
--- a/app/src/main/java/to/bitkit/ui/theme/Defaults.kt
+++ b/app/src/main/java/to/bitkit/ui/theme/Defaults.kt
@@ -15,17 +15,12 @@ import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import kotlin.time.Duration.Companion.milliseconds
-@Immutable
object AppTextFieldDefaults {
- @Stable
val noIndicatorColors: TextFieldColors
@Composable
get() = TextFieldDefaults.colors(
@@ -33,7 +28,6 @@ object AppTextFieldDefaults {
focusedIndicatorColor = Color.Transparent,
)
- @Stable
val transparent: TextFieldColors
@Composable
get() = noIndicatorColors.copy(
@@ -45,7 +39,6 @@ object AppTextFieldDefaults {
unfocusedPlaceholderColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
)
- @Stable
val semiTransparent: TextFieldColors
@Composable
get() = TextFieldDefaults.colors(
@@ -60,9 +53,7 @@ object AppTextFieldDefaults {
)
}
-@Immutable
object AppButtonDefaults {
- @Stable
val primaryColors: ButtonColors
@Composable
get() = ButtonDefaults.buttonColors(
@@ -72,7 +63,6 @@ object AppButtonDefaults {
disabledContentColor = Colors.White32,
)
- @Stable
val secondaryColors: ButtonColors
@Composable
get() = ButtonDefaults.outlinedButtonColors(
@@ -80,7 +70,6 @@ object AppButtonDefaults {
disabledContentColor = Colors.White32,
)
- @Stable
val tertiaryColors: ButtonColors
@Composable
get() = ButtonDefaults.textButtonColors(
@@ -89,9 +78,7 @@ object AppButtonDefaults {
)
}
-@Immutable
object AppSwitchDefaults {
- @Stable
val colors: SwitchColors
@Composable
get() = SwitchDefaults.colors(
@@ -108,7 +95,6 @@ object AppSwitchDefaults {
uncheckedIconColor = Colors.Gray4,
)
- @Stable
val colorsPurple: SwitchColors
@Composable
get() = SwitchDefaults.colors(
@@ -126,7 +112,7 @@ object AppSwitchDefaults {
)
}
-val ScreenTransitionMs = AnimationConstants.DefaultDurationMillis.milliseconds // 300ms
+const val TRANSITION_SCREEN_MS = AnimationConstants.DefaultDurationMillis.toLong() // 300ms
const val TRANSITION_SHEET_MS = 650L
object Insets {
@@ -147,6 +133,5 @@ object Insets {
}
}
-val TopBarHeight: Dp
- @OptIn(ExperimentalMaterial3Api::class)
- get() = TopAppBarDefaults.TopAppBarExpandedHeight
+@OptIn(ExperimentalMaterial3Api::class)
+val TopBarHeight: Dp = TopAppBarDefaults.TopAppBarExpandedHeight
diff --git a/app/src/main/java/to/bitkit/ui/theme/Theme.kt b/app/src/main/java/to/bitkit/ui/theme/Theme.kt
index 805d4f809..b10a54db6 100644
--- a/app/src/main/java/to/bitkit/ui/theme/Theme.kt
+++ b/app/src/main/java/to/bitkit/ui/theme/Theme.kt
@@ -11,9 +11,6 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-val Gray100 = Color(0xFFF4F4F4)
-val Gray900 = Color(0xFF212121)
-
private object ColorPalette {
@Stable
val Light = lightColorScheme(
@@ -21,9 +18,9 @@ private object ColorPalette {
secondary = Colors.White64,
background = Colors.Black,
surface = Color.White,
- surfaceVariant = Gray100,
- outline = Gray100,
- outlineVariant = Gray100, // divider default
+ surfaceVariant = Colors.Gray1,
+ outline = Colors.Gray1,
+ outlineVariant = Colors.Gray1, // divider default
// Other default colors to override
/*
onPrimary = Color.White,
@@ -41,8 +38,9 @@ private object ColorPalette {
surface = Colors.Black, // Color(0xFF101010),
onBackground = Colors.White,
onSurface = Colors.White, // Colors.Gray6,
- surfaceVariant = Gray900,
+ surfaceVariant = Colors.Gray6,
surfaceContainer = Colors.White16,
+ surfaceContainerHighest = Colors.White16, // card default
onPrimary = Colors.Black,
onSecondary = Colors.White,
outlineVariant = Colors.White10, // divider default
diff --git a/app/src/main/java/to/bitkit/ui/theme/Type.kt b/app/src/main/java/to/bitkit/ui/theme/Type.kt
index 373382a4d..a2392145b 100644
--- a/app/src/main/java/to/bitkit/ui/theme/Type.kt
+++ b/app/src/main/java/to/bitkit/ui/theme/Type.kt
@@ -5,7 +5,6 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp
import to.bitkit.R
@@ -44,6 +43,20 @@ val Typography = Typography(
)
object AppTextStyles {
+ val Display = TextStyle(
+ fontWeight = FontWeight.Black,
+ fontSize = 44.sp,
+ lineHeight = 44.sp,
+ letterSpacing = (-1).sp,
+ fontFamily = InterFontFamily,
+ )
+ val Headline = TextStyle(
+ fontWeight = FontWeight.Black,
+ fontSize = 30.sp,
+ lineHeight = 30.sp,
+ letterSpacing = (-1).sp,
+ fontFamily = InterFontFamily,
+ )
val Title = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 22.sp,
@@ -57,13 +70,12 @@ object AppTextStyles {
letterSpacing = 0.4.sp,
fontFamily = InterFontFamily,
)
- val BodyS = TextStyle(
+ val BodyM = TextStyle(
fontWeight = FontWeight.Normal,
- fontSize = 15.sp,
- lineHeight = 20.sp,
+ fontSize = 17.sp,
+ lineHeight = 22.sp,
letterSpacing = 0.4.sp,
fontFamily = InterFontFamily,
- textAlign = TextAlign.Start,
)
val BodyMSB = TextStyle(
fontWeight = FontWeight.SemiBold,
@@ -71,7 +83,20 @@ object AppTextStyles {
lineHeight = 22.sp,
letterSpacing = 0.4.sp,
fontFamily = InterFontFamily,
- textAlign = TextAlign.Start,
+ )
+ val BodyMB = TextStyle(
+ fontWeight = FontWeight.Bold,
+ fontSize = 17.sp,
+ lineHeight = 22.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
+ )
+ val BodyS = TextStyle(
+ fontWeight = FontWeight.Normal,
+ fontSize = 15.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
)
val BodySSB = TextStyle(
fontWeight = FontWeight.SemiBold,
@@ -79,6 +104,40 @@ object AppTextStyles {
lineHeight = 20.sp,
letterSpacing = 0.4.sp,
fontFamily = InterFontFamily,
- textAlign = TextAlign.Start,
+ )
+ val BodySB = TextStyle(
+ fontWeight = FontWeight.Bold,
+ fontSize = 15.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
+ )
+ val Caption = TextStyle(
+ fontWeight = FontWeight.Normal,
+ fontSize = 13.sp,
+ lineHeight = 18.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
+ )
+ val CaptionM = TextStyle(
+ fontWeight = FontWeight.Medium,
+ fontSize = 13.sp,
+ lineHeight = 18.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
+ )
+ val CaptionB = TextStyle(
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 13.sp,
+ lineHeight = 18.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
+ )
+ val FootnoteM = TextStyle(
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.4.sp,
+ fontFamily = InterFontFamily,
)
}
diff --git a/app/src/main/java/to/bitkit/ui/utils/ActivityItems.kt b/app/src/main/java/to/bitkit/ui/utils/ActivityItems.kt
index 5e4fab59c..b6d02ce4d 100644
--- a/app/src/main/java/to/bitkit/ui/utils/ActivityItems.kt
+++ b/app/src/main/java/to/bitkit/ui/utils/ActivityItems.kt
@@ -1,22 +1,19 @@
package to.bitkit.ui.utils
import com.synonym.bitkitcore.Activity
-import com.synonym.bitkitcore.PaymentType
import to.bitkit.R
+import to.bitkit.ext.isSent
+import to.bitkit.ext.isTransfer
fun Activity.getScreenTitleRes(): Int {
- val isSent = when (this) {
- is Activity.Lightning -> v1.txType == PaymentType.SENT
- is Activity.Onchain -> v1.txType == PaymentType.SENT
- }
+ val isSent = this.isSent()
var resId = when {
isSent -> R.string.wallet__activity_bitcoin_sent
else -> R.string.wallet__activity_bitcoin_received
}
- val isTransfer = this is Activity.Onchain && v1.isTransfer
- if (isTransfer) {
+ if (this.isTransfer()) {
resId = when {
isSent -> R.string.wallet__activity_transfer_spending_done
else -> R.string.wallet__activity_transfer_savings_done
diff --git a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
index f47eb4a73..a59e2c6d6 100644
--- a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
+++ b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
@@ -82,7 +82,7 @@ import to.bitkit.ui.Routes
import to.bitkit.ui.components.Sheet
import to.bitkit.ui.shared.toast.ToastEventBus
import to.bitkit.ui.sheets.SendRoute
-import to.bitkit.ui.theme.ScreenTransitionMs
+import to.bitkit.ui.theme.TRANSITION_SCREEN_MS
import to.bitkit.utils.Logger
import java.math.BigDecimal
import javax.inject.Inject
@@ -306,6 +306,8 @@ class AppViewModel @Inject constructor(
SendEvent.ConfirmAmountWarning -> onConfirmAmountWarning()
SendEvent.DismissAmountWarning -> onDismissAmountWarning()
SendEvent.PayConfirmed -> onConfirmPay()
+ SendEvent.BackToAmount -> setSendEffect(SendEffect.PopBack(SendRoute.Amount))
+ SendEvent.NavToAddress -> setSendEffect(SendEffect.NavigateToAddress)
}
}
}
@@ -396,7 +398,7 @@ class AppViewModel @Inject constructor(
)
}
refreshOnchainSendIfNeeded()
- setSendEffect(SendEffect.PopBackToConfirm)
+ setSendEffect(SendEffect.PopBack(SendRoute.Confirm))
}
}
@@ -503,16 +505,16 @@ class AppViewModel @Inject constructor(
resetQuickPayData()
val scan = runCatching { decode(result) }
- .onFailure { Logger.error("Failed to decode scan result: '$result'", it, context = TAG) }
- .onSuccess { Logger.info("Handling scan data: $it", context = TAG) }
+ .onFailure { Logger.error("Failed to decode scan data: '$result'", it, context = TAG) }
+ .onSuccess { Logger.info("Handling decoded scan data: $it", context = TAG) }
.getOrNull()
when (scan) {
- is Scanner.OnChain -> onScanOnchain(scan.invoice)
- is Scanner.Lightning -> onScanLightning(scan.invoice)
+ is Scanner.OnChain -> onScanOnchain(scan.invoice, result)
+ is Scanner.Lightning -> onScanLightning(scan.invoice, result)
is Scanner.LnurlPay -> onScanLnurlPay(scan.data)
is Scanner.LnurlWithdraw -> onScanLnurlWithdraw(scan.data)
- is Scanner.LnurlAuth -> onScanLnurlAuth(scan.data, result)
+ is Scanner.LnurlAuth -> onScanLnurlAuth(scan.data)
is Scanner.LnurlChannel -> onScanLnurlChannel(scan.data)
is Scanner.NodeId -> onScanNodeId(scan)
else -> {
@@ -526,7 +528,7 @@ class AppViewModel @Inject constructor(
}
}
- private suspend fun onScanOnchain(invoice: OnChainInvoice) {
+ private suspend fun onScanOnchain(invoice: OnChainInvoice, scanResult: String) {
val lnInvoice: LightningInvoice? = invoice.params?.get("lightning")?.let { bolt11 ->
val decoded = runCatching { decode(bolt11) }.getOrNull()
(decoded as? Scanner.Lightning)?.invoice
@@ -534,6 +536,8 @@ class AppViewModel @Inject constructor(
_sendUiState.update {
it.copy(
address = invoice.address,
+ addressInput = scanResult,
+ isAddressInputValid = true,
amount = invoice.amountSatoshis,
isUnified = invoice.params?.containsKey("lightning") == true,
decodedInvoice = lnInvoice,
@@ -568,7 +572,7 @@ class AppViewModel @Inject constructor(
}
}
- private suspend fun onScanLightning(invoice: LightningInvoice) {
+ private suspend fun onScanLightning(invoice: LightningInvoice, scanResult: String) {
if (invoice.isExpired) {
toast(
type = Toast.ToastType.ERROR,
@@ -593,6 +597,8 @@ class AppViewModel @Inject constructor(
_sendUiState.update {
it.copy(
amount = invoice.amountSatoshis,
+ addressInput = scanResult,
+ isAddressInputValid = true,
decodedInvoice = invoice,
payMethod = SendMethod.LIGHTNING,
)
@@ -699,13 +705,13 @@ class AppViewModel @Inject constructor(
}
}
- private suspend fun onScanLnurlAuth(data: LnurlAuthData, lnurl: String) {
+ private suspend fun onScanLnurlAuth(data: LnurlAuthData) {
Logger.debug("LNURL: $data", context = TAG)
if (!isMainScanner) {
hideSheet()
- delay(ScreenTransitionMs)
+ delay(TRANSITION_SCREEN_MS)
}
- showSheet(Sheet.LnurlAuth(domain = data.domain, lnurl = lnurl, k1 = data.k1))
+ showSheet(Sheet.LnurlAuth(domain = data.domain, lnurl = data.uri, k1 = data.k1))
}
fun requestLnurlAuth(callback: String, k1: String, domain: String) {
@@ -1414,21 +1420,22 @@ data class SendUiState(
val fees: Map = emptyMap(),
)
-enum class AmountWarning(@StringRes val message: Int) {
- VALUE_OVER_100_USD(R.string.wallet__send_dialog1),
- OVER_HALF_BALANCE(R.string.wallet__send_dialog2),
- FEE_OVER_HALF_VALUE(R.string.wallet__send_dialog3),
- FEE_OVER_10_USD(R.string.wallet__send_dialog4),
+enum class AmountWarning(@StringRes val message: Int, val testTag: String) {
+ VALUE_OVER_100_USD(R.string.wallet__send_dialog1, "SendDialog1"),
+ OVER_HALF_BALANCE(R.string.wallet__send_dialog2, "SendDialog2"),
+ FEE_OVER_HALF_VALUE(R.string.wallet__send_dialog3, "SendDialog3"),
+ FEE_OVER_10_USD(R.string.wallet__send_dialog4, "SendDialog4"),
+ // TODO SendDialog5 https://github.com/synonymdev/bitkit/blob/master/src/screens/Wallets/Send/ReviewAndSend.tsx#L457-L466
}
enum class SendMethod { ONCHAIN, LIGHTNING }
sealed class SendEffect {
+ data class PopBack(val route: SendRoute) : SendEffect()
data object NavigateToAddress : SendEffect()
data object NavigateToAmount : SendEffect()
data object NavigateToScan : SendEffect()
data object NavigateToConfirm : SendEffect()
- data object PopBackToConfirm : SendEffect()
data object NavigateToWithdrawConfirm : SendEffect()
data object NavigateToWithdrawError : SendEffect()
data object NavigateToCoinSelection : SendEffect()
@@ -1444,29 +1451,31 @@ sealed class MainScreenEffect {
data class ProcessClipboardAutoRead(val data: String) : MainScreenEffect()
}
-sealed class SendEvent {
- data object EnterManually : SendEvent()
- data object Paste : SendEvent()
- data object Scan : SendEvent()
+sealed interface SendEvent {
+ data object EnterManually : SendEvent
+ data object Paste : SendEvent
+ data object Scan : SendEvent
- data object AddressReset : SendEvent()
- data class AddressChange(val value: String) : SendEvent()
- data class AddressContinue(val data: String) : SendEvent()
+ data object AddressReset : SendEvent
+ data class AddressChange(val value: String) : SendEvent
+ data class AddressContinue(val data: String) : SendEvent
- data object AmountReset : SendEvent()
- data class AmountContinue(val amount: String) : SendEvent()
- data class AmountChange(val value: String) : SendEvent()
+ data object AmountReset : SendEvent
+ data class AmountContinue(val amount: String) : SendEvent
+ data class AmountChange(val value: String) : SendEvent
- data class CoinSelectionContinue(val utxos: List) : SendEvent()
+ data class CoinSelectionContinue(val utxos: List) : SendEvent
- data class CommentChange(val value: String) : SendEvent()
+ data class CommentChange(val value: String) : SendEvent
- data object SwipeToPay : SendEvent()
- data object SpeedAndFee : SendEvent()
- data object PaymentMethodSwitch : SendEvent()
- data object ConfirmAmountWarning : SendEvent()
- data object DismissAmountWarning : SendEvent()
- data object PayConfirmed : SendEvent()
+ data object SwipeToPay : SendEvent
+ data object SpeedAndFee : SendEvent
+ data object PaymentMethodSwitch : SendEvent
+ data object ConfirmAmountWarning : SendEvent
+ data object DismissAmountWarning : SendEvent
+ data object PayConfirmed : SendEvent
+ data object BackToAmount : SendEvent
+ data object NavToAddress : SendEvent
}
sealed interface LnurlParams {
diff --git a/docs/e2e-test-ids.md b/docs/e2e-test-ids.md
new file mode 100644
index 000000000..e6c98bf62
--- /dev/null
+++ b/docs/e2e-test-ids.md
@@ -0,0 +1,671 @@
+## RN e2e testIDs vs Android Compose testTags
+
+Legend:
+- ✅ = present in Android
+- ❌ = missing in Android
+- 🚫 = Descoped in Anroid
+
+### backup.e2e.js
+| RN testID | Android Status |
+| - | - |
+| Activity-1 | ✅ |
+| ActivitySavings | ✅ |
+| ActivityTag | ✅ |
+| ActivityTags | ✅ |
+| BlocksWidget | ✅ |
+| CurrenciesSettings | ✅ |
+| DrawerSettings | ✅ |
+| GeneralSettings | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| MoneyFiatSymbol | ✅ |
+| NavigationClose | ✅ |
+| NewsWidget | ✅ |
+| PriceWidget | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| Tag-${tag} | ✅ |
+| TagInput | ✅ |
+| TotalBalance | ✅ |
+| WidgetActionDelete | ✅ |
+| WidgetsEdit | ✅ |
+
+### boost.e2e.js
+| RN testID | Android Status |
+| - | - |
+| ActivityAmount | ✅ |
+| ActivityFee | ✅ |
+| ActivityShort-1 | ✅ |
+| ActivityShort-2 | ✅ |
+| ActivityShort-3 | ✅ |
+| ActivityTxDetails | ✅ |
+| AddressContinue | ✅ |
+| BoostButton | ✅ |
+| BoostDisabled | ✅ |
+| BoostedButton | ✅ |
+| BoostingIcon | ✅ |
+| CPFPBoost | ✅ |
+| CPFPBoosted | ✅ |
+| Close | ✅ |
+| ContinueAmount | ✅ |
+| CustomFeeButton | ✅ |
+| DevOptions | ✅ |
+| DevSettings | ✅ |
+| DrawerSettings | ✅ |
+| GRAB | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| Minus | ✅ |
+| MoneyText | ✅ |
+| N0 | ✅ |
+| N000 | ✅ |
+| N1 | ✅ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| Plus | ✅ |
+| QRCode | ✅ |
+| RBF | 🚫 |
+| RBFBoost | ✅ |
+| RBFBoosted | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| ReceivedTransactionButton | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| RecomendedFeeButton | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSuccess | ✅ |
+| StatusBoosting | ✅ |
+| StatusConfirmed | ✅ |
+| TXID | ✅ |
+| TotalBalance | ✅ |
+
+### lightning.e2e.js
+| RN testID | Android Status |
+| - | - |
+| Activity-1 | ✅ |
+| Activity-2 | ✅ |
+| Activity-3 | ✅ |
+| Activity-4 | ✅ |
+| Activity-5 | ✅ |
+| ActivityShort-1 | ✅ |
+| ActivityShort-2 | ✅ |
+| ActivityShort-3 | ✅ |
+| ActivityShowAll | ✅ |
+| AddressContinue | ✅ |
+| AdvancedSettings | ✅ |
+| Channel | ✅ |
+| ChannelScrollView | ✅ |
+| Channels | ✅ |
+| Close | ✅ |
+| CloseConnection | ✅ |
+| CloseConnectionButton | ✅ |
+| ContinueAmount | ✅ |
+| DrawerSettings | ✅ |
+| ExternalContinue | ✅ |
+| FundCustom | ✅ |
+| FundManual | ✅ |
+| GRAB | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| HostInput | ✅ |
+| InvoiceNote | ✅ |
+| IsUsableYes | ✅ |
+| LDKNodeID | ✅ |
+| LightningNodeInfo | ✅ |
+| MoneySign | ✅ |
+| MoneyText | ✅ |
+| N1 | ✅ |
+| NavigationAction | ✅ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| NodeIdInput | ✅ |
+| PortInput | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceiveLightningInvoice | ✅ |
+| ReceiveNote | ✅ |
+| ReceiveNumberPad | ✅ |
+| ReceiveNumberPadSubmit | ✅ |
+| ReceiveNumberPadTextField | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| ReviewAmount-primary | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSuccess | ✅ |
+| ShowQrReceive | ✅ |
+| SpecifyInvoiceButton | ✅ |
+| Tab-all | ✅ |
+| Tab-other | ✅ |
+| Tab-received | ✅ |
+| Tab-sent | ✅ |
+| Tag-rtag | ✅ |
+| Tag-rtag-delete | ✅ |
+| Tag-stag | ✅ |
+| Tag-stag-delete | ✅ |
+| TagInputReceive | ✅ |
+| TagInputSend | ✅ |
+| TagsAdd | ✅ |
+| TagsAddSend | ✅ |
+| TagsPrompt | ✅ |
+| TotalBalance | ✅ |
+| TotalSize | ✅ |
+
+### lnurl.e2e.js
+| RN testID | Android Status |
+| - | - |
+| ActivityShort-1 | ✅ |
+| AddressContinue | ✅ |
+| AdvancedSettings | ✅ |
+| Close | ✅ |
+| CommentInput | ✅ |
+| ConnectButton | ✅ |
+| ContinueAmount | ✅ |
+| DevOptions | ✅ |
+| DialogConfirm | ✅ |
+| DrawerSettings | ✅ |
+| ExternalSuccess | ✅ |
+| ExternalSuccess-button | ✅ |
+| GRAB | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| InvoiceComment | ❌ |
+| LDKNodeID | ✅ |
+| LightningNodeInfo | ✅ |
+| MoneyText | ✅ |
+| N0 | ✅ |
+| N1 | ✅ |
+| N2 | ✅ |
+| N3 | ✅ |
+| NavigationClose | ✅ |
+| QRInput | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| ReviewAmount-primary | ✅ |
+| Scan | ✅ |
+| ScanPrompt | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSuccess | ✅ |
+| WithdrawConfirmButton | ✅ |
+
+### numberpad.e2e.js
+| RN testID | Android Status |
+| - | - |
+| DenominationClassic | ✅ |
+| DrawerSettings | ✅ |
+| GeneralSettings | ✅ |
+| HeaderMenu | ✅ |
+| N0 | ✅ |
+| N000 | ✅ |
+| N1 | ✅ |
+| N2 | ✅ |
+| N3 | ✅ |
+| N4 | ✅ |
+| N6 | ✅ |
+| N9 | ✅ |
+| NDecimal | ✅ |
+| NRemove | ✅ |
+| NavigationClose | ✅ |
+| Receive | ✅ |
+| ReceiveNumberPad | ✅ |
+| ReceiveNumberPadTextField | ✅ |
+| ReceiveNumberPadUnit | ✅ |
+| SpecifyInvoiceButton | ✅ |
+| UnitSettings | ✅ |
+
+### onboarding.e2e.js
+| RN testID | Android Status |
+| - | - |
+| Check1 | ✅ |
+| Check2 | ✅ |
+| Continue | ✅ |
+| CreateNewWallet | ✅ |
+| GetStarted | ✅ |
+| Passphrase | ✅ |
+| PassphraseInput | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| SkipButton | ✅ |
+| Slide0 | ✅ |
+| Slide1 | ✅ |
+| Slide2 | ✅ |
+| Slide3 | ✅ |
+| WalletOnboardingClose | ✅ |
+
+### onchain.e2e.js
+| RN testID | Android Status |
+| - | - |
+| Activity-1 | ✅ |
+| Activity-2 | ✅ |
+| Activity-3 | ✅ |
+| Activity-4 | ✅ |
+| ActivityShort-1 | ✅ |
+| ActivityShort-2 | ✅ |
+| ActivityShort-3 | ✅ |
+| ActivityShowAll | ✅ |
+| ActivityTxDetails | ✅ |
+| AddressContinue | ✅ |
+| AvailableAmount | ✅ |
+| CalendarApplyButton | ✅ |
+| CalendarClearButton | ✅ |
+| Close | ✅ |
+| ContinueAmount | ✅ |
+| DatePicker | ✅ |
+| Day-1 | ❌ |
+| Day-28 | ❌ |
+| DialogConfirm | ✅ |
+| DrawerSettings | ✅ |
+| GRAB | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| MoneySign | ✅ |
+| MoneyText | ✅ |
+| N${num} | ✅ |
+| NRemove | ✅ |
+| NavigationClose | ✅ |
+| NextMonth | ❌ |
+| PrevMonth | ❌ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| SecuritySettings | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendAmountWarning | ✅ |
+| SendDialog1 | ✅ |
+| SendDialog2 | ✅ |
+| SendSuccess | ✅ |
+| ShowQrReceive | ✅ |
+| SpecifyInvoiceButton | ✅ |
+| Tab-all | ✅ |
+| Tab-other | ✅ |
+| Tab-received | ✅ |
+| Tab-sent | ✅ |
+| Tag-rtag0 | ✅ |
+| Tag-rtag0-delete | ✅ |
+| Tag-stag | ✅ |
+| Tag-stag-delete | ✅ |
+| TagInputReceive | ✅ |
+| TagInputSend | ✅ |
+| TagsAdd | ✅ |
+| TagsAddSend | ✅ |
+| TagsPrompt | ✅ |
+| Today | ❌ |
+| TotalBalance | ✅ |
+
+### receive.e2e.js
+| RN testID | Android Status |
+| - | - |
+| N1 | ✅ |
+| N2 | ✅ |
+| N3 | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceiveNote | ✅ |
+| ReceiveNumberPad | ✅ |
+| ReceiveNumberPadSubmit | ✅ |
+| ReceiveNumberPadTextField | ✅ |
+| ReceiveOnchainInvoice | ✅ |
+| ReceiveScreen | ✅ |
+| ReceiveSlider | ✅ |
+| ReceiveTagsSubmit | ✅ |
+| ShowQrReceive | ✅ |
+| SpecifyInvoiceButton | ✅ |
+| Tag-${tag} | ✅ |
+| Tag-${tag}-delete | ✅ |
+| TagInputReceive | ✅ |
+| TagsAdd | ✅ |
+
+### security.e2e.js
+| RN testID | Android Status |
+| - | - |
+| AddressContinue | ✅ |
+| AttemptsRemaining | ✅ |
+| Biometrics | ✅ |
+| ChangePIN | ✅ |
+| ChangePIN2 | ✅ |
+| Check1 | ✅ |
+| Close | ✅ |
+| ContinueAmount | ✅ |
+| ContinueButton | ✅ |
+| DisablePin | ✅ |
+| DrawerSettings | ✅ |
+| ForgotPIN | ✅ |
+| GRAB | ✅ |
+| HeaderMenu | ✅ |
+| LastAttempt | ✅ |
+| N000 | ✅ |
+| N1 | ✅ |
+| N2 | ✅ |
+| N3 | ✅ |
+| N9 | ✅ |
+| NRemove | ✅ |
+| OK | ✅ |
+| PINChange | ✅ |
+| PINCode | ✅ |
+| PinPad | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| SecureWallet-button-continue | ✅ |
+| SecuritySettings | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSuccess | ✅ |
+| ToggleBioForPayments | ✅ |
+| ToggleBiometrics | ✅ |
+| TotalBalance | ✅ |
+| UseBiometryInstead | ✅ |
+| WrongPIN | ✅ |
+
+### send.e2e.js
+| RN testID | Android Status |
+| - | - |
+| AddressContinue | ✅ |
+| AdvancedSettings | ✅ |
+| AssetButton-savings | ✅ |
+| AssetButton-spending | ✅ |
+| AssetButton-switch | ✅ |
+| AvailableAmount | ✅ |
+| Channel | ✅ |
+| ChannelScrollView | ✅ |
+| Channels | ✅ |
+| Close | ✅ |
+| ContinueAmount | ✅ |
+| DrawerSettings | ✅ |
+| ExternalContinue | ✅ |
+| FundCustom | ✅ |
+| FundManual | ✅ |
+| GRAB | ✅ |
+| GeneralSettings | ✅ |
+| HeaderMenu | ✅ |
+| HostInput | ✅ |
+| IsUsableYes | ✅ |
+| LDKNodeID | ✅ |
+| LightningNodeInfo | ✅ |
+| MoneyText | ✅ |
+| N0 | ✅ |
+| N1 | ✅ |
+| N2 | ✅ |
+| NRemove | ✅ |
+| NavigationAction | ✅ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| NodeIdInput | ✅ |
+| PortInput | ✅ |
+| QRCode | ✅ |
+| QuickpayIntro-button | ✅ |
+| QuickpaySettings | ✅ |
+| QuickpayToggle | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| ReviewAmount | ✅ |
+| ReviewAmount-primary | ✅ |
+| ReviewUri | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSheet | ✅ |
+| SendSuccess | ✅ |
+| TotalBalance | ✅ |
+| TotalSize | ✅ |
+
+### settings.e2e.js
+| RN testID | Android Status |
+| - | - |
+| About | ✅ |
+| AboutLogo | ✅ |
+| Address-0 | ✅ |
+| AddressTypePreference | 🚫 |
+| AddressViewer | ✅ |
+| AdvancedSettings | ✅ |
+| AppStatus | ✅ |
+| BackupSettings | ✅ |
+| BackupWallet | ✅ |
+| Bitcoin | ✅ |
+| ConnectToHost | ✅ |
+| ConnectToUrl | 🚫 |
+| Connected | ✅ |
+| ConnectedUrl | ✅ |
+| Continue | ✅ |
+| ContinueConfirmMnemonic | ✅ |
+| ContinueShowMnemonic | ✅ |
+| CopyNodeId | 🚫 |
+| CurrenciesSettings | ✅ |
+| CustomFee | ✅ |
+| DenominationClassic | ✅ |
+| DevOptions | ✅ |
+| DevSettings | ✅ |
+| DialogConfirm | ✅ |
+| Disconnected | ✅ |
+| DrawerSettings | ✅ |
+| ElectrumConfig | ✅ |
+| ElectrumProtocol | ✅ |
+| ElectrumStatus | ✅ |
+| ErrorReport | 🚫 |
+| GeneralSettings | ✅ |
+| HeaderMenu | ✅ |
+| HideBalanceOnOpen | ✅ |
+| HostInput | ✅ |
+| LDKDebug | 🚫 |
+| LightningNodeInfo | ✅ |
+| MoneyFiatSymbol | ✅ |
+| MoneyText | ✅ |
+| N1 | ✅ |
+| NavigationAction | ✅ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| OK | ✅ |
+| Path | ✅ |
+| PortInput | ✅ |
+| QRCode | ✅ |
+| QRInput | ✅ |
+| RGSServer | ✅ |
+| RGSUrl | ✅ |
+| RebroadcastLDKTXS | 🚫 |
+| Receive | ✅ |
+| ReceiveScreen | ✅ |
+| ReceiveTagsSubmit | ✅ |
+| RefreshLDK | 🚫 |
+| ResetAndRestore | ✅ |
+| ResetSuggestions | ✅ |
+| ResetToDefault | ✅ |
+| RestartLDK | 🚫 |
+| ScanPrompt | ✅ |
+| SecuritySettings | ✅ |
+| SeedContaider | ✅ |
+| ShowBalance | ✅ |
+| SpecifyInvoiceButton | ✅ |
+| Status-backup | ✅ |
+| Status-electrum | ✅ |
+| Status-internet | ✅ |
+| Status-lightning_connection | ✅ |
+| Status-lightning_node | ✅ |
+| Suggestion-lightning | ✅ |
+| SuggestionDismiss | ✅ |
+| Suggestions | ✅ |
+| Support | ✅ |
+| SwipeBalanceToHide | ✅ |
+| Tag-${tag}-delete | ✅ |
+| TagInputReceive | ✅ |
+| TagsAdd | ✅ |
+| TagsSettings | ✅ |
+| TapToReveal | ✅ |
+| TotalBalance | ✅ |
+| TransactionSpeedSettings | ✅ |
+| TriggerRenderError | 🚫 |
+| USD | ✅ |
+| UnitSettings | ✅ |
+| UrlInput | 🚫 |
+| Value | ✅ |
+| WebRelay | 🚫 |
+| WebRelayStatus | 🚫 |
+| Word-${word} | ✅ |
+| custom | ✅ |
+| fast | ✅ |
+| normal | ✅ |
+| p2pkh | 🚫 |
+| p2wpkh | 🚫 |
+
+### slashtags.e2e.js
+| RN testID | Android Status |
+| - | - |
+| Activity-1 | ✅ |
+| ActivityAssign | ❌ |
+| ActivityDetach | ❌ |
+| ActivitySavings | ✅ |
+| AddContact | ❌ |
+| AddContactButton | ❌ |
+| BioInput | ❌ |
+| ContactSmall | ❌ |
+| ContactURLInput | ❌ |
+| ContactURLInput-error | ❌ |
+| ContactsOnboarding-button | ❌ |
+| ContactsSearchInput | ❌ |
+| CopyButton | ❌ |
+| DeleteContactButton | ❌ |
+| DeleteDialog | ❌ |
+| DialogConfirm | ✅ |
+| DrawerContacts | ✅ |
+| EditButton | ❌ |
+| EmptyProfileHeader | ✅ |
+| Header | ✅ |
+| HeaderMenu | ✅ |
+| LinkLabelInput | ❌ |
+| LinkValueInput | ❌ |
+| NameInput | ❌ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| OnboardingContinue | ❌ |
+| ProfileAddLink | ❌ |
+| ProfileDeleteButton | ❌ |
+| ProfileLinkSuggestions | ❌ |
+| ProfileSaveButton | ❌ |
+| ProfileSlashtag | ❌ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| RemoveLinkButton | ❌ |
+| SaveContactButton | ❌ |
+| SaveLink | ❌ |
+
+### transfer.e2e.js
+| RN testID | Android Status |
+| - | - |
+| ActivitySavings | ✅ |
+| ActivityShort-1 | ✅ |
+| ActivitySpending | ✅ |
+| AddressContinue | ✅ |
+| AdvancedSettings | ✅ |
+| AvailabilityContinue | ✅ |
+| BoostButton | ✅ |
+| BoostingIcon | ✅ |
+| CPFPBoost | ✅ |
+| Channel | ✅ |
+| ChannelScrollView | ✅ |
+| Channels | ✅ |
+| ChannelsClosed | ✅ |
+| Close | ✅ |
+| ContinueAmount | ✅ |
+| CurrenciesSettings | ✅ |
+| DrawerSettings | ✅ |
+| ExternalAmount | ✅ |
+| ExternalAmountContinue | ✅ |
+| ExternalContinue | ✅ |
+| ExternalSuccess | ✅ |
+| ExternalSuccess-button | ✅ |
+| FeeCustomContinue | ✅ |
+| FeeCustomNumberPad | ✅ |
+| FundCustom | ✅ |
+| FundManual | ✅ |
+| FundTransfer | ✅ |
+| GRAB | ✅ |
+| GeneralSettings | ✅ |
+| HeaderMenu | ✅ |
+| HomeScrollView | ✅ |
+| HostInput | ✅ |
+| IsUsableYes | ✅ |
+| LDKNodeID | ✅ |
+| LightningNodeInfo | ✅ |
+| LightningSettingUp | ✅ |
+| LiquidityContinue | ✅ |
+| MoneyText | ✅ |
+| N0 | ✅ |
+| N1 | ✅ |
+| N2 | ✅ |
+| N5 | ✅ |
+| NRemove | ✅ |
+| NavigationAction | ✅ |
+| NavigationBack | ✅ |
+| NavigationClose | ✅ |
+| NodeIdInput | ✅ |
+| PortInput | ✅ |
+| QRCode | ✅ |
+| Receive | ✅ |
+| ReceivedTransaction | ✅ |
+| RecipientInput | ✅ |
+| RecipientManual | ✅ |
+| SavingsIntro-button | ✅ |
+| Send | ✅ |
+| SendAmountNumberPad | ✅ |
+| SendSuccess | ✅ |
+| SetCustomFee | ✅ |
+| SpendingAdvanced | ✅ |
+| SpendingAdvancedContinue | ✅ |
+| SpendingAdvancedDefault | ✅ |
+| SpendingAdvancedMax | ✅ |
+| SpendingAdvancedMin | ✅ |
+| SpendingAdvancedNumberField | ✅ |
+| SpendingAmount | |
+| SpendingAmountContinue | ✅ |
+| SpendingAmountMax | ✅ |
+| SpendingAmountQuarter | ✅ |
+| SpendingConfirmAdvanced | ✅ |
+| SpendingConfirmChannel | ✅ |
+| SpendingConfirmDefault | ✅ |
+| SpendingConfirmMore | ✅ |
+| SpendingIntro-button | ✅ |
+| StatusBoosting | ✅ |
+| StatusTransfer | ✅ |
+| Suggestion-lightning | ✅ |
+| Suggestion-lightningSettingUp | ❌ |
+| TotalBalance | ✅ |
+| TotalSize | ✅ |
+| TransferIntro-button | ✅ |
+| TransferSuccess | ✅ |
+| TransferSuccess-button | ✅ |
+| TransferToSavings | ✅ |
+| TransferToSpending | ✅ |
+
+### widgets.e2e.js
+| RN testID | Android Status |
+| - | - |
+| HomeScrollView | ✅ |
+| PriceWidget | ✅ |
+| PriceWidgetRow-BTC/EUR | ✅ |
+| PriceWidgetSource | ✅ |
+| WidgetActionDelete | ✅ |
+| WidgetActionEdit | ✅ |
+| WidgetEdit | ✅ |
+| WidgetEditField-1W | ✅ |
+| WidgetEditField-BTC/EUR | ✅ |
+| WidgetEditField-showSource | ✅ |
+| WidgetEditPreview | ✅ |
+| WidgetEditReset | ✅ |
+| WidgetEditScrollView | ✅ |
+| WidgetListItem-price | ✅ |
+| WidgetSave | ✅ |
+| WidgetsAdd | ✅ |
+| WidgetsEdit | ✅ |
+| WidgetsOnboarding-button | ✅ |
diff --git a/docs/screens-map.md b/docs/screens-map.md
new file mode 100644
index 000000000..727bd129b
--- /dev/null
+++ b/docs/screens-map.md
@@ -0,0 +1,173 @@
+# RN ↔ Android screens mapping
+
+Legend: RN = React Native screen, Android = Compose screen
+
+## Wallet
+| RN | Android |
+| - | - |
+| Home.tsx | HomeScreen.kt |
+| ActivitySavings.tsx | SavingsWalletScreen.kt |
+| ActivitySpending.tsx | SpendingWalletScreen.kt |
+
+## Activity
+| RN | Android |
+| - | - |
+| ActivityFiltered.tsx | AllActivityScreen.kt |
+| ActivityDetail.tsx | ActivityDetailScreen.kt + ActivityExploreScreen.kt |
+
+## Send
+| RN | Android |
+| - | - |
+| Send/Amount.tsx | SendAmountScreen.kt |
+| Recipient.tsx | SendRecipientScreen.kt |
+| Address.tsx | SendAddressScreen.kt |
+| ReviewAndSend.tsx | SendConfirmScreen.kt |
+| FeeRate.tsx | SendFeeRateScreen.kt |
+| FeeCustom.tsx | SendFeeCustomScreen.kt |
+| CoinSelection.tsx | SendCoinSelectionScreen.kt |
+| SendPinPad.tsx | SendPinCheckScreen.kt |
+| Quickpay.tsx | SendQuickPayScreen.kt |
+| Tags.tsx | AddTagScreen.kt |
+| Error.tsx | SendErrorScreen.kt |
+| Pending.tsx | `todo` |
+| Send/Success.tsx | `todo` |
+
+## Receive
+| RN | Android |
+| - | - |
+| ReceiveDetails.tsx | EditInvoiceScreen.kt |
+| ReceiveAmount.tsx | ReceiveAmountScreen.kt |
+| ReceiveQR.tsx | ReceiveQrScreen.kt |
+| ReceiveConnect.tsx | ReceiveConfirmScreen.kt |
+| ReceiveGeoBlocked.tsx | LocationBlockScreen.kt |
+| Receive/Liquidity.tsx | ReceiveLiquidityScreen.kt |
+
+## Scanner
+| RN | Android |
+| - | - |
+| MainScanner.tsx | QrScanningScreen.kt |
+
+## Transfer
+| RN | Android |
+| - | - |
+| TransferIntro.tsx | TransferIntroScreen.kt |
+| SpendingIntro.tsx | SpendingIntroScreen.kt |
+| SpendingConfirm.tsx | SpendingConfirmScreen.kt |
+| SavingsIntro.tsx | SavingsIntroScreen.kt |
+| SavingsConfirm.tsx | SavingsConfirmScreen.kt |
+| SavingsProgress.tsx | SavingsProgressScreen.kt |
+| SavingsAdvanced.tsx | SavingsAdvancedScreen.kt |
+| SpendingAmount.tsx | SpendingAmountScreen.kt |
+| Funding.tsx | FundingScreen.kt |
+| FundingAdvanced.tsx | FundingAdvancedScreen.kt |
+| SettingUp.tsx | SettingUpScreen.kt |
+| Transfer/Liquidity.tsx | LiquidityScreen.kt |
+| Availability.tsx | SavingsAvailabilityScreen.kt |
+
+## External Node / LNURL Channel
+| RN | Android |
+| - | - |
+| Connection.tsx | ExternalConnectionScreen.kt |
+| ExternalNode/Amount.tsx | ExternalAmountScreen.kt |
+| Confirm.tsx | ExternalConfirmScreen.kt |
+| ExternalNode/Success.tsx | ExternalSuccessScreen.kt |
+| LNURLChannel.tsx | LnurlChannelScreen.kt |
+
+## Lnurl
+| RN | Android |
+| - | - |
+| LNURLWithdraw/Amount.tsx | SendAmountScreen.kt |
+| LNURLWithdraw/Confirm.tsx | WithdrawConfirmScreen.kt |
+| `n/a` | WithdrawErrorScreen.kt |
+| `n/a` | LnurlAuthSheet.kt |
+
+## Settings
+| RN | Android |
+| - | - |
+| Settings/index.tsx | SettingsScreen.kt |
+| General/index.tsx | GeneralSettingsScreen.kt |
+| Currencies/index.tsx | LocalCurrencySettingsScreen.kt |
+| Unit/index.tsx | DefaultUnitSettingsScreen.kt |
+| Tags/index.tsx | TagsSettingsScreen.kt |
+| Advanced/index.tsx | AdvancedSettingsScreen.kt |
+| AddressTypePreference/index.tsx | `n/a` |
+| BitcoinNetworkSelection.tsx | `n/a` |
+| CoinSelectPreference/index.tsx | CoinSelectPreferenceScreen.kt |
+| AddressViewer/index.tsx | AddressViewerScreen.kt |
+| GapLimit/index.tsx | `n/a` |
+| About/index.tsx | AboutScreen.kt |
+| AppStatus/index.tsx | AppStatusScreen.kt |
+| Widgets/index.tsx | AddWidgetsScreen.kt / WidgetsIntroScreen.kt |
+| WebRelay/index.tsx | `n/a` |
+| TransactionSpeed/index.tsx | TransactionSpeedSettingsScreen.kt |
+| CustomFee.tsx | CustomFeeSettingsScreen.kt |
+| QuickpayIntro.tsx | QuickPayIntroScreen.kt |
+| QuickpaySettings.tsx | QuickPaySettingsScreen.kt |
+| RGSServer/index.tsx | RgsServerScreen.kt |
+| SupportSettings/index.tsx | SupportScreen.kt |
+| ReportIssue/index.tsx | ReportIssueScreen.kt |
+| FormSuccess.tsx | ReportIssueResultScreen.kt |
+| DevSettings/index.tsx | DevSettingsScreen.kt |
+| LdkDebug.tsx | `n/a` |
+| Channels.tsx | LightningConnectionsScreen.kt |
+| ChannelDetails.tsx | ChannelDetailScreen.kt |
+| CloseConnection.tsx | CloseConnectionScreen.kt |
+| LightningNodeInfo.tsx | NodeInfoScreen.kt |
+| BackupSettings/index.tsx | BackupSettingsScreen.kt |
+
+## Backup & Recovery
+| RN | Android |
+| - | - |
+| Warning.tsx | WarningScreen.kt |
+| Backup/Success.tsx | SuccessScreen.kt |
+| ShowPassphrase.tsx | ShowPassphraseScreen.kt |
+| ShowMnemonic.tsx | ShowMnemonicScreen.kt |
+| Backup/MultipleDevices.tsx | MultipleDevicesScreen.kt |
+| Metadata.tsx | MetadataScreen.kt |
+| ConfirmPassphrase.tsx | ConfirmPassphraseScreen.kt |
+| ConfirmMnemonic.tsx | ConfirmMnemonicScreen.kt |
+| ResetAndRestore.tsx | ResetAndRestoreScreen.kt |
+
+## Onboarding
+| RN | Android |
+| - | - |
+| Welcome.tsx | OnboardingSlidesScreen.kt / IntroScreen.kt |
+| Slideshow.tsx | OnboardingSlidesScreen.kt |
+| Passphrase.tsx | CreateWalletWithPassphraseScreen.kt |
+| RestoreFromSeed.tsx | RestoreWalletScreen.kt |
+| Loading.tsx | InitializingWalletView.kt |
+| Onboarding/MultipleDevices.tsx | WarningMultipleDevicesScreen.kt |
+| TermsOfUse.tsx | TermsOfUseScreen.kt |
+| CreateWallet.tsx | WalletRestoreSuccessView.kt + WalletRestoreErrorView.kt |
+
+## Profile & Contacts
+| RN | Android |
+| - | - |
+| Contacts.tsx | `todo` |
+| Contact.tsx | `todo` |
+| Profile.tsx | CreateProfileScreen.kt / ProfileIntroScreen.kt |
+| ProfileEdit.tsx | CreateProfileScreen.kt |
+| ProfileOnboarding.tsx | ProfileIntroScreen.kt |
+| ProfileLink.tsx | CreateProfileScreen.kt |
+
+## Widgets
+| RN | Android |
+| - | - |
+| Widget.tsx | widgets/*Card.kt |
+| WidgetEdit.tsx | widgets/*EditScreen.kt |
+| WidgetsOnboarding.tsx | WidgetsIntroScreen.kt |
+| WidgetsSuggestions.tsx | AddWidgetsScreen.kt |
+
+## Shop
+| RN | Android |
+| - | - |
+| ShopIntro.tsx | ShopIntroScreen.kt |
+| ShopDiscover.tsx | ShopDiscoverScreen.kt |
+| ShopMain.tsx | ShopWebViewScreen.kt |
+
+## Sheets
+| RN | Android |
+| - | - |
+| ReceivedTransaction.tsx | NewTransactionSheet.kt |
+| TransferFailed.tsx | todo |
+| AppUpdate.tsx | `todo` |