From f91961c8b799012d6c40b2b8e8b98ce8160fc821 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Sat, 1 Apr 2023 23:01:52 -0300 Subject: [PATCH 01/14] initial --- src/api/api.js | 5 +++ .../Settings/Subscribe/Subscribe.constants.js | 8 ---- .../Settings/Subscribe/Subscribe.container.js | 39 +++++++------------ src/cordova-util.js | 2 +- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/api/api.js b/src/api/api.js index 93ea8f130..0953969bd 100644 --- a/src/api/api.js +++ b/src/api/api.js @@ -570,6 +570,11 @@ class API { ); return data; } + + async listSubscriptions() { + const { data } = await this.axiosInstance.get(`/subscription/list`); + return data; + } } const API_INSTANCE = new API({}); diff --git a/src/components/Settings/Subscribe/Subscribe.constants.js b/src/components/Settings/Subscribe/Subscribe.constants.js index bb13b170a..076962713 100644 --- a/src/components/Settings/Subscribe/Subscribe.constants.js +++ b/src/components/Settings/Subscribe/Subscribe.constants.js @@ -1,17 +1,9 @@ -export const AVAIABLE_PRODUCTS_ID = [ - { - subscriptionId: 'premium_full', - planId: ['premium-full-features-yearl', 'premium-full-feature-monthly'] - } -]; - export const INCLUDED_FEATURES = [ 'onlineNeuralVoices', 'copyPublicBoards', 'publishBoards', 'copyTiles', 'pasteTiles', - 'powerfulUsageAnalytics', 'shareBoards', 'adsFree', 'exportToOpenBoardFormat', diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index bcc6230cc..6563c6e55 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -7,7 +7,6 @@ import { getUser, isLogged } from '../../App/App.selectors'; import API from '../../../api'; import { isAndroid } from '../../../cordova-util'; -import { AVAIABLE_PRODUCTS_ID } from './Subscribe.constants'; import { comprobeSubscription, updateSubscriberId, @@ -43,33 +42,21 @@ export class SubscribeContainer extends PureComponent { this.setProducts(); } - setProducts = () => { + setProducts = async () => { if (isAndroid()) { - const validProducts = window.CdvPurchase.store.products.filter( - product => - product.offers.length > 0 && - AVAIABLE_PRODUCTS_ID.some(p => p.subscriptionId === product.id) - ); + let validProducts = []; + try { + validProducts = window.CdvPurchase.store.products.filter( + product => product.offers.length > 0 + ); + } catch (err) { + console.error( + 'Error getting subscription / product data. Error: ', + err.message + ); + } return this.setState({ products: validProducts }); } - - const products = [ - { - id: '1', - title: 'Preimum full', - offers: [ - { - id: 'premiumfull@month', - pricingPhases: [{ price: 'USD 6,00', billingPeriod: 'P1M' }] - }, - { - id: 'premiumfull@year', - pricingPhases: [{ price: 'USD 50,00', billingPeriod: 'P1Y' }] - } - ] - } - ]; - this.setState({ products: products }); }; handleChange = name => event => { @@ -132,12 +119,14 @@ export class SubscribeContainer extends PureComponent { billingPeriod: offer.pricingPhases[0].billingPeriod, price: offer.pricingPhases[0].price }; + console.log(newProduct); const apiProduct = { product: { ...newProduct, subscriptionId: product.id } }; + console.log(apiProduct); try { updateSubscription({ diff --git a/src/cordova-util.js b/src/cordova-util.js index 4ee20bcb7..47e3fe231 100644 --- a/src/cordova-util.js +++ b/src/cordova-util.js @@ -57,7 +57,7 @@ const configAppPurchasePlugin = () => { store.register([ { - id: 'premium_full', + id: 'one_year_subscription', type: ProductType.PAID_SUBSCRIPTION, platform: Platform.GOOGLE_PLAY } From 772f1661db97bda156355c5cb30fbcd635e6a544 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Mon, 3 Apr 2023 20:52:40 -0300 Subject: [PATCH 02/14] fixes --- src/components/Settings/Subscribe/Subscribe.container.js | 9 +++++---- src/components/Settings/Subscribe/SubscriptionInfo.js | 7 ------- src/cordova-util.js | 4 ---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index 6563c6e55..eacf3b4a2 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -46,6 +46,7 @@ export class SubscribeContainer extends PureComponent { if (isAndroid()) { let validProducts = []; try { + await window.CdvPurchase.store.update(); validProducts = window.CdvPurchase.store.products.filter( product => product.offers.length > 0 ); @@ -112,6 +113,8 @@ export class SubscribeContainer extends PureComponent { if (isAndroid()) { if ( isLogged && + product && + offer && subscription.androidSubscriptionState === NOT_SUBSCRIBED ) { const newProduct = { @@ -119,14 +122,12 @@ export class SubscribeContainer extends PureComponent { billingPeriod: offer.pricingPhases[0].billingPeriod, price: offer.pricingPhases[0].price }; - console.log(newProduct); const apiProduct = { product: { ...newProduct, subscriptionId: product.id } }; - console.log(apiProduct); try { updateSubscription({ @@ -157,12 +158,12 @@ export class SubscribeContainer extends PureComponent { const order = await window.CdvPurchase.store.order(offer); if (order && order.isError) throw order; } catch (e) { - console.error('Cannot subscribe product', e.message); + console.error('Cannot subscribe product. Error: ', e.message); this.handleError(e); } return; } - console.error('Cannot subscribe product', e.message); + console.error('Cannot subscribe product. Error: ', e.message); this.handleError(e); } } diff --git a/src/components/Settings/Subscribe/SubscriptionInfo.js b/src/components/Settings/Subscribe/SubscriptionInfo.js index abde47920..ce925e5ae 100644 --- a/src/components/Settings/Subscribe/SubscriptionInfo.js +++ b/src/components/Settings/Subscribe/SubscriptionInfo.js @@ -40,13 +40,6 @@ const subscriptionInfo = ({ onRefreshSubscription, intl }) => { - // const subscription = { - // plan: 'Premium All Features', - // status: 'active', - // planAmount: '3USD / month', - // nextPayment: '25/5/12' - // }; - const { title, billingPeriod, price } = product; const planAmount = `${price} / ${formatDuration(billingPeriod)}`; diff --git a/src/cordova-util.js b/src/cordova-util.js index 47e3fe231..dd7f93e66 100644 --- a/src/cordova-util.js +++ b/src/cordova-util.js @@ -62,11 +62,7 @@ const configAppPurchasePlugin = () => { platform: Platform.GOOGLE_PLAY } ]); - - store.verbosity = LogLevel.DEBUG; - //error handler - store.error(errorHandler); function errorHandler(error) { console.error(`ERROR ${error.code}: ${error.message}`); From 760bf4738dace3c4cc229a1e884bf0a62fcca3b9 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Wed, 5 Apr 2023 23:32:34 -0300 Subject: [PATCH 03/14] wip --- src/components/Board/Board.actions.js | 2 +- .../Settings/Subscribe/Subscribe.container.js | 10 ++-- .../SubscriptionProvider.actions.js | 49 +++++++++++------ .../SubscriptionProvider.constants.js | 2 +- .../SubscriptionProvider.container.js | 55 +++++++++++++------ .../SubscriptionProvider.reducer.js | 2 +- 6 files changed, 78 insertions(+), 42 deletions(-) diff --git a/src/components/Board/Board.actions.js b/src/components/Board/Board.actions.js index dc454b105..1bdbcaaea 100644 --- a/src/components/Board/Board.actions.js +++ b/src/components/Board/Board.actions.js @@ -52,7 +52,7 @@ import { updateDefaultBoardsIncluded, addDefaultBoardIncluded } from '../Communicator/Communicator.actions'; -import { isAndroid, isCordova, writeCvaFile } from '../../cordova-util'; +import { isAndroid, writeCvaFile } from '../../cordova-util'; import { DEFAULT_BOARDS } from '../../helpers'; import history from './../../history'; diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index eacf3b4a2..47863e114 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -8,7 +8,7 @@ import API from '../../../api'; import { isAndroid } from '../../../cordova-util'; import { - comprobeSubscription, + checkSubscription, updateSubscriberId, updateSubscription, updateAndroidSubscriptionState, @@ -37,7 +37,7 @@ export class SubscribeContainer extends PureComponent { componentDidMount() { if (isAndroid()) { window.CdvPurchase.store.when('subscription').updated(this.setProducts); - this.props.comprobeSubscription(); + this.props.checkSubscription(); } this.setProducts(); } @@ -70,10 +70,10 @@ export class SubscribeContainer extends PureComponent { handleSubmit = async () => {}; handleRefreshSubscription = () => { - const { comprobeSubscription } = this.props; + const { checkSubscription } = this.props; window.CdvPurchase.store.restorePurchases(); - comprobeSubscription(); + checkSubscription(); }; handleError = e => { @@ -214,7 +214,7 @@ const mapStateToProps = state => { const mapDispatchToProps = { updateSubscriberId, updateSubscription, - comprobeSubscription, + checkSubscription: checkSubscription, updateAndroidSubscriptionState, updateSubscriptionError, updateProduct diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js index 499df40a3..a05e3b1ad 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js @@ -15,7 +15,7 @@ import { REQUIRING_PREMIUM_COUNTRIES, UPDATE_PRODUCT } from './SubscriptionProvider.constants'; - +import API from '../../api'; import { isLogged } from '../../components/App/App.selectors'; export function updateIsInFreeCountry() { @@ -36,21 +36,12 @@ export function updateIsOnTrialPeriod() { return (dispatch, getState) => { const state = getState(); const userCreatedAt = state.app.userData.createdAt; - const { isInFreeCountry, isSubscribed } = getState().subscription; const isOnTrialPeriod = isUserOnTrialPeriod(userCreatedAt); dispatch({ type: UPDATE_IS_ON_TRIAL_PERIOD, isOnTrialPeriod }); - if ( - !isInFreeCountry && - !isOnTrialPeriod && - !isSubscribed && - isLogged(state) - ) - dispatch(showPremiumRequired({ showTryPeriodFinishedMessages: true })); - function isUserOnTrialPeriod(createdAt) { if (!createdAt) return false; //this case are already created users const createdAtDate = new Date(createdAt); @@ -65,6 +56,36 @@ export function updateIsOnTrialPeriod() { }; } +export function updateIsSubscribed() { + return async (dispatch, getState) => { + let isSubscribed = false; + try { + const state = getState(); + if (!isLogged(state)) { + dispatch({ + type: UPDATE_IS_SUBSCRIBED, + isSubscribed + }); + } else { + const userId = state.app.userData.id; + const { status } = await API.getSubscriber(userId); + isSubscribed = status.toLowerCase() === 'active' ? true : false; + dispatch({ + type: UPDATE_IS_SUBSCRIBED, + isSubscribed + }); + } + } catch (err) { + console.error(err.message); + isSubscribed = false; + dispatch({ + type: UPDATE_IS_SUBSCRIBED, + isSubscribed + }); + } + }; +} + export function updateAndroidSubscriptionState(payload = {}) { return { type: UPDATE_ANDROID_SUBSCRIPTION_STATE, @@ -77,12 +98,6 @@ export function updateSubscriberId(payload = {}) { payload }; } -export function updateIsSubscribed(payload) { - return { - type: UPDATE_IS_SUBSCRIBED, - payload - }; -} export function updateSubscription(payload) { return { type: UPDATE_SUBSCRIPTION, @@ -95,7 +110,7 @@ export function updateSubscriptionError(payload) { payload }; } -export function comprobeSubscription(payload) { +export function checkSubscription(payload) { return async (dispatch, getState) => { const { expiryDate, diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js index e65ff6da6..db5976dbb 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js @@ -23,4 +23,4 @@ export const PAUSED = 'paused'; export const EXPIRED = 'expired'; export const ON_HOLD = 'on_hold'; -export const REQUIRING_PREMIUM_COUNTRIES = ['US', 'GB']; // ISO-2 country codes +export const REQUIRING_PREMIUM_COUNTRIES = ['US', 'GB', 'AR']; // ISO-2 country codes diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index 7354809c7..679c6b23f 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -10,8 +10,9 @@ import { updateAndroidSubscriptionState, updateIsSubscribed, updateSubscription, - comprobeSubscription, - updateIsOnTrialPeriod + checkSubscription, + updateIsOnTrialPeriod, + showPremiumRequired } from './SubscriptionProvider.actions'; import { onAndroidResume } from '../../cordova-util'; import { NOT_SUBSCRIBED, PROCCESING } from './SubscriptionProvider.constants'; @@ -25,19 +26,24 @@ export class SubscriptionProvider extends Component { componentDidMount() { const { isSubscribed, - comprobeSubscription, + checkSubscription, + updateIsSubscribed, updateIsOnTrialPeriod, updateIsInFreeCountry } = this.props; + console.log('entro en mount'); if (isAndroid()) { + updateIsSubscribed(); + updateIsInFreeCountry(); + updateIsOnTrialPeriod(); + console.log(isSubscribed); this.configInAppPurchasePlugin(); if (isSubscribed) { - comprobeSubscription(); + checkSubscription(); } - onAndroidResume(() => comprobeSubscription()); - updateIsInFreeCountry(); - updateIsOnTrialPeriod(); + onAndroidResume(() => checkSubscription()); + this.updateSubscriptionTrialDialog(); } } @@ -49,7 +55,7 @@ export class SubscriptionProvider extends Component { updateIsOnTrialPeriod, subscriberId, androidSubscriptionState, - comprobeSubscription + checkSubscription } = this.props; if (!prevProps.isLogged && isLogged) { if (!prevProps.subscriberId && subscriberId) { @@ -58,7 +64,7 @@ export class SubscriptionProvider extends Component { localTransaction.length || androidSubscriptionState !== NOT_SUBSCRIBED ) - comprobeSubscription(); + checkSubscription(); } } if (prevProps.isLogged !== isLogged) { @@ -68,6 +74,19 @@ export class SubscriptionProvider extends Component { } }; + updateSubscriptionTrialDialog = () => { + const { + isLogged, + isInFreeCountry, + isOnTrialPeriod, + isSubscribed, + showPremiumRequired + } = this.props; + if (!isInFreeCountry && !isOnTrialPeriod && !isSubscribed && isLogged) { + showPremiumRequired({ showTryPeriodFinishedMessages: true }); + } + }; + configPurchaseValidator = () => { let count = 1; window.CdvPurchase.store.validator = async function(receipt, callback) { @@ -79,17 +98,17 @@ export class SubscriptionProvider extends Component { ok: true, data: res.data }); - } catch (e) { - if (!e.ok && e.data) { + } catch (err) { + if (!err.ok && err.data) { callback({ ok: false, - code: e.data?.code, // **Validation error code - message: e.error.message + code: err.data?.code, // **Validation error code + message: err.error.message }); } else { callback({ ok: false, - message: 'Impossible to proceed with validation, ' + e + message: 'Unable to proceed with validation, ' + err.message }); } if (count < 3) { @@ -98,7 +117,7 @@ export class SubscriptionProvider extends Component { count++; }, 1000 * count); } - console.error(e); + console.error(err); } }; window.CdvPurchase.store.validator_privacy_policy = [ @@ -151,6 +170,7 @@ export class SubscriptionProvider extends Component { } const mapStateToProps = state => ({ + isInFreeCountry: state.subscription.isInFreeCountry, isSubscribed: state.subscription.isSubscribed, expiryDate: state.subscription.expiryDate, androidSubscriptionState: state.subscription.androidSubscriptionState, @@ -163,9 +183,10 @@ const mapDispatchToProps = { updateAndroidSubscriptionState, updateIsSubscribed, updateSubscription, - comprobeSubscription, + checkSubscription, updateIsInFreeCountry, - updateIsOnTrialPeriod + updateIsOnTrialPeriod, + showPremiumRequired }; export default connect( diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js index 6a95aedbd..cea5946c1 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js @@ -64,7 +64,7 @@ function subscriptionProviderReducer(state = initialState, action) { case UPDATE_IS_SUBSCRIBED: return { ...state, - isSubscribed: action.payload + isSubscribed: action.isSubscribed }; case UPDATE_SUBSCRIPTION: const { From abfdfe98fab33fab14f1d5feb9cb6360eb7217c0 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Mon, 10 Apr 2023 20:29:45 -0300 Subject: [PATCH 04/14] wip --- .../Settings/Subscribe/Subscribe.container.js | 28 ++++----- .../SubscriptionProvider.actions.js | 58 ++++++++++--------- .../SubscriptionProvider.constants.js | 4 -- .../SubscriptionProvider.container.js | 49 +++++++--------- .../SubscriptionProvider.reducer.js | 28 +-------- 5 files changed, 71 insertions(+), 96 deletions(-) diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index 47863e114..55053cd7c 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -13,11 +13,13 @@ import { updateSubscription, updateAndroidSubscriptionState, updateSubscriptionError, - updateProduct + updateProduct, + updateIsSubscribed } from '../../../providers/SubscriptionProvider/SubscriptionProvider.actions'; import { NOT_SUBSCRIBED, - PROCCESING + PROCCESING, + EXPIRED } from '../../../providers/SubscriptionProvider/SubscriptionProvider.constants'; import { formatTitle } from './Subscribe.helpers'; @@ -36,10 +38,8 @@ export class SubscribeContainer extends PureComponent { componentDidMount() { if (isAndroid()) { - window.CdvPurchase.store.when('subscription').updated(this.setProducts); - this.props.checkSubscription(); + this.setProducts(); } - this.setProducts(); } setProducts = async () => { @@ -70,10 +70,10 @@ export class SubscribeContainer extends PureComponent { handleSubmit = async () => {}; handleRefreshSubscription = () => { - const { checkSubscription } = this.props; - + const { checkSubscription, updateIsSubscribed } = this.props; window.CdvPurchase.store.restorePurchases(); - checkSubscription(); + updateIsSubscribed(); + // checkSubscription(); }; handleError = e => { @@ -112,10 +112,11 @@ export class SubscribeContainer extends PureComponent { } = this.props; if (isAndroid()) { if ( - isLogged && - product && - offer && - subscription.androidSubscriptionState === NOT_SUBSCRIBED + (isLogged && + product && + offer && + subscription.androidSubscriptionState === NOT_SUBSCRIBED) || + subscription.androidSubscriptionState === EXPIRED ) { const newProduct = { title: formatTitle(product.title), @@ -217,7 +218,8 @@ const mapDispatchToProps = { checkSubscription: checkSubscription, updateAndroidSubscriptionState, updateSubscriptionError, - updateProduct + updateProduct, + updateIsSubscribed }; export default connect( diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js index a05e3b1ad..a32fc4e5f 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js @@ -1,9 +1,6 @@ import { - UPDATE_IS_IN_FREE_COUNTRY, - UPDATE_IS_ON_TRIAL_PERIOD, UPDATE_ANDROID_SUBSCRIPTION_STATE, UPDATE_SUBSCRIBER_ID, - UPDATE_IS_SUBSCRIBED, UPDATE_SUBSCRIPTION, UPDATE_SUBSCRIPTION_ERROR, SHOW_PREMIUM_REQUIRED, @@ -25,10 +22,12 @@ export function updateIsInFreeCountry() { ? state.app.userData?.location?.countryCode : state.app.unloggedUserLocation?.countryCode; const isInFreeCountry = !REQUIRING_PREMIUM_COUNTRIES.includes(locationCode); - dispatch({ - type: UPDATE_IS_IN_FREE_COUNTRY, - isInFreeCountry - }); + dispatch( + updateSubscription({ + isInFreeCountry + }) + ); + return isInFreeCountry; }; } @@ -37,10 +36,12 @@ export function updateIsOnTrialPeriod() { const state = getState(); const userCreatedAt = state.app.userData.createdAt; const isOnTrialPeriod = isUserOnTrialPeriod(userCreatedAt); - dispatch({ - type: UPDATE_IS_ON_TRIAL_PERIOD, - isOnTrialPeriod - }); + dispatch( + updateSubscription({ + isOnTrialPeriod + }) + ); + return isOnTrialPeriod; function isUserOnTrialPeriod(createdAt) { if (!createdAt) return false; //this case are already created users @@ -62,27 +63,33 @@ export function updateIsSubscribed() { try { const state = getState(); if (!isLogged(state)) { - dispatch({ - type: UPDATE_IS_SUBSCRIBED, - isSubscribed - }); + dispatch( + updateSubscription({ + isSubscribed + }) + ); } else { const userId = state.app.userData.id; const { status } = await API.getSubscriber(userId); - isSubscribed = status.toLowerCase() === 'active' ? true : false; - dispatch({ - type: UPDATE_IS_SUBSCRIBED, - isSubscribed - }); + isSubscribed = + status.toLowerCase() === ('active' || 'canceled') ? true : false; + dispatch( + updateSubscription({ + androidSubscriptionState: status.toLowerCase(), + isSubscribed + }) + ); } } catch (err) { console.error(err.message); isSubscribed = false; - dispatch({ - type: UPDATE_IS_SUBSCRIBED, - isSubscribed - }); + dispatch( + updateSubscription({ + isSubscribed + }) + ); } + return isSubscribed; }; } @@ -110,6 +117,7 @@ export function updateSubscriptionError(payload) { payload }; } + export function checkSubscription(payload) { return async (dispatch, getState) => { const { @@ -162,8 +170,6 @@ export function checkSubscription(payload) { }) ); } - if (!isExpired && androidSubscriptionState === ACTIVE && !isSubscribed) - dispatch(updateIsSubscribed(true)); } }; } diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js index db5976dbb..984941afa 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js @@ -1,10 +1,6 @@ -export const UPDATE_IS_ON_TRIAL_PERIOD = 'UPDATE_IS_ON_TRIAL_PERIOD'; -export const UPDATE_IS_IN_FREE_COUNTRY = - 'cboard/subscription/UPDATE_IS_IN_FREE_COUNTRY'; export const UPDATE_ANDROID_SUBSCRIPTION_STATE = 'cboard/subscription/UPDATE_ANDROID_SUBSCRIPTION_STATE'; export const UPDATE_SUBSCRIBER_ID = 'cboard/subscription/UPDATE_SUBSCRIBER_ID'; -export const UPDATE_IS_SUBSCRIBED = 'cboard/subscription/UPDATE_IS_SUBSCRIBED'; export const UPDATE_SUBSCRIPTION = 'cboard/subscription/UPDATE_SUBSCRIPTION'; export const UPDATE_SUBSCRIPTION_ERROR = 'cboard/subscription/UPDATE_SUBSCRIPTION_ERROR'; diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index 679c6b23f..9159d5d47 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -23,34 +23,36 @@ export class SubscriptionProvider extends Component { children: PropTypes.node.isRequired }; - componentDidMount() { + async componentDidMount() { const { - isSubscribed, + isLogged, checkSubscription, updateIsSubscribed, updateIsOnTrialPeriod, - updateIsInFreeCountry + updateIsInFreeCountry, + showPremiumRequired } = this.props; console.log('entro en mount'); if (isAndroid()) { - updateIsSubscribed(); - updateIsInFreeCountry(); - updateIsOnTrialPeriod(); - console.log(isSubscribed); + const isSubscribed = await updateIsSubscribed(); + const isInFreeCountry = updateIsInFreeCountry(); + const isOnTrialPeriod = updateIsOnTrialPeriod(); this.configInAppPurchasePlugin(); - if (isSubscribed) { - checkSubscription(); + //onAndroidResume(() => checkSubscription()); + console.log(isInFreeCountry, isOnTrialPeriod, isSubscribed, isLogged); + if (!isInFreeCountry && !isOnTrialPeriod && !isSubscribed && isLogged) { + showPremiumRequired({ showTryPeriodFinishedMessages: true }); } - onAndroidResume(() => checkSubscription()); - this.updateSubscriptionTrialDialog(); } } - componentDidUpdate = prevProps => { + componentDidUpdate = async prevProps => { + console.log('entro en update '); if (isAndroid()) { const { isLogged, + updateIsSubscribed, updateIsInFreeCountry, updateIsOnTrialPeriod, subscriberId, @@ -68,25 +70,17 @@ export class SubscriptionProvider extends Component { } } if (prevProps.isLogged !== isLogged) { - updateIsInFreeCountry(); - updateIsOnTrialPeriod(); + const isSubscribed = await updateIsSubscribed(); + const isInFreeCountry = updateIsInFreeCountry(); + const isOnTrialPeriod = updateIsOnTrialPeriod(); + console.log(isInFreeCountry, isOnTrialPeriod, isSubscribed, isLogged); + if (!isInFreeCountry && !isOnTrialPeriod && !isSubscribed && isLogged) { + showPremiumRequired({ showTryPeriodFinishedMessages: true }); + } } } }; - updateSubscriptionTrialDialog = () => { - const { - isLogged, - isInFreeCountry, - isOnTrialPeriod, - isSubscribed, - showPremiumRequired - } = this.props; - if (!isInFreeCountry && !isOnTrialPeriod && !isSubscribed && isLogged) { - showPremiumRequired({ showTryPeriodFinishedMessages: true }); - } - }; - configPurchaseValidator = () => { let count = 1; window.CdvPurchase.store.validator = async function(receipt, callback) { @@ -153,6 +147,7 @@ export class SubscriptionProvider extends Component { if (subscriberId) window.CdvPurchase.store.verify(receipt); }) .verified(receipt => { + console.log('entro en verified'); updateSubscription({ isSubscribed: true, expiryDate: receipt.collection[0].expiryDate, diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js index cea5946c1..4b2a7b014 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js @@ -1,6 +1,4 @@ import { - UPDATE_IS_IN_FREE_COUNTRY, - UPDATE_IS_ON_TRIAL_PERIOD, UPDATE_ANDROID_SUBSCRIPTION_STATE, UPDATE_SUBSCRIBER_ID, UPDATE_IS_SUBSCRIBED, @@ -26,7 +24,7 @@ const initialState = { code: '', message: '' }, - isInFreeCountry: false, + isInFreeCountry: true, isOnTrialPeriod: true, premiumRequiredModalState: { open: false, @@ -41,16 +39,6 @@ const initialState = { function subscriptionProviderReducer(state = initialState, action) { switch (action.type) { - case UPDATE_IS_IN_FREE_COUNTRY: - return { - ...state, - isInFreeCountry: action.isInFreeCountry - }; - case UPDATE_IS_ON_TRIAL_PERIOD: - return { - ...state, - isOnTrialPeriod: action.isOnTrialPeriod - }; case UPDATE_ANDROID_SUBSCRIPTION_STATE: return { ...state, @@ -61,22 +49,10 @@ function subscriptionProviderReducer(state = initialState, action) { ...state, subscriberId: action.payload }; - case UPDATE_IS_SUBSCRIBED: - return { - ...state, - isSubscribed: action.isSubscribed - }; case UPDATE_SUBSCRIPTION: - const { - expiryDate, - isSubscribed, - androidSubscriptionState - } = action.payload; return { ...state, - expiryDate, - isSubscribed, - androidSubscriptionState + ...action.payload }; case UPDATE_PRODUCT: return { From c62d0d33e68e317d5e26b62383a982df3c188802 Mon Sep 17 00:00:00 2001 From: Rodri Sanchez Date: Tue, 11 Apr 2023 12:42:02 -0300 Subject: [PATCH 05/14] Check subscription status before activate --- .../SubscriptionProvider.container.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index 9159d5d47..7b7e3e4bf 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -15,7 +15,13 @@ import { showPremiumRequired } from './SubscriptionProvider.actions'; import { onAndroidResume } from '../../cordova-util'; -import { NOT_SUBSCRIBED, PROCCESING } from './SubscriptionProvider.constants'; +import { + ACTIVE, + CANCELED, + IN_GRACE_PERIOD, + NOT_SUBSCRIBED, + PROCCESING +} from './SubscriptionProvider.constants'; import { isLogged } from '../../components/App/App.selectors'; export class SubscriptionProvider extends Component { @@ -148,12 +154,15 @@ export class SubscriptionProvider extends Component { }) .verified(receipt => { console.log('entro en verified'); + const state = receipt.collection[0]?.subscriptionState; + if ([ACTIVE, CANCELED, IN_GRACE_PERIOD].includes(state)) { updateSubscription({ isSubscribed: true, expiryDate: receipt.collection[0].expiryDate, androidSubscriptionState: receipt.collection[0].subscriptionState }); window.CdvPurchase.store.finish(receipt); + } }); }; From 4318b9b4a3a7c79a6deedc5bcf24eaa212df565c Mon Sep 17 00:00:00 2001 From: Rodri Sanchez Date: Tue, 11 Apr 2023 12:44:34 -0300 Subject: [PATCH 06/14] Fix verification on first purchase --- .../SubscriptionProvider.container.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index 7b7e3e4bf..71f98217c 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -129,11 +129,7 @@ export class SubscriptionProvider extends Component { }; configInAppPurchasePlugin = () => { - const { - updateSubscription, - androidSubscriptionState, - subscriberId - } = this.props; + const { updateSubscription, androidSubscriptionState } = this.props; this.configPurchaseValidator(); @@ -150,7 +146,7 @@ export class SubscriptionProvider extends Component { }) .receiptUpdated(receipt => {}) .approved(receipt => { - if (subscriberId) window.CdvPurchase.store.verify(receipt); + window.CdvPurchase.store.verify(receipt); }) .verified(receipt => { console.log('entro en verified'); From dd4211315555bb844a7ee7ebf7b851bae96b3f56 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Fri, 14 Apr 2023 00:44:32 -0300 Subject: [PATCH 07/14] wip --- .../Settings/Subscribe/Subscribe.component.js | 15 --- .../Settings/Subscribe/Subscribe.container.js | 109 ++++++++-------- .../Settings/Subscribe/SubscriptionInfo.js | 15 ++- .../Settings/Subscribe/SubscriptionPlans.js | 117 +++++++++--------- src/cordova-util.js | 2 +- .../SubscriptionProvider.actions.js | 85 +++++++++++-- .../SubscriptionProvider.constants.js | 2 - .../SubscriptionProvider.container.js | 12 +- .../SubscriptionProvider.reducer.js | 25 ++-- 9 files changed, 215 insertions(+), 167 deletions(-) diff --git a/src/components/Settings/Subscribe/Subscribe.component.js b/src/components/Settings/Subscribe/Subscribe.component.js index b832090cc..1d852d835 100644 --- a/src/components/Settings/Subscribe/Subscribe.component.js +++ b/src/components/Settings/Subscribe/Subscribe.component.js @@ -23,14 +23,6 @@ const propTypes = { * flag for user */ isLogged: PropTypes.bool.isRequired, - /** - * Name of user - */ - name: PropTypes.string.isRequired, - /** - * User email - */ - email: PropTypes.string.isRequired, /** * Handle refresh subscription */ @@ -38,8 +30,6 @@ const propTypes = { }; const defaultProps = { - name: '', - email: '', location: { country: null, countryCode: null } }; @@ -47,11 +37,7 @@ const Subscribe = ({ onClose, isLogged, onSubscribe, - name, - email, location: { country, countryCode }, - onSubmitPeople, - products, subscription, onRefreshSubscription }) => { @@ -66,7 +52,6 @@ const Subscribe = ({ {!subscription.isSubscribed ? ( { - if (isAndroid()) { - let validProducts = []; - try { - await window.CdvPurchase.store.update(); - validProducts = window.CdvPurchase.store.products.filter( - product => product.offers.length > 0 - ); - } catch (err) { - console.error( - 'Error getting subscription / product data. Error: ', - err.message - ); - } - return this.setState({ products: validProducts }); - } - }; + componentDidMount() {} handleChange = name => event => { this.setState({ @@ -70,9 +42,10 @@ export class SubscribeContainer extends PureComponent { handleSubmit = async () => {}; handleRefreshSubscription = () => { - const { checkSubscription, updateIsSubscribed } = this.props; + const { checkSubscription, updateIsSubscribed, updatePlans } = this.props; window.CdvPurchase.store.restorePurchases(); updateIsSubscribed(); + updatePlans(); // checkSubscription(); }; @@ -100,52 +73,70 @@ export class SubscribeContainer extends PureComponent { }, 3000); }; - handleSubscribe = (product, offer) => async event => { + handleSubscribe = product => async event => { const { user, isLogged, location, updateSubscriberId, updateSubscription, - subscription, - updateProduct + subscription } = this.props; if (isAndroid()) { if ( (isLogged && product && - offer && subscription.androidSubscriptionState === NOT_SUBSCRIBED) || subscription.androidSubscriptionState === EXPIRED ) { const newProduct = { title: formatTitle(product.title), - billingPeriod: offer.pricingPhases[0].billingPeriod, - price: offer.pricingPhases[0].price + billingPeriod: product.billingPeriod, + price: product.price, + tag: product.tag, + subscriptionId: product.subscriptionId }; const apiProduct = { product: { - ...newProduct, - subscriptionId: product.id + ...newProduct } }; + console.log('enytro 1'); + + updateSubscription({ + isSubscribed: false, + expiryDate: null, + androidSubscriptionState: PROCCESING, + ownedProduct: '' + }); + // get offer from the plugin + let offers, offer; try { - updateSubscription({ - isSubscribed: false, - expiryDate: null, - androidSubscriptionState: PROCCESING - }); + await window.CdvPurchase.store.update(); + offers = await window.CdvPurchase.store.products[0].offers; + offer = offers.find(offer => offer.tags[0] === product.tag); + } catch (err) { + console.error('Cannot subscribe product. Error: ', err.message); + this.handleError(err); + } + try { + // update the api const subscriber = await API.getSubscriber(user.id); updateSubscriberId(subscriber._id); await API.updateSubscriber(apiProduct); - updateProduct(newProduct); + // proceed with the purchase const order = await window.CdvPurchase.store.order(offer); + console.log(order); if (order && order.isError) throw order; - } catch (e) { - if (e.response?.data.error === 'subscriber not found') { + console.log('enytro 2'); + updateSubscription({ + ownedProduct: product + }); + } catch (err) { + if (err.response?.data.error === 'subscriber not found') { try { const newSubscriber = { userId: user.id, @@ -155,17 +146,20 @@ export class SubscribeContainer extends PureComponent { }; const res = await API.createSubscriber(newSubscriber); updateSubscriberId(res._id); - updateProduct(newProduct); const order = await window.CdvPurchase.store.order(offer); if (order && order.isError) throw order; - } catch (e) { - console.error('Cannot subscribe product. Error: ', e.message); - this.handleError(e); + console.log('enytro 3'); + updateSubscription({ + ownedProduct: product + }); + } catch (err) { + console.error('Cannot subscribe product. Error: ', err.message); + this.handleError(err); } return; } - console.error('Cannot subscribe product. Error: ', e.message); - this.handleError(e); + console.error('Cannot subscribe product. Error: ', err.message); + this.handleError(err); } } } @@ -179,11 +173,8 @@ export class SubscribeContainer extends PureComponent { onClose={history.goBack} isLogged={this.props.isLogged} onSubscribe={this.handleSubscribe} - name={this.state.name} - email={this.state.email} location={location} onSubmitPeople={this.handleSubmit} - products={this.state.products} subscription={this.props.subscription} updateSubscriberId={this.props.updateSubscriberId} onRefreshSubscription={this.handleRefreshSubscription} @@ -216,10 +207,10 @@ const mapDispatchToProps = { updateSubscriberId, updateSubscription, checkSubscription: checkSubscription, - updateAndroidSubscriptionState, updateSubscriptionError, updateProduct, - updateIsSubscribed + updateIsSubscribed, + updatePlans }; export default connect( diff --git a/src/components/Settings/Subscribe/SubscriptionInfo.js b/src/components/Settings/Subscribe/SubscriptionInfo.js index ce925e5ae..b6e40354e 100644 --- a/src/components/Settings/Subscribe/SubscriptionInfo.js +++ b/src/components/Settings/Subscribe/SubscriptionInfo.js @@ -23,7 +23,7 @@ import RefreshIcon from '@material-ui/icons/Refresh'; import IconButton from '../../UI/IconButton'; const propTypes = { - product: PropTypes.object.isRequired, + ownedProduct: PropTypes.object.isRequired, expiryDate: PropTypes.string.isRequired, androidSubscriptionState: PropTypes.string.isRequired, onRefreshSubscription: PropTypes.func.isRequired, @@ -34,14 +34,17 @@ const LABEL = 0; const VALUE = 1; const subscriptionInfo = ({ - product, + ownedProduct, expiryDate, androidSubscriptionState, onRefreshSubscription, intl }) => { - const { title, billingPeriod, price } = product; - const planAmount = `${price} / ${formatDuration(billingPeriod)}`; + const { title, billingPeriod, price } = ownedProduct; + + const planAmount = `${price?.currencyCode} ${price?.units} / ${formatDuration( + billingPeriod + )}`; const formatedDate = new Date(expiryDate).toLocaleString(); @@ -125,9 +128,9 @@ const subscriptionInfo = ({ subscriptionInfo.propTypes = propTypes; const mapStateToProps = ({ - subscription: { product, expiryDate, androidSubscriptionState } + subscription: { ownedProduct, expiryDate, androidSubscriptionState } }) => ({ - product, + ownedProduct, expiryDate, androidSubscriptionState }); diff --git a/src/components/Settings/Subscribe/SubscriptionPlans.js b/src/components/Settings/Subscribe/SubscriptionPlans.js index a8e2d6f52..f7e4104ec 100644 --- a/src/components/Settings/Subscribe/SubscriptionPlans.js +++ b/src/components/Settings/Subscribe/SubscriptionPlans.js @@ -37,7 +37,6 @@ import messages from './Subscribe.messages'; import './Subscribe.css'; const propTypes = { - products: PropTypes.object.isRequired, subscription: PropTypes.object.isRequired, onRefreshSubscription: PropTypes.func.isRequired, isLogged: PropTypes.bool.isRequired, @@ -46,7 +45,6 @@ const propTypes = { const SubscriptionPlans = ({ subscription, - products, onRefreshSubscription, isLogged, onSubscribe @@ -56,7 +54,8 @@ const SubscriptionPlans = ({ expiryDate, error, isOnTrialPeriod, - isSubscribed + isSubscribed, + products } = subscription; const canPurchase = [NOT_SUBSCRIBED, EXPIRED, ON_HOLD].includes( @@ -137,66 +136,64 @@ const SubscriptionPlans = ({ justifyContent="space-around" > {products.map(product => { - return product.offers.map(offer => { - return [ - - - - - {formatTitle(product.title)} - - - {offer.pricingPhases[0].price} / - {formatDuration(offer.pricingPhases[0].billingPeriod)} - - - -
-
- -
- - {INCLUDED_FEATURES.map(feature => { - return [ - - - - - - } - secondary={null} - /> - - ]; - })} - -
- {/* //TODO + return [ + + + + + {formatTitle(product.title)} + + + {product.price.currencyCode} {product.price.units} / + {formatDuration(product.billingPeriod)} + + + +
+
+ +
+ + {INCLUDED_FEATURES.map(feature => { + return [ + + + + + + } + secondary={null} + /> + + ]; + })} + +
+ {/* //TODO */} -
-
- ]; - }); +
+
+ ]; })} diff --git a/src/cordova-util.js b/src/cordova-util.js index db9d14b1e..b2119d98a 100644 --- a/src/cordova-util.js +++ b/src/cordova-util.js @@ -55,7 +55,7 @@ export const initCordovaPlugins = () => { const configAppPurchasePlugin = () => { const store = window.CdvPurchase.store; - const { ProductType, Platform, LogLevel } = window.CdvPurchase; // shortcuts + const { ProductType, Platform } = window.CdvPurchase; // shortcuts store.register([ { diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js index a32fc4e5f..c8f73626b 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js @@ -1,5 +1,4 @@ import { - UPDATE_ANDROID_SUBSCRIPTION_STATE, UPDATE_SUBSCRIBER_ID, UPDATE_SUBSCRIPTION, UPDATE_SUBSCRIPTION_ERROR, @@ -60,21 +59,41 @@ export function updateIsOnTrialPeriod() { export function updateIsSubscribed() { return async (dispatch, getState) => { let isSubscribed = false; + let ownedProduct = ''; + let androidSubscriptionState = ''; try { const state = getState(); if (!isLogged(state)) { + console.log('enytro 4'); dispatch( updateSubscription({ + ownedProduct, + androidSubscriptionState, isSubscribed }) ); } else { const userId = state.app.userData.id; - const { status } = await API.getSubscriber(userId); + const { status, product } = await API.getSubscriber(userId); isSubscribed = - status.toLowerCase() === ('active' || 'canceled') ? true : false; + status.toLowerCase() === 'active' || + status.toLowerCase() === 'canceled' + ? true + : false; + if (product && isSubscribed) { + ownedProduct = { + billingPeriod: product.billingPeriod, + id: product._id, + price: product.price, + subscriptionId: product.subscriptionId, + tag: product.tag, + title: product.title + }; + } + console.log('enytro 5'); dispatch( updateSubscription({ + ownedProduct, androidSubscriptionState: status.toLowerCase(), isSubscribed }) @@ -93,12 +112,64 @@ export function updateIsSubscribed() { }; } -export function updateAndroidSubscriptionState(payload = {}) { - return { - type: UPDATE_ANDROID_SUBSCRIPTION_STATE, - payload +export function updatePlans() { + return async (dispatch, getState) => { + const state = getState(); + try { + const { data } = await API.listSubscriptions(); + const locationCode = isLogged(state) + ? state.app.userData?.location?.countryCode + : state.app.unloggedUserLocation?.countryCode; + // get just subscriptions with active plans + const plans = getActivePlans(data); + const products = plans.map(plan => { + const result = { + id: plan.planId, + subscriptionId: plan.subscriptionId, + billingPeriod: plan.period, + price: getPrice(plan.countries, locationCode), + title: plan.subscriptionName, + tag: plan.tags[0] + }; + return result; + }); + + dispatch( + updateSubscription({ + products: [...products] + }) + ); + } catch (err) { + console.error(err.message); + } }; + + function getPrice(countries, country) { + let price = ''; + if (countries) + countries.forEach(element => { + if (element.regionCode === country) price = element.price; + }); + return price; + } + + function getActivePlans(subscriptions) { + let plans = []; + if (subscriptions) + subscriptions.forEach(subscription => { + if (subscription.plans) + subscription.plans.forEach(plan => { + if (plan.status.toLowerCase() === 'active') { + plan.subscriptionName = subscription.name; + plan.subscriptionId = subscription.subscriptionId; + plans.push(plan); + } + }); + }); + return plans; + } } + export function updateSubscriberId(payload = {}) { return { type: UPDATE_SUBSCRIBER_ID, diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js index 984941afa..40ac9045b 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js @@ -1,5 +1,3 @@ -export const UPDATE_ANDROID_SUBSCRIPTION_STATE = - 'cboard/subscription/UPDATE_ANDROID_SUBSCRIPTION_STATE'; export const UPDATE_SUBSCRIBER_ID = 'cboard/subscription/UPDATE_SUBSCRIBER_ID'; export const UPDATE_SUBSCRIPTION = 'cboard/subscription/UPDATE_SUBSCRIPTION'; export const UPDATE_SUBSCRIPTION_ERROR = diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index 9159d5d47..c79eef395 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -7,9 +7,9 @@ import { isAndroid } from '../../cordova-util'; import { updateIsInFreeCountry, - updateAndroidSubscriptionState, updateIsSubscribed, updateSubscription, + updatePlans, checkSubscription, updateIsOnTrialPeriod, showPremiumRequired @@ -30,7 +30,8 @@ export class SubscriptionProvider extends Component { updateIsSubscribed, updateIsOnTrialPeriod, updateIsInFreeCountry, - showPremiumRequired + showPremiumRequired, + updatePlans } = this.props; console.log('entro en mount'); @@ -38,6 +39,7 @@ export class SubscriptionProvider extends Component { const isSubscribed = await updateIsSubscribed(); const isInFreeCountry = updateIsInFreeCountry(); const isOnTrialPeriod = updateIsOnTrialPeriod(); + await updatePlans(); this.configInAppPurchasePlugin(); //onAndroidResume(() => checkSubscription()); console.log(isInFreeCountry, isOnTrialPeriod, isSubscribed, isLogged); @@ -66,10 +68,12 @@ export class SubscriptionProvider extends Component { localTransaction.length || androidSubscriptionState !== NOT_SUBSCRIBED ) - checkSubscription(); + console.log('entro en first '); + // checkSubscription(); } } if (prevProps.isLogged !== isLogged) { + console.log('entro en second '); const isSubscribed = await updateIsSubscribed(); const isInFreeCountry = updateIsInFreeCountry(); const isOnTrialPeriod = updateIsOnTrialPeriod(); @@ -175,9 +179,9 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = { - updateAndroidSubscriptionState, updateIsSubscribed, updateSubscription, + updatePlans, checkSubscription, updateIsInFreeCountry, updateIsOnTrialPeriod, diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js index 4b2a7b014..eb9c2ae02 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js @@ -1,7 +1,5 @@ import { - UPDATE_ANDROID_SUBSCRIPTION_STATE, UPDATE_SUBSCRIBER_ID, - UPDATE_IS_SUBSCRIBED, UPDATE_SUBSCRIPTION, UPDATE_SUBSCRIPTION_ERROR, SHOW_PREMIUM_REQUIRED, @@ -30,20 +28,21 @@ const initialState = { open: false, showTryPeriodFinishedMessages: false }, - product: { - title: '', - billingPeriod: '', - price: '' - } + ownedProduct: '', + products: [ + { + id: '', + subscriptionId: '', + title: '', + billingPeriod: '', + price: '', + tag: '' + } + ] }; function subscriptionProviderReducer(state = initialState, action) { switch (action.type) { - case UPDATE_ANDROID_SUBSCRIPTION_STATE: - return { - ...state, - androidSubscriptionState: action.payload - }; case UPDATE_SUBSCRIBER_ID: return { ...state, @@ -57,7 +56,7 @@ function subscriptionProviderReducer(state = initialState, action) { case UPDATE_PRODUCT: return { ...state, - product: action.product + product: [...action.product] }; case UPDATE_SUBSCRIPTION_ERROR: const { showError, code, message } = action.payload; From fb0df66f5de761a7e12e31c8703a3546b125f2f6 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Sat, 15 Apr 2023 02:28:49 -0300 Subject: [PATCH 08/14] wip --- .../Settings/Subscribe/Subscribe.container.js | 26 ++++++++++++++----- .../Settings/Subscribe/SubscriptionPlans.js | 15 ++++++++--- .../SubscriptionProvider.actions.js | 12 ++------- .../SubscriptionProvider.constants.js | 1 - .../SubscriptionProvider.container.js | 1 - .../SubscriptionProvider.reducer.js | 14 +++------- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index 8dfd5f8f8..0d56a16d8 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -12,14 +12,14 @@ import { updateSubscriberId, updateSubscription, updateSubscriptionError, - updateProduct, updateIsSubscribed, updatePlans } from '../../../providers/SubscriptionProvider/SubscriptionProvider.actions'; import { NOT_SUBSCRIBED, PROCCESING, - EXPIRED + EXPIRED, + ACTIVE } from '../../../providers/SubscriptionProvider/SubscriptionProvider.constants'; import { formatTitle } from './Subscribe.helpers'; @@ -30,7 +30,11 @@ export class SubscribeContainer extends PureComponent { subscription: PropTypes.object.isRequired }; - componentDidMount() {} + componentDidMount() { + const { updateIsSubscribed, updatePlans } = this.props; + updateIsSubscribed(); + updatePlans(); + } handleChange = name => event => { this.setState({ @@ -133,7 +137,12 @@ export class SubscribeContainer extends PureComponent { if (order && order.isError) throw order; console.log('enytro 2'); updateSubscription({ - ownedProduct: product + ownedProduct: product, + ownedProduct: product, + androidSubscriptionState: ACTIVE, + isInFreeCountry: false, + isOnTrialPeriod: false, + isSubscribed: true }); } catch (err) { if (err.response?.data.error === 'subscriber not found') { @@ -142,7 +151,7 @@ export class SubscribeContainer extends PureComponent { userId: user.id, country: location.countryCode || 'Not localized', status: NOT_SUBSCRIBED, - apiProduct + ...apiProduct }; const res = await API.createSubscriber(newSubscriber); updateSubscriberId(res._id); @@ -150,7 +159,11 @@ export class SubscribeContainer extends PureComponent { if (order && order.isError) throw order; console.log('enytro 3'); updateSubscription({ - ownedProduct: product + ownedProduct: product, + androidSubscriptionState: ACTIVE, + isInFreeCountry: false, + isOnTrialPeriod: false, + isSubscribed: true }); } catch (err) { console.error('Cannot subscribe product. Error: ', err.message); @@ -208,7 +221,6 @@ const mapDispatchToProps = { updateSubscription, checkSubscription: checkSubscription, updateSubscriptionError, - updateProduct, updateIsSubscribed, updatePlans }; diff --git a/src/components/Settings/Subscribe/SubscriptionPlans.js b/src/components/Settings/Subscribe/SubscriptionPlans.js index f7e4104ec..ccd6d2513 100644 --- a/src/components/Settings/Subscribe/SubscriptionPlans.js +++ b/src/components/Settings/Subscribe/SubscriptionPlans.js @@ -72,7 +72,7 @@ const SubscriptionPlans = ({ ) return ON_TRIAL_PERIOD; if (products.length || androidSubscriptionState !== NOT_SUBSCRIBED) - return androidSubscriptionState; + return androidSubscriptionState || NOT_SUBSCRIBED; return EMPTY_PRODUCT; } return NOT_SUBSCRIBED; @@ -93,6 +93,11 @@ const SubscriptionPlans = ({ expired: 'warning' //TODO }; + const fallbabackMessage = { + id: 'cboard.components.Settings.Subscribe.fallback', + defaultMessage: 'Wait please...' + }; + const expiryDateFormated = expiryDate ? new Date(expiryDate).toLocaleString() : ''; @@ -125,7 +130,7 @@ const SubscriptionPlans = ({ } > @@ -178,7 +183,11 @@ const SubscriptionPlans = ({ + } secondary={null} /> diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js index c8f73626b..99b5a9cba 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.actions.js @@ -8,8 +8,7 @@ import { NOT_SUBSCRIBED, CANCELED, ACTIVE, - REQUIRING_PREMIUM_COUNTRIES, - UPDATE_PRODUCT + REQUIRING_PREMIUM_COUNTRIES } from './SubscriptionProvider.constants'; import API from '../../api'; import { isLogged } from '../../components/App/App.selectors'; @@ -60,7 +59,7 @@ export function updateIsSubscribed() { return async (dispatch, getState) => { let isSubscribed = false; let ownedProduct = ''; - let androidSubscriptionState = ''; + let androidSubscriptionState = NOT_SUBSCRIBED; try { const state = getState(); if (!isLogged(state)) { @@ -259,10 +258,3 @@ export function hidePremiumRequired() { type: HIDE_PREMIUM_REQUIRED }; } - -export function updateProduct(product = {}) { - return { - type: UPDATE_PRODUCT, - product - }; -} diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js index 40ac9045b..860672022 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.constants.js @@ -6,7 +6,6 @@ export const SHOW_PREMIUM_REQUIRED = 'cboard/subscription/SHOW_PREMIUM_REQUIRED'; export const HIDE_PREMIUM_REQUIRED = 'cboard/subscription/HIDE_PREMIUM_REQUIRED'; -export const UPDATE_PRODUCT = 'cboard/subscription/UPDATE_PRODUCT'; export const NOT_SUBSCRIBED = 'not_subscribed'; export const PROCCESING = 'proccesing'; diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js index c79eef395..c3aa84e58 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.container.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.container.js @@ -42,7 +42,6 @@ export class SubscriptionProvider extends Component { await updatePlans(); this.configInAppPurchasePlugin(); //onAndroidResume(() => checkSubscription()); - console.log(isInFreeCountry, isOnTrialPeriod, isSubscribed, isLogged); if (!isInFreeCountry && !isOnTrialPeriod && !isSubscribed && isLogged) { showPremiumRequired({ showTryPeriodFinishedMessages: true }); } diff --git a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js index eb9c2ae02..b6b9f208e 100644 --- a/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js +++ b/src/providers/SubscriptionProvider/SubscriptionProvider.reducer.js @@ -4,8 +4,7 @@ import { UPDATE_SUBSCRIPTION_ERROR, SHOW_PREMIUM_REQUIRED, HIDE_PREMIUM_REQUIRED, - NOT_SUBSCRIBED, - UPDATE_PRODUCT + NOT_SUBSCRIBED } from './SubscriptionProvider.constants'; import { LOGOUT, @@ -53,11 +52,6 @@ function subscriptionProviderReducer(state = initialState, action) { ...state, ...action.payload }; - case UPDATE_PRODUCT: - return { - ...state, - product: [...action.product] - }; case UPDATE_SUBSCRIPTION_ERROR: const { showError, code, message } = action.payload; return { @@ -73,16 +67,14 @@ function subscriptionProviderReducer(state = initialState, action) { const { id = '', status = NOT_SUBSCRIBED, - expiryDate: expiry = null, - product = initialState.product + expiryDate: expiry = null } = subscriber; return { ...state, subscriberId: id, androidSubscriptionState: status, - expiryDate: expiry, - product + expiryDate: expiry }; case LOGOUT: return initialState; From f0cf70e8109891698934c35af28fde8903edadd0 Mon Sep 17 00:00:00 2001 From: Martin Bedouret Date: Sat, 15 Apr 2023 18:25:50 -0300 Subject: [PATCH 09/14] fixes --- .../PremiumFeature/PremiumFeature.messages.js | 2 +- src/components/Settings/Settings.component.js | 18 +++---- .../Settings/Subscribe/Subscribe.container.js | 7 +-- .../Settings/Subscribe/SubscriptionPlans.js | 48 ++++++++++++++++--- .../SubscriptionProvider.actions.js | 6 +-- 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/components/PremiumFeature/PremiumFeature.messages.js b/src/components/PremiumFeature/PremiumFeature.messages.js index c4e2b6e58..3410b1c06 100644 --- a/src/components/PremiumFeature/PremiumFeature.messages.js +++ b/src/components/PremiumFeature/PremiumFeature.messages.js @@ -12,7 +12,7 @@ export default defineMessages({ featureBlockedText: { id: 'cboard.components.PremiumFeature.featureBlockedText', defaultMessage: - 'Cboard disable this feature. To continue using it and all the features like public boards, online voices, advanced edit functions and many more, please upgrade' + 'Cboard disabled this feature. To continue using it and all the features like public boards, online voices, advanced edit functions and many more, please upgrade' }, upgradeNow: { id: 'cboard.components.PremiumFeature.upgradeNow', diff --git a/src/components/Settings/Settings.component.js b/src/components/Settings/Settings.component.js index 50dc9c1cd..864569354 100644 --- a/src/components/Settings/Settings.component.js +++ b/src/components/Settings/Settings.component.js @@ -48,7 +48,7 @@ const propTypes = { export class Settings extends PureComponent { getSettingsSections() { - const { isLogged, logout, user, isInFreeCountry } = this.props; + const { isLogged, logout, user } = this.props; function handleLogOutClick() { if (isAndroid()) { @@ -98,14 +98,14 @@ export class Settings extends PureComponent { } ]; - if (isAndroid() && !isInFreeCountry) { - const subscribeSection = { - icon: , - text: messages.subscribe, - url: '/settings/subscribe' - }; - peopleSettings.push(subscribeSection); - } + //if (isAndroid() && !isInFreeCountry) { + const subscribeSection = { + icon: , + text: messages.subscribe, + url: '/settings/subscribe' + }; + peopleSettings.push(subscribeSection); + // } return [ { diff --git a/src/components/Settings/Subscribe/Subscribe.container.js b/src/components/Settings/Subscribe/Subscribe.container.js index 0d56a16d8..d3c8c40dc 100644 --- a/src/components/Settings/Subscribe/Subscribe.container.js +++ b/src/components/Settings/Subscribe/Subscribe.container.js @@ -43,14 +43,11 @@ export class SubscribeContainer extends PureComponent { }); }; - handleSubmit = async () => {}; - handleRefreshSubscription = () => { - const { checkSubscription, updateIsSubscribed, updatePlans } = this.props; + const { updateIsSubscribed, updatePlans } = this.props; window.CdvPurchase.store.restorePurchases(); updateIsSubscribed(); updatePlans(); - // checkSubscription(); }; handleError = e => { @@ -137,7 +134,6 @@ export class SubscribeContainer extends PureComponent { if (order && order.isError) throw order; console.log('enytro 2'); updateSubscription({ - ownedProduct: product, ownedProduct: product, androidSubscriptionState: ACTIVE, isInFreeCountry: false, @@ -187,7 +183,6 @@ export class SubscribeContainer extends PureComponent { isLogged={this.props.isLogged} onSubscribe={this.handleSubscribe} location={location} - onSubmitPeople={this.handleSubmit} subscription={this.props.subscription} updateSubscriberId={this.props.updateSubscriberId} onRefreshSubscription={this.handleRefreshSubscription} diff --git a/src/components/Settings/Subscribe/SubscriptionPlans.js b/src/components/Settings/Subscribe/SubscriptionPlans.js index ccd6d2513..e5e2dd256 100644 --- a/src/components/Settings/Subscribe/SubscriptionPlans.js +++ b/src/components/Settings/Subscribe/SubscriptionPlans.js @@ -1,9 +1,11 @@ import React from 'react'; import Grid from '@material-ui/core/Grid'; import Card from '@material-ui/core/Card'; +import Box from '@material-ui/core/Box'; import CardContent from '@material-ui/core/CardContent'; import Typography from '@material-ui/core/Typography'; import PropTypes from 'prop-types'; +import { makeStyles } from '@material-ui/core/styles'; import { FormattedMessage } from 'react-intl'; import { @@ -43,6 +45,20 @@ const propTypes = { onSubscribe: PropTypes.func.isRequired }; +const useStyles = makeStyles({ + root: { + width: '100%', + maxWidth: 360 + }, + titles: { + fontWeight: 'bold', + fontSize: '1.2rem' + }, + icon: { + color: 'green' + } +}); + const SubscriptionPlans = ({ subscription, onRefreshSubscription, @@ -58,6 +74,7 @@ const SubscriptionPlans = ({ products } = subscription; + const classes = useStyles(); const canPurchase = [NOT_SUBSCRIBED, EXPIRED, ON_HOLD].includes( subscription.androidSubscriptionState ); @@ -151,13 +168,32 @@ const SubscriptionPlans = ({ > - + {formatTitle(product.title)} - - {product.price.currencyCode} {product.price.units} / - {formatDuration(product.billingPeriod)} - + + + {product.price.currencyCode} {product.price.units} + + + /{formatDuration(product.billingPeriod)} + +