new tickets
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useCallback, useEffect, useRef } from "react";
|
||||||
import { View, Pressable, Text } from "react-native";
|
import { View, Pressable, Text } from "react-native";
|
||||||
import { VideoView, useVideoPlayer } from "expo-video";
|
import { VideoView, useVideoPlayer } from "expo-video";
|
||||||
import { videos } from "../assets";
|
import { videos } from "../assets";
|
||||||
@@ -10,37 +10,73 @@ import { Portal } from "@gorhom/portal";
|
|||||||
// - visible?: boolean, when false returns null
|
// - visible?: boolean, when false returns null
|
||||||
// - onClose: () => void, called when user skips or when video ends
|
// - onClose: () => void, called when user skips or when video ends
|
||||||
const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
||||||
if (!visible) return null;
|
|
||||||
const source = url
|
const source = url
|
||||||
? typeof url === "string"
|
? typeof url === "string"
|
||||||
? { uri: url }
|
? { uri: url }
|
||||||
: url
|
: url
|
||||||
: videos.test;
|
: videos.test;
|
||||||
|
|
||||||
|
const hasClosedRef = useRef(false);
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
if (hasClosedRef.current) return;
|
||||||
|
hasClosedRef.current = true;
|
||||||
|
try {
|
||||||
|
onClose?.();
|
||||||
|
} catch (e) {}
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
const player = useVideoPlayer(source, (p) => {
|
const player = useVideoPlayer(source, (p) => {
|
||||||
p.loop = false;
|
p.loop = false;
|
||||||
p.timeUpdateEventInterval = 0.25;
|
p.timeUpdateEventInterval = 0.25;
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (visible) {
|
||||||
|
hasClosedRef.current = false;
|
||||||
|
} else {
|
||||||
|
hasClosedRef.current = true;
|
||||||
|
try {
|
||||||
|
player?.pause?.();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
}, [player, visible]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
player?.play?.();
|
player?.play?.();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}, [player]);
|
}, [player, visible]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!player) return;
|
if (!player || !visible) return;
|
||||||
const sub = player.addListener?.("playToEnd", () => {
|
const playToEndSub = player.addListener?.("playToEnd", handleClose);
|
||||||
try {
|
const timeUpdateSub = player.addListener?.(
|
||||||
onClose?.();
|
"timeUpdate",
|
||||||
} catch (e) {}
|
({ currentTime } = {}) => {
|
||||||
});
|
if (!player?.duration || hasClosedRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const remaining = player.duration - currentTime;
|
||||||
|
if (Number.isFinite(remaining) && remaining <= 0.1) {
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
return () => {
|
return () => {
|
||||||
try {
|
try {
|
||||||
sub?.remove?.();
|
playToEndSub?.remove?.();
|
||||||
|
timeUpdateSub?.remove?.();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
};
|
};
|
||||||
}, [player, onClose]);
|
}, [handleClose, player, visible]);
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
@@ -65,7 +101,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
|||||||
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }}
|
style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }}
|
||||||
/>
|
/>
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() => onClose?.()}
|
onPress={handleClose}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 50,
|
top: 50,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Portal } from "@gorhom/portal";
|
import { Portal } from "@gorhom/portal";
|
||||||
import { Asset } from "expo-asset";
|
import { Asset } from "expo-asset";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { Pressable, Text, View } from "react-native";
|
import { Pressable, Text, View } from "react-native";
|
||||||
|
|
||||||
const overlayStyle = {
|
const overlayStyle = {
|
||||||
@@ -56,6 +56,13 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
|||||||
const videoRef = useRef(null);
|
const videoRef = useRef(null);
|
||||||
const [uri, setUri] = useState(null);
|
const [uri, setUri] = useState(null);
|
||||||
const [muted, setMuted] = useState(false);
|
const [muted, setMuted] = useState(false);
|
||||||
|
const hasClosedRef = useRef(false);
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
if (hasClosedRef.current) return;
|
||||||
|
hasClosedRef.current = true;
|
||||||
|
onClose?.();
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isMounted = true;
|
let isMounted = true;
|
||||||
@@ -97,13 +104,15 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasClosedRef.current = false;
|
||||||
|
|
||||||
const video = videoRef.current;
|
const video = videoRef.current;
|
||||||
|
|
||||||
if (!video || !uri) {
|
if (!video || !uri) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEnded = () => onClose?.();
|
const handleEnded = handleClose;
|
||||||
video.addEventListener("ended", handleEnded);
|
video.addEventListener("ended", handleEnded);
|
||||||
|
|
||||||
video.currentTime = 0;
|
video.currentTime = 0;
|
||||||
@@ -125,7 +134,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
|||||||
video.pause();
|
video.pause();
|
||||||
video.removeEventListener("ended", handleEnded);
|
video.removeEventListener("ended", handleEnded);
|
||||||
};
|
};
|
||||||
}, [muted, onClose, uri, visible]);
|
}, [handleClose, muted, uri, visible]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const video = videoRef.current;
|
const video = videoRef.current;
|
||||||
@@ -161,7 +170,7 @@ const FullscreenIntroVideo = ({ url, visible = true, onClose }) => {
|
|||||||
controls={false}
|
controls={false}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Pressable onPress={() => onClose?.()} style={closeButtonStyle}>
|
<Pressable onPress={handleClose} style={closeButtonStyle}>
|
||||||
<Text style={closeTextStyle}>Passer la vidéo</Text>
|
<Text style={closeTextStyle}>Passer la vidéo</Text>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { View, TextInput, Image } from "react-native";
|
|
||||||
import React from "react";
|
|
||||||
import { BlurView } from "expo-blur";
|
import { BlurView } from "expo-blur";
|
||||||
|
import React from "react";
|
||||||
|
import { Image, TextInput, View } from "react-native";
|
||||||
import { icons } from "../assets";
|
import { icons } from "../assets";
|
||||||
import Style, { size } from "../styles/Style";
|
|
||||||
import { Palette } from "../styles";
|
import { Palette } from "../styles";
|
||||||
import { FONT_FAMILY } from "../styles/Fonts";
|
import { FONT_FAMILY } from "../styles/Fonts";
|
||||||
|
import Style from "../styles/Style";
|
||||||
|
|
||||||
const SearchBar = ({
|
const SearchBar = ({
|
||||||
placeholder = "Que souhaites-tu écouter?",
|
placeholder = "Que souhaites-tu écouter?",
|
||||||
@@ -13,12 +13,13 @@ const SearchBar = ({
|
|||||||
return (
|
return (
|
||||||
<View style={{ borderRadius: 12, overflow: "hidden" }}>
|
<View style={{ borderRadius: 12, overflow: "hidden" }}>
|
||||||
<BlurView
|
<BlurView
|
||||||
intensity={10}
|
intensity={80}
|
||||||
style={{
|
style={{
|
||||||
height: 40,
|
height: 40,
|
||||||
paddingHorizontal: 8,
|
paddingHorizontal: 8,
|
||||||
gap: 10,
|
gap: 10,
|
||||||
...Style.containerRow,
|
...Style.containerRow,
|
||||||
|
backgroundColor: "Palette.ultraLightBlack",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image source={icons.search} />
|
<Image source={icons.search} />
|
||||||
|
|||||||
@@ -75,10 +75,20 @@ const styles = StyleSheet.create({
|
|||||||
overlay: {
|
overlay: {
|
||||||
...StyleSheet.absoluteFillObject,
|
...StyleSheet.absoluteFillObject,
|
||||||
zIndex: 200,
|
zIndex: 200,
|
||||||
|
...Platform.select({
|
||||||
|
web: {
|
||||||
|
position: "fixed",
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
backdrop: {
|
backdrop: {
|
||||||
...StyleSheet.absoluteFillObject,
|
...StyleSheet.absoluteFillObject,
|
||||||
backgroundColor: "rgba(0, 0, 0, 0.65)",
|
backgroundColor: "rgba(0, 0, 0, 0.65)",
|
||||||
|
...Platform.select({
|
||||||
|
web: {
|
||||||
|
position: "fixed",
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
centerWrapper: {
|
centerWrapper: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const useSearch = () => {
|
|||||||
algoliaObject: AlgoliaProjectConfig,
|
algoliaObject: AlgoliaProjectConfig,
|
||||||
batch: batchSizes.projects,
|
batch: batchSizes.projects,
|
||||||
searchParams: {
|
searchParams: {
|
||||||
filters: `hasPlayback:false AND hasSong:true`,
|
filters: `hasSong:true`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ const AllMyPlaylist = () => {
|
|||||||
intensity={Platform.OS !== "ios" ? 10 : 20}
|
intensity={Platform.OS !== "ios" ? 10 : 20}
|
||||||
style={{
|
style={{
|
||||||
...Style.containerSpaceBetween,
|
...Style.containerSpaceBetween,
|
||||||
height: 59,
|
minHeight: 59,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
|
paddingVertical: 12,
|
||||||
}}
|
}}
|
||||||
// experimentalBlurMethod={
|
// experimentalBlurMethod={
|
||||||
// Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
// Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
||||||
@@ -57,9 +58,12 @@ const AllMyPlaylist = () => {
|
|||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
|
flex: 1,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Palette.white,
|
color: Palette.white,
|
||||||
fontFamily: FONT_FAMILY.InterRegular,
|
fontFamily: FONT_FAMILY.InterRegular,
|
||||||
|
marginRight: 12,
|
||||||
|
flexShrink: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item?.name || "Sans nom"}
|
{item?.name || "Sans nom"}
|
||||||
|
|||||||
@@ -120,17 +120,21 @@ const AllMyPlaylist = ({ route }) => {
|
|||||||
intensity={30}
|
intensity={30}
|
||||||
style={{
|
style={{
|
||||||
...Style.containerSpaceBetween,
|
...Style.containerSpaceBetween,
|
||||||
height: 59,
|
minHeight: 59,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 12,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
|
flex: 1,
|
||||||
fontSize: isSelected ? 18 : 16,
|
fontSize: isSelected ? 18 : 16,
|
||||||
color: Palette.white,
|
color: Palette.white,
|
||||||
fontFamily: isSelected
|
fontFamily: isSelected
|
||||||
? FONT_FAMILY.InterSemiBold
|
? FONT_FAMILY.InterSemiBold
|
||||||
: FONT_FAMILY.InterRegular,
|
: FONT_FAMILY.InterRegular,
|
||||||
|
marginRight: 12,
|
||||||
|
flexShrink: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item?.name || "Sans nom"}
|
{item?.name || "Sans nom"}
|
||||||
@@ -172,7 +176,8 @@ const AllMyPlaylist = ({ route }) => {
|
|||||||
style={{
|
style={{
|
||||||
...Style.containerSpaceBetween,
|
...Style.containerSpaceBetween,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
height: 59,
|
minHeight: 59,
|
||||||
|
paddingVertical: 12,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ const MyPlaylist = () => {
|
|||||||
intensity={Platform.OS !== "ios" ? 10 : 20}
|
intensity={Platform.OS !== "ios" ? 10 : 20}
|
||||||
style={{
|
style={{
|
||||||
...Style.containerSpaceBetween,
|
...Style.containerSpaceBetween,
|
||||||
height: 59,
|
minHeight: 59,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
|
paddingVertical: 12,
|
||||||
}}
|
}}
|
||||||
// experimentalBlurMethod={
|
// experimentalBlurMethod={
|
||||||
// Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
// Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
||||||
@@ -54,9 +55,12 @@ const MyPlaylist = () => {
|
|||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
|
flex: 1,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Palette.white,
|
color: Palette.white,
|
||||||
fontFamily: FONT_FAMILY.InterRegular,
|
fontFamily: FONT_FAMILY.InterRegular,
|
||||||
|
marginRight: 12,
|
||||||
|
flexShrink: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item?.name || "Sans nom"}
|
{item?.name || "Sans nom"}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import { Pressable, ScrollView, Text, View } from "react-native";
|
import { Pressable, ScrollView, Text, View } from "react-native";
|
||||||
import MoreMenu from "../../../components/MoreMenu";
|
import MoreMenu from "../../../components/MoreMenu";
|
||||||
import ProfilePicture from "../../../components/ProfilePicture";
|
import ProfilePicture from "../../../components/ProfilePicture";
|
||||||
@@ -70,8 +70,20 @@ const SearchResultsList = ({
|
|||||||
onResultSelected?.();
|
onResultSelected?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const musicItems = useMemo(() => {
|
||||||
|
if (!Array.isArray(musics)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected === "Musiques") {
|
||||||
|
return musics;
|
||||||
|
}
|
||||||
|
|
||||||
|
return musics.filter((project) => project?.hasPlayback !== true);
|
||||||
|
}, [musics, selected]);
|
||||||
|
|
||||||
const shouldShowMusics =
|
const shouldShowMusics =
|
||||||
(!selected && (musics.length > 0 || musicsLoading)) ||
|
(!selected && (musicItems.length > 0 || musicsLoading)) ||
|
||||||
selected === "Musiques";
|
selected === "Musiques";
|
||||||
|
|
||||||
const shouldShowPlaybacks =
|
const shouldShowPlaybacks =
|
||||||
@@ -89,10 +101,10 @@ const SearchResultsList = ({
|
|||||||
>
|
>
|
||||||
{shouldShowMusics && (
|
{shouldShowMusics && (
|
||||||
<View style={{ gap: 10 }}>
|
<View style={{ gap: 10 }}>
|
||||||
{musics.length > 0 && (
|
{musicItems.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{Array.isArray(musics) &&
|
{Array.isArray(musicItems) &&
|
||||||
musics.slice(0, 6).map((project) => (
|
musicItems.slice(0, 6).map((project) => (
|
||||||
<MusicCard
|
<MusicCard
|
||||||
key={project.id}
|
key={project.id}
|
||||||
title={project?.title || "Sans titre"}
|
title={project?.title || "Sans titre"}
|
||||||
@@ -126,7 +138,7 @@ const SearchResultsList = ({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{musics.length === 0 && !musicsLoading && (
|
{musicItems.length === 0 && !musicsLoading && (
|
||||||
<EmptyText text={"Aucune musique trouvée"} />
|
<EmptyText text={"Aucune musique trouvée"} />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ const styles = StyleSheet.create({
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
maxWidth: 420,
|
maxWidth: 420,
|
||||||
maxHeight: "80%",
|
maxHeight: "80%",
|
||||||
backgroundColor: Palette.ultraLightWhite,
|
backgroundColor: Palette.ultraLightBlack,
|
||||||
borderRadius: 20,
|
borderRadius: 20,
|
||||||
padding: 16,
|
padding: 16,
|
||||||
gap: 12,
|
gap: 12,
|
||||||
|
|||||||
Reference in New Issue
Block a user