diff --git a/common/routing/detekt-baseline-debug.xml b/common/routing/detekt-baseline-debug.xml new file mode 100644 index 0000000000..84f08bf7e3 --- /dev/null +++ b/common/routing/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + BooleanPropertyNaming:AppRoute.kt$AppRoute.CreateWalletBackup$val setAccessCode: Boolean = false + NestedScopeFunctions:PayloadToDeeplinkConverter.kt$PayloadToDeeplinkConverter$let { addQueryParam(NAME_KEY, it) } + NestedScopeFunctions:PayloadToDeeplinkConverter.kt$PayloadToDeeplinkConverter$let { addQueryParam(TRANSACTION_ID_KEY, it) } + + diff --git a/common/test/detekt-baseline-debug.xml b/common/test/detekt-baseline-debug.xml new file mode 100644 index 0000000000..27ff65dbe7 --- /dev/null +++ b/common/test/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + CastNullableToNonNullableType:MockScanResponseFactory.kt$MockScanResponseFactory$as + MultilineLambdaItParameter:MockScanResponseFactory.kt$MockScanResponseFactory${ CardDTO.Wallet( CardWallet( publicKey = it.name.toByteArray(), // IMPORTANT: public key must equal to curve name chainCode = null, curve = it, settings = createSettings(), totalSignedHashes = null, remainingSignatures = null, index = 0, isImported = true, hasBackup = true, derivedKeys = emptyMap(), ), ) } + + diff --git a/common/ui-charts/detekt-baseline-debug.xml b/common/ui-charts/detekt-baseline-debug.xml new file mode 100644 index 0000000000..05694da92a --- /dev/null +++ b/common/ui-charts/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + SuspendFunSwallowedCancellation:MarketChartDataProducer.kt$MarketChartDataProducer$runCatching + + diff --git a/common/ui/detekt-baseline-debug.xml b/common/ui/detekt-baseline-debug.xml new file mode 100644 index 0000000000..76624db4ad --- /dev/null +++ b/common/ui/detekt-baseline-debug.xml @@ -0,0 +1,32 @@ + + + + + BooleanPropertyNaming:AddTokenUM.kt$AddTokenUM.Button$val showProgress: Boolean + BooleanPropertyNaming:AddTokenUM.kt$AddTokenUM.Network$val editable: Boolean + BooleanPropertyNaming:AmountCurrencyTransformer.kt$AmountCurrencyTransformer$private val value: Boolean + BooleanPropertyNaming:GiveTxPermissionState.kt$CancelPermissionButton$val enabled: Boolean + BooleanPropertyNaming:NotificationUM.kt$NotificationUM.Error.ExceedsBalance$val mergeFeeNetworkName: Boolean = false + BooleanPropertyNaming:NotificationsFactory.kt$NotificationsFactory$val showNotification = sendingAmount + feeAmount > balance - minimumRequirement.orZero() + BooleanPropertyNaming:TokenReceiveBottomSheetConfig.kt$TokenReceiveBottomSheetConfig$val showMemoDisclaimer: Boolean + CanBeNonNullable:AmountBlockV2.kt$onClick: (() -> Unit)? = null + CanBeNonNullable:NavigationButtonsBlock.kt$footerText: TextReference? + CanBeNonNullable:NavigationButtonsBlock.kt$pairButtons: Pair<NavigationButton, NavigationButton>? + CanBeNonNullable:NavigationButtonsBlock.kt$prevButton: NavigationButton? + CanBeNonNullable:NotificationsFactory.kt$NotificationsFactory$dustValue: BigDecimal? + CanBeNonNullable:NotificationsFactory.kt$NotificationsFactory$minAdaValue: BigDecimal? + CanBeNonNullable:NotificationsFactory.kt$NotificationsFactory$minimumSendAmount: BigDecimal? + CanBeNonNullable:NotificationsFactory.kt$NotificationsFactory$rentWarning: CryptoCurrencyWarning.Rent? + MultilineLambdaItParameter:ExpressStatusItems.kt${ val itemInfo = expressTxs[it].info val (iconRes, tint) = when (itemInfo.iconState) { ExpressTransactionStateIconUM.Warning -> { R.drawable.ic_alert_triangle_20 to TangemTheme.colors.icon.attention } ExpressTransactionStateIconUM.Error -> { R.drawable.ic_alert_circle_24 to TangemTheme.colors.icon.warning } ExpressTransactionStateIconUM.None -> null to null } ExpressStatusItem( title = itemInfo.title, fromTokenIconState = itemInfo.fromCurrencyIcon, toTokenIconState = itemInfo.toCurrencyIcon, fromAmount = itemInfo.fromAmount, fromSymbol = itemInfo.fromAmountSymbol, toAmount = itemInfo.toAmount, toSymbol = itemInfo.toAmountSymbol, onClick = itemInfo.onClick, infoIconRes = iconRes, infoIconTint = tint, modifier = modifier.animateItem(), ) } + MultilineLambdaItParameter:TokenItemStateConverter.kt$TokenItemStateConverter${ createTitleState(it, yieldModuleApyMap, stakingApyMap, { onApyLabelClick?.invoke(it) }) } + MultilineLambdaItParameter:TokenItemStateConverter.kt$TokenItemStateConverter.Companion${ it.key.equals( other = token.yieldSupplyKey(), ignoreCase = BlockchainUtils.isCaseInsensitiveContractAddress(token.network.rawId), ) } + NamedArguments:TokenItemStateConverter.kt$TokenItemStateConverter$createTitleState(it, yieldModuleApyMap, stakingApyMap, { onApyLabelClick?.invoke(it) }) + NoNameShadowing:NavigationButtonsBlock.kt$navigationUM + NoNameShadowing:UserWalletItem.kt$balance + NullableBooleanCheck:TokenItemStateConverter.kt$TokenItemStateConverter.Companion$cryptoCurrencyStatus.value.yieldSupplyStatus?.isActive ?: false + NullableToStringCall:TokenItemStateConverter.kt$TokenItemStateConverter.Companion$${id.rawCurrencyId} + ReusedModifierInstance:AddTokenContent.kt$AddButton( modifier = modifier.fillMaxWidth(), state = state.button, ) + UnnecessaryEventHandlerParameter:SendDoneButtons.kt$onShareClick: (String) -> Unit + UnnecessaryLet:TokenItemStateConverter.kt$TokenItemStateConverter.Companion$let(::add) + + diff --git a/core/ab-tests/detekt-baseline-debug.xml b/core/ab-tests/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d3bf1ceb5e --- /dev/null +++ b/core/ab-tests/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + NullableToStringCall:AmplitudeABTestsManager.kt$AmplitudeABTestsManager$${variant.key} + NullableToStringCall:AmplitudeABTestsManager.kt$AmplitudeABTestsManager$${variant.payload} + + diff --git a/core/config-toggles/build.gradle.kts b/core/config-toggles/build.gradle.kts index 0fb16f5ae7..490d2c6fa8 100644 --- a/core/config-toggles/build.gradle.kts +++ b/core/config-toggles/build.gradle.kts @@ -89,9 +89,9 @@ fun Task.generateToggles(inputFilePath: String, generatedFileName: String) { .add("mapOf(\n") .indent() .apply { - entries.forEachIndexed { index, entry -> + entries.forEach { entry -> add(entry) - if (index != entries.lastIndex) add(",\n") else add("\n") + add(",\n") } } .unindent() @@ -113,5 +113,15 @@ fun Task.generateToggles(inputFilePath: String, generatedFileName: String) { val outputPackageDir = File(outputDir, "") outputPackageDir.mkdirs() fileSpec.writeTo(outputPackageDir) + + // Remove redundant public visibility modifiers + val generatedFile = File(outputPackageDir, "com/tangem/core/configtoggle/$generatedFileName.kt") + if (generatedFile.exists()) { + val content = generatedFile.readText() + val fixedContent = content + .replace("public object ", "object ") + .replace("public val ", "val ") + generatedFile.writeText(fixedContent) + } } } \ No newline at end of file diff --git a/core/config-toggles/detekt-baseline-debug.xml b/core/config-toggles/detekt-baseline-debug.xml new file mode 100644 index 0000000000..b0e03ef827 --- /dev/null +++ b/core/config-toggles/detekt-baseline-debug.xml @@ -0,0 +1,10 @@ + + + + + DoubleMutabilityForCollection:DevExcludedBlockchainsManager.kt$DevExcludedBlockchainsManager$private var blockchainTogglesMap: MutableMap<String, Boolean> by Delegates.notNull() + DoubleMutabilityForCollection:DevFeatureTogglesManager.kt$DevFeatureTogglesManager$private var featureTogglesMap: MutableMap<String, Boolean> by Delegates.notNull() + Indentation:ExcludedBlockchainToggles.kt$ExcludedBlockchainToggles$ + Indentation:FeatureToggles.kt$FeatureToggles$ + + diff --git a/core/datasource/detekt-baseline-debug.xml b/core/datasource/detekt-baseline-debug.xml new file mode 100644 index 0000000000..7d14c576a1 --- /dev/null +++ b/core/datasource/detekt-baseline-debug.xml @@ -0,0 +1,17 @@ + + + + + CastNullableToNonNullableType:ApiResponseCallAdapterFactory.kt$ApiResponseCallAdapterFactory$as + MultilineLambdaItParameter:DefaultWalletManagersStore.kt$DefaultWalletManagersStore${ it.wallet.blockchain == walletManager.wallet.blockchain && it.wallet.publicKey.derivationPath == walletManager.wallet.publicKey.derivationPath } + NestedScopeFunctions:PendingActionConverter.kt$PendingActionConverter$let { amount -> PendingAction.PendingActionArgs.Amount( required = amount.required, minimum = amount.minimum, maximum = amount.maximum, ) } + NestedScopeFunctions:PendingActionConverter.kt$PendingActionConverter$let { duration -> PendingAction.PendingActionArgs.Duration( required = duration.required, minimum = duration.minimum, maximum = duration.maximum, ) } + NestedScopeFunctions:PendingActionConverter.kt$PendingActionConverter$let { tronResource -> PendingAction.PendingActionArgs.TronResource( required = tronResource.required, options = tronResource.options, ) } + NestedScopeFunctions:RetrofitApiBuilder.kt$RetrofitApiBuilder$let { withConnectTimeout(timeout = it.duration, unit = it.unit) } + NestedScopeFunctions:RetrofitApiBuilder.kt$RetrofitApiBuilder$let { withReadTimeout(timeout = it.duration, unit = it.unit) } + NestedScopeFunctions:RetrofitApiBuilder.kt$RetrofitApiBuilder$let { withWriteTimeout(timeout = it.duration, unit = it.unit) } + UnreachableCode:MockApiConfigsManager.kt$MockApiConfigsManager$apiConfigs + (apiConfig to environment) + UnreachableCode:MockApiConfigsManager.kt$MockApiConfigsManager$val apiConfig = apiConfigs.keys.firstOrNull { it.id.name == id } ?: error("Api config with id [$id] not found. Check that ApiConfig with id [$id] was provided into DI") + UnusedImports:NetworkModule.kt$import com.tangem.datasource.api.common.config.MoonPay + + diff --git a/core/ui/detekt-baseline-debug.xml b/core/ui/detekt-baseline-debug.xml new file mode 100644 index 0000000000..a625c6029f --- /dev/null +++ b/core/ui/detekt-baseline-debug.xml @@ -0,0 +1,33 @@ + + + + + BooleanPropertyNaming:BigDecimalPercentFormat.kt$BigDecimalPercentFormat$val withPercentSign: Boolean = true + BooleanPropertyNaming:FullScreen.kt$FullScreenLayout$private val focusable: Boolean + BooleanPropertyNaming:TokenItemState.kt$TokenItemState.TitleState.Content$val earnApyIsActive: Boolean = false + CanBeNonNullable:FooterContainer.kt$footer: TextReference? = null + CanBeNonNullable:InputRowImageBase.kt$iconRes: Int? + CanBeNonNullable:InputRowImageInfo.kt$subtitleEndIconRes: Int? + CanBeNonNullable:SearchBar.kt$keyboardController: SoftwareKeyboardController? + CanBeNonNullable:TextFields.kt$caption: String? = null + CanBeNonNullable:TransactionList.kt$txHistoryItems: LazyPagingItems<TxHistoryState.TxHistoryItemState>? + CastNullableToNonNullableType:DialogFullScreen.kt$as + CastNullableToNonNullableType:FullScreen.kt$FullScreenLayout$as + MultilineLambdaItParameter:Actions.kt${ ActionButtonContent( config = config, text = { textColor -> Text(text = config.text, textColor = textColor) }, modifier = it.padding( start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing24, ), ) } + MultilineLambdaItParameter:TangemDropdownMenu.kt${ if (it) { // Menu is expanded. 1f } else { // Menu is dismissed. 0.8f } } + MultilineLambdaItParameter:TangemDropdownMenu.kt${ if (it) { // Menu is expanded. 1f } else { // Menu is dismissed. 0f } } + NestedScopeFunctions:MessageBottomSheetUMV2.kt$apply(init) + NestedScopeFunctions:Shadow.kt$apply { isDither = true isAntiAlias = true setShadowLayer( radiusPx, offset.x.toPx(), offset.y.toPx(), color.toArgb(), ) } + NoNameShadowing:PinTextField.kt$value + NoNameShadowing:SimpleTextField.kt$textStyle + NoNameShadowing:TangemTheme.kt$systemUiController + NoNameShadowing:TextAnimatedCounter.kt$char + PropertyUsedBeforeDeclaration:InputManager.kt$InputManager$_query + ReusedModifierInstance:EllipsisText.kt$Text( text = layoutText, color = color, style = style, fontStyle = fontStyle, textDecoration = textDecoration, textAlign = textAlign, softWrap = softWrap, maxLines = 1, onTextLayout = { textLayoutResultState.value = it }, modifier = modifier, ) + ReusedModifierInstance:Label.kt$Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = modifier .padding(horizontal = 4.dp) .clip(TangemTheme.shapes.roundedCorners8) .background(color = backgroundColor) .then( if (state.onClick != null) { Modifier.clickable( interactionSource = remember { MutableInteractionSource() }, indication = ripple(), onClick = state.onClick, ) } else { Modifier }, ) .padding(horizontal = 8.dp, vertical = 4.dp), ) { Text( modifier = Modifier.weight(1.0f, fill = false), text = text.resolveReference(), style = TangemTheme.typography.caption1, color = textColor, ) AnimatedVisibility(state.icon != null) { val wrappedIcon = remember(this) { requireNotNull(state.icon) } Icon( imageVector = ImageVector.vectorResource(wrappedIcon), tint = iconColor, contentDescription = null, modifier = Modifier .size(16.dp) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = ripple(bounded = false), onClick = { state.onIconClick?.invoke() }, ), ) } } + ReusedModifierInstance:TangemRadioButton.kt$AnimatedVisibility( visible = isSelected, label = "Radio button animation", modifier = modifier .size(TangemTheme.dimens.size24), ) { Icon( painter = painterResource(id = R.drawable.ic_check_circle_24), contentDescription = null, tint = TangemTheme.colors.control.checked, ) } + ReusedModifierInstance:TokenPrice.kt$Icon( modifier = modifier, painter = painterResource( id = when (animatedType) { PriceChangeType.UP -> R.drawable.ic_arrow_up_8 PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8 PriceChangeType.NEUTRAL -> R.drawable.ic_elipse_8 }, ), tint = when (animatedType) { PriceChangeType.UP -> TangemTheme.colors.icon.accent PriceChangeType.DOWN -> TangemTheme.colors.icon.warning PriceChangeType.NEUTRAL -> TangemTheme.colors.icon.inactive }, contentDescription = null, ) + UnnecessaryEventHandlerParameter:PinTextField.kt$onValueChange: (String) -> Unit + UnnecessaryEventHandlerParameter:ResizableText.kt$onFontSizeChange: (Float) -> Unit + + diff --git a/data/account/detekt-baseline-debug.xml b/data/account/detekt-baseline-debug.xml new file mode 100644 index 0000000000..b1e2281ba5 --- /dev/null +++ b/data/account/detekt-baseline-debug.xml @@ -0,0 +1,14 @@ + + + + + CanBeNonNullable:FetchWalletAccountsErrorHandler.kt$FetchWalletAccountsErrorHandler$savedAccountsResponse: GetWalletAccountsResponse? + MultilineLambdaItParameter:DefaultAccountsCRUDRepository.kt$DefaultAccountsCRUDRepository${ if (it is HttpException && it.code == HttpException.Code.NOT_MODIFIED) { null } else { throw it } } + MultilineLambdaItParameter:FetchWalletAccountsErrorHandler.kt$FetchWalletAccountsErrorHandler${ it.copy( tokens = UserTokensResponseAccountIdEnricher(userWalletId = userWalletId, tokens = it.tokens), ) } + MultilineLambdaItParameter:GetWalletAccountsResponseExt.kt${ enrichedTokensByAccountId[it].orEmpty().map { token -> // Tokens from unexisting accounts should be copied to the main account token.copy(accountId = accountDTO.id) } } + NoNameShadowing:GetWalletAccountsResponseExt.kt$tokens + NullableToStringCall:AccountListCryptoCurrenciesProducer.kt$AccountListCryptoCurrenciesProducer$${this::class.simpleName} + NullableToStringCall:DefaultMultiWalletCryptoCurrenciesProducer.kt$DefaultMultiWalletCryptoCurrenciesProducer$${this::class.simpleName} + UnnecessaryLet:DefaultAccountsCRUDRepository.kt$DefaultAccountsCRUDRepository$let(AccountName::invoke) + + diff --git a/data/balance-hiding/detekt-baseline-debug.xml b/data/balance-hiding/detekt-baseline-debug.xml new file mode 100644 index 0000000000..eca9bec2a0 --- /dev/null +++ b/data/balance-hiding/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + CastNullableToNonNullableType:DefaultDeviceFlipDetector.kt$DefaultDeviceFlipDetector$as + + diff --git a/data/common/detekt-baseline-debug.xml b/data/common/detekt-baseline-debug.xml new file mode 100644 index 0000000000..c9e3828304 --- /dev/null +++ b/data/common/detekt-baseline-debug.xml @@ -0,0 +1,14 @@ + + + + + MultilineLambdaItParameter:ApiResponseRaise.kt${ Timber.e(it, "Unable to perform safe API call") onError(it) } + MultilineLambdaItParameter:DefaultCardCryptoCurrencyFactory.kt$DefaultCardCryptoCurrencyFactory${ cryptoCurrencyFactory.createCoin( blockchain = it, extraDerivationPath = null, userWallet = userWallet, ) } + MultilineLambdaItParameter:UserTokensResponseFactory.kt$UserTokensResponseFactory${ getDefaultWalletBlockchains(userWallet = it, demoConfig = DemoConfig) .map { blockchain -> val derivationPath = networkFactory.createDerivationPath( blockchain = blockchain, extraDerivationPath = null, cardDerivationStyleProvider = userWallet.derivationStyleProvider, ).value UserTokensResponse.Token( id = blockchain.toCoinId(), accountId = accountId?.value, networkId = blockchain.toNetworkId(), derivationPath = derivationPath, name = blockchain.getCoinName(), symbol = blockchain.currency, decimals = blockchain.decimals(), contractAddress = null, ) } } + MultilineLambdaItParameter:UserTokensSaver.kt$UserTokensSaver${ if (accountsFeatureToggles.isFeatureEnabled) { it.enrichByAccountId(userWalletId = userWalletId) } else { it } } + NamedArguments:CryptoCurrencyFactory.kt$CryptoCurrencyFactory$createCoin(blockchain, extraDerivationPath, userWallet, accountIndex) + NoNameShadowing:DefaultETagsStore.kt$DefaultETagsStore$key + UnnecessaryLet:DefaultCardCryptoCurrencyFactory.kt$DefaultCardCryptoCurrencyFactory$let(::listOf) + UseOrEmpty:UserTokensResponseAddressesEnricher.kt$UserTokensResponseAddressesEnricher$withTimeoutOrNull( FETCH_TIMEOUT_SECONDS.seconds, { multiNetworkStatusSupplier.invoke(MultiNetworkStatusProducer.Params(userWalletId)).first() }, ) ?: emptySet() + + diff --git a/data/express/detekt-baseline-debug.xml b/data/express/detekt-baseline-debug.xml new file mode 100644 index 0000000000..0be5181121 --- /dev/null +++ b/data/express/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + IgnoredReturnValue:DefaultExpressServiceFetcher.kt$DefaultExpressServiceFetcher$put(key = userWalletId, value = default) + MultilineLambdaItParameter:DefaultExpressRepository.kt$DefaultExpressRepository${ Timber.w(it, "Unable to fetch express providers") throw it } + + diff --git a/data/feedback/detekt-baseline-debug.xml b/data/feedback/detekt-baseline-debug.xml new file mode 100644 index 0000000000..596e50e191 --- /dev/null +++ b/data/feedback/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + BooleanPropertyNaming:DefaultFeedbackRepository.kt$DefaultFeedbackRepository$private val useNewUserWalletsRepository: Boolean + MultilineLambdaItParameter:DefaultFeedbackRepository.kt$DefaultFeedbackRepository${ it.toMutableMap().apply { put(userWallet.walletId, error) } } + UseOrEmpty:BlockchainInfoConverter.kt$BlockchainInfoConverter$value.wallet.publicKey.derivationPath?.rawPath ?: "" + + diff --git a/data/hot-wallet/detekt-baseline-debug.xml b/data/hot-wallet/detekt-baseline-debug.xml new file mode 100644 index 0000000000..e0f29a8922 --- /dev/null +++ b/data/hot-wallet/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + MultilineLambdaItParameter:DefaultHotWalletRepository.kt$DefaultHotWalletRepository${ it.setObjectMap( key = PreferencesKeys.ACCESS_CODE_SKIPPED_STATES_KEY, value = it.getObjectMap<Boolean>(PreferencesKeys.ACCESS_CODE_SKIPPED_STATES_KEY) .plus(userWalletId.stringValue to skipped), ) } + + diff --git a/data/manage-tokens/detekt-baseline-debug.xml b/data/manage-tokens/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d384bf15ce --- /dev/null +++ b/data/manage-tokens/detekt-baseline-debug.xml @@ -0,0 +1,17 @@ + + + + + MultilineLambdaItParameter:DefaultCustomTokensRepository.kt$DefaultCustomTokensRepository${ // TODO: refactor https://tangem.atlassian.net/browse/AND-10006\ if (it.isTestnet() || it in excludedBlockchains || it in hotWalletExcludedBlockchains) { return@mapNotNull null } networkFactory.create( blockchain = it, extraDerivationPath = null, userWallet = userWallet, ) } + MultilineLambdaItParameter:DefaultManageTokensRepository.kt$DefaultManageTokensRepository${ it.contractAddress != null && it.networkId == network.backendId && it.derivationPath == network.derivationPath.value } + MultilineLambdaItParameter:ManageTokensUpdateFetcher.kt$ManageTokensUpdateFetcher${ if (it.key == toUpdate[index].key) { Batch(it.key, updatedItems) } else { null } } + NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$create(coinsResponse, tokensResponse, userWallet, accountIndex) + NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$createToken(coin, tokensResponse, coinsResponse.imageHost, userWallet, accountIndex) + NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$findAddedInNetworks(coinResponse.id, tokensResponse, userWallet, accountIndex) + NamedArguments:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$findAddedInNetworks(testnetToken.id, tokensResponse, userWallet, accountIndex) + SuspendFunSwallowedCancellation:DefaultManageTokensRepository.kt$DefaultManageTokensRepository$runCatching + UnsafeCallOnNullableType:DefaultCustomTokensRepository.kt$DefaultCustomTokensRepository$coinNetwork.decimalCount!! + UseOrEmpty:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$testnetToken.networks?.mapNotNull { network -> createSource( networkId = network.id, contractAddress = network.address, decimals = network.decimalCount, userWallet = userWallet, accountIndex = accountIndex, ) } ?: emptyList() + UseOrEmpty:ManagedCryptoCurrencyFactory.kt$ManagedCryptoCurrencyFactory$tokensResponse ?.let { createCustomTokens(it, userWallet, accountIndex) } ?: emptyList() + + diff --git a/data/markets/detekt-baseline-debug.xml b/data/markets/detekt-baseline-debug.xml new file mode 100644 index 0000000000..fd96850854 --- /dev/null +++ b/data/markets/detekt-baseline-debug.xml @@ -0,0 +1,16 @@ + + + + + BooleanPropertyNaming:DefaultMarketsTokenRepository.kt$DefaultMarketsTokenRepository.<no name provided>$val last = res.tokens.size < request.limit + MultilineLambdaItParameter:DefaultMarketsTokenRepository.kt$DefaultMarketsTokenRepository${ val error = it as QuotesFetcher.Error.ApiOperationError val errorEvent = createDetailsErrorEvent( error = error.apiError, request = MarketsDataAnalyticsEvent.Details.Error.Request.Info, tokenSymbol = tokenSymbol, ) analyticsEventHandler.send(errorEvent.toEvent()) throw error.apiError } + MultilineLambdaItParameter:MarketsBatchUpdateFetcher.kt$MarketsBatchUpdateFetcher${ it.copy( tokenCharts = TokenMarketChartsConverter.convert( chartsToCopy = it.tokenCharts, tokenId = it.id, interval = updateRequest.interval, value = update, ), ) } + MultilineLambdaItParameter:MarketsBatchUpdateFetcher.kt$MarketsBatchUpdateFetcher${ val exception = if (it is QuotesFetcher.Error.ApiOperationError) { onApiResponseError(it.apiError) it.apiError } else { error("Cause: $it") } throw exception } + MultilineLambdaItParameter:TokenMarketInfoConverter.kt$TokenMarketInfoConverter${ TokenMarketInfo.Link( title = it.title, id = it.id, link = it.link, ) } + NullableBooleanCheck:TokenMarketListConverter.kt$TokenMarketListConverter$token.isUnderMarketCapLimit ?: false + SuspendFunWithFlowReturnType:DefaultMarketsTokenRepository.kt$DefaultMarketsTokenRepository$suspend + UnsafeCallOnNullableType:DefaultMarketsTokenRepository.kt$DefaultMarketsTokenRepository$network.contractAddress!! + UseEmptyCounterpart:MarketsDataAnalyticsEvent.kt$MarketsDataAnalyticsEvent.Details$mapOf() + UseEmptyCounterpart:MarketsDataAnalyticsEvent.kt$MarketsDataAnalyticsEvent.List$mapOf() + + diff --git a/data/networks/detekt-baseline-debug.xml b/data/networks/detekt-baseline-debug.xml new file mode 100644 index 0000000000..981dd137d6 --- /dev/null +++ b/data/networks/detekt-baseline-debug.xml @@ -0,0 +1,15 @@ + + + + + MultilineLambdaItParameter:CommonNetworkStatusFetcher.kt$CommonNetworkStatusFetcher${ Timber.e("Failed to fetch network status for $userWalletId [${network.rawId}]: $it") networksStatusesStore.setSourceAsOnlyCache(userWalletId = userWalletId, network = network) } + MultilineLambdaItParameter:DefaultMultiNetworkStatusFetcher.kt$DefaultMultiNetworkStatusFetcher${ networksStatusesStore.setSourceAsOnlyCache( userWalletId = params.userWalletId, networks = params.networks, ) raise(it) } + MultilineLambdaItParameter:DefaultNetworksRepository.kt$DefaultNetworksRepository${ Timber.e(it, "Unable to create wallet currencies") return emptyList() } + MultilineLambdaItParameter:DefaultNetworksRepository.kt$DefaultNetworksRepository${ Timber.e(it, "Unable to create wallet currencies") return@withContext } + MultilineLambdaItParameter:NetworkAmountsConverter.kt$NetworkAmountsConverter${ val amount = it.value as? NetworkStatus.Amount.Loaded ?: return@mapNotNull null CurrencyAmount( id = currencyIdConverter.convertBack(value = it.key), amount = amount.value, ) } + MultilineLambdaItParameter:NetworkAmountsConverter.kt$NetworkAmountsConverter${ val currencyId = currencyIdConverter.convert(value = it.id) val amount = NetworkStatus.Amount.Loaded(value = it.amount) currencyId to amount } + MultilineLambdaItParameter:NetworkStatusSupplierModule.kt$NetworkStatusSupplierModule.<no name provided>${ "single_network_status_${it.userWalletId.stringValue}_${it.network.rawId}_" + it.network.derivationPath.value } + MultilineLambdaItParameter:NetworkYieldSupplyStatusConverter.kt$NetworkYieldSupplyStatusConverter${ val id = currencyIdConverter.convert(value = it.id) val status = YieldSupplyStatus( isActive = it.isActive, isInitialized = it.isInitialized, isAllowedToSpend = it.isAllowedToSpend, effectiveProtocolBalance = it.effectiveProtocolBalance, ) id to status } + SuspendFunSwallowedCancellation:DefaultNetworksRepository.kt$DefaultNetworksRepository$runCatching + + diff --git a/data/news/src/main/java/com/tangem/data/news/repository/DefaultNewsRepository.kt b/data/news/src/main/java/com/tangem/data/news/repository/DefaultNewsRepository.kt index 600fdaa843..6e10db56d6 100644 --- a/data/news/src/main/java/com/tangem/data/news/repository/DefaultNewsRepository.kt +++ b/data/news/src/main/java/com/tangem/data/news/repository/DefaultNewsRepository.kt @@ -15,6 +15,7 @@ import com.tangem.pagination.exception.EndOfPaginationException import com.tangem.pagination.fetcher.BatchFetcher import com.tangem.pagination.toBatchFlow import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.coroutines.runSuspendCatching import javax.inject.Inject /** @@ -69,7 +70,7 @@ internal class DefaultNewsRepository @Inject constructor( private var state: NewsPaginationState? = null override suspend fun fetchFirst(requestParams: NewsListConfig): BatchFetchResult> { - return runCatching { + return runSuspendCatching { loadPage( page = FIRST_PAGE, params = requestParams, @@ -102,7 +103,7 @@ internal class DefaultNewsRepository @Inject constructor( val pageToLoad = if (shouldReset) FIRST_PAGE else currentState.nextPage val snapshot = if (shouldReset) overrideRequestParams.snapshot else currentState.snapshot - return runCatching { + return runSuspendCatching { loadPage( page = pageToLoad, params = params, diff --git a/data/nft/detekt-baseline-debug.xml b/data/nft/detekt-baseline-debug.xml new file mode 100644 index 0000000000..08a3e3aba8 --- /dev/null +++ b/data/nft/detekt-baseline-debug.xml @@ -0,0 +1,26 @@ + + + + + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ NFTCollections( network = network, content = NFTCollections.Content.Collections( collections = it ?.map { collection -> nftSdkCollectionConverter.convert(network to collection) } ?.filter { it.id !is NFTCollection.Identifier.Unknown }, source = StatusSource.CACHE, ), ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ getNFTPersistenceStore(userWalletId, it).clear() getNFTRuntimeStore(userWalletId, it).clear() } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ if (it !is UnsupportedOperationException) { saveFailedStateInRuntime( userWalletId = userWalletId, network = network, error = it, ) } } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ if (it.id == collectionId) { it.changeAssetsStatusSource(source) } else { it } } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ if (it.identifier == sdkCollectionId) { it.copy(assets = assets) } else { it } } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ networkFactory.create( blockchain = it, extraDerivationPath = null, userWallet = userWallet, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ nftRuntimeStores[storeId] = it val storedCollections = getStoredCollections(userWalletId, network) val storedPrices = getStoredPrices(userWalletId, network) it.initialize( collections = storedCollections, prices = storedPrices, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ saveCollectionsInRuntime( userWalletId = userWalletId, network = network, collections = it, ) saveCollectionsInPersistence( userWalletId = userWalletId, network = network, collections = it, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ saveFailedStateInRuntime( userWalletId = userWalletId, network = network, error = it, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ storedCollections.copy( content = it, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ val (assetId, _) = it assetIdConverter.convert(assetId) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ val (assetId, price) = it val nftCurrency = getNFTCurrency(network) NFTSalePrice.Value( assetId = assetId, value = price.value, fiatValue = null, symbol = nftCurrency.symbol, decimals = nftCurrency.decimals, ) } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ val assetId = assetIdConverter.convert(it.identifier) val price = getNFTRuntimeStore(userWalletId, network).getSalePriceSync(assetId) if (price is NFTSalePrice.Empty || price is NFTSalePrice.Error) { refreshSalePrice(userWalletId, network, sdkCollectionId, it.identifier) } } + MultilineLambdaItParameter:DefaultNFTRepository.kt$DefaultNFTRepository${ val sdkAssetId = assetIdConverter.convertBack(assetId) saveSalePriceInPersistence(userWalletId, network, sdkAssetId, it) } + NamedArguments:DefaultNFTRepository.kt$DefaultNFTRepository$refreshSalePrice(userWalletId, network, sdkCollectionId, it.identifier) + NamedArguments:DefaultNFTRepository.kt$DefaultNFTRepository$saveSalePriceInPersistence(userWalletId, network, sdkAssetId, it) + NoNameShadowing:DefaultNFTRepository.kt$DefaultNFTRepository${ it.id !is NFTCollection.Identifier.Unknown } + SuspendFunSwallowedCancellation:DefaultNFTRepository.kt$DefaultNFTRepository$runCatching + SuspendFunWithFlowReturnType:DefaultNFTRepository.kt$DefaultNFTRepository$suspend + UnnecessaryLet:DefaultNFTRepository.kt$DefaultNFTRepository$let { prices -> prices .mapKeys { val (assetId, _) = it assetIdConverter.convert(assetId) } .mapValues { val (assetId, price) = it val nftCurrency = getNFTCurrency(network) NFTSalePrice.Value( assetId = assetId, value = price.value, fiatValue = null, symbol = nftCurrency.symbol, decimals = nftCurrency.decimals, ) } } + + diff --git a/data/onramp/detekt-baseline-debug.xml b/data/onramp/detekt-baseline-debug.xml new file mode 100644 index 0000000000..ec3fa17add --- /dev/null +++ b/data/onramp/detekt-baseline-debug.xml @@ -0,0 +1,17 @@ + + + + + BooleanPropertyNaming:DefaultOnrampRepository.kt$DefaultOnrampRepository$val cachedValue = onrampSepaAvailabilityStore.getSyncOrNull(key) + MultilineLambdaItParameter:DefaultHotCryptoRepository.kt$DefaultHotCryptoRepository${ Timber.e(it, "Unable to fetch hot crypto") analyticsEventHandler.send( event = MainScreenAnalyticsEvent.HotTokenError( errorCode = (it as? ApiResponseError.HttpException)?.code?.numericCode?.toString().orEmpty(), ), ) } + MultilineLambdaItParameter:DefaultHotCryptoRepository.kt$DefaultHotCryptoRepository${ if (it.id == OLD_POLYGON_NAME) { it.copy(id = NEW_POLYGON_NAME) } else { it } } + MultilineLambdaItParameter:DefaultHotCryptoRepository.kt$DefaultHotCryptoRepository${ val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("UserWalletId [$userWalletId] not found") HotCryptoCurrencyConverter( userWallet = userWallet, imageHost = it.imageHost, excludedBlockchains = excludedBlockchains, ) .convertList(input = it.tokens) .filterNotNull() } + MultilineLambdaItParameter:DefaultOnrampRepository.kt$DefaultOnrampRepository${ Timber.w(it, "Unable to fetch express providers") throw it } + MultilineLambdaItParameter:DefaultOnrampRepository.kt$DefaultOnrampRepository${ Timber.w(it, "Unable to fetch onramp pairs") throw it } + MultilineLambdaItParameter:DefaultOnrampRepository.kt$DefaultOnrampRepository${ Timber.w(it, "Unable to fetch onramp payment methods") throw it } + UnnecessaryLet:DefaultOnrampRepository.kt$DefaultOnrampRepository$let(countryConverter::convert) + UnnecessaryLet:DefaultOnrampRepository.kt$DefaultOnrampRepository$let(paymentMethodsConverter::convertList) + UnnecessaryLet:DefaultOnrampRepository.kt$DefaultOnrampRepository$let(statusConverter::convert) + UseOrEmpty:DefaultOnrampTransactionRepository.kt$DefaultOnrampTransactionRepository$stored ?: emptySet() + + diff --git a/data/promo/detekt-baseline-debug.xml b/data/promo/detekt-baseline-debug.xml new file mode 100644 index 0000000000..0f6f378450 --- /dev/null +++ b/data/promo/detekt-baseline-debug.xml @@ -0,0 +1,10 @@ + + + + + NullableBooleanCheck:DefaultPromoRepository.kt$DefaultPromoRepository$getSepaPromoBanner()?.isActive ?: false + NullableBooleanCheck:DefaultPromoRepository.kt$DefaultPromoRepository$getVisaPromoBanner()?.isActive ?: false + SuspendFunSwallowedCancellation:DefaultPromoRepository.kt$DefaultPromoRepository$runCatching + SuspendFunWithFlowReturnType:DefaultPromoRepository.kt$DefaultPromoRepository$suspend + + diff --git a/data/quotes/detekt-baseline-debug.xml b/data/quotes/detekt-baseline-debug.xml new file mode 100644 index 0000000000..c69926fdf1 --- /dev/null +++ b/data/quotes/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + MultilineLambdaItParameter:DefaultMultiQuoteStatusFetcher.kt$DefaultMultiQuoteStatusFetcher${ Timber.e(it) quotesStatusesStore.setSourceAsOnlyCache(currenciesIds = params.currenciesIds) } + + diff --git a/data/settings/detekt-baseline-debug.xml b/data/settings/detekt-baseline-debug.xml new file mode 100644 index 0000000000..5489dc6b26 --- /dev/null +++ b/data/settings/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + SuspendFunSwallowedCancellation:DefaultSettingsRepository.kt$DefaultSettingsRepository$runCatching + + diff --git a/data/staking/detekt-baseline-debug.xml b/data/staking/detekt-baseline-debug.xml new file mode 100644 index 0000000000..39dba1e36e --- /dev/null +++ b/data/staking/detekt-baseline-debug.xml @@ -0,0 +1,15 @@ + + + + + MultilineLambdaItParameter:DefaultMultiYieldBalanceFetcher.kt$DefaultMultiYieldBalanceFetcher${ Timber.e(it, "Unable to fetch yield balances $params") yieldsBalancesStore.storeError(userWalletId = params.userWalletId, stakingIds = stakingIds) } + MultilineLambdaItParameter:DefaultMultiYieldBalanceFetcher.kt$DefaultMultiYieldBalanceFetcher${ Timber.e(it, "Unable to fetch yield balances $userWalletId") yieldsBalancesStore.storeError(userWalletId = userWalletId, stakingIds = stakingIds) throw it } + MultilineLambdaItParameter:DefaultMultiYieldBalanceFetcher.kt$DefaultMultiYieldBalanceFetcher${ request.integrationId == it.integrationId && request.addresses.address == it.addresses.address } + MultilineLambdaItParameter:DefaultMultiYieldBalanceFetcher.kt$DefaultMultiYieldBalanceFetcher${ stakingId.integrationId == it.integrationId && stakingId.address == it.addresses.address } + MultilineLambdaItParameter:DefaultStakingRepository.kt$DefaultStakingRepository${ YieldConverter.convertListIgnoreErrors( input = it, onError = { Timber.e("Error converting one of the items in enabled yields: $it") }, ) } + NamedArguments:DefaultP2PEthPoolRepository.kt$DefaultP2PEthPoolRepository$getRewards(network.value, delegatorAddress, vaultAddress, period) + NoNameShadowing:DefaultStakingRepository.kt$DefaultStakingRepository${ Timber.e("Error converting one of the items in enabled yields: $it") } + NullableToStringCall:DefaultStakingRepository.kt$DefaultStakingRepository$${(response as? ApiResponse.Error)?.cause} + UseEmptyCounterpart:YieldBalanceRequestBodyFactory.kt$YieldBalanceRequestBodyFactory$listOf() + + diff --git a/data/swap/detekt-baseline-debug.xml b/data/swap/detekt-baseline-debug.xml new file mode 100644 index 0000000000..b047ac0eff --- /dev/null +++ b/data/swap/detekt-baseline-debug.xml @@ -0,0 +1,19 @@ + + + + + MaxChainedCallsOnSameLine:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2$fromCryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value.orEmpty() + MultilineLambdaItParameter:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2${ Timber.w(it, "Unable to get pairs") throw it } + MultilineLambdaItParameter:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2${ it.currency.getContractAddress() == pair.from.contractAddress && it.currency.network.backendId == pair.from.network } + MultilineLambdaItParameter:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2${ it.currency.getContractAddress() == pair.to.contractAddress && it.currency.network.backendId == pair.to.network } + MultilineLambdaItParameter:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2${ it.getContractAddress() == pair.from.contractAddress && it.network.backendId == pair.from.network } + MultilineLambdaItParameter:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2${ it.getContractAddress() == pair.to.contractAddress && it.network.backendId == pair.to.network } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.checkId( checkUserWalletId = userWalletId, fromCurrencyId = fromCryptoCurrency.id, toCurrencyId = toCryptoCurrency.id, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.userWalletId == userWallet.walletId.stringValue && ( it.toCryptoCurrencyId == cryptoCurrencyId.value || it.fromCryptoCurrencyId == cryptoCurrencyId.value ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ listConverter.convertBack( value = it, multiAccountList = multiAccountList, userWallet = userWallet, txStatuses = txStatuses, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ storeTransactionState( txId = transaction.txId, status = it, accountWithCurrency = fromAccount?.accountId to fromCryptoCurrency, ) } + MultilineLambdaItParameter:SwapDataConverter.kt$SwapDataConverter${ if (it == "0") { BigDecimal.ZERO } else { requireNotNull(it.toBigDecimalOrNull()) { "wrong amount format, use only digits" } } } + NoNameShadowing:DefaultSwapRepositoryV2.kt$DefaultSwapRepositoryV2$mappedProviders + NoNameShadowing:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.txId == txId } + + diff --git a/data/tokens/detekt-baseline-debug.xml b/data/tokens/detekt-baseline-debug.xml new file mode 100644 index 0000000000..8be9ea8bd3 --- /dev/null +++ b/data/tokens/detekt-baseline-debug.xml @@ -0,0 +1,13 @@ + + + + + MultilineLambdaItParameter:CustomTokensMerger.kt$CustomTokensMerger${ Timber.e(it, "Unable to fetch token:\n$token") null } + MultilineLambdaItParameter:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository${ it.networkId == blockchainNetworkId && compareIdWithMigrations(it, coinId) && it.derivationPath == derivationPath.value } + NullableToStringCall:AccountListCryptoCurrenciesFetcher.kt$AccountListCryptoCurrenciesFetcher$${this::class.simpleName} + NullableToStringCall:DefaultMultiWalletCryptoCurrenciesFetcher.kt$DefaultMultiWalletCryptoCurrenciesFetcher$${this::class.simpleName} + SuspendFunSwallowedCancellation:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository$runCatching + SuspendFunWithFlowReturnType:DefaultCurrenciesRepository.kt$DefaultCurrenciesRepository$suspend + UseOrEmpty:DefaultYieldSupplyWarningsViewedRepository.kt$DefaultYieldSupplyWarningsViewedRepository$appPreferencesStore.getObjectSet<String>(PreferencesKeys.YIELD_SUPPLY_WARNINGS_STATES_KEY).firstOrNull() ?: emptySet() + + diff --git a/data/transaction/detekt-baseline-debug.xml b/data/transaction/detekt-baseline-debug.xml new file mode 100644 index 0000000000..dd2976b413 --- /dev/null +++ b/data/transaction/detekt-baseline-debug.xml @@ -0,0 +1,11 @@ + + + + + CastNullableToNonNullableType:DefaultTransactionRepository.kt$DefaultTransactionRepository$as + NoNameShadowing:DefaultTransactionRepository.kt$DefaultTransactionRepository$amount + NoNameShadowing:DefaultTransactionRepository.kt$DefaultTransactionRepository$destination + NullableBooleanCheck:DefaultWalletAddressServiceRepository.kt$DefaultWalletAddressServiceRepository$(walletManager as? NearWalletManager)?.validateAddress(address) ?: false + NullableToStringCall:DefaultTransactionRepository.kt$DefaultTransactionRepository$${walletManager?.wallet?.blockchain} + + diff --git a/data/txhistory/detekt-baseline-debug.xml b/data/txhistory/detekt-baseline-debug.xml new file mode 100644 index 0000000000..3dfda1c580 --- /dev/null +++ b/data/txhistory/detekt-baseline-debug.xml @@ -0,0 +1,13 @@ + + + + + BooleanPropertyNaming:TxHistoryPagingSource.kt$TxHistoryPagingSource.Params$val refresh: Boolean + MaxChainedCallsOnSameLine:DefaultTxHistoryRepository.kt$DefaultTxHistoryRepository$walletManager?.wallet?.recentTransactions?.last()?.hash.orEmpty() + MultilineLambdaItParameter:TxHistoryPageBatchFetcher.kt$TxHistoryPageBatchFetcher${ currentCoroutineContext().ensureActive() BatchFetchResult.Error(it) } + NamedArguments:DefaultTxHistoryRepository.kt$DefaultTxHistoryRepository$Params(userWalletId, currency, pageSize, refresh) + NamedArguments:TxHistoryDataModule.kt$TxHistoryDataModule$DefaultTxHistoryRepository( cacheRegistry, walletManagersFacade, userWalletsStore, txHistoryItemsStore, dispatchers, ) + SuspendFunSwallowedCancellation:TxHistoryPageBatchFetcher.kt$TxHistoryPageBatchFetcher$runCatching + UseOrEmpty:DefaultTxHistoryRepository.kt$DefaultTxHistoryRepository$txs ?: emptyList() + + diff --git a/data/visa/detekt-baseline-debug.xml b/data/visa/detekt-baseline-debug.xml new file mode 100644 index 0000000000..4c936a4a08 --- /dev/null +++ b/data/visa/detekt-baseline-debug.xml @@ -0,0 +1,30 @@ + + + + + MaxChainedCallsOnSameLine:DefaultVisaRepository.kt$DefaultVisaRepository$userWallet.requireColdWallet().scanResponse.card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } + MultilineLambdaItParameter:DefaultVisaActivationRepository.kt$DefaultVisaActivationRepository${ VisaDataToSignByCardWallet( request = request, hashToSign = it.result.hash, ) } + MultilineLambdaItParameter:DefaultVisaActivationRepository.kt$DefaultVisaActivationRepository${ VisaDataToSignByCustomerWallet( request = request, hashToSign = it.result.hash, ) } + MultilineLambdaItParameter:VisaApiRequestMaker.kt$VisaApiRequestMaker${ if (it is ApiResponseError.HttpException && it.code == ApiResponseError.HttpException.Code.UNAUTHORIZED ) { userWalletsStore.update(userWalletId) { userWallet -> userWallet.requireColdWallet().copy( scanResponse = userWallet.scanResponse.copy( // visaCardActivationStatus = VisaCardActivationStatus.RefreshTokenExpired, ), ) } } throw RefreshTokenExpiredException() } + MultilineLambdaItParameter:VisaTxDetailsFactory.kt$VisaTxDetailsFactory${ when (val txUrl = walletBlockchain.getExploreTxUrl(it)) { is TxExploreState.Url -> txUrl.url is TxExploreState.Unsupported -> "" } } + MultilineLambdaItParameter:VisaTxHistoryPagingSource.kt$VisaTxHistoryPagingSource${ it.toMutableMap().apply { this[cardPublicKey] = this[cardPublicKey].orEmpty() + response.transactions } } + MultilineLambdaItParameter:VisaTxHistoryPagingSource.kt$VisaTxHistoryPagingSource${ it.toMutableMap().apply { this[offset] = response.transactions.map(VisaTxHistoryItemConverter::convert) } } + NamedArguments:DefaultVisaRepository.kt$DefaultVisaRepository$parZip( dispatchers.io, { contractInfoProvider.getContractInfo( walletAddress = address, paymentAccountAddress = paymentAccountAddress, ) }, { getFiatRate() }, { contractInfo, fiatRate -> fetchedCurrencies.update { value -> value.apply { put(address, visaCurrencyFactory.create(userWallet, contractInfo, fiatRate)) } } }, ) + NoNameShadowing:DefaultVisaActivationRepository.kt$DefaultVisaActivationRepository$responseError + NullCheckOnMutableProperty:VisaLibLoader.kt$VisaLibLoader$if (config != null) return@withLock requireNotNull(config) + NullCheckOnMutableProperty:VisaLibLoader.kt$VisaLibLoader$if (provider != null) return@withLock requireNotNull(provider) + NullableToStringCall:DefaultOnboardingRepository.kt$DefaultOnboardingRepository$${error.message} + NullableToStringCall:DefaultTangemPayCardDetailsRepository.kt$DefaultTangemPayCardDetailsRepository$${response.result?.status} + NullableToStringCall:TangemPayRequestPerformer.kt$TangemPayRequestPerformer$${error.message} + RedundantSuspendModifier:DefaultVisaRepository.kt$DefaultVisaRepository$suspend + SuspendFunSwallowedCancellation:DefaultVisaRepository.kt$DefaultVisaRepository$runCatching + SuspendFunSwallowedCancellation:TangemPayRequestPerformer.kt$TangemPayRequestPerformer$runCatching + SuspendFunSwallowedCancellation:VisaApiRequestMaker.kt$VisaApiRequestMaker$runCatching + UnreachableCode:VisaApiRequestMaker.kt$VisaApiRequestMaker$if (status is VisaCardActivationStatus.RefreshTokenExpired) { throw RefreshTokenExpiredException() } + UnreachableCode:VisaApiRequestMaker.kt$VisaApiRequestMaker$return (status as? VisaCardActivationStatus.Activated)?.visaAuthTokens ?: error("Visa card is not activated") + UnreachableCode:VisaApiRequestMaker.kt$VisaApiRequestMaker$val status: VisaCardActivationStatus = TODO("Fix visaCardActivationStatus retrieval") + UnsafeCallOnNullableType:DefaultVisaActivationRepository.kt$DefaultVisaActivationRepository$responseError.errorBody!! + UnsafeCallOnNullableType:DefaultVisaAuthRemoteDataSource.kt$DefaultVisaAuthRemoteDataSource$responseError.errorBody!! + UnsafeCallOnNullableType:VisaActivationStatusConverterWithState.kt$VisaActivationStatusConverterWithState$result.activationOrder!! + + diff --git a/data/wallet-connect/detekt-baseline-debug.xml b/data/wallet-connect/detekt-baseline-debug.xml new file mode 100644 index 0000000000..6d06073a70 --- /dev/null +++ b/data/wallet-connect/detekt-baseline-debug.xml @@ -0,0 +1,61 @@ + + + + + BooleanPropertyNaming:DefaultWcRequestService.kt$DefaultWcRequestService$val noHaveCached = cachedRequest.none { (_, hashParams) -> hash == hashParams } + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val haveEmptyDto = emptyNetworksDto.isNotEmpty() + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val haveEmptySessions = emptyNetworkSessions.isNotEmpty() + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val haveSomeUnknown = unknownStoredSessions.isNotEmpty() + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val haveSomeUnknownSdkSessions = unknownSdkSessions.isNotEmpty() + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val someMigrate = migrateToAccountSession(inStore) + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$val someRemove = removeUnknownSessions(inStore, inSdk, associatedSessions) + BooleanPropertyNaming:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$var someMigrated = false + CastNullableToNonNullableType:WcEthSendTransactionUseCase.kt$WcEthSendTransactionUseCase$as + CastNullableToNonNullableType:WcEthSignTransactionUseCase.kt$WcEthSignTransactionUseCase$as + MultilineLambdaItParameter:BlockAidVerificationDelegate.kt$BlockAidVerificationDelegate${ Timber.e("Failed to verify transaction: ${it.localizedMessage}") emit(Lce.Error(it)) } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ Timber.tag(WC_TAG).e(it, "Failed to call pair $pairRequest") analytics.send( WcAnalyticEvents.PairFailed( errorCode = it.code, errorMessage = it.message, ), ) emit(WcPairState.Error(it)) } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ Timber.tag(WC_TAG).e(it, "Failed to verify DApp ${sessionProposal.name}") CheckDAppResult.FAILED_TO_VERIFY } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ analytics.send( WcAnalyticEvents.DAppConnectionFailed( errorCode = it.code, errorMessage = it.message, ), ) sdkDelegate.rejectSession(sdkSessionProposal.proposerPublicKey) Timber.tag(WC_TAG).e(it, "Failed to approve session ${sdkSessionProposal.name}") } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ analytics.send( WcAnalyticEvents.PairFailed( errorCode = it.code, errorMessage = it.message, ), ) emit(WcPairState.Error(it)) } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ if (it != null) { Timber.tag(WC_TAG).e(it, "Completed with error $pairRequest") } else { Timber.tag(WC_TAG).i("Completed successfully $pairRequest") } } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ val pairError: WcPairError = when (it) { is TimeoutCancellationException -> WcPairError.TimeoutException(it.message.orEmpty()) else -> WcPairError.Unknown(it.message.orEmpty()) } emit(WcPairState.Error(pairError)) } + MultilineLambdaItParameter:DefaultWcPairUseCase.kt$DefaultWcPairUseCase${ when (it) { is WcPairError -> it.left() else -> WcPairError.Unknown(it.localizedMessage.orEmpty()).left() } } + MultilineLambdaItParameter:DefaultWcRequestUseCaseFactory.kt$DefaultWcRequestUseCaseFactory${ Timber.tag(WC_TAG).e("$it") it.left() } + MultilineLambdaItParameter:DefaultWcRespondService.kt$DefaultWcRespondService${ if (continuation.isCompleted) return@respondSessionRequest Timber.tag(WC_TAG).e(it.throwable, "Failed respond for request $request") continuation.resume(WcRequestError.UnknownError(it.throwable).left()) } + MultilineLambdaItParameter:DefaultWcRespondService.kt$DefaultWcRespondService${ if (continuation.isCompleted) return@respondSessionRequest val result = when (val response = it.jsonRpcResponse) { is Wallet.Model.JsonRpcResponse.JsonRpcError -> { Timber.tag(WC_TAG).e("Failed respond $response for request $request") WcRequestError.WcRespondError( code = response.code, message = response.message, ).left() } is Wallet.Model.JsonRpcResponse.JsonRpcResult -> { Timber.tag(WC_TAG).i("Successful respond $response for request $request") if (response.result == null) { Timber.tag(WC_TAG).e( "Response result is null, but it should be String. Casted to empty", ) } (response.result ?: "").right() } } continuation.resume(result) } + MultilineLambdaItParameter:WcEthMessageSignUseCase.kt$LegacySdkHelper${ if (!it.isAscii()) return null Integer.toHexString(it.code) } + MultilineLambdaItParameter:WcEthMessageSignUseCase.kt$LegacySdkHelper${ val char = it.toInt().toChar() if (char.isAscii()) char else return null } + MultilineLambdaItParameter:WcEthNetwork.kt$WcEthNetwork${ if (this == WcEthMethodName.AddEthereumChain) { WcEthMethod.AddEthereumChain(rawChain = it).right() } else { WcEthMethod.SwitchEthereumChain(rawChain = it).right() } } + MultilineLambdaItParameter:WcEthNetwork.kt$WcEthNetwork${ if (this == WcEthMethodName.SignTransaction) { WcEthMethod.SignTransaction(transaction = it).right() } else { WcEthMethod.SendTransaction(transaction = it).right() } } + MultilineLambdaItParameter:WcNetworksConverter.kt$WcNetworksConverter${ val walletAddress = walletManagersFacade.getDefaultAddress(wallet.walletId, it) walletAddress?.lowercase() == caip10.accountAddress.lowercase() } + MultilineLambdaItParameter:WcPairSdkDelegate.kt$WcPairSdkDelegate${ proposalCallback.cancel() return@coroutineScope it.left() } + MultilineLambdaItParameter:WcPairSdkDelegate.kt$WcPairSdkDelegate${ store.removePendingApproval(forSave) it.left() } + MultilineLambdaItParameter:WcSdkSessionConverter.kt$WcSdkSessionConverter${ WcAppMetaDataConverter.convert( value = WcAppMetaDataConverter.Input( originUrl = value.originUrl, peerMetaData = it, ), ) } + MultilineLambdaItParameter:WcSdkSessionRequestConverter.kt$WcSdkSessionRequestConverter${ WcAppMetaDataConverter.convert( value = WcAppMetaDataConverter.Input( originUrl = value.originUrl, peerMetaData = it, ), ) } + MultilineLambdaItParameter:WcSolanaSignTransactionUseCase.kt$WcSolanaSignTransactionUseCase${ analytics.send(SolanaLargeTransactionStatus(SolanaLargeTransactionStatus.Status.Failed)) Timber.e(it.toString()) emit(state.toResult(parseSendError(it).left())) } + NamedArguments:AssociateNetworksDelegate.kt$AssociateNetworksDelegate$mapNetworksForPortfolio(wallet, null, requiredNamespaces, optionalNamespaces, sessionProposal) + NamedArguments:WcEthTxHelper.kt$WcEthTxHelper$ethSpecificFee(userWallet, currency, gasLimit, gasPrice) + NoNameShadowing:CaipNamespaceDelegate.kt$CaipNamespaceDelegate$optionalNamespaces + NoNameShadowing:CaipNamespaceDelegate.kt$CaipNamespaceDelegate$requiredNamespaces + NoNameShadowing:DefaultWcRespondService.kt$DefaultWcRespondService$response + NoNameShadowing:WcSolanaNetwork.kt$WcSolanaNetwork$request + NullCheckOnMutableProperty:WcEthSendTransactionUseCase.kt$WcEthSendTransactionUseCase$if (dAppFee != null) return dAppFee + NullCheckOnMutableProperty:WcEthSignTransactionUseCase.kt$WcEthSignTransactionUseCase$if (dAppFee != null) return dAppFee + NullableBooleanCheck:DefaultWcPairService.kt$DefaultWcPairService$existSessionTopic(request.uri).getOrNull() ?: false + NullableToStringCall:WcSolanaSignTransactionUseCase.kt$WcSolanaSignTransactionUseCase$${e.message} + SuspendFunSwallowedCancellation:DefaultWcPairService.kt$DefaultWcPairService$runCatching + SuspendFunSwallowedCancellation:DefaultWcPairUseCase.kt$DefaultWcPairUseCase$runCatching + UseAnyOrNoneInsteadOfFind:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$find { it.sdkModel.topic == dto.topic } + UseEmptyCounterpart:AssociateNetworksDelegate.kt$AssociateNetworksDelegate.Companion$listOf() + UseEmptyCounterpart:DefaultWcRequestService.kt$DefaultWcRequestService$setOf() + UseEmptyCounterpart:WcAppMetaDataConverter.kt$WcAppMetaDataConverter$listOf() + UseEmptyCounterpart:WcNetworksConverter.kt$WcNetworksConverter$listOf() + UseEmptyCounterpart:WcSdkSessionConverter.kt$WcSdkSessionConverter$listOf() + UseOrEmpty:AssociateNetworksDelegate.kt$AssociateNetworksDelegate.Companion$proposal.chains ?: listOf() + UseOrEmpty:DefaultWcRespondService.kt$DefaultWcRespondService$response.result ?: "" + UseOrEmpty:DefaultWcSessionsManager.kt$DefaultWcSessionsManager$storeSession.url ?: sdkSession.metaData?.url ?: "" + UseOrEmpty:WcNetworksConverter.kt$WcNetworksConverter$getAccountStatus(accountId) ?.flattenCurrencies() ?.map { it.currency } ?.filterIsInstance<CryptoCurrency.Coin>() ?.map(CryptoCurrency.Coin::network) ?: emptyList() + UseOrEmpty:WcSdkSessionConverter.kt$WcSdkSessionConverter$session.chains ?: listOf() + UselessCallOnNotNull:DefaultWcRequestUseCaseFactory.kt$DefaultWcRequestUseCaseFactory$error.code().orEmpty() + + diff --git a/data/wallet-manager/detekt-baseline-debug.xml b/data/wallet-manager/detekt-baseline-debug.xml new file mode 100644 index 0000000000..b5ce5d471d --- /dev/null +++ b/data/wallet-manager/detekt-baseline-debug.xml @@ -0,0 +1,12 @@ + + + + + MultilineLambdaItParameter:DefaultWalletManagersFacade.kt$DefaultWalletManagersFacade${ Token( name = it.name, symbol = it.symbol, contractAddress = it.contractAddress, decimals = it.decimals, id = it.id, ) } + MultilineLambdaItParameter:UpdateWalletManagerResultFactory.kt$UpdateWalletManagerResultFactory${ createCurrencyTransaction( txHistoryItemConverter = txHistoryItemConverter, data = it, ) } + NamedArguments:DefaultWalletManagersFacade.kt$DefaultWalletManagersFacade$getAndUpdateWalletManager(userWallet, blockchain, derivationPath, extraTokens) + UnnecessaryLet:DefaultWalletManagersFacade.kt$DefaultWalletManagersFacade$let(txHistoryStateConverter::convert) + UnsafeCallOnNullableType:WalletManagerFactory.kt$blockchain.getTestnetVersion()!! + UnsafeCallOnNullableType:WalletManagerFactory.kt$scanResponse.secondTwinPublicKey!! + + diff --git a/data/wallets/detekt-baseline-debug.xml b/data/wallets/detekt-baseline-debug.xml new file mode 100644 index 0000000000..fa109771d4 --- /dev/null +++ b/data/wallets/detekt-baseline-debug.xml @@ -0,0 +1,38 @@ + + + + + BooleanPropertyNaming:DefaultWalletsRepository.kt$DefaultWalletsRepository$val legacySaveWalletsInTheApp = appPreferencesStore.getSyncOrNull( key = PreferencesKeys.SAVE_USER_WALLETS_KEY, ) + BooleanPropertyNaming:DefaultWalletsRepository.kt$DefaultWalletsRepository$val legacyShouldSaveAccessCode = appPreferencesStore.getSyncOrNull( key = PreferencesKeys.SHOULD_SAVE_ACCESS_CODES_KEY, ) + BooleanPropertyNaming:DefaultWalletsRepository.kt$DefaultWalletsRepository$val requireAccessCode = appPreferencesStore.getSyncOrNull( key = PreferencesKeys.REQUIRE_ACCESS_CODE_KEY, ) + BooleanPropertyNaming:DefaultWalletsRepository.kt$DefaultWalletsRepository$val useBiometricAuthentication = appPreferencesStore.getSyncOrNull( key = PreferencesKeys.USE_BIOMETRIC_AUTHENTICATION_KEY, ) + MultilineLambdaItParameter:DefaultColdMapDerivationsRepository.kt$DefaultColdMapDerivationsRepository${ networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, userWallet = userWallet, ) } + MultilineLambdaItParameter:DefaultDerivationsRepository.kt$DefaultDerivationsRepository${ userWallet.update(it.first) it.second } + MultilineLambdaItParameter:DefaultHotMapDerivationsRepository.kt$DefaultHotMapDerivationsRepository${ networkFactory.create( blockchain = Blockchain.fromNetworkId(it.value) ?: return@mapNotNull null, extraDerivationPath = null, userWallet = userWallet, ) } + MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ AttemptsPersistentData( attempts = it[PreferencesKeys.getHotWalletUnlockAttemptsKey(id.attemptIdKey())] ?: 0, bootCount = it[PreferencesKeys.getHotWalletUnlockBootKey(id.attemptIdKey())] ?: 0, deadline = it[PreferencesKeys.getHotWalletUnlockDeadlineKey(id.attemptIdKey())] ?: 0L, ) } + MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ it.remove(PreferencesKeys.getHotWalletUnlockAttemptsKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockAttemptsKey(noAuthAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockBootKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockBootKey(noAuthAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockDeadlineKey(authAttemptId.attemptIdKey())) it.remove(PreferencesKeys.getHotWalletUnlockDeadlineKey(noAuthAttemptId.attemptIdKey())) } + MultilineLambdaItParameter:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository${ while (true) { emit(toState(id, it.attempts, it.deadline, it.bootCount)) val remaining = remainingSeconds(it.deadline, it.bootCount) if (remaining <= 0) break delay(timeMillis = 1000) } } + MultilineLambdaItParameter:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor${ block(UnlockHotWallet(hotWalletId, it)).also { hotWalletPasswordRequester.successfulAuthentication() hotWalletPasswordRequester.dismiss() } } + MultilineLambdaItParameter:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor${ tangemHotSdk.getContextUnlock(it).also { unlockHotWallet -> contextualUnlockHotWallet[hotWalletId] = unlockHotWallet } } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ if (it is HttpException && it.code == HttpException.Code.NOT_FOUND) { Status.NOTIFIED } else { Status.NOT_NEEDED } } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ it.getOrDefault( key = userWalletId, defaultValue = SeedPhraseNotificationsStatus.NOT_NEEDED, ) } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ it.setObjectMap( key = PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY, value = it.getObjectMap<Boolean>(PreferencesKeys.NOTIFICATIONS_ENABLED_STATES_KEY) .plus(userWalletId.stringValue to isEnabled), ) } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ it.setObjectMap( key = PreferencesKeys.WALLETS_NFT_ENABLED_STATES_KEY, value = it.getObjectMap<Boolean>(PreferencesKeys.WALLETS_NFT_ENABLED_STATES_KEY) .plus(userWalletId.stringValue to false), ) } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ it.setObjectMap( key = PreferencesKeys.WALLETS_NFT_ENABLED_STATES_KEY, value = it.getObjectMap<Boolean>(PreferencesKeys.WALLETS_NFT_ENABLED_STATES_KEY) .plus(userWalletId.stringValue to true), ) } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ it.toMutableMap().apply { this[id] = value } } + MultilineLambdaItParameter:DefaultWalletsRepository.kt$DefaultWalletsRepository${ val added = it[PreferencesKeys.ADDED_WALLETS_WITH_RING_KEY].orEmpty() it[PreferencesKeys.ADDED_WALLETS_WITH_RING_KEY] = added + userWalletId.stringValue } + MultilineLambdaItParameter:TangemHotWalletSigner.kt$TangemHotWalletSigner${ Timber.e(it) return if (it is TangemSdkError) { CompletionResult.Failure(it) } else { CompletionResult.Failure(TangemSdkError.ExceptionError(it)) } } + MultilineLambdaItParameter:WalletIdBodyConverter.kt$WalletIdBodyConverter${ CardInfoBody( cardId = it.key, cardPublicKey = it.value, ) } + NamedArguments:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository$toState(id, count, deadline, boot) + NamedArguments:DefaultHotWalletAccessCodeAttemptsRepository.kt$DefaultHotWalletAccessCodeAttemptsRepository$toState(id, it.attempts, it.deadline, it.bootCount) + NoNameShadowing:DefaultWalletsRepository.kt$DefaultWalletsRepository$error + NoNameShadowing:DefaultWalletsRepository.kt$DefaultWalletsRepository${ UserWalletId(it.key) } + SuspendFunSwallowedCancellation:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor$runCatching + SuspendFunSwallowedCancellation:TangemHotWalletSigner.kt$TangemHotWalletSigner$runCatching + UnnecessaryLet:MissedDerivationsFinder.kt$MissedDerivationsFinder$let(::findByNetworks) + UnusedImports:DefaultDerivationsRepository.kt$import com.tangem.common.map + UseOrEmpty:DefaultColdMapDerivationsRepository.kt$DefaultColdMapDerivationsRepository$oldKeys[walletKey] ?: emptyMap() + UseOrEmpty:DefaultHotMapDerivationsRepository.kt$DefaultHotMapDerivationsRepository$oldKeys[walletKey] ?: emptyMap() + VarCouldBeVal:DefaultHotWalletAccessor.kt$DefaultHotWalletAccessor$private var contextualUnlockHotWallet: ConcurrentHashMap<HotWalletId, UnlockHotWallet?> = ConcurrentHashMap() + + diff --git a/data/yield-supply/detekt-baseline-debug.xml b/data/yield-supply/detekt-baseline-debug.xml new file mode 100644 index 0000000000..422ee5de58 --- /dev/null +++ b/data/yield-supply/detekt-baseline-debug.xml @@ -0,0 +1,15 @@ + + + + + BooleanPropertyNaming:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$val emptyContractAddress = existingYieldAddress == null || existingYieldAddress == EthereumUtils.ZERO_ADDRESS + MultilineLambdaItParameter:DefaultYieldSupplyRepository.kt$DefaultYieldSupplyRepository${ it.type == TxInfo.TransactionType.YieldSupply.Enter || it.type == TxInfo.TransactionType.Approve && (it.interactionAddressType as? TxInfo.InteractionAddressType.Contract)?.address == yieldAddress } + NoNameShadowing:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$maxNetworkFee + NullableBooleanCheck:DefaultYieldSupplyRepository.kt$DefaultYieldSupplyRepository$(walletManager as? YieldSupplyProvider)?.isSupported() ?: false + NullableBooleanCheck:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$yieldSupplyStatus?.isActive ?: false + NullableBooleanCheck:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$yieldSupplyStatus?.isAllowedToSpend ?: false + NullableBooleanCheck:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$yieldSupplyStatus?.isInitialized ?: false + NullableBooleanCheck:YieldMarketTokenConverter.kt$YieldMarketTokenConverter$value.isActive ?: false + SuspendFunSwallowedCancellation:DefaultYieldSupplyTransactionRepository.kt$DefaultYieldSupplyTransactionRepository$runCatching + + diff --git a/detekt_baseline_report.txt b/detekt_baseline_report.txt new file mode 100644 index 0000000000..9c154d1888 --- /dev/null +++ b/detekt_baseline_report.txt @@ -0,0 +1,121 @@ +========================================== +Detekt Baseline Updater & Issue Counter +========================================== +Date: 2025-11-18 15:11:30 + +Updating detekt baseline for debug variant... + + +Baseline updated successfully! + +========================================== +Counting issues in baseline files... +========================================== + +Summary: + Total Issues: 1798 + Modules with Issues: 91 + Average Issues per Module: 19 + +Progress: + Fixed: 4 out of 1802 (0%) + Remaining: 1798 + +========================================== +All Modules with Issues (sorted by count) +========================================== + +Module Issues +──────────────────────────────────────────────────────────────── +features/wallet/impl 171 +features/markets/impl 155 +features/onboarding-v2/impl 137 +features/onramp/impl 89 +features/send-v2/impl 80 +features/swap/impl 73 +features/hot-wallet/impl 66 +features/staking/impl 56 +data/wallet-connect 55 +features/swap-v2/impl 53 +features/walletconnect/impl 51 +features/tokendetails/impl 50 +features/manage-tokens/impl 45 +domain/wallets 39 +features/nft/impl 36 +data/wallets 32 +features/tester/impl 31 +features/yield-supply/impl 28 +domain/tokens 28 +features/swap/domain 27 +core/ui 27 +common/ui 26 +features/tangempay/details/impl 24 +data/visa 24 +features/account/impl 23 +features/wallet-settings/impl 21 +data/nft 20 +features/swap/data 15 +data/swap 13 +domain/account/status 12 +features/token-recieve/impl 11 +features/qr-scanning/impl 11 +data/onramp 11 +data/manage-tokens 11 +core/datasource 11 +features/referral/impl 10 +features/details/impl 10 +data/markets 10 +domain/staking 9 +data/yield-supply 9 +data/staking 9 +data/networks 9 +features/welcome/impl 8 +features/home/impl 8 +domain/transaction 8 +data/common 8 +data/account 8 +libs/tangem-sdk-api 7 +data/txhistory 7 +data/tokens 7 +features/send-v2/api 6 +domain/markets 6 +data/wallet-manager 6 +libs/visa 5 +domain/legacy 5 +data/transaction 5 +features/referral/domain 4 +features/biometry/impl 4 +features/account/api 4 +data/promo 4 +core/config-toggles 4 +features/txhistory/impl 3 +features/tangempay/onboarding/impl 3 +features/create-wallet-start/impl 3 +domain/manage-tokens 3 +domain/demo/models 3 +domain/card 3 +data/feedback 3 +common/routing 3 +features/yield-supply/api 2 +features/swap/domain/models 2 +features/stories/impl 2 +features/create-wallet-selection/impl 2 +domain/yield-supply 2 +domain/swap 2 +domain/nft 2 +data/express 2 +core/ab-tests 2 +common/test 2 +features/referral/data 1 +features/manage-tokens/api 1 +features/kyc/impl 1 +features/hot-wallet/api 1 +features/disclaimer/impl 1 +domain/wallet-connect 1 +domain/visa 1 +data/settings 1 +data/quotes 1 +data/hot-wallet 1 +data/balance-hiding 1 +common/ui-charts 1 +──────────────────────────────────────────────────────────────── \ No newline at end of file diff --git a/domain/account/status/detekt-baseline-debug.xml b/domain/account/status/detekt-baseline-debug.xml new file mode 100644 index 0000000000..5b524e1585 --- /dev/null +++ b/domain/account/status/detekt-baseline-debug.xml @@ -0,0 +1,18 @@ + + + + + ExplicitCollectionElementAccessMethod:ManageCryptoCurrenciesUseCase.kt$ManageCryptoCurrenciesUseCase$mutableMap.put(id, currency) + MultilineLambdaItParameter:AccountCryptoCurrencyStatusFinder.kt$AccountCryptoCurrencyStatusFinder${ val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@filter false cryptoPortfolio.derivationIndex.value in possibleAccountIndexes } + MultilineLambdaItParameter:AccountCryptoCurrencyStatusFinder.kt$AccountCryptoCurrencyStatusFinder${ val cryptoPortfolio = it.account as? Account.CryptoPortfolio ?: return@firstOrNull false cryptoPortfolio.derivationIndex.value == possibleAccountIndex } + MultilineLambdaItParameter:AccountCryptoCurrencyStatusFinder.kt$AccountCryptoCurrencyStatusFinder${ val currency = it.currency val isContractAddressMatch = contractAddress == null || currency.id.contractAddress.equals(contractAddress, ignoreCase = true) currency.network.rawId == networkId.rawId.value && currency.network.derivationPath.value == derivationPath.value && isContractAddressMatch } + MultilineLambdaItParameter:ApplyTokenListSortingUseCaseV2.kt$ApplyTokenListSortingUseCaseV2${ errors[account.accountId] = it return@map account } + MultilineLambdaItParameter:DefaultMultiAccountStatusListProducer.kt$DefaultMultiAccountStatusListProducer${ singleAccountStatusListSupplier( params = SingleAccountStatusListProducer.Params(it.walletId), ) } + MultilineLambdaItParameter:ManageCryptoCurrenciesUseCase.kt$ManageCryptoCurrenciesUseCase${ ExpressAsset.ID( networkId = it.network.backendId, contractAddress = (it as? CryptoCurrency.Token)?.contractAddress, ) } + MultilineLambdaItParameter:ManageCryptoCurrenciesUseCase.kt$ManageCryptoCurrenciesUseCase${ it.network.backendId == networkId && !it.isCustom && it.contractAddress.equals(contractAddress, true) } + UnnecessaryAbstractClass:MultiAccountStatusListSupplier.kt$MultiAccountStatusListSupplier$MultiAccountStatusListSupplier + UnnecessaryAbstractClass:SingleAccountStatusListSupplier.kt$SingleAccountStatusListSupplier$SingleAccountStatusListSupplier + UnnecessaryAbstractClass:SingleAccountStatusSupplier.kt$SingleAccountStatusSupplier$SingleAccountStatusSupplier + UnnecessaryLet:RecoverCryptoPortfolioUseCase.kt$RecoverCryptoPortfolioUseCase$let(AccountName::invoke) + + diff --git a/domain/card/detekt-baseline-debug.xml b/domain/card/detekt-baseline-debug.xml new file mode 100644 index 0000000000..277a01c1fe --- /dev/null +++ b/domain/card/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + NamedArguments:TangemCardTypesResolver.kt$TangemCardTypesResolver$Token( cardToken.name, cardToken.symbol, cardToken.contractAddress, cardToken.decimals, ) + PropertyUsedBeforeDeclaration:TapWorkarounds.kt$TapWorkarounds$excludedBatches + PropertyUsedBeforeDeclaration:TapWorkarounds.kt$TapWorkarounds$excludedIssuers + + diff --git a/domain/demo/models/detekt-baseline-debug.xml b/domain/demo/models/detekt-baseline-debug.xml new file mode 100644 index 0000000000..638c5c1870 --- /dev/null +++ b/domain/demo/models/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$debugTestDemoCardIds + PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$releaseDemoCardIds + PropertyUsedBeforeDeclaration:DemoConfig.kt$DemoConfig$testDemoCardIds + + diff --git a/domain/legacy/detekt-baseline-debug.xml b/domain/legacy/detekt-baseline-debug.xml new file mode 100644 index 0000000000..3d02fabec6 --- /dev/null +++ b/domain/legacy/detekt-baseline-debug.xml @@ -0,0 +1,11 @@ + + + + + BooleanPropertyNaming:LogConfig.kt$AnalyticsHandlersLogConfig$val amplitude: Boolean = BuildConfig.LOG_ENABLED + BooleanPropertyNaming:LogConfig.kt$AnalyticsHandlersLogConfig$val appsflyer: Boolean = BuildConfig.LOG_ENABLED + BooleanPropertyNaming:LogConfig.kt$AnalyticsHandlersLogConfig$val firebase: Boolean = BuildConfig.LOG_ENABLED + BooleanPropertyNaming:LogConfig.kt$LogConfig$val storeAction: Boolean = BuildConfig.LOG_ENABLED + BooleanPropertyNaming:LogConfig.kt$NetworkLogConfig$val blockchainSdkNetwork: Boolean = BuildConfig.LOG_ENABLED + + diff --git a/domain/manage-tokens/detekt-baseline-debug.xml b/domain/manage-tokens/detekt-baseline-debug.xml new file mode 100644 index 0000000000..5c9a9d5ec2 --- /dev/null +++ b/domain/manage-tokens/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + NamedArguments:CheckIsCurrencyNotAddedUseCase.kt$CheckIsCurrencyNotAddedUseCase$isCurrencyNotAdded(userWalletId, networkId, derivationPath, contractAddress) + NamedArguments:CreateCryptoCurrencyUseCase.kt$CreateCryptoCurrencyUseCase$createCustomToken(userWalletId, networkId, derivationPath, formValues) + NamedArguments:ValidateTokenFormUseCase.kt$ValidateTokenFormUseCase$zipOrAccumulate( { ensureIsContractAddressValid(formValues.contractAddress, networkId) }, { ensureIsDecimalsValid(formValues.decimals) }, { ensure(formValues.name.isNotBlank()) { CustomTokenFormValidationException.EmptyName } }, { ensure(formValues.symbol.isNotBlank()) { CustomTokenFormValidationException.EmptySymbol } }, ) { contractAddress, decimals, _, _ -> AddCustomTokenForm.Validated.All( contractAddress = contractAddress, symbol = formValues.symbol, name = formValues.name, decimals = decimals, ) } + + diff --git a/domain/markets/detekt-baseline-debug.xml b/domain/markets/detekt-baseline-debug.xml new file mode 100644 index 0000000000..ef5fed0f16 --- /dev/null +++ b/domain/markets/detekt-baseline-debug.xml @@ -0,0 +1,12 @@ + + + + + BooleanPropertyNaming:FilterAvailableNetworksForWalletUseCase.kt$FilterAvailableNetworksForWalletUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:GetStakingNotificationMaxApyUseCase.kt$GetStakingNotificationMaxApyUseCase$val showStakingNotification = if (!hideClicked && walletFirstUsageDate != 0L) { currentDate - walletFirstUsageDate > TWO_WEEKS_IN_MILLIS } else { false } + MultilineLambdaItParameter:FilterAvailableNetworksForWalletUseCase.kt$FilterAvailableNetworksForWalletUseCase${ val blockchain = Blockchain.fromNetworkId(it.networkId) supportedBlockchains.contains(blockchain) } + MultilineLambdaItParameter:SaveMarketTokensUseCase.kt$SaveMarketTokensUseCase${ marketsTokenRepository.createCryptoCurrency( userWalletId = userWalletId, token = tokenMarketParams, network = it, ) } + SuspendFunWithFlowReturnType:GetStakingNotificationMaxApyUseCase.kt$GetStakingNotificationMaxApyUseCase$suspend + SuspendFunWithFlowReturnType:MarketsTokenRepository.kt$MarketsTokenRepository$suspend + + diff --git a/domain/nft/detekt-baseline-debug.xml b/domain/nft/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d57ec3f083 --- /dev/null +++ b/domain/nft/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + MultilineLambdaItParameter:FilterNFTAvailableNetworksUseCase.kt$FilterNFTAvailableNetworksUseCase${ it.name.contains(searchQuery, ignoreCase = true) || it.currencySymbol.contains(searchQuery, ignoreCase = true) } + UseEmptyCounterpart:NFTAnalyticsEvent.kt$NFTAnalyticsEvent$mapOf() + + diff --git a/domain/staking/detekt-baseline-debug.xml b/domain/staking/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d84b9b39da --- /dev/null +++ b/domain/staking/detekt-baseline-debug.xml @@ -0,0 +1,15 @@ + + + + + CanBeNonNullable:StakingAnalyticsEvent.kt$StakingAnalyticsEvent$value: Any? + MultilineLambdaItParameter:FetchStakingYieldBalanceUseCase.kt$FetchStakingYieldBalanceUseCase${ when (it) { is StakingIdFactory.Error.UnableToGetAddress -> raise(StakingError.DomainError("$it")) StakingIdFactory.Error.UnsupportedCurrency -> Unit.right() } return@either } + MultilineLambdaItParameter:InvalidatePendingTransactionsUseCase.kt$InvalidatePendingTransactionsUseCase${ !it.isPending && action.amount < it.amount && it.type == BalanceType.STAKED && it.validatorAddress == action.validatorAddress } + NamedArguments:GetConstructedStakingTransactionUseCase.kt$GetConstructedStakingTransactionUseCase$constructTransaction(networkId, fee, amount, transactionId) + NullableToStringCall:StakingApyFlowUseCase.kt$StakingApyFlowUseCase$${yield.token.coinGeckoId} + UnnecessaryAbstractClass:MultiYieldBalanceSupplier.kt$MultiYieldBalanceSupplier$MultiYieldBalanceSupplier + UnnecessaryAbstractClass:SingleYieldBalanceSupplier.kt$SingleYieldBalanceSupplier$SingleYieldBalanceSupplier + UseEmptyCounterpart:StakingAnalyticsEvent.kt$StakingAnalyticsEvent$mapOf() + UseOrEmpty:InvalidatePendingTransactionsUseCase.kt$InvalidatePendingTransactionsUseCase$action.validatorAddress ?: action.validatorAddresses?.getOrNull(0) ?: "" + + diff --git a/domain/swap/detekt-baseline-debug.xml b/domain/swap/detekt-baseline-debug.xml new file mode 100644 index 0000000000..950588cc6a --- /dev/null +++ b/domain/swap/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + CouldBeSequence:GetSwapPairsUseCase.kt$GetSwapPairsUseCase$filter { pair -> filteringCurrency(pair).currency.id.rawCurrencyId == initialCurrency.id.rawCurrencyId } + CouldBeSequence:GetSwapSupportedPairsUseCase.kt$GetSwapSupportedPairsUseCase$filter { pair -> filteringCurrency(pair).currency.id.rawCurrencyId == initialCurrency.id.rawCurrencyId } + + diff --git a/domain/tokens/detekt-baseline-debug.xml b/domain/tokens/detekt-baseline-debug.xml new file mode 100644 index 0000000000..f1b234f537 --- /dev/null +++ b/domain/tokens/detekt-baseline-debug.xml @@ -0,0 +1,34 @@ + + + + + BooleanPropertyNaming:TokenActionsState.kt$TokenActionsState.ActionState.Swap$val showBadge: Boolean + CanBeNonNullable:BaseActionsFactory.kt$BaseActionsFactory$requirementsDeferred: Deferred<AssetRequirementsCondition?>? + CanBeNonNullable:CommonActionsFactory.kt$CommonActionsFactory$swapUnavailableReasonDeferred: Deferred<ScenarioUnavailabilityReason>? + ExplicitCollectionElementAccessMethod:GetWalletTotalBalanceUseCase.kt$GetWalletTotalBalanceUseCase$walletBalanceCache.put(userWalletId, content) + MultilineLambdaItParameter:AddCryptoCurrenciesUseCase.kt$AddCryptoCurrenciesUseCase${ it.network.backendId == networkId && !it.isCustom && it.contractAddress.equals(contractAddress, true) } + MultilineLambdaItParameter:AddCryptoCurrenciesUseCase.kt$AddCryptoCurrenciesUseCase${ when (it) { is StakingIdFactory.Error.UnableToGetAddress -> raise(IllegalStateException("$it")) StakingIdFactory.Error.UnsupportedCurrency -> Unit.right() } return@either } + MultilineLambdaItParameter:BaseCurrencyStatusOperations.kt$BaseCurrencyStatusOperations${ singleQuoteStatusSupplier(params = SingleQuoteStatusProducer.Params(rawCurrencyId = it)) .firstOrNull() } + MultilineLambdaItParameter:BaseCurrencyStatusOperations.kt$BaseCurrencyStatusOperations${ val exception = IllegalStateException("$it") Error.DataError(exception) } + MultilineLambdaItParameter:FetchCurrencyStatusUseCase.kt$FetchCurrencyStatusUseCase${ when (it) { is StakingIdFactory.Error.UnableToGetAddress -> raise(IllegalStateException("$it")) StakingIdFactory.Error.UnsupportedCurrency -> Unit.right() } return@either } + MultilineLambdaItParameter:GetBalanceNotEnoughForFeeWarningUseCase.kt$GetBalanceNotEnoughForFeeWarningUseCase${ it is CryptoCurrency.Token && it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && it.network.derivationPath == tokenStatus.currency.network.derivationPath } + MultilineLambdaItParameter:GetCryptoCurrencyActionsUseCase.kt$GetCryptoCurrencyActionsUseCase${ TokenActionsState( walletId = userWallet.walletId, cryptoCurrencyStatus = cryptoCurrencyStatus, states = it.toList(), ) } + MultilineLambdaItParameter:GetCryptoCurrencyActionsUseCase.kt$GetCryptoCurrencyActionsUseCase${ outdatedDataActionsFactory.create( userWallet = userWallet, cryptoCurrencyStatus = cryptoCurrencyStatus, stakingAvailability = it, ) } + MultilineLambdaItParameter:GetCurrencyWarningsUseCase.kt$GetCurrencyWarningsUseCase${ if (isNeedToCreateAccountWithoutReserve(networkId = currencyStatus.currency.network.rawId)) { CryptoCurrencyWarning.TopUpWithoutReserve } else { CryptoCurrencyWarning.SomeNetworksNoAccount( amountToCreateAccount = it.amountToCreateAccount, amountCurrency = currencyStatus.currency, ) } } + MultilineLambdaItParameter:GetCurrencyWarningsUseCase.kt$GetCurrencyWarningsUseCase${ it is CryptoCurrency.Token && it.contractAddress.equals(feePaidToken.contractAddress, ignoreCase = true) && it.network.derivationPath == tokenStatus.currency.network.derivationPath } + MultilineLambdaItParameter:GetWalletTotalBalanceUseCase.kt$GetWalletTotalBalanceUseCase${ Timber.e("failed to load balances with error: $it") TotalFiatBalance.Failed } + MultilineLambdaItParameter:PriceChangeCalculator.kt$PriceChangeCalculator${ val weight = it.value.fiatAmount.orZero().divide(balance, 2, RoundingMode.HALF_UP) val priceChange = it.value.priceChange.orZero() weight * priceChange } + MultilineLambdaItParameter:WalletBalanceFetcher.kt$WalletBalanceFetcher${ val stakingId = stakingIdFactory.create(userWalletId = userWalletId, cryptoCurrency = it) if (stakingId.isLeft { it is StakingIdFactory.Error.UnableToGetAddress }) { Timber.e("Unable to get staking ID for user wallet $userWalletId and currency ${it.id}") } stakingId } + NamedArguments:ApplyTokenListSortingUseCase.kt$ApplyTokenListSortingUseCase$saveTokens(userWalletId, currencies, isGrouped, isSortedByBalance) + NamedArguments:CryptoCurrencyStatusFactory.kt$CryptoCurrencyStatusFactory$createStatus(currency, status, quoteStatus, maybeYieldBalance) + NamedArguments:GetCurrencyWarningsUseCase.kt$GetCurrencyWarningsUseCase$combine( getCoinRelatedWarnings( userWalletId = userWalletId, networkId = currency.network.id, currencyId = currency.id, derivationPath = derivationPath, isSingleWalletWithTokens = isSingleWalletWithTokens, ), flowOf(currencyChecksRepository.getRentInfoWarning(userWalletId, currencyStatus)), flowOf(currencyChecksRepository.getExistentialDeposit(userWalletId, currency.network)), flowOf(currencyChecksRepository.getFeeResourceAmount(userWalletId, currency.network)), ) { coinRelatedWarnings, maybeRentWarning, maybeEdWarning, maybeFeeResource -> setOfNotNull( maybeRentWarning, maybeEdWarning?.let { getExistentialDepositWarning(currency, it) }, maybeFeeResource?.let { getFeeResourceWarning(it) }, * coinRelatedWarnings.toTypedArray(), getNetworkUnavailableWarning(currencyStatus), getNetworkNoAccountWarning(currencyStatus), getBeaconChainShutdownWarning(rawId = currency.network.id.rawId), getAssetRequirementsWarning(userWalletId = userWalletId, currency = currency), getMigrationFromMaticToPolWarning(currency), ) } + NoNameShadowing:WalletBalanceFetcher.kt$WalletBalanceFetcher${ it is StakingIdFactory.Error.UnableToGetAddress } + NullableBooleanCheck:GetCurrencyCheckUseCase.kt$GetCurrencyCheckUseCase$recipientAddress?.let { currencyChecksRepository.checkIfAccountFunded( userWalletId, network, recipientAddress, ) } ?: false + SuspendFunWithFlowReturnType:BaseCurrencyStatusOperations.kt$BaseCurrencyStatusOperations$suspend + SuspendFunWithFlowReturnType:GetCurrencyWarningsUseCase.kt$GetCurrencyWarningsUseCase$suspend + SuspendFunWithFlowReturnType:GetNetworkCoinStatusUseCase.kt$GetNetworkCoinStatusUseCase$suspend + SuspendFunWithFlowReturnType:GetSingleCryptoCurrencyStatusUseCase.kt$GetSingleCryptoCurrencyStatusUseCase$suspend + UnnecessaryAbstractClass:MultiWalletCryptoCurrenciesSupplier.kt$MultiWalletCryptoCurrenciesSupplier$MultiWalletCryptoCurrenciesSupplier + UnsafeCallOnNullableType:CommonActionsFactory.kt$CommonActionsFactory$swapUnavailableReasonDeferred!! + + diff --git a/domain/transaction/detekt-baseline-debug.xml b/domain/transaction/detekt-baseline-debug.xml new file mode 100644 index 0000000000..40a21e2f39 --- /dev/null +++ b/domain/transaction/detekt-baseline-debug.xml @@ -0,0 +1,14 @@ + + + + + BooleanPropertyNaming:SendTransactionUseCase.kt$SendTransactionUseCase$val linkedTerminal = cardSdkConfigRepository.isLinkedTerminal() + BooleanPropertyNaming:ValidateWalletAddressUseCase.kt$ValidateWalletAddressUseCase$val current = isCurrentAddress(addressToValidate) + MultilineLambdaItParameter:AssociateAssetUseCase.kt$AssociateAssetUseCase${ val network = currency.network it.network.id == network.id && it.network.derivationPath == network.derivationPath } + NamedArguments:SendTransactionUseCase.kt$SendTransactionUseCase$invoke(listOf(txData), userWallet, network, TransactionSender.MultipleTransactionSendMode.DEFAULT) + NamedArguments:ValidateWalletAddressUseCase.kt$ValidateWalletAddressUseCase$validateAddressInternal( userWalletId, network, address, isCurrentAddress = { toValidate -> currencyAddresses?.any { it.value == toValidate } ?: true }, ) + NamedArguments:ValidateWalletAddressUseCase.kt$ValidateWalletAddressUseCase$validateAddressInternal( userWalletId, network, address, isCurrentAddress = { toValidate -> senderAddresses.any { it.address == toValidate } }, ) + NullableBooleanCheck:ValidateWalletAddressUseCase.kt$ValidateWalletAddressUseCase$currencyAddresses?.any { it.value == toValidate } ?: true + UnnecessaryLet:RetryIncompleteTransactionUseCase.kt$RetryIncompleteTransactionUseCase$let { raise(IncompleteTransactionError.SendError(it)) } + + diff --git a/domain/visa/detekt-baseline-debug.xml b/domain/visa/detekt-baseline-debug.xml new file mode 100644 index 0000000000..6f7affc0e3 --- /dev/null +++ b/domain/visa/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + SuspendFunSwallowedCancellation:SetVisaPinCodeUseCase.kt$SetVisaPinCodeUseCase$runCatching + + diff --git a/domain/wallet-connect/detekt-baseline-debug.xml b/domain/wallet-connect/detekt-baseline-debug.xml new file mode 100644 index 0000000000..9f061ccbe0 --- /dev/null +++ b/domain/wallet-connect/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + UseEmptyCounterpart:WcAnalyticEvents.kt$WcAnalyticEvents$mapOf() + + diff --git a/domain/wallets/detekt-baseline-debug.xml b/domain/wallets/detekt-baseline-debug.xml new file mode 100644 index 0000000000..149134a54c --- /dev/null +++ b/domain/wallets/detekt-baseline-debug.xml @@ -0,0 +1,45 @@ + + + + + BooleanPropertyNaming:DefaultUserWalletsSyncDelegate.kt$DefaultUserWalletsSyncDelegate$private val useNewRepository: Boolean + BooleanPropertyNaming:DeleteWalletUseCase.kt$DeleteWalletUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:GenerateWalletNameUseCase.kt$GenerateWalletNameUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:GetSavedWalletsCountUseCase.kt$GetSavedWalletsCountUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:GetSelectedWalletSyncUseCase.kt$GetSelectedWalletSyncUseCase$private val useNewRepository: Boolean = false + BooleanPropertyNaming:GetSelectedWalletUseCase.kt$GetSelectedWalletUseCase$private val useNewRepository: Boolean = false + BooleanPropertyNaming:GetUserWalletUseCase.kt$GetUserWalletUseCase$private val useNewListRepository: Boolean + BooleanPropertyNaming:GetWalletNamesUseCase.kt$GetWalletNamesUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:GetWalletsUseCase.kt$GetWalletsUseCase$private val useNewListRepository: Boolean + BooleanPropertyNaming:HotWalletAccessCodeAttemptsRepository.kt$HotWalletAccessCodeAttemptsRepository.AttemptId$val auth: Boolean + BooleanPropertyNaming:HotWalletPasswordRequester.kt$HotWalletPasswordRequester.AttemptRequest$val authMode: Boolean + BooleanPropertyNaming:IsNeedToBackupUseCase.kt$IsNeedToBackupUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:IsWalletAlreadySavedUseCase.kt$IsWalletAlreadySavedUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:SaveWalletUseCase.kt$SaveWalletUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:SaveWalletUseCase.kt$SaveWalletUseCase$val newUserWallet = userWalletsListRepository.userWalletsSync().none { it.walletId == userWallet.walletId } + BooleanPropertyNaming:SelectWalletUseCase.kt$SelectWalletUseCase$private val useNewRepository: Boolean + BooleanPropertyNaming:UpdateWalletUseCase.kt$UpdateWalletUseCase$private val useNewRepository: Boolean + MaxChainedCallsOnSameLine:UserWalletExtensions.kt$wallets.orEmpty().first { it.curve == primaryCurve }.derivedKeys.keys.any { it == dp } + MultilineLambdaItParameter:ColdUserWalletBuilder.kt$ColdUserWalletBuilder${ UserWallet.Cold( walletId = it, name = generateWalletNameUseCase( card = card, productType = productType, isStartToCoin = cardTypesResolver.isStart2Coin(), ), cardsInWallet = backupCardsIds.plus(card.cardId), scanResponse = this, isMultiCurrency = cardTypesResolver.isMultiwalletAllowed(), hasBackupError = hasBackupError, ) } + MultilineLambdaItParameter:HotUserWalletBuilder.kt$HotUserWalletBuilder${ MobileWallet( publicKey = it.seedKey.publicKey, chainCode = it.seedKey.chainCode, curve = it.curve, derivedKeys = it.publicKeys, ) } + MultilineLambdaItParameter:HotUserWalletBuilder.kt$HotUserWalletBuilder${ val derivationPath = it.derivationPath(DerivationStyle.V3) ?: return@mapNotNull null if (it == Blockchain.Cardano) { val extendedDerivationPath = CardanoUtils.extendedDerivationPath(derivationPath) listOf(derivationPath, extendedDerivationPath) } else { listOf(derivationPath) } } + MultilineLambdaItParameter:SaveWalletUseCase.kt$SaveWalletUseCase${ return when (it) { is UserWalletsListError.WalletAlreadySaved -> SaveWalletError.WalletAlreadySaved( it.messageResId, ) else -> SaveWalletError.DataError(it.messageResId) }.left() } + MultilineLambdaItParameter:SelectWalletUseCase.kt$SelectWalletUseCase${ reduxStateHolder.onUserWalletSelected(it) it } + MultilineLambdaItParameter:UpdateWalletUseCase.kt$UpdateWalletUseCase${ when (it) { is SaveWalletError.DataError -> DataError( IllegalStateException("Failed to update wallet: ${it.messageId}"), ) is SaveWalletError.WalletAlreadySaved -> UpdateWalletError.NameAlreadyExists } } + NestedScopeFunctions:ColdUserWalletBuilder.kt$ColdUserWalletBuilder$let { UserWallet.Cold( walletId = it, name = generateWalletNameUseCase( card = card, productType = productType, isStartToCoin = cardTypesResolver.isStart2Coin(), ), cardsInWallet = backupCardsIds.plus(card.cardId), scanResponse = this, isMultiCurrency = cardTypesResolver.isMultiwalletAllowed(), hasBackupError = hasBackupError, ) } + NoNameShadowing:SaveWalletUseCase.kt$SaveWalletUseCase$userWallet + NonBooleanPropertyPrefixedWithIs:GetExtendedPublicKeyForCurrencyUseCase.kt$GetExtendedPublicKeyForCurrencyUseCase$val isHdKey = walletManager.wallet.publicKey.derivationType?.hdKey + NonBooleanPropertyPrefixedWithIs:UserWalletsListManagerExtensions.kt$/** * Indicates that the [UserWalletsListManager] is locked * * @return If [UserWalletsListManager] not implements [UserWalletsListManager.Lockable] returns [Flow] which * produces only one false value * * @see UserWalletsListManager.Lockable.isLocked * */ val UserWalletsListManager.isLocked: Flow<Boolean> get() = asLockable()?.lockedState ?: flowOf(false) + NullableToStringCall:GenerateBuyTangemCardLinkUseCase.kt$GenerateBuyTangemCardLinkUseCase$$id + NullableToStringCall:UpdateWalletUseCase.kt$UpdateWalletUseCase$${it.messageId} + ObjectExtendsThrowable:UserWalletsListError.kt$UserWalletsListError$AllKeysInvalidated : UserWalletsListError + ObjectExtendsThrowable:UserWalletsListError.kt$UserWalletsListError$BiometricsAuthenticationDisabled : UserWalletsListError + ObjectExtendsThrowable:UserWalletsListError.kt$UserWalletsListError$NoUserWalletSelected : UserWalletsListError + ObjectExtendsThrowable:UserWalletsListError.kt$UserWalletsListError$NotAllUserWalletsUnlocked : UserWalletsListError + ObjectExtendsThrowable:UserWalletsListError.kt$UserWalletsListError$WalletAlreadySaved : UserWalletsListError + RedundantSuspendModifier:GetHotWalletContextualUnlockUseCase.kt$GetHotWalletContextualUnlockUseCase$suspend + SuspendFunSwallowedCancellation:RenameWalletUseCase.kt$RenameWalletUseCase$runCatching + UnsafeCallOnNullableType:GetWalletsUseCase.kt$GetWalletsUseCase$userWalletsListRepository.userWallets.value!! + UnsafeCallOnNullableType:UserWalletIdBuilder.kt$UserWalletIdBuilder.Companion$UserWalletIdBuilder( publicKey = publicKey, ).build()!! + + diff --git a/domain/yield-supply/detekt-baseline-debug.xml b/domain/yield-supply/detekt-baseline-debug.xml new file mode 100644 index 0000000000..7bb0bea0e1 --- /dev/null +++ b/domain/yield-supply/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + NestedScopeFunctions:YieldSupplyGetRewardsBalanceUseCase.kt$YieldSupplyGetRewardsBalanceUseCase$let { rate -> amt.multiply(rate) } + UnnecessaryNotNullCheck:YieldSupplyGetProtocolBalanceUseCase.kt$YieldSupplyGetProtocolBalanceUseCase$requireNotNull(cryptoCurrency as CryptoCurrency.Token) + + diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1a0bdccf7e..0b4ac32038 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -22,7 +22,7 @@ platform :android do FileUtils.cp("../app/src/main/assets/tangem-app-config/android/google-services/dev/google-services.json", "../app") FileUtils.cp("../tangem-android-tools/CI/gradle_properties/tests_ci_gradle.properties", "../gradle.properties") puts File.read("../gradle.properties") - gradle(task: "detekt detektGoogleDebug --continue") + gradle(task: "detekt detektGoogleDebug detektDebug --continue") end desc "Run tests" diff --git a/features/account/api/detekt-baseline-debug.xml b/features/account/api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..43b883bfc2 --- /dev/null +++ b/features/account/api/detekt-baseline-debug.xml @@ -0,0 +1,10 @@ + + + + + BooleanPropertyNaming:PortfolioFetcher.kt$PortfolioFetcher.Mode.All$val onlyMultiCurrency: Boolean + NonBooleanPropertyPrefixedWithIs:PortfolioSelectorComponent.kt$PortfolioSelectorController$/** * for some Feature specific filtering * combine and update with your Feature data and [PortfolioFetcher.data] */ val isEnabled: MutableStateFlow<(UserWallet, AccountStatus) -> Boolean> + NonBooleanPropertyPrefixedWithIs:PortfolioSelectorComponent.kt$PortfolioSelectorController$val isAccountMode: Flow<Boolean> + UseSumOfInsteadOfFlatMapSize:PortfolioFetcher.kt$PortfolioFetcher.Data$flatten() + + diff --git a/features/account/impl/detekt-baseline-debug.xml b/features/account/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..b3408ebf0b --- /dev/null +++ b/features/account/impl/detekt-baseline-debug.xml @@ -0,0 +1,29 @@ + + + + + BooleanPropertyNaming:AccountCreateEditModel.kt$AccountCreateEditModel$val duplicateAccountNames = (error as? AddCryptoPortfolioUseCase.Error.AccountListRequirementsNotMet) ?.cause is AccountList.Error.DuplicateAccountNames + BooleanPropertyNaming:AccountCreateEditModel.kt$AccountCreateEditModel$val duplicateAccountNames = (error as? UpdateCryptoPortfolioUseCase.Error.AccountListRequirementsNotMet) ?.cause is AccountList.Error.DuplicateAccountNames + BooleanPropertyNaming:AccountCreateEditModel.kt$AccountCreateEditModel$val showConfirmDialog = uiState.value.buttonState.isButtonEnabled + BooleanPropertyNaming:AccountCreateEditUM.kt$AccountCreateEditUM.Button$val showProgress: Boolean + MultilineLambdaItParameter:AccountCreateEditContent.kt${ /* * If the user had the default main account name and enters the same name during renaming, * we should use the default value instead of custom to avoid breaking the name validation process. */ val newName = if (wasDefault && it == defaultAccountName) { AccountNameUM.DefaultMain } else { AccountNameUM.Custom(raw = it) } account.onNameChange(newName) } + MultilineLambdaItParameter:ArchivedAccountListContent.kt$PreviewStateProvider${ ArchivedAccountUM( accountId = it.toString(), accountName = accountName, accountIconUM = portfolioIcon(), tokensInfo = stringReference("10 tokens"), networksInfo = stringReference("2 networks"), onClick = {}, isLoading = it % 2 == 0, ) } + NamedArguments:PortfolioSelectorModel.kt$PortfolioSelectorModel$buildAccountsList(portfolioData, artworks, isEnabled, selectedAccount) + NamedArguments:PortfolioSelectorModel.kt$PortfolioSelectorModel$buildUiList(isAccountsMode, portfolioData, artworks, isEnabled, selectedAccount) + NamedArguments:PortfolioSelectorModel.kt$PortfolioSelectorModel$buildWalletList(portfolioData, artworks, isEnabled, selectedAccount) + NonBooleanPropertyPrefixedWithIs:DefaultPortfolioSelectorController.kt$DefaultPortfolioSelectorController$override val isAccountMode: Flow<Boolean> by lazy { isAccountsModeEnabledUseCase() } + NonBooleanPropertyPrefixedWithIs:DefaultPortfolioSelectorController.kt$DefaultPortfolioSelectorController$override val isEnabled: MutableStateFlow<(UserWallet, AccountStatus) -> Boolean> = MutableStateFlow { _, _ -> true } + NonBooleanPropertyPrefixedWithIs:DefaultPortfolioSelectorController.kt$DefaultPortfolioSelectorController$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:PortfolioSelectorModel.kt$PortfolioSelectorModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NullableBooleanCheck:AccountDetailsModel.kt$AccountDetailsModel$getUserWalletUseCase(account.accountId.userWalletId) .getOrNull()?.isMultiCurrency ?: false + PropertyUsedBeforeDeclaration:AccountDetailsModel.kt$AccountDetailsModel$_uiState + PropertyUsedBeforeDeclaration:ArchivedAccountListModel.kt$ArchivedAccountListModel$_uiState + UnnecessaryLet:ArchivedAccountListModel.kt$ArchivedAccountListModel$let { _uiState.value = newState } + UnnecessaryLet:PortfolioSelectorContent.kt$PortfolioSelectorPreviewData$let(::add) + UnusedImports:PortfolioSelectorBS.kt$import androidx.compose.foundation.background + UseEmptyCounterpart:AccountCreateEditModel.kt$AccountCreateEditModel$mapOf() + UseEmptyCounterpart:ArchivedAccountListModel.kt$ArchivedAccountListModel$mapOf() + VarCouldBeVal:AccountDetailsContent.kt$PreviewStateProvider$var portfolioIcon = AccountIconPreviewData.randomAccountIcon() + VarCouldBeVal:ArchivedAccountListModel.kt$ArchivedAccountListModel$private var getArchivedAccountsJob = JobHolder() + + diff --git a/features/biometry/impl/detekt-baseline-debug.xml b/features/biometry/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..f439e02f2e --- /dev/null +++ b/features/biometry/impl/detekt-baseline-debug.xml @@ -0,0 +1,10 @@ + + + + + BooleanPropertyNaming:AskBiometryUM.kt$AskBiometryUM$val bottomSheetVariant: Boolean = false + BooleanPropertyNaming:AskBiometryUM.kt$AskBiometryUM$val showProgress: Boolean = false + BooleanPropertyNaming:DefaultAskBiometryComponent.kt$DefaultAskBiometryComponent$val bsShown by bsShown.collectAsStateWithLifecycle() + MultilineLambdaItParameter:AskBiometryModel.kt$AskBiometryModel${ uiMessageSender.send( SnackbarMessage(stringReference("Something went wrong. Please contact support: $it")), ) } + + diff --git a/features/create-wallet-selection/impl/detekt-baseline-debug.xml b/features/create-wallet-selection/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..5cabd0af5c --- /dev/null +++ b/features/create-wallet-selection/impl/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + BooleanPropertyNaming:CreateWalletSelectionUM.kt$CreateWalletSelectionUM$val showAlreadyHaveWallet: Boolean = false + MultilineLambdaItParameter:CreateWalletSelectionContent.kt${ Feature( feature = it, modifier = Modifier .padding(top = 12.dp), ) } + + diff --git a/features/create-wallet-start/impl/detekt-baseline-debug.xml b/features/create-wallet-start/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..7090dd6ebf --- /dev/null +++ b/features/create-wallet-start/impl/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + BooleanPropertyNaming:CreateWalletStartUM.kt$CreateWalletStartUM$val showScanSecondaryButton: Boolean + MultilineLambdaItParameter:CreateWalletStartContent.kt${ FeatureItem( iconResId = it.iconResId, text = it.text, ) } + MultilineLambdaItParameter:CreateWalletStartModel.kt$CreateWalletStartModel${ delay(HIDE_PROGRESS_DELAY) setLoading(false) when (it) { is SaveWalletError.DataError -> Timber.e(it.toString(), "Unable to save user wallet") is SaveWalletError.WalletAlreadySaved -> { userWalletsListRepository.unlock( userWalletId = userWallet.walletId, unlockMethod = UserWalletsListRepository.UnlockMethod.Scan(scanResponse), ).onRight { appRouter.replaceAll(AppRoute.Wallet) } } } } + + diff --git a/features/details/impl/detekt-baseline-debug.xml b/features/details/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..e574008e71 --- /dev/null +++ b/features/details/impl/detekt-baseline-debug.xml @@ -0,0 +1,16 @@ + + + + + HasPlatformType:DetailsModel.kt$DetailsModel.Companion$val APP_LANGUAGE = Locale.getDefault().language + HasPlatformType:DetailsModel.kt$DetailsModel.Companion$val SYSTEM_LANGUAGE = runCatching { Resources.getSystem().configuration.locales[0].language }.getOrElse { "" } + MultilineLambdaItParameter:DetailsModel.kt$DetailsModel${ Timber.w("Unable to check WalletConnect availability: $it") false } + MultilineLambdaItParameter:DetailsModel.kt$DetailsModel${ it.copy( selectFeedbackEmailTypeBSConfig = TangemBottomSheetConfig( isShown = true, onDismissRequest = { state.update { it.copy( selectFeedbackEmailTypeBSConfig = it.selectFeedbackEmailTypeBSConfig.copy(isShown = false), ) } }, content = SelectEmailFeedbackTypeBS( onOptionClick = { option -> onEmailFeedbackTypeOptionSelected( selectedWalletMetaInfo = selectedWalletMetaInfo, option = option, ) state.update { it.copy( selectFeedbackEmailTypeBSConfig = it.selectFeedbackEmailTypeBSConfig.copy(isShown = false), ) } }, ), ), ) } + MultilineLambdaItParameter:DetailsModel.kt$DetailsModel${ it.copy( selectFeedbackEmailTypeBSConfig = it.selectFeedbackEmailTypeBSConfig.copy(isShown = false), ) } + MultilineLambdaItParameter:PreviewUserWalletListComponent.kt$PreviewUserWalletListComponent${ it.copy( balance = UserWalletItemUM.Balance.Loaded( value = "1.000 BTC", isFlickering = true, ), ) } + MultilineLambdaItParameter:UserWalletSaver.kt$UserWalletSaver${ val message = it.message if (!message.isNullOrEmpty()) { messageSender.send(SnackbarMessage(message)) } } + NonBooleanPropertyPrefixedWithIs:UserWalletListModel.kt$UserWalletListModel$private val isWalletSavingInProgress: MutableStateFlow<Boolean> = MutableStateFlow(value = false) + RedundantSuspendModifier:UserWalletSaver.kt$UserWalletSaver$suspend + UnnecessaryLet:ItemsBuilder.kt$ItemsBuilder$let(::add) + + diff --git a/features/disclaimer/impl/detekt-baseline-debug.xml b/features/disclaimer/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d104e3978e --- /dev/null +++ b/features/disclaimer/impl/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + NullableToStringCall:DisclaimerWebViewClient.kt$DisclaimerWebViewClient$$url + + diff --git a/features/home/impl/detekt-baseline-debug.xml b/features/home/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..684e103473 --- /dev/null +++ b/features/home/impl/detekt-baseline-debug.xml @@ -0,0 +1,14 @@ + + + + + BooleanPropertyNaming:HomeButtons.kt$HomeButtonsState$val btnScanStateInProgress: Boolean + BooleanPropertyNaming:HomeUM.kt$HomeUM$val scanInProgress: Boolean + MultilineLambdaItParameter:HomeModel.kt$HomeModel${ delay(HIDE_PROGRESS_DELAY) setLoading(false) when (it) { is SaveWalletError.DataError -> Timber.e(it.toString(), "Unable to save user wallet") is SaveWalletError.WalletAlreadySaved -> appRouter.replaceAll(AppRoute.Wallet) } } + MultilineLambdaItParameter:StoriesProgressBar.kt${ when (index) { currentStep -> it.fillMaxWidth(progress.value) in 0 until currentStep -> it.fillMaxWidth(fraction = 1f) else -> it } } + NonBooleanPropertyPrefixedWithIs:StoriesAnimation.kt$val isFirstStepLaunched = remember { mutableStateOf(false) } + NonBooleanPropertyPrefixedWithIs:StoriesAnimation.kt$val isLaunched = remember { mutableStateOf(false) } + NonBooleanPropertyPrefixedWithIs:StoriesAnimation.kt$val isSecondStepLaunched = remember { mutableStateOf(false) } + ReusedModifierInstance:HomeButtonsV2.kt$StoriesButton( modifier = modifier, text = stringResourceSafe(id = R.string.common_get_started), useDarkerColors = false, onClick = onGetStartedClick, ) + + diff --git a/features/hot-wallet/api/detekt-baseline-debug.xml b/features/hot-wallet/api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..a4cc7258d2 --- /dev/null +++ b/features/hot-wallet/api/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + BooleanPropertyNaming:CreateWalletBackupComponent.kt$CreateWalletBackupComponent.Params$val setAccessCode: Boolean + + diff --git a/features/hot-wallet/impl/detekt-baseline-debug.xml b/features/hot-wallet/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..49d05f161c --- /dev/null +++ b/features/hot-wallet/impl/detekt-baseline-debug.xml @@ -0,0 +1,72 @@ + + + + + BooleanPropertyNaming:AccessCodeModel.kt$AccessCodeModel$var buttonClicked = false + BooleanPropertyNaming:AccessCodeUM.kt$AccessCodeUM$val buttonEnabled: Boolean + BooleanPropertyNaming:AccessCodeUM.kt$AccessCodeUM$val buttonInProgress: Boolean + BooleanPropertyNaming:AddExistingWalletImportUM.kt$AddExistingWalletImportUM$val importWalletEnabled: Boolean + BooleanPropertyNaming:AddExistingWalletImportUM.kt$AddExistingWalletImportUM$val importWalletProgress: Boolean + BooleanPropertyNaming:AddExistingWalletImportUM.kt$AddExistingWalletImportUM$val readyToImport: Boolean + BooleanPropertyNaming:CreateMobileWalletUM.kt$CreateMobileWalletUM$val createButtonLoading: Boolean + BooleanPropertyNaming:ForgetWalletUM.kt$ForgetWalletUM$val firstCheckboxChecked: Boolean + BooleanPropertyNaming:ForgetWalletUM.kt$ForgetWalletUM$val secondCheckboxChecked: Boolean + BooleanPropertyNaming:HotAccessCodeRequestUM.kt$HotAccessCodeRequestUM$val useBiometricVisible: Boolean = true + BooleanPropertyNaming:HotWalletStepperComponent.kt$HotWalletStepperComponent.StepperUM$val showBackButton: Boolean + BooleanPropertyNaming:HotWalletStepperComponent.kt$HotWalletStepperComponent.StepperUM$val showFeedbackButton: Boolean + BooleanPropertyNaming:HotWalletStepperComponent.kt$HotWalletStepperComponent.StepperUM$val showSkipButton: Boolean + BooleanPropertyNaming:ManualBackupCheckUM.kt$ManualBackupCheckUM$val completeButtonEnabled: Boolean + BooleanPropertyNaming:ManualBackupCheckUM.kt$ManualBackupCheckUM$val completeButtonProgress: Boolean + BooleanPropertyNaming:ManualBackupCheckUM.kt$ManualBackupCheckUM.WordField$val error: Boolean + BooleanPropertyNaming:MobileWalletSetupFinishedContent.kt$var showConfetti by remember { mutableStateOf(false) } + BooleanPropertyNaming:UpgradeWalletModel.kt$UpgradeWalletModel$val otherWalletAndAlreadyCreated by lazy { userWallet?.walletId != params.userWalletId && it.card.wallets.map { it.curve }.toSet().isNotEmpty() } + BooleanPropertyNaming:UpgradeWalletModel.kt$UpgradeWalletModel$val sameWalletButNotFinishedBackup by lazy { userWallet?.walletId == params.userWalletId && BackupValidator.isValidFull(it.card).not() } + BooleanPropertyNaming:WalletBackupUM.kt$WalletBackupUM$val backedUp: Boolean + BooleanPropertyNaming:WalletHardwareBackupUM.kt$WalletHardwareBackupUM$val showPurchaseBlock: Boolean = false + MaxChainedCallsOnSameLine:UpgradeWalletModel.kt$UpgradeWalletModel$it.card.wallets.map { it.curve }.toSet().isNotEmpty() + MultilineLambdaItParameter:AccessCodeModel.kt$AccessCodeModel${ Timber.e(it) uiState.update { it.copy(buttonInProgress = false) } } + MultilineLambdaItParameter:AccessCodeModel.kt$AccessCodeModel${ it.copy( accessCode = value, buttonEnabled = if (params.accessCodeToConfirm != null) { value == params.accessCodeToConfirm } else { value.length == uiState.value.accessCodeLength }, accessCodeColor = when { params.accessCodeToConfirm == null -> PinTextColor.Primary value.length != uiState.value.accessCodeLength -> PinTextColor.Primary value == params.accessCodeToConfirm -> PinTextColor.Primary else -> PinTextColor.WrongCode }, ) } + MultilineLambdaItParameter:AddExistingWalletImportModel.kt$AddExistingWalletImportModel${ Timber.e(it) setImportProgress(false) } + MultilineLambdaItParameter:AddExistingWalletImportModel.kt$AddExistingWalletImportModel${ setImportProgress(false) when (it) { is SaveWalletError.DataError -> Timber.e(it.toString(), "Unable to save user wallet") is SaveWalletError.WalletAlreadySaved -> { uiMessageSender.send( SnackbarMessage(resourceReference(R.string.hw_import_seed_phrase_already_imported)), ) } } } + MultilineLambdaItParameter:CreateHardwareWalletModel.kt$CreateHardwareWalletModel${ delay(HIDE_PROGRESS_DELAY) setLoading(false) when (it) { is SaveWalletError.DataError -> Timber.e(it.toString(), "Unable to save user wallet") is SaveWalletError.WalletAlreadySaved -> { userWalletsListRepository.unlock( userWalletId = userWallet.walletId, unlockMethod = UserWalletsListRepository.UnlockMethod.Scan(scanResponse), ).onRight { router.replaceAll(AppRoute.Wallet) } } } } + MultilineLambdaItParameter:CreateMobileWalletModel.kt$CreateMobileWalletModel${ Timber.e(it) uiState.update { it.copy(createButtonLoading = false) } } + MultilineLambdaItParameter:ForgetWalletModel.kt$ForgetWalletModel${ Timber.e("Unable to delete wallet: $it") uiMessageSender.send( message = SnackbarMessage(resourceReference(R.string.common_unknown_error)), ) return@launch } + MultilineLambdaItParameter:ForgetWalletModel.kt$ForgetWalletModel${ val newValue = !it.firstCheckboxChecked it.copy( firstCheckboxChecked = newValue, isForgetButtonEnabled = newValue && it.secondCheckboxChecked, ) } + MultilineLambdaItParameter:ForgetWalletModel.kt$ForgetWalletModel${ val newValue = !it.secondCheckboxChecked it.copy( secondCheckboxChecked = newValue, isForgetButtonEnabled = it.firstCheckboxChecked && newValue, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( accessCode = accessCode, accessCodeColor = PinTextColor.Primary, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( accessCodeColor = PinTextColor.Success, onAccessCodeChange = {}, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( accessCodeColor = PinTextColor.WrongCode, onAccessCodeChange = {}, useBiometricVisible = currentRequest.isBiometryButtonVisible(), ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( isShown = true, accessCode = "", useBiometricVisible = attemptRequest.isBiometryButtonVisible(), onAccessCodeChange = ::onAccessCodeChange, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( onAccessCodeChange = {}, useBiometricVisible = false, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( wrongAccessCodeText = null, onAccessCodeChange = ::onAccessCodeChange, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( wrongAccessCodeText = remainingSecondsToText(attempts.remainingSeconds) ?: resourceReference( R.string.access_code_check_warining_delete, wrappedList(attempts.remainingAttemptsCountBeforeDeletion), ), onAccessCodeChange = ::onAccessCodeChange.takeIf { attempts.remainingSeconds <= 0 } ?: {}, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( wrongAccessCodeText = remainingSecondsToText(attempts.remainingSeconds), onAccessCodeChange = ::onAccessCodeChange.takeIf { attempts.remainingSeconds <= 0 } ?: {}, ) } + MultilineLambdaItParameter:HotAccessCodeRequestModel.kt$HotAccessCodeRequestModel${ it.copy( wrongAccessCodeText = resourceReference( R.string.access_code_check_warining_lock, wrappedList(MAX_FAST_FORWARD_ATTEMPTS - attempts.count), ), onAccessCodeChange = ::onAccessCodeChange, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( importWalletEnabled = false, wordsErrorText = null, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( invalidWords = emptyList<String>().toImmutableList(), wordsErrorText = null, importWalletEnabled = true, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( invalidWords = invalidWords.toImmutableList(), wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_wrong_words), importWalletEnabled = false, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_invalid_checksum), importWalletEnabled = false, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ launchInterceptWords(wordsField = it) suggestNextWord(it) updateUiState { state -> state.copy(words = it) } } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ passphrase = it.text updateUiState { state -> state.copy(passPhrase = it) } } + MultilineLambdaItParameter:InvalidWordsColorTransformation.kt$InvalidWordsColorTransformation${ if (it == WORD_SEPARATOR) { append(WHITE_SPACE) } else if (wordsToBrush.contains(it)) { append(it.annotate()) } else { append(it) } } + MultilineLambdaItParameter:ManualBackupCheckModel.kt$ManualBackupCheckModel${ Timber.e(it) uiState.update { it.copy(completeButtonProgress = false) } } + MultilineLambdaItParameter:ManualBackupCheckModel.kt$ManualBackupCheckModel${ it.copy( words = seedPhrasePrivateInfo.mnemonic.mnemonicComponents.filterIndexed { index, _ -> WORD_FIELD_INDICES.contains(index + 1) }.toImmutableList(), ) } + MultilineLambdaItParameter:ManualBackupPhraseContent.kt${ EnumeratedTwoColumnGridItem( index = it + 1, mnemonic = "word${it + 1}", ) } + MultilineLambdaItParameter:ManualBackupPhraseModel.kt$ManualBackupPhraseModel${ it.copy( words = seedPhrasePrivateInfo.mnemonic.mnemonicComponents.mapIndexed { index, s -> EnumeratedTwoColumnGridItem(index + 1, s) }.toImmutableList(), ) } + MultilineLambdaItParameter:UpgradeWalletModel.kt$UpgradeWalletModel${ // Check if user attempted to upgrade before but something went wrong and a full reset is required val userWallet = coldUserWalletBuilderFactory.create(it).build() val sameWalletButNotFinishedBackup by lazy { userWallet?.walletId == params.userWalletId && BackupValidator.isValidFull(it.card).not() } val otherWalletAndAlreadyCreated by lazy { userWallet?.walletId != params.userWalletId && it.card.wallets.map { it.curve }.toSet().isNotEmpty() } if (userWallet != null && (sameWalletButNotFinishedBackup || otherWalletAndAlreadyCreated)) { startResetCardsFlow.emit(userWallet) return@doOnSuccess } delay(DELAY_SDK_DIALOG_CLOSE) tangemSdkManager.changeDisplayedCardIdNumbersCount(it) navigateToUpgradeFlow(it) } + MultilineLambdaItParameter:ViewPhraseContent.kt${ EnumeratedTwoColumnGridItem( index = it + 1, mnemonic = "word${it + 1}", ) } + MultilineLambdaItParameter:ViewPhraseModel.kt$ViewPhraseModel${ it.copy( words = words.mapIndexed { index, s -> EnumeratedTwoColumnGridItem(index + 1, s) }.toImmutableList(), ) } + NoNameShadowing:AccessCodeModel.kt$AccessCodeModel${ it.copy(buttonInProgress = false) } + NoNameShadowing:CreateMobileWalletModel.kt$CreateMobileWalletModel${ it.copy(createButtonLoading = false) } + NoNameShadowing:ManualBackupCheckModel.kt$ManualBackupCheckModel${ it.copy(completeButtonProgress = false) } + PropertyUsedBeforeDeclaration:AddExistingWalletImportModel.kt$AddExistingWalletImportModel$uiState + ReusedModifierInstance:AddExistingWalletImportContent.kt$OutlineTextFieldWithIcon( modifier = modifier .padding(horizontal = 16.dp) .fillMaxWidth(), value = state.passPhrase, onValueChange = state.passPhraseChange, iconResId = R.drawable.ic_information_24, iconColor = TangemTheme.colors.icon.informative, label = stringResourceSafe(id = R.string.common_passphrase), placeholder = stringResourceSafe(id = R.string.send_optional_field), onIconClick = state.onPassphraseInfoClick, keyboardOptions = KeyboardOptions( autoCorrectEnabled = false, keyboardType = KeyboardType.Password, ), ) + ReusedModifierInstance:HotAccessCodeRequestFullScreenContent.kt$AnimatedVisibility( modifier = modifier, visible = state.isShown, enter = fadeIn(), exit = fadeOut(), ) { Column( Modifier .fillMaxSize() .background(TangemTheme.colors.background.primary), horizontalAlignment = Alignment.CenterHorizontally, ) { TangemTopAppBar( modifier = Modifier.statusBarsPadding(), startButton = TopAppBarButtonUM.Back(state.onDismiss), ) SpacerH(68.dp) Column( Modifier .weight(1f) .fillMaxWidth() .padding(horizontal = 24.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( modifier = Modifier.animateEnterExit( enter = slideInVertically( tween(), initialOffsetY = { it + 200 }, ) + fadeIn(tween()), exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()), ), text = stringResourceSafe(R.string.access_code_check_title), style = TangemTheme.typography.h2, color = TangemTheme.colors.text.primary1, ) SpacerH24() PinTextField( modifier = Modifier.animateEnterExit( enter = slideInVertically( tween(), initialOffsetY = { it + 200 }, ) + fadeIn(tween()), exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()), ), length = 6, isPasswordVisual = true, value = state.accessCode, pinTextColor = state.accessCodeColor, onValueChange = state.onAccessCodeChange, ) SpacerH(20.dp) AnimatedVisibility( modifier = Modifier.animateEnterExit( enter = slideInVertically( tween(), initialOffsetY = { it + 200 }, ) + fadeIn(tween()), exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()), ), visible = state.wrongAccessCodeText != null, enter = fadeIn(), exit = fadeOut(), ) { val wrongAccessCodeText = state.wrongAccessCodeText ?: return@AnimatedVisibility Text( text = wrongAccessCodeText.resolveReference(), textAlign = TextAlign.Center, style = TangemTheme.typography.caption2.copy( lineBreak = LineBreak.Heading, ), color = TangemTheme.colors.text.warning, ) } } AnimatedVisibility( visible = state.useBiometricVisible, enter = fadeIn(), exit = fadeOut(), ) { SecondaryButton( modifier = Modifier .padding(16.dp) .fillMaxWidth() .navigationBarsPadding() .imePadding(), text = stringResourceSafe( id = R.string.welcome_unlock, stringResourceSafe(R.string.common_biometrics), ), onClick = state.useBiometricClick, ) } } } + ReusedModifierInstance:HotWalletStepper.kt$TangemTopAppBar( startButton = if (state.showBackButton) { TopAppBarButtonUM.Back(onBackClick) } else { null }, endButton = when { state.showSkipButton -> TopAppBarButtonUM.Text( text = resourceReference(R.string.common_skip), onClicked = onSkipClick, ) state.showFeedbackButton -> TopAppBarButtonUM.Icon( iconRes = R.drawable.ic_chat_24, onClicked = onFeedbackClick, ) else -> null }, title = state.title, containerColor = TangemTheme.colors.background.primary, modifier = modifier, titleAlignment = Alignment.CenterHorizontally, ) + SuspendFunSwallowedCancellation:AccessCodeModel.kt$AccessCodeModel$runCatching + SuspendFunSwallowedCancellation:AddExistingWalletImportModel.kt$AddExistingWalletImportModel$runCatching + SuspendFunSwallowedCancellation:CreateMobileWalletModel.kt$CreateMobileWalletModel$runCatching + SuspendFunSwallowedCancellation:ManualBackupCheckModel.kt$ManualBackupCheckModel$runCatching + SuspendFunSwallowedCancellation:ManualBackupPhraseModel.kt$ManualBackupPhraseModel$runCatching + + diff --git a/features/kyc/impl/detekt-baseline-debug.xml b/features/kyc/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..65df7413d9 --- /dev/null +++ b/features/kyc/impl/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + UnnecessaryLet:DefaultKycComponent.kt$DefaultKycComponent$let { launchSdk(startInfo) } + + diff --git a/features/manage-tokens/api/detekt-baseline-debug.xml b/features/manage-tokens/api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..a71e6537bf --- /dev/null +++ b/features/manage-tokens/api/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + PropertyUsedBeforeDeclaration:ManageTokensSource.kt$AddCustomTokenMode$userWalletId + + diff --git a/features/manage-tokens/impl/detekt-baseline-debug.xml b/features/manage-tokens/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d580e5706e --- /dev/null +++ b/features/manage-tokens/impl/detekt-baseline-debug.xml @@ -0,0 +1,51 @@ + + + + + BooleanPropertyNaming:AddCustomTokenUM.kt$AddCustomTokenUM$val showBackButton: Boolean + BooleanPropertyNaming:CustomCurrencyValidator.kt$CustomCurrencyValidator.Status.Validated$val fillForm: Boolean + BooleanPropertyNaming:CustomTokenFormModel.kt$CustomTokenFormModel$val needColdWalletInteraction = coldWalletAndHasMissedDerivationsUseCase.invoke( userWalletId = params.mode.userWalletId, networksWithDerivationPath = mapOf(currency.network.backendId to getDerivationPath().value), ) + BooleanPropertyNaming:ManageTokensListManager.kt$ManageTokensListManager$val loadUserTokensFromRemote = when (mode) { is ManageTokensMode.Wallet, is ManageTokensMode.Account, -> source == ManageTokensSource.ONBOARDING ManageTokensMode.None, -> false } + BooleanPropertyNaming:ManageTokensModel.kt$ManageTokensModel$val needToInteractWithColdWallet = useCasesFacade.needColdWalletInteraction(networks) + BooleanPropertyNaming:ManageTokensUM.kt$ManageTokensUM.ManageContent$val needToInteractWithColdWallet: Boolean + BooleanPropertyNaming:OnboardingManageTokensModel.kt$OnboardingManageTokensModel$val showTangemIcon = useCasesFacade.needColdWalletInteraction(network = network) + BooleanPropertyNaming:OnboardingManageTokensUM.kt$OnboardingManageTokensUM.ActionButtonConfig$abstract val showProgress: Boolean + BooleanPropertyNaming:OnboardingManageTokensUM.kt$OnboardingManageTokensUM.ActionButtonConfig.Continue$val showTangemIcon: Boolean + MaxChainedCallsOnSameLine:ChooseManagedTokensModel.kt$ChooseManagedTokensModel$params.initialCurrency.network.id.rawId.value + MultilineLambdaItParameter:ChooseManagedTokenContent.kt${ add( CurrencyItemUM.Basic( id = ManagedCryptoCurrency.ID( value = "ID+$it", ), name = "Bitcoin", symbol = "BTC", icon = CurrencyIconState.Loading, networks = CurrencyItemUM.Basic.NetworksUM.Collapsed, onExpandClick = {}, ), ) } + MultilineLambdaItParameter:ChooseManagedTokensModel.kt$ChooseManagedTokensModel${ it.copy( notificationUM = null, ) } + MultilineLambdaItParameter:CurrencyItemMapper.kt${ it.toCurrencyNetworkModel( isSelected = it.network in addedIn, isEditable = false, onSelectedStateChange = { _, _ -> }, onLongTap = { _ -> }, ) } + MultilineLambdaItParameter:CurrencyNetworksMapper.kt${ it.toCurrencyNetworkModel( isSelected = it.network in addedIn, isEditable = isItemsEditable, onSelectedStateChange = onSelectedStateChange, onLongTap = onLongTap, ) } + MultilineLambdaItParameter:CustomCurrencyFormOperations.kt${ it[Field.CONTRACT_ADDRESS] = it.getValue(Field.CONTRACT_ADDRESS).copy( error = when (exception) { CustomTokenFormValidationException.ContractAddress.Invalid -> { resourceReference(R.string.custom_token_creation_error_invalid_contract_address) } }, ) } + MultilineLambdaItParameter:CustomCurrencyFormOperations.kt${ it[Field.DECIMALS] = it.getValue(Field.DECIMALS).copy( error = when (exception) { is CustomTokenFormValidationException.Decimals.Empty -> { null // Should not display this error } is CustomTokenFormValidationException.Decimals.Invalid -> { resourceReference( R.string.custom_token_creation_error_wrong_decimals, wrappedList(ValidateTokenFormUseCase.MAX_DECIMALS), ) } }, ) } + MultilineLambdaItParameter:CustomTokenFormContent.kt$PreviewCustomTokenFormComponentProvider${ it[Field.CONTRACT_ADDRESS] = it[Field.CONTRACT_ADDRESS]!!.copy( label = stringReference("Contract address"), value = "0x1234567890", error = stringReference("Contract address is invalid"), placeholder = stringReference("0x1234567890"), ) } + MultilineLambdaItParameter:CustomTokenFormContent.kt$PreviewCustomTokenFormComponentProvider${ it[Field.CONTRACT_ADDRESS] = it[Field.CONTRACT_ADDRESS]!!.copy( label = stringReference("Contract address"), value = "0x1234567890", placeholder = stringReference("0x1234567890"), ) } + MultilineLambdaItParameter:CustomTokenFormModel.kt$CustomTokenFormModel${ Timber.e(it, "Failed to add currency") showErrorDialog() return@resource } + MultilineLambdaItParameter:CustomTokenFormModel.kt$CustomTokenFormModel${ Timber.e(it, "Failed to derive public keys") showErrorDialog() return@resource } + MultilineLambdaItParameter:CustomTokenSelectorModel.kt$CustomTokenSelectorModel${ when (it) { is AccountStatus.CryptoPortfolio -> it.sameNodeAndNotMain() } } + MultilineLambdaItParameter:ManageTokensListManager.kt$ManageTokensListManager${ Timber.e( it, """ Failed to check currency unsupported state |- Mode: $mode |- Source Network: $sourceNetwork """.trimIndent(), ) val message = SnackbarMessage( message = it.localizedMessage ?.let(::stringReference) ?: resourceReference(R.string.common_error), ) messageSender.send(message) null } + MultilineLambdaItParameter:ManageTokensListManager.kt$ManageTokensListManager${ Timber.e( it, """ Failed to check linked tokens |- Mode: $mode |- Network ID: ${network.id} """.trimIndent(), ) val message = SnackbarMessage( message = it.localizedMessage ?.let(::stringReference) ?: resourceReference(R.string.common_error), ) messageSender.send(message) false } + MultilineLambdaItParameter:ManageTokensModel.kt$ManageTokensModel${ Timber.e(it, "Failed to save changes") return@resource } + MultilineLambdaItParameter:ManageTokensUseCasesFacade.kt$ManageTokensUseCasesFacade${ it is CryptoCurrency.Token && it.network.backendId == network.backendId && it.network.derivationPath == network.derivationPath } + MultilineLambdaItParameter:OnboardingManageTokensModel.kt$OnboardingManageTokensModel${ Timber.e(it, "Failed to save changes") return@resource } + MultilineLambdaItParameter:PreviewManageTokensComponent.kt$PreviewManageTokensComponent${ it.fastForEachIndexed { index, network -> if (index == networkIndex) { it[index] = network.copy( iconResId = if (isSelected) { R.drawable.img_eth_22 } else { R.drawable.ic_eth_16 }, isSelected = isSelected, ) } } } + NamedArguments:ChangedCurrenciesManager.kt$ChangedCurrenciesManager$updateChangedItems(currency, network, currenciesToAdd, currenciesToRemove) + NamedArguments:ChangedCurrenciesManager.kt$ChangedCurrenciesManager$updateChangedItems(currency, network, currenciesToRemove, currenciesToAdd) + NamedArguments:ChooseManagedTokensModel.kt$ChooseManagedTokensModel$TokenSearched( params.analyticsCategoryName, token = null, blockchain = null, isTokenChosen = false, ) + NamedArguments:ManageTokensListManager.kt$ManageTokensListManager$selectNetwork(currencyBatch.key, currency, networkId, isSelected) + NamedArguments:ManageTokensListManager.kt$ManageTokensListManager$sendSelectCurrencyAction(batchKey, currency.id, network, isSelected = false) + NamedArguments:ManageTokensListManager.kt$ManageTokensListManager$sendSelectCurrencyAction(batchKey, currency.id, network, isSelected = true) + NestedScopeFunctions:CustomTokenSelectorModel.kt$CustomTokenSelectorModel$let { recognizer.recognize(it) } + NullableBooleanCheck:CustomCurrencyFormOperations.kt$this.tokenForm?.wasFilled ?: false + PropertyUsedBeforeDeclaration:ChooseManagedTokensModel.kt$ChooseManagedTokensModel$bottomSheetNavigation + PropertyUsedBeforeDeclaration:ChooseManagedTokensModel.kt$ChooseManagedTokensModel$uiState + UnsafeCallOnNullableType:CustomTokenFormContent.kt$PreviewCustomTokenFormComponentProvider$it[Field.CONTRACT_ADDRESS]!! + UnsafeCallOnNullableType:PreviewAddCustomTokenComponent.kt$PreviewAddCustomTokenComponent$config.selectedDerivationPath!! + UnsafeCallOnNullableType:PreviewAddCustomTokenComponent.kt$PreviewAddCustomTokenComponent$config.selectedNetwork!! + UseEmptyCounterpart:CustomTokenAnalyticsEvent.kt$CustomTokenAnalyticsEvent$mapOf() + UseEmptyCounterpart:ManageTokensAnalyticEvent.kt$ManageTokensAnalyticEvent$mapOf() + UseOrEmpty:ChangedCurrenciesManager.kt$ChangedCurrenciesManager$items[currency] ?: emptySet() + UseOrEmpty:PreviewCustomTokenSelectorComponent.kt$PreviewCustomTokenSelectorComponent$d.id?.rawId?.value ?: "" + VarCouldBeVal:CustomTokenFormModel.kt$CustomTokenFormModel$private var useCasesFacade: CustomTokenFormUseCasesFacade = customTokenFormUseCasesFacadeFactory.create(params.mode) + + diff --git a/features/markets/impl/detekt-baseline-debug.xml b/features/markets/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..58ef1132a3 --- /dev/null +++ b/features/markets/impl/detekt-baseline-debug.xml @@ -0,0 +1,161 @@ + + + + + BooleanPropertyNaming:AddToPortfolioBSContentUM.kt$AddToPortfolioBSContentUM$val continueButtonEnabled: Boolean + BooleanPropertyNaming:AvailableToAddData.kt$AvailableToAddData$val availableToAdd: Boolean get() = availableToAddWallets.isNotEmpty() + BooleanPropertyNaming:AvailableToAddData.kt$SelectedNetwork$val availableMoreNetwork: Boolean + BooleanPropertyNaming:AvailableToAddData.kt$SelectedPortfolio$val availableMorePortfolio: Boolean + BooleanPropertyNaming:DefaultAddToPortfolioComponent.kt$DefaultAddToPortfolioComponent$val scrollableContent = when (stack.active.configuration) { AddToPortfolioRoutes.PortfolioSelector -> false AddToPortfolioRoutes.AddToken, AddToPortfolioRoutes.Empty, is AddToPortfolioRoutes.NetworkSelector, AddToPortfolioRoutes.TokenActions, -> true } + BooleanPropertyNaming:MarketsList.kt$val mainScrolled by remember { derivedStateOf { mainLazyListState.firstVisibleItemScrollOffset > 0 } } + BooleanPropertyNaming:MarketsList.kt$val searchScrolledState by remember { derivedStateOf { searchLazyListState.firstVisibleItemScrollOffset > 0 } } + BooleanPropertyNaming:MarketsListAnalyticsEvent.kt$MarketsListAnalyticsEvent.TokenSearched$val tokenFound: Boolean + BooleanPropertyNaming:MarketsListUM.kt$ListUM.Content$val showUnder100kTokensNotification: Boolean + BooleanPropertyNaming:MarketsListUM.kt$ListUM.Content$val showUnder100kTokensNotificationWasHidden: Boolean + BooleanPropertyNaming:MarketsListUMStateManager.kt$MarketsListUMStateManager$private var sortByBottomSheetIsShown get() = state.value.sortByBottomSheet.isShown set(value) = state.update { it.copy(sortByBottomSheet = it.sortByBottomSheet.copy(isShown = value)) } + BooleanPropertyNaming:MarketsTokenDetailsContent.kt$val showPriceSubtitle by remember { derivedStateOf { lazyListState.firstVisibleItemIndex > 1 } } + BooleanPropertyNaming:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel$val allWalletsIsHot = getUserWalletsUseCase.invokeSync().all { it is UserWallet.Hot } + BooleanPropertyNaming:MarketsTokenDetailsUM.kt$MarketsTokenDetailsUM$val markerSet: Boolean + BooleanPropertyNaming:MetricsBlock.kt$var expanded by remember { mutableStateOf(false) } + BooleanPropertyNaming:PortfolioBSVisibilityModel.kt$PortfolioBSVisibilityModel$val addToPortfolioBSVisibility: Boolean = false + BooleanPropertyNaming:PortfolioBSVisibilityModel.kt$PortfolioBSVisibilityModel$val walletSelectorBSVisibility: Boolean = false + BooleanPropertyNaming:PortfolioItem.kt$var quickActionsShown by remember { mutableStateOf(value = false) } + BooleanPropertyNaming:PortfolioUIData.kt$PortfolioUIData$val needColdWalletInteraction: Boolean + BooleanPropertyNaming:QuickActionUM.kt$QuickActionUM$val longClickAvailable: Boolean = false + BooleanPropertyNaming:QuickActionUM.kt$QuickActionUM.Exchange$val showBadge: Boolean + BooleanPropertyNaming:TokenActionsHandler.kt$TokenActionsHandler$val demoCard = isDemoCardUseCase.invoke(userWallet.cardId) + BooleanPropertyNaming:TokenActionsHandler.kt$TokenActionsHandler$val needShowDemoWarning = demoCard && disabledActionsInDemoMode.contains(action) + CanBeNonNullable:TokenMarketDetailsBody.kt$portfolioBlock: @Composable ((Modifier) -> Unit)? + CastNullableToNonNullableType:PortfolioItem.kt$PortfolioTokenUMProvider$as + CastNullableToNonNullableType:PortfolioItem.kt$PortfolioTokenUMProvider.Companion$as + MaxChainedCallsOnSameLine:AddToPortfolioModel.kt$AddToPortfolioModel$selectedPortfolio.first().account.account.account.accountId + MaxChainedCallsOnSameLine:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager$batchFlow.state.value.data.map { it.data }.flatten().find { it.id == id } + MaxChainedCallsOnSameLine:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager$batchFlow.state.value.data.map { it.key }.toSet() + MaxChainedCallsOnSameLine:MarketsListModel.kt$MarketsListModel$marketsListUMStateManager.state.map { it.selectedSortBy }.distinctUntilChanged().drop(1).collectLatest { mainMarketsListManager.reload() } + MaxChainedCallsOnSameLine:MarketsPortfolioModel.kt$MarketsPortfolioModel$handledAction.cryptoCurrencyData.status.currency.network.name + MaxChainedCallsOnSameLine:TokenActionsModel.kt$TokenActionsModel$handledAction.cryptoCurrencyData.status.currency.network.name + MultilineLambdaItParameter:AddToPortfolioBSContentUMFactory.kt$AddToPortfolioBSContentUMFactory${ if (it != selectedWalletId) { onAnotherWalletSelect(it) onWalletSelectorVisibilityChange(false) } } + MultilineLambdaItParameter:AddToPortfolioBottomSheet.kt${ Content( modifier = Modifier.fillMaxWidth(), state = it, ) WalletSelectorBottomSheet(it.walletSelectorConfig) } + MultilineLambdaItParameter:AddToPortfolioManager.kt$AddToPortfolioManager${ it.toMutableMap().apply { this[userWalletId] = if (isAddAction) { this[userWalletId].orEmpty() + network } else { this[userWalletId].orEmpty() - network } } } + MultilineLambdaItParameter:AddToPortfolioModel.kt$AddToPortfolioModel${ PortfolioData.CryptoCurrencyData( userWallet = selectedPortfolio.userWallet, status = addedToken, actions = it.states, ) } + MultilineLambdaItParameter:AddToPortfolioModel.kt$AddToPortfolioModel${ Timber.e(it) params.callback.onDismiss() } + MultilineLambdaItParameter:AddToPortfolioModel.kt$AddToPortfolioModel${ tokenActionsData.emit(it) navigation.replaceAll(AddToPortfolioRoutes.TokenActions) } + MultilineLambdaItParameter:AddTokenModel.kt$AddTokenModel${ processError(error = it) uiState.value = um.toggleProgress(false) return@launch } + MultilineLambdaItParameter:AvailableToAddDataConverter.kt$AvailableToAddDataConverter${ val (walletId, _) = it val availableToAddWallet = getAvailableToAddWallet(it) walletId to availableToAddWallet } + MultilineLambdaItParameter:ChooseNetworkModel.kt$ChooseNetworkModel${ Timber.e( it, """ Failed to check currency unsupported state |- User wallet ID: $userWalletId |- Network ID: $rawNetworkId |- Is main network: $isMainNetwork """.trimIndent(), ) val message = SnackbarMessage( message = it.localizedMessage?.let(::stringReference) ?: resourceReference(R.string.common_error), ) messageSender.send(message) null } + MultilineLambdaItParameter:DefaultMarketsTokenDetailsComponent.kt$DefaultMarketsTokenDetailsComponent${ when (it) { is TokenNetworksState.NetworksAvailable -> portfolioComponent?.setTokenNetworks(it.networks) TokenNetworksState.NoNetworksAvailable -> portfolioComponent?.setNoNetworksAvailable() else -> {} } } + MultilineLambdaItParameter:DefaultMarketsTokenListComponent.kt$DefaultMarketsTokenListComponent${ MarketsListWithBack( modifier = Modifier .statusBarsPadding() .imePadding() .padding(it), state = state, bottomSheetState = BottomSheetState.EXPANDED, onBackClick = router::pop, ) } + MultilineLambdaItParameter:EntryBottomSheetContent.kt${ when (it.configuration) { is MarketsEntryChildFactory.Child.TokenDetails -> { (it.instance as MarketsTokenDetailsComponent).BottomSheetContent( bottomSheetState = bottomSheetState, onHeaderSizeChange = onHeaderSizeChange, modifier = modifier, ) } is MarketsEntryChildFactory.Child.TokenList -> { (it.instance as MarketsTokenListComponent).BottomSheetContent( bottomSheetState = bottomSheetState, onHeaderSizeChange = onHeaderSizeChange, modifier = modifier, ) } } } + MultilineLambdaItParameter:InsightsBlock.kt${ InfoPoint( modifier = Modifier.align(Alignment.CenterStart), infoPointUM = it, ) } + MultilineLambdaItParameter:InsightsBlock.kt${ currentInterval = it state.onIntervalChanged(it) } + MultilineLambdaItParameter:LinksBlock.kt${ Chip( text = stringReference(it.title), iconResId = it.iconRes, onClick = { onLinkClick(it) }, ) } + MultilineLambdaItParameter:MarketTokenDetailsChart.kt${ when (it) { MarketChartLook.Type.Growing -> growingColor MarketChartLook.Type.Falling -> fallingColor MarketChartLook.Type.Neutral -> neutralColor } } + MultilineLambdaItParameter:MarketsList.kt${ if (it.size.height > 0) { with(density) { onHeaderSizeChange(it.size.height.toDp()) } } } + MultilineLambdaItParameter:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager${ Batch( key = it.key, data = converter.convertList(it.data), ) } + MultilineLambdaItParameter:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager${ currentSearchText().isNullOrEmpty().not() && it.status is PaginationStatus.EndOfPagination && it.data.isEmpty() } + MultilineLambdaItParameter:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager${ val first = it.data.firstOrNull() ?: return@filter false val chartByInterval = when (interval) { TrendInterval.H24 -> first.tokenCharts.h24 TrendInterval.D7 -> first.tokenCharts.week TrendInterval.M1 -> first.tokenCharts.month } chartByInterval != null } + MultilineLambdaItParameter:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager${ when (val status = it.status) { is PaginationStatus.Paginating -> { if (status.lastResult is BatchFetchResult.Success) { it.data.lastOrNull()?.key } else { null } } is PaginationStatus.EndOfPagination -> { it.data.lastOrNull()?.key } else -> null } } + MultilineLambdaItParameter:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager${ when (val status = it.status) { is PaginationStatus.Paginating -> { if (status.lastResult is BatchFetchResult.Success) { it.data.size == 1 } else { null } } is PaginationStatus.EndOfPagination -> { it.data.size == 1 } else -> null } } + MultilineLambdaItParameter:MarketsListItem.kt${ if (Random.nextBoolean()) { it.first.inc() to PriceChangeType.UP } else { it.first.dec() to PriceChangeType.DOWN } } + MultilineLambdaItParameter:MarketsListLazyColumn.kt${ (it.key as? String)?.split(TOKEN_LAZY_LIST_ID_SEPARATOR)?.first() ?.let { rawId -> CryptoCurrency.RawID(rawId) } } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ if (it == BottomSheetState.EXPANDED) { analyticsEventHandler.send(MarketsListAnalyticsEvent.BottomSheetOpened) } } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ if (it) { analyticsEventHandler.send(MarketsListAnalyticsEvent.TokenSearched(tokenFound = false)) } } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ if (it.isNotEmpty()) { activeListManager.getBatchKeysByItemIds(visibleItemIds.value) } else { null } } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ if (it.list !is ListUM.Content) { visibleItemIds.value = emptyList() } } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ mainMarketsListManager.loadCharts(setOf(it), marketsListUMStateManager.selectedInterval) modelScope.loadQuotesWithTimer(timeMillis = UPDATE_QUOTES_TIMER_MILLIS) } + MultilineLambdaItParameter:MarketsListModel.kt$MarketsListModel${ searchMarketsListManager.loadCharts(setOf(it), marketsListUMStateManager.selectedInterval) modelScope.loadQuotesWithTimer(timeMillis = UPDATE_QUOTES_TIMER_MILLIS) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( list = if (it.list is ListUM.Content) { it.list.copy( triggerScrollReset = consumedEvent(), ) } else { it.list }, ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( price = it.price.copy( changeType = if (visibleItemIds.contains(it.id)) { it.price.changeType } else { null }, ), ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( searchBar = it.searchBar.copy( query = value, isActive = value.isNotEmpty(), ), ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( selectedInterval = value, list = if (it.list is ListUM.Content && it.selectedSortBy != SortByTypeUM.Rating && it.selectedInterval != value ) { it.list.copy(triggerScrollReset = triggeredEvent(Unit) { consumeTriggerResetScrollEvent() }) } else { it.list }, ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( selectedSortBy = sortByTypeUM, sortByBottomSheet = it.sortByBottomSheet.copy( isShown = false, content = (it.sortByBottomSheet.content as SortByBottomSheetContentUM).copy( selectedOption = sortByTypeUM, ), ), ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ it.copy( selectedSortBy = value, sortByBottomSheet = it.sortByBottomSheet.copy( content = (it.sortByBottomSheet.content as SortByBottomSheetContentUM).copy( selectedOption = value, ), ), list = if (it.list is ListUM.Content && it.selectedSortBy != value) { it.list.copy(triggerScrollReset = triggeredEvent(Unit) { consumeTriggerResetScrollEvent() }) } else { it.list }, ) } + MultilineLambdaItParameter:MarketsListUMStateManager.kt$MarketsListUMStateManager${ when { isInErrorState -> { it.copy( list = ListUM.LoadingError(onRetryClicked = onRetryButtonClicked), ) } isSearchNotFound -> { it.copy(list = ListUM.SearchNothingFound) } uiItems.isEmpty() -> { it.copy(list = ListUM.Loading) } else -> { it.updateItems( newItems = uiItems, stakingNotificationMaxApy = stakingNotificationMaxApy, ) } } } + MultilineLambdaItParameter:MarketsPortfolioModel.kt$MarketsPortfolioModel${ Timber.e( it, """ Failed to check currency unsupported state |- User wallet ID: $userWalletId |- Network ID: $rawNetworkId |- Is main network: $isMainNetwork """.trimIndent(), ) val message = SnackbarMessage( message = it.localizedMessage ?.let(::stringReference) ?: resourceReference(R.string.common_error), ) messageSender.send(message) null } + MultilineLambdaItParameter:MarketsPortfolioModel.kt$MarketsPortfolioModel${ onWalletSelect(it) // === Analytics === analyticsEventHandler.send( analyticsEventBuilder.addToPortfolioWalletChanged(), ) } + MultilineLambdaItParameter:MarketsPortfolioModel.kt$MarketsPortfolioModel${ when (it) { is NewAddToPortfolioManager.State.AvailableToAdd -> AddButtonState.Available NewAddToPortfolioManager.State.Init -> AddButtonState.Loading NewAddToPortfolioManager.State.NothingToAdd -> AddButtonState.Unavailable } } + MultilineLambdaItParameter:MarketsTokenDetailsContent.kt${ if (it.size.height > 0) { with(density) { onHeaderSizeChange(it.size.height.toDp()) } } } + MultilineLambdaItParameter:MarketsTokenDetailsContent.kt${ val nextColor = when (it) { PriceChangeType.UP, -> growColor PriceChangeType.DOWN -> fallColor PriceChangeType.NEUTRAL -> return@EventEffect } color.animateTo(nextColor, snap()) color.animateTo(generalColor, tween(durationMillis = 500)) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ BlockchainUtils.isSupportedNetworkId( blockchainId = it.networkId, excludedBlockchains = excludedBlockchains, hotExcludedBlockchains = hotWalletExcludedBlockchains, hasOnlyHotWallets = allWalletsIsHot, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ ExchangesBottomSheetContent.Content( exchangeItems = ExchangeItemStateConverter.convertList(it).toImmutableList(), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ MarketsDateTimeFormatters.formatDateByIntervalWithMarker( interval = currentState.selectedInterval, markerTimestamp = it, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ analyticsEventHandler.send( analyticsEventBuilder.intervalChanged( intervalType = MarketDetailsAnalyticsEvent.IntervalType.Insights, interval = it, ), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ analyticsEventHandler.send( analyticsEventBuilder.intervalChanged( intervalType = MarketDetailsAnalyticsEvent.IntervalType.PricePerformance, interval = it, ), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ getChangePercentBetween( previousPrice = it, currentPrice = currentQuotes.value.currentPrice, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ if (it.chartState.status == MarketsTokenDetailsUM.ChartState.Status.DATA) { it.copy( body = MarketsTokenDetailsUM.Body.Error( onLoadRetryClick = ::onLoadRetryClicked, ), ) } else { it.copy( body = MarketsTokenDetailsUM.Body.Nothing, ) } } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( body = MarketsTokenDetailsUM.Body.Loading, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( chartState = it.chartState.copy( status = MarketsTokenDetailsUM.ChartState.Status.DATA, ), body = if (it.body is MarketsTokenDetailsUM.Body.Nothing) { MarketsTokenDetailsUM.Body.Error(onLoadRetryClick = ::onLoadRetryClicked) } else { it.body }, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( chartState = it.chartState.copy( status = MarketsTokenDetailsUM.ChartState.Status.ERROR, ), body = if (it.body is MarketsTokenDetailsUM.Body.Error) { MarketsTokenDetailsUM.Body.Nothing } else { it.body }, ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( chartState = it.chartState.copy( status = MarketsTokenDetailsUM.ChartState.Status.LOADING, ), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( priceChangePercentText = priceChangePercent, selectedInterval = interval, priceChangeType = quotes.getPercentByInterval(interval)?.percentChangeType() ?: PriceChangeType.NEUTRAL, dateTimeText = getDefaultDateTimeString(interval), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( priceText = newInfo.quotes.currentPrice.format { fiat( fiatCurrencySymbol = currentAppCurrency.value.symbol, fiatCurrencyCode = currentAppCurrency.value.code, ).price() }, priceChangePercentText = newInfo.quotes.getFormattedPercentByInterval( interval = it.selectedInterval, ), priceChangeType = percent.percentChangeType(), body = MarketsTokenDetailsUM.Body.Content( description = descriptionConverter.convert(newInfo), infoBlocks = infoConverter.convert(newInfo), ), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( selectedInterval = interval, chartState = it.chartState.copy( status = MarketsTokenDetailsUM.ChartState.Status.LOADING, ), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( type = percent.percentChangeType().toChartType(), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( xAxisFormatter = xAxisFormatter, type = state.value.priceChangeType.toChartType(), ) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.urlData?.fullUrl?.let { url -> urlOpener.openUrl(url) } // === Analytics === analyticsEventHandler.send(analyticsEventBuilder.securityScoreProviderClicked(it.name)) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ showBottomSheet(it) // === Analytics === analyticsEventHandler.send(analyticsEventBuilder.readMoreClicked()) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ showBottomSheet(it) // === Analytics === analyticsEventHandler.send(analyticsEventBuilder.securityScoreOpened()) } + MultilineLambdaItParameter:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ val percentChangeType = params.token.tokenQuotes.h24Percent.percentChangeType() it.copy( type = percentChangeType.toChartType(), xAxisFormatter = MarketsDateTimeFormatters.getChartXFormatterByInterval(PriceChangeInterval.H24), yAxisFormatter = { value -> value.format { fiat( fiatCurrencyCode = currentAppCurrency.value.code, fiatCurrencySymbol = currentAppCurrency.value.symbol, ).price() } }, ) } + MultilineLambdaItParameter:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate${ PortfoliosWithThisCurrency( currencyRawId = currencyRawId, portfolios = it.toList(), ) } + MultilineLambdaItParameter:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate${ when (it) { AddButtonState.Loading -> MyPortfolioUM.Loading AddButtonState.Available -> MyPortfolioUM.AddFirstToken( onAddClick = onAddClick, addToPortfolioBSConfig = TangemBottomSheetConfig.Empty, ) AddButtonState.Unavailable -> MyPortfolioUM.Unavailable } } + MultilineLambdaItParameter:PortfolioDataLoader.kt$PortfolioDataLoader${ PortfolioData.CryptoCurrencyData( userWallet = wallet, status = it, actions = emptyList(), ) } + MultilineLambdaItParameter:PortfolioDataLoader.kt$PortfolioDataLoader${ PortfolioData.CryptoCurrencyData( userWallet = wallet, status = status, actions = it.states, ) } + MultilineLambdaItParameter:PortfolioItem.kt${ val onClick = state.tokenItemState.onItemClick if (onClick != null) { hapticManager.perform(TangemHapticEffect.View.ContextClick) onClick.invoke(it) } } + MultilineLambdaItParameter:PortfolioTokenUMConverter.kt$PortfolioTokenUMConverter.Companion${ if (it == QuickActionUM.Receive) { tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.CopyAddress, cryptoCurrencyData = cryptoData, ) } } + MultilineLambdaItParameter:PortfolioTokenUMConverter.kt$PortfolioTokenUMConverter.Companion${ when (it) { QuickActionUM.Buy -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Buy, cryptoCurrencyData = cryptoData, ) is QuickActionUM.Exchange -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Exchange, cryptoCurrencyData = cryptoData, ) QuickActionUM.Receive -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Receive, cryptoCurrencyData = cryptoData, ) QuickActionUM.Stake -> tokenActionsHandler.handle( action = TokenActionsBSContentUM.Action.Stake, cryptoCurrencyData = cryptoData, ) } } + MultilineLambdaItParameter:PricePerformanceBlock.kt${ currentInterval = it state.onIntervalChanged(it) } + MultilineLambdaItParameter:SecurityScoreConverter.kt$SecurityScoreConverter${ SecurityScoreBottomSheetContent.SecurityScoreProviderUM( name = it.providerName, lastAuditDate = it.lastAuditDate?.let { date -> MarketsDateTimeFormatters.formatAsDate(date.millis) }, score = it.securityScore, urlData = it.urlData?.let { urlData -> SecurityScoreBottomSheetContent.SecurityScoreProviderUM.UrlData( fullUrl = urlData.fullUrl, rootHost = urlData.rootHost, ) }, iconUrl = it.iconUrl, ) } + MultilineLambdaItParameter:TokenActionsContent.kt${ key(it.title) { ActionRow( state = it, onClick = { state.quickActions.onQuickActionClick(it) }, onLongClick = { state.quickActions.onQuickActionLongClick(it) }, ) } } + MultilineLambdaItParameter:TokenMarketBlockModel.kt$TokenMarketBlockModel${ it.onSome { res -> quotesState = QuotesState( currentPrice = res.fiatRate, h24Percent = res.priceChange, ) state.value = state.value.copy( currentPrice = res.fiatRate.format { fiat( // TODO get currency from quotes use case AND-8022 fiatCurrencyCode = currentAppCurrency.value.code, // TODO get currency from quotes use case AND-8022 fiatCurrencySymbol = currentAppCurrency.value.symbol, ).price() }, h24Percent = res.priceChange.format { percent() }, priceChangeType = PriceChangeType.fromBigDecimal(res.priceChange), ) } } + MultilineLambdaItParameter:TokenMarketInfoConverter.kt$TokenMarketInfoConverter${ pricePerformanceConverter.convert( value = it, currentPrice = value.quotes.currentPrice, ) } + MultilineLambdaItParameter:TokensPortfolioUMConverter.kt$TokensPortfolioUMConverter${ it.copy( isQuickActionsShown = if (it.matchWith(cryptoData)) { !it.isQuickActionsShown } else { false }, ) } + NamedArguments:AvailableToAddDataConverter.kt$AvailableToAddDataConverter$createCryptoCurrency(wallet, it, marketParams, this.account) + NamedArguments:MarketsListModel.kt$MarketsListModel$combine( mainMarketsListManager.uiItems, mainMarketsListManager.isInInitialLoadingErrorState, getStakingNotificationMaxApyUseCase(), getUserCountryUseCase.invoke(), ) { uiItems, isInInitialLoadingErrorState, stakingNotificationMaxApy, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = false, stakingNotificationMaxApy = stakingNotificationMaxApy, userCountry = userCountry, ) } + NamedArguments:MarketsListModel.kt$MarketsListModel$combine( searchMarketsListManager.uiItems, searchMarketsListManager.isInInitialLoadingErrorState, searchMarketsListManager.isSearchNotFoundState, getStakingNotificationMaxApyUseCase(), getUserCountryUseCase.invoke(), ) { uiItems, isInInitialLoadingErrorState, isSearchNotFoundState, stakingMaxApy, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = isSearchNotFoundState, stakingNotificationMaxApy = stakingMaxApy, userCountry = userCountry, ) } + NestedScopeFunctions:DescriptionConverter.kt$DescriptionConverter$let { fullDescription -> stringReference(fullDescription) } + NoNameShadowing:MarketsPortfolioModel.kt$MarketsPortfolioModel${ it.isMultiCurrency } + NoNameShadowing:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ if (it.chartState.status == MarketsTokenDetailsUM.ChartState.Status.DATA) { it.copy( body = MarketsTokenDetailsUM.Body.Error( onLoadRetryClick = ::onLoadRetryClicked, ), ) } else { it.copy( body = MarketsTokenDetailsUM.Body.Nothing, ) } } + NoNameShadowing:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel${ it.copy( chartState = it.chartState.copy( status = MarketsTokenDetailsUM.ChartState.Status.ERROR, ), body = if (it.body is MarketsTokenDetailsUM.Body.Error) { MarketsTokenDetailsUM.Body.Nothing } else { it.body }, ) } + NoNameShadowing:MyPortfolioUMFactory.kt$MyPortfolioUMFactory${ networkIds.contains(it.status.currency.network.backendId) } + NoNameShadowing:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate$portfolio + NonBooleanPropertyPrefixedWithIs:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager$val isInInitialLoadingErrorState = batchFlow.state .map { it.status is PaginationStatus.InitialLoadingError } .distinctUntilChanged() .stateIn( scope = modelScope, started = SharingStarted.Eagerly, initialValue = false, ) + NonBooleanPropertyPrefixedWithIs:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager$val isSearchNotFoundState = batchFlow.state .map { currentSearchText().isNullOrEmpty().not() && it.status is PaginationStatus.EndOfPagination && it.data.isEmpty() } .distinctUntilChanged() .stateIn( scope = modelScope, started = SharingStarted.Eagerly, initialValue = false, ) + NonBooleanPropertyPrefixedWithIs:MarketsListModel.kt$MarketsListModel$val isVisibleOnScreen = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:MarketsListUMStateManager.kt$MarketsListUMStateManager$val isInSearchStateFlow = state.map { it.searchBar.isActive }.distinctUntilChanged() + NonBooleanPropertyPrefixedWithIs:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel$val isVisibleOnScreen = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:TokenActionsHandler.kt$TokenActionsHandler$private val isDemoCardUseCase: IsDemoCardUseCase + NullableToStringCall:MarketsListItemUM.kt$MarketsListItemUM$marketCap.toString() + PropertyUsedBeforeDeclaration:MarketsListModel.kt$MarketsListModel$activeListManager + PropertyUsedBeforeDeclaration:MarketsListUMStateManager.kt$MarketsListUMStateManager$state + PropertyUsedBeforeDeclaration:MarketsPortfolioModel.kt$MarketsPortfolioModel$_state + PropertyUsedBeforeDeclaration:MarketsPortfolioModel.kt$MarketsPortfolioModel$currentAppCurrency + PropertyUsedBeforeDeclaration:PreviewMyPortfolioUMProvider.kt$PreviewMyPortfolioUMProvider$accountHeader + PropertyUsedBeforeDeclaration:PreviewMyPortfolioUMProvider.kt$PreviewMyPortfolioUMProvider$accountToken + PropertyUsedBeforeDeclaration:PreviewMyPortfolioUMProvider.kt$PreviewMyPortfolioUMProvider$sampleToken + PropertyUsedBeforeDeclaration:PreviewMyPortfolioUMProvider.kt$PreviewMyPortfolioUMProvider$walletHeader + PropertyUsedBeforeDeclaration:PreviewMyPortfolioUMProvider.kt$PreviewMyPortfolioUMProvider$walletPortfolioHeader + ReusedModifierInstance:EntryBottomSheetContent.kt$BottomSheetContent( bottomSheetState = bottomSheetState, onHeaderSizeChange = onHeaderSizeChange, modifier = modifier, ) + ReusedModifierInstance:PortfolioQuickActions.kt$Column(modifier = modifier) { actions.fastForEach { action -> LineSeparator() QuickActionItem( state = action, onClick = { onActionClick(action) }, onLongClick = { onActionLongClick(action) }.takeIf { action.longClickAvailable }, ) } } + ReusedModifierInstance:TokenActionsContent.kt$SecondaryButton( modifier = modifier.fillMaxWidth(), text = stringResourceSafe(R.string.common_later), onClick = state.onLaterClick, ) + SuspendFunWithFlowReturnType:AddToPortfolioModel.kt$AddToPortfolioModel$suspend + UnnecessaryEventHandlerParameter:SecurityScoreBottomSheet.kt$onLinkClick: (SecurityScoreBottomSheetContent.SecurityScoreProviderUM) -> Unit + UnnecessaryLet:PortfolioAnalyticsEvent.kt$PortfolioAnalyticsEvent.EventBuilder$let { put("Source", source) } + UnnecessaryLet:SecurityScoreBottomSheet.kt$let { Text( text = providerUM.lastAuditDate, style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, ) } + UnsafeCallOnNullableType:DefaultMarketsPortfolioComponent.kt$DefaultMarketsPortfolioComponent$model.newAddToPortfolioManager!! + UnsafeCallOnNullableType:MarketsListBatchFlowManager.kt$MarketsListBatchFlowManager$previousList!! + UnsafeCallOnNullableType:PricePerformanceConverter.kt$PricePerformanceConverter$high!! + UnsafeCallOnNullableType:PricePerformanceConverter.kt$PricePerformanceConverter$low!! + UseAnyOrNoneInsteadOfFind:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate$find { account -> account.addedCurrency.isNotEmpty() } + UseEmptyCounterpart:MarketDetailsAnalyticsEvent.kt$MarketDetailsAnalyticsEvent$mapOf() + UseEmptyCounterpart:MarketsListAnalyticsEvent.kt$MarketsListAnalyticsEvent$mapOf() + UseEmptyCounterpart:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate$setOf() + UseEmptyCounterpart:PortfolioAnalyticsEvent.kt$PortfolioAnalyticsEvent$mapOf() + UseOrEmpty:DescriptionConverter.kt$DescriptionConverter$value.fullDescription ?: "" + UseOrEmpty:Formatters.kt$percent?.format { percent() } ?: "" + UseOrEmpty:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel$percent?.format { percent() } ?: "" + UseOrEmpty:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate$allActions[currencyStatus.currency]?.states ?: emptyList() + UseOrEmpty:NewMarketsPortfolioDelegate.kt$NewMarketsPortfolioDelegate$portfolio.portfolios .find { it.accountsWithAdded.find { account -> account.addedCurrency.isNotEmpty() } != null } ?.userWallet ?.let { setOf(it.walletId to currency.currency.id) } ?: setOf() + VarCouldBeVal:MarketsListModel.kt$MarketsListModel$private var updateQuotesJob = JobHolder() + VarCouldBeVal:MarketsTokenDetailsModel.kt$MarketsTokenDetailsModel$private var quotesJob = JobHolder() + + diff --git a/features/nft/impl/detekt-baseline-debug.xml b/features/nft/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..27148479aa --- /dev/null +++ b/features/nft/impl/detekt-baseline-debug.xml @@ -0,0 +1,42 @@ + + + + + BooleanPropertyNaming:NFTAssetUM.kt$NFTAssetUM$val showAllTraitsButton: Boolean + BooleanPropertyNaming:NFTAssetUM.kt$NFTAssetUM.BlockItem$val showInfoButton: Boolean + BooleanPropertyNaming:NFTAssetUM.kt$NFTAssetUM.Rarity.Content$val showDivider: Boolean + BooleanPropertyNaming:NFTCollectionsModel.kt$NFTCollectionsModel$val assetsFulfillQuery = if (query.isEmpty()) { true } else { when (val assets = it.assets) { is NFTCollection.Assets.Empty, is NFTCollection.Assets.Failed, is NFTCollection.Assets.Loading, -> false is NFTCollection.Assets.Value -> { assets.items.any { asset -> asset.name?.lowercase()?.contains(query.lowercase()) == true } } } } + BooleanPropertyNaming:NFTCollectionsModel.kt$NFTCollectionsModel$val collectionFulfillQuery = query.isEmpty() || it.name?.lowercase()?.contains(query.lowercase()) == true + BooleanPropertyNaming:UpdateDataStateTransformer.kt$UpdateDataStateTransformer$val custom = derivationPath is Network.DerivationPath.Custom + CanBeNonNullable:NFTReceive.kt$bottomSheetConfig: TangemBottomSheetConfig? + MultilineLambdaItParameter:ChangeCollectionExpandedStateTransformer.kt$ChangeCollectionExpandedStateTransformer${ val collectionId = collection.collectionIdProvider() if (it.id == collectionId && it is NFTCollectionUM) { if (!it.isExpanded) { onFirstExpanded() } it.copy(isExpanded = !it.isExpanded) } else { it } } + MultilineLambdaItParameter:NFTCollectionsContent.kt${ key(it.id) { NFTCollectionWarning( modifier = Modifier .padding(top = TangemTheme.dimens.spacing16), state = it, ) } } + MultilineLambdaItParameter:NFTCollectionsModel.kt$NFTCollectionsModel${ ChangeCollectionExpandedStateTransformer( collection = collection, collectionIdProvider = collectionIdProvider, onFirstExpanded = { onFirstExpanded(collection) }, ).transform(it) } + MultilineLambdaItParameter:NFTCollectionsModel.kt$NFTCollectionsModel${ UpdateDataStateTransformer( nftCollections = listOf(), isAccountMode = isAccountMode, walletNFTCollections = nftCollections.copy(collections = filteredNFTs), onReceiveClick = { params.onReceiveClick() }, onRetryClick = ::onRefresh, onExpandCollectionClick = ::onExpandCollectionClick, onRetryAssetsClick = ::onRetryAssetsClick, onAssetClick = { asset, collection -> params.onAssetClick(asset, collection) }, initialSearchBarFactory = ::getInitialSearchBar, collectionIdProvider = collectionIdProvider, ).transform(it) } + MultilineLambdaItParameter:NFTCollectionsModel.kt$NFTCollectionsModel${ UpdateDataStateTransformer( nftCollections = nftCollections.filter(query), onReceiveClick = { params.onReceiveClick() }, onRetryClick = ::onRefresh, onExpandCollectionClick = ::onExpandCollectionClick, onRetryAssetsClick = ::onRetryAssetsClick, onAssetClick = { asset, collection -> params.onAssetClick(asset, collection) }, initialSearchBarFactory = ::getInitialSearchBar, collectionIdProvider = collectionIdProvider, ).transform(it) } + MultilineLambdaItParameter:NFTCollectionsModel.kt$NFTCollectionsModel${ it.copy( content = when (val content = it.content) { is NFTCollections.Content.Collections -> content.copy( collections = content.collections.orEmpty().filter { val assetsFulfillQuery = if (query.isEmpty()) { true } else { when (val assets = it.assets) { is NFTCollection.Assets.Empty, is NFTCollection.Assets.Failed, is NFTCollection.Assets.Loading, -> false is NFTCollection.Assets.Value -> { assets.items.any { asset -> asset.name?.lowercase()?.contains(query.lowercase()) == true } } } } val collectionFulfillQuery = query.isEmpty() || it.name?.lowercase()?.contains(query.lowercase()) == true collectionFulfillQuery || assetsFulfillQuery }, ) is NFTCollections.Content.Error -> it.content }, ) } + MultilineLambdaItParameter:NFTCollectionsModel.kt$NFTCollectionsModel${ val assetsFulfillQuery = if (query.isEmpty()) { true } else { when (val assets = it.assets) { is NFTCollection.Assets.Empty, is NFTCollection.Assets.Failed, is NFTCollection.Assets.Loading, -> false is NFTCollection.Assets.Value -> { assets.items.any { asset -> asset.name?.lowercase()?.contains(query.lowercase()) == true } } } } val collectionFulfillQuery = query.isEmpty() || it.name?.lowercase()?.contains(query.lowercase()) == true collectionFulfillQuery || assetsFulfillQuery } + MultilineLambdaItParameter:NFTDetailsUMFactory.kt$NFTDetailsUMFactory${ NFTAssetUM.BlockItem( title = stringReference(it.name), value = it.value, showInfoButton = false, ) } + MultilineLambdaItParameter:NFTDetailsUMFactory.kt$NFTDetailsUMFactory${ NFTAssetUM.Media.Content( url = it, ) } + MultilineLambdaItParameter:NFTReceiveModel.kt$NFTReceiveModel${ ShowReceiveBottomSheetTransformer( network = network, networkAddress = value.address, onDismissBottomSheet = ::onReceiveBottomSheetDismiss, onCopyClick = { text -> onCopyClick(text, network) }, onShareClick = { text -> onShareClick(text, network) }, ).transform(it) } + MultilineLambdaItParameter:NFTReceiveModel.kt$NFTReceiveModel${ UpdateDataStateTransformer( networks = filteredNetworks, onNetworkClick = ::onNetworkClick, ).transform(it) } + MultilineLambdaItParameter:NFTReceiveModel.kt$NFTReceiveModel${ it.copy( bottomSheetConfig = it.bottomSheetConfig?.copy(isShown = false), ) } + MultilineLambdaItParameter:UpdateDataStateTransformer.kt$UpdateDataStateTransformer${ NFTCollectionUM( id = it.collectionIdProvider(), networkIconId = getActiveIconRes(it.network.rawId), name = it.name.orEmpty(), description = TextReference.PluralRes( R.plurals.nft_collections_count, it.count, wrappedList(it.count), ), logoUrl = it.logoUrl, assets = it.transformAssets(), onExpandClick = { onExpandCollectionClick(it) }, isExpanded = it.isExpanded(state), ) } + NoNameShadowing:NFTCollectionsModel.kt$NFTCollectionsModel${ val assetsFulfillQuery = if (query.isEmpty()) { true } else { when (val assets = it.assets) { is NFTCollection.Assets.Empty, is NFTCollection.Assets.Failed, is NFTCollection.Assets.Loading, -> false is NFTCollection.Assets.Value -> { assets.items.any { asset -> asset.name?.lowercase()?.contains(query.lowercase()) == true } } } } val collectionFulfillQuery = query.isEmpty() || it.name?.lowercase()?.contains(query.lowercase()) == true collectionFulfillQuery || assetsFulfillQuery } + NonBooleanPropertyPrefixedWithIs:NFTCollectionsModel.kt$NFTCollectionsModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:NFTReceiveModel.kt$NFTReceiveModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NullableBooleanCheck:UpdateDataStateTransformer.kt$UpdateDataStateTransformer$(state.content as? NFTCollectionsUM.Content) ?.collections ?.filterIsInstance<NFTCollectionUM>() ?.firstOrNull { it.id == this.collectionIdProvider() } ?.isExpanded ?: false + NullableToStringCall:NFTCollectionsContent.kt$${item2?.id} + NullableToStringCall:NFTCollectionsModel.kt$NFTCollectionsModel$${network.derivationPath.value} + PropertyUsedBeforeDeclaration:NFTDetailsModel.kt$NFTDetailsModel$_state + ReusedModifierInstance:NFTCollectionsContent.kt$Box( modifier = modifier .fillMaxSize() .padding(bottom = bottomPadding), ) { Text( modifier = Modifier .align(Alignment.Center), text = stringResourceSafe(id = R.string.nft_empty_search), style = TangemTheme.typography.body2, color = TangemTheme.colors.text.tertiary, textAlign = TextAlign.Center, ) } + ReusedModifierInstance:NFTCollectionsLoading.kt$Card( modifier = modifier .fillMaxWidth() .padding( top = TangemTheme.dimens.spacing16, ), shape = RoundedCornerShape(TangemTheme.dimens.radius16), colors = CardDefaults.cardColors( containerColor = TangemTheme.colors.background.primary, contentColor = TangemTheme.colors.text.primary1, disabledContainerColor = TangemTheme.colors.background.primary, disabledContentColor = TangemTheme.colors.text.primary1, ), ) { Column { repeat(SHIMMER_ITEMS_COUNT) { CollectionPlaceholder() } } } + ReusedModifierInstance:NFTDetailsAsset.kt$Column( modifier = modifier .verticalScroll(scrollState) .padding( start = TangemTheme.dimens.spacing16, top = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing16, bottom = bottomPadding, ) .fillMaxSize(), ) { NFTDetailsLogo( state = state.media, modifier = Modifier .aspectRatio(1f), ) NFTDetailsInfoGroup( modifier = Modifier .padding(top = TangemTheme.dimens.spacing12), state = state.topInfo, onReadMoreClick = onReadMoreClick, ) NFTDetailsBlocksGroup( modifier = Modifier .padding(top = TangemTheme.dimens.spacing12), items = state.traits, title = resourceReference(R.string.nft_details_traits), action = if (state.showAllTraitsButton) { { NFTBlocksGroupAction( text = resourceReference(R.string.common_see_all), startIcon = { }, onClick = onSeeAllTraitsClick, ) } } else { null }, ) NFTDetailsBlocksGroup( modifier = Modifier .padding(top = TangemTheme.dimens.spacing12), items = state.baseInfoItems, title = resourceReference(R.string.nft_details_base_information), action = { NFTBlocksGroupAction( text = resourceReference(R.string.common_explore), startIcon = { NFTBlocksGroupActionIcon(iconRes = R.drawable.ic_compass_24) }, onClick = onExploreClick, ) }, ) } + ReusedModifierInstance:NFTDetailsInfoGroup.kt$Column( modifier = modifier .padding( start = TangemTheme.dimens.spacing12, end = TangemTheme.dimens.spacing12, ), ) { TextShimmer( modifier = Modifier .width(TangemTheme.dimens.size158), style = TangemTheme.typography.head, textSizeHeight = true, ) TextShimmer( modifier = Modifier .padding(top = TangemTheme.dimens.spacing4) .width(TangemTheme.dimens.size90), style = TangemTheme.typography.caption2, textSizeHeight = true, ) } + ReusedModifierInstance:NFTDetailsInfoGroup.kt$Column( modifier = modifier .padding( start = TangemTheme.dimens.spacing12, end = TangemTheme.dimens.spacing12, ), verticalArrangement = Arrangement.SpaceAround, ) { Text( text = state.cryptoPrice.resolveReference(), style = TangemTheme.typography.head, color = TangemTheme.colors.text.primary1, ) Text( modifier = Modifier .padding(top = TangemTheme.dimens.spacing4) .flicker(state.isFlickering), text = state.fiatPrice.resolveReference(), style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, ) } + UnsafeCallOnNullableType:DefaultNFTComponent.kt$DefaultNFTComponent$portfolioFetcher!! + UseEmptyCounterpart:NFTCollectionsModel.kt$NFTCollectionsModel$listOf() + UseEmptyCounterpart:UpdateDataStateTransformer.kt$UpdateDataStateTransformer$listOf() + UseOrEmpty:UpdateDataStateTransformer.kt$UpdateDataStateTransformer$walletNFTCollections.collections.values.firstOrNull() ?: listOf() + + diff --git a/features/onboarding-v2/impl/detekt-baseline-debug.xml b/features/onboarding-v2/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..e4d1590e43 --- /dev/null +++ b/features/onboarding-v2/impl/detekt-baseline-debug.xml @@ -0,0 +1,143 @@ + + + + + BooleanPropertyNaming:MultiWalletAccessCodeComponent.kt$MultiWalletAccessCodeComponent$val showBs by showBs.collectAsStateWithLifecycle() + BooleanPropertyNaming:MultiWalletAccessCodeUM.kt$MultiWalletAccessCodeUM$val atLeast4CharError: Boolean = false + BooleanPropertyNaming:MultiWalletAccessCodeUM.kt$MultiWalletAccessCodeUM$val codesNotMatchError: Boolean = false + BooleanPropertyNaming:MultiWalletBackupUM.kt$MultiWalletBackupUM$val addBackupButtonEnabled: Boolean = true + BooleanPropertyNaming:MultiWalletBackupUM.kt$MultiWalletBackupUM$val addBackupButtonLoading: Boolean = false + BooleanPropertyNaming:MultiWalletBackupUM.kt$MultiWalletBackupUM$val finalizeButtonEnabled: Boolean = false + BooleanPropertyNaming:MultiWalletBackupUM.kt$MultiWalletBackupUMDialog$val warningCancelColor: Boolean = false + BooleanPropertyNaming:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel$val cardDoesNotSupportBackup = result.data.card.settings.isBackupAllowed.not() + BooleanPropertyNaming:MultiWalletCreateWalletUM.kt$MultiWalletCreateWalletUM$val showOtherOptionsButton: Boolean + BooleanPropertyNaming:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel$private var walletHasBackupError = false + BooleanPropertyNaming:MultiWalletFinalizeUM.kt$MultiWalletFinalizeUM$val scanPrimary: Boolean = true + BooleanPropertyNaming:MultiWalletSeedPhraseUM.kt$MultiWalletSeedPhraseUM.GeneratedWordsCheck$val createWalletButtonEnabled: Boolean = false + BooleanPropertyNaming:MultiWalletSeedPhraseUM.kt$MultiWalletSeedPhraseUM.GeneratedWordsCheck$val createWalletButtonProgress: Boolean = false + BooleanPropertyNaming:MultiWalletSeedPhraseUM.kt$MultiWalletSeedPhraseUM.GeneratedWordsCheck.WordField$val error: Boolean + BooleanPropertyNaming:MultiWalletSeedPhraseUM.kt$MultiWalletSeedPhraseUM.Import$val createWalletEnabled: Boolean = false + BooleanPropertyNaming:MultiWalletSeedPhraseUM.kt$MultiWalletSeedPhraseUM.Import$val createWalletProgress: Boolean = false + BooleanPropertyNaming:MultiWalletUpgradeWalletModel.kt$MultiWalletUpgradeWalletModel$val cardDoesNotSupportBackup = result.data.card.settings.isBackupAllowed.not() + BooleanPropertyNaming:OnboardingDialogUM.kt$OnboardingDialogUM$val dismissWarningColor: Boolean = false + BooleanPropertyNaming:OnboardingDone.kt$var showConfetti by remember { mutableStateOf(false) } + BooleanPropertyNaming:OnboardingMultiWalletComponent.kt$OnboardingMultiWalletComponent.Params$val withSeedPhraseFlow: Boolean + BooleanPropertyNaming:OnboardingNoteCreateWalletUM.kt$OnboardingNoteCreateWalletUM$val createWalletInProgress: Boolean = false + BooleanPropertyNaming:OnboardingRoute.kt$OnboardingRoute.MultiWallet$val withSeedPhraseFlow: Boolean + BooleanPropertyNaming:OnboardingStepperComponent.kt$OnboardingStepperComponent.StepperState$val showProgress: Boolean + BooleanPropertyNaming:OnboardingTwin.kt$var toggle by remember { mutableStateOf(false) } + BooleanPropertyNaming:OnboardingTwinModel.kt$OnboardingTwinModel$val twinningInProgress = state is OnboardingTwinUM.ScanCard && (state.step == OnboardingTwinUM.ScanCard.Step.Second || state.step == OnboardingTwinUM.ScanCard.Step.Third) + BooleanPropertyNaming:OnboardingTwinUM.kt$OnboardingTwinUM.ResetWarning$val acceptToggle: Boolean = false + BooleanPropertyNaming:OnboardingVisaAccessCodeUM.kt$OnboardingVisaAccessCodeUM$val accessCodeHidden: Boolean = true + BooleanPropertyNaming:OnboardingVisaAccessCodeUM.kt$OnboardingVisaAccessCodeUM$val atLeastMinCharsError: Boolean = false + BooleanPropertyNaming:OnboardingVisaAccessCodeUM.kt$OnboardingVisaAccessCodeUM$val buttonLoading: Boolean = false + BooleanPropertyNaming:OnboardingVisaAccessCodeUM.kt$OnboardingVisaAccessCodeUM$val codesNotMatchError: Boolean = false + BooleanPropertyNaming:OnboardingVisaApproveUM.kt$OnboardingVisaApproveUM$val approveButtonLoading: Boolean = false + BooleanPropertyNaming:OnboardingVisaPinCodeUM.kt$OnboardingVisaPinCodeUM$val submitButtonEnabled: Boolean = true + BooleanPropertyNaming:OnboardingVisaPinCodeUM.kt$OnboardingVisaPinCodeUM$val submitButtonLoading: Boolean = false + BooleanPropertyNaming:OnboardingVisaRoute.kt$OnboardingVisaRoute.PinCode$val pinCodeValidationError: Boolean + BooleanPropertyNaming:OnboardingVisaRoute.kt$OnboardingVisaRoute.TangemWalletApproveOption$val allowNavigateBack: Boolean + BooleanPropertyNaming:OnboardingVisaWelcomeUM.kt$OnboardingVisaWelcomeUM$val continueButtonLoading: Boolean = false + BooleanPropertyNaming:SeedPhraseCheckUiStateBuilder.kt$SeedPhraseCheckUiStateBuilder$val allFieldsCorrect = newState.allFieldsCorrect() + BooleanPropertyNaming:SeedPhraseCheckUiStateBuilder.kt$SeedPhraseCheckUiStateBuilder$val correct = checkWordField(word = newText.text, shownIndex = shownIndex) + BooleanPropertyNaming:SeedPhraseState.kt$SeedPhraseState$val readyToImport: Boolean + BooleanPropertyNaming:Wallet1ChooseOptionModel.kt$Wallet1ChooseOptionModel$private var skipClicked = false + BooleanPropertyNaming:WalletArtwork.kt$WalletArtworksState.Leapfrog$val threeCards: Boolean = true + BooleanPropertyNaming:WalletArtwork.kt$WalletArtworksState.Stack$val threeCards: Boolean = true + CanBeNonNullable:DefaultOnboardingTwinComponent.kt$DefaultOnboardingTwinComponent.TwinInnerNavigationState$override val stackMaxSize: Int? = 5 + MaxChainedCallsOnSameLine:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel$result.data.card.settings.isBackupAllowed.not() + MaxChainedCallsOnSameLine:MultiWalletUpgradeWalletModel.kt$MultiWalletUpgradeWalletModel$result.data.card.settings.isBackupAllowed.not() + MaxChainedCallsOnSameLine:OnboardingTwinModel.kt$OnboardingTwinModel$params.scanResponse.card.issuer.publicKey.toHexString() + MaxChainedCallsOnSameLine:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel$result.data.signedActivationData.dataToSign.request.activationOrderInfo.customerWalletAddress + MaxChainedCallsOnSameLine:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel$result.data.signedActivationData.dataToSign.request.activationOrderInfo.orderId + MaxChainedCallsOnSameLine:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel$result.data.signedActivationData.dataToSign.request.cardWalletAddress + MaxChainedCallsOnSameLine:Wallet1ChooseOptionModel.kt$Wallet1ChooseOptionModel$params.multiWalletState.value.currentScanResponse.card.canSkipBackup + MultilineLambdaItParameter:DefaultOnboardingEntryComponent.kt$DefaultOnboardingEntryComponent${ it.copy( currentStep = state.stackSize, steps = state.stackMaxSize ?: 0, title = model.titleProvider.currentTitle.value, showProgress = state.stackMaxSize != null, ) } + MultilineLambdaItParameter:DefaultOnboardingEntryComponent.kt$DefaultOnboardingEntryComponent${ it.copy( currentStep = when (stack.active.configuration) { is OnboardingRoute.ManageTokens -> 7 is OnboardingRoute.AskBiometry -> 8 is OnboardingRoute.Done -> 9 else -> error("Unsupported route") }, steps = 9, title = when (stack.active.configuration) { is OnboardingRoute.ManageTokens -> resourceReference(R.string.main_manage_tokens) is OnboardingRoute.AskBiometry -> resourceReference(R.string.onboarding_navbar_save_wallet) is OnboardingRoute.Done -> resourceReference(R.string.onboarding_done_header) else -> error("Unsupported route") }, showProgress = true, ) } + MultilineLambdaItParameter:DefaultOnboardingVisaComponent.kt$DefaultOnboardingVisaComponent${ model.stackNavigation.replaceAll( OnboardingVisaRoute.PinCode(activationOrderInfo = it, pinCodeValidationError = false), ) } + MultilineLambdaItParameter:DefaultOnboardingVisaComponent.kt$DefaultOnboardingVisaComponent${ val activationReadyEvent = (it as? OnboardingVisaWelcomeComponent.DoneEvent.WelcomeBackDone)?.activationReadyEvent if (activationReadyEvent != null) { model.navigateFromActivationScreen(activationReadyEvent) } } + MultilineLambdaItParameter:GenerateSeedPhraseUiStateBuilder.kt$GenerateSeedPhraseUiStateBuilder${ switchType( newType = it, generatedWords12 = words12, generatedWords24 = words24, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( createWalletEnabled = false, wordsErrorText = null, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( invalidWords = emptyList<String>().toImmutableList(), wordsErrorText = null, createWalletEnabled = true, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( invalidWords = invalidWords.toImmutableList(), wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_wrong_words), createWalletEnabled = false, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ it.copy( wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_invalid_checksum), createWalletEnabled = false, ) } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ launchInterceptWords(wordsField = it) suggestNextWord(it) updateUiState { state -> state.copy(words = it) } } + MultilineLambdaItParameter:ImportSeedPhraseUiStateBuilder.kt$ImportSeedPhraseUiStateBuilder${ passphrase = it.text updateUiState { state -> state.copy(passPhrase = it) } } + MultilineLambdaItParameter:InvalidWordsColorTransformation.kt$InvalidWordsColorTransformation${ if (it == WORD_SEPARATOR) { append(WHITE_SPACE) } else if (wordsToBrush.contains(it)) { append(it.annotate()) } else { append(it) } } + MultilineLambdaItParameter:MultiWalletAccessCodeModel.kt$MultiWalletAccessCodeModel${ it.copy( accessCodeFirst = textFieldValue, atLeast4CharError = false, ) } + MultilineLambdaItParameter:MultiWalletAccessCodeModel.kt$MultiWalletAccessCodeModel${ it.copy( accessCodeSecond = textFieldValue, codesNotMatchError = false, ) } + MultilineLambdaItParameter:MultiWalletAccessCodeModel.kt$MultiWalletAccessCodeModel${ it.copy( step = MultiWalletAccessCodeUM.Step.AccessCode, accessCodeSecond = TextFieldValue(""), ) } + MultilineLambdaItParameter:MultiWalletAccessCodeModel.kt$MultiWalletAccessCodeModel${ it.copy( step = MultiWalletAccessCodeUM.Step.ConfirmAccessCode, atLeast4CharError = false, ) } + MultilineLambdaItParameter:MultiWalletAccessCodeModel.kt$MultiWalletAccessCodeModel${ it.copy( step = MultiWalletAccessCodeUM.Step.Intro, accessCodeFirst = TextFieldValue(""), accessCodeSecond = TextFieldValue(""), ) } + MultilineLambdaItParameter:MultiWalletBackupComponent.kt$MultiWalletBackupComponent${ it.copy( stackSize = 5, stackMaxSize = 9, ) } + MultilineLambdaItParameter:MultiWalletBackupModel.kt$MultiWalletBackupModel${ it.copy( card2 = if (state.value.numberOfBackupCards == 1) backupCardInfo else it.card2, card3 = if (state.value.numberOfBackupCards == 2) backupCardInfo else it.card3, ) } + MultilineLambdaItParameter:MultiWalletBackupModel.kt$MultiWalletBackupModel${ it.copy( dialog = onlyOneBackupDeviceDialog( onDismiss = { _uiState.update { it.copy(dialog = null) } }, onConfirm = { onFinalizeClick(fromDialog = true) }, ), ) } + MultilineLambdaItParameter:MultiWalletBackupModel.kt$MultiWalletBackupModel${ it.copy( numberOfBackupCards = it.numberOfBackupCards + 1, ) } + MultilineLambdaItParameter:MultiWalletCreateWalletComponent.kt$MultiWalletCreateWalletComponent${ it.copy( stackSize = 2, stackMaxSize = 9, ) } + MultilineLambdaItParameter:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel${ it.copy( currentScanResponse = it.currentScanResponse.copy( card = result.data.card, derivedKeys = result.data.derivedKeys, primaryCard = result.data.primaryCard, ), ) } + MultilineLambdaItParameter:MultiWalletFinalizeComponent.kt$MultiWalletFinalizeComponent${ it.copy( stackSize = 7, stackMaxSize = 9, ) } + MultilineLambdaItParameter:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel${ it is UserWallet.Cold && it.scanResponse.primaryCard?.cardId == scanResponse.primaryCard?.cardId } + MultilineLambdaItParameter:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel${ it.requireColdWallet().copy( scanResponse = scanResponse.updateScanResponseAfterBackup(), ) } + MultilineLambdaItParameter:MultiWalletScanPrimaryComponent.kt$MultiWalletScanPrimaryComponent${ it.copy( stackSize = 4, stackMaxSize = 9, ) } + MultilineLambdaItParameter:MultiWalletScanPrimaryModel.kt$MultiWalletScanPrimaryModel${ it.copy( currentScanResponse = scanResponse.copy( primaryCard = result.data, ), ) } + MultilineLambdaItParameter:MultiWalletSeedPhraseComponent.kt$MultiWalletSeedPhraseComponent${ // change stepper state based on the stack of the current step @Suppress("MagicNumber") params.innerNavigation.update { st -> st.copy( stackSize = 3 + it.order, stackMaxSize = 11, ) } val title = when (it) { is MultiWalletSeedPhraseUM.Import -> R.string.onboarding_seed_intro_button_import is MultiWalletSeedPhraseUM.GenerateSeedPhrase, is MultiWalletSeedPhraseUM.GeneratedWordsCheck, is MultiWalletSeedPhraseUM.Start, -> R.string.onboarding_create_wallet_header } params.parentParams.titleProvider.changeTitle(text = resourceReference(title)) } + MultilineLambdaItParameter:MultiWalletSeedPhraseModel.kt$MultiWalletSeedPhraseModel${ if (it !is T) return@update it block(it) } + MultilineLambdaItParameter:MultiWalletSeedPhraseModel.kt$MultiWalletSeedPhraseModel${ it.copy( generatedWords12 = words12, generatedWords24 = words24, ) } + MultilineLambdaItParameter:MultiWalletSeedPhraseWords.kt${ EnumeratedTwoColumnGridItem( index = it + 1, mnemonic = "word1", ) } + MultilineLambdaItParameter:MultiWalletSeedPhraseWords.kt${ Text( text = pluralStringResourceSafe( id = R.plurals.onboarding_seed_generate_words_count, count = it.length, it.length, ), modifier = Modifier .padding(vertical = TangemTheme.dimens.spacing10) .fillMaxWidth(), style = TangemTheme.typography.subtitle2, color = TangemTheme.colors.text.primary1, textAlign = TextAlign.Center, ) } + MultilineLambdaItParameter:MultiWalletSeedPhraseWords.kt${ when { state.option == GeneratedWordsType.Words12 && it == GeneratedWordsType.Words24 -> { state.onOptionChange(it) } state.option == GeneratedWordsType.Words24 && it == GeneratedWordsType.Words12 -> { state.onOptionChange(it) } } } + MultilineLambdaItParameter:MultiWalletUpgradeWalletComponent.kt$MultiWalletUpgradeWalletComponent${ it.copy( stackSize = 2, stackMaxSize = 9, ) } + MultilineLambdaItParameter:MultiWalletUpgradeWalletModel.kt$MultiWalletUpgradeWalletModel${ it.copy( currentScanResponse = it.currentScanResponse.copy( card = result.data.card, derivedKeys = result.data.derivedKeys, primaryCard = result.data.primaryCard, ), ) } + MultilineLambdaItParameter:OnboardingTwinModel.kt$OnboardingTwinModel${ Timber.e("Unable to save user wallet: $it") setLoading(false) return@coroutineScope } + MultilineLambdaItParameter:OnboardingTwinModel.kt$OnboardingTwinModel${ Timber.e("Unable to save user wallet: $it") setLoading(false) return@launch } + MultilineLambdaItParameter:OnboardingTwinModel.kt$OnboardingTwinModel${ it.copy( isLoading = false, artworkStep = it.artworkStep.next(), step = OnboardingTwinUM.ScanCard.Step.Second, onScanClick = { createSecondWallet(firstPublicKey = result.data.wallet.publicKey.toHexString()) }, ) } + MultilineLambdaItParameter:OnboardingTwinModel.kt$OnboardingTwinModel${ it.copy( isLoading = false, artworkStep = it.artworkStep.next(), step = OnboardingTwinUM.ScanCard.Step.Third, onScanClick = { createThirdWallet( secondCardPublicKey = result.data.wallet.publicKey, ) }, ) } + MultilineLambdaItParameter:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel${ it.copy( accessCodeFirst = textFieldValue, accessCodeSecond = TextFieldValue(), atLeastMinCharsError = false, ) } + MultilineLambdaItParameter:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel${ it.copy( accessCodeSecond = textFieldValue, codesNotMatchError = false, ) } + MultilineLambdaItParameter:OnboardingVisaAccessCodeModel.kt$OnboardingVisaAccessCodeModel${ onError(it) return@launch } + MultilineLambdaItParameter:OnboardingVisaApproveModel.kt$OnboardingVisaApproveModel${ onError(it) return@launch } + MultilineLambdaItParameter:OnboardingVisaInProgressModel.kt$OnboardingVisaInProgressModel${ if (it.isUnknown()) { uiMessageSender.send(unexpectedErrorAlertBS) } else { uiMessageSender.showErrorDialog(it) } analyticsEventHandler.send(VisaAnalyticsEvent.ErrorOnboarding(it)) delay(timeMillis = 2000) runShortPolling() return@launch } + MultilineLambdaItParameter:OnboardingVisaInProgressModel.kt$OnboardingVisaInProgressModel${ uiMessageSender.showErrorDialog(it) return } + MultilineLambdaItParameter:OnboardingVisaModel.kt$OnboardingVisaModel${ val derivedKey = it.derivedKeys[VisaUtilities.visaDefaultDerivationPath] ?: return@any false VisaWalletPublicKeyUtility.validateExtendedPublicKey( targetAddress = targetAddress, extendedPublicKey = derivedKey, ).onLeft { return@any VisaWalletPublicKeyUtility.findKeyWithoutDerivation( targetAddress = targetAddress, card = wallet.scanResponse.card, ).isRight() }.isRight() } + MultilineLambdaItParameter:OnboardingVisaOtherWalletModel.kt$OnboardingVisaOtherWalletModel${ if (it is VisaActivationRemoteState.AwaitingPinCode) { onDone.emit(it.activationOrderInfo) return@launch } } + MultilineLambdaItParameter:OnboardingVisaOtherWalletModel.kt$OnboardingVisaOtherWalletModel${ uiMessageSender.showErrorDialog(it) analyticsEventHandler.send(VisaAnalyticsEvent.ErrorOnboarding(it)) delay(timeMillis = 60_000) } + MultilineLambdaItParameter:OnboardingVisaPinCodeModel.kt$OnboardingVisaPinCodeModel${ it.copy( pinCode = pin, submitButtonEnabled = PinCodeValidation.validate(pin), error = if (isError) { analyticsEventHandler.send(OnboardingVisaAnalyticsEvent.ErrorPinValidation) resourceReference(R.string.visa_onboarding_pin_validation_error_message) } else { null }, ) } + MultilineLambdaItParameter:OnboardingVisaWelcomeModel.kt$OnboardingVisaWelcomeModel${ onError(it) return@launch } + MultilineLambdaItParameter:SeedPhraseCheckUiStateBuilder.kt$SeedPhraseCheckUiStateBuilder${ checkWordField( word = it.word.text, shownIndex = it.index, ) } + MultilineLambdaItParameter:TwinWalletArtwork.kt${ animationState = it val maxTime = maxOf( transition1.totalDurationNanos, transition2.totalDurationNanos, ) delay(TimeUnit.NANOSECONDS.toMillis(maxTime)) } + MultilineLambdaItParameter:Wallet1ChooseOptionComponent.kt$Wallet1ChooseOptionComponent${ it.copy( stackSize = 3, stackMaxSize = 9, ) } + MultilineLambdaItParameter:WalletArtwork.kt${ animationState = it val maxTime = maxOf( transition1.totalDurationNanos, transition2.totalDurationNanos, transition3.totalDurationNanos, ) delay(TimeUnit.NANOSECONDS.toMillis(maxTime)) } + NoNameShadowing:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel${ it.copy(resultUserWallet = userWallet) } + NoNameShadowing:MultiWalletUpgradeWalletModel.kt$MultiWalletUpgradeWalletModel${ it.copy(resultUserWallet = userWallet) } + NoNameShadowing:Wallet1ChooseOptionModel.kt$Wallet1ChooseOptionModel${ it.copy(resultUserWallet = userWallet) } + NonBooleanPropertyPrefixedWithIs:MultiWalletSeedPhraseModel.kt$MultiWalletSeedPhraseModel$private val isWalletAlreadySavedUseCase: IsWalletAlreadySavedUseCase + PropertyUsedBeforeDeclaration:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel$onDone + RedundantSuspendModifier:MultiWalletCreateWalletModel.kt$MultiWalletCreateWalletModel$suspend + RedundantSuspendModifier:OnboardingNoteCreateWalletModel.kt$OnboardingNoteCreateWalletModel$suspend + ReusedModifierInstance:DefaultOnboardingNoteComponent.kt$DefaultOnboardingNoteComponent$Content(modifier) + ReusedModifierInstance:DefaultOnboardingVisaComponent.kt$DefaultOnboardingVisaComponent$Content(modifier) + ReusedModifierInstance:MultiWalletAccessCodeEnter.kt$OutlineTextField( modifier = modifier .focusRequester(focusRequester) .fillMaxWidth(), value = if (reEnterAccessCodeState) { state.accessCodeSecond } else { state.accessCodeFirst }, onValueChange = if (reEnterAccessCodeState) { state.onAccessCodeSecondChange } else { state.onAccessCodeFirstChange }, label = stringResourceSafe(id = R.string.onboarding_wallet_info_title_third), isError = state.codesNotMatchError, visualTransformation = PasswordVisualTransformation(), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), caption = when { state.codesNotMatchError && reEnterAccessCodeState -> stringResourceSafe(R.string.onboarding_access_codes_doesnt_match) else -> null }, ) + ReusedModifierInstance:MultiWalletSeedPhraseImport.kt$OutlineTextFieldWithIcon( modifier = modifier .padding(horizontal = 16.dp) .fillMaxWidth(), value = state.passPhrase, onValueChange = state.passPhraseChange, iconResId = R.drawable.ic_information_24, iconColor = TangemTheme.colors.icon.informative, label = stringResourceSafe(id = R.string.common_passphrase), placeholder = stringResourceSafe(id = R.string.send_optional_field), onIconClick = state.onPassphraseInfoClick, keyboardOptions = KeyboardOptions( autoCorrectEnabled = false, keyboardType = KeyboardType.Password, ), ) + ReusedModifierInstance:OnboardingEntry.kt$Content(modifier = modifier) + ReusedModifierInstance:OnboardingStepper.kt$TangemTopAppBar( startButton = TopAppBarButtonUM.Back(onBackClick), endButton = TopAppBarButtonUM.Icon(iconRes = R.drawable.ic_chat_24, onClicked = onSupportButtonClick) .takeIf { state.steps != state.currentStep }, title = if (state.steps == state.currentStep) { resourceReference(R.string.common_done) } else { state.title }, containerColor = TangemTheme.colors.background.primary, modifier = modifier, ) + ReusedModifierInstance:OnboardingVisaAccessCode.kt$OutlineTextFieldWithIcon( modifier = modifier .padding(horizontal = 16.dp) .focusRequester(focusRequester) .fillMaxWidth(), iconResId = if (state.accessCodeHidden) { R.drawable.ic_eye_outline_24 } else { R.drawable.ic_eye_off_outline_24 }, iconColor = TangemTheme.colors.icon.primary1, onIconClick = state.onAccessCodeHideClick, value = if (reEnterAccessCodeState) { state.accessCodeSecond } else { state.accessCodeFirst }, onValueChange = if (reEnterAccessCodeState) { state.onAccessCodeSecondChange } else { state.onAccessCodeFirstChange }, label = stringResourceSafe(id = R.string.onboarding_wallet_info_title_third), isError = state.codesNotMatchError || state.atLeastMinCharsError, visualTransformation = if (state.accessCodeHidden) { PasswordVisualTransformation() } else { VisualTransformation.None }, caption = when { state.codesNotMatchError && reEnterAccessCodeState -> stringResourceSafe(R.string.onboarding_access_codes_doesnt_match) state.atLeastMinCharsError && !reEnterAccessCodeState -> stringResourceSafe(R.string.onboarding_access_code_too_short) else -> null }, ) + ReusedModifierInstance:OnboardingVisaPinCode.kt$PinCode( modifier = modifier, value = state.pinCode, onValueChange = state.onPinCodeChange, focusRequester = focusRequester, ) + ReusedModifierInstance:OnboardingVisaWelcome.kt$Image( painter = painterResource(R.drawable.img_card_visa), contentDescription = null, modifier = modifier .align(Alignment.Center) .onSizeChanged { cardHeightPx = it.height } .widthIn(max = 512.dp) .fillMaxWidth(), ) + SuspendFunSwallowedCancellation:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel$runCatching + UnreachableCode:OnboardingNoteCreateWalletModel.kt$OnboardingNoteCreateWalletModel$params.childParams.commonState.value.scanResponse ?: return@launch + UnsafeCallOnNullableType:MultiWalletBackupModel.kt$MultiWalletBackupModel$backupServiceHolder.backupService.get()!! + UnsafeCallOnNullableType:OnboardingEntryModel.kt$OnboardingEntryModel$userWalletsListManager.asLockable()?.isLocked!! + UseEmptyCounterpart:OnboardingEntryEvent.kt$OnboardingEntryEvent$mapOf() + UseEmptyCounterpart:OnboardingEvent.kt$OnboardingEvent$mapOf() + UseEmptyCounterpart:OnboardingEvent.kt$OnboardingEvent.Backup$mapOf() + UseEmptyCounterpart:OnboardingEvent.kt$OnboardingEvent.CreateWallet$mapOf() + UseEmptyCounterpart:OnboardingEvent.kt$OnboardingEvent.Topup$mapOf() + UseEmptyCounterpart:OnboardingEvent.kt$OnboardingEvent.Twins$mapOf() + UseEmptyCounterpart:OnboardingVisaAnalyticsEvent.kt$OnboardingVisaAnalyticsEvent$mapOf() + UseEmptyCounterpart:VisaAnalyticsEvent.kt$VisaAnalyticsEvent$mapOf() + UseEmptyCounterpart:WalletArtwork.kt$listOf() + UseOrEmpty:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel$backupService.backupCardIds.firstOrNull()?.lastMasked() ?: "" + UseOrEmpty:MultiWalletFinalizeModel.kt$MultiWalletFinalizeModel$backupService.backupCardIds.getOrNull(cardIndex + 1) ?.lastMasked() ?: "" + UseOrEmpty:OnboardingVisaPinCode.kt$value.getOrNull(index)?.toString() ?: "" + + diff --git a/features/onramp/impl/detekt-baseline-debug.xml b/features/onramp/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..ea9c735b45 --- /dev/null +++ b/features/onramp/impl/detekt-baseline-debug.xml @@ -0,0 +1,95 @@ + + + + + BooleanPropertyNaming:ConfirmResidencyComponent.kt$ConfirmResidencyComponent.Params$val launchSepa: Boolean + BooleanPropertyNaming:DefaultHotCryptoComponent.kt$DefaultHotCryptoComponent$val scrollableContent = when (stack.active.configuration) { OnrampAddTokenRoute.PortfolioSelector -> false OnrampAddTokenRoute.AddToken, OnrampAddTokenRoute.Empty, -> true } + BooleanPropertyNaming:OnrampAddTokenComponent.kt$OnrampAddTokenComponent.AddHotCryptoData$val availableMorePortfolio: Boolean + BooleanPropertyNaming:OnrampMainComponent.kt$OnrampMainComponent.Params$val launchSepa: Boolean + BooleanPropertyNaming:OnrampMainComponentUM.kt$BuyButtonConfig$val enabled: Boolean + BooleanPropertyNaming:ProviderListPaymentMethodUM.kt$ProviderListPaymentMethodUM$val enabled: Boolean + BooleanPropertyNaming:SelectProviderModel.kt$SelectProviderModel$val allErrorProviders = providers.all { it is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod } + MaxChainedCallsOnSameLine:OnrampMainComponentModel.kt$OnrampMainComponentModel$content.amountBlockState.amountFieldModel.fiatAmount.value.isNullOrZero() + MaxChainedCallsOnSameLine:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel$content.amountBlockState.amountFieldModel.fiatAmount.value.isNullOrZero() + MultilineLambdaItParameter:AvailableSwapPairsModel.kt$AvailableSwapPairsModel${ handleErrorState( cause = it, networkInfo = params.selectedStatus.value?.toLeastTokenInfo(), currencies = currencies, ) } + MultilineLambdaItParameter:AvailableSwapPairsModel.kt$AvailableSwapPairsModel${ handleErrorStateV2( cause = it, networkInfo = params.selectedStatus.value?.toLeastTokenInfo(), accountList = accountList, ) } + MultilineLambdaItParameter:AvailableSwapPairsModel.kt$AvailableSwapPairsModel${ it.currency.name.contains(other = query, ignoreCase = true) || it.currency.symbol.contains(other = query, ignoreCase = true) } + MultilineLambdaItParameter:AvailableSwapPairsModel.kt$AvailableSwapPairsModel${ it.toMutableMap().apply { put(networkInfo, state) } } + MultilineLambdaItParameter:DefaultOnrampComponent.kt$DefaultOnrampComponent${ navigation.push( OnrampChild.RedirectPage( quote = it, cryptoCurrency = params.cryptoCurrency, ), ) } + MultilineLambdaItParameter:HotCryptoModel.kt$HotCryptoModel${ Timber.e(it) closeNavigationFlow() } + MultilineLambdaItParameter:HotCryptoModel.kt$HotCryptoModel${ bottomSheetNavigation.dismiss() params.onTokenClick(it) } + MultilineLambdaItParameter:HotCryptoPortfolioDataLoader.kt$HotCryptoPortfolioDataLoader${ val account: AccountStatus.CryptoPortfolio = when (it) { is AccountStatus.CryptoPortfolio -> it } val addedHotCrypto = mapOfAddedCurrencies[account.account] ?: listOf() HotCryptoPortfolioData.Account( account = account, addedHotCrypto = addedHotCrypto, ) } + MultilineLambdaItParameter:OnrampAddToPortfolioModel.kt$OnrampAddToPortfolioModel${ Timber.e("Failed to derive public keys: $it") changeAddButtonProgressStatus(isProgress = false) } + MultilineLambdaItParameter:OnrampAddTokenModel.kt$OnrampAddTokenModel${ processError(error = it) uiState.value = um.toggleProgress(false) return@launch } + MultilineLambdaItParameter:OnrampMainComponentModel.kt$OnrampMainComponentModel${ (it as? OnrampMainComponentUM.Content)?.copy( errorNotification = null, providerBlockState = OnrampProviderBlockUM.Loading, amountBlockState = it.amountBlockState.copy(secondaryFieldModel = OnrampAmountSecondaryFieldUM.Loading), ) ?: it } + MultilineLambdaItParameter:OnrampMainComponentModel.kt$OnrampMainComponentModel${ if (it is OnrampMainComponentUM.InitialLoading) { stateFactory.getReadyState(country.defaultCurrency) } else { amountStateFactory.getUpdatedCurrencyState(country.defaultCurrency) } } + MultilineLambdaItParameter:OnrampMainComponentModel.kt$OnrampMainComponentModel${ it.provider.id == providerState?.providerId && it.paymentMethod.id == providerState.paymentMethod.id } + MultilineLambdaItParameter:OnrampOffersContent.kt${ SpacerH(12.dp) SecondaryButton( modifier = Modifier.fillMaxWidth(), text = it.title.resolveReference(), onClick = it.onClick, ) } + MultilineLambdaItParameter:OnrampOffersContent.kt${ Text( modifier = Modifier .background( color = TangemTheme.colors.text.warning.copy(alpha = 0.1f), shape = RoundedCornerShape(4.dp), ) .padding(horizontal = 4.dp), text = it.resolveReference(), style = TangemTheme.typography.caption1, color = TangemTheme.colors.text.warning, ) } + MultilineLambdaItParameter:OnrampRedirectModel.kt$OnrampRedirectModel${ latestOnrampTransaction = it // Workaround to open Unlimit provider in external browser instead of chrome custom tabs if (params.onrampProviderWithQuote.provider.id.equals(UNLIMIT_PROVIDER_ID, ignoreCase = true)) { urlOpener.openUrlExternalBrowser(it.redirectUrl) } else { urlOpener.openUrl(it.redirectUrl) } } + MultilineLambdaItParameter:OnrampTokenItemStateConverterFactory.kt$OnrampTokenItemStateConverterFactory${ TokenItemState.TitleState.Content( text = stringReference(value = it.currency.name), isAvailable = false, ) } + MultilineLambdaItParameter:OnrampTokenItemStateConverterFactory.kt$OnrampTokenItemStateConverterFactory${ createSubtitleState( status = it, isAvailable = false, text = unavailableErrorText, ) } + MultilineLambdaItParameter:OnrampTokenItemStateConverterFactory.kt$OnrampTokenItemStateConverterFactory${ createSubtitleState( status = it, isAvailable = true, text = stringReference(value = it.currency.symbol), ) } + MultilineLambdaItParameter:OnrampTokenItemStateConverterFactory.kt$OnrampTokenItemStateConverterFactory${ createSubtitleState( status = it, text = stringReference(value = it.currency.symbol), isAvailable = false, ) } + MultilineLambdaItParameter:OnrampTokenListModel.kt$OnrampTokenListModel${ if (hasRestrictionForSell || isInsufficientBalanceForSell) { mapOf(false to it) } else { it.filterByAvailability() } } + MultilineLambdaItParameter:OnrampTokenListModel.kt$OnrampTokenListModel${ it.currency.name.contains(other = query, ignoreCase = true) || it.currency.symbol.contains(other = query, ignoreCase = true) } + MultilineLambdaItParameter:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel${ (it as? OnrampV2MainComponentUM.Content)?.copy( errorNotification = null, offersBlockState = OnrampOffersBlockUM.Loading, amountBlockState = it.amountBlockState.copy(secondaryFieldModel = OnrampSecondaryFieldErrorUM.Empty), ) ?: it } + MultilineLambdaItParameter:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel${ when (it) { is OnrampV2MainComponentUM.Content -> { amountStateFactory.getUpdatedCurrencyState(country.defaultCurrency) } is OnrampV2MainComponentUM.InitialLoading -> { stateFactory.getReadyState(country.defaultCurrency) } } } + MultilineLambdaItParameter:SelectProviderModel.kt$SelectProviderModel${ when (it) { is OnrampProviderWithQuote.Data -> it.toAmount.value // negative difference to sort both when data and unavailable is present is OnrampProviderWithQuote.Unavailable.AmountError -> { when (val error = it.quoteError.error) { is OnrampError.AmountError.TooSmallError -> it.quoteError.fromAmount.value - error.requiredAmount is OnrampError.AmountError.TooBigError -> error.requiredAmount - it.quoteError.fromAmount.value else -> null } } is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod -> null } } + NoNameShadowing:OnrampAddTokenUiBuilder.kt$OnrampAddTokenUiBuilder$tokenToAdd + NonBooleanPropertyPrefixedWithIs:AvailableSwapPairsModel.kt$AvailableSwapPairsModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:HotCryptoModel.kt$HotCryptoModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:OnrampAddTokenUiBuilder.kt$OnrampAddTokenUiBuilder$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:OnrampMainComponentModel.kt$OnrampMainComponentModel$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:OnrampOperationModel.kt$OnrampOperationModel$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:OnrampTokenListModel.kt$OnrampTokenListModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SwapSelectTokensModel.kt$SwapSelectTokensModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NullableBooleanCheck:HotCryptoModel.kt$HotCryptoModel$hotCryptoPortfolioData.wallet.accounts .find { it.account.accountId == accountStatus.accountId } ?.addedHotCrypto ?.none { it.currency.id.rawCurrencyId == hotCrypto.cryptoCurrency.id.rawCurrencyId } ?: false + NullableToStringCall:SwapSelectTokensController.kt$SwapSelectTokensController$${transformer::class.simpleName} + NullableToStringCall:TokenListUMController.kt$TokenListUMController$${transformer::class.simpleName} + PropertyUsedBeforeDeclaration:AllOffersModel.kt$AllOffersModel$state + PropertyUsedBeforeDeclaration:CountryListUMController.kt$CountryListUMController$_state + PropertyUsedBeforeDeclaration:CurrencyListController.kt$CurrencyListController$_state + PropertyUsedBeforeDeclaration:HotCryptoModel.kt$HotCryptoModel$_state + PropertyUsedBeforeDeclaration:OnrampAddToPortfolioModel.kt$OnrampAddToPortfolioModel$_state + PropertyUsedBeforeDeclaration:OnrampMainComponentModel.kt$OnrampMainComponentModel$_state + PropertyUsedBeforeDeclaration:OnrampMainComponentModel.kt$OnrampMainComponentModel$userCountry + PropertyUsedBeforeDeclaration:OnrampOperationModel.kt$OnrampOperationModel$_state + PropertyUsedBeforeDeclaration:OnrampSelectCountryModel.kt$OnrampSelectCountryModel$controller + PropertyUsedBeforeDeclaration:OnrampSelectCurrencyModel.kt$OnrampSelectCurrencyModel$controller + PropertyUsedBeforeDeclaration:OnrampSettingsModel.kt$OnrampSettingsModel$_state + PropertyUsedBeforeDeclaration:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel$_state + PropertyUsedBeforeDeclaration:SelectProviderModel.kt$SelectProviderModel$_state + PropertyUsedBeforeDeclaration:SwapSelectTokensController.kt$SwapSelectTokensController$_state + PropertyUsedBeforeDeclaration:SwapSelectTokensModel.kt$SwapSelectTokensModel$_fromCurrencyStatus + PropertyUsedBeforeDeclaration:TokenListUMController.kt$TokenListUMController$_state + RedundantSuspendModifier:OnrampSelectCountryModel.kt$OnrampSelectCountryModel$suspend + ReusedModifierInstance:DefaultOnrampComponent.kt$DefaultOnrampComponent$Content(modifier = modifier) + SuspendFunSwallowedCancellation:AvailableSwapPairsModel.kt$AvailableSwapPairsModel$runCatching + SuspendFunSwallowedCancellation:OnrampMainComponentModel.kt$OnrampMainComponentModel$runCatching + SuspendFunSwallowedCancellation:OnrampSuccessComponentModel.kt$OnrampSuccessComponentModel$runCatching + SuspendFunSwallowedCancellation:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel$runCatching + UnnecessaryApply:OnrampFooterContent.kt$apply { AnimatedVisibility( modifier = Modifier .imePadding() .align(Alignment.BottomCenter), visible = state.offersBlockState is OnrampOffersBlockUM.Empty, enter = slideInVertically( initialOffsetY = { it }, animationSpec = tween(durationMillis = 300), ), exit = slideOutVertically( targetOffsetY = { it }, animationSpec = tween(durationMillis = 300), ), label = "Footer block animation", ) { Column( modifier = modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally, ) { SpacerH(16.dp) OnrampAmountButtons(state = state.onrampAmountButtonUMState) } } } + UnnecessaryLet:AllOffersModel.kt$AllOffersModel$let { analyticsEventHandler::send } + UnnecessaryLet:HotTokenItemStateConverter.kt$HotTokenItemStateConverter$let { onItemClick -> { onItemClick(it, value) } } + UnnecessaryLet:OnrampButtonComponent.kt$let { state.onLinkClick(privacyPolicyLink) } + UnnecessaryLet:OnrampButtonComponent.kt$let { state.onLinkClick(termsOfUseLink) } + UnnecessaryLet:OnrampTokenListModel.kt$OnrampTokenListModel$let(::resourceReference) + UnnecessaryLet:OnrampTokenListUMExt.kt$let(::add) + UnnecessaryLet:OnrampV2MainComponentModel.kt$OnrampV2MainComponentModel$let(analyticsEventHandler::send) + UnnecessaryLet:SetNothingToFoundStateTransformer.kt$SetNothingToFoundStateTransformer$let(::add) + UnnecessaryLet:SetNothingToFoundStateTransformerV2.kt$SetNothingToFoundStateTransformerV2$let(::add) + UnsafeCallOnNullableType:DefaultHotCryptoComponent.kt$DefaultHotCryptoComponent$addTokenComponent!! + UnsafeCallOnNullableType:DefaultHotCryptoComponent.kt$DefaultHotCryptoComponent$model.portfolioFetcher!! + UnsafeCallOnNullableType:DefaultHotCryptoComponent.kt$DefaultHotCryptoComponent$portfolioSelectorComponent!! + UseEmptyCounterpart:HotCryptoPortfolioDataLoader.kt$HotCryptoPortfolioDataLoader$listOf() + UseEmptyCounterpart:SelectProviderPreviewData.kt$SelectProviderPreviewData$listOf() + UseOrEmpty:AvailableSwapPairsModel.kt$AvailableSwapPairsModel$selectedStatus?.currency?.name?.capitalize() ?: "" + UseOrEmpty:HotCryptoPortfolioDataLoader.kt$HotCryptoPortfolioDataLoader$getAccountCurrencyStatusUseCase .invokeSync(userWalletId, hotCryptoCurrencies) .getOrNull() ?: emptyMap() + UseOrEmpty:HotCryptoPortfolioDataLoader.kt$HotCryptoPortfolioDataLoader$mapOfAddedCurrencies[account.account] ?: listOf() + UselessCallOnNotNull:OnrampAddToPortfolioModel.kt$OnrampAddToPortfolioModel$listOfNotNull(params.cryptoCurrency) + VarCouldBeVal:AvailableSwapPairsModel.kt$AvailableSwapPairsModel$private var params: AvailableSwapPairsComponent.Params = paramsContainer.require() + VarCouldBeVal:OnrampSuccessComponentModel.kt$OnrampSuccessComponentModel$private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>() + VarCouldBeVal:SwapSelectTokensModel.kt$SwapSelectTokensModel$private var account: Account.CryptoPortfolio? = null + + diff --git a/features/qr-scanning/impl/detekt-baseline-debug.xml b/features/qr-scanning/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d8aaeb807c --- /dev/null +++ b/features/qr-scanning/impl/detekt-baseline-debug.xml @@ -0,0 +1,17 @@ + + + + + CanBeNonNullable:MLKitBarcodeAnalyzer.kt$MLKitBarcodeAnalyzer$onClose: (() -> Unit)? = null + MultilineLambdaItParameter:DefaultQrScanningComponent.kt$DefaultQrScanningComponent${ val selectedImage = it ?: Uri.EMPTY if (selectedImage != Uri.EMPTY) { val mimeType = context.contentResolver.getType(selectedImage) if (mimeType.isImageMimeType()) { try { val image = InputImage.fromFilePath(context, selectedImage) analyzer.analyze(image) } catch (e: IOException) { Timber.e(e, "Unable to get image $selectedImage from gallery") } } } } + MultilineLambdaItParameter:QrScanningContent.kt${ TopAppBarButton( button = TopAppBarButtonUM.Icon( iconRes = if (it) R.drawable.ic_flash_on_24 else R.drawable.ic_flash_off_24, onClicked = { isFlash = !isFlash }, ), tint = TangemColorPalette.White, modifier = Modifier.testTag(QrCodeScreenTestTags.FLASHLIGHT_BUTTON), ) } + MultilineLambdaItParameter:QrScanningContent.kt${ textMeasurer.measure( text = it, style = style, constraints = Constraints.fixedWidth(squareSize.roundToInt()), ) } + NestedScopeFunctions:MLKitBarcodeAnalyzer.kt$MLKitBarcodeAnalyzer$let { onScanned.invoke(it) } + NestedScopeFunctions:QrScanningContent.kt$let { textMeasurer.measure( text = it, style = style, constraints = Constraints.fixedWidth(squareSize.roundToInt()), ) } + NoNameShadowing:QrScanningContent.kt${ textMeasurer.measure( text = it, style = style, constraints = Constraints.fixedWidth(squareSize.roundToInt()), ) } + NoNameShadowing:QrScanningModel.kt$QrScanningModel$qrCode + PropertyUsedBeforeDeclaration:QrScanningStateController.kt$QrScanningStateController$mutableUiState + UnnecessaryLet:QrScanningContent.kt$let { textMeasurer.measure( text = it, style = style, constraints = Constraints.fixedWidth(squareSize.roundToInt()), ) } + UnnecessaryLet:QrScanningContent.kt$let { val textLayoutResult = text.let { textMeasurer.measure( text = it, style = style, constraints = Constraints.fixedWidth(squareSize.roundToInt()), ) } drawText( textLayoutResult = textLayoutResult, color = whiteColor, topLeft = Offset( x = horizontalOffset, y = verticalOffset - textPadding - textLayoutResult.size.height, ), ) } + + diff --git a/features/referral/data/detekt-baseline-debug.xml b/features/referral/data/detekt-baseline-debug.xml new file mode 100644 index 0000000000..c6103ddaf9 --- /dev/null +++ b/features/referral/data/detekt-baseline-debug.xml @@ -0,0 +1,7 @@ + + + + + MultilineLambdaItParameter:ReferralConverter.kt$ExpectedAwardsConverter${ ExpectedAward( paymentDate = it.paymentDate.toDateTimeAtStartOfDay().millis.toDateFormat(), amount = "${it.amount} ${it.currency}", ) } + + diff --git a/features/referral/domain/detekt-baseline-debug.xml b/features/referral/domain/detekt-baseline-debug.xml new file mode 100644 index 0000000000..822bbfee9f --- /dev/null +++ b/features/referral/domain/detekt-baseline-debug.xml @@ -0,0 +1,10 @@ + + + + + MultilineLambdaItParameter:ReferralInteractorImpl.kt$ReferralInteractorImpl${ Timber.e("Failed to derive public keys: $it") throw it.mapToDomainError() } + ObjectExtendsThrowable:ReferralError.kt$ReferralError$SdkError : ReferralError + ObjectExtendsThrowable:ReferralError.kt$ReferralError$UserCancelledException : ReferralError + UselessCallOnNotNull:ReferralInteractorImpl.kt$ReferralInteractorImpl$listOfNotNull(cryptoCurrency) + + diff --git a/features/referral/impl/detekt-baseline-debug.xml b/features/referral/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..d0a4690a1f --- /dev/null +++ b/features/referral/impl/detekt-baseline-debug.xml @@ -0,0 +1,16 @@ + + + + + MultilineLambdaItParameter:AgreementText.kt${ val clickableSpanStyle = requireNotNull(agreementText.spanStyles.getOrNull(1)) if (it in clickableSpanStyle.start..clickableSpanStyle.end) { onClick() } } + MultilineLambdaItParameter:ReferralModel.kt$ReferralModel${ analyticsEventHandler.send(ReferralEvents.ParticipateSuccessful) referralData.value = it } + MultilineLambdaItParameter:ReferralScreen.kt${ // TODO: use StateEvent if (stateHolder.errorSnackbar != null) { TangemSnackbar(data = it, actionOnNewLine = true) } else { CopiedTextSnackbar(it) } } + MultilineLambdaItParameter:ReferralScreen.kt${ ReferralContent( stateHolder = stateHolder, snackbarHostState = snackbarHostState, onAgreementClick = stateHolder.analytics.onAgreementClicked, modifier = Modifier.padding(it), ) } + NamedArguments:ReferralScreen.kt$Text( formatAwardConditionsString( quantity = award, network = networkName, address = if (!address.isNullOrBlank()) " $address" else "", ), color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier.testTag(ReferralProgramScreenTestTags.INFO_FOR_YOU_TEXT), ) + NonBooleanPropertyPrefixedWithIs:ParticipateBottomBlock.kt$val isExpanded = remember { mutableStateOf(false) } + NonBooleanPropertyPrefixedWithIs:ReferralModel.kt$ReferralModel$private val isDemoCardUseCase: IsDemoCardUseCase + SuspendFunSwallowedCancellation:ReferralModel.kt$ReferralModel$runCatching + UseOrEmpty:ReferralScreen.kt$matchResult.groups[1]?.value ?: "" + VarCouldBeVal:ReferralModel.kt$ReferralModel$private var referralData: MutableStateFlow<ReferralData?> = MutableStateFlow(null) + + diff --git a/features/send-v2/api/detekt-baseline-debug.xml b/features/send-v2/api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..6512d3e5ba --- /dev/null +++ b/features/send-v2/api/detekt-baseline-debug.xml @@ -0,0 +1,12 @@ + + + + + BooleanPropertyNaming:FeeSelectorData.kt$FeeSelectorData$val removeSuggestedFee: Boolean = false + BooleanPropertyNaming:SendEntryRoute.kt$SendEntryRoute.ChooseToken$val showSendViaSwapNotification: Boolean + NonBooleanPropertyPrefixedWithIs:SendDestinationComponentParams.kt$SendDestinationComponentParams.DestinationParams$val isBalanceHidingFlow: StateFlow<Boolean> + UseEmptyCounterpart:CommonSendAmountAnalyticEvents.kt$CommonSendAmountAnalyticEvents$mapOf() + UseEmptyCounterpart:CommonSendAnalyticEvents.kt$CommonSendAnalyticEvents$mapOf() + UseEmptyCounterpart:CommonSendFeeAnalyticEvents.kt$CommonSendFeeAnalyticEvents$mapOf() + + diff --git a/features/send-v2/impl/detekt-baseline-debug.xml b/features/send-v2/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..c88748c497 --- /dev/null +++ b/features/send-v2/impl/detekt-baseline-debug.xml @@ -0,0 +1,86 @@ + + + + + BooleanPropertyNaming:ConfirmUM.kt$ConfirmUM.Content$val showTapHelp: Boolean + BooleanPropertyNaming:FeeSelectorAlertFactory.kt$FeeSelectorAlertFactory$val showFeeTooHigh = checkAndShowFeeTooHigh(feeSelectorUM, onConfirmClick) + BooleanPropertyNaming:FeeSelectorAlertFactory.kt$FeeSelectorAlertFactory$val showFeeTooLow = checkAndShowFeeTooLow(feeSelectorUM, onConfirmClick) + BooleanPropertyNaming:FeeSelectorModalBottomSheet.kt$val lastItem = index == state.feeItems.size - 1 + BooleanPropertyNaming:FeeSelectorModalBottomSheet.kt$val showDivider = index != customFeeFields.size - 1 || nonce is FeeNonce.Nonce + BooleanPropertyNaming:NFTSendAnalyticEvents.kt$NFTSendAnalyticEvents.TransactionScreenOpened$val nonceNotEmpty: Boolean + BooleanPropertyNaming:NFTSendSuccessContent.kt$var visible by remember { mutableStateOf(false) } + BooleanPropertyNaming:SendAnalyticEvents.kt$SendAnalyticEvents.TransactionScreenOpened$val nonceNotEmpty: Boolean + BooleanPropertyNaming:SendAnalyticHelper.kt$SendAnalyticHelper$val blockchainAddressForEns = (sendUM.destinationUM as? DestinationUM.Content)?.addressTextField?.isAddressEns + BooleanPropertyNaming:SendConfirmSuccessContent.kt$var visible by remember { mutableStateOf(false) } + BooleanPropertyNaming:SendEntryPointModel.kt$SendEntryPointModel$val showSendViaSwapNotification = shouldShowNotificationUseCase( NotificationId.SendViaSwapTokenSelectorNotification.key, ) + BooleanPropertyNaming:SendRecipientHistoryListConverter.kt$SendRecipientHistoryListConverter$val notZero = !item.amount.isZero() + BooleanPropertyNaming:TapHelp.kt$var wrappedIsDisplay by remember { mutableStateOf(false) } + CanBeNonNullable:SendDestinationContent.kt$memoField: DestinationTextFieldUM.RecipientMemo? + CanBeNonNullable:SendDestinationModel.kt$SendDestinationModel$type: EnterAddressSource? + MaxChainedCallsOnSameLine:FeeSelectorBlockContent.kt$state.selectedFeeItem.fee.amount.value.format { crypto( symbol = state.selectedFeeItem.fee.amount.currencySymbol, decimals = state.selectedFeeItem.fee.amount.decimals, ).fee(canBeLower = state.feeExtraInfo.isFeeApproximate) } + MultilineLambdaItParameter:DefaultSellRedirectDeepLinkHandler.kt$DefaultSellRedirectDeepLinkHandler${ Timber.e("Error on getting cryptoCurrency: $it") return@launch } + MultilineLambdaItParameter:FeeSelectorCustomFieldConverter.kt$FeeSelectorCustomFieldConverter${ when (it) { is Fee.Kaspa -> kaspaCustomFeeConverter.tryAutoFixValue( minimumFee = it, customValues = customValues, ) else -> customValues } } + MultilineLambdaItParameter:FeeSelectorModel.kt$FeeSelectorModel${ feeSelectorAlertFactory.getFeeUpdatedAlert( newFee = it, feeSelectorUM = uiState.value, proceedAction = { modelScope.launch { feeSelectorCheckReloadTrigger.callbackCheckResult(true) } }, stopAction = { modelScope.launch { feeSelectorCheckReloadTrigger.callbackCheckResult(false) } }, ) } + MultilineLambdaItParameter:KaspaCustomFeeConverter.kt$KaspaCustomFeeConverter${ val valueDecimal = it.value.parseToBigDecimal(it.decimals) // krc-20 transaction will be failed if custom fee value is less than minimum, // so we set value to minimum in this case if (valueDecimal < minimumFee.amount.value) { val fixedValue = minimumFeeAmountValue.parseBigDecimal(it.decimals) set( FEE_AMOUNT_INDEX, it.copy( value = fixedValue, label = getFiatReference( rate = currencyStatus.fiatRate, value = valueDecimal, appCurrency = appCurrency, ), ), ) } } + MultilineLambdaItParameter:NFTSendConfirmModel.kt$NFTSendConfirmModel${ it.copy( confirmUM = NFTSendConfirmInitialStateTransformer( isShowTapHelp = isShowTapHelp, walletName = stringReference(userWallet.name), ).transform(uiState.value.confirmUM), ) } + MultilineLambdaItParameter:NFTSendConfirmModel.kt$NFTSendConfirmModel${ it.copy( confirmUM = NFTSendConfirmationNotificationsTransformerV2( feeSelectorUM = uiState.value.feeSelectorUM, analyticsEventHandler = analyticsEventHandler, cryptoCurrency = cryptoCurrencyStatus.currency, appCurrency = params.appCurrency, analyticsCategoryName = analyticsCategoryName, ).transform(uiState.value.confirmUM), ) } + MultilineLambdaItParameter:NFTSendConfirmModel.kt$NFTSendConfirmModel${ val confirmUM = it.confirmUM as? ConfirmUM.Content it.copy(confirmUM = confirmUM?.copy(showTapHelp = showTapHelp) ?: it.confirmUM) } + MultilineLambdaItParameter:NFTSendConfirmModel.kt$NFTSendConfirmModel${ val isFeeNotNull = it.feeSelectorUM is FeeSelectorUMRedesigned.Content it.copy( confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( isPrimaryButtonEnabled = !hasError && isFeeNotNull, ) ?: it.confirmUM, ) } + MultilineLambdaItParameter:RecentListUtils.kt${ add( DestinationRecipientListUM( id = "$tag$it", isLoading = false, isVisible = false, ), ) } + MultilineLambdaItParameter:RecentListUtils.kt${ add( DestinationRecipientListUM( id = "$tag$it", isLoading = true, ), ) } + MultilineLambdaItParameter:SendAmountModel.kt$SendAmountModel${ (it as? AmountState.Data)?.copy( isPrimaryButtonEnabled = false, ) ?: it } + MultilineLambdaItParameter:SendAmountModel.kt$SendAmountModel${ EnterAmountBoundary( amount = it, fiatRate = cryptoCurrencyStatus.value.fiatRate.orZero(), ) } + MultilineLambdaItParameter:SendConfirmModel.kt$SendConfirmModel${ it.copy( confirmUM = SendConfirmInitialStateTransformer( isShowTapHelp = isShowTapHelp, walletName = stringReference(userWallet.name), ).transform(uiState.value.confirmUM), confirmData = confirmData, ) } + MultilineLambdaItParameter:SendConfirmModel.kt$SendConfirmModel${ it.copy( confirmUM = SendConfirmationNotificationsTransformerV2( feeSelectorUM = uiState.value.feeSelectorUM, amountUM = uiState.value.amountUM, analyticsEventHandler = analyticsEventHandler, cryptoCurrency = cryptoCurrencyStatus.currency, appCurrency = appCurrency, analyticsCategoryName = params.analyticsCategoryName, ).transform(uiState.value.confirmUM), ) } + MultilineLambdaItParameter:SendConfirmModel.kt$SendConfirmModel${ val confirmUM = it.confirmUM as? ConfirmUM.Content it.copy(confirmUM = confirmUM?.copy(showTapHelp = showTapHelp) ?: it.confirmUM) } + MultilineLambdaItParameter:SendConfirmModel.kt$SendConfirmModel${ val feeUM = it.feeSelectorUM as? FeeSelectorUMRedesigned.Content it.copy( confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( isPrimaryButtonEnabled = !hasError && feeUM != null, ) ?: it.confirmUM, ) } + MultilineLambdaItParameter:SendDestinationContent.kt${ if (it) { content() } else { Box(modifier = Modifier.fillMaxWidth()) } } + MultilineLambdaItParameter:SendDestinationModel.kt$SendDestinationModel${ analyticsEventHandler.send( SendDestinationAnalyticEvents.AddressEntered( categoryName = analyticsCategoryName, source = params.analyticsSendSource, method = it, isValid = addressValidationResult.isRight(), ), ) } + MultilineLambdaItParameter:SendDestinationModel.kt$SendDestinationModel${ if (it.network.rawId == cryptoCurrencyNetwork.rawId) { getNetworkAddressesUseCase.invokeSync( userWalletId = wallet.walletId, networkRawId = it.network.id.rawId, ) } else { null } } + MultilineLambdaItParameter:SendDestinationValidationResultTransformer.kt$SendDestinationValidationResultTransformer${ when (it) { is AddressValidation.Error.DataError, AddressValidation.Error.InvalidAddress, -> R.string.send_recipient_address_error AddressValidation.Error.AddressInWallet -> R.string.send_error_address_same_as_wallet } } + MultilineLambdaItParameter:SendModel.kt$SendModel${ Timber.w(it.toString()) showAlertError() return@launch } + MultilineLambdaItParameter:SendModel.kt$SendModel${ it.copy( destinationUM = SendDestinationInitialStateTransformer( cryptoCurrency = cryptoCurrency, ).transform(DestinationUM.Empty()), feeSelectorUM = FeeSelectorUM.Loading, confirmUM = ConfirmUM.Empty, confirmData = null, navigationUM = NavigationUM.Empty, ) } + MultilineLambdaItParameter:SendRecipientWalletListConverter.kt$SendRecipientWalletListConverter${ val isCoin = it.cryptoCurrency is CryptoCurrency.Coin val isNotSameAddress = it.address != senderAddress val isNotBlankAddress = it.address.isNotBlank() isNotBlankAddress && isCoin && (isNotSameAddress || isSelfSendAvailable) } + NamedArguments:EthereumCustomFeeConverter.kt$EthereumCustomFeeConverter$onValueChange(feeValue, customValues, index, value) + NamedArguments:FeeSelectorCustomValueChangedTransformer.kt$FeeSelectorCustomValueChangedTransformer$onValueChange(state, customFee.customValues, index, value) + NestedScopeFunctions:KaspaCustomFeeConverter.kt$KaspaCustomFeeConverter$let { val valueDecimal = it.value.parseToBigDecimal(it.decimals) // krc-20 transaction will be failed if custom fee value is less than minimum, // so we set value to minimum in this case if (valueDecimal < minimumFee.amount.value) { val fixedValue = minimumFeeAmountValue.parseBigDecimal(it.decimals) set( FEE_AMOUNT_INDEX, it.copy( value = fixedValue, label = getFiatReference( rate = currencyStatus.fiatRate, value = valueDecimal, appCurrency = appCurrency, ), ), ) } } + NoNameShadowing:FeeSelectorAlertFactory.kt$FeeSelectorAlertFactory$newFee + NoNameShadowing:SendContent.kt$navigationUM + NonBooleanPropertyPrefixedWithIs:FeeSelectorModel.kt$FeeSelectorModel$private val isFeeApproximateUseCase: IsFeeApproximateUseCase + NonBooleanPropertyPrefixedWithIs:NFTSendConfirmComponent.kt$NFTSendConfirmComponent.Params$val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:NFTSendConfirmModel.kt$NFTSendConfirmModel$private val isSendTapHelpEnabledUseCase: IsSendTapHelpEnabledUseCase + NonBooleanPropertyPrefixedWithIs:NFTSendModel.kt$NFTSendModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:NFTSendModel.kt$NFTSendModel$val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:NotificationsModel.kt$NotificationsModel$private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams$abstract val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams$abstract val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams.AmountBlockParams$override val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams.AmountBlockParams$override val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams.AmountParams$override val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountComponentParams.kt$SendAmountComponentParams.AmountParams$override val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendAmountModel.kt$SendAmountModel$val isSendWithSwapAvailable: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:SendConfirmComponent.kt$SendConfirmComponent.Params$val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendConfirmComponent.kt$SendConfirmComponent.Params$val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendConfirmModel.kt$SendConfirmModel$private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase + NonBooleanPropertyPrefixedWithIs:SendConfirmModel.kt$SendConfirmModel$private val isSendTapHelpEnabledUseCase: IsSendTapHelpEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SendConfirmModel.kt$SendConfirmModel$val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:SendDestinationModel.kt$SendDestinationModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SendDestinationModel.kt$SendDestinationModel$private val isSelfSendAvailableUseCase: IsSelfSendAvailableUseCase + NonBooleanPropertyPrefixedWithIs:SendModel.kt$SendModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SendModel.kt$SendModel$val isAccountModeFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:SendModel.kt$SendModel$val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NullCheckOnMutableProperty:SendAmountModel.kt$SendAmountModel$if (uiState.value is AmountState.Empty && userWallet != null) { val isOnlyOneWallet = getWalletsUseCase.invokeSync().size == 1 val walletTitle = if (isOnlyOneWallet) { resourceReference(R.string.send_from_title) } else { resourceReference( R.string.send_from_wallet_name, WrappedList(listOf(userWallet?.name.orEmpty())), // TODO AND-11440 ) } _uiState.update { AmountStateConverter( clickIntents = this, appCurrency = appCurrency, cryptoCurrencyStatus = cryptoCurrencyStatus, maxEnterAmount = maxAmountBoundary, iconStateConverter = CryptoCurrencyToIconStateConverter(), isBalanceHidden = params.isBalanceHidingFlow.value, accountTitleUM = AmountAccountConverter( isAccountsMode = isAccountsMode, walletTitle = walletTitle, prefixText = resourceReference(R.string.common_from), ).convert(account), ).convert( AmountParameters( title = walletTitle, value = "", ), ) } } + NullableToStringCall:BitcoinCustomFeeConverter.kt$BitcoinCustomFeeConverter$toSatoshiPerByte( amount = feeValue, decimals = value.amount.decimals, txSize = value.txSize, ).toString() + NullableToStringCall:NFTSendConfirmModel.kt$NFTSendConfirmModel$params.nftAsset.amount.toString() + ReusedModifierInstance:DefaultSendEntryPointComponent.kt$DefaultSendEntryPointComponent$Content(modifier.fillMaxSize()) + UnnecessaryLet:EthereumCustomFeeConverter.kt$EthereumCustomFeeConverter$let(::add) + UnnecessaryLet:EthereumCustomFeeConverter.kt$EthereumCustomFeeConverter$let(::addAll) + UnnecessaryLet:SendAmountModel.kt$SendAmountModel$let { onCurrencyChangeClick(isEnterInFiat) } + UseEmptyCounterpart:NFTSendAnalyticEvents.kt$NFTSendAnalyticEvents$mapOf() + UseEmptyCounterpart:NotificationsAnalyticEvents.kt$NotificationsAnalyticEvents$mapOf() + UseEmptyCounterpart:SendAnalyticEvents.kt$SendAnalyticEvents$mapOf() + UseEmptyCounterpart:SendDestinationAnalyticEvents.kt$SendDestinationAnalyticEvents$mapOf() + VarCouldBeVal:SendDestinationModel.kt$SendDestinationModel$private var validationJobHolder = JobHolder() + VarCouldBeVal:SendModel.kt$SendModel$private var balanceHidingJobHolder = JobHolder() + + diff --git a/features/staking/impl/detekt-baseline-debug.xml b/features/staking/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..920a160906 --- /dev/null +++ b/features/staking/impl/detekt-baseline-debug.xml @@ -0,0 +1,62 @@ + + + + + BooleanPropertyNaming:AddStakingNotificationsTransformer.kt$AddStakingNotificationsTransformer$val showNotification = sendingAmount + feeAmount > balance + BooleanPropertyNaming:AmountCurrencyChangeStateTransformer.kt$AmountCurrencyChangeStateTransformer$private val value: Boolean + BooleanPropertyNaming:StakingModel.kt$StakingModel$val noBalanceState = balanceState == null + BooleanPropertyNaming:StakingModel.kt$StakingModel$val noYieldBalanceData = cryptoCurrencyStatus.value.yieldBalance !is YieldBalance.Data + BooleanPropertyNaming:StakingUiState.kt$StakingStates.InitialInfoState.Data$val showBanner: Boolean + BooleanPropertyNaming:StakingUiState.kt$StakingUiState$val showColdWalletInteractionIcon: Boolean + CanBeNonNullable:StakingScreen.kt$bottomSheetConfig: TangemBottomSheetConfig? + CastNullableToNonNullableType:SetApprovalBottomSheetInProgressTransformer.kt$SetApprovalBottomSheetInProgressTransformer$as + CastNullableToNonNullableType:SetApprovalBottomSheetTypeChangeTransformer.kt$SetApprovalBottomSheetTypeChangeTransformer$as + MultilineLambdaItParameter:AddStakingNotificationsTransformer.kt$AddStakingNotificationsTransformer${ it is StakingNotification.Error || it is NotificationUM.Error || it is NotificationUM.Warning.NetworkFeeUnreachable || it is StakingNotification.Warning.TransactionInProgress || it is StakingNotification.Warning.InitializeTonAccount } + MultilineLambdaItParameter:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler${ val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true) val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true isNetwork && isCurrency } + MultilineLambdaItParameter:StakingFeeBlock.kt${ if (it == FeeState.Error) { Text( text = DASH_SIGN, color = TangemTheme.colors.text.primary1, style = TangemTheme.typography.body1, ) } } + MultilineLambdaItParameter:StakingFeeBlock.kt${ if (it == FeeState.Loading) { RectangleShimmer( radius = TangemTheme.dimens.radius3, modifier = Modifier.size( height = TangemTheme.dimens.size24, width = TangemTheme.dimens.size90, ), ) } } + MultilineLambdaItParameter:StakingFeeTransactionLoader.kt$StakingFeeTransactionLoader${ onStakingFeeError(it) null } + MultilineLambdaItParameter:StakingFeeTransactionLoader.kt$StakingFeeTransactionLoader${ onStakingFeeError(it) return } + MultilineLambdaItParameter:StakingInfoNotificationsFactory.kt$StakingInfoNotificationsFactory${ it.type == BalanceType.PREPARING || it.type == BalanceType.STAKED || it.type == BalanceType.LOCKED } + MultilineLambdaItParameter:StakingInfoNotificationsFactory.kt$StakingInfoNotificationsFactory${ it.type == BalanceType.STAKED || it.type == BalanceType.PREPARING || it.type == BalanceType.UNSTAKED } + MultilineLambdaItParameter:StakingModel.kt$StakingModel${ EnterAmountBoundary( amount = it, fiatRate = status.value.fiatRate.orZero(), ) } + MultilineLambdaItParameter:StakingModel.kt$StakingModel${ Timber.e(it) false } + MultilineLambdaItParameter:StakingModel.kt$StakingModel${ isBalanceHiddenFlow.value = it.isBalanceHidden stateController.update( transformer = HideBalanceStateTransformer( isBalanceHidden = it.isBalanceHidden, cryptoCurrencyStatus = cryptoCurrencyStatus, appCurrency = appCurrency, ), ) } + MultilineLambdaItParameter:StakingModel.kt$StakingModel${ stateController.update( SetFeeToTonInitializeBottomSheetTransformer( appCurrencyProvider = Provider { appCurrency }, feeCryptoCurrencyStatus = feeCryptoCurrencyStatus, fee = it.normal, isFeeApproximate = false, ), ) } + MultilineLambdaItParameter:StakingStateController.kt$StakingStateController${ it.copy( showColdWalletInteractionIcon = userWallet is UserWallet.Cold, ) } + MultilineLambdaItParameter:StakingTransactionSender.kt$StakingTransactionSender${ onConstructError(it) null } + MultilineLambdaItParameter:StakingTransactionSender.kt$StakingTransactionSender${ onConstructError(it) return emptyList() } + NoNameShadowing:StakingFeeTransactionLoader.kt$StakingFeeTransactionLoader$amount + NoNameShadowing:StakingFeeTransactionLoader.kt$StakingFeeTransactionLoader${ if (!it.amount.isZero()) return feeResult } + NonBooleanPropertyPrefixedWithIs:AddStakingNotificationsTransformer.kt$AddStakingNotificationsTransformer$private val isAccountInitializedProvider: Provider<Boolean> + NonBooleanPropertyPrefixedWithIs:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler$val isStakingEnabled = getStakingAvailabilityUseCase.invokeSync( userWalletId = selectedUserWalletId, cryptoCurrency = cryptoCurrency, ).getOrNull() + NonBooleanPropertyPrefixedWithIs:StakingFeeTransactionLoader.kt$StakingFeeTransactionLoader$private val isFeeApproximateUseCase: IsFeeApproximateUseCase + NonBooleanPropertyPrefixedWithIs:StakingModel.kt$StakingModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:StakingModel.kt$StakingModel$private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase + NonBooleanPropertyPrefixedWithIs:StakingModel.kt$StakingModel$private val isAnyTokenStakedUseCase: IsAnyTokenStakedUseCase + NonBooleanPropertyPrefixedWithIs:StakingModel.kt$StakingModel$private val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:StakingTransactionSender.kt$StakingTransactionSender$private val isFeeApproximateUseCase: IsFeeApproximateUseCase + NullCheckOnMutableProperty:StakingModel.kt$StakingModel$if (feeCryptoCurrencyStatus != null && fee != null) { getBalanceNotEnoughForFeeWarningUseCase( fee = fee, userWalletId = userWalletId, tokenStatus = cryptoCurrencyStatus, coinStatus = feeCryptoCurrencyStatus ?: cryptoCurrencyStatus, ).getOrNull() } else { null } + NullableToStringCall:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler$$networkId + NullableToStringCall:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler$$tokenId + PropertyUsedBeforeDeclaration:StakingFeeBlock.kt$FeeBlockPreviewProvider$contentState + PropertyUsedBeforeDeclaration:StakingModel.kt$StakingModel$isAmountSubtractAvailable + PropertyUsedBeforeDeclaration:StakingStateController.kt$StakingStateController$uiState + ReusedModifierInstance:StakingClaimRewardsValidatorContent.kt$InputRowImageInfo( subtitle = item.title, caption = item.getAprTextNeutral(), infoTitle = item.formattedFiatAmount, infoSubtitle = item.formattedCryptoAmount, imageUrl = item.validator?.image.orEmpty(), onImageError = { ValidatorImagePlaceholder() }, modifier = modifier .roundedShapeItemDecoration(index, state.rewards.lastIndex, false) .background(TangemTheme.colors.background.action) .clickable( enabled = item.pendingActions.isNotEmpty(), onClick = { clickIntents.onActiveStake(item) }, ), ) + SuspendFunSwallowedCancellation:StakingModel.kt$StakingModel$runCatching + UnnecessaryEventHandlerParameter:StakingInitialInfoContent.kt$onClick: (BalanceState) -> Unit + UnnecessaryFilter:StakingInfoNotificationsFactory.kt$StakingInfoNotificationsFactory$filter { it.validator?.address == validatorAddress } + UnnecessaryLet:StakingModel.kt$StakingModel$let(::add) + UnnecessaryLet:StakingTosText.kt$let { onTextClick(PRIVACY_POLICY_URL) } + UnnecessaryLet:StakingTosText.kt$let { onTextClick(TERMS_OF_USE_URL) } + UnsafeCallOnNullableType:StakingModel.kt$StakingModel$tonAccountInitializeTransaction!! + UseOrEmpty:StakingModel.kt$StakingModel$yieldBalance?.balance?.items ?: emptyList() + UseOrEmpty:StakingTransactionSender.kt$StakingTransactionSender$getExplorerTransactionUrlUseCase( txHash = transactionHashes.last(), networkId = cryptoCurrencyStatus.currency.network.id, ).getOrNull() ?: "" + VarCouldBeVal:StakingModel.kt$StakingModel$private var actionsJobHolder: JobHolder = JobHolder() + VarCouldBeVal:StakingModel.kt$StakingModel$private var approvalJobHolder: JobHolder = JobHolder() + VarCouldBeVal:StakingModel.kt$StakingModel$private var feeJobHolder: JobHolder = JobHolder() + VarCouldBeVal:StakingModel.kt$StakingModel$private var sendTransactionJobHolder = JobHolder() + VarCouldBeVal:StakingModel.kt$StakingModel$private var stakingStateRouter: StakingStateRouter = StakingStateRouter( appRouter = appRouter, stateController = stateController, analyticsEventsHandler = analyticsEventHandler, ) + VarCouldBeVal:StakingModel.kt$StakingModel$private var stepChangesJobHolder = JobHolder() + + diff --git a/features/stories/impl/detekt-baseline-debug.xml b/features/stories/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..15299582b8 --- /dev/null +++ b/features/stories/impl/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + PropertyUsedBeforeDeclaration:StoriesModel.kt$StoriesModel$_state + UseEmptyCounterpart:StoriesEvents.kt$StoriesEvents$mapOf() + + diff --git a/features/swap-v2/impl/detekt-baseline-debug.xml b/features/swap-v2/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..3bc57815b3 --- /dev/null +++ b/features/swap-v2/impl/detekt-baseline-debug.xml @@ -0,0 +1,59 @@ + + + + + BooleanPropertyNaming:ConfirmUM.kt$ConfirmUM.Content$val showTapHelp: Boolean + BooleanPropertyNaming:SwapAmountModel.kt$SwapAmountModel$private var showBestRateAnimation: Boolean = false + BooleanPropertyNaming:SwapAmountModel.kt$SwapAmountModel$val showSendViaSwapNotification = shouldShowNotificationUseCase( NotificationId.SendViaSwapTokenSelectorNotification.key, ) + BooleanPropertyNaming:SwapAmountPrimaryReadyStateTransformer.kt$SwapAmountPrimaryReadyStateTransformer$private val showBestRateAnimation: Boolean + BooleanPropertyNaming:SwapAmountSecondaryReadyStateTransformer.kt$SwapAmountSecondaryReadyStateTransformer$private val showBestRateAnimation: Boolean + BooleanPropertyNaming:SwapAmountSelectQuoteTransformer.kt$SwapAmountSelectQuoteTransformer$private val needApplyFCARestrictions: Boolean + BooleanPropertyNaming:SwapAmountSetQuotesTransformer.kt$SwapAmountSetQuotesTransformer$private val needApplyFcaRestrictions: Boolean + BooleanPropertyNaming:SwapAmountUM.kt$SwapAmountUM.Content$val showBestRateAnimation: Boolean + BooleanPropertyNaming:SwapAmountUM.kt$SwapAmountUM.Content$val showFCAWarning: Boolean + BooleanPropertyNaming:SwapChooseProviderModel.kt$SwapChooseProviderModel$private val needApplyFCARestrictions = params.userCountry.needApplyFCARestrictions() + BooleanPropertyNaming:SwapProviderListItemConverter.kt$SwapProviderListItemConverter$private val needApplyFCARestrictions: Boolean + BooleanPropertyNaming:SwapProviderStateConverter.kt$SwapProviderStateConverter$private val needApplyFCARestrictions: Boolean + CouldBeSequence:SwapAmountModel.kt$SwapAmountModel$filter { it.currencyStatus.currency.id == toCryptoCurrency.id } + MaxChainedCallsOnSameLine:SwapAlertFactory.kt$SwapAlertFactory$confirmData?.fee?.amount?.value?.toString().orEmpty() + MultilineLambdaItParameter:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel${ it.copy( confirmUM = SendWithSwapConfirmInitialStateTransformer( isShowTapHelp = isShowTapHelp, ).transform(uiState.value.confirmUM), ) } + MultilineLambdaItParameter:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel${ val confirmUM = it.confirmUM as? ConfirmUM.Content it.copy(confirmUM = confirmUM?.copy(showTapHelp = showTapHelp) ?: it.confirmUM) } + MultilineLambdaItParameter:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel${ val feeUM = it.feeSelectorUM as? FeeSelectorUM.Content it.copy( confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( isPrimaryButtonEnabled = !hasError && feeUM != null, ) ?: it.confirmUM, ) } + MultilineLambdaItParameter:SendWithSwapConfirmationNotificationsTransformer.kt$SendWithSwapConfirmationNotificationsTransformer${ ConfirmUM.Content.LegalUM( title = resourceReference(R.string.common_privacy_policy), link = it, ) } + MultilineLambdaItParameter:SendWithSwapConfirmationNotificationsTransformer.kt$SendWithSwapConfirmationNotificationsTransformer${ ConfirmUM.Content.LegalUM( title = resourceReference(R.string.common_terms_of_use), link = it, ) } + MultilineLambdaItParameter:SendWithSwapModel.kt$SendWithSwapModel${ Timber.w(it.toString()) swapAlertFactory.getGenericErrorState( expressError = ExpressError.UnknownError, onFailedTxEmailClick = { modelScope.launch { swapAlertFactory.onFailedTxEmailClick( userWallet = userWallet, cryptoCurrency = params.currency, errorMessage = it.toString(), ) } }, popBack = ::onBackClick, ) } + MultilineLambdaItParameter:SendWithSwapModel.kt$SendWithSwapModel${ it.copy( destinationUM = DestinationUM.Empty(), feeSelectorUM = FeeSelectorUM.Loading, confirmUM = ConfirmUM.Empty, navigationUM = NavigationUM.Empty, ) } + MultilineLambdaItParameter:SwapAmountSetQuotesTransformer.kt$SwapAmountSetQuotesTransformer${ it is SwapQuoteUM.Content || it is SwapQuoteUM.Allowance || (it as? SwapQuoteUM.Error)?.expressError is ExpressError.AmountError } + MultilineLambdaItParameter:SwapChooseProviderModel.kt$SwapChooseProviderModel${ it is SwapQuoteUM.Content || it is SwapQuoteUM.Allowance || (it as? SwapQuoteUM.Error)?.expressError is ExpressError.AmountError } + MultilineLambdaItParameter:SwapChooseTokenNetworkModel.kt$SwapChooseTokenNetworkModel${ Timber.e("Failed to get user wallet: $it") swapChooseTokenAlertFactory.getGenericErrorState(params.onDismiss) return } + MultilineLambdaItParameter:SwapChooseTokenNetworkModel.kt$SwapChooseTokenNetworkModel${ Timber.e(it.toString()) uiState.update( SwapChooseErrorStateTransformer( tokenName = params.token.name, onDismiss = params.onDismiss, ), ) return@launch } + MultilineLambdaItParameter:SwapTransactionSender.kt$SwapTransactionSender${ Timber.e(it, "Failed to create swap CEX tx data") onSendError(SendTransactionError.UnknownError(Exception(it))) return } + MultilineLambdaItParameter:SwapTransactionSender.kt$SwapTransactionSender${ onExpressError(it); return } + NamedArguments:SwapTransactionSender.kt$SwapTransactionSender$getSwapDataUseCase( userWallet = userWallet, fromCryptoCurrencyStatus = fromStatus, fromAmount = fromAmount.toStringWithRightOffset(fromStatus.currency.decimals), toCryptoCurrency = toStatus.currency, toAddress = destination, expressProvider = provider, rateType = rateType, expressOperationType, ) + NoNameShadowing:SendWithSwapContent.kt$navigationUM + NoNameShadowing:SwapAmountContent.kt$amountFieldUM + NonBooleanPropertyPrefixedWithIs:SendWithSwapConfirmComponent.kt$SendWithSwapConfirmComponent.Params$val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendWithSwapConfirmComponent.kt$SendWithSwapConfirmComponent.Params$val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel$private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase + NonBooleanPropertyPrefixedWithIs:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel$private val isSendTapHelpEnabledUseCase: IsSendTapHelpEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SendWithSwapModel.kt$SendWithSwapModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:SendWithSwapModel.kt$SendWithSwapModel$val isAccountModeFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:SendWithSwapModel.kt$SendWithSwapModel$val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams$abstract val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams$abstract val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams.AmountBlockParams$override val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams.AmountBlockParams$override val isBalanceHidingFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams.AmountParams$override val isAccountModeFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapAmountComponentParams.kt$SwapAmountComponentParams.AmountParams$override val isBalanceHidingFlow: StateFlow<Boolean> + NullableToStringCall:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel$error.toString() + NullableToStringCall:SwapAmountModel.kt$SwapAmountModel$$primaryStatus + NullableToStringCall:SwapAmountModel.kt$SwapAmountModel$$secondaryStatus + PropertyUsedBeforeDeclaration:SendWithSwapConfirmModel.kt$SendWithSwapConfirmModel$amountUM + UnnecessaryEventHandlerParameter:SwapAmountContent.kt$onExpandEditField: (SwapAmountType) -> Unit + UseEmptyCounterpart:SendWithSwapAnalyticEvents.kt$SendWithSwapAnalyticEvents$mapOf() + UseEmptyCounterpart:SendWithSwapSuccessContent.kt$listOf() + UseEmptyCounterpart:SwapAmountAnalyticEvents.kt$SwapAmountAnalyticEvents$mapOf() + VarCouldBeVal:SwapAmountModel.kt$SwapAmountModel$private var primaryCryptoCurrency: CryptoCurrency = params.primaryCryptoCurrencyStatusFlow.value.currency + VarCouldBeVal:SwapAmountModel.kt$SwapAmountModel$private var userWallet = params.userWallet + + diff --git a/features/swap/data/detekt-baseline-debug.xml b/features/swap/data/detekt-baseline-debug.xml new file mode 100644 index 0000000000..640fd2fbc1 --- /dev/null +++ b/features/swap/data/detekt-baseline-debug.xml @@ -0,0 +1,21 @@ + + + + + BooleanPropertyNaming:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository$val fromCurrency = it.fromCryptoCurrencyId == cryptoCurrencyId.value + BooleanPropertyNaming:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository$val toCurrency = it.toCryptoCurrencyId == cryptoCurrencyId.value + MultilineLambdaItParameter:DefaultSwapRepository.kt$DefaultSwapRepository${ Timber.e("getExchangeStatus error: $it") raise(UnknownError(it.message)) } + MultilineLambdaItParameter:DefaultSwapRepository.kt$DefaultSwapRepository${ val requirements = walletManagersFacade.getAssetRequirements(userWallet.walletId, it) val isAvailableForSwap = rampStateManager.checkAssetRequirements(requirements) isAvailableForSwap } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ converter.convertBack( value = it, userWallet = userWallet, accountList = accountList, txStatuses = txStatuses, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ converter.convertBack( value = it, userWallet = userWallet, accountList = accountList, txStatuses = txStatuses, onFilter = { it.swapTxTypeDTO == SwapTxTypeDTO.Swap }, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.checkId( checkUserWalletId = userWalletId, fromCurrencyId = fromCryptoCurrency.id, toCurrencyId = toCryptoCurrency.id, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ storeTransactionState( txId = transaction.txId, status = it, accountWithCurrency = null, ) } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ val isUserWallet = it.userWalletId == userWallet.walletId.stringValue val fromCurrency = it.fromCryptoCurrencyId == cryptoCurrencyId.value isUserWallet && fromCurrency } + MultilineLambdaItParameter:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ val isUserWallet = it.userWalletId == userWallet.walletId.stringValue val toCurrency = it.toCryptoCurrencyId == cryptoCurrencyId.value isUserWallet && toCurrency } + MultilineLambdaItParameter:ExpressDataConverter.kt$ExpressDataConverter${ if (it == "0") { BigDecimal.ZERO } else { requireNotNull(it.toBigDecimalOrNull()) { "wrong amount format, use only digits" } } } + NoNameShadowing:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.swapTxTypeDTO == SwapTxTypeDTO.Swap } + NoNameShadowing:DefaultSwapTransactionRepository.kt$DefaultSwapTransactionRepository${ it.txId == txId } + UseOrEmpty:DefaultSwapRepository.kt$DefaultSwapRepository$ex.errorBody ?: "" + UseOrEmpty:DefaultSwapRepository.kt$DefaultSwapRepository$exception.errorBody ?: "" + + diff --git a/features/swap/domain/detekt-baseline-debug.xml b/features/swap/domain/detekt-baseline-debug.xml new file mode 100644 index 0000000000..02326b7307 --- /dev/null +++ b/features/swap/domain/detekt-baseline-debug.xml @@ -0,0 +1,33 @@ + + + + + BooleanPropertyNaming:SwapInteractorImpl.kt$SwapInteractorImpl$val allQuotesFound = cachedQuotes?.all { it.value !is QuoteStatus.Empty } == true + BooleanPropertyNaming:SwapInteractorImpl.kt$SwapInteractorImpl$val currencyFilter = it.currency.network.backendId != currency.network.backendId || it.currency.getContractAddress() != currency.getContractAddress() + BooleanPropertyNaming:SwapInteractorImpl.kt$SwapInteractorImpl$val notCustomTokenFilter = !it.currency.isCustom + BooleanPropertyNaming:SwapInteractorImpl.kt$SwapInteractorImpl$val statusFilter = it.value is CryptoCurrencyStatus.Loaded || it.value is CryptoCurrencyStatus.NoAccount + CanBeNonNullable:SwapInteractorImpl.kt$SwapInteractorImpl$spenderAddress: String? + MaxChainedCallsOnSameLine:SwapInteractorImpl.kt$SwapInteractorImpl$currencyToGet.value.networkAddress?.defaultAddress?.value.orEmpty() + MaxChainedCallsOnSameLine:SwapInteractorImpl.kt$SwapInteractorImpl$currencyToSend.value.networkAddress?.defaultAddress?.value.orEmpty() + MaxChainedCallsOnSameLine:SwapInteractorImpl.kt$SwapInteractorImpl$currencyToSendStatus.value.networkAddress?.defaultAddress?.value.orEmpty() + MaxChainedCallsOnSameLine:SwapInteractorImpl.kt$SwapInteractorImpl$fromToken.value.networkAddress?.defaultAddress?.value.orEmpty() + MaxChainedCallsOnSameLine:SwapInteractorImpl.kt$SwapInteractorImpl$toToken.value.networkAddress?.defaultAddress?.value.orEmpty() + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ Timber.e(it, "Failed to create approveTransaction") return SwapTransactionState.Error.UnknownError } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ Timber.e(it, "Failed to create swap CEX tx data") return SwapTransactionState.Error.UnknownError } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ Timber.e(it, "Failed to create swap dex tx data") return SwapTransactionState.Error.UnknownError } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ it.contractAddress.equals(feePaidCurrency.contractAddress, ignoreCase = true) && it.network.derivationPath == fromTokenStatus.currency.network.derivationPath } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ tokenInfoForFilter(it).contractAddress == currency.getContractAddress() && tokenInfoForFilter(it).network == currency.network.backendId } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ val currencyFilter = it.currency.network.backendId != currency.network.backendId || it.currency.getContractAddress() != currency.getContractAddress() val statusFilter = it.value is CryptoCurrencyStatus.Loaded || it.value is CryptoCurrencyStatus.NoAccount val notCustomTokenFilter = !it.currency.isCustom statusFilter && currencyFilter && notCustomTokenFilter } + MultilineLambdaItParameter:SwapInteractorImpl.kt$SwapInteractorImpl${ val listTokenInfo = tokenInfoForAvailable(it) if (cryptoCurrencyStatuses.currency.network.backendId == listTokenInfo.network && cryptoCurrencyStatuses.currency.getContractAddress() == listTokenInfo.contractAddress && isAvailableForSwap ) { it.providers } else { null } } + NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$getCoinBalanceAfterTransaction(fromTokenStatus, amount, includeFeeInAmount, fee) + NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$isAllowedToSpend(networkId, fromToken.currency, amount, it) + NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$tryGetFromCache(userWallet, initialCryptoCurrency, state, isReverseFromTo) + NamedArguments:SwapInteractorImpl.kt$SwapInteractorImpl$tryGetFromCacheV2(userWallet, initialCryptoCurrency, state, isReverseFromTo) + NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl$account + NoNameShadowing:SwapInteractorImpl.kt$SwapInteractorImpl${ it.isAvailable } + NonBooleanPropertyPrefixedWithIs:SwapInteractorImpl.kt$SwapInteractorImpl$private val isDemoCardUseCase: IsDemoCardUseCase + NullableToStringCall:SwapInteractorImpl.kt$SwapInteractorImpl$$swapData + NullableToStringCall:SwapInteractorImpl.kt$SwapInteractorImpl$${e.message} + SuspendFunSwallowedCancellation:SwapInteractorImpl.kt$SwapInteractorImpl$runCatching + + diff --git a/features/swap/domain/models/detekt-baseline-debug.xml b/features/swap/domain/models/detekt-baseline-debug.xml new file mode 100644 index 0000000000..04b765b070 --- /dev/null +++ b/features/swap/domain/models/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + NamedArguments:TokensDataStateExpress.kt$TokensDataStateExpress.Companion$CurrenciesGroup(emptyList(), emptyList(), emptyList(), false) + NullableBooleanCheck:ExchangeStatus.kt$ExchangeStatusModel$createdAt?.isBefore(DateTime.now().minusMinutes(FIFTEEN_MINUTES)) ?: false + + diff --git a/features/swap/impl/detekt-baseline-debug.xml b/features/swap/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..e7ed3b9972 --- /dev/null +++ b/features/swap/impl/detekt-baseline-debug.xml @@ -0,0 +1,79 @@ + + + + + BooleanPropertyNaming:ChooseFeeBottomSheet.kt$val showDivider = content.feeItems.lastIndex != index + BooleanPropertyNaming:SwapEvents.kt$SwapEvents.ChooseTokenScreenOpened$val availableTokens: Boolean + BooleanPropertyNaming:SwapEvents.kt$SwapEvents.ChooseTokenScreenResult$val tokenChosen: Boolean + BooleanPropertyNaming:SwapNotificationsFactory.kt$SwapNotificationsFactory$val needShowCoverWarning = quoteModel.preparedSwapConfigState.isBalanceEnough && quoteModel.permissionState !is PermissionDataState.PermissionLoading && feeEnoughState.feeCurrency != fromToken + BooleanPropertyNaming:SwapSelectTokenStateHolder.kt$SwapSelectTokenStateHolder$val afterSearch: Boolean + BooleanPropertyNaming:SwapSelectTokenStateHolder.kt$TokenToSelectState.TokenToSelect$val available: Boolean = true + BooleanPropertyNaming:SwapStateHolder.kt$SwapButton$val enabled: Boolean + BooleanPropertyNaming:SwapStateHolder.kt$TransactionCardType.ReadOnly$val showWarning: Boolean = false + BooleanPropertyNaming:SwapSuccessStateHolder.kt$SwapSuccessStateHolder$val showStatusButton: Boolean + CastNullableToNonNullableType:SwapModel.kt$SwapModel$as + MaxChainedCallsOnSameLine:SwapModel.kt$SwapModel$it.value.toTokenInfo.cryptoCurrencyStatus.currency.decimals + MaxChainedCallsOnSameLine:SwapNotificationsFactory.kt$SwapNotificationsFactory$quoteModel.fromTokenInfo.cryptoCurrencyStatus.currency.network.currencySymbol + MultilineLambdaItParameter:AccountTokenItemConverter.kt$AccountTokenItemConverter${ TokenItemState.TitleState.Content( text = stringReference(value = it.currency.name), isAvailable = false, ) } + MultilineLambdaItParameter:AccountTokenItemConverter.kt$AccountTokenItemConverter${ createSubtitleState( status = it, isAvailable = false, text = unavailableErrorText, ) } + MultilineLambdaItParameter:AccountTokenItemConverter.kt$AccountTokenItemConverter${ createSubtitleState( status = it, isAvailable = true, text = stringReference(value = it.currency.symbol), ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = if (it > 0) "+$it%" else "$it%", style = TangemTheme.typography.body2, color = textColor, modifier = Modifier.padding(start = TangemTheme.dimens.spacing4), overflow = TextOverflow.Ellipsis, maxLines = 1, ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = it, style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.primary1, ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = it, style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = it, style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, modifier = Modifier.padding(start = TangemTheme.dimens.spacing4), ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = it.resolveReference(), style = TangemTheme.typography.body2, color = TangemTheme.colors.text.tertiary, modifier = Modifier.padding(top = TangemTheme.dimens.spacing6), ) } + MultilineLambdaItParameter:ProviderItem.kt${ Text( text = it.resolveReference(), style = TangemTheme.typography.body2, color = TangemTheme.colors.text.tertiary, overflow = TextOverflow.Ellipsis, maxLines = 1, ) } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ LegalState( title = resourceReference(R.string.common_privacy_policy), link = it, onClick = actions.onLinkClick, ) } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ LegalState( title = resourceReference(R.string.common_terms_of_use), link = it, onClick = actions.onLinkClick, ) } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ it is SwapNotificationUM.Error || it is NotificationUM.Error || it is SwapNotificationUM.Warning.ExpressError || it is SwapNotificationUM.Warning.ExpressGeneralError || it is SwapNotificationUM.Warning.NoAvailableTokensToSwap || it is SwapNotificationUM.Warning.NeedReserveToCreateAccount || it is SwapNotificationUM.Info.PermissionNeeded } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ it.convertToProviderBottomSheetState( pricesLowerBest = pricesLowerBest, onProviderSelect = actions.onProviderSelect, needApplyFCARestrictions = needApplyFCARestrictions, ) } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ val selectedItem = when (it) { FeeType.NORMAL -> txFeeState.normalFee FeeType.PRIORITY -> txFeeState.priorityFee } actions.onSelectFeeType.invoke(selectedItem) } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ val tokenInfo = tokenSwapInfoForProviders[it.id] if (it is ProviderState.Content && tokenInfo != null) { val rateString = tokenInfo.tokenAmount .getFormattedCryptoAmount(tokenInfo.cryptoCurrencyStatus.currency) it.copy( subtitle = stringReference(rateString), percentLowerThenBest = pricesLowerBest[it.id]?.let { percent -> PercentDifference.Value(percent) } ?: PercentDifference.Value(0f), ) } else { it } } + MultilineLambdaItParameter:StateBuilder.kt$StateBuilder${ when (it) { is TokenToSelectState.TokenToSelect -> { it.copy( addedTokenBalanceData = it.addedTokenBalanceData?.copy(isBalanceHidden = isBalanceHidden), ) } is TokenToSelectState.Title -> { it } } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ AccountCryptoCurrencyStatus( account = it.account, status = it.cryptoCurrencyStatus, ) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ Timber.d("${coin.id} balance is ${it.value.amount}") dataState = dataState.copy( feePaidCryptoCurrency = getFeePaidCryptoCurrencyStatusSyncUseCase( userWalletId = userWalletId, cryptoCurrencyStatus = it, ).getOrNull() ?: it, ) uiState = if (isFromCurrency) { dataState = dataState.copy(fromCryptoCurrency = it) stateBuilder.updateSendCurrencyBalance(uiState, it) } else { dataState = dataState.copy(toCryptoCurrency = it) stateBuilder.updateReceiveCurrencyBalance(uiState, it) } startLoadingQuotesFromLastState(isSilent = true) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ Timber.e("Error when loading quotes: $it") uiState = stateBuilder.addNotification(uiState, null) { startLoadingQuotesFromLastState() } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ Timber.e(it) applyInitialTokenChoice( state = TokensDataStateExpress.EMPTY, selectedCurrency = null, selectedAccount = null, isReverseFromTo = isReverseFromTo, ) uiState = stateBuilder.createInitialErrorState( uiState, (it as? ExpressException)?.expressDataError?.code ?: ExpressDataError.UnknownError.code, ) { uiState = stateBuilder.createInitialLoadingState( initialCurrencyFrom = initialCurrencyFrom, initialCurrencyTo = initialCurrencyTo, fromNetworkInfo = initialCurrencyFrom.getNetworkInfo(), ) initTokens(isReverseFromTo) } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ Timber.e(it) startLoadingQuotesFromLastState() makeDefaultAlert() } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ Timber.e(it.message.orEmpty()) makeDefaultAlert() } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ getAccountCurrencyStatusUseCase.invokeSync( userWalletId = userWalletId, currency = it, ).getOrNull() } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync( userWalletId = userWalletId, cryptoCurrencyId = it.id, ).getOrNull() } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ if (!it.value.fromTokenInfo.amountFiat.isNullOrZero() && !it.value.toTokenInfo.amountFiat.isNullOrZero()) { it.value.fromTokenInfo.amountFiat.divide( it.value.toTokenInfo.amountFiat, it.value.toTokenInfo.cryptoCurrencyStatus.currency.decimals, RoundingMode.HALF_UP, ) } else { BigDecimal.ZERO } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ if (it.key != selectedProviderEntry.key) { val amount = it.value.toTokenInfo.tokenAmount.value val percentDiff = BigDecimal.ONE.minus( selectedProviderRate.divide(amount, RoundingMode.HALF_UP), ).multiply(hundredPercent) it.key.providerId to percentDiff.setScale(2, RoundingMode.HALF_UP).toFloat() } else { null } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ isBalanceHidden = it.isBalanceHidden uiState = stateBuilder.updateBalanceHiddenState(uiState, isBalanceHidden) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ it is SwapState.SwapError && ( it.error is ExpressDataError.ExchangeTooSmallAmountError || it.error is ExpressDataError.ExchangeTooBigAmountError ) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ it.currencyStatus.currency.name.contains(searchQuery, ignoreCase = true) || it.currencyStatus.currency.symbol.contains(searchQuery, ignoreCase = true) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ subscribeToCoinBalanceUpdates( userWalletId = userWalletId, coin = it, isFromCurrency = false, ) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ subscribeToCoinBalanceUpdates( userWalletId = userWalletId, coin = it, isFromCurrency = true, ) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ uiState = stateBuilder.dismissBottomSheet(uiState) dataState = dataState.copy(selectedFee = it) modelScope.launch(dispatchers.io) { startLoadingQuotesFromLastState(false) } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val balance = swapInteractor.getTokenBalance(it) onAmountChanged(balance.formatToUIRepresentation()) } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ val provider = findAndSelectProvider(it) val swapState = dataState.lastLoadedSwapStates[provider] val fromToken = dataState.fromCryptoCurrency if (provider != null && swapState != null && fromToken != null) { analyticsEventHandler.send(SwapEvents.ProviderChosen(provider)) uiState = stateBuilder.dismissBottomSheet(uiState) setupLoadedState( provider = provider, state = swapState, fromToken = fromToken, ) } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ when (it) { is SwapTransactionState.TxSent -> { sendApproveSuccessEvent(fromToken, feeForPermission.feeType, approveType) updateWalletBalance() uiState = stateBuilder.loadingPermissionState(uiState) uiState = stateBuilder.dismissBottomSheet(uiState) startLoadingQuotesFromLastState(isSilent = true) } is SwapTransactionState.Error -> { uiState = stateBuilder.createErrorTransactionAlert( uiState = uiState, error = it, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, onSupportClick = ::onFailedTxEmailClick, isReverseSwapPossible = isReverseSwapPossible(), ) } SwapTransactionState.DemoMode -> { uiState = stateBuilder.createDemoModeAlert( uiState = uiState, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, isReverseSwapPossible = isReverseSwapPossible(), ) } } } + MultilineLambdaItParameter:SwapModel.kt$SwapModel${ when (it) { is SwapTransactionState.TxSent -> { sendSuccessSwapEvent(fromCurrency.currency, fee.feeType) val url = getExplorerTransactionUrlUseCase( txHash = it.txHash, networkId = fromCurrency.currency.network.id, ).getOrElse { Timber.i("tx hash explore not supported") "" } updateWalletBalance() uiState = stateBuilder.createSuccessState( uiState = uiState, swapTransactionState = it, dataState = dataState, txUrl = url, onExploreClick = { if (it.txHash.isNotEmpty()) { urlOpener.openUrl(url) } analyticsEventHandler.send( event = SwapEvents.ButtonExplore(initialCurrencyFrom.symbol), ) }, onStatusClick = { val txExternalUrl = it.txExternalUrl if (!txExternalUrl.isNullOrBlank()) { urlOpener.openUrl(txExternalUrl) analyticsEventHandler.send( event = SwapEvents.ButtonStatus(initialCurrencyFrom.symbol), ) } }, ) sendSuccessEvent() swapRouter.openScreen(SwapNavScreen.Success) } SwapTransactionState.DemoMode -> { uiState = stateBuilder.createDemoModeAlert( uiState = uiState, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, isReverseSwapPossible = isReverseSwapPossible(), ) } is SwapTransactionState.Error -> { startLoadingQuotesFromLastState() uiState = stateBuilder.createErrorTransactionAlert( uiState = uiState, error = it, onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, onSupportClick = ::onFailedTxEmailClick, isReverseSwapPossible = isReverseSwapPossible(), ) } } } + MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, ) } + MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier .align(Alignment.CenterVertically) .testTag(SwapTokenScreenTestTags.BALANCE), ) } + MultilineLambdaItParameter:TransactionCard.kt${ Text( text = it, color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size20), ) } + NamedArguments:SwapModel.kt$SwapModel$PeriodicTask( UPDATE_DELAY, task = { uiState = stateBuilder.createSilentLoadState(uiState) runCatching(dispatchers.io) { dataState = dataState.copy( amount = amount, reduceBalanceBy = reduceBalanceBy, swapDataModel = null, approveDataModel = null, ) swapInteractor.findBestQuote( fromToken = fromToken, fromAccount = fromAccount, toToken = toToken, toAccount = toAccount, providers = toProvidersList, amountToSwap = amount, reduceBalanceBy = reduceBalanceBy, selectedFee = dataState.selectedFee?.feeType ?: FeeType.NORMAL, ) } }, onSuccess = { providersState -> if (providersState.isNotEmpty()) { val (provider, state) = updateLoadedQuotes(providersState) setupLoadedState(provider, state, fromToken) val successStates = providersState.getLastLoadedSuccessStates() val pricesLowerBest = getPricesLowerBest(provider.providerId, successStates) uiState = stateBuilder.updateProvidersBottomSheetContent( uiState = uiState, pricesLowerBest = pricesLowerBest, tokenSwapInfoForProviders = successStates.entries .associate { it.key.providerId to it.value.toTokenInfo }, ) } else { Timber.e("Accidentally empty quotes list") } }, onError = { Timber.e("Error when loading quotes: $it") uiState = stateBuilder.addNotification(uiState, null) { startLoadingQuotesFromLastState() } }, ) + NoNameShadowing:SwapModel.kt$SwapModel${ it.cryptoCurrencyStatus } + NoNameShadowing:SwapModel.kt$SwapModel${ it.cryptoCurrencyStatus.currency.id.value == id } + NoNameShadowing:SwapModel.kt$SwapModel${ it.key == selectedSwapProvider } + NonBooleanPropertyPrefixedWithIs:StateBuilder.kt$StateBuilder$private val isAccountsModeProvider: Provider<Boolean> + NonBooleanPropertyPrefixedWithIs:StateBuilder.kt$StateBuilder$private val isBalanceHiddenProvider: Provider<Boolean> + NonBooleanPropertyPrefixedWithIs:SwapModel.kt$SwapModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:TokensDataConverter.kt$TokensDataConverter$private val isBalanceHiddenProvider: Provider<Boolean> + NullableToStringCall:SwapModel.kt$SwapModel$${currencyStatus.value.amount} + NullableToStringCall:SwapModel.kt$SwapModel$${it.value.amount} + NullableToStringCall:TransactionCard.kt$data.toString() + PropertyUsedBeforeDeclaration:SwapModel.kt$SwapModel$isAccountsMode + SuspendFunSwallowedCancellation:SwapModel.kt$SwapModel$runCatching + UnnecessaryEventHandlerParameter:ChooseFeeBottomSheet.kt$onReadMoreClick: (String) -> Unit + UnnecessaryLet:SwapModel.kt$SwapModel$let { return nonEmptyStates.entries.first { it.key == selectedSwapProvider }.toPair() } + UnusedImports:TransactionCard.kt$import com.tangem.domain.models.account.Account + UseEmptyCounterpart:StoriesEvents.kt$StoriesEvents$mapOf() + UseEmptyCounterpart:SwapEvents.kt$SwapEvents$mapOf() + UseOrEmpty:StateBuilder.kt$StateBuilder$initialCurrencyTo?.symbol ?: "" + UseOrEmpty:SwapModel.kt$SwapModel$receiveToken ?: "" + UseOrEmpty:SwapScreenContent.kt$swapCardState.tokenIconUrl ?: "" + VarCouldBeVal:SwapModel.kt$SwapModel$private var swapRouter: SwapRouter = SwapRouter(router = router) + + diff --git a/features/tangempay/details/impl/detekt-baseline-debug.xml b/features/tangempay/details/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..6c37bced10 --- /dev/null +++ b/features/tangempay/details/impl/detekt-baseline-debug.xml @@ -0,0 +1,30 @@ + + + + + BooleanPropertyNaming:PinCodeChangeTransformer.kt$PinCodeChangeTransformer$val valid = PinCodeValidation.validate(pinCode = newPin) + BooleanPropertyNaming:TangemPayAddToWalletUM.kt$TangemPayAddToWalletUM$val showAddToWalletButton: Boolean + BooleanPropertyNaming:TangemPayChangePinCodeSuccessScreen.kt$var showConfetti by remember { mutableStateOf(false) } + BooleanPropertyNaming:TangemPayChangePinUM.kt$TangemPayChangePinUM$val submitButtonEnabled: Boolean + BooleanPropertyNaming:TangemPayChangePinUM.kt$TangemPayChangePinUM$val submitButtonLoading: Boolean + BooleanPropertyNaming:TangemPayDetailsScreen.kt$var showDropdownMenu by rememberSaveable { mutableStateOf(false) } + BooleanPropertyNaming:TangemPayDetailsUM.kt$TangemPayDetailsUM$val addFundsEnabled: Boolean + BooleanPropertyNaming:TangemPayFreezeUnfreezeStateTransformer.kt$TangemPayFreezeUnfreezeStateTransformer$private val frozen: Boolean + BooleanPropertyNaming:TangemPayTxHistoryListManager.kt$TangemPayTxHistoryListManager$val clearUiBatches = state.status is PaginationStatus.InitialLoading && batchListState.status is PaginationStatus.Paginating + CanBeNonNullable:TangemPayTxHistoryDetailsModel.kt$TangemPayTxHistoryDetailsModel$txHash: String? + MaxChainedCallsOnSameLine:TangemPayTxHistoryUiManager.kt$TangemPayTxHistoryUiManager$prevBatch?.data?.lastOrNull()?.date?.millis?.toDateFormatWithTodayYesterday() + MultilineLambdaItParameter:TangemPayAddFundsContent.kt${ key(it.title) { TangemPayTopUpItem(state = it) } } + MultilineLambdaItParameter:TangemPayCardDetailsBlockModel.kt$TangemPayCardDetailsBlockModel${ uiState.update( transformer = DetailsRevealedStateTransformer( details = it, onClickHide = ::hideCardDetails, ), ) } + MultilineLambdaItParameter:TangemPayDetailsScreen.kt${ TangemDropdownItem( item = it.dropdownItem, dismissParent = { showDropdownMenu = false }, ) } + MultilineLambdaItParameter:TangemPayTxHistoryUiManager.kt$TangemPayTxHistoryUiManager${ it.status !is PaginationStatus.None && it.status !is PaginationStatus.InitialLoading && it.status !is PaginationStatus.InitialLoadingError } + NullCheckOnMutableProperty:GoogleWalletUtil.kt$GoogleWalletUtil$if (walletIntent != null) { walletIntent } else { try { context.packageManager.getLaunchIntentForPackage(WALLET_PACKAGE_NAME) ?.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } .also { walletIntent = it } } catch (exception: Exception) { Timber.tag(TAG).e(exception) null } } + NullableBooleanCheck:TangemPayDetailsModel.kt$TangemPayDetailsModel$cardDetailsRepository.isAddToWalletDone().getOrNull() ?: false + ReusedModifierInstance:DefaultTangemPayDetailsContainerComponent.kt$DefaultTangemPayDetailsContainerComponent$Content(modifier = modifier) + ReusedModifierInstance:TangemPayChangePinCodeSuccessScreen.kt$Column( modifier .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { SuccessContent( modifier = Modifier .fillMaxWidth() .weight(1f), ) PrimaryButton( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) .padding(bottom = 16.dp) .navigationBarsPadding(), text = stringResourceSafe(R.string.common_done), onClick = onClick, ) } + ReusedModifierInstance:TangemPayChangePinScreen.kt$Column( modifier = modifier .fillMaxWidth() .padding(top = 48.dp) .padding(horizontal = 36.dp) .weight(1f), horizontalAlignment = Alignment.CenterHorizontally, ) { Text( text = stringResourceSafe(R.string.visa_onboarding_pin_code_title), style = TangemTheme.typography.h2, color = TangemTheme.colors.text.primary1, textAlign = TextAlign.Center, ) SpacerH16() Text( text = stringResourceSafe(R.string.visa_onboarding_pin_code_description), style = TangemTheme.typography.body1, color = TangemTheme.colors.text.secondary, textAlign = TextAlign.Center, ) SpacerH(26.dp) PinCodeSection(state) } + ReusedModifierInstance:TangemPayChangePinScreen.kt$PinCode( modifier = modifier, value = state.pinCode, onValueChange = state.onPinCodeChange, focusRequester = focusRequester, ) + UnnecessaryLet:TangempayTxDetailsUi.kt$let { Label(state = state.labelState, modifier = Modifier.padding(top = 12.dp)) } + UnnecessaryLet:TangempayTxDetailsUi.kt$let { Notification( config = state.notification, titleColor = TangemTheme.colors.text.tertiary, iconTint = TangemTheme.colors.icon.secondary, ) } + UseEmptyCounterpart:TangemPayTxHistoryState.kt$TangemPayTxHistoryState$listOf() + + diff --git a/features/tangempay/onboarding/impl/detekt-baseline-debug.xml b/features/tangempay/onboarding/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..244ca0e5f5 --- /dev/null +++ b/features/tangempay/onboarding/impl/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + MultilineLambdaItParameter:TangemPayOnboardingModel.kt$TangemPayOnboardingModel${ TangemPayOnboardingScreenState.Content( onBack = it.onBack, onTermsClick = ::onTermsClick, buttonConfig = TangemPayOnboardingScreenState.Content.ButtonConfig( isLoading = false, onClick = ::onGetCardClick, ), ) } + MultilineLambdaItParameter:TangemPayOnboardingModel.kt$TangemPayOnboardingModel${ Timber.e("Error getCustomerInfo: ${it.errorCode}") uiState.transformerUpdate(TangemPayOnboardingButtonLoadingTransformer(isLoading = false)) } + NullableToStringCall:TangemPayOnboardingModel.kt$TangemPayOnboardingModel$${result.leftOrNull()?.message} + + diff --git a/features/tester/impl/detekt-baseline-debug.xml b/features/tester/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..4a5ba6a9ce --- /dev/null +++ b/features/tester/impl/detekt-baseline-debug.xml @@ -0,0 +1,37 @@ + + + + + BooleanPropertyNaming:ExcludedBlockchainsScreenUM.kt$ExcludedBlockchainsScreenUM$val showRecoverWarning: Boolean + CanBeNonNullable:TestPushDeepLinkBottomSheet.kt$config: TangemBottomSheetConfig? + CastNullableToNonNullableType:TestPushMarketTokenSearchBottomSheetTransformer.kt$TestPushMarketTokenSearchBottomSheetTransformer$as + CastNullableToNonNullableType:TestPushViewModel.kt$TestPushViewModel$as + ExplicitCollectionElementAccessMethod:TestPushAddKeyDataTransformer.kt$TestPushAddKeyDataTransformer$mutableData.set(index = index, updated) + ExplicitCollectionElementAccessMethod:TestPushAddValueDataTransformer.kt$TestPushAddValueDataTransformer$mutableData.set(index = index, updated) + MaxChainedCallsOnSameLine:BlockchainProvidersScreen.kt$ProvidersDnDTarget$event.toAndroidDragEvent().clipData.getItemAt(0).text.toString().toInt() + MultilineLambdaItParameter:ApiEnvironmentComparator.kt$ApiEnvironmentComparator${ when (it) { ApiEnvironment.DEV -> 0 ApiEnvironment.DEV_2 -> 1 ApiEnvironment.DEV_3 -> 2 ApiEnvironment.STAGE -> 3 ApiEnvironment.MOCK -> 4 ApiEnvironment.PROD -> 5 } } + MultilineLambdaItParameter:BlockchainProvidersScreen.kt${ value = it state.onValueChange(it.text) } + MultilineLambdaItParameter:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ if (it.blockchainId == blockchainId) { it.update() } else { it } } + MultilineLambdaItParameter:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ it.copyProvidersUM(blockchainId = id) { copy( addPublicProviderDialog = addPublicProviderDialog.copy( hasError = !PatternsCompat.WEB_URL.matcher(url).matches(), ), ) } } + MultilineLambdaItParameter:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ it.copyProvidersUM(blockchainId = id) { copy(providers = providers.toImmutableList()) } } + MultilineLambdaItParameter:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ it.key.fullName.contains(other = query, ignoreCase = true) || it.key.currency.contains(other = query, ignoreCase = true) } + MultilineLambdaItParameter:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ val (blockchain, providers) = it ProvidersUM( blockchainId = blockchain.id, blockchainName = blockchain.fullName, blockchainSymbol = blockchain.currency, providers = providers.map(BlockchainProvidersUM::ProviderUM).toImmutableList(), isExpanded = false, onDrop = { prev, current -> onDrop(blockchain.id, prev, current) }, addPublicProviderDialog = AddPublicProviderDialogUM( hasError = false, onValueChange = { onPublicProviderUrlChange(id = blockchain.id, url = it) }, onSaveClick = { onAddProviderClick(id = blockchain.id, url = it) }, ), ) } + MultilineLambdaItParameter:EnvironmentTogglesScreen.kt${ Text( text = it, color = TangemTheme.colors.text.accent, overflow = TextOverflow.Ellipsis, maxLines = 1, style = TangemTheme.typography.body2, ) } + MultilineLambdaItParameter:EnvironmentsTogglesViewModel.kt$EnvironmentsTogglesViewModel${ val (config, currentEnvironment) = it if (config.environmentConfigs.size <= 1) return@mapNotNull null EnvironmentTogglesScreenUM.ApiInfoUM( name = config.id.name, select = currentEnvironment.name, url = config.environmentConfigs.firstOrNull { it.environment == currentEnvironment }?.baseUrl ?: error("Current environment's url isn't found"), environments = config.environmentConfigs .sortedWith(ApiEnvironmentComparator) .map { environmentConfig -> environmentConfig.environment.name } .toImmutableSet(), ) } + MultilineLambdaItParameter:TestPushViewModel.kt$TestPushViewModel${ _uiState.update( TestPushMarketTokenClickBottomSheetTransformer( it, ), ) marketsJobHolder.cancel() dismissBottomSheet() } + MultilineLambdaItParameter:TestPushViewModel.kt$TestPushViewModel${ _uiState.update( TestPushMarketTokenSearchBottomSheetTransformer( it, ), ) onMarketsBatchReload(it.text) } + MultilineLambdaItParameter:TesterAccountsViewModel.kt$TesterAccountsViewModel${ it.copy( accountListBottomSheetConfig = it.accountListBottomSheetConfig.copy( isAccountsShown = false, ), ) } + MultilineLambdaItParameter:TesterAccountsViewModel.kt$TesterAccountsViewModel${ it.copy( walletSelector = it.walletSelector.copy(selected = userWallet), accountListBottomSheetConfig = it.accountListBottomSheetConfig.copy( accounts = getWalletAccounts(userWallet.walletId), ), ) } + MultilineLambdaItParameter:TesterActionsScreen.kt${ builder.setStream( FileProvider.getUriForFile(activity, "${activity.packageName}.provider", it), ) } + MultilineLambdaItParameter:TesterActivity.kt$TesterActivity${ val route = when (it) { ButtonUM.FEATURE_TOGGLES -> TesterScreen.FEATURE_TOGGLES ButtonUM.EXCLUDED_BLOCKCHAINS -> TesterScreen.EXCLUDED_BLOCKCHAINS ButtonUM.ENVIRONMENT_TOGGLES -> TesterScreen.ENVIRONMENTS_TOGGLES ButtonUM.BLOCKCHAIN_PROVIDERS -> TesterScreen.BLOCKCHAIN_PROVIDERS ButtonUM.TESTER_ACTIONS -> TesterScreen.TESTER_ACTIONS ButtonUM.TEST_PUSHES -> TesterScreen.TEST_PUSHES ButtonUM.ACCOUNTS -> TesterScreen.ACCOUNTS } innerTesterRouter.open(route) } + NoNameShadowing:AccountsScreen.kt$content + NoNameShadowing:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ onAddProviderClick(id = blockchain.id, url = it) } + NoNameShadowing:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel${ onPublicProviderUrlChange(id = blockchain.id, url = it) } + NoNameShadowing:EnvironmentsTogglesViewModel.kt$EnvironmentsTogglesViewModel${ it.environment == currentEnvironment } + NoNameShadowing:TesterActivity.kt$TesterActivity${ val route = when (it) { ButtonUM.FEATURE_TOGGLES -> TesterScreen.FEATURE_TOGGLES ButtonUM.EXCLUDED_BLOCKCHAINS -> TesterScreen.EXCLUDED_BLOCKCHAINS ButtonUM.ENVIRONMENT_TOGGLES -> TesterScreen.ENVIRONMENTS_TOGGLES ButtonUM.BLOCKCHAIN_PROVIDERS -> TesterScreen.BLOCKCHAIN_PROVIDERS ButtonUM.TESTER_ACTIONS -> TesterScreen.TESTER_ACTIONS ButtonUM.TEST_PUSHES -> TesterScreen.TEST_PUSHES ButtonUM.ACCOUNTS -> TesterScreen.ACCOUNTS } innerTesterRouter.open(route) } + PropertyUsedBeforeDeclaration:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel$_state + PropertyUsedBeforeDeclaration:BlockchainProvidersViewModel.kt$BlockchainProvidersViewModel$searchQuery + PropertyUsedBeforeDeclaration:EnvironmentsTogglesViewModel.kt$EnvironmentsTogglesViewModel$_uiState + PropertyUsedBeforeDeclaration:TesterActionsViewModel.kt$TesterActionsViewModel$initialState + + diff --git a/features/token-recieve/impl/detekt-baseline-debug.xml b/features/token-recieve/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..791c19cd17 --- /dev/null +++ b/features/token-recieve/impl/detekt-baseline-debug.xml @@ -0,0 +1,17 @@ + + + + + BooleanPropertyNaming:ReceiveAssetsUM.kt$ReceiveAssetsUM$val showMemoDisclaimer: Boolean + BooleanPropertyNaming:TokenReceiveAssetsComponent.kt$TokenReceiveAssetsComponent.TokenReceiveAssetsParams$val showMemoDisclaimer: Boolean + BooleanPropertyNaming:TokenReceiveStateFactory.kt$TokenReceiveStateFactory$val needUseToLegacyAndDefaultName = addresses.any { it.nameService == ReceiveAddressModel.NameService.Legacy } + MaxChainedCallsOnSameLine:DefaultTokenReceiveComponent.kt$DefaultTokenReceiveComponent$model.params.config.cryptoCurrency.network.name + MultilineLambdaItParameter:TokenReceiveAssetsContent.kt${ hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) assetsUM.onOpenQrCodeClick(it) } + MultilineLambdaItParameter:TokenReceiveAssetsContent.kt${ hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) assetsUM.onShareClick(it) } + MultilineLambdaItParameter:TokenReceiveAssetsContent.kt${ hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) coroutineScope.launch { snackbarHostState.showSnackbar( message = resources.getStringSafe( R.string.wallet_notification_address_copied, ), ) } assetsUM.onCopyClick(it) } + NoNameShadowing:TokenReceiveStateFactory.kt$TokenReceiveStateFactory$ensAddress + PropertyUsedBeforeDeclaration:TokenReceiveModel.kt$TokenReceiveModel$params + PropertyUsedBeforeDeclaration:TokenReceiveModel.kt$TokenReceiveModel$state + ReusedModifierInstance:TokenReceiveAssetsContent.kt$Box( modifier = modifier .fillMaxWidth() .heightIn(min = 64.dp), contentAlignment = Alignment.Center, ) { CircularProgressIndicator( color = TangemTheme.colors.icon.informative, modifier = Modifier.padding(TangemTheme.dimens.spacing8), ) } + + diff --git a/features/tokendetails/impl/detekt-baseline-debug.xml b/features/tokendetails/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..ca58193fa1 --- /dev/null +++ b/features/tokendetails/impl/detekt-baseline-debug.xml @@ -0,0 +1,56 @@ + + + + + BooleanPropertyNaming:ExchangeUM.kt$ExchangeUM$val showProviderLink: Boolean + BooleanPropertyNaming:TokenDetailsActionButton.kt$TokenDetailsActionButton.Buy$val dimContent: Boolean + BooleanPropertyNaming:TokenDetailsActionButton.kt$TokenDetailsActionButton.Sell$val dimContent: Boolean + BooleanPropertyNaming:TokenDetailsActionButton.kt$TokenDetailsActionButton.Send$val dimContent: Boolean + BooleanPropertyNaming:TokenDetailsActionButton.kt$TokenDetailsActionButton.Swap$val dimContent: Boolean + BooleanPropertyNaming:TokenDetailsActionButton.kt$TokenDetailsActionButton.Swap$val showBadge: Boolean + BooleanPropertyNaming:TokenDetailsDialogConfig.kt$TokenDetailsDialogConfig.DialogContentConfig.ButtonConfig$val warning: Boolean = false + BooleanPropertyNaming:TokenDetailsNotification.kt$TokenDetailsNotification.NetworkFeeWithBuyButton$val mergeFeeNetworkName: Boolean = false + BooleanPropertyNaming:TokenDetailsSwapTransactionsStateConverter.kt$TokenDetailsSwapTransactionsStateConverter$val showProviderLink = getShowProviderLink(notification, statusModel) + BooleanPropertyNaming:TokenDetailsSwapTransactionsStateConverter.kt$TokenDetailsSwapTransactionsStateConverter$val showProviderLink = getShowProviderLink(notification, transaction.status) + BooleanPropertyNaming:TokenDetailsTopAppBar.kt$var showDropdownMenu by rememberSaveable { mutableStateOf(false) } + MultilineLambdaItParameter:DefaultTokenDetailsDeepLinkHandler.kt$DefaultTokenDetailsDeepLinkHandler${ val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true) val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true val isDefaultDerivation = it.network.derivationPath is Network.DerivationPath.Card val isCustomDerivation = derivationPath?.equals(it.network.derivationPath.value) == true val isCorrectDerivation = isDefaultDerivation || isCustomDerivation isNetwork && isCurrency && isCorrectDerivation } + MultilineLambdaItParameter:ExpressStatusFactory.kt$ExpressStatusFactory${ when (it) { is ExpressTransactionStateUM.OnrampUM -> it.activeStatus.isHidden else -> false } } + MultilineLambdaItParameter:OnrampStatusFactory.kt$OnrampStatusFactory${ Timber.e("Couldn't update onramp status. $it") onrampTx } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ Timber.e(it.cause?.localizedMessage.orEmpty()) "" } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ analyticsEventsHandler.send( TokenReceiveAnalyticsEvent.ButtonShareAddress(cryptoCurrency.symbol), ) shareManager.shareText(text = it) } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ analyticsEventsHandler.send(TokenReceiveAnalyticsEvent.ButtonCopyAddress(cryptoCurrency.symbol)) clipboardManager.setText(text = it, isSensitive = true) } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ analyticsExceptionHandler.sendException( event = ExceptionAnalyticsEvent( exception = it, params = mapOf( "blockchainId" to cryptoCurrency.network.id.rawId.value, "networkId" to cryptoCurrency.network.backendId, ), ), ) Timber.e( /* t = */ it, /* message = */ "Unable to get wallet manager for user wallet %s and network %s", /* ...args = */ userWalletId, cryptoCurrency.network, ) false } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ internalUiState.value = stateFactory.getStateWithErrorDialog(stringReference(it)) Timber.e(it) } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ internalUiState.value = stateFactory.getStateWithUpdatedHidden( isBalanceHidden = it.isBalanceHidden, ) } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ sendButtonsEvents(it.states) internalUiState.value = stateFactory.getManageButtonsState(actions = it.states) } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ val stakingEntryInfo = if (it is StakingAvailability.Available) { getStakingEntryInfoUseCase( cryptoCurrencyId = cryptoCurrency.id, symbol = cryptoCurrency.symbol, ).getOrNull() } else { null } internalUiState.update { state -> stateFactory.getStakingInfoState( state = state, stakingEntryInfo = stakingEntryInfo, stakingAvailability = it, cryptoCurrencyStatus = cryptoCurrencyStatus, ) } } + MultilineLambdaItParameter:TokenDetailsModel.kt$TokenDetailsModel${ val updatedState = stateFactory.getStateWithNotifications(it) notificationsAnalyticsSender.send(internalUiState.value, updatedState.notifications) internalUiState.value = updatedState } + MultilineLambdaItParameter:TokenDetailsOnrampTransactionStateConverter.kt$TokenDetailsOnrampTransactionStateConverter${ analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider) clickIntents.onGoToProviderClick(it) } + MultilineLambdaItParameter:TokenDetailsScreen.kt${ Notification( modifier = itemModifier.animateItem(), config = it.config, iconTint = when (it) { is TokenDetailsNotification.Informational -> TangemTheme.colors.icon.accent is TokenDetailsNotification.UsedOutdatedData -> TangemTheme.colors.text.attention else -> null }, ) } + MultilineLambdaItParameter:TokenDetailsTopAppBar.kt${ TangemDropdownItem( item = it, dismissParent = { showDropdownMenu = false }, ) } + MultilineLambdaItParameter:TokenStakingBlock.kt${ when (it) { is StakingBlockUM.TemporaryUnavailable -> StakingTemporaryUnavailableBlock() is StakingBlockUM.Loading -> StakingLoading() is StakingBlockUM.Staked -> StakingBalanceBlock( state = it, isBalanceHidden = isBalanceHidden, ) is StakingBlockUM.StakeAvailable -> StakingAvailableContent( state = it, ) } } + NamedArguments:TokenDetailsLoadedBalanceConverter.kt$TokenDetailsLoadedBalanceConverter$formatFiatAmount( status.value, stakingFiatAmount, currentState.selectedBalanceType, appCurrencyProvider(), ) + NamedArguments:TokenDetailsSwapTransactionsStateConverter.kt$TokenDetailsSwapTransactionsStateConverter$createStateInfo( transaction, toCryptoCurrency, fromCryptoCurrency, toFiatAmount, fromFiatAmount, ) + NestedScopeFunctions:TokenDetailsBalanceSelectStateConverter.kt$TokenDetailsBalanceSelectStateConverter$let { cryptoCurrencyStatus.value.fiatRate?.multiply(it) } + NonBooleanPropertyPrefixedWithIs:TokenDetailsModel.kt$TokenDetailsModel$private val isDemoCardUseCase: IsDemoCardUseCase + NullableBooleanCheck:TokenDetailsSwapTransactionsStateConverter.kt$TokenDetailsSwapTransactionsStateConverter$transaction.status?.hasLongTime ?: false + NullableToStringCall:DefaultTokenDetailsDeepLinkHandler.kt$DefaultTokenDetailsDeepLinkHandler$$networkId + NullableToStringCall:DefaultTokenDetailsDeepLinkHandler.kt$DefaultTokenDetailsDeepLinkHandler$$tokenId + NullableToStringCall:TokenDetailsStakingInfoConverter.kt$TokenDetailsStakingInfoConverter$$stakingCryptoAmount + NullableToStringCall:TokenDetailsStakingInfoConverter.kt$TokenDetailsStakingInfoConverter$$stakingEntryInfo + NullableToStringCall:TokenDetailsStakingInfoConverter.kt$TokenDetailsStakingInfoConverter$$yieldBalance + PropertyUsedBeforeDeclaration:ExpressStatusBottomSheetStateProvider.kt$ExpressStatusBottomSheetStateProvider$network + PropertyUsedBeforeDeclaration:ExpressStatusBottomSheetStateProvider.kt$ExpressStatusBottomSheetStateProvider$token + PropertyUsedBeforeDeclaration:TokenDetailsModel.kt$TokenDetailsModel$uiState + SuspendFunSwallowedCancellation:ExchangeStatusFactory.kt$ExchangeStatusFactory$runCatching + SuspendFunSwallowedCancellation:TokenDetailsModel.kt$TokenDetailsModel$runCatching + UnnecessaryLet:TokenDetailsModel.kt$TokenDetailsModel$let { internalUiState.value = stateFactory.getStateWithErrorDialog(message) } + UnnecessaryLet:TokenDetailsSkeletonStateConverter.kt$TokenDetailsSkeletonStateConverter$let(::add) + UnnecessaryLet:TokenDetailsStateFactory.kt$TokenDetailsStateFactory$let(::add) + UseEmptyCounterpart:TokenDetailsAnalyticsEvent.kt$TokenDetailsAnalyticsEvent$mapOf() + UseEmptyCounterpart:TokenDetailsAnalyticsEvent.kt$TokenDetailsAnalyticsEvent.Notice$mapOf() + UseOrEmpty:ExchangeStatusFactory.kt$ExchangeStatusFactory$savedTransactions ?.flatMap { setOf(it.fromCryptoCurrency.id, it.toCryptoCurrency.id) } ?.toSet() ?.getQuotesOrEmpty() ?: emptySet() + UseOrEmpty:TokenDetailsStakingInfoConverter.kt$TokenDetailsStakingInfoConverter$yieldBalance?.balance?.items ?: emptyList() + VarCouldBeVal:TokenDetailsModel.kt$TokenDetailsModel$private var expressTxStatusTaskScheduler = SingleTaskScheduler<PersistentList<ExpressTransactionStateUM>>() + + diff --git a/features/txhistory/impl/detekt-baseline-debug.xml b/features/txhistory/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..7a98042e54 --- /dev/null +++ b/features/txhistory/impl/detekt-baseline-debug.xml @@ -0,0 +1,9 @@ + + + + + BooleanPropertyNaming:TxHistoryListManager.kt$TxHistoryListManager$val clearUiBatches = state.status is PaginationStatus.InitialLoading && batchListState.status is PaginationStatus.Paginating + MultilineLambdaItParameter:TxHistoryUiManager.kt$TxHistoryUiManager${ it.status !is PaginationStatus.None && it.status !is PaginationStatus.InitialLoading && it.status !is PaginationStatus.InitialLoadingError } + UseEmptyCounterpart:TxHistoryListState.kt$TxHistoryListState$listOf() + + diff --git a/features/wallet-settings/impl/detekt-baseline-debug.xml b/features/wallet-settings/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..7eb2a6e84e --- /dev/null +++ b/features/wallet-settings/impl/detekt-baseline-debug.xml @@ -0,0 +1,27 @@ + + + + + BooleanPropertyNaming:AccountItemsDelegate.kt$AccountItemsDelegate$val addAccountEnabled = accounts.size < AccountList.MAX_ACCOUNTS_COUNT + BooleanPropertyNaming:AccountItemsDelegate.kt$AccountItemsDelegate$val showDescription = accounts.size > 1 + BooleanPropertyNaming:WalletSettingsItemUM.kt$WalletSettingsAccountsUM.Footer$val showDescription: Boolean + BooleanPropertyNaming:WalletSettingsItemUM.kt$WalletSettingsAccountsUM.Footer.AddAccountUM$val addAccountEnabled: Boolean + BooleanPropertyNaming:WalletSettingsModel.kt$WalletSettingsModel$val accountsFeatureEnabled = accountsFeatureToggles.isFeatureEnabled + BooleanPropertyNaming:WalletSettingsUM.kt$WalletSettingsUM$val requestPushNotificationsPermission: Boolean = false + BooleanPropertyNaming:WalletSettingsUM.kt$WalletSettingsUM$val walletUpgradeDismissed: Boolean = false + MultilineLambdaItParameter:RenameWalletModel.kt$RenameWalletModel${ Timber.e("Unable to rename wallet: $it") showRenameWalletError(error = it, updatedName = newName.text) } + MultilineLambdaItParameter:RenameWalletModel.kt$RenameWalletModel${ val newName = value.text it.copy( walletNameValue = value, isConfirmEnabled = getConfirmButtonAvailability(newName), error = getErrorOrNull(newName), ) } + MultilineLambdaItParameter:WalletSettingsModel.kt$WalletSettingsModel${ Timber.e("Unable to delete wallet: $it") messageSender.send( message = SnackbarMessage(resourceReference(R.string.common_unknown_error)), ) return@launch } + MultilineLambdaItParameter:WalletSettingsModel.kt$WalletSettingsModel${ val id = (it as? WalletSettingsAccountsUM.Account)?.state?.id ?: return@mapNotNull null AccountId.forCryptoPortfolio(userWalletId = params.userWalletId, value = id).getOrNull() } + NonBooleanPropertyPrefixedWithIs:AccountItemsDelegate.kt$AccountItemsDelegate$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:WalletSettingsModel.kt$WalletSettingsModel$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:WalletSettingsModel.kt$WalletSettingsModel$private val isUpgradeWalletNotificationEnabledUseCase: IsUpgradeWalletNotificationEnabledUseCase + PropertyUsedBeforeDeclaration:NetworksAvailableForNotificationsModel.kt$NetworksAvailableForNotificationsModel$_state + PropertyUsedBeforeDeclaration:RenameWalletModel.kt$RenameWalletModel$_state + UnnecessaryLet:AccountItemsDelegate.kt$AccountItemsDelegate$let(::add) + UnnecessaryLet:ItemsBuilder.kt$ItemsBuilder$let(::add) + UnnecessaryLet:PreviewWalletSettingsComponent.kt$PreviewWalletSettingsComponent$let(::add) + UseEmptyCounterpart:Settings.kt$Settings$mapOf() + UseEmptyCounterpart:WalletSettingsAnalyticEvents.kt$WalletSettingsAnalyticEvents$mapOf() + + diff --git a/features/wallet/impl/detekt-baseline-debug.xml b/features/wallet/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..252986850a --- /dev/null +++ b/features/wallet/impl/detekt-baseline-debug.xml @@ -0,0 +1,177 @@ + + + + + BooleanPropertyNaming:DefaultUserWalletsFetcher.kt$DefaultUserWalletsFetcher$@Assisted("onlyMultiCurrency") private val onlyMultiCurrency: Boolean + BooleanPropertyNaming:DraggableItem.kt$DraggableItem$abstract val showShadow: Boolean + BooleanPropertyNaming:DraggableItem.kt$DraggableItem.RoundingMode$abstract val showGap: Boolean + BooleanPropertyNaming:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$val accessCodeSkipped = array[7] as Boolean + BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private var readyForRateAppNotification = false + BooleanPropertyNaming:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$val userHasWalletOrWallet2 = userWallets.filterIsInstance<UserWallet.Cold>().any { val typesResolver = it.scanResponse.cardTypesResolver typesResolver.isTangemWallet() || typesResolver.isWallet2() } + BooleanPropertyNaming:OrganizeTokensState.kt$OrganizeTokensState.ActionsConfig$val showApplyProgress: Boolean = false + BooleanPropertyNaming:ScrollToWalletTransformer.kt$ScrollToWalletTransformer$private val withScrollAnimation: Boolean = true + BooleanPropertyNaming:SetWalletCardDropDownItemsTransformer.kt$SetWalletCardDropDownItemsTransformer$private val dropdownEnabled: Boolean + BooleanPropertyNaming:TangemPayState.kt$TangemPayState.Progress$val showProgress: Boolean = false + BooleanPropertyNaming:TokenActionButtonConfig.kt$TokenActionButtonConfig$val enabled: Boolean = true + BooleanPropertyNaming:UpdateMultiWalletActionButtonBadgeTransformer.kt$UpdateMultiWalletActionButtonBadgeTransformer$private val showSwapBadge: Boolean + BooleanPropertyNaming:WalletAdditionalInfo.kt$WalletAdditionalInfo$val hideable: Boolean + BooleanPropertyNaming:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor$val showSwapStories = maybeSwapStories.getOrNull() != null + BooleanPropertyNaming:WalletManageButton.kt$WalletManageButton$/** Is click enabled */ abstract val enabled: Boolean + BooleanPropertyNaming:WalletManageButton.kt$WalletManageButton$/** Whether to dim content */ abstract val dimContent: Boolean + BooleanPropertyNaming:WalletManageButton.kt$WalletManageButton.Swap$val showBadge: Boolean = false + BooleanPropertyNaming:WalletModel.kt$WalletModel$private var needToRefreshWallet = false + BooleanPropertyNaming:WalletModel.kt$WalletModel$val initialDataProduced = tangemPayOnboardingRepository.isTangemPayInitialDataProduced() + BooleanPropertyNaming:WalletNameMigrationUseCase.kt$WalletNameMigrationUseCase$private val useNewListRepository: Boolean + BooleanPropertyNaming:WalletScreen.kt$val portfolioContent = state is WalletState.MultiCurrency.Content && state.tokensListState is WalletTokensListState.ContentState.PortfolioContent + BooleanPropertyNaming:WalletScreen.kt$val showMarketsHint by remember { derivedStateOf { // Show hint only when there are items in the list // and when there a no items to scroll listState.layoutInfo.totalItemsCount > 0 && !listState.canScrollBackward && !listState.canScrollForward || listState.canScrollBackward && !listState.canScrollForward } } + BooleanPropertyNaming:WalletScreen.kt$var visible by remember { mutableStateOf(value = false) } + BooleanPropertyNaming:WalletScreenState.kt$WalletScreenState$val showMarketsOnboarding: Boolean + BooleanPropertyNaming:WalletWithFundsChecker.kt$WalletWithFundsChecker$val prevStatus = statusByWalletId.get(userWalletId) + CanBeNonNullable:WalletScreen.kt$bottomSheetConfig: TangemBottomSheetConfig? + IgnoredReturnValue:MultiWalletTokenListStore.kt$MultiWalletTokenListStore$remove(userWalletId) + MaxChainedCallsOnSameLine:HasSingleWalletSignedHashesUseCase.kt$HasSingleWalletSignedHashesUseCase$userWallet.scanResponse.card.wallets.firstOrNull()?.totalSignedHashes + MultilineLambdaItParameter:BasicTokenListSubscriber.kt$BasicTokenListSubscriber${ it.getOrElse { e -> Timber.e("Failed to load app currency: $e") AppCurrency.Default } } + MultilineLambdaItParameter:DefaultPromoDeeplinkHandler.kt$DefaultPromoDeeplinkHandler${ Timber.tag(LOG_TAG).e("Error on getting user wallet: $it") showAlert(Failed) } + MultilineLambdaItParameter:DefaultUserWalletImageFetcher.kt$DefaultUserWalletImageFetcher${ it.fold( ifLeft = { emit(UserWalletItemUM.ImageState.Loading) }, ifRight = { wallet -> emitAll(walletImage(wallet, size)) }, ) } + MultilineLambdaItParameter:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory${ hasSingleWalletSignedHashesUseCase(userWallet = selectedWallet, network = it) .conflate() .distinctUntilChanged() .firstOrNull() } + MultilineLambdaItParameter:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory${ val typesResolver = it.scanResponse.cardTypesResolver typesResolver.isTangemWallet() || typesResolver.isWallet2() } + MultilineLambdaItParameter:NetworkGroupToDraggableItemsConverterV2.kt$NetworkGroupToDraggableItemsConverterV2${ AccountCryptoCurrencyStatus( account = account, status = it, ) } + MultilineLambdaItParameter:OrganizeTokensModel.kt$OrganizeTokensModel${ isBalanceHidden = it.isBalanceHidden stateHolder.updateHiddenState(isBalanceHidden) } + MultilineLambdaItParameter:OrganizeTokensModel.kt$OrganizeTokensModel${ stateHolder.updateStateAfterTokenListSorting(it) cachedTokenList = it } + MultilineLambdaItParameter:OrganizeTokensModel.kt$OrganizeTokensModel${ stateHolder.updateStateAfterTokenListSortingV2(it, isAccountsModeEnabled) cachedAccountStatusList = it } + MultilineLambdaItParameter:OrganizedTokenListConverter.kt$OrganizedTokenListConverter${ AccountCryptoCurrencyStatus( account = cryptoAccount, status = it, ) } + MultilineLambdaItParameter:PrimaryCurrencySubscriber.kt$PrimaryCurrencySubscriber${ // do not send tokens count for single currency wallet analyticsEventHandler.send( event = WalletScreenAnalyticsEvent.Basic.BalanceLoaded( balance = it, tokensCount = null, ), ) } + MultilineLambdaItParameter:PrimaryCurrencySubscriber.kt$PrimaryCurrencySubscriber${ Timber.e("Unable to get primary currency status: $it") return@onEach } + MultilineLambdaItParameter:PrimaryCurrencySubscriberV2.kt$PrimaryCurrencySubscriberV2${ // do not send tokens count for single currency wallet analyticsEventHandler.send( event = WalletScreenAnalyticsEvent.Basic.BalanceLoaded( balance = it, tokensCount = null, ), ) } + MultilineLambdaItParameter:ReviewManagerRequester.kt$ReviewManagerRequester${ handleOnCompleteRequestTask( reviewManager = reviewManager, activity = context.findActivity(), task = it, onDismissClick = onDismissClick, ) } + MultilineLambdaItParameter:SetRefreshStateTransformer.kt$SetRefreshStateTransformer${ it.mapNotNull { button -> when (button) { is WalletManageButton.Buy -> button.copy(enabled = isButtonsEnabled) is WalletManageButton.Send -> button.copy(enabled = isButtonsEnabled) is WalletManageButton.Sell -> button.copy(enabled = isButtonsEnabled) is WalletManageButton.Receive -> button is WalletManageButton.Stake -> null is WalletManageButton.Swap -> null } } } + MultilineLambdaItParameter:SetVisaInfoTransformer.kt$SetVisaInfoTransformer${ if (it is RefreshTokenExpiredException) { return getRefreshTokenExpiredState(prevState) } return prevState.copy( buttons = createVisaButtonsDimmed(), walletCardState = getErrorWalletCardState(prevState.walletCardState), balancesAndLimitBlockState = BalancesAndLimitsBlockState.Error, ) } + MultilineLambdaItParameter:SingleWalletExpressStatusesSubscriber.kt$SingleWalletExpressStatusesSubscriber${ Timber.e("Unable to get primary currency status: $it") return@onEach } + MultilineLambdaItParameter:SingleWalletOnrampTransactionConverter.kt$SingleWalletOnrampTransactionConverter${ analyticsEventHandler.send(TokenOnrampAnalyticsEvent.GoToProvider) clickIntents.onGoToProviderClick(it) } + MultilineLambdaItParameter:TokenListAnalyticsSender.kt$TokenListAnalyticsSender${ val status = it.value if (status is CryptoCurrencyStatus.Loaded) { sendTokenBalancesForSpecificBlockchains(it, status) } } + MultilineLambdaItParameter:TokenListStateConverter.kt$TokenListStateConverter${ if (isExtend) { clickIntents.onAccountCollapseClick(it) } else { clickIntents.onAccountExpandClick(it) } } + MultilineLambdaItParameter:TxHistorySubscriber.kt$TxHistorySubscriber${ SetTxHistoryCountErrorTransformer( userWallet = userWallet, error = it, pendingTransactions = status.value.pendingTransactions, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:TxHistorySubscriber.kt$TxHistorySubscriber${ SetTxHistoryCountTransformer( userWalletId = userWallet.walletId, transactionsCount = it, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:TxHistorySubscriber.kt$TxHistorySubscriber${ SetTxHistoryItemsErrorTransformer( userWalletId = userWallet.walletId, error = it, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:TxHistorySubscriberV2.kt$TxHistorySubscriberV2${ SetTxHistoryCountErrorTransformer( userWallet = userWallet, error = it, pendingTransactions = status.value.pendingTransactions, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:TxHistorySubscriberV2.kt$TxHistorySubscriberV2${ SetTxHistoryCountTransformer( userWalletId = userWallet.walletId, transactionsCount = it, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:TxHistorySubscriberV2.kt$TxHistorySubscriberV2${ SetTxHistoryItemsErrorTransformer( userWalletId = userWallet.walletId, error = it, clickIntents = clickIntents, ) } + MultilineLambdaItParameter:UpdateMultiWalletActionsTransformer.kt$UpdateMultiWalletActionsTransformer${ when (it) { is WalletManageButton.Buy -> { it.copy( enabled = buyStatus.isContent(), dimContent = !buyStatus.isContent(), ) } is WalletManageButton.Sell -> { it.copy( enabled = sellStatus.isContent(), dimContent = !sellStatus.isContent(), ) } is WalletManageButton.Swap -> { it.copy( enabled = swapStatus.isContent(), dimContent = !swapStatus.isContent(), ) } else -> it } } + MultilineLambdaItParameter:UseCaseExt.kt${ Timber.e("Impossible to get primary currency status $it") null } + MultilineLambdaItParameter:UseCaseExt.kt${ Timber.e("Impossible to get selected wallet $it") null } + MultilineLambdaItParameter:VisaWalletIntents.kt$VisaWalletIntentsImplementor${ Timber.e("Unable to get balances and limits: $it") return@launch } + MultilineLambdaItParameter:VisaWalletIntents.kt$VisaWalletIntentsImplementor${ Timber.e(it, "Failed to get transaction details") return@launch } + MultilineLambdaItParameter:VisaWalletIntents.kt$VisaWalletIntentsImplementor${ Timber.e(it, "Failed to get visa currency") return@launch } + MultilineLambdaItParameter:VisaWalletSubscriber.kt$VisaWalletSubscriber${ Timber.e(it, "Failed to load VISA currency") setFailedTxHistoryState(it) return@flow } + MultilineLambdaItParameter:VisaWalletSubscriber.kt$VisaWalletSubscriber${ Timber.e(it, "Failed to load tx history for wallet ${userWallet.walletId}") throw it } + MultilineLambdaItParameter:WalletCard.kt${ haptic.performHapticFeedback(HapticFeedbackType.LongPress) isMenuVisible = true pressOffset = DpOffset(x = it.x.toDp(), y = it.y.toDp()) } + MultilineLambdaItParameter:WalletCard.kt${ val press = PressInteraction.Press(it) interactionSource.emit(press) tryAwaitRelease() interactionSource.emit(PressInteraction.Release(press)) } + MultilineLambdaItParameter:WalletCardClickIntents.kt$WalletCardClickIntentsImplementor${ Timber.e("Unable to delete user wallet: $it") return@launch } + MultilineLambdaItParameter:WalletClickIntents.kt$WalletClickIntents${ if (!it.isLocked) { launch { walletContentFetcher(userWalletId = it.walletId) } } walletScreenContentLoader.load( userWallet = it, clickIntents = this@WalletClickIntents, coroutineScope = modelScope, ) } + MultilineLambdaItParameter:WalletContentClickIntents.kt$WalletContentClickIntentsImplementor${ Timber.e( """ Unable to get user wallet |- ID: $userWalletId |- Exception: $it """.trimIndent(), ) return@launch } + MultilineLambdaItParameter:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor${ analyticsEventHandler.send(TokenReceiveAnalyticsEvent.ButtonCopyAddress(currency.symbol)) clipboardManager.setText(text = it, isSensitive = true) } + MultilineLambdaItParameter:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor${ analyticsEventHandler.send(TokenReceiveAnalyticsEvent.ButtonShareAddress(currency.symbol)) shareManager.shareText(text = it) } + MultilineLambdaItParameter:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor${ onAddressTypeSelected( userWalletId = userWalletId, currency = currency, addressModel = it, ) } + MultilineLambdaItParameter:WalletDropDownItemsSubscriber.kt$WalletDropDownItemsSubscriber${ stateHolder.update( SetWalletCardDropDownItemsTransformer( dropdownEnabled = it, clickIntents = clickIntents, ), ) } + MultilineLambdaItParameter:WalletLoaderStorage.kt$WalletLoaderStorage${ it.forEach(Job::cancel) loaders.remove(id) } + MultilineLambdaItParameter:WalletModel.kt$WalletModel${ it .conflate() .distinctUntilChanged() .onEach { selectedWallet -> if (selectedWallet.isMultiCurrency) { selectedWalletAnalyticsSender.send(selectedWallet) } subscribeOnExpressTransactionsUpdates(selectedWallet) observeAndClearNFTCacheIfNeedUseCase(selectedWallet) } .flowOn(dispatchers.main) .launchIn(modelScope) } + MultilineLambdaItParameter:WalletModel.kt$WalletModel${ walletScreenContentLoader.load( userWallet = it, clickIntents = clickIntents, coroutineScope = modelScope, isRefresh = true, ) } + MultilineLambdaItParameter:WalletModel.kt$WalletModel${ walletsUpdateActionResolver.resolve( wallets = it, currentState = stateHolder.value, ) } + MultilineLambdaItParameter:WalletNFTListSubscriber.kt$WalletNFTListSubscriber${ stateHolder.update( SetNFTCollectionsTransformer( userWalletId = userWallet.walletId, nftCollections = it, onItemClick = { clickIntents.onNFTClick(userWallet) }, ), ) } + MultilineLambdaItParameter:WalletNFTListSubscriberV2.kt$WalletNFTListSubscriberV2${ stateController.update( SetNFTCollectionsTransformer( userWalletId = userWallet.walletId, nftCollections = it, onItemClick = { clickIntents.onNFTClick(userWallet) }, ), ) } + MultilineLambdaItParameter:WalletNameMigrationUseCase.kt$WalletNameMigrationUseCase${ val defaultName = it.name val suggestedWalletName = suggestedWalletName(defaultName, existingNames) if (defaultName != suggestedWalletName) { userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true) } Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName) } + MultilineLambdaItParameter:WalletNotifications.kt${ // TODO develop promo banner general component when (it) { is WalletNotification.SwapPromo -> { // Use it on new promo action } is WalletNotification.NoteMigration -> { NoteMigrationNotification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), ) } is WalletNotification.FinishWalletActivation -> { Notification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), ) } else -> { Notification( config = it.config, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null), iconTint = when (it) { is WalletNotification.Critical -> TangemTheme.colors.icon.warning is WalletNotification.Informational -> TangemTheme.colors.icon.accent is WalletNotification.RateApp -> TangemTheme.colors.icon.attention is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1 is WalletNotification.UsedOutdatedData -> TangemTheme.colors.text.attention else -> null }, ) } } } + MultilineLambdaItParameter:WalletScreen.kt${ PaddingValues( bottom = it.calculateBottomPadding() + marketHintAproxHeight + 52.dp, ) } + MultilineLambdaItParameter:WalletScreen.kt${ WalletSnackbarHost( snackbarHostState = it, event = state.event, modifier = Modifier .padding(bottom = TangemTheme.dimens.spacing4) .navigationBarsPadding(), ) } + MultilineLambdaItParameter:WalletScreen.kt${ balancesAndLimitsBlock( modifier = itemModifier, state = it.balancesAndLimitBlockState, ) } + MultilineLambdaItParameter:WalletScreen.kt${ findPortfolioVisibleState( portfolio = it, expandedState = expandedState, collapsedState = collapsedState, ) } + MultilineLambdaItParameter:WalletScreen.kt${ it.organizeTokensButtonConfig?.let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } } + MultilineLambdaItParameter:WalletScreen.kt${ nftCollections( modifier = itemModifier, state = it.nftState, ) } + MultilineLambdaItParameter:WalletWarningsClickIntents.kt$WalletWarningsClickIntentsImplementor${ Timber.e( """ Unable to get user wallet |- ID: $userWalletId |- Exception: $it """.trimIndent(), ) null } + MultilineLambdaItParameter:WalletWarningsClickIntents.kt$WalletWarningsClickIntentsImplementor${ router.openOnboardingScreen( scanResponse = it.scanResponse, continueBackup = true, ) } + MultilineLambdaItParameter:WalletWarningsClickIntents.kt$WalletWarningsClickIntentsImplementor${ when (it) { UnlockWalletError.AlreadyUnlocked -> Unit UnlockWalletError.ScannedCardWalletNotMatched -> { uiMessageSender.send( message = DialogMessage( title = resourceReference(R.string.common_warning), message = resourceReference(R.string.error_wrong_wallet_tapped), ), ) } UnlockWalletError.UnableToUnlock -> { Timber.e("Unable to unlock wallet with id: $selectedUserWalletId") uiMessageSender.send( SnackbarMessage(TextReference.Res(R.string.generic_error)), ) } UnlockWalletError.UserCancelled -> Unit UnlockWalletError.UserWalletNotFound -> { // This should never happen in this flow Timber.e("User wallet not found for unlock: $selectedUserWalletId") uiMessageSender.send( SnackbarMessage(TextReference.Res(R.string.generic_error)), ) } } } + MultilineLambdaItParameter:WalletWithFundsChecker.kt$WalletWithFundsChecker${ val amount = it.value.amount ?: return@any false !amount.isZero() } + MultilineLambdaItParameter:WalletsUpdateActionResolver.kt$WalletsUpdateActionResolver${ if (it.warnings.any { it is WalletNotification.FinishWalletActivation }) { it.walletCardState.id } else { null } } + NamedArguments:BasicAccountListSubscriber.kt$BasicAccountListSubscriber$updateContent(convertParams, appCurrency, yieldSupplyApyMap, stakingApyMap) + NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addFinishWalletActivationNotification(userWallet, totalFiatBalance, clickIntents, accessCodeSkipped) + NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addInformationalNotifications(userWallet, cardTypesResolver, flattenCurrencies, clickIntents) + NamedArguments:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$addWarningNotifications(cardTypesResolver, flattenCurrencies, isNeedToBackup, clickIntents) + NamedArguments:TangemSnapFlingBehavior.kt$HighVelocityApproachAnimation$animateDecay(offset, animationState, decayAnimationSpec, onAnimationStep) + NamedArguments:TangemSnapFlingBehavior.kt$TangemSnapFlingBehavior$animateSnap( closestOffset, closestOffset, animationState, snapAnimationSpec, ) { delta -> remainingScrollOffset -= delta onRemainingScrollOffsetUpdate(remainingScrollOffset) } + NamedArguments:TangemSnapFlingBehavior.kt$TangemSnapFlingBehavior$animateSnap( remainingOffset, remainingOffset, animationState.copy(value = 0f), snapAnimationSpec, ) { delta -> remainingScrollOffset -= delta onAnimationStep(remainingScrollOffset) } + NamedArguments:TangemSnapFlingBehavior.kt$TangemSnapFlingBehavior$approach( initialTargetOffset, initialVelocity, animation, snapLayoutInfoProvider, density, onAnimationStep, ) + NamedArguments:TangemSnapFlingBehavior.kt$approachAnimation( this, initialTargetOffset, initialVelocity, onAnimationStep, ) + NamedArguments:WalletContent.kt$tokensListItems(state.tokensListState, modifier, isBalanceHidden, portfolioVisibleState) + NamedArguments:WalletContent.kt$txHistoryItems(state.txHistoryState, txHistoryItems, isBalanceHidden, modifier) + NamedArguments:WalletScreenContentLoader.kt$WalletScreenContentLoader$loadInternal(userWallet, clickIntents, coroutineScope, isRefresh = true) + NamedArguments:WalletScreenContentLoader.kt$WalletScreenContentLoader$loadInternal(userWallet, clickIntents, coroutineScope, isRefresh) + NestedScopeFunctions:WalletScreen.kt$let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } + NestedScopeFunctions:WalletScreen.kt$let { it.organizeTokensButtonConfig?.let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } } + NestedScopeFunctions:WalletScreen.kt$let { marketPriceBlockState -> marketPriceBlock(state = marketPriceBlockState, modifier = itemModifier) } + NoNameShadowing:DefaultUserWalletsFetcher.kt$DefaultUserWalletsFetcher${ it.isMultiCurrency } + NoNameShadowing:MultiCurrencyAccountContent.kt$modifier + NoNameShadowing:TxHistorySubscriber.kt$TxHistorySubscriber${ it.cachedIn(coroutineScope) } + NoNameShadowing:TxHistorySubscriberV2.kt$TxHistorySubscriberV2${ it.cachedIn(coroutineScope) } + NoNameShadowing:WalletComponent.kt$WalletComponent$dialog + NoNameShadowing:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor${ it is TokensListItemUM.Token } + NoNameShadowing:WalletNFTItem.kt$modifier + NoNameShadowing:WalletScreen.kt${ it.organizeTokensButtonConfig?.let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } } + NoNameShadowing:WalletWarningsClickIntents.kt$WalletWarningsClickIntentsImplementor${ when (it) { UnlockWalletError.AlreadyUnlocked -> Unit UnlockWalletError.ScannedCardWalletNotMatched -> { uiMessageSender.send( message = DialogMessage( title = resourceReference(R.string.common_warning), message = resourceReference(R.string.error_wrong_wallet_tapped), ), ) } UnlockWalletError.UnableToUnlock -> { Timber.e("Unable to unlock wallet with id: $selectedUserWalletId") uiMessageSender.send( SnackbarMessage(TextReference.Res(R.string.generic_error)), ) } UnlockWalletError.UserCancelled -> Unit UnlockWalletError.UserWalletNotFound -> { // This should never happen in this flow Timber.e("User wallet not found for unlock: $selectedUserWalletId") uiMessageSender.send( SnackbarMessage(TextReference.Res(R.string.generic_error)), ) } } } + NoNameShadowing:WalletsUpdateActionResolver.kt$WalletsUpdateActionResolver${ it is WalletNotification.FinishWalletActivation } + NonBooleanPropertyPrefixedWithIs:AccountDependencies.kt$AccountDependencies$val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:ExpandedAccountsHolder.kt$ExpandedAccountsHolder$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$private val isNeedToBackupUseCase: IsNeedToBackupUseCase + NonBooleanPropertyPrefixedWithIs:GetMultiWalletWarningsFactory.kt$GetMultiWalletWarningsFactory$private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase + NonBooleanPropertyPrefixedWithIs:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private val isNeedToBackupUseCase: IsNeedToBackupUseCase + NonBooleanPropertyPrefixedWithIs:GetSingleWalletWarningsFactory.kt$GetSingleWalletWarningsFactory$private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase + NonBooleanPropertyPrefixedWithIs:OrganizeTokensModel.kt$OrganizeTokensModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:ScreenLifecycleProvider.kt$ScreenLifecycleProvider$val isBackgroundState: StateFlow<Boolean> = _isBackgroundState + NonBooleanPropertyPrefixedWithIs:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor$private val isCryptoCurrencyCoinCouldHide: IsCryptoCurrencyCoinCouldHideUseCase + NonBooleanPropertyPrefixedWithIs:WalletCurrencyActionsClickIntents.kt$WalletCurrencyActionsClickIntentsImplementor$private val isDemoCardUseCase: IsDemoCardUseCase + NonBooleanPropertyPrefixedWithIs:WalletModel.kt$WalletModel$private val isWalletsScrollPreviewEnabled: IsWalletsScrollPreviewEnabled + NonBooleanPropertyPrefixedWithIs:WalletScreen.kt$val isAutoScroll = remember { mutableStateOf(value = false) } + NonBooleanPropertyPrefixedWithIs:WalletScreen.kt$val isNavBarVisible = remember { mutableStateOf(true) } + NullableToStringCall:DefaultPromoDeeplinkHandler.kt$DefaultPromoDeeplinkHandler$$bitcoinCurrency + NullableToStringCall:DefaultPromoDeeplinkHandler.kt$DefaultPromoDeeplinkHandler$$bitcoinStatus + NullableToStringCall:DefaultPromoDeeplinkHandler.kt$DefaultPromoDeeplinkHandler$${cryptoCurrencies?.size} + NullableToStringCall:DefaultPromoDeeplinkHandler.kt$DefaultPromoDeeplinkHandler$${networkStatuses?.size} + NullableToStringCall:WalletStateController.kt$WalletStateController$${transformer::class.simpleName} + NullableToStringCall:WalletSubscriber.kt$WalletSubscriber$${this::class.simpleName} + PropertyUsedBeforeDeclaration:BaseWalletClickIntents.kt$BaseWalletClickIntents$_modelScope + PropertyUsedBeforeDeclaration:BaseWalletClickIntents.kt$BaseWalletClickIntents$_router + PropertyUsedBeforeDeclaration:OrganizeTokensModel.kt$OrganizeTokensModel$uiState + PropertyUsedBeforeDeclaration:WalletScreenPreviewData.kt$WalletScreenPreviewData$buyButton + PropertyUsedBeforeDeclaration:WalletStateController.kt$WalletStateController$mutableUiState + ReusedModifierInstance:DefaultWalletEntryComponent.kt$DefaultWalletEntryComponent$Content(modifier) + ReusedModifierInstance:VisaTxDetailsBottomSheet.kt$LazyColumn( modifier = modifier.background(TangemTheme.colors.background.secondary), contentPadding = PaddingValues( bottom = TangemTheme.dimens.spacing16, ), verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing12), horizontalAlignment = Alignment.CenterHorizontally, ) { item { TransactionBlock(config.transaction) } items(config.requests) { item -> BlockchainRequestBlock(item) } item { DisputeButton(config.onDisputeClick) } } + ReusedModifierInstance:WalletNFTItem.kt$Image( modifier = modifier .background(TangemTheme.colors.stroke.primary), painter = painterResource(R.drawable.ic_nft_preview_more_16), contentDescription = null, ) + ReusedModifierInstance:WalletNFTItem.kt$SubcomposeAsyncImage( modifier = modifier, model = s.url, loading = { RectangleShimmer(radius = 0.dp) }, error = { Box( modifier = Modifier.background(TangemTheme.colors.field.primary), ) }, contentDescription = null, ) + ReusedModifierInstance:WalletNFTItem.kt$take(modifiers.size) + SuspendFunSwallowedCancellation:WalletModel.kt$WalletModel$runCatching + UnnecessaryLet:BalancesAndLimitsBottomSheetConverter.kt$BalancesAndLimitsBottomSheetConverter$let(::formatAmount) + UnnecessaryLet:MultiWalletContentLoader.kt$MultiWalletContentLoader$let(::add) + UnnecessaryLet:SingleWalletWithTokenContentLoader.kt$SingleWalletWithTokenContentLoader$let(::add) + UnnecessaryLet:TangemSnapFlingBehavior.kt$TangemSnapFlingBehavior$let { abs(it) * sign(initialVelocity) // ensure offset sign is correct } + UnnecessaryLet:WalletClickIntents.kt$WalletClickIntents$let(::add) + UnnecessaryLet:WalletScreen.kt$let { (state.tokensListState as? WalletTokensListState.ContentState)?.let { it.organizeTokensButtonConfig?.let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } } } + UnnecessaryLet:WalletScreen.kt$let { it.organizeTokensButtonConfig?.let { config -> organizeTokensButton( modifier = itemModifier, isEnabled = config.isEnabled, onClick = config.onClick, ) } } + UnnecessarySafeCall:SetVisaInfoTransformer.kt$SetVisaInfoTransformer$visaCurrency.fiatRate?.let { visaCurrency.balances.available.multiply(it) } + UseEmptyCounterpart:DefaultUserWalletImageFetcher.kt$DefaultUserWalletImageFetcher$mapOf<String, ArtworkUM>() + UseEmptyCounterpart:ExpandedAccountsHolder.kt$ExpandedAccountsHolder$mapOf() + UseEmptyCounterpart:ExpandedAccountsHolder.kt$ExpandedAccountsHolder$setOf() + UseEmptyCounterpart:PortfolioOrganizeTokensAnalyticsEvent.kt$PortfolioOrganizeTokensAnalyticsEvent$mapOf() + UseEmptyCounterpart:PromoActivationAnalytics.kt$PromoActivationAnalytics$mapOf() + UseEmptyCounterpart:SingleWalletExpressStatusesSubscriber.kt$SingleWalletExpressStatusesSubscriber$listOf() + UseEmptyCounterpart:SingleWalletExpressStatusesSubscriberV2.kt$SingleWalletExpressStatusesSubscriberV2$listOf() + UseEmptyCounterpart:TokenListStateConverter.kt$TokenListStateConverter$listOf() + UseEmptyCounterpart:WalletScreenAnalyticsEvent.kt$WalletScreenAnalyticsEvent.Basic$mapOf() + UseEmptyCounterpart:WalletScreenAnalyticsEvent.kt$WalletScreenAnalyticsEvent.MainScreen$mapOf() + UseEmptyCounterpart:WalletScreenAnalyticsEvent.kt$WalletScreenAnalyticsEvent.PushBannerPromo$mapOf() + UseOrEmpty:CryptoCurrenciesIdsResolver.kt$CryptoCurrenciesIdsResolver$accountStatusList?.accountStatuses ?.filter { it.getCryptoTokenList() != TokenList.Empty } ?.associate { accountStatus -> val currencies = accountStatus.flattenCurrencies() accountStatus.account as Account.CryptoPortfolio to draggableTokens .asSequence() .filter { it.accountId == accountStatus.account.accountId.value } .mapNotNull { sortedToken -> currencies.firstOrNull { it.currency.id.value == sortedToken.id }?.currency } .toList() } ?: emptyMap() + UseSumOfInsteadOfFlatMapSize:TokenListStateConverter.kt$TokenListStateConverter$flatMap(NetworkGroup::currencies) + VarCouldBeVal:TangemSnapFlingBehavior.kt$TangemSnapFlingBehavior$private var motionScaleDuration = DefaultScrollMotionDurationScale + VarCouldBeVal:WalletModel.kt$WalletModel$private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>() + + diff --git a/features/walletconnect/impl/detekt-baseline-debug.xml b/features/walletconnect/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..569bdbc31c --- /dev/null +++ b/features/walletconnect/impl/detekt-baseline-debug.xml @@ -0,0 +1,57 @@ + + + + + BooleanPropertyNaming:WcAppInfoBS.kt$var connectionRequestExpanded by remember { mutableStateOf(false) } + BooleanPropertyNaming:WcConnectButtonProgressTransformer.kt$WcConnectButtonProgressTransformer$private val showProgress: Boolean + BooleanPropertyNaming:WcConnectionsContent.kt$var showDropdownMenu by rememberSaveable { mutableStateOf(false) } + BooleanPropertyNaming:WcNetworkInfoItem.kt$WcNetworkInfoItem.Checkable$val checked: Boolean + BooleanPropertyNaming:WcNetworkInfoItem.kt$WcNetworkInfoItem.Checkable$val enabled: Boolean = true + BooleanPropertyNaming:WcNetworkInfoItem.kt$WcNetworkInfoItem.Checked$val enabled: Boolean = true + BooleanPropertyNaming:WcPrimaryButtonConfig.kt$WcPrimaryButtonConfig$val enabled: Boolean + BooleanPropertyNaming:WcPrimaryButtonConfig.kt$WcPrimaryButtonConfig$val showProgress: Boolean + BooleanPropertyNaming:WcSelectNetworksCheckedTransformer.kt$WcSelectNetworksCheckedTransformer$val doneButtonEnabled = available.any { it.checked } || prevState.required.isNotEmpty() + BooleanPropertyNaming:WcSelectNetworksModel.kt$WcSelectNetworksModel$val doneButtonEnabled = params.missingRequiredNetworks.isEmpty() && (params.requiredNetworks.isNotEmpty() || params.availableNetworks.isNotEmpty()) + BooleanPropertyNaming:WcSelectNetworksModel.kt$WcSelectNetworksModel$val editEnabled = params.missingRequiredNetworks.isEmpty() + BooleanPropertyNaming:WcSelectNetworksUM.kt$WcSelectNetworksUM$val doneButtonEnabled: Boolean + BooleanPropertyNaming:WcSendTransactionUM.kt$WcSendTransactionItemUM$val sendEnabled: Boolean + CanBeNonNullable:WcNavigationUtils.kt$feeSelectorComponentFactory: FeeSelectorComponent.Factory? = null + MaxChainedCallsOnSameLine:WcConnectedAppInfoModel.kt$WcConnectedAppInfoModel$session.sdkModel.appMetaData.icons.firstOrNull().orEmpty() + MaxChainedCallsOnSameLine:WcTransactionAppInfoContentUMConverter.kt$WcTransactionAppInfoContentUMConverter$value.session.sdkModel.appMetaData.icons.firstOrNull().orEmpty() + MultilineLambdaItParameter:WcConnectedAppInfoModel.kt$WcConnectedAppInfoModel${ WcNetworkInfoItem.Required( id = it.rawId, icon = it.iconResId, name = it.name, symbol = it.currencySymbol, ) } + MultilineLambdaItParameter:WcConnectionsContent.kt${ ConnectionItem( modifier = Modifier .fillMaxWidth() .background( color = TangemTheme.colors.background.primary, shape = RoundedCornerShape(TangemTheme.dimens.radius14), ) .clip(RoundedCornerShape(TangemTheme.dimens.radius14)), connection = it, ) } + MultilineLambdaItParameter:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter${ spendAllowanceUMConverter.convert( WcSpendAllowanceUMConverter.Input( approvedAmount = it, onLearnMoreClick = value.onApproveLearnMoreClick, ), ) } + MultilineLambdaItParameter:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter${ when (it) { is AmountInfo.FungibleTokens -> estimatedWalletChangeUMConverter.convert( WcEstimatedWalletChangeUMConverter.Input( amountInfo = it, iconRes = R.drawable.ic_receive_new_24, titleRes = R.string.common_receive, sign = StringsSigns.PLUS, ), ) is AmountInfo.NonFungibleTokens -> estimatedWalletChangeUMConverter.convert( WcEstimatedWalletChangeUMConverter.Input( amountInfo = it, iconRes = R.drawable.ic_receive_new_24, titleRes = R.string.common_receive, ), ) } } + MultilineLambdaItParameter:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter${ when (it) { is AmountInfo.FungibleTokens -> estimatedWalletChangeUMConverter.convert( WcEstimatedWalletChangeUMConverter.Input( amountInfo = it, iconRes = R.drawable.ic_send_new_24, titleRes = R.string.common_send, sign = StringsSigns.MINUS, ), ) is AmountInfo.NonFungibleTokens -> estimatedWalletChangeUMConverter.convert( WcEstimatedWalletChangeUMConverter.Input( amountInfo = it, iconRes = R.drawable.ic_send_new_24, titleRes = R.string.common_send, ), ) } } + MultilineLambdaItParameter:WcSendTransactionModel.kt$WcSendTransactionModel${ it?.copy( feeSelectorUM = feeSelectorUM, transaction = it.transaction.copy( sendEnabled = feeSelectorUM is FeeSelectorUM.Content && feeErrorNotification == null, feeErrorNotification = feeErrorNotification, ), ) } + MultilineLambdaItParameter:WcSwitchNetworkModel.kt$WcSwitchNetworkModel${ if (it.isExistInWcSession) { router.pop() } else { showErrorDialog(HandleMethodError.RequiredNetwork(it.network.name)) } } + NamedArguments:WcAddEthereumChainModalBottomSheetContent.kt$WcAddEthereumChainModalBottomSheetContent(state, {}, {}, {}) + NamedArguments:WcAlertsFactory.kt$WcAlertsFactory$createMaliciousDAppAlert(alertType.description, alertType.onClick, alertType.iconType, alertType.iconBgType) + NamedArguments:WcPairModel.kt$WcPairModel$handlePairState( pairState, portfolios, selected, isAccountMode, ) + NamedArguments:WcSendTransactionModel.kt$WcSendTransactionModel$buildUiState(securityCheck, useCase, signState, isApprovalMethod) + NestedScopeFunctions:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter$let { spendAllowanceUMConverter.convert( WcSpendAllowanceUMConverter.Input( approvedAmount = it, onLearnMoreClick = value.onApproveLearnMoreClick, ), ) } + NoNameShadowing:WcNavigationUtils.kt$model + NonBooleanPropertyPrefixedWithIs:WcConnectionsModel.kt$WcConnectionsModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:WcPairModel.kt$WcPairModel$private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase + NonBooleanPropertyPrefixedWithIs:WcPortfolioNameDelegate.kt$WcPortfolioNameDelegate$val isAccountMode = isAccountsModeEnabledUseCase.invoke() .stateIn(scope = scope, started = SharingStarted.Eagerly, initialValue = false) + NonBooleanPropertyPrefixedWithIs:WcRoutingModel.kt$WcRoutingModel$private val isSlotEmpty = MutableStateFlow(true) + NullCheckOnMutableProperty:WcCommonTransactionComponentDelegate.kt$WcCommonTransactionComponentDelegate$if (contentStack != null) { val content by contentStack!!.subscribeAsState() BackHandler(onBack = ::onChildBack) content.active.instance.BottomSheet() } + NullableBooleanCheck:WcPairModel.kt$WcPairModel$isAccountMode ?: false + NullableToStringCall:WcEstimatedWalletChangeUMConverter.kt$WcEstimatedWalletChangeUMConverter$${value.sign} + ReusedModifierInstance:DefaultWalletConnectEntryComponent.kt$DefaultWalletConnectEntryComponent$Content(modifier = modifier) + ReusedModifierInstance:WcAppInfoBS.kt$Box( modifier = modifier .padding(start = 48.dp) .border( width = 2.dp, color = TangemTheme.colors.background.action, shape = CircleShape, ) .padding(2.dp) .background(color = TangemTheme.colors.background.action) .size(20.dp) .clip(CircleShape) .background(color = TangemTheme.colors.icon.primary1.copy(alpha = 0.1F)), ) { Text( modifier = Modifier.align(Alignment.Center), text = "+$remainingCount", style = TangemTheme.typography.overline, color = TangemTheme.colors.text.secondary, ) } + ReusedModifierInstance:WcEstimatedWalletChangesLoadingItem.kt$Text( modifier = modifier .fillMaxWidth() .padding(start = 8.dp), text = stringResourceSafe(R.string.wc_common_loading), color = TangemTheme.colors.text.disabled, style = TangemTheme.typography.body2, ) + ReusedModifierInstance:WcEstimatedWalletChangesNotificationItem.kt$Text( modifier = modifier .fillMaxWidth() .padding(start = 12.dp, end = 12.dp, bottom = 14.dp), text = description?.resolveReference() ?: stringResourceSafe(R.string.wc_estimated_wallet_changes_not_simulated), color = TangemTheme.colors.text.tertiary, style = TangemTheme.typography.body2, ) + ReusedModifierInstance:WcSelectNetworksComponent.kt$HorizontalDivider( modifier = modifier.fillMaxWidth(), thickness = 1.dp, color = TangemTheme.colors.stroke.primary, ) + UnnecessaryAbstractClass:WcCommonTransactionComponentDelegate.kt$WcCommonTransactionComponentDelegate$WcCommonTransactionComponentDelegate + UnnecessaryLet:WcSendTransactionModel.kt$WcSendTransactionModel$let { stackNavigation.pushNew(WcTransactionRoutes.CustomAllowance) } + UnsafeCallOnNullableType:WcAddNetworkComponent.kt$WcAddNetworkComponent$content!! + UnsafeCallOnNullableType:WcCommonTransactionComponentDelegate.kt$WcCommonTransactionComponentDelegate$contentStack!! + UnsafeCallOnNullableType:WcPairComponent.kt$WcPairComponent$model.portfolioFetcher!! + UnsafeCallOnNullableType:WcSignTransactionComponent.kt$WcSignTransactionComponent$content!! + UnsafeCallOnNullableType:WcTransactionRequestInfoComponent.kt$WcTransactionRequestInfoComponent$content!! + UseEmptyCounterpart:WcPairModel.kt$WcPairModel$setOf<Network>() + UseOrEmpty:WcSpendAllowanceUMConverter.kt$WcSpendAllowanceUMConverter$value.approvedAmount.amount?.currencySymbol ?: "" + UseOrEmpty:WcTransactionCheckErrorItem.kt$notification.text?.resolveReference() ?: "" + + diff --git a/features/welcome/impl/detekt-baseline-debug.xml b/features/welcome/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..eebd20e796 --- /dev/null +++ b/features/welcome/impl/detekt-baseline-debug.xml @@ -0,0 +1,14 @@ + + + + + BooleanPropertyNaming:WelcomeModel.kt$WelcomeModel$private var routedOut = false + BooleanPropertyNaming:WelcomeUM.kt$WelcomeUM.SelectWallet$val showUnlockWithBiometricButton: Boolean = false + CanBeNonNullable:WelcomeModel.kt$WelcomeModel$specificWalletId: UserWalletId? + MultilineLambdaItParameter:WelcomeModel.kt$WelcomeModel${ if (it.isEmpty()) { router.replaceAll(AppRoute.Home()) } wallets.value = it } + MultilineLambdaItParameter:WelcomeModel.kt$WelcomeModel${ it.handle( specificWalletId = null, onUserCancelled = { tryToUnlockWithAccessCodeRightAway() }, ) setSelectWalletState() } + NullableToStringCall:WelcomeModel.kt$WelcomeModel$$specificWalletId + ReusedModifierInstance:Welcome.kt$WelcomePlain(modifier = modifier) + ReusedModifierInstance:Welcome.kt$WelcomeSelectWallet( state = st, modifier = modifier, ) + + diff --git a/features/yield-supply/api/detekt-baseline-debug.xml b/features/yield-supply/api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..2c1d5f69ba --- /dev/null +++ b/features/yield-supply/api/detekt-baseline-debug.xml @@ -0,0 +1,8 @@ + + + + + BooleanPropertyNaming:YieldSupplyComponent.kt$YieldSupplyComponent.Params$val handleNavigation: Boolean? = null + UseEmptyCounterpart:YieldSupplyAnalytics.kt$YieldSupplyAnalytics$mapOf() + + diff --git a/features/yield-supply/impl/detekt-baseline-debug.xml b/features/yield-supply/impl/detekt-baseline-debug.xml new file mode 100644 index 0000000000..0fef2c630f --- /dev/null +++ b/features/yield-supply/impl/detekt-baseline-debug.xml @@ -0,0 +1,34 @@ + + + + + BooleanPropertyNaming:YieldSupplyApyComponent.kt$YieldSupplyApyComponent$val state by loadingState.collectAsState() + BooleanPropertyNaming:YieldSupplyModel.kt$YieldSupplyModel$private val handleNavigation = params.handleNavigation + BooleanPropertyNaming:YieldSupplyModel.kt$YieldSupplyModel$val processing = uiState.value is YieldSupplyUM.Processing + BooleanPropertyNaming:YieldSupplyModel.kt$YieldSupplyModel$val showInfoIcon = cryptoCurrencyStatus.yieldSupplyNotAllAmountSupplied() + BooleanPropertyNaming:YieldSupplyModel.kt$YieldSupplyModel$val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend + BooleanPropertyNaming:YieldSupplyUM.kt$YieldSupplyUM.Content$val showInfoIcon: Boolean + BooleanPropertyNaming:YieldSupplyUM.kt$YieldSupplyUM.Content$val showWarningIcon: Boolean + MultilineLambdaItParameter:YieldSupplyApproveModel.kt$YieldSupplyApproveModel${ Timber.e(it) return } + MultilineLambdaItParameter:YieldSupplyModel.kt$YieldSupplyModel${ Timber.e(it) uiState.update { YieldSupplyUM.Content( title = resourceReference( R.string.yield_module_token_details_earn_notification_earning_on_your_balance_title, ), subtitle = resourceReference( R.string.yield_module_token_details_earn_notification_earning_on_your_balance_subtitle, ), rewardsApy = TextReference.EMPTY, onClick = ::onActiveClick, showWarningIcon = showWarningIcon, showInfoIcon = showInfoIcon, apy = "", ) } } + MultilineLambdaItParameter:YieldSupplyModel.kt$YieldSupplyModel${ Timber.e(it) uiState.update { YieldSupplyUM.Initial } } + MultilineLambdaItParameter:YieldSupplyModel.kt$YieldSupplyModel${ Timber.w(it.toString()) return@launch } + MultilineLambdaItParameter:YieldSupplyStartEarningModel.kt$YieldSupplyStartEarningModel${ Timber.w(it.toString()) showAlertError() } + NamedArguments:YieldSupplyActiveContent.kt$Icon( painterResource(R.drawable.ic_arrow_up_8), tint = TangemTheme.colors.text.accent, contentDescription = null, modifier = Modifier .padding(end = 6.dp) .size(12.dp), ) + NamedArguments:YieldSupplyActiveContent.kt$Icon( painterResource(R.drawable.ic_token_info_24), contentDescription = null, modifier = Modifier.size(20.dp), tint = TangemTheme.colors.text.warning, ) + NamedArguments:YieldSupplyChartUM.kt$YieldSupplyMarketChartDataUM.Companion$YieldSupplyMarketChartDataUM(y = y, x = x, avr = 5.15, "%.1f") + NoNameShadowing:YieldSupplyStopEarningModel.kt$YieldSupplyStopEarningModel$fee + NonBooleanPropertyPrefixedWithIs:YieldSupplyActiveComponent.kt$YieldSupplyActiveComponent.Params$val isBalanceHiddenFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:YieldSupplyActiveEntryComponent.kt$YieldSupplyActiveEntryComponent.Params$val isBalanceHiddenFlow: StateFlow<Boolean> + NonBooleanPropertyPrefixedWithIs:YieldSupplyActiveEntryModel.kt$YieldSupplyActiveEntryModel$val isTransactionInProgressFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NonBooleanPropertyPrefixedWithIs:YieldSupplyModel.kt$YieldSupplyModel$val isBalanceHiddenFlow: StateFlow<Boolean> field = MutableStateFlow(false) + NullableToStringCall:YieldSupplyModel.kt$YieldSupplyModel$$tokenPendingStatus + NullableToStringCall:YieldSupplyModel.kt$YieldSupplyModel$$tokenProtocolStatus + NullableToStringCall:YieldSupplyModel.kt$YieldSupplyModel$$yieldSupplyStatus + ReusedModifierInstance:YieldSupplyActiveContent.kt$Text( modifier = modifier, text = apyText, style = TangemTheme.typography.h2, color = TangemTheme.colors.text.accent, ) + ReusedModifierInstance:YieldSupplyActiveContent.kt$TextShimmer( modifier = modifier.width(94.dp), text = "", style = TangemTheme.typography.h2, ) + UnnecessaryEventHandlerParameter:YieldSupplyPromoContent.kt$onClick: (String) -> Unit + VarCouldBeVal:YieldSupplyApproveModel.kt$YieldSupplyApproveModel$private var userWallet = params.userWallet + VarCouldBeVal:YieldSupplyStopEarningModel.kt$YieldSupplyStopEarningModel$private var userWallet = params.userWallet + + diff --git a/libs/tangem-sdk-api/detekt-baseline-debug.xml b/libs/tangem-sdk-api/detekt-baseline-debug.xml new file mode 100644 index 0000000000..98aedb65f1 --- /dev/null +++ b/libs/tangem-sdk-api/detekt-baseline-debug.xml @@ -0,0 +1,13 @@ + + + + + BooleanPropertyNaming:TangemSdkManager.kt$TangemSdkManager$val needEnrollBiometrics: Boolean + ObjectExtendsThrowable:TapErrors.kt$TapError$NoInternetConnection : TapError + ObjectExtendsThrowable:TapErrors.kt$TapError$UnknownError : TapError + ObjectExtendsThrowable:TapErrors.kt$TapError.WalletManager$BlockchainIsUnreachableTryLater : TapError + ObjectExtendsThrowable:TapErrors.kt$TapSdkError$CardForDifferentApp : TapSdkError + ObjectExtendsThrowable:TapErrors.kt$TapSdkError$CardNotSupportedByRelease : TapSdkError + UseEmptyCounterpart:CreateProductWalletTaskResponse.kt$CreateProductWalletTaskResponse$mapOf() + + diff --git a/libs/visa/detekt-baseline-debug.xml b/libs/visa/detekt-baseline-debug.xml new file mode 100644 index 0000000000..084b518b4e --- /dev/null +++ b/libs/visa/detekt-baseline-debug.xml @@ -0,0 +1,11 @@ + + + + + BooleanPropertyNaming:VisaContractInfoProvider.kt$VisaContractInfoProvider.Builder$private val useTestnetRpc: Boolean + NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { fetchToken(paymentAccount) }, { fetchBalances(paymentAccount, paymentToken) }, { fetchLimits(paymentAccount, paymentToken, walletAddress) }, { token, balances, (oldLimit, newLimit, changeDate) -> VisaContractInfo( token = token, balances = balances, oldLimits = oldLimit, newLimits = newLimit, paymentAccountAddress = paymentAccount.contractAddress, limitsChangeDate = changeDate, ) }, ) + NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { loadPaymentAccount(walletAddress = walletAddress, paymentAccountAddress = paymentAccountAddress) }, { loadPaymentTokenInfo() }, { paymentAccount, paymentToken -> fetchBalancesAndLimits( paymentAccount = paymentAccount, paymentToken = paymentToken, walletAddress = walletAddress, ) }, ) + NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { paymentToken.contract.balanceOf(paymentAccount.contractAddress).send() }, { paymentAccount.verifiedBalance().send() }, { paymentAccount.availableForPayment().send() }, { paymentAccount.availableForWithdrawal().send() }, { paymentAccount.availableForDebtPayment().send() }, { paymentAccount.blockedAmount().send() }, { paymentAccount.debtAmount().send() }, ) { total, verified, payment, withdrawal, debtPayment, blocked, debt -> val decimals = paymentToken.decimals Balances( total = total.toBigDecimal(decimals), verified = verified.toBigDecimal(decimals), available = Balances.Available( forPayment = payment.toBigDecimal(decimals), forWithdrawal = withdrawal.toBigDecimal(decimals), forDebtPayment = debtPayment.toBigDecimal(decimals), ), blocked = blocked.toBigDecimal(decimals), debt = debt.toBigDecimal(decimals), ) } + NamedArguments:DefaultVisaContractInfoProvider.kt$DefaultVisaContractInfoProvider$parZip( dispatchers.io, { paymentTokenContract.name().send() }, { paymentTokenContract.symbol().send() }, { paymentTokenContract.decimals().send() }, ) { name, symbol, decimals -> Token( name = name, symbol = symbol, decimals = decimals.toInt(), address = paymentTokenContractAddress, ) } + + diff --git a/update_detekt_baseline.sh b/update_detekt_baseline.sh new file mode 100755 index 0000000000..80b6588f8e --- /dev/null +++ b/update_detekt_baseline.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +OUTPUT_FILE="${1:-detekt_baseline_report.txt}" + +INITIAL_ISSUES=1802 + +log() { + echo "$@" | tee -a "$OUTPUT_FILE" +} + +> "$OUTPUT_FILE" + +log "==========================================" +log "Detekt Baseline Updater & Issue Counter" +log "==========================================" +log "Date: $(date '+%Y-%m-%d %H:%M:%S')" +log "" + +log "Updating detekt baseline for debug variant..." +log "" + +./gradlew detektBaselineDebug + +log "" +log "Baseline updated successfully!" +log "" + +log "==========================================" +log "Counting issues in baseline files..." +log "==========================================" +log "" + +total_issues=0 +module_count=0 + +temp_file=$(mktemp) + +find . -name "detekt-baseline-debug.xml" -type f | while IFS= read -r file; do + issue_count=$(grep -c "" "$file" 2>/dev/null || echo "0") + + if [ "$issue_count" -gt 0 ]; then + module_name=$(echo "$file" | sed 's|^\./||' | sed 's|/detekt-baseline-debug.xml$||') + echo "$issue_count|$module_name" + fi +done | sort -rn -t'|' -k1 > "$temp_file" + +total_issues=$(awk -F'|' '{sum+=$1} END {print sum}' "$temp_file") +module_count=$(wc -l < "$temp_file" | tr -d ' ') + +log "Summary:" +log " Total Issues: $total_issues" +log " Modules with Issues: $module_count" + +if [ "$module_count" -gt 0 ]; then + avg_issues=$((total_issues / module_count)) + log " Average Issues per Module: $avg_issues" +fi + +fixed_issues=$((INITIAL_ISSUES - total_issues)) +progress_percent=$((fixed_issues * 100 / INITIAL_ISSUES)) + +log "" +log "Progress:" +if [ "$fixed_issues" -gt 0 ]; then + log " Fixed: $fixed_issues out of $INITIAL_ISSUES ($progress_percent%)" + log " Remaining: $total_issues" +elif [ "$fixed_issues" -lt 0 ]; then + new_issues=$((total_issues - INITIAL_ISSUES)) + log " Warning: $new_issues new issues added since baseline!" +else + log " Fixed: 0 out of $INITIAL_ISSUES (0%)" + log " Remaining: $total_issues" +fi + +log "" +log "==========================================" +log "All Modules with Issues (sorted by count)" +log "==========================================" +log "" +printf "%-60s %10s\n" "Module" "Issues" | tee -a "$OUTPUT_FILE" +log "────────────────────────────────────────────────────────────────" + +awk -F'|' '{printf "%-60s %10s\n", $2, $1}' "$temp_file" | tee -a "$OUTPUT_FILE" + +log "────────────────────────────────────────────────────────────────" + +rm "$temp_file" +