web playlist modal
This commit is contained in:
@@ -9,10 +9,10 @@ import {
|
|||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { SheetManager } from "react-native-actions-sheet";
|
import { SheetManager } from "react-native-actions-sheet";
|
||||||
|
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
|
||||||
import SwiperFlatList from "react-native-swiper-flatlist";
|
import SwiperFlatList from "react-native-swiper-flatlist";
|
||||||
import { icons } from "../../assets";
|
import { icons } from "../../assets";
|
||||||
import { arrayUnion, playlistsRef } from "../../config/firebase";
|
import { arrayUnion, playlistsRef } from "../../config/firebase";
|
||||||
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
|
|
||||||
import { useUserData } from "../../providers/UserDataProvider";
|
import { useUserData } from "../../providers/UserDataProvider";
|
||||||
import { createPlaylist } from "../../screens/Library/Playlists/playlist";
|
import { createPlaylist } from "../../screens/Library/Playlists/playlist";
|
||||||
import { Palette } from "../../styles";
|
import { Palette } from "../../styles";
|
||||||
@@ -33,12 +33,22 @@ const PlaylistModal = (props) => {
|
|||||||
const startAtCreate = props?.payload?.startAtCreate || false;
|
const startAtCreate = props?.payload?.startAtCreate || false;
|
||||||
const { setTooltip } = useMinuit();
|
const { setTooltip } = useMinuit();
|
||||||
|
|
||||||
|
const sanitizedPlaylists = useMemo(
|
||||||
|
() => (Array.isArray(userPlaylists) ? userPlaylists : []),
|
||||||
|
[userPlaylists],
|
||||||
|
);
|
||||||
|
|
||||||
const isDuplicateName = useMemo(() => {
|
const isDuplicateName = useMemo(() => {
|
||||||
const lower = (playlist || "").trim().toLowerCase();
|
const lower = (playlist || "").trim().toLowerCase();
|
||||||
if (!lower) return false;
|
if (!lower) return false;
|
||||||
const list = Array.isArray(userPlaylists) ? userPlaylists : [];
|
return sanitizedPlaylists.some(
|
||||||
return list.some((p) => (p?.name || "").trim().toLowerCase() === lower);
|
(p) => (p?.name || "").trim().toLowerCase() === lower,
|
||||||
}, [playlist, JSON.stringify(userPlaylists)]);
|
);
|
||||||
|
}, [playlist, sanitizedPlaylists]);
|
||||||
|
|
||||||
|
const hideSheet = () => {
|
||||||
|
SheetManager.hide("Playlist");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppActionSheet id="Playlist">
|
<AppActionSheet id="Playlist">
|
||||||
@@ -60,8 +70,10 @@ const PlaylistModal = (props) => {
|
|||||||
>
|
>
|
||||||
Ajouter ce titre à une playlist
|
Ajouter ce titre à une playlist
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<FlatList
|
<FlatList
|
||||||
data={Array.isArray(userPlaylists) ? userPlaylists : []}
|
data={sanitizedPlaylists}
|
||||||
|
keyExtractor={(item, index) => item?.id || `playlist-${index}`}
|
||||||
contentContainerStyle={{ gap: 20 }}
|
contentContainerStyle={{ gap: 20 }}
|
||||||
ListHeaderComponent={
|
ListHeaderComponent={
|
||||||
<Pressable
|
<Pressable
|
||||||
@@ -70,7 +82,7 @@ const PlaylistModal = (props) => {
|
|||||||
gap: 10,
|
gap: 10,
|
||||||
}}
|
}}
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
scrollRef.current.scrollToIndex({
|
scrollRef.current?.scrollToIndex({
|
||||||
index: 1,
|
index: 1,
|
||||||
animated: true,
|
animated: true,
|
||||||
})
|
})
|
||||||
@@ -96,6 +108,7 @@ const PlaylistModal = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<GradientButton
|
<GradientButton
|
||||||
title="Valider"
|
title="Valider"
|
||||||
containerStyle={{
|
containerStyle={{
|
||||||
@@ -113,9 +126,9 @@ const PlaylistModal = (props) => {
|
|||||||
musics: arrayUnion(projectId),
|
musics: arrayUnion(projectId),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
});
|
});
|
||||||
const addedPlaylist = (
|
const addedPlaylist = sanitizedPlaylists.find(
|
||||||
Array.isArray(userPlaylists) ? userPlaylists : []
|
(p) => p?.id === selectedId,
|
||||||
).find((p) => p?.id === selectedId);
|
);
|
||||||
const name = addedPlaylist?.name || "la playlist";
|
const name = addedPlaylist?.name || "la playlist";
|
||||||
setTooltip({
|
setTooltip({
|
||||||
type: "success",
|
type: "success",
|
||||||
@@ -129,18 +142,19 @@ const PlaylistModal = (props) => {
|
|||||||
text: e?.message || "Ajout impossible",
|
text: e?.message || "Ajout impossible",
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
SheetManager.hide("Playlist");
|
hideSheet();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ width, paddingHorizontal: 14 }}>
|
<View style={{ width, paddingHorizontal: 14 }}>
|
||||||
<View style={{ gap: 20 }}>
|
<View style={{ gap: 20 }}>
|
||||||
{!startAtCreate && (
|
{!startAtCreate && (
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
scrollRef.current.scrollToIndex({
|
scrollRef.current?.scrollToIndex({
|
||||||
index: 0,
|
index: 0,
|
||||||
animated: true,
|
animated: true,
|
||||||
});
|
});
|
||||||
@@ -158,12 +172,14 @@ const PlaylistModal = (props) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={{ ...Style.containerCenter, gap: 14 }}>
|
<View style={{ ...Style.containerCenter, gap: 14 }}>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Palette.white,
|
color: Palette.white,
|
||||||
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
||||||
|
textAlign: "center",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Nommer la playlist
|
Nommer la playlist
|
||||||
@@ -197,6 +213,7 @@ const PlaylistModal = (props) => {
|
|||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<GradientButton
|
<GradientButton
|
||||||
title={isCreating ? "Création..." : "Créer la playlist"}
|
title={isCreating ? "Création..." : "Créer la playlist"}
|
||||||
containerStyle={{
|
containerStyle={{
|
||||||
@@ -211,10 +228,9 @@ const PlaylistModal = (props) => {
|
|||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
const name = playlist.trim();
|
const name = playlist.trim();
|
||||||
const lower = name.toLowerCase();
|
const lower = name.toLowerCase();
|
||||||
// Unicité du nom pour l'utilisateur courant (insensible à la casse)
|
const exists = sanitizedPlaylists.some(
|
||||||
const exists = (
|
(p) => (p?.name || "").trim().toLowerCase() === lower,
|
||||||
Array.isArray(userPlaylists) ? userPlaylists : []
|
);
|
||||||
).some((p) => (p?.name || "").trim().toLowerCase() === lower);
|
|
||||||
if (exists) {
|
if (exists) {
|
||||||
setTooltip({
|
setTooltip({
|
||||||
type: "error",
|
type: "error",
|
||||||
@@ -222,6 +238,7 @@ const PlaylistModal = (props) => {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await createPlaylist({
|
await createPlaylist({
|
||||||
createdBy: currentUID,
|
createdBy: currentUID,
|
||||||
name,
|
name,
|
||||||
@@ -231,15 +248,20 @@ const PlaylistModal = (props) => {
|
|||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
});
|
});
|
||||||
|
|
||||||
setTooltip({
|
setTooltip({
|
||||||
type: "success",
|
type: "success",
|
||||||
text: props?.payload?.projectId
|
text: props?.payload?.projectId
|
||||||
? `Playlist “${name}” créée et musique ajoutée`
|
? `Playlist “${name}” créée et musique ajoutée`
|
||||||
: `Playlist “${name}” créée`,
|
: `Playlist “${name}” créée`,
|
||||||
});
|
});
|
||||||
|
|
||||||
setPlaylist("");
|
setPlaylist("");
|
||||||
SheetManager.hide("Playlist");
|
scrollRef.current?.scrollToIndex({
|
||||||
scrollRef.current.scrollToIndex({ index: 0, animated: true });
|
index: 0,
|
||||||
|
animated: true,
|
||||||
|
});
|
||||||
|
hideSheet();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
setTooltip({
|
setTooltip({
|
||||||
|
|||||||
@@ -0,0 +1,347 @@
|
|||||||
|
import { Portal } from "@gorhom/portal";
|
||||||
|
import { BlurView } from "expo-blur";
|
||||||
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
import {
|
||||||
|
FlatList,
|
||||||
|
Image,
|
||||||
|
Pressable,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
View,
|
||||||
|
} from "react-native";
|
||||||
|
import { SheetManager, useProviderContext } from "react-native-actions-sheet";
|
||||||
|
import { actionSheetEventManager } from "react-native-actions-sheet/dist/src/eventmanager";
|
||||||
|
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
|
||||||
|
import { icons } from "../../assets";
|
||||||
|
import { arrayUnion, playlistsRef } from "../../config/firebase";
|
||||||
|
import { useUserData } from "../../providers/UserDataProvider";
|
||||||
|
import { createPlaylist } from "../../screens/Library/Playlists/playlist";
|
||||||
|
import { Palette } from "../../styles";
|
||||||
|
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||||
|
import Style, { size } from "../../styles/Style";
|
||||||
|
import AppCheckbox from "../AppCheckbox";
|
||||||
|
import GradientButton from "../GradientButton";
|
||||||
|
|
||||||
|
const PlaylistModal = (props) => {
|
||||||
|
const [selectedId, setSelectedId] = useState("");
|
||||||
|
const [playlist, setPlaylist] = useState("");
|
||||||
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
|
const { currentUID, userPlaylists = [] } = useUserData();
|
||||||
|
const { setTooltip } = useMinuit();
|
||||||
|
const startAtCreate = props?.payload?.startAtCreate || false;
|
||||||
|
const [mode, setMode] = useState(startAtCreate ? "create" : "select");
|
||||||
|
const [visible, setVisible] = useState(true);
|
||||||
|
const providerContext = useProviderContext();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMode(startAtCreate ? "create" : "select");
|
||||||
|
}, [startAtCreate]);
|
||||||
|
|
||||||
|
const sanitizedPlaylists = useMemo(
|
||||||
|
() => (Array.isArray(userPlaylists) ? userPlaylists : []),
|
||||||
|
[userPlaylists]
|
||||||
|
);
|
||||||
|
|
||||||
|
const isDuplicateName = useMemo(() => {
|
||||||
|
const lower = (playlist || "").trim().toLowerCase();
|
||||||
|
if (!lower) return false;
|
||||||
|
return sanitizedPlaylists.some(
|
||||||
|
(p) => (p?.name || "").trim().toLowerCase() === lower
|
||||||
|
);
|
||||||
|
}, [playlist, sanitizedPlaylists]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setVisible(true);
|
||||||
|
}, [props?.sheetId, props?.payload]);
|
||||||
|
|
||||||
|
const hideModal = () => {
|
||||||
|
setVisible(false);
|
||||||
|
props?.payload?.onClose?.();
|
||||||
|
|
||||||
|
const sheetId = props?.sheetId || "Playlist";
|
||||||
|
|
||||||
|
if (props?.sheetId) {
|
||||||
|
SheetManager.hide(sheetId, { context: providerContext });
|
||||||
|
// Web modal is rendered outside an actual ActionSheet, so we broadcast the
|
||||||
|
// close event manually to let the SheetProvider unmount it.
|
||||||
|
actionSheetEventManager.publish(`onclose_${sheetId}`, undefined, providerContext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleValidateSelection = async () => {
|
||||||
|
if (!selectedId) return;
|
||||||
|
try {
|
||||||
|
const projectId = props?.payload?.projectId;
|
||||||
|
if (projectId) {
|
||||||
|
await playlistsRef.doc(selectedId).update({
|
||||||
|
musics: arrayUnion(projectId),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
});
|
||||||
|
const addedPlaylist = sanitizedPlaylists.find(
|
||||||
|
(p) => p?.id === selectedId
|
||||||
|
);
|
||||||
|
const name = addedPlaylist?.name || "la playlist";
|
||||||
|
setTooltip({ type: "success", text: `Ajouté à “${name}”` });
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Add to playlist error", e?.message);
|
||||||
|
setTooltip({
|
||||||
|
type: "error",
|
||||||
|
text: e?.message || "Ajout impossible",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
hideModal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreatePlaylist = async () => {
|
||||||
|
if (!playlist?.trim()?.length || !currentUID) return;
|
||||||
|
try {
|
||||||
|
setIsCreating(true);
|
||||||
|
const name = playlist.trim();
|
||||||
|
const lower = name.toLowerCase();
|
||||||
|
const exists = sanitizedPlaylists.some(
|
||||||
|
(p) => (p?.name || "").trim().toLowerCase() === lower
|
||||||
|
);
|
||||||
|
if (exists) {
|
||||||
|
setTooltip({
|
||||||
|
type: "error",
|
||||||
|
text: "Ce nom de playlist existe déjà",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await createPlaylist({
|
||||||
|
createdBy: currentUID,
|
||||||
|
name,
|
||||||
|
musics: props?.payload?.projectId ? [props.payload.projectId] : [],
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
setTooltip({
|
||||||
|
type: "success",
|
||||||
|
text: props?.payload?.projectId
|
||||||
|
? `Playlist “${name}” créée et musique ajoutée`
|
||||||
|
: `Playlist “${name}” créée`,
|
||||||
|
});
|
||||||
|
|
||||||
|
setPlaylist("");
|
||||||
|
setSelectedId("");
|
||||||
|
setMode("select");
|
||||||
|
hideModal();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
setTooltip({
|
||||||
|
type: "error",
|
||||||
|
text: e?.message || "Création impossible",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsCreating(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderSelectStep = () => (
|
||||||
|
<View style={{ gap: 24 }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 22,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Ajouter ce titre à une playlist
|
||||||
|
</Text>
|
||||||
|
<FlatList
|
||||||
|
data={sanitizedPlaylists}
|
||||||
|
keyExtractor={(item, index) => item?.id || `playlist-${index}`}
|
||||||
|
contentContainerStyle={{ gap: 20 }}
|
||||||
|
style={{ maxHeight: 320 }}
|
||||||
|
ListHeaderComponent={
|
||||||
|
<Pressable
|
||||||
|
style={{
|
||||||
|
...Style.containerRow,
|
||||||
|
gap: 10,
|
||||||
|
alignSelf: "center",
|
||||||
|
}}
|
||||||
|
onPress={() => {
|
||||||
|
setPlaylist("");
|
||||||
|
setMode("create");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image source={icons.add} style={size({ size: 15 })} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 16,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Créer une nouvelle playlist
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<AppCheckbox
|
||||||
|
label={item?.name || "Sans nom"}
|
||||||
|
onPress={() => setSelectedId(item?.id)}
|
||||||
|
selected={selectedId === item?.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
ListEmptyComponent={
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 14,
|
||||||
|
color: Palette.white,
|
||||||
|
opacity: 0.8,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Aucune playlist pour le moment
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<GradientButton
|
||||||
|
title="Valider"
|
||||||
|
containerStyle={{
|
||||||
|
width: "80%",
|
||||||
|
alignSelf: "center",
|
||||||
|
opacity: selectedId ? 1 : 0.5,
|
||||||
|
}}
|
||||||
|
disabled={!selectedId}
|
||||||
|
onPress={handleValidateSelection}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderCreateStep = () => (
|
||||||
|
<View style={{ gap: 24 }}>
|
||||||
|
{!startAtCreate && (
|
||||||
|
<Pressable
|
||||||
|
onPress={() => {
|
||||||
|
setMode("select");
|
||||||
|
setPlaylist("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 12,
|
||||||
|
color: Palette.gray,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Retour
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
)}
|
||||||
|
<View style={{ ...Style.containerCenter, gap: 14 }}>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 20,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Nommer la playlist
|
||||||
|
</Text>
|
||||||
|
<TextInput
|
||||||
|
autoFocus={true}
|
||||||
|
style={{
|
||||||
|
paddingVertical: 6,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderColor: Palette.white,
|
||||||
|
fontSize: 20,
|
||||||
|
color: Palette.white,
|
||||||
|
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||||
|
minWidth: "40%",
|
||||||
|
maxWidth: "80%",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
value={playlist}
|
||||||
|
onChangeText={setPlaylist}
|
||||||
|
/>
|
||||||
|
{isDuplicateName && (
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
fontSize: 12,
|
||||||
|
color: Palette.red,
|
||||||
|
fontFamily: FONT_FAMILY.InterRegular,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Ce nom de playlist existe déjà
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<GradientButton
|
||||||
|
title={isCreating ? "Création..." : "Créer la playlist"}
|
||||||
|
containerStyle={{
|
||||||
|
width: "80%",
|
||||||
|
alignSelf: "center",
|
||||||
|
opacity: playlist?.trim()?.length ? 1 : 0.5,
|
||||||
|
}}
|
||||||
|
disabled={!playlist?.trim()?.length || isCreating}
|
||||||
|
onPress={handleCreatePlaylist}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!visible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Portal>
|
||||||
|
<View style={styles.overlayContainer}>
|
||||||
|
<BlurView
|
||||||
|
intensity={25}
|
||||||
|
tint="dark"
|
||||||
|
style={styles.blurOverlay}
|
||||||
|
pointerEvents="none"
|
||||||
|
/>
|
||||||
|
<Pressable style={styles.backdrop} onPress={hideModal} />
|
||||||
|
<View style={styles.modalWrapper}>
|
||||||
|
<View style={styles.modalContent}>
|
||||||
|
{mode === "select" ? renderSelectStep() : renderCreateStep()}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</Portal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
overlayContainer: {
|
||||||
|
...StyleSheet.absoluteFillObject,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
zIndex: 1000,
|
||||||
|
},
|
||||||
|
blurOverlay: {
|
||||||
|
...StyleSheet.absoluteFillObject,
|
||||||
|
zIndex: 0,
|
||||||
|
},
|
||||||
|
backdrop: {
|
||||||
|
...StyleSheet.absoluteFillObject,
|
||||||
|
backgroundColor: "rgba(10, 5, 20, 0.55)",
|
||||||
|
zIndex: 1,
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
modalWrapper: {
|
||||||
|
width: "90%",
|
||||||
|
maxWidth: 520,
|
||||||
|
borderRadius: 24,
|
||||||
|
overflow: "hidden",
|
||||||
|
zIndex: 2,
|
||||||
|
},
|
||||||
|
modalContent: {
|
||||||
|
paddingVertical: 32,
|
||||||
|
paddingHorizontal: 28,
|
||||||
|
backgroundColor: "rgba(30, 23, 38, 0.92)",
|
||||||
|
gap: 24,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PlaylistModal;
|
||||||
Reference in New Issue
Block a user