add compact premium dialog

This commit is contained in:
ammarahm-ed
2021-11-15 15:24:37 +05:00
parent 268c221e99
commit d2473fd481
8 changed files with 245 additions and 143 deletions

View File

@@ -84,7 +84,7 @@ const GeneralSheet = ({context}) => {
) : null}
</View>
{dialogData.component}
{typeof dialogData.component === "function" ? dialogData.component(actionSheetRef):dialogData.component}
{dialogData?.learnMore ? (
<Paragraph

View File

@@ -0,0 +1,69 @@
import React from 'react';
import {ScrollView} from 'react-native';
import {useTracked} from '../../provider';
import {FeatureBlock} from './feature';
export const CompactFeatures = ({vertical,features = [],maxHeight=500,scrollRef}) => {
const [state, dispatch] = useTracked();
const {colors} = state;
let data = vertical ? features : [
{
highlight: 'Everything',
content: 'in basic',
icon: 'emoticon-wink'
},
{
highlight: 'Unlimited',
content: 'notebooks',
icon: 'notebook'
},
{
highlight: 'File & image',
content: 'attachments',
icon: 'attachment'
},
{
highlight: 'Instant',
content: 'syncing',
icon: 'sync'
},
{
highlight: 'Private',
content: 'vault',
icon: 'shield'
},
{
highlight: 'Rich text',
content: 'editing',
icon: 'square-edit-outline'
},
{
highlight: 'PDF & markdown',
content: 'exports',
icon: 'file'
},
{
highlight: 'Encrypted',
content: 'backups',
icon: 'backup-restore'
}
]
return (
<ScrollView
horizontal={!vertical}
nestedScrollEnabled
onMomentumScrollEnd={() => {
scrollRef?.current?.handleChildScrollEnd();
}}
showsHorizontalScrollIndicator={false}
style={{
width: '100%',
maxHeight:maxHeight
}}>
{data.map(item => (
<FeatureBlock vertical={vertical} {...item} />
))}
</ScrollView>
);
};

View File

@@ -9,7 +9,6 @@ import { eOpenLoginDialog } from '../../utils/Events';
import { SIZE } from '../../utils/SizeUtils';
import { ActionIcon } from '../ActionIcon';
import { Button } from '../Button';
import { Dialog } from '../Dialog';
import GeneralSheet from '../GeneralSheet';
import Seperator from '../Seperator';
import { Toast } from '../Toast';
@@ -62,7 +61,6 @@ export const Component = ({close, promo, getRef}) => {
borderRadius: 10,
maxHeight: DDS.isTab ? '90%' : '100%'
}}>
<GeneralSheet context="pricing_plans" />
<ActionIcon
onPress={() => {

View File

@@ -1,12 +1,12 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, View } from 'react-native';
import { View } from 'react-native';
import { useTracked } from '../../provider';
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
presentSheet
eUnSubscribeEvent
} from '../../services/EventManager';
import PremiumService from '../../services/PremiumService';
import {
eOpenPremiumDialog,
eOpenResultDialog,
@@ -20,18 +20,17 @@ import DialogContainer from '../Dialog/dialog-container';
import Seperator from '../Seperator';
import Heading from '../Typography/Heading';
import Paragraph from '../Typography/Paragraph';
import { FeatureBlock } from './feature';
import { CompactFeatures } from './compact-features';
import { Offer } from './offer';
import { PricingPlans } from './pricing-plans';
export const Expiring = () => {
const [state, dispatch] = useTracked();
const {colors} = state;
const [visible, setVisible] = useState(false);
const [status, setStatus] = useState({
title: '',
title: 'Your trial is ending soon',
offer: null,
extend: false
extend: true
});
useEffect(() => {
@@ -97,57 +96,7 @@ export const Expiring = () => {
</>
)}
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={{
width: '100%'
}}>
{[
{
highlight: 'Everything',
content: 'in basic',
icon: 'emoticon-wink'
},
{
highlight: 'Unlimited',
content: 'notebooks',
icon: 'notebook'
},
{
highlight: 'File & image',
content: 'attachments',
icon: 'attachment'
},
{
highlight: 'Instant',
content: 'syncing',
icon: 'sync'
},
{
highlight: 'Private',
content: 'vault',
icon: 'shield'
},
{
highlight: 'Rich text',
content: 'editing',
icon: 'square-edit-outline'
},
{
highlight: 'PDF & markdown',
content: 'exports',
icon: 'file'
},
{
highlight: 'Encrypted',
content: 'backups',
icon: 'backup-restore'
}
].map(item => (
<FeatureBlock {...item} />
))}
</ScrollView>
<CompactFeatures/>
<Paragraph
onPress={async () => {
@@ -181,16 +130,12 @@ export const Expiring = () => {
onPress={async () => {
setVisible(false);
await sleep(300);
presentSheet({
component: <PricingPlans marginTop={1} promo={null} />,
noIcon: true,
noProgress: true
});
PremiumService.sheet(null,status.offer)
}}
fontSize={SIZE.lg}
fontSize={SIZE.md + 2}
style={{
marginBottom: status.extend ? 0 : 12,
marginTop: 12,
marginBottom: status.extend ? 0 : 10,
marginTop: 10,
paddingHorizontal: 24
}}
/>
@@ -212,10 +157,10 @@ export const Expiring = () => {
button: 'Continue'
});
}}
fontSize={SIZE.sm}
fontSize={SIZE.xs + 1}
height={30}
style={{
marginBottom: 12
marginBottom: 10
}}
/>
)}

View File

@@ -8,11 +8,38 @@ import Seperator from '../Seperator';
import Paragraph from '../Typography/Paragraph';
import {ProTag} from './pro-tag';
export const FeatureBlock = ({highlight, content, icon, pro, proTagBg}) => {
export const FeatureBlock = ({
vertical,
highlight,
content,
icon,
pro,
proTagBg
}) => {
const [state, dispatch] = useTracked();
const {colors} = state;
return (
return vertical ? (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
marginBottom: 10,
}}>
<Icon color={colors.accent} name="check" size={SIZE.lg} />
<Paragraph
style={{
flexWrap: 'wrap',
marginLeft: 5,
flexShrink: 1
}}
size={SIZE.md}>
{content}
</Paragraph>
</View>
) : (
<View
style={{
height: 100,

View File

@@ -1,34 +1,41 @@
import React from 'react';
import {View} from 'react-native';
import {useTracked} from '../../provider';
import { getElevation } from '../../utils';
import {SIZE} from '../../utils/SizeUtils';
import {PressableButton} from '../PressableButton';
import Heading from '../Typography/Heading';
import Paragraph from '../Typography/Paragraph';
export const PricingItem = ({product, onPress}) => {
export const PricingItem = ({product, onPress, compact}) => {
const [state, dispatch] = useTracked();
const colors = state.colors;
return (
<PressableButton
onPress={onPress}
type="grayBg"
customStyle={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
alignItems: 'center',
paddingHorizontal: 12,
paddingVertical: 10
paddingVertical: compact ? 15 : 10,
width: compact ? null : '100%',
minWidth: 150,
}}>
<View>
<Heading size={SIZE.lg - 2}>
{product?.type === 'yearly' || product?.offerType === 'yearly'
? 'Yearly'
: 'Monthly'}
</Heading>
{product?.info && (
<Paragraph size={SIZE.xs + 1}>{product.info}</Paragraph>
)}
</View>
{!compact && (
<View>
<Heading size={SIZE.lg - 2}>
{product?.type === 'yearly' || product?.offerType === 'yearly'
? 'Yearly'
: 'Monthly'}
</Heading>
{product?.info && (
<Paragraph size={SIZE.xs + 1}>{product.info}</Paragraph>
)}
</View>
)}
<View>
<Paragraph size={SIZE.sm}>

View File

@@ -37,10 +37,15 @@ const promoCyclesYearly = {
3: 'first 3 years'
};
export const PricingPlans = ({promo, marginTop}) => {
export const PricingPlans = ({
promo,
marginTop,
heading = true,
compact = false
}) => {
const [state, dispatch] = useTracked();
const colors = state.colors;
const user = useUserStore(state => state.user);
const user = {}; //useUserStore(state => state.user);
const [product, setProduct] = useState(null);
const [products, setProducts] = useState([]);
const [offers, setOffers] = useState(null);
@@ -155,40 +160,52 @@ export const PricingPlans = ({promo, marginTop}) => {
{user && !product ? (
<>
<Heading
style={{
alignSelf: 'center',
marginTop: marginTop || 20,
marginBottom: 20
}}>
Choose a plan
</Heading>
<PricingItem
onPress={() => buySubscription(offers?.monthly)}
product={{
type: 'monthly',
data: offers?.monthly,
info: 'Pay monthly, cancel anytime.'
}}
/>
{heading ? (
<Heading
style={{
alignSelf: 'center',
marginTop: marginTop || 20,
marginBottom: 20
}}>
Choose a plan
</Heading>
) : null}
<View
style={{
height: 1,
backgroundColor: colors.nav,
marginVertical: 10
}}
/>
flexDirection: !compact ? 'column' : 'row',
flexWrap: 'wrap',
justifyContent: 'space-around'
}}>
<PricingItem
onPress={() => buySubscription(offers?.monthly)}
compact={compact}
product={{
type: 'monthly',
data: offers?.monthly,
info: 'Pay monthly, cancel anytime.'
}}
/>
<PricingItem
onPress={() => buySubscription(offers?.yearly)}
product={{
type: 'yearly',
data: offers?.yearly,
info: 'Pay yearly'
}}
/>
{!compact && (
<View
style={{
height: 1,
marginVertical: 5
}}
/>
)}
<PricingItem
onPress={() => buySubscription(offers?.yearly)}
compact={compact}
product={{
type: 'yearly',
data: offers?.yearly,
info: 'Pay yearly'
}}
/>
</View>
<Button
height={35}
@@ -258,7 +275,7 @@ export const PricingPlans = ({promo, marginTop}) => {
<>
<PricingItem
product={product}
onPress={() => buySubscription(product)}
onPress={() => buySubscription(product.data)}
/>
<Button
onPress={() => {
@@ -318,20 +335,12 @@ export const PricingPlans = ({promo, marginTop}) => {
marginTop: 10,
textAlign: 'center'
}}>
By tapping Subscribe,
<Paragraph size={SIZE.xs + 1} color={colors.accent}>
{product?.data?.localizedPrice}
</Paragraph>{' '}
will be charged to your iTunes Account for 1-
{product?.type === 'yearly' ? 'year' : 'month'} subscription of
Notesnook Pro.{'\n\n'}
Subscriptions will automatically renew unless cancelled within
24-hours before the end of the current period. You can cancel
anytime with your iTunes Account settings.
By subscribing, you will be charged to your iTunes Account for the
selected plan. Subscriptions will automatically renew unless
cancelled within 24-hours before the end of the current period.
</Paragraph>
) : (
<Paragraph
textBreakStrategy="balanced"
size={SIZE.xs + 1}
color={colors.icon}
style={{
@@ -339,22 +348,15 @@ export const PricingPlans = ({promo, marginTop}) => {
marginTop: 10,
textAlign: 'center'
}}>
By tapping Subscribe, your payment will be charged on your Google
Account, and your subscription will automatically renew for the
same package length at the same price until you cancel in settings
in the Android Play Store prior to the end of the then current
period.
By subscribing, your will be charged on your Google Account, and
your subscription will automatically renew until you cancel prior
to the end of the then current period.
</Paragraph>
)}
<View
style={{
backgroundColor: colors.nav,
width: '100%',
paddingVertical: 10,
marginTop: 5,
borderRadius: 5,
paddingHorizontal: 12
}}>
<Paragraph
size={SIZE.xs + 1}

View File

@@ -1,12 +1,15 @@
import {CHECK_IDS} from 'notes-core/common';
import React from 'react';
import * as RNIap from 'react-native-iap';
import InAppBrowser from 'react-native-inappbrowser-reborn';
import DialogHeader from '../components/Dialog/dialog-header';
import {CompactFeatures} from '../components/Premium/compact-features';
import {PricingPlans} from '../components/Premium/pricing-plans';
import Seperator from '../components/Seperator';
import {useMessageStore, useUserStore} from '../provider/stores';
import {itemSkus, SUBSCRIPTION_STATUS} from '../utils';
import {db} from '../utils/database';
import {
eOpenPremiumDialog,
eOpenProgressDialog,
eOpenTrialEndingDialog,
eShowGetPremium
} from '../utils/Events';
@@ -302,6 +305,56 @@ async function getRemainingTrialDaysStatus() {
}
}
const features_list = [
{
content: 'Unlock unlimited notebooks, tags, colors. Organize like a pro'
},
{
content: 'Attach files upto 500MB, upload 4K images with unlimited storage'
},
{
content: 'Instantly sync to unlimited devices'
},
{
content: 'A private vault to keep everything imporant always locked'
},
{
content:
'Rich note editing experience with markdown, tables, checklists and more'
},
{
content: 'Export your notes in Pdf, markdown and html formats'
}
];
const sheet = (context, promo) => {
presentSheet({
context:context,
component: ref => (
<>
<DialogHeader
centered
title="Upgrade to Notesnook"
titlePart="Pro"
paragraph="Manage your work on another level, enjoy seemless sync and keep all notes in one place."
padding={12}
/>
<Seperator />
<CompactFeatures
scrollRef={ref}
maxHeight={300}
features={features_list}
vertical
/>
<Seperator half />
<PricingPlans compact heading={false} promo={promo} />
</>
),
noIcon: true,
noProgress: true
});
};
export default {
verify,
setPremiumStatus,
@@ -312,5 +365,6 @@ export default {
getUser,
subscriptions,
getMontlySub,
getRemainingTrialDaysStatus
getRemainingTrialDaysStatus,
sheet
};