Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove PackageGroup #4413

Merged
merged 8 commits into from
Oct 31, 2024
Merged

Conversation

joshdholtz
Copy link
Member

Motivation

Remove unneeded package group from paywall components

Description

PackageGroupComponent was not really needed. It was an extra type of component to think of that didn't provide much value over a StackComponent.

  • Removed PackageGroupComponent (and its view and view model)
  • PackageComponent now has boolean if its default selected
  • PackageComponentViewModel now finds the Package from the package identifier
  • New PackageValidator class
    • Injected into recursive view model creator and collects PackageComponentViewModels all the package views
      • Previously this was done in PackageGroupViewModel however, PackageComponents can live anywhere in the paywall
      • Injecting this clas into the whole process is a way to collect all the view models without recursively finding them again later
    • Validate packages (that at least one exists)
    • Finds the default selected package

@joshdholtz joshdholtz requested review from a team October 28, 2024 05:17
Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

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

LGTM! just a suggestion... Also leaving it to someone with more context on the approach to approve

@@ -29,6 +28,7 @@ enum PaywallComponentViewModel {
extension PaywallComponent {

func toViewModel(
packageValidator: PackageValidator,
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm instead of passing the validator around the view models, would it be possible to perform an initial validation before starting to create views/viewmodels? I think it would be cleaner if after we can just assume it's valid. (There might be a reason why that's difficult not really sure, so FFTI).

Copy link
Member Author

@joshdholtz joshdholtz Oct 28, 2024

Choose a reason for hiding this comment

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

@tonidero This is what I wanted to do however, it would required traversing the component tree twice (since there is no standard placement for packages)

So I figured if we were already traversing/remapping the components to view models, might as well pull out the information we need at the same time?

It feels gross from a code aspect but felt better in performance? 🤷‍♂️ And maybe I should add this as a comment?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can abstract this away somehow. What about a wrapper function, e.g. buildInitialState(), that wraps toViewModel() and calls isValid at the end, and returns the root VIewModel + PaywallState?

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe we can abstract this away somehow. What about a wrapper function, e.g. buildInitialState(), that wraps toViewModel() and calls isValid at the end, and returns the root VIewModel + PaywallState?

I dooooo like an idea of this! I think I'd like to come back to that a little later though 🤷‍♂️ Once we have things out and have a little more time to breath? Or until this absolutely feels horrible? 😛

Copy link
Member

Choose a reason for hiding this comment

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

Yea it's not that much in the way, for sure! I'm okay with keeping it around for now.

Copy link
Member

@JayShortway JayShortway left a comment

Choose a reason for hiding this comment

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

I like it! Had some comments, mostly around ease of understanding.

RevenueCatUI/Templates/Components/PackageValidator.swift Outdated Show resolved Hide resolved
RevenueCatUI/Templates/Components/PackageValidator.swift Outdated Show resolved Hide resolved
@@ -29,6 +28,7 @@ enum PaywallComponentViewModel {
extension PaywallComponent {

func toViewModel(
packageValidator: PackageValidator,
Copy link
Member

Choose a reason for hiding this comment

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

This can get a default value of PackageValidator() so it almost becomes an implementation detail of the toViewModel() function. This is a usual pattern I think with recursive functions, where the top level call gets a default argument, which it then passes down to every recursive call.

Copy link
Member Author

Choose a reason for hiding this comment

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

@JayShortway I did think about this but I almost don't want to because it really needs to accept that single high level instance of PackageValidator. I want to make sure that its not accidentally skipped when somebody creates a new view model 😬

I'm kind of keeping it here for somebody adds another container component and needs to pass packageValidator into it and it causes a compile error if its missing 🤷‍♂️ Hopefully that makes sense 😅

Copy link
Member

Choose a reason for hiding this comment

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

Yea works for me! I can always get behind a lil more explicitness.

@@ -29,6 +28,7 @@ enum PaywallComponentViewModel {
extension PaywallComponent {

func toViewModel(
packageValidator: PackageValidator,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can abstract this away somehow. What about a wrapper function, e.g. buildInitialState(), that wraps toViewModel() and calls isValid at the end, and returns the root VIewModel + PaywallState?

Copy link
Member

@JayShortway JayShortway left a comment

Choose a reason for hiding this comment

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

Nice nice!

@joshdholtz joshdholtz merged commit ee3fb18 into main Oct 31, 2024
7 checks passed
@joshdholtz joshdholtz deleted the paywalls-components/remove-package-group branch October 31, 2024 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants