From 7ad3fd405704b768d8a9a248972ef6ae39b66640 Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Sat, 13 Sep 2025 12:13:36 +0500 Subject: [PATCH] mobile: refactor --- .../paywall.tsx => paywall/index.tsx} | 38 ++++++++----- .../app/components/premium/features-list.tsx | 24 -------- apps/mobile/app/hooks/use-pricing-plans.ts | 56 ++++++++++++++++++- .../app/navigation/navigation-stack.tsx | 3 +- 4 files changed, 80 insertions(+), 41 deletions(-) rename apps/mobile/app/components/{premium/paywall.tsx => paywall/index.tsx} (98%) delete mode 100644 apps/mobile/app/components/premium/features-list.tsx diff --git a/apps/mobile/app/components/premium/paywall.tsx b/apps/mobile/app/components/paywall/index.tsx similarity index 98% rename from apps/mobile/app/components/premium/paywall.tsx rename to apps/mobile/app/components/paywall/index.tsx index 53af33961..052ddea58 100644 --- a/apps/mobile/app/components/premium/paywall.tsx +++ b/apps/mobile/app/components/paywall/index.tsx @@ -18,7 +18,14 @@ along with this program. If not, see . */ import { getFeaturesTable } from "@notesnook/common"; -import { EV, EVENTS, Plan, SubscriptionPlan, User } from "@notesnook/core"; +import { + EV, + EVENTS, + Plan, + SKUResponse, + SubscriptionPlan, + User +} from "@notesnook/core"; import { strings } from "@notesnook/intl"; import { useThemeColors } from "@notesnook/theme"; import React, { useEffect, useState } from "react"; @@ -924,22 +931,14 @@ const PricingPlanCard = ({ setStep: (step: number) => void; }) => { const { colors } = useThemeColors(); - const isSelected = pricingPlans?.currentPlan?.id === plan.id; const isFreePlan = plan.id === "free"; + const [regionalDiscount, setRegionaDiscount] = useState(); const product = plan.subscriptions?.[ `notesnook.${plan.id}.${annualBilling ? "yearly" : "monthly"}` ]; - const discountPercentage = annualBilling - ? pricingPlans?.compareProductPrice( - plan.id, - `notesnook.${plan.id}.yearly`, - `notesnook.${plan.id}.monthly` - ) - : null; - const price = pricingPlans?.getPrice( product as RNIap.Subscription, pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0, @@ -951,6 +950,19 @@ const PricingPlanCard = ({ annualBilling ? "yearly" : "monthly" ); + useEffect(() => { + pricingPlans + ?.getRegionalDiscount( + plan.id, + pricingPlans.isGithubRelease + ? (WebPlan?.period as string) + : (product?.productId as string) + ) + .then((value) => { + setRegionaDiscount(value); + }); + }, [pricingPlans, plan, product, WebPlan]); + return ( - {/* {discountPercentage ? ( + {regionalDiscount?.discount ? ( - {discountPercentage}% Off + {regionalDiscount?.discount}% Off - ) : null} */} + ) : null} diff --git a/apps/mobile/app/components/premium/features-list.tsx b/apps/mobile/app/components/premium/features-list.tsx deleted file mode 100644 index 46c82886d..000000000 --- a/apps/mobile/app/components/premium/features-list.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/* -This file is part of the Notesnook project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ -export const FeaturesList = { - // Monthly: ["$0/mo", "$1.99/mo", "$5.99/mo", "$9.99/mo"], - // Yearly: ["$0/yr", "$14.99/yr", "$59.99/yr", "$109.99/yr"], - // "5 year": [null, null, "$249.99/5yr", "$449.99/5yr"], - Plans: ["Free", "Essential", "Pro", "Believer"] -}; diff --git a/apps/mobile/app/hooks/use-pricing-plans.ts b/apps/mobile/app/hooks/use-pricing-plans.ts index 87d711cb7..9d1ee82cf 100644 --- a/apps/mobile/app/hooks/use-pricing-plans.ts +++ b/apps/mobile/app/hooks/use-pricing-plans.ts @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { Plan } from "@notesnook/core"; +import { Plan, SKUResponse, SubscriptionPlanId } from "@notesnook/core"; import { useEffect, useState } from "react"; import { Platform } from "react-native"; import Config from "react-native-config"; @@ -160,6 +160,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => { const [cancelPromo, setCancelPromo] = useState(false); const [userCanRequestTrial, setUserCanRequestTrial] = useState(false); const [webPricingPlans, setWebPricingPlans] = useState([]); + const [regionalDiscount, setRegionalDiscount] = useState(); const getProduct = (planId: string, skuId: string) => { if (isGithubRelease) @@ -189,6 +190,17 @@ const usePricingPlans = (options?: PricingPlansOptions) => { if (!selectedProductSku && !productId) return false; if (productId?.includes("5year")) return false; + if (isGithubRelease) { + if ( + user?.subscription.trialsAvailed?.some( + (plan) => plan === planIdToIndex(planId || currentPlan) + ) + ) { + return false; + } else { + return true; + } + } return Platform.OS === "ios" ? ( @@ -652,6 +664,43 @@ const usePricingPlans = (options?: PricingPlansOptions) => { // } + useEffect(() => { + db.pricing + .sku( + isGithubRelease + ? "paddle" + : Platform.OS === "android" + ? "google" + : "apple", + selectedProductSku.includes("5") + ? "5-year" + : selectedProductSku.includes("year") + ? "yearly" + : "monthly", + currentPlan as SubscriptionPlanId + ) + .then((sku) => setRegionalDiscount(sku)) + .catch((e) => console.log(e)); + }, [currentPlan, selectedProductSku]); + + async function getRegionalDiscount(plan: string, productId: string) { + try { + return await db.pricing.sku( + isGithubRelease + ? "paddle" + : Platform.OS === "android" + ? "google" + : "apple", + productId.includes("5") + ? "5-year" + : productId.includes("year") + ? "yearly" + : "monthly", + plan as SubscriptionPlanId + ); + } catch (e) {} + } + return { currentPlan: pricingPlans.find((p) => p.id === currentPlan), pricingPlans: plans, @@ -700,7 +749,10 @@ const usePricingPlans = (options?: PricingPlansOptions) => { return webPricingPlans.find( (plan) => plan.plan === planIndex && plan.period === period ); - } + }, + regionalDiscount, + getRegionalDiscount, + isGithubRelease: isGithubRelease }; }; diff --git a/apps/mobile/app/navigation/navigation-stack.tsx b/apps/mobile/app/navigation/navigation-stack.tsx index 124a2ef36..f566ccc0f 100644 --- a/apps/mobile/app/navigation/navigation-stack.tsx +++ b/apps/mobile/app/navigation/navigation-stack.tsx @@ -358,8 +358,7 @@ export const RootNavigation = () => { { - PayWall = - PayWall || require("../components/premium/paywall").default; + PayWall = PayWall || require("../components/paywall").default; return PayWall; }} />