diff --git a/build.gradle b/build.gradle index e7aff89284..a8050354ef 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,7 @@ plugins { dependencies { detektPlugins libs.detekt.formatting + detektPlugins libs.detekt.compose } allprojects { diff --git a/config/detekt/detekt-baseline.xml b/config/detekt/detekt-baseline.xml index 5affcde2d7..95440616c8 100644 --- a/config/detekt/detekt-baseline.xml +++ b/config/detekt/detekt-baseline.xml @@ -2,9 +2,20 @@ + ComposableNaming:PaywallAPI.kt$PaywallAPI$check + ComposableNaming:PaywallAPI.kt$PaywallAPI$checkDialog + ComposableNaming:PaywallAPI.kt$PaywallAPI$checkFooter + ComposableParamOrder:AdaptiveComposable.kt$AdaptiveComposable + ComposableParamOrder:IntroEligibilityStateView.kt$IntroEligibilityStateView + ComposableParamOrder:PaywallIcon.kt$PaywallIcon + ComposableParamOrder:PaywallSuccessView.kt$DefaultMarketingContent + ComposableParamOrder:RemoteImage.kt$AsyncImage + ComposableParamOrder:RemoteImage.kt$Image + ComposableParamOrder:SettingOffering.kt$SettingOffering + ComposableParamOrder:Template7.kt$AnimatedPackages + CompositionLocalAllowlist:HelperFunctions.kt$LocalActivity CyclomaticComplexMethod:EntitlementInfo.kt$EntitlementInfo$override fun equals(other: Any?): Boolean DestructuringDeclarationWithTooManyEntries:Period.kt$val (year, month, week, day) = periodResult.destructured - EmptyCatchBlock:PurchasesOrchestrator.kt$PurchasesOrchestrator.Companion.<no name provided>${ } Filename:backendHelpers.kt$com.revenuecat.purchases.subscriberattributes.backendHelpers.kt Filename:billingClientParamBuilders.kt$com.revenuecat.purchases.google.billingClientParamBuilders.kt Filename:billingResultExtensions.kt$com.revenuecat.purchases.google.billingResultExtensions.kt @@ -42,22 +53,201 @@ MagicNumber:SampleWeatherData.kt$SampleWeatherData.Companion$91 MagicNumber:storeProductConversions.kt$3 MaxLineLength:Constants.kt$Constants$/* The entitlement ID from the RevenueCat dashboard that is activated upon successful in-app purchase for the duration of the purchase. Modify this property to reflect your app's entitlement identifier. */ + ModifierComposed:Placeholder.kt$placeholder + ModifierMissing:AppInfoScreen.kt$AppInfoScreen + ModifierMissing:CloseButton.kt$CloseButton + ModifierMissing:CustomerInfoDetailScreen.kt$CustomerInfoDetailScreen + ModifierMissing:CustomerInfoEventList.kt$CustomerInfoEventsList + ModifierMissing:CustomerInfoEventList.kt$CustomerInfoEventsListItem + ModifierMissing:DisableTouchesComposable.kt$DisableTouchesComposable + ModifierMissing:ExplanationScreen.kt$ExplanationScreen + ModifierMissing:InsetSpacers.kt$StatusBarSpacer + ModifierMissing:InsetSpacers.kt$SystemBarsSpacer + ModifierMissing:MainScreen.kt$MainScreen + ModifierMissing:MainScreen.kt$MainScreenNavigation + ModifierMissing:PaywallFooter.kt$PaywallFooter + ModifierMissing:PaywallFooterScreen.kt$PaywallFooterScreen + ModifierMissing:PaywallScreen.kt$PaywallScreen + ModifierMissing:PaywallsScreen.kt$PaywallsScreen + ModifierMissing:WeatherScreen.kt$WeatherScreen + ModifierNaming:Footer.kt$childModifier + ModifierNaming:IconImage.kt$childModifier + ModifierNaming:PurchaseButton.kt$childModifier + ModifierNaming:Template2.kt$childModifier + ModifierNotUsedAtRoot:Markdown.kt$modifier + ModifierNotUsedAtRoot:Markdown.kt$modifier = modifier + ModifierNotUsedAtRoot:Markdown.kt$overriddenStyle + ModifierNotUsedAtRoot:PaywallScreen.kt$modifier = modifier.padding(padding) + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier .fillMaxWidth() .weight(1f) + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(32.dp) + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier.clip(RoundedCornerShape(10.dp)).weight(2f, true) + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier.fillMaxSize() + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier.padding(16.dp) + ModifierNotUsedAtRoot:PaywallSuccessView.kt$modifier = modifier.padding(8.dp) + ModifierNotUsedAtRoot:Template4.kt$modifier = modifier .alpha(buttonAlpha) // Trick to prevent white line around the button border .padding(with(LocalDensity.current) { 1.toDp() }) .semantics { selected = isSelected // Append discount discountText?.let { text = AnnotatedString(it) } } .fillMaxHeight() + ModifierNotUsedAtRoot:UserScreen.kt$modifier = modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 8.dp) + ModifierNotUsedAtRoot:UserScreen.kt$modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(horizontal = 32.dp) + ModifierNotUsedAtRoot:UserScreen.kt$modifier = modifier.padding(16.dp) + ModifierNotUsedAtRoot:UserScreen.kt$modifier = modifier.padding(8.dp) + ModifierReused:Markdown.kt$Box( modifier = modifier .drawBehind { drawLine( color = color, strokeWidth = 2f, start = Offset(12.dp.value, 0f), end = Offset(12.dp.value, size.height), ) } .padding(start = 16.dp, top = 4.dp, bottom = 4.dp), ) { val text = buildAnnotatedString { pushStyle( MaterialTheme.typography.bodyLarge.toSpanStyle() .plus(SpanStyle(fontStyle = FontStyle.Italic)), ) appendMarkdownChildren(blockQuote, color, allowLinks) pop() } Text(text, modifier) } + ModifierReused:Markdown.kt$Box(modifier = modifier) { val styledText = buildAnnotatedString { pushStyle( style .copy(fontWeight = fontWeight) .toSpanStyle(), ) appendMarkdownChildren(paragraph as Node, color, allowLinks) pop() } MarkdownText(styledText, color, style, fontWeight, textAlign, allowLinks, modifier) } + ModifierReused:Markdown.kt$Box(modifier = modifier.padding(bottom = padding)) { val text = buildAnnotatedString { appendMarkdownChildren(heading, color, allowLinks) } MarkdownText(text, color, overriddenStyle, fontWeight, textAlign, allowLinks, modifier) } + ModifierReused:Markdown.kt$Box(modifier = modifier.padding(start = 8.dp, bottom = padding)) { Text( text = fencedCodeBlock.literal, style = TextStyle(fontFamily = FontFamily.Monospace), modifier = modifier, ) } + ModifierReused:Markdown.kt$Column(modifier = modifier.padding(start = start, bottom = bottom)) { var listItem = listBlock.firstChild while (listItem != null) { var child = listItem.firstChild while (child != null) { when (child) { is BulletList -> MDBulletList(child, color, style, fontWeight, textAlign, allowLinks, modifier) is OrderedList -> MDOrderedList(child, color, style, fontWeight, textAlign, allowLinks, modifier) else -> item(child) } child = child.next } listItem = listItem.next } } + ModifierReused:Markdown.kt$MDBulletList(child, color, style, fontWeight, textAlign, allowLinks, modifier) + ModifierReused:Markdown.kt$MDListItems( bulletList, color = color, style = style, fontWeight = fontWeight, textAlign = textAlign, allowLinks = allowLinks, modifier = modifier, ) { val text = buildAnnotatedString { pushStyle(MaterialTheme.typography.bodyLarge.toSpanStyle()) append("$marker ") appendMarkdownChildren(it, color, allowLinks) pop() } MarkdownText(text, color, style, fontWeight, textAlign, allowLinks, modifier) } + ModifierReused:Markdown.kt$MDListItems( orderedList, color = color, style = style, fontWeight = fontWeight, textAlign = textAlign, allowLinks = allowLinks, modifier = modifier, ) { val text = buildAnnotatedString { pushStyle(style.toSpanStyle()) append("${number++}$delimiter ") appendMarkdownChildren(it, color, allowLinks) pop() } MarkdownText(text, color, style, fontWeight, textAlign, allowLinks, modifier) } + ModifierReused:Markdown.kt$MDOrderedList(child, color, style, fontWeight, textAlign, allowLinks, modifier) + ModifierReused:Markdown.kt$MarkdownText(styledText, color, style, fontWeight, textAlign, allowLinks, modifier) + ModifierReused:Markdown.kt$MarkdownText(text, color, overriddenStyle, fontWeight, textAlign, allowLinks, modifier) + ModifierReused:Markdown.kt$MarkdownText(text, color, style, fontWeight, textAlign, allowLinks, modifier) + ModifierReused:Markdown.kt$Text( text = fencedCodeBlock.literal, style = TextStyle(fontFamily = FontFamily.Monospace), modifier = modifier, ) + ModifierReused:Markdown.kt$Text(text, modifier) + ModifierReused:PaywallSuccessView.kt$Box( modifier = modifier .fillMaxWidth() .weight(1f), ) { Column( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { Text( text = state.title, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.h5, ) Text( text = state.subtitle, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.subtitle1, ) } } + ModifierReused:PaywallSuccessView.kt$Box( modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(32.dp), contentAlignment = Alignment.Center, ) { DefaultMarketingContent(state = uiState) } + ModifierReused:PaywallSuccessView.kt$Column( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { Text( text = state.title, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.h5, ) Text( text = state.subtitle, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.subtitle1, ) } + ModifierReused:PaywallSuccessView.kt$Column( modifier = modifier.fillMaxSize().padding(horizontal = 32.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { if (marketingContent == null) { Box( modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(32.dp), contentAlignment = Alignment.Center, ) { DefaultMarketingContent(state = uiState) } } else { marketingContent() } Spacer(modifier = modifier.padding(8.dp)) uiState.offering.availablePackages .sortedBy { it.product.period?.unit } .forEach { packageToDisplay -> PackageButton(packageToDisplay, modifier) { activity, packageToPurchase -> viewModel.purchasePackage( activity, packageToPurchase, purchaseListener, ) } } Spacer(modifier = modifier.padding(16.dp)) } + ModifierReused:PaywallSuccessView.kt$Image( painter = painterResource(id = state.imageResource), modifier = modifier.clip(RoundedCornerShape(10.dp)).weight(2f, true), alignment = Alignment.Center, contentDescription = null, ) + ModifierReused:PaywallSuccessView.kt$PackageButton(packageToDisplay, modifier) { activity, packageToPurchase -> viewModel.purchasePackage( activity, packageToPurchase, purchaseListener, ) } + ModifierReused:PaywallSuccessView.kt$Spacer(modifier = modifier.padding(16.dp)) + ModifierReused:PaywallSuccessView.kt$Spacer(modifier = modifier.padding(8.dp)) + ModifierReused:PaywallSuccessView.kt$Text( text = state.subtitle, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.subtitle1, ) + ModifierReused:PaywallSuccessView.kt$Text( text = state.title, modifier = modifier, textAlign = TextAlign.Center, style = MaterialTheme.typography.h5, ) + ModifierReused:Template2.kt$AnimatedPackages( state, packageSelectionVisible, landscapeLayout = true, viewModel, childModifier, ) + ModifierReused:Template2.kt$IconImage(state, childModifier) + ModifierReused:Template2.kt$PurchaseButton(state, viewModel, childModifier) + ModifierReused:Template2.kt$PurchaseButton(state, viewModel, childModifier, horizontalPadding = 0.dp) + ModifierReused:Template2.kt$Subtitle(state, childModifier) + ModifierReused:Template2.kt$Subtitle(state, childModifier, TextAlign.Start) + ModifierReused:Template2.kt$Template2PortraitContent(state, viewModel, packageSelectorVisible, childModifier) + ModifierReused:Template2.kt$Title(state, childModifier) + ModifierReused:Template2.kt$Title(state, childModifier, TextAlign.Start) + ModifierReused:Template4.kt$Button( modifier = modifier .alpha(buttonAlpha) // Trick to prevent white line around the button border .padding(with(LocalDensity.current) { 1.toDp() }) .semantics { selected = isSelected // Append discount discountText?.let { text = AnnotatedString(it) } } .fillMaxHeight(), onClick = { viewModel.selectPackage(packageInfo) }, colors = ButtonDefaults.buttonColors(containerColor = colors.background), shape = RoundedCornerShape(UIConstant.defaultCornerRadius), contentPadding = PaddingValues( vertical = UIConstant.defaultVerticalSpacing, horizontal = UIConstant.defaultHorizontalPadding, ), ) { SelectPackageButtonContent(packageInfo, colors) } + ModifierReused:Template4.kt$Column( modifier = columnModifier .semantics(mergeDescendants = true) {}, horizontalAlignment = Alignment.CenterHorizontally, ) { DiscountRelativeToMostExpensivePerMonth(colors = colors, text = discountText, selected = isSelected) Box( modifier = Modifier // Apply the border to the box instead of the button to avoid the border showing // a white line around .border( width = UIConstant.defaultPackageBorderWidth, color = mainColor, shape = RoundedCornerShape(UIConstant.defaultCornerRadius), ), ) { Button( modifier = modifier .alpha(buttonAlpha) // Trick to prevent white line around the button border .padding(with(LocalDensity.current) { 1.toDp() }) .semantics { selected = isSelected // Append discount discountText?.let { text = AnnotatedString(it) } } .fillMaxHeight(), onClick = { viewModel.selectPackage(packageInfo) }, colors = ButtonDefaults.buttonColors(containerColor = colors.background), shape = RoundedCornerShape(UIConstant.defaultCornerRadius), contentPadding = PaddingValues( vertical = UIConstant.defaultVerticalSpacing, horizontal = UIConstant.defaultHorizontalPadding, ), ) { SelectPackageButtonContent(packageInfo, colors) } CheckmarkBox( isSelected = isSelected, colors = state.currentColors, modifier = Modifier .align(Alignment.TopEnd) .padding(Template4UIConstants.checkmarkPadding), ) } } + ModifierReused:UserScreen.kt$Box( modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(horizontal = 32.dp), contentAlignment = Alignment.Center, ) { UserInfo(uiState) } + ModifierReused:UserScreen.kt$Button( modifier = modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 8.dp), onClick = { viewModel.initiateLogIn() }, ) { Text(text = "Login") } + ModifierReused:UserScreen.kt$Button( modifier = modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 8.dp), onClick = { viewModel.restorePurchases() }, ) { Text(text = "Restore purchases") } + ModifierReused:UserScreen.kt$Column( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Box( modifier = modifier .fillMaxWidth() .weight(1f, true) .padding(horizontal = 32.dp), contentAlignment = Alignment.Center, ) { UserInfo(uiState) } Spacer(modifier = modifier.padding(8.dp)) Button( modifier = modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 8.dp), onClick = { viewModel.initiateLogIn() }, ) { Text(text = "Login") } Button( modifier = modifier .fillMaxWidth() .padding(horizontal = 32.dp, vertical = 8.dp), onClick = { viewModel.restorePurchases() }, ) { Text(text = "Restore purchases") } Spacer(modifier = modifier.padding(16.dp)) } + ModifierReused:UserScreen.kt$Spacer(modifier = modifier.padding(16.dp)) + ModifierReused:UserScreen.kt$Spacer(modifier = modifier.padding(8.dp)) + ModifierWithoutDefault:Footer.kt$childModifier + ModifierWithoutDefault:Markdown.kt$modifier + ModifierWithoutDefault:RemoteImage.kt$modifier + ModifierWithoutDefault:Template2.kt$childModifier + MultiLineIfElse:BillingWrapper.kt$BillingWrapper$googlePurchasingData.productId + MultiLineIfElse:ConfigureFragment.kt$ConfigureFragment$PurchasesConfiguration.Builder(application, apiKey) + MultiLineIfElse:ConfigureFragment.kt$ConfigureFragment$R.id.google_store_radio_id + MultiLineIfElse:CustomerInfoHelper.kt$CustomerInfoHelper$CustomerInfoStrings.CUSTOMERINFO_STALE_UPDATING_FOREGROUND + MultiLineIfElse:DeviceCache.kt$DeviceCache$VerificationResult.NOT_REQUESTED.name + MultiLineIfElse:OfferingsManager.kt$OfferingsManager$OfferingStrings.OFFERINGS_STALE_UPDATING_IN_FOREGROUND + MultiLineIfElse:Purchases.kt$Purchases$PurchasesAreCompletedBy.MY_APP + MultiLineIfElse:PurchasesConfiguration.kt$PurchasesConfiguration.Builder$PurchasesAreCompletedBy.REVENUECAT + MultiLineIfElse:PurchasesOrchestrator.kt$PurchasesOrchestrator$purchasingData.productId + MultiLineIfElse:SampleWeatherData.kt$SampleWeatherData$it.toString() + MultiLineIfElse:SubscriberAttributesManager.kt$SubscriberAttributesManager.ObtainDeviceIdentifiersObservable$listeners.add { completion() } + MutableStateAutoboxing:AdaptiveComposable.kt$mutableStateOf(0) + MutableStateAutoboxing:Placeholder.kt$mutableStateOf(0f) + MutableStateAutoboxing:TierSwitcher.kt$mutableStateOf(0) + MutableStateParam:PurchaseButton.kt$selectedPackage NoWildcardImports:PaywallFragment.kt$import com.revenuecat.purchases.* NoWildcardImports:UserFragment.kt$import com.revenuecat.purchases.* + ParameterNaming:AppInfoScreen.kt$onDismissed + ParameterNaming:CustomerInfoEventList.kt$onEventClicked + ParameterNaming:DebugRevenueCatBottomSheet.kt$onPurchaseCompleted + ParameterNaming:DebugRevenueCatBottomSheet.kt$onPurchaseErrored + ParameterNaming:DebugRevenueCatScreen.kt$onPurchaseCompleted + ParameterNaming:DebugRevenueCatScreen.kt$onPurchaseErrored + ParameterNaming:InternalDebugRevenueCatBottomSheet.kt$onPurchaseCompleted + ParameterNaming:InternalDebugRevenueCatBottomSheet.kt$onPurchaseErrored + ParameterNaming:InternalDebugRevenueCatScreen.kt$onPurchaseCompleted + ParameterNaming:InternalDebugRevenueCatScreen.kt$onPurchaseErrored + ParameterNaming:MainScreen.kt$onPurchaseClicked + ParameterNaming:PaywallSuccessView.kt$onPurchaseClicked + ParameterNaming:PurchasesDebugViewAPI.kt$PurchasesDebugViewAPI$onPurchaseCompleted + ParameterNaming:PurchasesDebugViewAPI.kt$PurchasesDebugViewAPI$onPurchaseErrored + ParameterNaming:TierSwitcher.kt$onTierSelected + PreviewPublic:AppInfoScreen.kt$AppInfoScreenPreview + PreviewPublic:CustomEntitlementComputationApp.kt$CustomEntitlementComputationAppPreview + PreviewPublic:ExplanationScreen.kt$ExplanationScreenPreview + PreviewPublic:MainActivity.kt$GreetingPreview + PreviewPublic:MainScreen.kt$MainScreenPreview + PreviewPublic:OfferingsScreen.kt$OfferingsScreenPreview + PreviewPublic:PaywallErrorView.kt$PaywallErrorViewPreview + PreviewPublic:PaywallLoadingView.kt$PaywallLoadingViewPreview + PreviewPublic:PaywallsScreen.kt$PaywallsScreenPreview + PreviewPublic:WeatherApp.kt$WeatherAppPreview SwallowedException:DeviceCache.kt$DeviceCache$e: ClassCastException SwallowedException:DeviceCache.kt$DeviceCache$e: JSONException SwallowedException:DeviceCache.kt$DeviceCache$e: NullPointerException - SwallowedException:PurchasesOrchestrator.kt$PurchasesOrchestrator.Companion.<no name provided>$e: IllegalArgumentException SwallowedException:utils.kt$e: PackageManager.NameNotFoundException ThrowingExceptionsWithoutMessageOrCause:BillingWrapper.kt$BillingWrapper$Throwable() TooGenericExceptionCaught:DeviceCache.kt$DeviceCache$e: NullPointerException TooGenericExceptionThrown:HTTPClient.kt$HTTPClient$throw RuntimeException(e) - TooManyFunctions:AmazonBilling.kt$AmazonBilling : BillingAbstractProductDataResponseListenerPurchaseResponseListenerPurchaseUpdatesResponseListenerUserDataResponseListener TooManyFunctions:HTTPClient.kt$HTTPClient TooManyFunctions:Purchases.kt$Purchases : LifecycleDelegate TooManyFunctions:SubscriberAttributesCache.kt$SubscriberAttributesCache TooManyFunctions:listenerConversions.kt$com.revenuecat.purchases.listenerConversions.kt UnusedParameter:SampleWeatherData.kt$SampleWeatherData.Companion$environment: Environment + ViewModelForwarding:AppInfoScreen.kt$LoginDialog(viewModel) { showLogInDialog = false } + ViewModelForwarding:Footer.kt$Footer( mode = templateConfiguration.mode, configuration = templateConfiguration.configuration, colors = colors, viewModel = viewModel, childModifier = childModifier, allPlansTapped = allPlansTapped, ) + ViewModelForwarding:InternalPaywall.kt$LoadedPaywall(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template1(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template2(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template3(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template4(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template5(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$Template7(state = state, viewModel = viewModel) + ViewModelForwarding:InternalPaywall.kt$TemplatePaywall(state = state, viewModel = viewModel) + ViewModelForwarding:LoadingPaywall.kt$Template2( state = state, viewModel = viewModel, childModifier = Modifier .placeholder( visible = true, shape = RoundedCornerShape(UIConstant.defaultPackageCornerRadius), highlight = Fade( highlightColor = LoadingPaywallConstants.placeholderColor, animationSpec = PlaceholderDefaults.fadeAnimationSpec, ), color = LoadingPaywallConstants.placeholderColor, ), ) + ViewModelForwarding:MainScreen.kt$SwitchUserDialog(viewModel) + ViewModelForwarding:PaywallFooterScreen.kt$PurchaseAlertDialog(viewModel, it) + ViewModelForwarding:PaywallScreen.kt$PurchaseAlertDialog(viewModel, it) + ViewModelForwarding:PurchaseButton.kt$PurchaseButton( colors = colors, packages = state.templateConfiguration.packages, selectedPackage = state.selectedPackage, viewModel = viewModel, horizontalPadding = horizontalPadding, childModifier = childModifier, ) + ViewModelForwarding:SettingGroup.kt$SettingOffering( settingState, activity = activity, screenViewModel = viewModel, ) + ViewModelForwarding:SettingOffering.kt$SettingPackage(rcPackage, activity, screenViewModel) + ViewModelForwarding:SettingOffering.kt$SettingSubscriptionOption( activity = activity, screenViewModel = screenViewModel, subscriptionOption = subscriptionOption, isDefaultOption = subscriptionOption == rcPackage.product.defaultOption, ) + ViewModelForwarding:Template1.kt$Footer(templateConfiguration = state.templateConfiguration, viewModel = viewModel) + ViewModelForwarding:Template1.kt$PurchaseButton(state, viewModel) + ViewModelForwarding:Template2.kt$AnimatedPackages( state, packageSelectionVisible, landscapeLayout = false, viewModel, childModifier, ) + ViewModelForwarding:Template2.kt$AnimatedPackages( state, packageSelectionVisible, landscapeLayout = true, viewModel, childModifier, ) + ViewModelForwarding:Template2.kt$Footer( templateConfiguration = state.templateConfiguration, viewModel = viewModel, childModifier = childModifier, allPlansTapped = { packageSelectorVisible = !packageSelectorVisible }, ) + ViewModelForwarding:Template2.kt$PurchaseButton(state, viewModel, childModifier) + ViewModelForwarding:Template2.kt$PurchaseButton(state, viewModel, childModifier, horizontalPadding = 0.dp) + ViewModelForwarding:Template2.kt$SelectPackageButton(state, packageInfo, viewModel, childModifier) + ViewModelForwarding:Template2.kt$Template2LandscapeContent(state, viewModel, packageSelectorVisible, childModifier) + ViewModelForwarding:Template2.kt$Template2PortraitContent(state, viewModel, packageSelectorVisible, childModifier) + ViewModelForwarding:Template3.kt$Footer(templateConfiguration = state.templateConfiguration, viewModel = viewModel) + ViewModelForwarding:Template3.kt$LandscapeContent(state, viewModel) + ViewModelForwarding:Template3.kt$PortraitContent(state, viewModel) + ViewModelForwarding:Template3.kt$PurchaseButton(state, viewModel) + ViewModelForwarding:Template3.kt$PurchaseButton(state, viewModel, horizontalPadding = 0.dp) + ViewModelForwarding:Template4.kt$Footer( templateConfiguration = state.templateConfiguration, viewModel = viewModel, allPlansTapped = { packageSelectorVisible = !packageSelectorVisible }, ) + ViewModelForwarding:Template4.kt$Packages(state, viewModel) + ViewModelForwarding:Template4.kt$PurchaseButton(state, viewModel) + ViewModelForwarding:Template4.kt$SelectPackageButton( state, packageInfo, viewModel, Modifier.width(packageWidth), ) + ViewModelForwarding:Template4.kt$Template4MainContent(state, viewModel) + ViewModelForwarding:Template5.kt$AnimatedPackages(state, viewModel) + ViewModelForwarding:Template5.kt$AnimatedPackages(state, viewModel, packageSelectionVisible) + ViewModelForwarding:Template5.kt$Footer( templateConfiguration = state.templateConfiguration, viewModel = viewModel, allPlansTapped = { packageSelectorVisible = !packageSelectorVisible }, ) + ViewModelForwarding:Template5.kt$PurchaseButton(state, viewModel) + ViewModelForwarding:Template5.kt$SelectPackageButton(state, packageInfo, viewModel) + ViewModelForwarding:Template5.kt$Template5LandscapeContent(state, viewModel) + ViewModelForwarding:Template5.kt$Template5PortraitContent(state, viewModel, packageSelectorVisible) + ViewModelForwarding:Template7.kt$AnimatedPackages( state = state, viewModel = viewModel, packages = selectedTier.packages, colors = colorForTier, ) + ViewModelForwarding:Template7.kt$AnimatedPackages( state = state, viewModel = viewModel, packages = selectedTier.packages, colors = colorForTier, packageSelectionVisible = packageSelectionVisible, ) + ViewModelForwarding:Template7.kt$Footer( templateConfiguration = state.templateConfiguration, viewModel = viewModel, colors = colorForTier, allPlansTapped = { packageSelectorVisible = !packageSelectorVisible }, ) + ViewModelForwarding:Template7.kt$PurchaseButton(state, viewModel, colors = colorForTier) + ViewModelForwarding:Template7.kt$SelectPackageButton(state, packageInfo, viewModel, colors) + ViewModelForwarding:Template7.kt$Template7LandscapeContent( state, viewModel, allTiers, selectedTier, ) { selectedTier = it state.selectPackage(selectedTier.defaultPackage) } + ViewModelForwarding:Template7.kt$Template7PortraitContent( state, viewModel, packageSelectorVisible, allTiers, selectedTier, ) { selectedTier = it state.selectPackage(selectedTier.defaultPackage) } + ViewModelForwarding:UserScreen.kt$LoginDialog(viewModel) + ViewModelInjection:InternalPaywall.kt$viewModel + ViewModelInjection:MainScreen.kt$viewModel + ViewModelInjection:PaywallScreen.kt$viewModel + ViewModelInjection:PaywallSuccessView.kt$viewModel + ViewModelInjection:WeatherScreen.kt$viewModel WildcardImport:PaywallFragment.kt$import com.revenuecat.purchases.* WildcardImport:UserFragment.kt$import com.revenuecat.purchases.* diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ee0c7b7263..2d6d1650a9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,8 @@ assertJ = "3.22.0" annotation = "1.3.0" mockwebserver = "4.2.0" tink = "1.8.0" -detekt = "1.23.0" +detekt = "1.23.6" +detektRulesCompose = "0.4.10" coroutines = "1.6.4" androidxNavigation = "2.5.3" appcompat = "1.4.1" @@ -91,6 +92,7 @@ assertJ = { module = "org.assertj:assertj-core", version.ref = "assertJ"} billing = { module = "com.android.billingclient:billing" , version.ref = "billing" } detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } +detekt-compose = { module = "io.nlopez.compose.rules:detekt", version.ref = "detektRulesCompose" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJSON"}