diff --git a/apps/mobile/app/hooks/use-app-events.tsx b/apps/mobile/app/hooks/use-app-events.tsx index 055a7b471..78ca9f098 100644 --- a/apps/mobile/app/hooks/use-app-events.tsx +++ b/apps/mobile/app/hooks/use-app-events.tsx @@ -17,13 +17,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +import { isFeatureAvailable } from "@notesnook/common"; import { EV, EVENTS, EventManagerSubscription, SYNC_CHECK_IDS, SubscriptionPlan, - SubscriptionType, SyncStatusEvent, User } from "@notesnook/core"; @@ -51,7 +51,9 @@ import { MMKV } from "../common/database/mmkv"; import { endProgress, startProgress } from "../components/dialogs/progress"; import Migrate from "../components/sheets/migrate"; import NewFeature from "../components/sheets/new-feature"; +import PaywallSheet from "../components/sheets/paywall"; import { Walkthrough } from "../components/walkthroughs"; +import AddReminder from "../screens/add-reminder"; import { resetTabStore, useTabStore @@ -104,9 +106,6 @@ import { getGithubVersion } from "../utils/github-version"; import { fluidTabsRef } from "../utils/global-refs"; import { NotesnookModule } from "../utils/notesnook-module"; import { sleep } from "../utils/time"; -import AddReminder from "../screens/add-reminder"; -import { isFeatureAvailable } from "@notesnook/common"; -import PaywallSheet from "../components/sheets/paywall"; import useFeatureManager from "./use-feature-manager"; const onCheckSyncStatus = async (type: SyncStatusEvent) => { @@ -226,11 +225,7 @@ const onUserEmailVerified = async () => { const onUserSubscriptionStatusChanged = async ( subscription: User["subscription"] ) => { - if ( - !PremiumService.get() && - (subscription.type === SubscriptionType.PREMIUM || - subscription.plan != SubscriptionPlan.FREE) - ) { + if (!PremiumService.get() && subscription.plan !== SubscriptionPlan.FREE) { PremiumService.subscriptions.clear(); useUserStore.setState({ user: { diff --git a/apps/mobile/app/screens/settings/components.tsx b/apps/mobile/app/screens/settings/components.tsx index 81e04d5e7..1b6996670 100644 --- a/apps/mobile/app/screens/settings/components.tsx +++ b/apps/mobile/app/screens/settings/components.tsx @@ -18,11 +18,15 @@ along with this program. If not, see . */ import React, { ReactElement } from "react"; +import { View } from "react-native"; import { AttachmentDialog } from "../../components/attachments"; +import { ChangePassword } from "../../components/auth/change-password"; +import { DefaultAppStyles } from "../../utils/styles"; +import { AttachmentGroupProgress } from "./attachment-group-progress"; +import { ChangeEmail } from "./change-email"; import DebugLogs from "./debug"; import { ConfigureToolbar } from "./editor/configure-toolbar"; import { Licenses } from "./licenses"; -import { AttachmentGroupProgress } from "./attachment-group-progress"; import { ApplockTimerPicker, BackupReminderPicker, @@ -37,18 +41,12 @@ import { import { RestoreBackup } from "./restore-backup"; import { ServersConfiguration } from "./server-config"; import SoundPicker from "./sound-picker"; -import { Subscription } from "./subscription"; import ThemeSelector from "./theme-selector"; import { TitleFormat } from "./title-format"; -import { View } from "react-native"; -import { DefaultAppStyles } from "../../utils/styles"; -import { ChangePassword } from "../../components/auth/change-password"; -import { ChangeEmail } from "./change-email"; export const components: { [name: string]: ReactElement } = { homeselector: , autobackups: , - subscription: , configuretoolbar: , "debug-logs": , "sound-picker": , diff --git a/apps/mobile/app/screens/settings/settings-data.tsx b/apps/mobile/app/screens/settings/settings-data.tsx index df38c15ec..ca2a48fb5 100644 --- a/apps/mobile/app/screens/settings/settings-data.tsx +++ b/apps/mobile/app/screens/settings/settings-data.tsx @@ -18,7 +18,7 @@ along with this program. If not, see . */ import { formatBytes } from "@notesnook/common"; -import { User } from "@notesnook/core"; +import { SubscriptionPlan, SubscriptionStatus, User } from "@notesnook/core"; import { strings } from "@notesnook/intl"; import notifee from "@notifee/react-native"; import Clipboard from "@react-native-clipboard/clipboard"; @@ -27,7 +27,6 @@ import React from "react"; import { Appearance, Linking, Platform } from "react-native"; import { getVersion } from "react-native-device-info"; import * as RNIap from "react-native-iap"; -//@ts-ignore import { enabled } from "react-native-privacy-snapshot"; import ScreenGuardModule from "react-native-screenguard"; import { db } from "../../common/database"; @@ -57,7 +56,6 @@ import SettingsService from "../../services/settings"; import Sync from "../../services/sync"; import { useThemeStore } from "../../stores/use-theme-store"; import { useUserStore } from "../../stores/use-user-store"; -import { SUBSCRIPTION_STATUS } from "../../utils/constants"; import { eCloseSheet, eOpenRecoveryKeyDialog } from "../../utils/events"; import { NotesnookModule } from "../../utils/notesnook-module"; import { sleep } from "../../utils/time"; @@ -75,59 +73,67 @@ export const settingsGroups: SettingSection[] = [ useHook: () => useUserStore((state) => state.user), hidden: (current) => !current, sections: [ - // { - // id: "subscription-status", - // useHook: () => useUserStore((state) => state.user), - // hidden: (current) => !current, - // name: (current) => { - // const user = (current as User) || useUserStore.getState().user; - // if (!user) return strings.upgradePlan(); - // const isBasic = user.subscription?.type === SUBSCRIPTION_STATUS.BASIC; - // const isTrial = user.subscription?.type === SUBSCRIPTION_STATUS.TRIAL; - // return isBasic || !user.subscription?.type - // ? strings.upgradePlan() - // : isTrial - // ? strings.trialStarted() - // : strings.subDetails(); - // ``; - // }, - // type: "component", - // component: "subscription", - // icon: "crown", - // description: (current) => { - // const user = current as User; - // if (!user) return strings.neverHesitate(); - // const subscriptionDaysLeft = - // user && - // getTimeLeft( - // parseInt(user.subscription?.expiry as unknown as string) - // ); - // const expiryDate = dayjs(user?.subscription?.expiry).format( - // "MMMM D, YYYY" - // ); - // const startDate = dayjs(user?.subscription?.start).format( - // "MMMM D, YYYY" - // ); + { + id: "subscription-status", + useHook: () => useUserStore((state) => state.user), + hidden: (current) => + !current || + (current as User).subscription?.plan === SubscriptionPlan.FREE, + name: (current) => { + const user = (current as User) || useUserStore.getState().user; + return ( + strings.subscriptionProviderInfo[ + user?.subscription?.provider + ].title() || "Unknown provider" + ); + }, + icon: "credit-card", + modifer: () => { + const user = useUserStore.getState().user; + if (!user) return; + const subscriptionProviderInfo = + strings.subscriptionProviderInfo[user?.subscription.provider]; + presentSheet({ + title: subscriptionProviderInfo.title(), + paragraph: subscriptionProviderInfo.desc() + }); + }, + description: (current) => { + const user = current as User; + if (!user) return strings.neverHesitate(); + const subscriptionDaysLeft = + user && getTimeLeft(user.subscription?.expiry); + const expiryDate = dayjs(user?.subscription?.expiry).format( + "dddd, MMMM D, YYYY h:mm A" + ); + const startDate = dayjs(user?.subscription?.start).format( + "dddd, MMMM D, YYYY h:mm A" + ); - // if (user.subscription.provider === 4) { - // return strings.subEndsOn(expiryDate); - // } + if (user.subscription.plan !== SubscriptionPlan.FREE) { + const status = user.subscription.status; + return status === SubscriptionStatus.TRIAL + ? strings.trialEndsOn( + dayjs(user?.subscription?.start) + .add( + user?.subscription?.productId.includes("monthly") ? 7 : 14 + ) + .format("dddd, MMMM D, YYYY h:mm A") + ) + : status === SubscriptionStatus.ACTIVE + ? strings.subRenewOn(expiryDate) + : status === SubscriptionStatus.CANCELED + ? strings.subEndsOn(expiryDate) + : status === SubscriptionStatus.EXPIRED + ? subscriptionDaysLeft.time < -3 + ? strings.subEnded() + : strings.accountDowngradedIn(3) + : strings.neverHesitate(); + } - // return user.subscription?.type === 2 - // ? strings.signedUpOn(startDate) - // : user.subscription?.type === 1 - // ? strings.trialEndsOn(expiryDate) - // : user.subscription?.type === 6 - // ? subscriptionDaysLeft.time < -3 - // ? strings.subEnded() - // : strings.accountDowngradedIn(3) - // : user.subscription?.type === 7 - // ? strings.subEndsOn(expiryDate) - // : user.subscription?.type === 5 - // ? strings.subRenewOn(expiryDate) - // : strings.neverHesitate(); - // } - // }, + return strings.neverHesitate(); + } + }, { id: "redeem-gift-code", name: strings.redeemGiftCode(), @@ -137,9 +143,7 @@ export const settingsGroups: SettingSection[] = [ }, useHook: () => useUserStore( - (state) => - state.user?.subscription.type == SUBSCRIPTION_STATUS.TRIAL || - state.user?.subscription.type == SUBSCRIPTION_STATUS.BASIC + (state) => state.user?.subscription.plan === SubscriptionPlan.FREE ), icon: "gift", modifer: () => { diff --git a/apps/mobile/app/screens/settings/subscription.jsx b/apps/mobile/app/screens/settings/subscription.jsx deleted file mode 100644 index 8205b3efd..000000000 --- a/apps/mobile/app/screens/settings/subscription.jsx +++ /dev/null @@ -1,146 +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 . -*/ - -import { strings } from "@notesnook/intl"; -import React from "react"; -import { Linking, Platform, View } from "react-native"; -import Config from "react-native-config"; -import { usePricing } from "../../hooks/use-pricing"; -import { - eSendEvent, - presentSheet, - ToastManager -} from "../../services/event-manager"; -import PremiumService from "../../services/premium"; -import { useUserStore } from "../../stores/use-user-store"; -import { SUBSCRIPTION_STATUS } from "../../utils/constants"; -import { eOpenPremiumDialog } from "../../utils/events"; -export const Subscription = () => { - const user = useUserStore((state) => state.user); - const monthlyPlan = usePricing("monthly"); - const isNotPro = - user?.subscription?.type !== SUBSCRIPTION_STATUS.PREMIUM && - user?.subscription?.type !== SUBSCRIPTION_STATUS.BETA; - - const hasCancelledPremium = - SUBSCRIPTION_STATUS.PREMIUM_CANCELLED === user?.subscription?.type; - - const subscriptionProviderInfo = - strings.subscriptionProviderInfo[user?.subscription?.provider]; - - const manageSubscription = () => { - if (!user?.isEmailConfirmed) { - PremiumService.showVerifyEmailDialog(); - return; - } - - if (Config.GITHUB_RELEASE === "true") { - presentSheet({ - paragraph: strings.subNotSupported(), - action: () => { - Linking.openURL("https://app.notesnook.com"); - }, - actionText: strings.goToWebApp() - }); - return; - } - - if (hasCancelledPremium && Platform.OS === "android") { - if (user.subscription?.provider === 3) { - ToastManager.show({ - heading: strings.subOnWeb(), - message: strings.openInBrowserToManageSub(), - type: "success" - }); - return; - } - Linking.openURL("https://play.google.com/store/account/subscriptions"); - - /** - * - * Platform.OS === 'ios' - ? 'https://apps.apple.com/account/subscriptions' - : 'https://play.google.com/store/account/subscriptions' - */ - } else { - eSendEvent(eOpenPremiumDialog); - } - }; - - function getPrice() { - return Platform.OS === "android" - ? monthlyPlan?.product?.subscriptionOfferDetails[0]?.pricingPhases - .pricingPhaseList?.[0]?.formattedPrice - : monthlyPlan?.product?.localizedPrice; - } - - return ( - - {/* {isNotPro ? ( -