-
Notifications
You must be signed in to change notification settings - Fork 160
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
Code refactoring + more safety with freezed #270
Code refactoring + more safety with freezed #270
Conversation
Hi!! 👋 Thanks for opening and sorry about the delay in replying! This PR is absolutely amazing 🏆 Love how much cleaner this looks. Will do a more thorough review now, just wanted to start by stating how big a fan I am of having the serialization done in models instead of manually. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this PR is AWESOME 🔥. Thanks so much for opening!
I'm still going through it, sorry if I'm going slow.
I left a few comments in the meantime, let me know what you think!
analysis_options.yaml
Outdated
unnecessary_string_interpolations: true | ||
unnecessary_this: true | ||
invalid_annotation_target: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love the new rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: could we keep these alphabetized? I think this is the only one that isn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed that one
@JsonKey(name: 'current', nullable: true) Offering? current, | ||
}) = _Offerings; | ||
|
||
factory Offerings.fromJson(Map<String, dynamic> json) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this class looks much better than before, but the one missing element from it is the ability to get an offering by name, could you add it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checked for other getters|methods, my bad - fixed
|
||
/// This class contains all the offerings configured in RevenueCat dashboard. | ||
/// For more info see https://docs.revenuecat.com/docs/entitlements | ||
class Offerings with _$Offerings { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there might be an issue with the mapping for this class, when testing using the MagicWeather app I'm running into type '_InternalLinkedHashMap<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>'
when trying to getOfferings
. Does it work correctly for you? Maybe I'm missing a step
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch, below are the fixes
lib/models/offering_wrapper.dart
Outdated
final String serverDescription, | ||
|
||
/// Array of `Package` objects available for purchase. | ||
final List<Package> availablePackages, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps it would be clearer for readers to have the {
either as a separate line or as the first line in the first optional parameter, to clearly delineate the beginning of optional params? I had missed it at first, being at the end of this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts on this? @devasidmi
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's vscode autoformatting, do u have any idea how to change that behaviour without changing editor settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know 🤷♂️ . But if that's how it's auto-formatted, let's leave it like that
d6ab05d
to
cae7581
Compare
Thank you, I really wanted to participate and make the best subscription package even better ✌🏻 |
lib/models/offering_wrapper.dart
Outdated
final String serverDescription, | ||
|
||
/// Array of `Package` objects available for purchase. | ||
final List<Package> availablePackages, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any thoughts on this?
@JsonKey(name: 'currency_code') String currencyCode, { | ||
|
||
/// Introductory price for product. Can be null. | ||
@JsonKey(name: 'introPrice', nullable: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this needs to be intro_price
https://github.com/RevenueCat/purchases-flutter/blob/main/lib/product_wrapper.dart#L35
lib/models/introductory_price.dart
Outdated
class IntroductoryPrice with _$IntroductoryPrice { | ||
const factory IntroductoryPrice( | ||
/// Introductory price of a subscription in the local currency. | ||
@JsonKey(name: 'price') double introPrice, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The response is fine. The issue is that the JsonKey to use in product_wrapper for the introductoryPrice
should be introPrice
instead of intro_price
. introductory_price.dart
also needs to be updated to match the keys in the introPrice
object of the response:
'introPrice': {
'price': 0,
'priceString': '\$0.00',
'period': 'P1W',
'cycles': 1,
'periodUnit': 'DAY',
'periodNumberOfUnits': 7
},
The information is duplicated in the response, because we used to have the intro price information in the root of the JSON, then we moved it to its own object introPrice
and changed the json keys to be camelcase. We left the keys in the JSON root because other SDKs still use those :)
Let me know if you want me to do the update to fix the test :)
lib/models/introductory_price.dart
Outdated
|
||
/// Formatted introductory price of a subscription, including | ||
/// its currency sign, such as €3.99. | ||
@JsonKey(name: 'priceString') String introPriceString, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the mappings here should start with intro_
and use snake_case, right?
final purchaserInfo = PurchaserInfo.fromJson( | ||
Map<String, dynamic>.from(result['purchaserInfo']), | ||
); | ||
final bool created = result['created']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[not needed for this PR] we could add a loginResult.dart
freezed model to map this
static Future<void> close() async { | ||
await _channel.invokeMethod('close'); | ||
} | ||
static Future<void> close() => _channel.invokeMethod('close'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do these not need async
when using =>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really, because _channel.invokeMethod
returns Future<T>
and we don't need await
it. Only caller of method close
can await
it (but it's optional).
Thanks so much for updating! I left a few more comments |
I believe I got u right @vegaro |
@devasidmi sorry I missed the review request. I approved it but now there's some conflicts because we added a new property to entitlement info 😮💨 |
@devasidmi sorry to ask any more of you, but would you mind rebasing or otherwise solving the merge conflicts so we can merge? |
Sorry for the delays in the responses, I will do it soon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for this PR. And sorry it took so long to merge 🥴
Code improvements + more safety with hashcodes & json parsing with Freezed package
No PR or issue number
Single test failed because of wrong API key