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

Subscription fixes #1447

Merged
merged 16 commits into from
Apr 18, 2023
5 changes: 5 additions & 0 deletions src/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({});
Expand Down
2 changes: 1 addition & 1 deletion src/components/Board/Board.actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
8 changes: 0 additions & 8 deletions src/components/Settings/Subscribe/Subscribe.constants.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
72 changes: 32 additions & 40 deletions src/components/Settings/Subscribe/Subscribe.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ 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,
checkSubscription,
updateSubscriberId,
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';
Expand All @@ -37,39 +38,26 @@ export class SubscribeContainer extends PureComponent {

componentDidMount() {
if (isAndroid()) {
window.CdvPurchase.store.when('subscription').updated(this.setProducts);
this.props.comprobeSubscription();
this.setProducts();
}
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 {
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 });
}

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 => {
Expand All @@ -82,10 +70,10 @@ export class SubscribeContainer extends PureComponent {
handleSubmit = async () => {};

handleRefreshSubscription = () => {
const { comprobeSubscription } = this.props;

const { checkSubscription, updateIsSubscribed } = this.props;
window.CdvPurchase.store.restorePurchases();
comprobeSubscription();
updateIsSubscribed();
// checkSubscription();
};

handleError = e => {
Expand Down Expand Up @@ -124,8 +112,11 @@ export class SubscribeContainer extends PureComponent {
} = this.props;
if (isAndroid()) {
if (
isLogged &&
subscription.androidSubscriptionState === NOT_SUBSCRIBED
(isLogged &&
product &&
offer &&
subscription.androidSubscriptionState === NOT_SUBSCRIBED) ||
subscription.androidSubscriptionState === EXPIRED
) {
const newProduct = {
title: formatTitle(product.title),
Expand Down Expand Up @@ -168,12 +159,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);
}
}
Expand Down Expand Up @@ -224,10 +215,11 @@ const mapStateToProps = state => {
const mapDispatchToProps = {
updateSubscriberId,
updateSubscription,
comprobeSubscription,
checkSubscription: checkSubscription,
martinbedouret marked this conversation as resolved.
Show resolved Hide resolved
updateAndroidSubscriptionState,
updateSubscriptionError,
updateProduct
updateProduct,
updateIsSubscribed
};

export default connect(
Expand Down
7 changes: 0 additions & 7 deletions src/components/Settings/Subscribe/SubscriptionInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)}`;

Expand Down
6 changes: 1 addition & 5 deletions src/cordova-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,12 @@ const configAppPurchasePlugin = () => {

store.register([
{
id: 'premium_full',
id: 'one_year_subscription',
type: ProductType.PAID_SUBSCRIPTION,
platform: Platform.GOOGLE_PLAY
}
]);

store.verbosity = LogLevel.DEBUG;

//error handler

store.error(errorHandler);
function errorHandler(error) {
console.error(`ERROR ${error.code}: ${error.message}`);
Expand Down
81 changes: 51 additions & 30 deletions src/providers/SubscriptionProvider/SubscriptionProvider.actions.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -15,7 +12,7 @@ import {
REQUIRING_PREMIUM_COUNTRIES,
UPDATE_PRODUCT
} from './SubscriptionProvider.constants';

import API from '../../api';
import { isLogged } from '../../components/App/App.selectors';

export function updateIsInFreeCountry() {
Expand All @@ -25,31 +22,26 @@ 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;
};
}

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 }));
dispatch(
updateSubscription({
isOnTrialPeriod
})
);
return isOnTrialPeriod;

function isUserOnTrialPeriod(createdAt) {
if (!createdAt) return false; //this case are already created users
Expand All @@ -65,6 +57,42 @@ export function updateIsOnTrialPeriod() {
};
}

export function updateIsSubscribed() {
return async (dispatch, getState) => {
let isSubscribed = false;
try {
const state = getState();
if (!isLogged(state)) {
dispatch(
updateSubscription({
isSubscribed
})
);
} else {
const userId = state.app.userData.id;
const { status } = await API.getSubscriber(userId);
isSubscribed =
status.toLowerCase() === ('active' || 'canceled') ? true : false;
martinbedouret marked this conversation as resolved.
Show resolved Hide resolved
dispatch(
updateSubscription({
androidSubscriptionState: status.toLowerCase(),
isSubscribed
})
);
}
} catch (err) {
console.error(err.message);
isSubscribed = false;
dispatch(
updateSubscription({
isSubscribed
})
);
}
return isSubscribed;
};
}

export function updateAndroidSubscriptionState(payload = {}) {
return {
type: UPDATE_ANDROID_SUBSCRIPTION_STATE,
Expand All @@ -77,12 +105,6 @@ export function updateSubscriberId(payload = {}) {
payload
};
}
export function updateIsSubscribed(payload) {
return {
type: UPDATE_IS_SUBSCRIBED,
payload
};
}
export function updateSubscription(payload) {
return {
type: UPDATE_SUBSCRIPTION,
Expand All @@ -95,7 +117,8 @@ export function updateSubscriptionError(payload) {
payload
};
}
export function comprobeSubscription(payload) {

export function checkSubscription(payload) {
return async (dispatch, getState) => {
const {
expiryDate,
Expand Down Expand Up @@ -147,8 +170,6 @@ export function comprobeSubscription(payload) {
})
);
}
if (!isExpired && androidSubscriptionState === ACTIVE && !isSubscribed)
dispatch(updateIsSubscribed(true));
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -23,4 +19,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
Loading