Change main page and modify flows

This commit is contained in:
Thomas Demirdjian
2025-09-02 11:45:27 +02:00
parent 8b7980308a
commit 98367af0b7
47 changed files with 3695 additions and 1020 deletions
+1
View File
@@ -0,0 +1 @@
export class AppBlurView {}
+5 -1
View File
@@ -16,7 +16,11 @@ const BorderGradientButton = ({
disabled = false,
}) => {
return (
<Pressable onPress={onPress} disabled={disabled} style={{ ...containerStyle, opacity: disabled ? 0.6 : 1 }}>
<Pressable
onPress={onPress}
disabled={disabled}
style={{ ...containerStyle, opacity: disabled ? 0.6 : 1 }}
>
<BorderGradient
gradientProps={{
colors: ["#F94697", "#7023F7"],
+104 -93
View File
@@ -7,6 +7,7 @@ import Animated, { Easing, FadeIn, FadeOut } from "react-native-reanimated";
import { arrayRemove, playlistsRef } from "../config/firebase";
import { Palette } from "../styles";
import { FONT_FAMILY } from "../styles/Fonts";
import { Portal } from "@gorhom/portal";
const MoreMenu = ({
visible = false,
@@ -49,99 +50,44 @@ const MoreMenu = ({
};
return (
<View
style={{
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
zIndex: 9999,
elevation: 9999,
}}
>
<Pressable
style={{ position: "absolute", left: 0, right: 0, top: 0, bottom: 0 }}
onPress={onClose}
/>
<Animated.View
entering={FadeIn.duration(300).easing(Easing.ease)}
exiting={FadeOut.duration(300).easing(Easing.ease)}
<Portal>
<View
style={{
position: "absolute",
left: 0,
right: 0,
top,
zIndex: 10000,
elevation: 10000,
top: 0,
bottom: 0,
zIndex: 9999,
elevation: 9999,
}}
>
<View style={{ gap: 2 }}>
{inPlaylist && (
<Pressable onPress={removeFromPlaylist}>
<BlurView
intensity={20}
style={{
paddingHorizontal: 12,
paddingVertical: 10,
backgroundColor: Palette.glass,
borderRadius: 12,
overflow: "hidden",
}}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Supprimer de la playlist
</Text>
</BlurView>
</Pressable>
)}
<Pressable onPress={addToPlaylist}>
<BlurView
intensity={20}
style={{
paddingHorizontal: 12,
paddingVertical: 10,
backgroundColor: Palette.glass,
borderRadius: 12,
overflow: "hidden",
}}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Ajouter à une playlist
</Text>
</BlurView>
</Pressable>
{Array.isArray(extraItems) &&
extraItems.map((item, idx) => (
<Pressable
key={idx}
onPress={() => {
try {
item?.onPress?.();
} finally {
onClose?.();
}
}}
>
{/* Background overlay to close on outside press */}
<Pressable
onPress={onClose}
style={{
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
zIndex: 1,
}}
/>
<Animated.View
entering={FadeIn.duration(300).easing(Easing.ease)}
exiting={FadeOut.duration(300).easing(Easing.ease)}
style={{
position: "absolute",
right: 0,
top,
zIndex: 2,
elevation: 2,
}}
>
<View style={{ gap: 2 }}>
{inPlaylist && (
<Pressable onPress={removeFromPlaylist}>
<BlurView
intensity={20}
style={{
@@ -162,14 +108,79 @@ const MoreMenu = ({
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item?.label || "Action"}
Supprimer de la playlist
</Text>
</BlurView>
</Pressable>
))}
</View>
</Animated.View>
</View>
)}
<Pressable onPress={addToPlaylist}>
<BlurView
intensity={20}
style={{
paddingHorizontal: 12,
paddingVertical: 10,
backgroundColor: Palette.glass,
borderRadius: 12,
overflow: "hidden",
}}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Ajouter à une playlist
</Text>
</BlurView>
</Pressable>
{Array.isArray(extraItems) &&
extraItems.map((item, idx) => (
<Pressable
key={idx}
onPress={() => {
try {
item?.onPress?.();
} finally {
onClose?.();
}
}}
>
<BlurView
intensity={20}
style={{
paddingHorizontal: 12,
paddingVertical: 10,
backgroundColor: Palette.glass,
borderRadius: 12,
overflow: "hidden",
}}
experimentalBlurMethod={
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item?.label || "Action"}
</Text>
</BlurView>
</Pressable>
))}
</View>
</Animated.View>
</View>
</Portal>
);
};
+7 -2
View File
@@ -1,4 +1,5 @@
import { Image, Text, View } from "react-native";
import { Text, View } from "react-native";
import { Image as ExpoImage } from "expo-image";
import { responsiveWidth } from "../actions/responsiveSizes.js";
import { getInitials } from "../helpers";
import { Fonts, Style } from "../styles";
@@ -62,8 +63,12 @@ export default ({
}}
>
{url ? (
<Image
<ExpoImage
source={{ uri: url }}
cachePolicy="memory-disk"
priority="high"
contentFit="cover"
transition={100}
style={{
width: size,
height: size,
+3 -7
View File
@@ -1,14 +1,10 @@
import { useContext } from "reactn";
import { Pressable, View, Image, Text } from "react-native";
import { Video, ResizeMode } from "expo-av";
import { Video, ResizeMode } from "expo-video";
import { Fonts, gutters, Palette } from "../styles";
import Style, { mainBorderRadius } from "../styles/Style";
import { icons } from "../assets";
import { substringTextLength } from "../helpers/index.js";
import { substringTextLength } from "../helpers";
import { WebViewContext } from "../providers/WebViewProvider.js";
const thumbnailStyle = {
@@ -20,7 +16,7 @@ const thumbnailStyle = {
const RenderChatFile = (
{ uri, type = "image", name = "", containerStyle = {} },
index
index,
) => {
const { setWebViewUrl } = useContext(WebViewContext);
+43 -6
View File
@@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useMemo, useRef, useState } from "react";
import {
Dimensions,
FlatList,
@@ -33,6 +33,13 @@ const PlaylistModal = (props) => {
const startAtCreate = props?.payload?.startAtCreate || false;
const { setTooltip } = useMinuit();
const isDuplicateName = useMemo(() => {
const lower = (playlist || "").trim().toLowerCase();
if (!lower) return false;
const list = Array.isArray(userPlaylists) ? userPlaylists : [];
return list.some((p) => (p?.name || "").trim().toLowerCase() === lower);
}, [playlist, JSON.stringify(userPlaylists)]);
return (
<AppActionSheet id="Playlist">
<SwiperFlatList
@@ -106,9 +113,8 @@ const PlaylistModal = (props) => {
musics: arrayUnion(projectId),
updatedAt: new Date(),
});
const addedPlaylist = (Array.isArray(userPlaylists)
? userPlaylists
: []
const addedPlaylist = (
Array.isArray(userPlaylists) ? userPlaylists : []
).find((p) => p?.id === selectedId);
const name = addedPlaylist?.name || "la playlist";
setTooltip({
@@ -118,7 +124,10 @@ const PlaylistModal = (props) => {
}
} catch (e) {
console.log("Add to playlist error", e?.message);
setTooltip({ type: "error", text: e?.message || "Ajout impossible" });
setTooltip({
type: "error",
text: e?.message || "Ajout impossible",
});
} finally {
SheetManager.hide("Playlist");
}
@@ -160,6 +169,7 @@ const PlaylistModal = (props) => {
Nommer la playlist
</Text>
<TextInput
autoFocus={true}
style={{
paddingVertical: 6,
borderBottomWidth: 1,
@@ -174,6 +184,18 @@ const PlaylistModal = (props) => {
onChangeText={setPlaylist}
textAlign="center"
/>
{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"}
@@ -188,6 +210,18 @@ const PlaylistModal = (props) => {
try {
setIsCreating(true);
const name = playlist.trim();
const lower = name.toLowerCase();
// Unicité du nom pour l'utilisateur courant (insensible à la casse)
const exists = (
Array.isArray(userPlaylists) ? userPlaylists : []
).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,
@@ -208,7 +242,10 @@ const PlaylistModal = (props) => {
scrollRef.current.scrollToIndex({ index: 0, animated: true });
} catch (e) {
console.log(e);
setTooltip({ type: "error", text: e?.message || "Création impossible" });
setTooltip({
type: "error",
text: e?.message || "Création impossible",
});
} finally {
setIsCreating(false);
}