mobile: update iap library to latest

This commit is contained in:
Ammar Ahmed
2023-11-17 10:03:32 +05:00
parent 9b6a6de415
commit 67b7bdcea3
13 changed files with 574 additions and 138 deletions

View File

@@ -165,7 +165,12 @@ export const Component = ({ close, promo }) => {
}}
size={SIZE.md}
>
({pricing?.product?.localizedPrice} / mo)
(
{Platform.OS === "android"
? pricing.product?.subscriptionOfferDetails[0].pricingPhases
.pricingPhaseList?.[0].formattedPrice
: pricing.product?.localizedPrice}{" "}
/ mo)
</Paragraph>
)}

View File

@@ -18,13 +18,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { View } from "react-native";
import { Platform, View } from "react-native";
import { SIZE } from "../../utils/size";
import { PressableButton } from "../ui/pressable";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import RNIap from "react-native-iap";
export const PricingItem = ({ product, onPress, compact }) => {
export const PricingItem = ({
product,
onPress,
compact
}: {
product: {
type: "yearly" | "monthly";
data?: RNIap.Subscription;
info: string;
offerType?: "yearly" | "monthly";
};
onPress?: () => void;
compact?: boolean;
}) => {
return (
<PressableButton
onPress={onPress}
@@ -54,7 +68,13 @@ export const PricingItem = ({ product, onPress, compact }) => {
<View>
<Paragraph size={SIZE.sm}>
<Heading size={SIZE.lg - 2}>{product?.data?.localizedPrice}/</Heading>
<Heading size={SIZE.lg - 2}>
{Platform.OS === "android"
? (product.data as RNIap.SubscriptionAndroid)
?.subscriptionOfferDetails[0].pricingPhases
.pricingPhaseList?.[0].formattedPrice
: (product.data as RNIap.SubscriptionIOS)?.localizedPrice}
</Heading>
{product?.type === "yearly" || product?.offerType === "yearly"
? "/year"
: "/month"}

View File

@@ -47,11 +47,15 @@ import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
import { Walkthrough } from "../walkthroughs";
import { PricingItem } from "./pricing-item";
import { useSettingStore } from "../../stores/use-setting-store";
const promoCyclesMonthly = {
1: "first month",
2: "first 2 months",
3: "first 3 months"
3: "first 3 months",
4: "first 4 months",
5: "first 5 months",
6: "first 3 months"
};
const promoCyclesYearly = {
@@ -65,10 +69,24 @@ export const PricingPlans = ({
marginTop,
heading = true,
compact = false
}: {
promo?: {
promoCode: string;
};
marginTop?: any;
heading?: boolean;
compact?: boolean;
}) => {
const { colors } = useThemeColors();
const user = useUserStore((state) => state.user);
const [product, setProduct] = useState(null);
const [product, setProduct] = useState<{
type: string;
offerType: "monthly" | "yearly";
data: RNIap.Subscription;
cycleText: string;
info: string;
}>();
const [buying, setBuying] = useState(false);
const [loading, setLoading] = useState(false);
const userCanRequestTrial =
@@ -90,27 +108,40 @@ export const PricingPlans = ({
}
}, [promo?.promoCode]);
const getPromo = async (code) => {
const getPromo = async (code: string) => {
try {
let productId;
let skuId: string;
if (code.startsWith("com.streetwriters.notesnook")) {
productId = code;
skuId = code;
} else {
productId = await db.offers.getCode(code.split(":")[0], Platform.OS);
skuId = await db.offers?.getCode(code.split(":")[0], Platform.OS);
}
let products = await PremiumService.getProducts();
let product = products.find((p) => p.productId === productId);
const products = await PremiumService.getProducts();
const product = products.find((p) => p.productId === skuId);
if (!product) return false;
let isMonthly = product.productId.indexOf(".mo") > -1;
let cycleText = isMonthly
const isMonthly = product.productId.indexOf(".mo") > -1;
const cycleText = isMonthly
? promoCyclesMonthly[
product.introductoryPriceCyclesAndroid ||
product.introductoryPriceNumberOfPeriodsIOS
(Platform.OS === "android"
? (product as RNIap.SubscriptionAndroid)
.subscriptionOfferDetails[0]?.pricingPhases
.pricingPhaseList?.[0].billingCycleCount
: parseInt(
(product as RNIap.SubscriptionIOS)
.introductoryPriceNumberOfPeriodsIOS as string
)) as keyof typeof promoCyclesMonthly
]
: promoCyclesYearly[
product.introductoryPriceCyclesAndroid ||
product.introductoryPriceNumberOfPeriodsIOS
(Platform.OS === "android"
? (product as RNIap.SubscriptionAndroid)
.subscriptionOfferDetails[0]?.pricingPhases
.pricingPhaseList?.[0].billingCycleCount
: parseInt(
(product as RNIap.SubscriptionIOS)
.introductoryPriceNumberOfPeriodsIOS as string
)) as keyof typeof promoCyclesYearly
];
setProduct({
@@ -118,7 +149,7 @@ export const PricingPlans = ({
offerType: isMonthly ? "monthly" : "yearly",
data: product,
cycleText: cycleText,
info: "Pay monthly, cancel anytime"
info: `Pay ${isMonthly ? "monthly" : "yearly"}, cancel anytime`
});
return true;
} catch (e) {
@@ -131,22 +162,37 @@ export const PricingPlans = ({
getSkus();
}, [getSkus]);
const buySubscription = async (product) => {
if (buying) return;
const buySubscription = async (product: RNIap.Subscription) => {
if (buying || !product) return;
setBuying(true);
try {
if (!user) {
setBuying(false);
return;
}
await RNIap.requestSubscription(
product?.productId,
false,
null,
-1,
user.id,
user.id
);
useSettingStore.getState().setAppDidEnterBackgroundForAction(true);
const androidOfferToken =
Platform.OS === "android"
? (product as RNIap.SubscriptionAndroid).subscriptionOfferDetails[0]
.offerToken
: null;
await RNIap.requestSubscription({
sku: product?.productId,
obfuscatedAccountIdAndroid: user.id,
obfuscatedProfileIdAndroid: user.id,
appAccountToken: user.id,
andDangerouslyFinishTransactionAutomaticallyIOS: false,
subscriptionOffers: androidOfferToken
? [
{
offerToken: androidOfferToken,
sku: product?.productId
}
]
: undefined
});
useSettingStore.getState().setAppDidEnterBackgroundForAction(false);
setBuying(false);
eSendEvent(eCloseSheet);
eSendEvent(eClosePremiumDialog);
@@ -198,7 +244,14 @@ export const PricingPlans = ({
}}
size={SIZE.lg}
>
{PremiumService.getMontlySub().localizedPrice} / mo
{(Platform.OS === "android"
? (monthlyPlan?.product as RNIap.SubscriptionAndroid)
?.subscriptionOfferDetails[0].pricingPhases
.pricingPhaseList?.[0].formattedPrice
: (monthlyPlan?.product as RNIap.SubscriptionIOS)
.localizedPrice) ||
(PremiumService.getMontlySub() as any).localizedPrice}
/ mo
</Paragraph>
<Button
onPress={() => {
@@ -218,7 +271,7 @@ export const PricingPlans = ({
<Button
onPress={async () => {
try {
await db.user.activateTrial();
await db.user?.activateTrial();
eSendEvent(eClosePremiumDialog);
eSendEvent(eCloseSheet);
await sleep(300);
@@ -247,7 +300,11 @@ export const PricingPlans = ({
}}
size={SIZE.lg - 4}
>
{product.data.introductoryPrice}
{Platform.OS === "android"
? (product.data as RNIap.SubscriptionAndroid)
?.subscriptionOfferDetails[0].pricingPhases
.pricingPhaseList?.[0].formattedPrice
: (product.data as RNIap.SubscriptionIOS)?.introductoryPrice}
<Paragraph
style={{
textDecorationLine: "line-through",
@@ -255,7 +312,11 @@ export const PricingPlans = ({
}}
size={SIZE.sm}
>
({product.data.localizedPrice})
{Platform.OS === "android"
? (product.data as RNIap.SubscriptionAndroid)
?.subscriptionOfferDetails[1].pricingPhases
.pricingPhaseList?.[1].formattedPrice
: (product.data as RNIap.SubscriptionIOS)?.localizedPrice}
</Paragraph>{" "}
for {product.cycleText}
</Heading>
@@ -263,9 +324,9 @@ export const PricingPlans = ({
{user && !product ? (
<>
{heading || monthlyPlan?.info?.discount > 0 ? (
{heading || (monthlyPlan?.info?.discount || 0) > 0 ? (
<>
{monthlyPlan && monthlyPlan?.info?.discount > 0 ? (
{monthlyPlan && (monthlyPlan?.info?.discount || 0) > 0 ? (
<View
style={{
alignSelf: "center",
@@ -300,7 +361,10 @@ export const PricingPlans = ({
}}
>
<PricingItem
onPress={() => buySubscription(monthlyPlan?.product)}
onPress={() => {
if (!monthlyPlan?.product) return;
buySubscription(monthlyPlan?.product);
}}
compact={compact}
product={{
type: "monthly",
@@ -319,7 +383,10 @@ export const PricingPlans = ({
)}
<PricingItem
onPress={() => buySubscription(yearlyPlan?.product)}
onPress={() => {
if (!yearlyPlan?.product) return;
buySubscription(yearlyPlan?.product);
}}
compact={compact}
product={{
type: "yearly",
@@ -346,7 +413,7 @@ export const PricingPlans = ({
eSendEvent(eCloseSimpleDialog);
setBuying(true);
try {
if (!(await getPromo(value)))
if (!(await getPromo(value as string)))
throw new Error("Error applying promo code");
ToastEvent.show({
heading: "Discount applied!",
@@ -358,7 +425,7 @@ export const PricingPlans = ({
setBuying(false);
ToastEvent.show({
heading: "Promo code invalid or expired",
message: e.message,
message: (e as Error).message,
type: "error",
context: "local"
});
@@ -427,7 +494,10 @@ export const PricingPlans = ({
) : (
<>
<Button
onPress={() => buySubscription(product.data)}
onPress={() => {
if (!product?.data) return;
buySubscription(product.data);
}}
height={40}
width="50%"
type="accent"
@@ -436,7 +506,7 @@ export const PricingPlans = ({
<Button
onPress={() => {
setProduct(null);
setProduct(undefined);
}}
style={{
marginTop: 5
@@ -523,7 +593,7 @@ export const PricingPlans = ({
<Paragraph
size={SIZE.xs}
onPress={() => {
openLinkInBrowser("https://notesnook.com/tos", colors)
openLinkInBrowser("https://notesnook.com/tos")
.catch(() => {})
.then(() => {});
}}
@@ -538,7 +608,7 @@ export const PricingPlans = ({
<Paragraph
size={SIZE.xs}
onPress={() => {
openLinkInBrowser("https://notesnook.com/privacy", colors)
openLinkInBrowser("https://notesnook.com/privacy")
.catch(() => {})
.then(() => {});
}}

View File

@@ -229,12 +229,25 @@ async function saveEditorState() {
MMKV.setString("appState", state);
}
}
/**
*
* @param {RNIap.Purchase} subscription
*/
const onSuccessfulSubscription = async (subscription) => {
console.log(
"Subscription success!",
subscription.transactionId,
subscription.obfuscatedAccountIdAndroid,
subscription.obfuscatedProfileIdAndroid
);
await PremiumService.subscriptions.set(subscription);
await PremiumService.subscriptions.verify(subscription);
};
/**
*
* @param {RNIap.PurchaseError} error
*/
const onSubscriptionError = async (error) => {
ToastEvent.show({
heading: "Failed to subscribe",
@@ -490,9 +503,9 @@ export const useAppEvents = () => {
);
const subscribeToIAPListeners = useCallback(async () => {
await RNIap.initConnection()
.catch(() => null)
.then(async () => {
RNIap.flushFailedPurchasesCachedAsPendingAndroid()
.catch(() => {})
.then(() => {
refValues.current.subsriptionSuccessListener =
RNIap.purchaseUpdatedListener(onSuccessfulSubscription);
refValues.current.subsriptionErrorListener =

View File

@@ -88,6 +88,13 @@ export const Subscription = () => {
}
};
function getPrice() {
return Platform.OS === "android"
? monthlyPlan?.product?.subscriptionOfferDetails[0].pricingPhases
.pricingPhaseList?.[0].formattedPrice
: monthlyPlan?.product?.localizedPrice;
}
return (
<View>
{isNotPro ? (
@@ -114,12 +121,8 @@ export const Subscription = () => {
Config.GITHUB_RELEASE !== "true"
? "Resubscribe from Google Playstore"
: user.subscription?.type === SUBSCRIPTION_STATUS.PREMIUM_EXPIRED
? `Resubscribe to Pro (${
monthlyPlan?.product?.localizedPrice || "$4.49"
} / mo)`
: `Get Pro (${
monthlyPlan?.product?.localizedPrice || "$4.49"
} / mo)`
? `Resubscribe to Pro (${getPrice() || "$4.49"} / mo)`
: `Get Pro (${getPrice() || "$4.49"} / mo)`
}
/>
) : null}

View File

@@ -39,6 +39,10 @@ import { eSendEvent, presentSheet, ToastEvent } from "./event-manager";
import SettingsService from "./settings";
let premiumStatus = 0;
/**
* @type {RNIap.Subscription[]}
*/
let products = [];
let user = null;
@@ -68,7 +72,9 @@ async function setPremiumStatus() {
}
try {
await RNIap.initConnection();
products = await RNIap.getSubscriptions(itemSkus);
products = await RNIap.getSubscriptions({
skus: itemSkus
});
} catch (e) {
console.log("subscriptions: ", e);
}
@@ -223,12 +229,21 @@ const showVerifyEmailDialog = () => {
};
const subscriptions = {
/**
*
* @returns {RNIap.Purchase} subscription
*/
get: async () => {
if (Platform.OS === "android") return;
let _subscriptions = MMKV.getString("subscriptionsIOS");
if (!_subscriptions) return [];
return JSON.parse(_subscriptions);
},
/**
*
* @param {RNIap.Purchase} subscription
* @returns
*/
set: async (subscription) => {
if (Platform.OS === "android") return;
let _subscriptions = MMKV.getString("subscriptionsIOS");
@@ -263,6 +278,10 @@ const subscriptions = {
MMKV.setString("subscriptionsIOS", JSON.stringify(_subscriptions));
}
},
/**
*
* @param {RNIap.Purchase} subscription
*/
verify: async (subscription) => {
if (Platform.OS === "android") return;

View File

@@ -111,7 +111,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 2066
versionCode 2067
versionName getNpmVersion()
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

View File

@@ -8,6 +8,10 @@ import com.ammarahmed.mmkv.MMKV;
public class OnClearFromRecentService extends Service {
static {
System.loadLibrary("rnmmkv");
}
@Override
public IBinder onBind(Intent intent) {
return null;
@@ -15,7 +19,6 @@ public class OnClearFromRecentService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@@ -31,8 +34,10 @@ public class OnClearFromRecentService extends Service {
MMKV mmkv = MMKV.mmkvWithID("default",MMKV.SINGLE_PROCESS_MODE);
mmkv.removeValueForKey("appState");
stopSelf();
} catch (Exception e) {
} catch (UnsatisfiedLinkError e) {
} catch (Exception e) {
}
//System.exit(0);
}

View File

@@ -7,7 +7,7 @@ buildscript {
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
ext.kotlinVersion = '1.6.10'
ext.kotlinVersion = '1.8.0'
androidXAnnotation = "1.1.0"
androidXCoreVersion = "1.7.0"
androidXCore = "1.7.0"

View File

@@ -477,7 +477,7 @@ PODS:
- React-Core
- RNGestureHandler (2.12.0):
- React-Core
- RNIap (7.5.6):
- RNIap (12.11.0):
- React-Core
- RNKeychain (4.0.5):
- React
@@ -911,7 +911,7 @@ SPEC CHECKSUMS:
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFlashList: 399bf6a0db68f594ad2c86aaff3ea39564f39f8a
RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5
RNIap: d248609d1b8937e63bd904e865c318e9b1457eff
RNIap: fc9af04ee706894a80c9d8f979bae930b0dee191
RNKeychain: 840f8e6f13be0576202aefcdffd26a4f54bfe7b5
RNNotifee: 2ae3c18196e6f307fa62ae5c8e5305dea03ff147
RNPrivacySnapshot: 8eaf571478a353f2e5184f5c803164f22428b023

View File

@@ -40,7 +40,7 @@
"react-native-get-random-values": "^1.7.0",
"react-native-gzip": "1.1.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "7.5.6",
"react-native-iap": "12.11.0",
"react-native-image-picker": "4.1.2",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",

View File

@@ -26,7 +26,8 @@
"@trpc/react-query": "10.38.3",
"@trpc/server": "10.38.3",
"react": "18.2.0",
"react-native": "0.72.0"
"react-native": "0.72.0",
"react-native-iap": "12.11.0"
},
"devDependencies": {
"fonteditor-core": "^2.1.11",
@@ -110,28 +111,28 @@
"@social-embed/lib": "^0.0.2-next.1",
"@theme-ui/components": ">=0.14.0",
"@theme-ui/core": ">=0.14.0",
"@tiptap/core": "2.1.11",
"@tiptap/extension-character-count": "2.1.11",
"@tiptap/extension-color": "2.1.11",
"@tiptap/extension-font-family": "2.1.11",
"@tiptap/extension-history": "2.1.11",
"@tiptap/extension-horizontal-rule": "2.1.11",
"@tiptap/extension-link": "2.1.11",
"@tiptap/extension-list-keymap": "2.1.11",
"@tiptap/extension-placeholder": "2.1.11",
"@tiptap/extension-subscript": "2.1.11",
"@tiptap/extension-superscript": "2.1.11",
"@tiptap/extension-table": "2.1.11",
"@tiptap/extension-table-cell": "2.1.11",
"@tiptap/extension-table-header": "2.1.11",
"@tiptap/extension-table-row": "2.1.11",
"@tiptap/extension-task-item": "2.1.11",
"@tiptap/extension-task-list": "2.1.11",
"@tiptap/extension-text-align": "2.1.11",
"@tiptap/extension-text-style": "2.1.11",
"@tiptap/extension-underline": "2.1.11",
"@tiptap/pm": "2.1.11",
"@tiptap/starter-kit": "2.1.11",
"@tiptap/core": "2.1.12",
"@tiptap/extension-character-count": "2.1.12",
"@tiptap/extension-color": "2.1.12",
"@tiptap/extension-font-family": "2.1.12",
"@tiptap/extension-history": "2.1.12",
"@tiptap/extension-horizontal-rule": "2.1.12",
"@tiptap/extension-link": "2.1.12",
"@tiptap/extension-list-keymap": "2.1.12",
"@tiptap/extension-placeholder": "2.1.12",
"@tiptap/extension-subscript": "2.1.12",
"@tiptap/extension-superscript": "2.1.12",
"@tiptap/extension-table": "2.1.12",
"@tiptap/extension-table-cell": "2.1.12",
"@tiptap/extension-table-header": "2.1.12",
"@tiptap/extension-table-row": "2.1.12",
"@tiptap/extension-task-item": "2.1.12",
"@tiptap/extension-task-list": "2.1.12",
"@tiptap/extension-text-align": "2.1.12",
"@tiptap/extension-text-style": "2.1.12",
"@tiptap/extension-underline": "2.1.12",
"@tiptap/pm": "2.1.12",
"@tiptap/starter-kit": "2.1.12",
"clipboard-polyfill": "4.0.0",
"detect-indent": "^7.0.0",
"entities": "^4.5.0",
@@ -139,7 +140,7 @@
"nanoid": "^4.0.1",
"prism-themes": "^1.9.0",
"prosemirror-codemark": "^0.4.2",
"prosemirror-view": "^1.31.8",
"prosemirror-view": "1.32.2",
"re-resizable": "^6.9.9",
"react-colorful": "^5.5.1",
"react-modal": "3.13.1",
@@ -313,7 +314,7 @@
"react-native-get-random-values": "^1.7.0",
"react-native-gzip": "1.1.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "7.5.6",
"react-native-iap": "12.11.0",
"react-native-image-picker": "4.1.2",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",
@@ -5001,6 +5002,169 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@expo/config-plugins": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-6.0.2.tgz",
"integrity": "sha512-Cn01fXMHwjU042EgO9oO3Mna0o/UCrW91MQLMbJa4pXM41CYGjNgVy1EVXiuRRx/upegHhvltBw5D+JaUm8aZQ==",
"dependencies": {
"@expo/config-types": "^48.0.0",
"@expo/json-file": "~8.2.37",
"@expo/plist": "^0.0.20",
"@expo/sdk-runtime-versions": "^1.0.0",
"@react-native/normalize-color": "^2.0.0",
"chalk": "^4.1.2",
"debug": "^4.3.1",
"find-up": "~5.0.0",
"getenv": "^1.0.0",
"glob": "7.1.6",
"resolve-from": "^5.0.0",
"semver": "^7.3.5",
"slash": "^3.0.0",
"xcode": "^3.0.1",
"xml2js": "0.4.23"
}
},
"node_modules/@expo/config-plugins/node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@expo/config-plugins/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@expo/config-plugins/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@expo/config-plugins/node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"engines": {
"node": ">=8"
}
},
"node_modules/@expo/config-plugins/node_modules/uuid": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/@expo/config-plugins/node_modules/xcode": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
"integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
"dependencies": {
"simple-plist": "^1.1.0",
"uuid": "^7.0.3"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@expo/config-plugins/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/@expo/config-types": {
"version": "48.0.0",
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-48.0.0.tgz",
"integrity": "sha512-DwyV4jTy/+cLzXGAo1xftS6mVlSiLIWZjl9DjTCLPFVgNYQxnh7htPilRv4rBhiNs7KaznWqKU70+4zQoKVT9A=="
},
"node_modules/@expo/json-file": {
"version": "8.2.37",
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.2.37.tgz",
"integrity": "sha512-YaH6rVg11JoTS2P6LsW7ybS2CULjf40AbnAHw2F1eDPuheprNjARZMnyHFPkKv7GuxCy+B9GPcbOKgc4cgA80Q==",
"dependencies": {
"@babel/code-frame": "~7.10.4",
"json5": "^2.2.2",
"write-file-atomic": "^2.3.0"
}
},
"node_modules/@expo/json-file/node_modules/@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dependencies": {
"@babel/highlight": "^7.10.4"
}
},
"node_modules/@expo/json-file/node_modules/write-file-atomic": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
"integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
"dependencies": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.2"
}
},
"node_modules/@expo/plist": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.0.20.tgz",
"integrity": "sha512-UXQ4LXCfTZ580LDHGJ5q62jSTwJFFJ1GqBu8duQMThiHKWbMJ+gajJh6rsB6EJ3aLUr9wcauxneL5LVRFxwBEA==",
"dependencies": {
"@xmldom/xmldom": "~0.7.7",
"base64-js": "^1.2.3",
"xmlbuilder": "^14.0.0"
}
},
"node_modules/@expo/plist/node_modules/@xmldom/xmldom": {
"version": "0.7.13",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz",
"integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@expo/plist/node_modules/xmlbuilder": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-14.0.0.tgz",
"integrity": "sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==",
"engines": {
"node": ">=8.0"
}
},
"node_modules/@expo/sdk-runtime-versions": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
"integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="
},
"node_modules/@fastify/ajv-compiler": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz",
@@ -10089,15 +10253,6 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dooboolab-welcome": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dooboolab-welcome/-/dooboolab-welcome-1.3.2.tgz",
"integrity": "sha512-2NbMaIIURElxEf/UAoVUFlXrO+7n/FRhLCiQlk4fkbGRh9cJ3/f8VEMPveR9m4Ug2l2Zey+UCXjd6EcBqHJ5bw==",
"hasInstallScript": true,
"bin": {
"dooboolab-welcome": "bin/hello.js"
}
},
"node_modules/dtrace-provider": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
@@ -12115,6 +12270,14 @@
"node": ">=0.10.0"
}
},
"node_modules/getenv": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/getenv/-/getenv-1.0.0.tgz",
"integrity": "sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==",
"engines": {
"node": ">=6"
}
},
"node_modules/gifwrap": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz",
@@ -18190,15 +18353,15 @@
"integrity": "sha512-HeD7YDHO7pL/4n/lAJCo1L4x0+JeKiME95B8jwH8lGBzkcHNX1hmb+CFM9SGSI//YtUL/a2sQjjkkoh6Cf7GNw=="
},
"node_modules/react-native-iap": {
"version": "7.5.6",
"resolved": "https://registry.npmjs.org/react-native-iap/-/react-native-iap-7.5.6.tgz",
"integrity": "sha512-ua+KTq7NO+/Rw+S9cGDZizR45AdmpQ0LEx9gSubbRD3f5KSTp91mEMHgdyVcqUcxiBuVgRTfv3zy9mbPEdo8Mg==",
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/react-native-iap/-/react-native-iap-12.11.0.tgz",
"integrity": "sha512-KrRHTqbwEypntb/C+zyD2cV7fRi2Izx9NTd0fIb30yUIvIZ5sD5RQd0kOcabqyQYzfSYPAnZVUIXEtOfjwcJFg==",
"dependencies": {
"dooboolab-welcome": "1.3.2"
"@expo/config-plugins": "^6.0.1"
},
"peerDependencies": {
"react": ">=16.13.1",
"react-native": ">=0.54"
"react-native": ">=0.65.1"
}
},
"node_modules/react-native-image-pan-zoom": {
@@ -18876,7 +19039,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
"engines": {
"node": ">=8"
}
@@ -25460,6 +25622,145 @@
"integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
"dev": true
},
"@expo/config-plugins": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-6.0.2.tgz",
"integrity": "sha512-Cn01fXMHwjU042EgO9oO3Mna0o/UCrW91MQLMbJa4pXM41CYGjNgVy1EVXiuRRx/upegHhvltBw5D+JaUm8aZQ==",
"requires": {
"@expo/config-types": "^48.0.0",
"@expo/json-file": "~8.2.37",
"@expo/plist": "^0.0.20",
"@expo/sdk-runtime-versions": "^1.0.0",
"@react-native/normalize-color": "^2.0.0",
"chalk": "^4.1.2",
"debug": "^4.3.1",
"find-up": "~5.0.0",
"getenv": "^1.0.0",
"glob": "7.1.6",
"resolve-from": "^5.0.0",
"semver": "^7.3.5",
"slash": "^3.0.0",
"xcode": "^3.0.1",
"xml2js": "0.4.23"
},
"dependencies": {
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"uuid": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="
},
"xcode": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
"integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
"requires": {
"simple-plist": "^1.1.0",
"uuid": "^7.0.3"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"@expo/config-types": {
"version": "48.0.0",
"resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-48.0.0.tgz",
"integrity": "sha512-DwyV4jTy/+cLzXGAo1xftS6mVlSiLIWZjl9DjTCLPFVgNYQxnh7htPilRv4rBhiNs7KaznWqKU70+4zQoKVT9A=="
},
"@expo/json-file": {
"version": "8.2.37",
"resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-8.2.37.tgz",
"integrity": "sha512-YaH6rVg11JoTS2P6LsW7ybS2CULjf40AbnAHw2F1eDPuheprNjARZMnyHFPkKv7GuxCy+B9GPcbOKgc4cgA80Q==",
"requires": {
"@babel/code-frame": "~7.10.4",
"json5": "^2.2.2",
"write-file-atomic": "^2.3.0"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"requires": {
"@babel/highlight": "^7.10.4"
}
},
"write-file-atomic": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
"integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
"requires": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.2"
}
}
}
},
"@expo/plist": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.0.20.tgz",
"integrity": "sha512-UXQ4LXCfTZ580LDHGJ5q62jSTwJFFJ1GqBu8duQMThiHKWbMJ+gajJh6rsB6EJ3aLUr9wcauxneL5LVRFxwBEA==",
"requires": {
"@xmldom/xmldom": "~0.7.7",
"base64-js": "^1.2.3",
"xmlbuilder": "^14.0.0"
},
"dependencies": {
"@xmldom/xmldom": {
"version": "0.7.13",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz",
"integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g=="
},
"xmlbuilder": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-14.0.0.tgz",
"integrity": "sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg=="
}
}
},
"@expo/sdk-runtime-versions": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
"integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="
},
"@fastify/ajv-compiler": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz",
@@ -26473,28 +26774,28 @@
"@social-embed/lib": "^0.0.2-next.1",
"@theme-ui/components": ">=0.14.0",
"@theme-ui/core": ">=0.14.0",
"@tiptap/core": "2.1.11",
"@tiptap/extension-character-count": "2.1.11",
"@tiptap/extension-color": "2.1.11",
"@tiptap/extension-font-family": "2.1.11",
"@tiptap/extension-history": "2.1.11",
"@tiptap/extension-horizontal-rule": "2.1.11",
"@tiptap/extension-link": "2.1.11",
"@tiptap/extension-list-keymap": "2.1.11",
"@tiptap/extension-placeholder": "2.1.11",
"@tiptap/extension-subscript": "2.1.11",
"@tiptap/extension-superscript": "2.1.11",
"@tiptap/extension-table": "2.1.11",
"@tiptap/extension-table-cell": "2.1.11",
"@tiptap/extension-table-header": "2.1.11",
"@tiptap/extension-table-row": "2.1.11",
"@tiptap/extension-task-item": "2.1.11",
"@tiptap/extension-task-list": "2.1.11",
"@tiptap/extension-text-align": "2.1.11",
"@tiptap/extension-text-style": "2.1.11",
"@tiptap/extension-underline": "2.1.11",
"@tiptap/pm": "2.1.11",
"@tiptap/starter-kit": "2.1.11",
"@tiptap/core": "2.1.12",
"@tiptap/extension-character-count": "2.1.12",
"@tiptap/extension-color": "2.1.12",
"@tiptap/extension-font-family": "2.1.12",
"@tiptap/extension-history": "2.1.12",
"@tiptap/extension-horizontal-rule": "2.1.12",
"@tiptap/extension-link": "2.1.12",
"@tiptap/extension-list-keymap": "2.1.12",
"@tiptap/extension-placeholder": "2.1.12",
"@tiptap/extension-subscript": "2.1.12",
"@tiptap/extension-superscript": "2.1.12",
"@tiptap/extension-table": "2.1.12",
"@tiptap/extension-table-cell": "2.1.12",
"@tiptap/extension-table-header": "2.1.12",
"@tiptap/extension-table-row": "2.1.12",
"@tiptap/extension-task-item": "2.1.12",
"@tiptap/extension-task-list": "2.1.12",
"@tiptap/extension-text-align": "2.1.12",
"@tiptap/extension-text-style": "2.1.12",
"@tiptap/extension-underline": "2.1.12",
"@tiptap/pm": "2.1.12",
"@tiptap/starter-kit": "2.1.12",
"@types/katex": "^0.14.0",
"@types/prismjs": "^1.26.0",
"@types/react": "17.0.2",
@@ -26513,7 +26814,7 @@
"prism-themes": "^1.9.0",
"prosemirror-codemark": "^0.4.2",
"prosemirror-test-builder": "^1.1.0",
"prosemirror-view": "^1.31.8",
"prosemirror-view": "1.32.2",
"re-resizable": "^6.9.9",
"react": "17.0.2",
"react-colorful": "^5.5.1",
@@ -26669,7 +26970,7 @@
"react-native-get-random-values": "^1.7.0",
"react-native-gzip": "1.1.0",
"react-native-html-to-pdf-lite": "^0.9.1",
"react-native-iap": "7.5.6",
"react-native-iap": "12.11.0",
"react-native-image-picker": "4.1.2",
"react-native-in-app-review": "4.3.3",
"react-native-keychain": "4.0.5",
@@ -29651,11 +29952,6 @@
"domhandler": "^5.0.3"
}
},
"dooboolab-welcome": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dooboolab-welcome/-/dooboolab-welcome-1.3.2.tgz",
"integrity": "sha512-2NbMaIIURElxEf/UAoVUFlXrO+7n/FRhLCiQlk4fkbGRh9cJ3/f8VEMPveR9m4Ug2l2Zey+UCXjd6EcBqHJ5bw=="
},
"dtrace-provider": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
@@ -31195,6 +31491,11 @@
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="
},
"getenv": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/getenv/-/getenv-1.0.0.tgz",
"integrity": "sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg=="
},
"gifwrap": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz",
@@ -35753,11 +36054,11 @@
"integrity": "sha512-HeD7YDHO7pL/4n/lAJCo1L4x0+JeKiME95B8jwH8lGBzkcHNX1hmb+CFM9SGSI//YtUL/a2sQjjkkoh6Cf7GNw=="
},
"react-native-iap": {
"version": "7.5.6",
"resolved": "https://registry.npmjs.org/react-native-iap/-/react-native-iap-7.5.6.tgz",
"integrity": "sha512-ua+KTq7NO+/Rw+S9cGDZizR45AdmpQ0LEx9gSubbRD3f5KSTp91mEMHgdyVcqUcxiBuVgRTfv3zy9mbPEdo8Mg==",
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/react-native-iap/-/react-native-iap-12.11.0.tgz",
"integrity": "sha512-KrRHTqbwEypntb/C+zyD2cV7fRi2Izx9NTd0fIb30yUIvIZ5sD5RQd0kOcabqyQYzfSYPAnZVUIXEtOfjwcJFg==",
"requires": {
"dooboolab-welcome": "1.3.2"
"@expo/config-plugins": "^6.0.1"
}
},
"react-native-image-pan-zoom": {
@@ -36267,8 +36568,7 @@
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="
},
"resolve-url": {
"version": "0.2.1",

View File

@@ -41,6 +41,7 @@
"@trpc/react-query": "10.38.3",
"@trpc/server": "10.38.3",
"react": "18.2.0",
"react-native": "0.72.0"
"react-native": "0.72.0",
"react-native-iap": "12.11.0"
}
}
}