-
Notifications
You must be signed in to change notification settings - Fork 1
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
[VIO-104] feat: Implement IAP #991
Conversation
a3dfa23
to
d1da5f9
Compare
05e4821
to
8bfac6a
Compare
@zatteo @Crash-- I cleaned all current-progress commits and I added a description to the PR. Current progress can be reviewed and I think it can be merged (i still have to fix the CI error). The following steps will consist to:
They may be done in another PR |
5dbfea9
to
eef4e9d
Compare
J'approuve |
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.
Can you explain the reasoning behind this event emiter implementation?
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 is the same one we implemented for some other dialogs (ex: the one for OauthClientsLimitService)
The goal is that from anywhere in the code we can trigger this event to display the corresponding dialog.
Here we have two places that can trigger the ClouderyOffer dialog: the OauthClientsLimitService's navigation interception (in onShouldStartLoadWithRequest
) and the ReloadInterceptorWebView's one
The ClouderyOffer
dialog is declared somewhere in the app, and listen this event in order to chose when it should be displayed.
Another approach would be to create a root Context, but there are already a lot of root provider and I find this method easier to handle (one time event, no global rerender, no risk to forget declaring the context or to call the openDialog method outside of the context)
@@ -25,6 +25,9 @@ | |||
"title": "Déconnexion" | |||
}, | |||
"screens": { | |||
"clouderyOffer": { | |||
"backButton": "RETOUR À MON COZY" |
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.
OUAIS VIVE LES MAJ!
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.
902a997
to
81fd6c5
Compare
81fd6c5
to
6b73311
Compare
|
||
export const CLOUDERY_OFFER = 'CLOUDERY_OFFER' | ||
|
||
const START_IAP_REDIRECT_URL = 'https://iapflagship' |
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.
Those strings look more like config than code, maybe we should put them somewhere else
</View> | ||
) | ||
} | ||
|
||
const styles = StyleSheet.create({ |
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.
starting to have a lot of styles LoC in that file maybe we can extract it. Also it seems some of the value are magic numbers at first glance
@@ -94,6 +99,13 @@ const isStartIapUrl = (url: string): boolean => { | |||
return url.startsWith(START_IAP_URL) | |||
} | |||
|
|||
const isOsStoreUrl = (url: string): boolean => { | |||
return ( | |||
url.startsWith('https://apps.apple.com/account/subscriptions') || |
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.
same as earlier, I think those kinds of strings shouldn't be hardcoded into a "service" file. Maybe we can have "config" folders into a "domain" if we really want that kind of info to live near the code
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.
Left some comments but they are non blocking 👍
4bb373b
to
7b2a6c9
Compare
This package is needed by the following commits to implement InAppPurchase scenario
react-native-iap suggests minSdkVersion = 24 but it seems to work also with minSdkVersion = 21 (hyochan/react-native-iap#2423 and hyochan/react-native-iap#2528). So I decided to try without changing minSdKVersion. Updating kotlinVersion is also asked and does not break the build. I also decided to try without setting androidXAnnotation and AndroidXBrowser as suggested.
For now we want to add IAP support only for Cozy's app Adding react-native-iap package in package.json is enough to add the "in app purchase" flag to the store. This is because the react-native auto linking feature will automatically add the BILLING permission to Android To fix this and in order to have a generic solution, this commit adds the ability to set different packages configurations for each brand This is done in `white_label/config.json` in the `package` field. Either add the specified package version to fix it, or add `remove` to remove it
The ClouderyOffer view is responsible to show the Cloudery web page that will allow the user to buy premium plans We want to open it when intercepting "View offers" redirection in `OauthLimitExceeded` view
We want to open the ClouderyOffer view when intercepting "View offers" redirection in cozy-apps (i.e. paywalls modals)
We do nothing for the moment because : - cloudery is not ready - IAP is not ready and will be implemented in future commits
In the ClouderyOffer view, when the user click on a plan, we want to trigger the corresponding in-app purchase The IAP request is done by injecting the corresponding productId and the cozy's UUID that will be used by the Cloudery in order to link the IAP receipt with the corresponding Cozy instance During the IAP process, the ClouderyOffer view is hidden behind an overlay. For now this overlay is filled with primaryColor, but it should be replaced by a loading spinner later
If the user doesn't want to buy a premium plan, they should be able to manually close the ClouderyOffer view The close button's UI is the same as for CLISK launcher
Because the ClouderyOffer view's URL is provided by the cozy-app, we want to ensure it is legit by comparing it with the Cozy instance's URL and UUID Requires `cozy-intent` to be `>=43.4.1` Related PR: cozy/cozy-client#1418
The app cannot unsubscribe a plan by itself. The only thing we can do it to redirect the user to the OS Store's subscriptions page The Cloudery is expected to do this when the user clicks on the "Manage plan" button, then the app will intercept the corresponding link and open the OS page
This PR adds support for IAP by: