start adding payment
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
+1
-32
@@ -54,10 +54,6 @@ import cloud from "./icons/cloud.png";
|
||||
import dashboard from "./icons/dashboard.png";
|
||||
import file from "./icons/file.png";
|
||||
|
||||
import circle from "./art/circle.png";
|
||||
import gradientTriangle from "./art/gradientTriangle.png";
|
||||
import square from "./art/square.png";
|
||||
import triangle from "./art/triangle.png";
|
||||
import algolia from "./icons/algolia.png";
|
||||
import calendar from "./icons/calendar.png";
|
||||
import chatBubble from "./icons/chatBubble.png";
|
||||
@@ -82,16 +78,6 @@ import play from "./icons/play.png";
|
||||
import share from "./icons/share.png";
|
||||
import stars from "./icons/stars.png";
|
||||
|
||||
import boost from "./art/boost.png";
|
||||
import boostBig from "./art/boostBig.png";
|
||||
import threeCoins from "./art/threeCoins.png";
|
||||
|
||||
import tutorialChat from "./tutorial/chat.png";
|
||||
import coins from "./tutorial/coins.png";
|
||||
import followProgress from "./tutorial/followProgress.png";
|
||||
import tutorialTasks from "./tutorial/tasks.png";
|
||||
import welcome from "./tutorial/welcome.png";
|
||||
|
||||
import hitParadeBG from "./UI/hitParadeBG.png";
|
||||
import homeBG from "./UI/homeBG.png";
|
||||
import libraryBG from "./UI/libraryBG.png";
|
||||
@@ -202,24 +188,6 @@ export const icons = {
|
||||
coin,
|
||||
};
|
||||
|
||||
export const art = {
|
||||
triangle,
|
||||
circle,
|
||||
square,
|
||||
gradientTriangle,
|
||||
threeCoins,
|
||||
boost,
|
||||
boostBig,
|
||||
};
|
||||
|
||||
export const tutorial = {
|
||||
welcome,
|
||||
chat: tutorialChat,
|
||||
coins,
|
||||
followProgress,
|
||||
tasks: tutorialTasks,
|
||||
};
|
||||
|
||||
export const background = {
|
||||
writingBG,
|
||||
writingBgWeb: require("./UI/writingBgWeb.png"),
|
||||
@@ -240,6 +208,7 @@ export const background = {
|
||||
homeBGWeb: require("./UI/homeBGWeb.png"),
|
||||
loginBgWeb: require("./UI/loginBgWeb.png"),
|
||||
profileWebBG: require("./UI/profileWebBG.jpg"),
|
||||
bgTrans: require("./UI/bgTrans.png"),
|
||||
};
|
||||
|
||||
export const ai = {
|
||||
|
||||
@@ -56,6 +56,7 @@ const FeatureCarousel = ({
|
||||
activeIndex,
|
||||
onActiveIndexChange,
|
||||
backgroundImage,
|
||||
isFocused,
|
||||
}) => {
|
||||
const stageStates = useMemo(() => {
|
||||
if (stageStatesProp) {
|
||||
@@ -223,6 +224,23 @@ const FeatureCarousel = ({
|
||||
scrollToIndex(activeIndexRef.current, false);
|
||||
}, [carouselItems.length, isWeb, itemHeight, scrollToIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isWeb || !isFocused) {
|
||||
return;
|
||||
}
|
||||
if (!itemHeight) {
|
||||
return;
|
||||
}
|
||||
clearPendingAlignment();
|
||||
scrollToIndex(activeIndexRef.current, false);
|
||||
}, [
|
||||
clearPendingAlignment,
|
||||
isFocused,
|
||||
isWeb,
|
||||
itemHeight,
|
||||
scrollToIndex,
|
||||
]);
|
||||
|
||||
const alignToOffset = useCallback(
|
||||
(offset, layoutHeight, options = {}) => {
|
||||
const { forceSnap = false } = options || {};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { Platform } from "react-native";
|
||||
import {
|
||||
getReactNativePersistence,
|
||||
initializeAuth,
|
||||
@@ -9,6 +10,26 @@ import "firebase/compat/firestore";
|
||||
import "firebase/compat/functions";
|
||||
import "firebase/compat/storage";
|
||||
|
||||
const functionsInstances = {};
|
||||
const emulatorConfigured = {};
|
||||
const emulatorHost = Platform.OS === "web" ? "localhost" : "192.168.1.146";
|
||||
|
||||
const configureFunctionsEmulator = (instance, regionKey = "us-central1") => {
|
||||
if (!__DEV__ || !instance?.useEmulator || emulatorConfigured[regionKey]) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
instance.useEmulator(emulatorHost, 5001);
|
||||
emulatorConfigured[regionKey] = true;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`[firebase] Unable to set functions emulator for region ${regionKey}`,
|
||||
error?.message,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const firebaseConfig = {
|
||||
apiKey: "AIzaSyCuHJHdwVN_F-VmUG4Hd7bGiMRqj6rPlLo",
|
||||
authDomain: "musicland-d33f9.firebaseapp.com",
|
||||
@@ -29,6 +50,9 @@ if (!firebase?.apps?.filter(({ name_ }) => name_ === "[DEFAULT]").length) {
|
||||
// if (__DEV__) {
|
||||
// firebase.functions().useEmulator("localhost", 5001);
|
||||
// }
|
||||
const defaultFunctions = firebase.functions();
|
||||
functionsInstances["us-central1"] = defaultFunctions;
|
||||
configureFunctionsEmulator(defaultFunctions, "us-central1");
|
||||
console.log("Firebase init");
|
||||
}
|
||||
|
||||
@@ -57,4 +81,18 @@ export const reportsRef = firestore.collection("reports");
|
||||
export const { arrayUnion, arrayRemove, increment, serverTimestamp } =
|
||||
firebase.firestore.FieldValue;
|
||||
|
||||
export const getFunctionsClient = (region = "us-central1") => {
|
||||
const regionKey = region || "us-central1";
|
||||
|
||||
if (!functionsInstances[regionKey]) {
|
||||
functionsInstances[regionKey] = firebase.app().functions(regionKey);
|
||||
}
|
||||
|
||||
const instance = functionsInstances[regionKey];
|
||||
|
||||
configureFunctionsEmulator(instance, regionKey);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export default firebase;
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
export const STRIPE_PUBLISHABLE_KEY_TEST = "..";
|
||||
export const STRIPE_PUBLISHABLE_KEY_LIVE = "...";
|
||||
export const STRIPE_PUBLISHABLE_KEY_TEST =
|
||||
"pk_test_51SPfcjCzf2o5bDRdxkCvPUnZnc5XS80HEIo1mlOmqsC2i8pkFBwD78dVLM5AOlFDMnddKH6EFA2kiPzIuqrTi7YQ001YJz4T7r";
|
||||
export const STRIPE_PUBLISHABLE_KEY_LIVE = "";
|
||||
export const GOOGLE_API_KEY = "...";
|
||||
|
||||
// OAuth Client IDs for Google Sign-In
|
||||
|
||||
@@ -22,6 +22,7 @@ import RecordedPlayback from "../screens/Playback/RecordedPlayback";
|
||||
import VideoFinalize from "../screens/Playback/VideoFinalize";
|
||||
import PublishYoutube from "../screens/Publishing/PublishYoutube";
|
||||
import PrivacyPolicy from "../screens/PrivacyPolicy";
|
||||
import Payments from "../screens/Payments";
|
||||
import DownloadPrices from "../screens/Production/DownloadPrices";
|
||||
import DownloadSongs from "../screens/Production/DownloadSongs";
|
||||
import PlaybackExample from "../screens/Production/PlaybackExample";
|
||||
@@ -109,6 +110,11 @@ const baseScreens = [
|
||||
component: PrivacyPolicy,
|
||||
title: "Politique de confidentialité",
|
||||
},
|
||||
{
|
||||
name: Routes.Payments,
|
||||
component: Payments,
|
||||
title: "Abonnements",
|
||||
},
|
||||
{
|
||||
name: Routes.Writing,
|
||||
component: Writing,
|
||||
|
||||
@@ -23,6 +23,7 @@ export const Routes = {
|
||||
|
||||
TermsOfUse: "TermsOfUse",
|
||||
PrivacyPolicy: "PrivacyPolicy",
|
||||
Payments: "Payments",
|
||||
|
||||
Writing: "Writing",
|
||||
WritingLyrics: "WritingLyrics",
|
||||
|
||||
@@ -9,7 +9,7 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { AppState, Platform } from "react-native";
|
||||
import { useGlobal } from "reactn";
|
||||
import firebase, {
|
||||
arrayUnion,
|
||||
@@ -66,6 +66,18 @@ export default function NotificationProvider({ children }) {
|
||||
}
|
||||
}, [notifications]);
|
||||
|
||||
const clearBadgeCount = useCallback(async () => {
|
||||
if (Platform.OS === "web") {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await Notifications.setBadgeCountAsync(0);
|
||||
} catch (error) {
|
||||
console.log("clearBadgeCount error:", error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const markNotificationAsRead = useCallback(async (notificationId) => {
|
||||
try {
|
||||
if (!notificationId) return;
|
||||
@@ -117,6 +129,33 @@ export default function NotificationProvider({ children }) {
|
||||
registerForPushNotificationsAsync();
|
||||
}, [user, uid, notifInit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Platform.OS === "web") {
|
||||
return;
|
||||
}
|
||||
|
||||
clearBadgeCount();
|
||||
|
||||
const handleAppStateChange = (state) => {
|
||||
if (state === "active") {
|
||||
clearBadgeCount();
|
||||
}
|
||||
};
|
||||
|
||||
const subscription = AppState.addEventListener(
|
||||
"change",
|
||||
handleAppStateChange
|
||||
);
|
||||
|
||||
return () => {
|
||||
if (subscription?.remove) {
|
||||
subscription.remove();
|
||||
} else {
|
||||
AppState.removeEventListener("change", handleAppStateChange);
|
||||
}
|
||||
};
|
||||
}, [clearBadgeCount]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!allowNotifications) {
|
||||
return;
|
||||
|
||||
@@ -84,6 +84,7 @@ const DEFAULT_CONTEXT = {
|
||||
isLooping: false,
|
||||
setLooping: noop,
|
||||
toggleLooping: noop,
|
||||
getTrackInfo: () => null,
|
||||
};
|
||||
|
||||
export const PlayerContext = createContext(DEFAULT_CONTEXT);
|
||||
@@ -230,6 +231,7 @@ const PlayerProvider = ({ children }) => {
|
||||
const autoPlayRef = useRef(false);
|
||||
const pendingSeekValueRef = useRef(null);
|
||||
const didJustFinishRef = useRef(false);
|
||||
const trackInfoRef = useRef({});
|
||||
|
||||
const setQueueIndexValue = useCallback((index = -1) => {
|
||||
const list = queueRef.current;
|
||||
@@ -401,6 +403,18 @@ const PlayerProvider = ({ children }) => {
|
||||
durationMs,
|
||||
};
|
||||
});
|
||||
|
||||
if (currentTrack?.id) {
|
||||
trackInfoRef.current[currentTrack.id] = {
|
||||
durationMs:
|
||||
durationMs > 0
|
||||
? durationMs
|
||||
: trackInfoRef.current[currentTrack.id]?.durationMs || 0,
|
||||
positionMs,
|
||||
isLoaded,
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
}
|
||||
}, [status, currentTrack]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -614,6 +628,10 @@ const PlayerProvider = ({ children }) => {
|
||||
const toggleLooping = useCallback(() => {
|
||||
setIsLooping((prev) => !prev);
|
||||
}, []);
|
||||
const getTrackInfo = useCallback((trackId) => {
|
||||
if (!trackId) return null;
|
||||
return trackInfoRef.current[trackId] || null;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentTrack?.id) {
|
||||
@@ -692,6 +710,7 @@ const PlayerProvider = ({ children }) => {
|
||||
isLooping,
|
||||
setLooping,
|
||||
toggleLooping,
|
||||
getTrackInfo,
|
||||
}),
|
||||
[
|
||||
currentTrack,
|
||||
@@ -715,6 +734,7 @@ const PlayerProvider = ({ children }) => {
|
||||
setLooping,
|
||||
toggleLooping,
|
||||
setQueue,
|
||||
getTrackInfo,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import { Palette, Style } from "../../../styles";
|
||||
import { icons } from "../../../assets";
|
||||
import { size } from "../../../styles/Style";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
|
||||
const CoinBadge = () => {
|
||||
return (
|
||||
<View style={{ ...Style.containerRow }}>
|
||||
<View
|
||||
style={{
|
||||
paddingLeft: 5,
|
||||
paddingRight: 10,
|
||||
paddingVertical: 3,
|
||||
borderTopLeftRadius: 8,
|
||||
borderBottomLeftRadius: 8,
|
||||
backgroundColor: Palette.glass,
|
||||
right: -10,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
100
|
||||
</Text>
|
||||
</View>
|
||||
<Image source={icons.coin} style={size({ size: 26 })} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CoinBadge;
|
||||
@@ -4,7 +4,6 @@ import { BlurView } from "expo-blur";
|
||||
import { img } from "../../../assets";
|
||||
import { Palette, Style } from "../../../styles";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
import CoinBadge from "./CoinBadge";
|
||||
|
||||
const PlaybacksCard = ({
|
||||
rank = 1,
|
||||
@@ -72,7 +71,6 @@ const PlaybacksCard = ({
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<CoinBadge />
|
||||
</BlurView>
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,6 @@ import { BlurView } from "expo-blur";
|
||||
import Style, { size } from "../../../styles/Style";
|
||||
import { Palette } from "../../../styles";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
import CoinBadge from "./CoinBadge";
|
||||
|
||||
const SongCard = ({
|
||||
rank = 1,
|
||||
@@ -91,7 +90,6 @@ const SongCard = ({
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<CoinBadge />
|
||||
</BlurView>
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { useGlobal } from "reactn";
|
||||
import { background, icons } from "../../assets";
|
||||
import BorderGradient from "../../components/BorderGradient/BorderGradient";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import MoreMenu from "../../components/MoreMenu";
|
||||
import PressableScale from "../../components/PressableScale";
|
||||
import ProfilePicture from "../../components/ProfilePicture";
|
||||
@@ -473,6 +474,19 @@ const Profile = () => {
|
||||
<Text style={styles.label}>abonnements</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
{isSelf ? (
|
||||
<GradientButton
|
||||
title="Découvrir les abonnements"
|
||||
size="large"
|
||||
onPress={() => push(Routes.Payments)}
|
||||
containerStyle={{
|
||||
marginTop: 18,
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
gradientStyle={{ width: "100%" }}
|
||||
/>
|
||||
) : null}
|
||||
{!isSelf && (
|
||||
<Pressable onPress={handleFollowUser}>
|
||||
<View
|
||||
|
||||
@@ -181,7 +181,7 @@ const GeneratingSong = () => {
|
||||
"Le service Suno est indisponible. Veuillez réessayer plus tard.";
|
||||
AppAlert(
|
||||
"Impossible de générer la musique",
|
||||
sanitized || fallbackMessage
|
||||
sanitized || fallbackMessage,
|
||||
);
|
||||
if (selectedProjectId) {
|
||||
try {
|
||||
@@ -196,12 +196,12 @@ const GeneratingSong = () => {
|
||||
message: sanitized || fallbackMessage,
|
||||
},
|
||||
},
|
||||
{ merge: true }
|
||||
{ merge: true },
|
||||
);
|
||||
} catch (firestoreError) {
|
||||
console.log(
|
||||
"GeneratingSong Firestore update error",
|
||||
firestoreError?.message
|
||||
firestoreError?.message,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user