fix(mobile): hide payment ui outside apk (#4847)
This commit is contained in:
parent
87784b2246
commit
50ed7aae10
|
|
@ -2,16 +2,18 @@ import { createAtomHooks } from "@follow/utils/jotai"
|
|||
import type { StatusConfigs } from "@follow-app/client-sdk"
|
||||
import { atom } from "jotai"
|
||||
|
||||
import { isPaymentFeatureEnabled } from "@/src/lib/payment"
|
||||
|
||||
export const [, , useServerConfigs, , getServerConfigs, setServerConfigs] = createAtomHooks(
|
||||
atom<Nullable<StatusConfigs>>(null),
|
||||
)
|
||||
|
||||
export const useIsPaymentEnabled = () => {
|
||||
const serverConfigs = useServerConfigs()
|
||||
return Boolean(serverConfigs?.PAYMENT_ENABLED)
|
||||
return isPaymentFeatureEnabled(serverConfigs?.PAYMENT_ENABLED)
|
||||
}
|
||||
|
||||
export const getIsPaymentEnabled = () => {
|
||||
const serverConfigs = getServerConfigs()
|
||||
return Boolean(serverConfigs?.PAYMENT_ENABLED)
|
||||
return isPaymentFeatureEnabled(serverConfigs?.PAYMENT_ENABLED)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,13 @@ export const toastFetchError = (error: Error, { title: _title }: { title?: strin
|
|||
return
|
||||
}
|
||||
|
||||
const needUpgradeError = status === 402 && getIsPaymentEnabled()
|
||||
const isPaymentFeatureEnabled = getIsPaymentEnabled()
|
||||
|
||||
if (status === 402 && !isPaymentFeatureEnabled) {
|
||||
return toast.error(t("errors:1004"))
|
||||
}
|
||||
|
||||
const needUpgradeError = status === 402 && isPaymentFeatureEnabled
|
||||
|
||||
if (needUpgradeError) {
|
||||
showUpgradeRequiredDialog({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
import DeviceInfo from "react-native-device-info"
|
||||
|
||||
import { isAndroid } from "./platform"
|
||||
|
||||
const GOOGLE_PLAY_INSTALLER_PACKAGE_NAME = "com.android.vending"
|
||||
let isAndroidApkInstallCache: boolean | undefined
|
||||
|
||||
const isGooglePlayInstall = (installerPackageName?: string | null) =>
|
||||
installerPackageName === GOOGLE_PLAY_INSTALLER_PACKAGE_NAME
|
||||
|
||||
export const isAndroidApkInstall = () => {
|
||||
if (isAndroidApkInstallCache !== undefined) {
|
||||
return isAndroidApkInstallCache
|
||||
}
|
||||
|
||||
if (!isAndroid) {
|
||||
isAndroidApkInstallCache = false
|
||||
return isAndroidApkInstallCache
|
||||
}
|
||||
|
||||
try {
|
||||
isAndroidApkInstallCache = !isGooglePlayInstall(DeviceInfo.getInstallerPackageNameSync())
|
||||
return isAndroidApkInstallCache
|
||||
} catch {
|
||||
// Treat unknown installer as APK-style install and keep behavior permissive.
|
||||
isAndroidApkInstallCache = true
|
||||
return isAndroidApkInstallCache
|
||||
}
|
||||
}
|
||||
|
||||
export const isPaymentFeatureEnabled = (paymentEnabled?: boolean | null) =>
|
||||
Boolean(paymentEnabled) && isAndroidApkInstall()
|
||||
|
|
@ -3,6 +3,7 @@ import { useEffect } from "react"
|
|||
import { useTranslation } from "react-i18next"
|
||||
import { View } from "react-native"
|
||||
|
||||
import { getIsPaymentEnabled } from "@/src/atoms/server-configs"
|
||||
import { Text } from "@/src/components/ui/typography/Text"
|
||||
import type { DialogComponent } from "@/src/lib/dialog"
|
||||
import { Dialog } from "@/src/lib/dialog"
|
||||
|
|
@ -20,6 +21,10 @@ let currentPayload: UpgradeDialogPayload = defaultPayload
|
|||
const getPayload = () => currentPayload
|
||||
|
||||
export const showUpgradeRequiredDialog = (payload?: UpgradeDialogPayload) => {
|
||||
if (!getIsPaymentEnabled()) {
|
||||
return
|
||||
}
|
||||
|
||||
currentPayload = {
|
||||
title: payload?.title,
|
||||
message: payload?.message,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Fragment, useMemo } from "react"
|
|||
import { useTranslation } from "react-i18next"
|
||||
import { Alert, PixelRatio, View } from "react-native"
|
||||
|
||||
import { useServerConfigs } from "@/src/atoms/server-configs"
|
||||
import { getIsPaymentEnabled, useServerConfigs } from "@/src/atoms/server-configs"
|
||||
import {
|
||||
GroupedInsetListCard,
|
||||
GroupedInsetListNavigationLink,
|
||||
|
|
@ -28,6 +28,7 @@ import { UserSettingCuteFiIcon } from "@/src/icons/user_setting_cute_fi"
|
|||
import { signOut } from "@/src/lib/auth"
|
||||
import { useNavigation } from "@/src/lib/navigation/hooks"
|
||||
import type { Navigation } from "@/src/lib/navigation/Navigation"
|
||||
import { isPaymentFeatureEnabled } from "@/src/lib/payment"
|
||||
import { accentColor } from "@/src/theme/colors"
|
||||
|
||||
import { AboutScreen } from "./routes/About"
|
||||
|
|
@ -109,7 +110,7 @@ const SubscriptionGroupNavigationLinks: GroupNavigationLink[] = [
|
|||
},
|
||||
iconBackgroundColor: accentColor,
|
||||
anonymous: false,
|
||||
hideIf: (serverConfigs) => !serverConfigs?.PAYMENT_ENABLED,
|
||||
hideIf: (serverConfigs) => !isPaymentFeatureEnabled(serverConfigs?.PAYMENT_ENABLED),
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -210,7 +211,11 @@ const NavigationLinkGroup: FC<{
|
|||
</GroupedInsetListNavigationLinkIcon>
|
||||
}
|
||||
onPress={() => {
|
||||
if (link.trialNotAllowed && (role === UserRole.Free || role === UserRole.Trial)) {
|
||||
if (
|
||||
link.trialNotAllowed &&
|
||||
(role === UserRole.Free || role === UserRole.Trial) &&
|
||||
getIsPaymentEnabled()
|
||||
) {
|
||||
navigation.presentControllerView(PlanScreen)
|
||||
} else {
|
||||
link.onPress({ navigation })
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { useTranslation } from "react-i18next"
|
|||
import type { LayoutChangeEvent } from "react-native"
|
||||
import { ActivityIndicator, Animated, Easing, Pressable, StyleSheet, View } from "react-native"
|
||||
|
||||
import { useServerConfigs } from "@/src/atoms/server-configs"
|
||||
import { useIsPaymentEnabled, useServerConfigs } from "@/src/atoms/server-configs"
|
||||
import {
|
||||
NavigationBlurEffectHeaderView,
|
||||
SafeNavigationScrollView,
|
||||
|
|
@ -111,11 +111,11 @@ const isFeatureValueVisible = (value: PaymentFeature[keyof PaymentFeature] | nul
|
|||
export const PlanScreen: NavigationControllerView = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
const serverConfigs = useServerConfigs()
|
||||
const isPaymentEnabled = useIsPaymentEnabled()
|
||||
const role = useUserRole()
|
||||
const roleEndAt = useRoleEndAt()
|
||||
|
||||
const plans = useMemo(() => serverConfigs?.PAYMENT_PLAN_LIST ?? [], [serverConfigs])
|
||||
const isPaymentEnabled = serverConfigs?.PAYMENT_ENABLED
|
||||
|
||||
const defaultBillingPeriod: BillingPeriod = "yearly"
|
||||
const [billingPeriod, setBillingPeriod] = useState<BillingPeriod>(defaultBillingPeriod)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import { getIsPaymentEnabled } from "@/src/atoms/server-configs"
|
||||
import { Navigation } from "@/src/lib/navigation/Navigation"
|
||||
|
||||
export const navigateToPlanScreen = () => {
|
||||
if (!getIsPaymentEnabled()) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return import("./Plan")
|
||||
.then(({ PlanScreen }) => {
|
||||
Navigation.rootNavigation.pushControllerView(PlanScreen)
|
||||
|
|
|
|||
Loading…
Reference in New Issue