share modal
This commit is contained in:
@@ -3,6 +3,7 @@ import React from "react";
|
||||
import { Platform } from "react-native";
|
||||
import ActionSheet from "react-native-actions-sheet";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { isWeb } from "../hooks/useLayoutType";
|
||||
import { gutters, Palette } from "../styles";
|
||||
|
||||
const AppActionSheet = ({ children, props }) => {
|
||||
@@ -19,7 +20,7 @@ const AppActionSheet = ({ children, props }) => {
|
||||
{...props}
|
||||
>
|
||||
<BlurView
|
||||
intensity={Platform.OS === "ios" ? 20 : 10}
|
||||
intensity={Platform.OS === "ios" || isWeb ? 20 : 10}
|
||||
style={{
|
||||
paddingTop: 36,
|
||||
paddingHorizontal: 14,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { View, Text, Pressable, Image, Platform } from "react-native";
|
||||
import React from "react";
|
||||
import BorderGradient from "./BorderGradient/BorderGradient";
|
||||
import { Palette, Style } from "../styles";
|
||||
import { BlurView } from "expo-blur";
|
||||
import React from "react";
|
||||
import { Image, Pressable, Text, View } from "react-native";
|
||||
import { Palette, Style } from "../styles";
|
||||
import { FONT_FAMILY } from "../styles/Fonts";
|
||||
import { size } from "../styles/Style";
|
||||
import BorderGradient from "./BorderGradient/BorderGradient";
|
||||
|
||||
const BorderGradientButton = ({
|
||||
title = "J’ai déjà mes paroles",
|
||||
@@ -45,7 +45,7 @@ const BorderGradientButton = ({
|
||||
}}
|
||||
>
|
||||
<BlurView
|
||||
intensity={Platform.OS === "ios" ? 40 : 10}
|
||||
intensity={40}
|
||||
tint={tint}
|
||||
style={{
|
||||
width: "100%",
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { View } from "react-native";
|
||||
import Svg, { Rect } from "react-native-svg";
|
||||
import { generateQrMatrix } from "../utils/generateQrMatrix";
|
||||
|
||||
const DEFAULT_SIZE = 220;
|
||||
|
||||
const QrCode = ({
|
||||
value,
|
||||
size = DEFAULT_SIZE,
|
||||
color = "#FFFFFF",
|
||||
backgroundColor = "transparent",
|
||||
errorCorrectionLevel = "M",
|
||||
}) => {
|
||||
const { matrix } = useMemo(() => {
|
||||
return generateQrMatrix({ value, errorCorrectionLevel });
|
||||
}, [value, errorCorrectionLevel]);
|
||||
|
||||
const cellSize = useMemo(() => {
|
||||
if (!matrix || !matrix.length) {
|
||||
return 0;
|
||||
}
|
||||
return size / matrix.length;
|
||||
}, [matrix, size]);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: size,
|
||||
height: size,
|
||||
backgroundColor,
|
||||
}}
|
||||
>
|
||||
<Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
|
||||
{matrix.map((row, rowIndex) => {
|
||||
return row.map((isDark, colIndex) => {
|
||||
if (!isDark) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = `${rowIndex}-${colIndex}`;
|
||||
|
||||
return (
|
||||
<Rect
|
||||
key={key}
|
||||
x={colIndex * cellSize}
|
||||
y={rowIndex * cellSize}
|
||||
width={cellSize}
|
||||
height={cellSize}
|
||||
fill={color}
|
||||
/>
|
||||
);
|
||||
});
|
||||
})}
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default QrCode;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import {
|
||||
Feather,
|
||||
FontAwesome,
|
||||
MaterialCommunityIcons,
|
||||
} from "@expo/vector-icons";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
@@ -15,21 +20,18 @@ import {
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import {
|
||||
Feather,
|
||||
FontAwesome,
|
||||
MaterialCommunityIcons,
|
||||
} from "@expo/vector-icons";
|
||||
|
||||
import AppActionSheet from "../AppActionSheet";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { isWeb } from "../../hooks/useLayoutType";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { setGlobal } from "reactn";
|
||||
import {
|
||||
musiclandShareHeading,
|
||||
musiclandShareMessage,
|
||||
musiclandShareUrl,
|
||||
} from "../../data";
|
||||
import { isWeb } from "../../hooks/useLayoutType";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import AppActionSheet from "../AppActionSheet";
|
||||
|
||||
const ShareModal = ({ payload }) => {
|
||||
const heading = payload?.heading ?? musiclandShareHeading;
|
||||
@@ -38,9 +40,12 @@ const ShareModal = ({ payload }) => {
|
||||
const shareMessage = payload?.shareMessage ?? musiclandShareMessage;
|
||||
const linkLabel = payload?.linkLabel ?? url;
|
||||
const sectionTitle = payload?.sectionTitle ?? "Partager sur...";
|
||||
const qrTitle = payload?.qrTitle ?? "Scannez le QR-code";
|
||||
const qrUrl = payload?.qrUrl ?? musiclandShareUrl;
|
||||
|
||||
const [copied, setCopied] = useState(false);
|
||||
const copyTimeout = useRef(null);
|
||||
const qrOpenTimeout = useRef(null);
|
||||
|
||||
const closeSheet = useCallback(() => {
|
||||
SheetManager.hide("Share");
|
||||
@@ -61,6 +66,9 @@ const ShareModal = ({ payload }) => {
|
||||
if (copyTimeout.current) {
|
||||
clearTimeout(copyTimeout.current);
|
||||
}
|
||||
if (qrOpenTimeout.current) {
|
||||
clearTimeout(qrOpenTimeout.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -123,6 +131,22 @@ const ShareModal = ({ payload }) => {
|
||||
|
||||
const handleShareOption = useCallback(
|
||||
async (option) => {
|
||||
if (option?.type === "qr") {
|
||||
const qrTitleValue = qrTitle;
|
||||
|
||||
closeSheet();
|
||||
qrOpenTimeout.current = setTimeout(() => {
|
||||
setGlobal({
|
||||
shareQrModal: {
|
||||
visible: true,
|
||||
url: qrUrl,
|
||||
title: qrTitleValue,
|
||||
},
|
||||
});
|
||||
}, 200);
|
||||
return;
|
||||
}
|
||||
|
||||
const target = option?.target;
|
||||
|
||||
if (!target) {
|
||||
@@ -151,7 +175,7 @@ const ShareModal = ({ payload }) => {
|
||||
await handleSystemShare();
|
||||
closeSheet();
|
||||
},
|
||||
[closeSheet, handleSystemShare]
|
||||
[closeSheet, handleSystemShare, qrTitle, qrUrl]
|
||||
);
|
||||
|
||||
const onSystemShare = useCallback(async () => {
|
||||
@@ -193,11 +217,11 @@ const ShareModal = ({ payload }) => {
|
||||
},
|
||||
{
|
||||
key: "qr",
|
||||
type: "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]);
|
||||
@@ -205,7 +229,12 @@ const ShareModal = ({ payload }) => {
|
||||
return (
|
||||
<AppActionSheet id="Share">
|
||||
<View style={styles.container}>
|
||||
<View style={styles.card}>
|
||||
<BlurView
|
||||
style={[styles.card, styles.blurCard]}
|
||||
tint="dark"
|
||||
intensity={40}
|
||||
experimentalBlurMethod="dimezisBlurView"
|
||||
>
|
||||
<Text style={styles.heading}>{heading}</Text>
|
||||
<View style={styles.linkRow}>
|
||||
<Text numberOfLines={1} style={styles.linkText}>
|
||||
@@ -232,31 +261,39 @@ const ShareModal = ({ payload }) => {
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
{copied ? (
|
||||
<Text style={styles.copiedText}>Lien copie</Text>
|
||||
) : null}
|
||||
</View>
|
||||
{copied ? <Text style={styles.copiedText}>Lien copié</Text> : null}
|
||||
</BlurView>
|
||||
|
||||
<View style={styles.card}>
|
||||
<BlurView
|
||||
intensity={70}
|
||||
experimentalBlurMethod="dimezisBlurView"
|
||||
style={styles.card}
|
||||
>
|
||||
<Text style={styles.sectionHeading}>{sectionTitle}</Text>
|
||||
<View style={styles.optionsList}>
|
||||
{shareOptions.map((option) => {
|
||||
{shareOptions.map((option, index) => {
|
||||
const Icon = option?.Icon ?? Feather;
|
||||
return (
|
||||
<Pressable
|
||||
key={option?.key}
|
||||
onPress={() => handleShareOption(option)}
|
||||
style={styles.optionRow}
|
||||
<BlurView
|
||||
key={option?.key || index}
|
||||
style={styles.optionBlur}
|
||||
intensity={40}
|
||||
experimentalBlurMethod="dimezisBlurView"
|
||||
>
|
||||
<View style={styles.optionIconWrapper}>
|
||||
<Icon size={18} color={Palette.white} />
|
||||
</View>
|
||||
<Text style={styles.optionLabel}>{option?.label}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => handleShareOption(option)}
|
||||
style={styles.optionRow}
|
||||
>
|
||||
<View style={styles.optionIconWrapper}>
|
||||
<Icon size={18} color={Palette.white} />
|
||||
</View>
|
||||
<Text style={styles.optionLabel}>{option?.label}</Text>
|
||||
</Pressable>
|
||||
</BlurView>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
</AppActionSheet>
|
||||
);
|
||||
@@ -267,7 +304,8 @@ const styles = StyleSheet.create({
|
||||
gap: 24,
|
||||
},
|
||||
card: {
|
||||
backgroundColor: Palette.glass,
|
||||
// backgroundColor: Palette.glass,
|
||||
overflow: "hidden",
|
||||
borderRadius: 24,
|
||||
borderWidth: 1,
|
||||
borderColor: "rgba(255, 255, 255, 0.08)",
|
||||
@@ -275,6 +313,9 @@ const styles = StyleSheet.create({
|
||||
paddingVertical: 18,
|
||||
gap: 16,
|
||||
},
|
||||
blurCard: {
|
||||
overflow: "hidden",
|
||||
},
|
||||
heading: {
|
||||
fontSize: 20,
|
||||
color: Palette.white,
|
||||
@@ -325,11 +366,15 @@ const styles = StyleSheet.create({
|
||||
optionsList: {
|
||||
gap: 12,
|
||||
},
|
||||
optionBlur: {
|
||||
borderRadius: 18,
|
||||
overflow: "hidden",
|
||||
},
|
||||
optionRow: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.04)",
|
||||
borderRadius: 18,
|
||||
// borderRadius: 18,
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 14,
|
||||
gap: 14,
|
||||
@@ -351,4 +396,3 @@ const styles = StyleSheet.create({
|
||||
});
|
||||
|
||||
export default ShareModal;
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
||||
import { Feather } from "@expo/vector-icons";
|
||||
import { Portal } from "@gorhom/portal";
|
||||
|
||||
import QrCode from "../QrCode";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
|
||||
const ShareQrModal = ({ visible, onClose, url, title = "Scannez le QR-code" }) => {
|
||||
const shareUrl = useMemo(() => url, [url]);
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const blurIntensity = Platform.select({ ios: 40, default: 20 });
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<View style={StyleSheet.absoluteFill} pointerEvents="box-none">
|
||||
<Pressable
|
||||
onPress={onClose}
|
||||
style={[StyleSheet.absoluteFill, styles.backdrop]}
|
||||
/>
|
||||
|
||||
<View style={styles.centerWrapper} pointerEvents="box-none">
|
||||
<BlurView intensity={blurIntensity} tint="dark" style={styles.modalCard}>
|
||||
<Pressable onPress={onClose} style={styles.closeButton} hitSlop={10}>
|
||||
<Feather name="x" size={20} color={Palette.white} />
|
||||
</Pressable>
|
||||
|
||||
<View style={styles.content}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Partage ce code pour guider tes contacts directement vers MusicLand.
|
||||
</Text>
|
||||
|
||||
<View style={styles.qrWrapper}>
|
||||
<QrCode value={shareUrl} size={220} backgroundColor="transparent" />
|
||||
</View>
|
||||
|
||||
<Text numberOfLines={1} ellipsizeMode="middle" style={styles.linkText}>
|
||||
{shareUrl}
|
||||
</Text>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
</View>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
backdrop: {
|
||||
backgroundColor: "rgba(0, 0, 0, 0.65)",
|
||||
},
|
||||
centerWrapper: {
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: 24,
|
||||
},
|
||||
modalCard: {
|
||||
width: 360,
|
||||
maxWidth: "90%",
|
||||
borderRadius: 28,
|
||||
overflow: "hidden",
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 32,
|
||||
backgroundColor: Palette.glass,
|
||||
},
|
||||
closeButton: {
|
||||
position: "absolute",
|
||||
top: 18,
|
||||
right: 18,
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.12)",
|
||||
},
|
||||
content: {
|
||||
alignItems: "center",
|
||||
gap: 18,
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
opacity: 0.8,
|
||||
textAlign: "center",
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
paddingHorizontal: 8,
|
||||
},
|
||||
qrWrapper: {
|
||||
padding: 16,
|
||||
borderRadius: 24,
|
||||
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
||||
},
|
||||
linkText: {
|
||||
fontSize: 13,
|
||||
color: Palette.white,
|
||||
opacity: 0.9,
|
||||
textAlign: "center",
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
},
|
||||
});
|
||||
|
||||
export default ShareQrModal;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from "react";
|
||||
import { useGlobal } from "reactn";
|
||||
|
||||
import { musiclandShareUrl } from "../../data";
|
||||
import ShareQrModal from "./ShareQrModal";
|
||||
|
||||
const ShareQrModalContainer = () => {
|
||||
const [shareQrModal, setShareQrModal] = useGlobal("shareQrModal");
|
||||
|
||||
const { visible, url, title } = shareQrModal || {};
|
||||
|
||||
const handleClose = () => {
|
||||
setShareQrModal({
|
||||
visible: false,
|
||||
url: null,
|
||||
title: "",
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ShareQrModal
|
||||
visible={!!visible}
|
||||
url={url || musiclandShareUrl}
|
||||
title={title || "Scannez le QR-code"}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShareQrModalContainer;
|
||||
@@ -8,6 +8,12 @@ export default {
|
||||
webBackgroundImg: null,
|
||||
webLayoutMode: "default",
|
||||
|
||||
shareQrModal: {
|
||||
visible: false,
|
||||
url: null,
|
||||
title: "",
|
||||
},
|
||||
|
||||
_config: {
|
||||
colors: {
|
||||
primary: Palette.primary,
|
||||
|
||||
@@ -187,7 +187,7 @@ const HitParade = () => {
|
||||
backgroundImg={isWeb ? background.libraryBgWeb : background.hitParadeBG}
|
||||
headerType="NONE"
|
||||
width="100%"
|
||||
maxWidth={null}
|
||||
maxWidth={800}
|
||||
blurIntensity={isWeb ? 2 : 0}
|
||||
>
|
||||
<View style={{ gap: 12, flex: 1 }}>
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import React, { useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useGlobal } from "reactn";
|
||||
import MoreMenu from "../../../components/MoreMenu";
|
||||
import { projectsRef } from "../../../config/firebase";
|
||||
import { Routes } from "../../../navigation";
|
||||
import { navigate } from "../../../navigation/NavigationService";
|
||||
import { useUser } from "../../../providers/UserDataProvider";
|
||||
import CardContainer from "./CardContainer";
|
||||
import MusicCard from "./MusicCard";
|
||||
import MoreMenu from "../../../components/MoreMenu";
|
||||
|
||||
const MyMusic = () => {
|
||||
const { userProjects = [] } = useUser();
|
||||
const [menuPosition, setMenuPosition] = useState(null);
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const [selectedProjectId, setSelectedProjectId] = useState(null);
|
||||
const projects = Array.isArray(userProjects) ? userProjects.slice(0, 3) : [];
|
||||
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
|
||||
return (
|
||||
<CardContainer
|
||||
label="Mes musiques"
|
||||
@@ -39,8 +44,7 @@ const MyMusic = () => {
|
||||
setSelectedProjectId(p.id);
|
||||
setMenuPosition(posTop);
|
||||
setShowMenu(
|
||||
(prev) =>
|
||||
!prev || posTop?.top !== (menuPosition?.top ?? null),
|
||||
(prev) => !prev || posTop?.top !== (menuPosition?.top ?? null)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
@@ -52,6 +56,34 @@ const MyMusic = () => {
|
||||
onClose={() => setShowMenu(false)}
|
||||
inPlaylist={false}
|
||||
projectId={selectedProjectId}
|
||||
extraItems={[
|
||||
{
|
||||
label: "Supprimer",
|
||||
onPress: () =>
|
||||
SheetManager.show("Delete", {
|
||||
payload: {
|
||||
title: "Supprimer le projet",
|
||||
message:
|
||||
"Cette action supprimera définitivement ce projet.",
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
if (!selectedProjectId) return;
|
||||
await projectsRef.doc(selectedProjectId).delete();
|
||||
setTooltip({
|
||||
type: "success",
|
||||
text: "Projet supprimé",
|
||||
});
|
||||
} catch (e) {
|
||||
setTooltip({
|
||||
type: "error",
|
||||
text: e?.message || "Suppression impossible",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
</CardContainer>
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
Image,
|
||||
Pressable,
|
||||
Platform,
|
||||
} from "react-native";
|
||||
import { BlurView } from "expo-blur";
|
||||
import React, { useState } from "react";
|
||||
import { Platform, Pressable, Text, TextInput, View } from "react-native";
|
||||
import EyeSlashSVG from "../../../assets/UI/EyeSlashSVG";
|
||||
import EyeSVG from "../../../assets/UI/EyeSVG";
|
||||
import { Palette, Style } from "../../../styles";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { icons } from "../../../assets";
|
||||
|
||||
const EditInput = ({
|
||||
label = "",
|
||||
@@ -79,7 +73,7 @@ const EditInput = ({
|
||||
/>
|
||||
{type === "password" && (
|
||||
<Pressable onPress={() => setShowPassword(!showPassword)}>
|
||||
<Image source={icons.eye} />
|
||||
{showPassword ? <EyeSVG /> : <EyeSlashSVG />}
|
||||
</Pressable>
|
||||
)}
|
||||
</BlurView>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import QRCode from "qrcode-terminal/vendor/QRCode";
|
||||
import QRErrorCorrectLevel from "qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel";
|
||||
|
||||
const getErrorLevel = (level) => {
|
||||
if (typeof level === "number") {
|
||||
return level;
|
||||
}
|
||||
|
||||
const normalized = String(level || "M").toUpperCase();
|
||||
return QRErrorCorrectLevel?.[normalized] ?? QRErrorCorrectLevel.M;
|
||||
};
|
||||
|
||||
export const generateQrMatrix = ({
|
||||
value,
|
||||
errorCorrectionLevel = "M",
|
||||
}) => {
|
||||
if (!value) {
|
||||
throw new Error("generateQrMatrix requires a value");
|
||||
}
|
||||
|
||||
const qr = new QRCode(-1, getErrorLevel(errorCorrectionLevel));
|
||||
qr.addData(value);
|
||||
qr.make();
|
||||
|
||||
const size = qr.getModuleCount();
|
||||
const matrix = new Array(size);
|
||||
|
||||
for (let row = 0; row < size; row += 1) {
|
||||
matrix[row] = new Array(size);
|
||||
for (let col = 0; col < size; col += 1) {
|
||||
matrix[row][col] = qr.isDark(row, col);
|
||||
}
|
||||
}
|
||||
|
||||
return { matrix, size };
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ const defaultPayload = {
|
||||
url: musiclandShareUrl,
|
||||
shareTitle: "MusicLand",
|
||||
shareMessage: musiclandShareMessage,
|
||||
qrUrl: musiclandShareUrl,
|
||||
};
|
||||
|
||||
export const openShareSheet = (payload = {}) => {
|
||||
@@ -21,4 +22,3 @@ export const openShareSheet = (payload = {}) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user