share modal
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 302 KiB |
@@ -40,6 +40,7 @@
|
|||||||
"expo-blur": "~14.0.3",
|
"expo-blur": "~14.0.3",
|
||||||
"expo-build-properties": "~0.13.3",
|
"expo-build-properties": "~0.13.3",
|
||||||
"expo-camera": "~16.0.18",
|
"expo-camera": "~16.0.18",
|
||||||
|
"expo-clipboard": "~7.0.1",
|
||||||
"expo-constants": "~17.0.8",
|
"expo-constants": "~17.0.8",
|
||||||
"expo-dev-client": "~5.0.20",
|
"expo-dev-client": "~5.0.20",
|
||||||
"expo-device": "~7.0.3",
|
"expo-device": "~7.0.3",
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { BlurView } from "expo-blur";
|
import { BlurView } from "expo-blur";
|
||||||
import { Pressable } from "react-native";
|
import { Pressable } from "react-native";
|
||||||
import { Entypo } from "@expo/vector-icons";
|
import { Entypo } from "@expo/vector-icons";
|
||||||
|
import { openShareSheet } from "../../utils/shareSheet";
|
||||||
|
|
||||||
export default function ShareBtn({ style, onPress = null }) {
|
export default function ShareBtn({ style, onPress = null }) {
|
||||||
|
const handlePress = useCallback(() => {
|
||||||
|
if (typeof onPress === "function") {
|
||||||
|
onPress();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openShareSheet();
|
||||||
|
}, [onPress]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={onPress}
|
onPress={handlePress}
|
||||||
disabled={!onPress}
|
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { BlurView } from "expo-blur";
|
import { BlurView } from "expo-blur";
|
||||||
import { Pressable, Text } from "react-native";
|
import { Pressable, Text } from "react-native";
|
||||||
import { Palette } from "../../styles";
|
import { Palette } from "../../styles";
|
||||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||||
import { Entypo } from "@expo/vector-icons";
|
import { Entypo } from "@expo/vector-icons";
|
||||||
|
import { openShareSheet } from "../../utils/shareSheet";
|
||||||
|
|
||||||
export default function ShareBtn({ style, onPress = null }) {
|
export default function ShareBtn({ style, onPress = null }) {
|
||||||
|
const handlePress = useCallback(() => {
|
||||||
|
if (typeof onPress === "function") {
|
||||||
|
onPress();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openShareSheet();
|
||||||
|
}, [onPress]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={onPress}
|
onPress={handlePress}
|
||||||
disabled={!onPress}
|
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React from "react";
|
|
||||||
import { Alert, Pressable, Platform, Text } from "react-native";
|
|
||||||
import { BlurView } from "expo-blur";
|
import { BlurView } from "expo-blur";
|
||||||
|
import { Image } from "expo-image";
|
||||||
|
import React from "react";
|
||||||
|
import { Alert, Platform, Pressable, Text } from "react-native";
|
||||||
|
import { icons } from "../assets";
|
||||||
import { Palette } from "../styles";
|
import { Palette } from "../styles";
|
||||||
import { FONT_FAMILY } from "../styles/Fonts";
|
import { FONT_FAMILY } from "../styles/Fonts";
|
||||||
import { icons } from "../assets";
|
|
||||||
import { Image } from "expo-image";
|
|
||||||
|
|
||||||
export default function ShareBtnWeb({ style }) {
|
export default function ShareBtnWeb({ style }) {
|
||||||
const handleShare = () => {
|
const handleShare = () => {
|
||||||
@@ -51,7 +51,7 @@ export default function ShareBtnWeb({ style }) {
|
|||||||
fontFamily: FONT_FAMILY.InterMedium,
|
fontFamily: FONT_FAMILY.InterMedium,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Partager l'expérience
|
Partagez l'expérience
|
||||||
</Text>
|
</Text>
|
||||||
<Image
|
<Image
|
||||||
source={icons.share}
|
source={icons.share}
|
||||||
|
|||||||
@@ -1,120 +1,354 @@
|
|||||||
import React, { useMemo } from "react";
|
import React, {
|
||||||
import { Linking, Pressable, Text, View } from "react-native";
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import {
|
||||||
|
Linking,
|
||||||
|
Platform,
|
||||||
|
Pressable,
|
||||||
|
Share,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
} from "react-native";
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
import { shareLink } from "../../helpers";
|
import {
|
||||||
|
Feather,
|
||||||
|
FontAwesome,
|
||||||
|
MaterialCommunityIcons,
|
||||||
|
} from "@expo/vector-icons";
|
||||||
|
|
||||||
|
import AppActionSheet from "../AppActionSheet";
|
||||||
import { Palette } from "../../styles";
|
import { Palette } from "../../styles";
|
||||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||||
import AppActionSheet from "../AppActionSheet";
|
import { isWeb } from "../../hooks/useLayoutType";
|
||||||
|
import {
|
||||||
|
musiclandShareHeading,
|
||||||
|
musiclandShareMessage,
|
||||||
|
musiclandShareUrl,
|
||||||
|
} from "../../data";
|
||||||
|
|
||||||
const ShareModal = ({ payload }) => {
|
const ShareModal = ({ payload }) => {
|
||||||
const {
|
const heading = payload?.heading ?? musiclandShareHeading;
|
||||||
title = "Partager",
|
const url = payload?.url ?? musiclandShareUrl;
|
||||||
message = "Choisis une application pour partager",
|
const shareTitle = payload?.shareTitle ?? heading;
|
||||||
text = "Découvre ce playback sur MusicLand",
|
const shareMessage = payload?.shareMessage ?? musiclandShareMessage;
|
||||||
url = "",
|
const linkLabel = payload?.linkLabel ?? url;
|
||||||
} = payload || {};
|
const sectionTitle = payload?.sectionTitle ?? "Partager sur...";
|
||||||
|
|
||||||
const onClose = () => {
|
const [copied, setCopied] = useState(false);
|
||||||
|
const copyTimeout = useRef(null);
|
||||||
|
|
||||||
|
const closeSheet = useCallback(() => {
|
||||||
SheetManager.hide("Share");
|
SheetManager.hide("Share");
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const shareText = useMemo(() => {
|
const shareText = useMemo(() => {
|
||||||
return [text, url].filter(Boolean).join(" ");
|
return [shareMessage, url].filter(Boolean).join(" ");
|
||||||
}, [text, url]);
|
}, [shareMessage, url]);
|
||||||
|
|
||||||
const openScheme = async () => {
|
const encodedUrl = useMemo(() => encodeURIComponent(url), [url]);
|
||||||
try {
|
const encodedShareText = useMemo(
|
||||||
const supported = await Linking.canOpenURL(url);
|
() => encodeURIComponent(shareText),
|
||||||
if (supported) {
|
[shareText]
|
||||||
await Linking.openURL(url);
|
);
|
||||||
} else {
|
|
||||||
// fallback vers partage natif
|
useEffect(() => {
|
||||||
shareLink({ url, title: "Partager", message: shareText });
|
return () => {
|
||||||
}
|
if (copyTimeout.current) {
|
||||||
} catch (e) {
|
clearTimeout(copyTimeout.current);
|
||||||
shareLink({ url, title: "Partager", message: shareText });
|
|
||||||
} finally {
|
|
||||||
onClose();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCopy = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (copyTimeout.current) {
|
||||||
|
clearTimeout(copyTimeout.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWeb && typeof navigator !== "undefined" && navigator.clipboard) {
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
} else {
|
||||||
|
const Clipboard = await import("expo-clipboard");
|
||||||
|
if (typeof Clipboard?.setStringAsync === "function") {
|
||||||
|
await Clipboard.setStringAsync(url);
|
||||||
|
} else if (typeof Clipboard?.default?.setStringAsync === "function") {
|
||||||
|
await Clipboard.default.setStringAsync(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCopied(true);
|
||||||
|
copyTimeout.current = setTimeout(() => {
|
||||||
|
setCopied(false);
|
||||||
|
}, 2000);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("share.copy.failed", error);
|
||||||
|
}
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
const handleSystemShare = useCallback(async () => {
|
||||||
|
if (Platform.OS === "web" && typeof navigator !== "undefined") {
|
||||||
|
try {
|
||||||
|
if (typeof navigator.share === "function") {
|
||||||
|
await navigator.share({
|
||||||
|
url,
|
||||||
|
text: shareText,
|
||||||
|
title: shareTitle,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("share.system.web", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Share.share(
|
||||||
|
Platform.select({
|
||||||
|
ios: url
|
||||||
|
? { url, message: shareText, title: shareTitle }
|
||||||
|
: { message: shareText, title: shareTitle },
|
||||||
|
android: { message: shareText, title: shareTitle },
|
||||||
|
default: { message: shareText, title: shareTitle },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("share.system.native", error);
|
||||||
|
}
|
||||||
|
}, [shareText, shareTitle, url]);
|
||||||
|
|
||||||
|
const handleShareOption = useCallback(
|
||||||
|
async (option) => {
|
||||||
|
const target = option?.target;
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
await handleSystemShare();
|
||||||
|
closeSheet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (Platform.OS === "web") {
|
||||||
|
window.open(target, "_blank", "noopener,noreferrer");
|
||||||
|
closeSheet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const supported = await Linking.canOpenURL(target);
|
||||||
|
if (supported) {
|
||||||
|
await Linking.openURL(target);
|
||||||
|
closeSheet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`share.option.error.${option?.key || "unknown"}`, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
await handleSystemShare();
|
||||||
|
closeSheet();
|
||||||
|
},
|
||||||
|
[closeSheet, handleSystemShare]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onSystemShare = useCallback(async () => {
|
||||||
|
await handleSystemShare();
|
||||||
|
closeSheet();
|
||||||
|
}, [closeSheet, handleSystemShare]);
|
||||||
|
|
||||||
|
const shareOptions = useMemo(() => {
|
||||||
|
if (Array.isArray(payload?.options) && payload.options.length) {
|
||||||
|
return payload.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: "facebook",
|
||||||
|
label: "Partager sur Facebook",
|
||||||
|
Icon: (props) => <FontAwesome name="facebook" {...props} />,
|
||||||
|
target: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "instagram",
|
||||||
|
label: "Partager sur Instagram",
|
||||||
|
Icon: (props) => <FontAwesome name="instagram" {...props} />,
|
||||||
|
target: `https://www.instagram.com/?url=${encodedUrl}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "x",
|
||||||
|
label: "Partager sur X",
|
||||||
|
Icon: (props) => <FontAwesome name="twitter" {...props} />,
|
||||||
|
target: `https://twitter.com/intent/tweet?url=${encodedUrl}&text=${encodedShareText}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "email",
|
||||||
|
label: "Partager par e-mail",
|
||||||
|
Icon: (props) => <Feather name="mail" {...props} />,
|
||||||
|
target: `mailto:?subject=${encodeURIComponent(
|
||||||
|
shareTitle
|
||||||
|
)}&body=${encodedShareText}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "qr",
|
||||||
|
label: "Partager par QR-code",
|
||||||
|
Icon: (props) => (
|
||||||
|
<MaterialCommunityIcons name="qrcode-scan" {...props} />
|
||||||
|
),
|
||||||
|
target: `https://api.qrserver.com/v1/create-qr-code/?size=512x512&data=${encodedUrl}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, [encodedShareText, encodedUrl, payload?.options, shareTitle]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppActionSheet id="Share">
|
<AppActionSheet id="Share">
|
||||||
<View style={{ gap: 24 }}>
|
<View style={styles.container}>
|
||||||
<View style={{ gap: 6 }}>
|
<View style={styles.card}>
|
||||||
<Text
|
<Text style={styles.heading}>{heading}</Text>
|
||||||
style={{
|
<View style={styles.linkRow}>
|
||||||
fontSize: 20,
|
<Text numberOfLines={1} style={styles.linkText}>
|
||||||
color: Palette.white,
|
{linkLabel}
|
||||||
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
|
||||||
textAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<View style={styles.linkActions}>
|
||||||
style={{
|
<Pressable
|
||||||
fontSize: 14,
|
hitSlop={8}
|
||||||
color: Palette.white,
|
onPress={handleCopy}
|
||||||
opacity: 0.8,
|
style={styles.iconButton}
|
||||||
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
|
||||||
textAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{message}
|
<Feather
|
||||||
</Text>
|
name={copied ? "check" : "copy"}
|
||||||
|
size={16}
|
||||||
|
color={Palette.white}
|
||||||
|
/>
|
||||||
|
</Pressable>
|
||||||
|
<Pressable
|
||||||
|
hitSlop={8}
|
||||||
|
onPress={onSystemShare}
|
||||||
|
style={styles.iconButton}
|
||||||
|
>
|
||||||
|
<Feather name="share-2" size={16} color={Palette.white} />
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{copied ? (
|
||||||
|
<Text style={styles.copiedText}>Lien copie</Text>
|
||||||
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View style={styles.card}>
|
||||||
style={{
|
<Text style={styles.sectionHeading}>{sectionTitle}</Text>
|
||||||
flexDirection: "row",
|
<View style={styles.optionsList}>
|
||||||
justifyContent: "space-between",
|
{shareOptions.map((option) => {
|
||||||
alignItems: "center",
|
const Icon = option?.Icon ?? Feather;
|
||||||
gap: 16,
|
return (
|
||||||
paddingHorizontal: 12,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => {
|
key={option?.key}
|
||||||
openScheme();
|
onPress={() => handleShareOption(option)}
|
||||||
}}
|
style={styles.optionRow}
|
||||||
style={{ alignItems: "center", gap: 8, flex: 1 }}
|
|
||||||
>
|
>
|
||||||
<View
|
<View style={styles.optionIconWrapper}>
|
||||||
style={{
|
<Icon size={18} color={Palette.white} />
|
||||||
width: 56,
|
|
||||||
height: 56,
|
|
||||||
borderRadius: 28,
|
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: "#FFFFFF60",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: Palette.white,
|
|
||||||
fontFamily: FONT_FAMILY.InterMedium,
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
partager
|
|
||||||
</Text>
|
|
||||||
</View>
|
</View>
|
||||||
<Text
|
<Text style={styles.optionLabel}>{option?.label}</Text>
|
||||||
style={{
|
|
||||||
color: Palette.white,
|
|
||||||
fontFamily: FONT_FAMILY.InterMedium,
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
partager
|
|
||||||
</Text>
|
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</AppActionSheet>
|
</AppActionSheet>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
gap: 24,
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
backgroundColor: Palette.glass,
|
||||||
|
borderRadius: 24,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "rgba(255, 255, 255, 0.08)",
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingVertical: 18,
|
||||||
|
gap: 16,
|
||||||
|
},
|
||||||
|
heading: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: Palette.white,
|
||||||
|
textAlign: "center",
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
||||||
|
},
|
||||||
|
linkRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "rgba(255, 255, 255, 0.06)",
|
||||||
|
borderRadius: 16,
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
paddingVertical: 10,
|
||||||
|
gap: 12,
|
||||||
|
},
|
||||||
|
linkText: {
|
||||||
|
flex: 1,
|
||||||
|
color: Palette.white,
|
||||||
|
fontSize: 15,
|
||||||
|
fontFamily: FONT_FAMILY.InterMedium,
|
||||||
|
},
|
||||||
|
linkActions: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 8,
|
||||||
|
},
|
||||||
|
iconButton: {
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
copiedText: {
|
||||||
|
fontSize: 12,
|
||||||
|
textAlign: "center",
|
||||||
|
color: Palette.white,
|
||||||
|
opacity: 0.8,
|
||||||
|
fontFamily: FONT_FAMILY.InterMedium,
|
||||||
|
},
|
||||||
|
sectionHeading: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
optionsList: {
|
||||||
|
gap: 12,
|
||||||
|
},
|
||||||
|
optionRow: {
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "rgba(255, 255, 255, 0.04)",
|
||||||
|
borderRadius: 18,
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
paddingVertical: 14,
|
||||||
|
gap: 14,
|
||||||
|
},
|
||||||
|
optionIconWrapper: {
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
borderRadius: 18,
|
||||||
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
optionLabel: {
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 15,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.InterMedium,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default ShareModal;
|
export default ShareModal;
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,7 @@ export const firebaseDashboardUrl =
|
|||||||
export const appleAppStoreUrl = "https://apps.apple.com/app";
|
export const appleAppStoreUrl = "https://apps.apple.com/app";
|
||||||
export const algoliaAppUrl = "https://dashboard.algolia.com/apps";
|
export const algoliaAppUrl = "https://dashboard.algolia.com/apps";
|
||||||
|
|
||||||
|
export const musiclandShareUrl = "https://musicland.ai";
|
||||||
|
export const musiclandShareHeading = "Partagez l'expérience MusicLand";
|
||||||
|
export const musiclandShareMessage =
|
||||||
|
"Invite tes proches a decouvrir MusicLand et cree des experiences musicales ensemble.";
|
||||||
|
|||||||
+12
-12
@@ -1,21 +1,21 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { Platform, StyleSheet, View } from "react-native";
|
import { Platform, StyleSheet, View } from "react-native";
|
||||||
import Page from "../../layouts/Page";
|
|
||||||
import { background } from "../../assets";
|
import { background } from "../../assets";
|
||||||
import { gutters, Palette } from "../../styles";
|
import BorderGradientButton from "../../components/BorderGradientButton";
|
||||||
import { navigate } from "../../navigation/NavigationService";
|
|
||||||
import { Routes } from "../../navigation";
|
|
||||||
import { useUser } from "../../providers/UserDataProvider";
|
|
||||||
import ProjectDropDown from "../../components/ProjectDropDown/ProjectDropDown";
|
|
||||||
import FeatureCarousel from "../../components/FeatureCarousel/FeatureCarousel";
|
import FeatureCarousel from "../../components/FeatureCarousel/FeatureCarousel";
|
||||||
import GradientButton from "../../components/GradientButton";
|
import GradientButton from "../../components/GradientButton";
|
||||||
import BorderGradientButton from "../../components/BorderGradientButton";
|
import ProjectDropDown from "../../components/ProjectDropDown/ProjectDropDown";
|
||||||
import { isWeb } from "../../hooks/useLayoutType.js";
|
|
||||||
import ShareBtn from "../../components/ShareBtn/ShareBtn";
|
import ShareBtn from "../../components/ShareBtn/ShareBtn";
|
||||||
|
import { isWeb } from "../../hooks/useLayoutType.js";
|
||||||
|
import Page from "../../layouts/Page";
|
||||||
|
import { Routes } from "../../navigation";
|
||||||
|
import { navigate } from "../../navigation/NavigationService";
|
||||||
|
import { useUser } from "../../providers/UserDataProvider";
|
||||||
|
import { gutters, Palette } from "../../styles";
|
||||||
import {
|
import {
|
||||||
|
findFirstUnlockedStageIndex,
|
||||||
getCreationStageStates,
|
getCreationStageStates,
|
||||||
getStageAction,
|
getStageAction,
|
||||||
findFirstUnlockedStageIndex,
|
|
||||||
} from "../../utils/projectStages";
|
} from "../../utils/projectStages";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
@@ -29,7 +29,7 @@ const Home = () => {
|
|||||||
|
|
||||||
const projects = useMemo(
|
const projects = useMemo(
|
||||||
() => (Array.isArray(userProjects) ? userProjects : []),
|
() => (Array.isArray(userProjects) ? userProjects : []),
|
||||||
[userProjects],
|
[userProjects]
|
||||||
);
|
);
|
||||||
|
|
||||||
const currentProject = useMemo(() => {
|
const currentProject = useMemo(() => {
|
||||||
@@ -75,7 +75,7 @@ const Home = () => {
|
|||||||
|
|
||||||
const stageStates = useMemo(
|
const stageStates = useMemo(
|
||||||
() => getCreationStageStates(currentProject),
|
() => getCreationStageStates(currentProject),
|
||||||
[currentProject],
|
[currentProject]
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstUnlockedIndex = useMemo(() => {
|
const firstUnlockedIndex = useMemo(() => {
|
||||||
@@ -139,7 +139,7 @@ const Home = () => {
|
|||||||
|
|
||||||
const songwriterAction = useMemo(
|
const songwriterAction = useMemo(
|
||||||
() => getStageAction("songwriter", null),
|
() => getStageAction("songwriter", null),
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleStartNew = useCallback(() => {
|
const handleStartNew = useCallback(() => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { Image as ExpoImage } from "expo-image";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Pressable, ScrollView, Text, View } from "react-native";
|
import { Pressable, ScrollView, Text, View } from "react-native";
|
||||||
import { Image as ExpoImage } from "expo-image";
|
|
||||||
import { img } from "../../../assets";
|
import { img } from "../../../assets";
|
||||||
import MoreMenu from "../../../components/MoreMenu";
|
import MoreMenu from "../../../components/MoreMenu";
|
||||||
import { Routes } from "../../../navigation";
|
import { Routes } from "../../../navigation";
|
||||||
@@ -85,12 +85,12 @@ const SearchResultsList = ({
|
|||||||
setShowMenu(
|
setShowMenu(
|
||||||
(previous) =>
|
(previous) =>
|
||||||
!previous ||
|
!previous ||
|
||||||
positionTop?.top !== (menuPosition?.top ?? null),
|
positionTop?.top !== (menuPosition?.top ?? null)
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{(filteredProjects.length >= 6 || projectsLoading) && (
|
{/* {(filteredProjects.length >= 6 || projectsLoading) && (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={loadMoreProjects}
|
onPress={loadMoreProjects}
|
||||||
style={{ alignSelf: "center", marginTop: 6 }}
|
style={{ alignSelf: "center", marginTop: 6 }}
|
||||||
@@ -106,7 +106,7 @@ const SearchResultsList = ({
|
|||||||
{projectsLoading ? "Chargement…" : "Charger plus"}
|
{projectsLoading ? "Chargement…" : "Charger plus"}
|
||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)}
|
)} */}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{filteredProjects.length === 0 && !projectsLoading && (
|
{filteredProjects.length === 0 && !projectsLoading && (
|
||||||
@@ -163,7 +163,7 @@ const SearchResultsList = ({
|
|||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
))}
|
))}
|
||||||
{(filteredUsers.length >= 5 || usersLoading) && (
|
{/* {(filteredUsers.length >= 5 || usersLoading) && (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={loadMoreUsers}
|
onPress={loadMoreUsers}
|
||||||
style={{ alignSelf: "center", marginTop: 6 }}
|
style={{ alignSelf: "center", marginTop: 6 }}
|
||||||
@@ -179,7 +179,7 @@ const SearchResultsList = ({
|
|||||||
{usersLoading ? "Chargement…" : "Charger plus"}
|
{usersLoading ? "Chargement…" : "Charger plus"}
|
||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)}
|
)} */}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{filteredUsers.length === 0 && !usersLoading && (
|
{filteredUsers.length === 0 && !usersLoading && (
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import DeleteAccountModal from "../components/modal/DeleteAccountModal";
|
|||||||
import DeletePlaybackModal from "../components/modal/DeletePlaybackModal";
|
import DeletePlaybackModal from "../components/modal/DeletePlaybackModal";
|
||||||
import DeleteAudioModal from "../components/modal/DeleteAudioModal";
|
import DeleteAudioModal from "../components/modal/DeleteAudioModal";
|
||||||
import PlaylistModal from "../components/modal/PlaylistModal";
|
import PlaylistModal from "../components/modal/PlaylistModal";
|
||||||
|
import ShareModal from "../components/modal/ShareModal";
|
||||||
|
|
||||||
registerSheet("Delete", DeleteModal);
|
registerSheet("Delete", DeleteModal);
|
||||||
registerSheet("ProfileSettings", ProfileSettingsModal);
|
registerSheet("ProfileSettings", ProfileSettingsModal);
|
||||||
@@ -12,5 +13,6 @@ registerSheet("DeleteAccount", DeleteAccountModal);
|
|||||||
registerSheet("DeletePlayback", DeletePlaybackModal);
|
registerSheet("DeletePlayback", DeletePlaybackModal);
|
||||||
registerSheet("DeleteAudio", DeleteAudioModal);
|
registerSheet("DeleteAudio", DeleteAudioModal);
|
||||||
registerSheet("Playlist", PlaylistModal);
|
registerSheet("Playlist", PlaylistModal);
|
||||||
|
registerSheet("Share", ShareModal);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
|
||||||
|
import {
|
||||||
|
musiclandShareHeading,
|
||||||
|
musiclandShareMessage,
|
||||||
|
musiclandShareUrl,
|
||||||
|
} from "../data";
|
||||||
|
|
||||||
|
const defaultPayload = {
|
||||||
|
heading: musiclandShareHeading,
|
||||||
|
url: musiclandShareUrl,
|
||||||
|
shareTitle: "MusicLand",
|
||||||
|
shareMessage: musiclandShareMessage,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const openShareSheet = (payload = {}) => {
|
||||||
|
SheetManager.show("Share", {
|
||||||
|
payload: {
|
||||||
|
...defaultPayload,
|
||||||
|
...payload,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
@@ -5063,6 +5063,11 @@ expo-camera@~16.0.18:
|
|||||||
dependencies:
|
dependencies:
|
||||||
invariant "^2.2.4"
|
invariant "^2.2.4"
|
||||||
|
|
||||||
|
expo-clipboard@~7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-7.0.1.tgz#31d61270e77a37d2a6b7ae9abf79e060497ef43b"
|
||||||
|
integrity sha512-rqYk0+WoqitPcPKxmMxSpLonX1E5Ije3LBYfnYMbH3xU5Gr8EAH9QnOWOi4BgahUPvcot6nbFEnx+DqARrmxKQ==
|
||||||
|
|
||||||
expo-constants@~17.0.5, expo-constants@~17.0.8:
|
expo-constants@~17.0.5, expo-constants@~17.0.8:
|
||||||
version "17.0.8"
|
version "17.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-17.0.8.tgz#d7a21ec6f1f4834ea25aa645be20292ef99c0b81"
|
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-17.0.8.tgz#d7a21ec6f1f4834ea25aa645be20292ef99c0b81"
|
||||||
|
|||||||
Reference in New Issue
Block a user