Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: billing #636

Merged
merged 14 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions .github/workflows/android-weekly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false

# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: false
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: false

- name: Get branch name
run: |
# Short name for current branch. For PRs, use target branch (base ref)
Expand Down
16 changes: 0 additions & 16 deletions .github/workflows/play-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,6 @@ jobs:
- name: clean generated builds
run: rm -rf android/app/build/generated/

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false

# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: false
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: false

- name: gradle build AAB
run: cd android && chmod +x gradlew && ./gradlew bundleRelease

Expand Down

This file was deleted.

55 changes: 0 additions & 55 deletions .yarn/patches/react-native-npm-0.76.1-c738a2fa39.patch

This file was deleted.

2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=true
newArchEnabled=false

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
Expand Down
11 changes: 1 addition & 10 deletions android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,4 @@ include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')

apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
useExpoModules()

includeBuild('../node_modules/react-native') {
dependencySubstitution {
substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:hermes-android")).using(project(":packages:react-native:ReactAndroid:hermes-engine"))
substitute(module("com.facebook.react:hermes-engine")).using(project(":packages:react-native:ReactAndroid:hermes-engine"))
}
}
useExpoModules()
14 changes: 6 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
"@react-native-cookies/cookies": "^6.2.1",
"@react-native-masked-view/masked-view": "^0.3.2",
"@react-native/babel-preset": "^0.76.1",
"@react-native/gradle-plugin": "patch:@react-native/gradle-plugin@npm%3A0.76.1#~/.yarn/patches/@react-native-gradle-plugin-npm-0.76.1-f19c439d00.patch",
"@react-native/gradle-plugin": "^0.76.1",
"@react-native/metro-config": "^0.76.1",
"@react-native/typescript-config": "0.76.1",
"@react-navigation/drawer": "^7.0.1",
"@react-navigation/material-top-tabs": "^7.0.1",
"@react-navigation/native": "^7.0.0",
"@react-navigation/native-stack": "^7.0.0",
"@sentry/react-native": "^6.1.0",
"@sharcoux/slider": "8.0.4",
"@sharcoux/slider": "8.0.5",
"@shopify/flash-list": "^1.7.2",
"@shopify/react-native-skia": "1.5.3",
"axios": "^1.7.7",
Expand All @@ -61,7 +61,7 @@
"deepmerge": "^4.3.1",
"dropbox": "git+https://lovegaoshi@github.com/lovegaoshi/dropbox-sdk-js.git",
"event-target-polyfill": "^0.0.4",
"expo": "^52.0.2",
"expo": "^52.0.4",
"expo-auth-session": "~6.0.0",
"expo-clipboard": "~7.0.0",
"expo-crypto": "~14.0.1",
Expand All @@ -86,7 +86,7 @@
"qs": "^6.13.0",
"react": "18.3.1",
"react-i18next": "^15.1.1",
"react-native": "patch:react-native@npm%3A0.76.1#~/.yarn/patches/react-native-npm-0.76.1-c738a2fa39.patch",
"react-native": "^0.76.1",
"react-native-app-auth": "^8.0.0",
"react-native-background-timer": "git+https://github.com/lovegaoshi/react-native-background-timer.git",
"react-native-blob-jsi-helper": "^0.3.1",
Expand All @@ -107,7 +107,7 @@
"react-native-screens": "4.0.0",
"react-native-shadow-2": "^7.1.1",
"react-native-share-menu": "git+https://github.com/Expensify/react-native-share-menu.git",
"react-native-svg": "15.8.0",
"react-native-svg": "15.9.0",
"react-native-svga-player": "https://lovegaoshi@github.com/lovegaoshi/react-native-svga-player.git#commit=f8c6303fddb528a1a94d2ab4696c9318c0002cfd",
"react-native-text-ticker": "https://lovegaoshi@github.com/lovegaoshi/react-native-text-ticker.git#commit=b9eb454b18bb621a769ce4b57b4603a81501b477",
"react-native-track-player": "https://github.com/lovegaoshi/react-native-track-player.git#commit=6142378143e43cf28b74940195b1def6e0ec795d",
Expand All @@ -124,9 +124,7 @@
"zustand": "^5.0.1"
},
"resolutions": {
"metro": "^0.81.0",
"react-native@npm:*": "patch:react-native@npm%3A0.76.1#~/.yarn/patches/react-native-npm-0.76.1-c738a2fa39.patch",
"@react-native/gradle-plugin@npm:0.76.1": "patch:@react-native/gradle-plugin@npm%3A0.76.1#~/.yarn/patches/@react-native-gradle-plugin-npm-0.76.1-f19c439d00.patch"
"metro": "^0.81.0"
},
"devDependencies": {
"@babel/core": "^7.26.0",
Expand Down
13 changes: 0 additions & 13 deletions patches/@sharcoux+slider+8.0.4.patch

This file was deleted.

25 changes: 0 additions & 25 deletions patches/react-native-tab-view+4.0.1.patch

This file was deleted.

4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import MainBackground from './components/background/MainBackground';
import useTheme from './hooks/useTheme';
// eslint-disable-next-line import/no-unresolved
import { TRACKING } from '@env';
import useVIP from './hooks/useVIP';
import { useSetupVIP } from './hooks/useVIP';

if (TRACKING) {
Sentry.init({
Expand Down Expand Up @@ -52,7 +52,7 @@ const APM = ({ PIP, isLandscape }: { PIP: boolean; isLandscape: boolean }) => {
};

export default function App(appProps: NoxComponent.AppProps) {
const { vip } = useVIP();
const { vip } = useSetupVIP();
const isSplashReady = useSplash(
__DEV__ || appProps.intentData || vip ? 1 : 2500,
);
Expand Down
131 changes: 131 additions & 0 deletions src/components/billing/View.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { View, StyleSheet } from 'react-native';
import React, { useState } from 'react';
import { Text, Button, ActivityIndicator } from 'react-native-paper';
import { useTranslation } from 'react-i18next';
import { Image } from 'expo-image';
import Purchases from 'react-native-purchases';

import useVIP, { checkGuardVIP, purchaseVIP } from '@hooks/useVIP';
import { styles } from '../style';
import logger from '@utils/Logger';

interface LoadingChildrenProps {
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
}
interface LoadingWrapperProps {
Child: (p: LoadingChildrenProps) => JSX.Element;
}

const LoadingIconWrapper = ({ Child }: LoadingWrapperProps) => {
const [loading, setLoading] = useState(false);
if (loading) {
return <ActivityIndicator />;
}
return <Child setLoading={setLoading} />;
};

const BiliVIP = ({ setLoading }: LoadingChildrenProps) => {
const { t } = useTranslation();

const checkBiliVIP = async () => {
setLoading(true);
await checkGuardVIP();
setLoading(false);
};

return <Button onPress={checkBiliVIP}>{t('Billing.NoxAuth')}</Button>;
};

const RevenueCatVIP = ({ setLoading }: LoadingChildrenProps) => {
const { t } = useTranslation();
const checkRevenueCatVIP = async () => {
setLoading(true);
try {
const offerings = await Purchases.getOfferings();
if (
offerings.current !== null &&
offerings.current.availablePackages.length !== 0
) {
const { customerInfo } = await Purchases.purchasePackage(
offerings.current.availablePackages[0],
);
if (
typeof customerInfo.entitlements.active['apm-pro'] !== 'undefined'
) {
purchaseVIP();
}
}
} catch (e) {
logger.error(JSON.stringify(e));
}
setLoading(false);
};

return (
<Button onPress={checkRevenueCatVIP}>{t('Billing.RevenueCat')}</Button>
);
};

const PurchaseVIPScreen = () => {
const { t } = useTranslation();
return (
<View style={mStyle.container}>
<Image
style={mStyle.azusaBeg}
source={{
uri: 'https://img.nga.178.com/attachments/mon_202201/31/-zue37Q2p-ixpkXsZ7tT3cS9y-af.gif',
}}
/>
<Text>{t('Billing.PremiumFeaturesIntro')}</Text>
<View style={styles.alignMiddle}>
<LoadingIconWrapper Child={BiliVIP} />
<LoadingIconWrapper Child={RevenueCatVIP} />
</View>
<Text>{t('Billing.NoxFans')}</Text>
</View>
);
};

const VIPScreen = () => {
const { t } = useTranslation();

return (
<View style={mStyle.container}>
<Image
style={mStyle.azusaMock}
source={{
uri: 'https://img.nga.178.com/attachments/mon_202202/01/-zue37Q2p-6rfwK2dT1kShs-b4.jpg',
}}
/>
<Text style={styles.centerText}>{t('Billing.thankU')}</Text>
<Text style={styles.centerText}>{t('Billing.godBlessU')}</Text>
<Text style={styles.centerText}>{t('Billing.urVeryVeryGorgeous')}</Text>
</View>
);
};

export default () => {
const vip = useVIP(state => state.VIP);

if (vip) {
return <VIPScreen />;
}
return <PurchaseVIPScreen />;
};

const mStyle = StyleSheet.create({
container: { flex: 1, paddingHorizontal: 10, paddingTop: 10 },
text: {
fontSize: 20,
},
azusaBeg: {
width: '100%',
height: '40%',
alignSelf: 'center',
},
azusaMock: {
width: '100%',
height: '30%',
alignSelf: 'center',
},
});
4 changes: 0 additions & 4 deletions src/components/billing/bill.ts

This file was deleted.

Loading