like playbacks
This commit is contained in:
@@ -6,13 +6,15 @@ import { Image, Platform, Pressable, Text, View } from "react-native";
|
|||||||
import Carousel from "react-native-reanimated-carousel";
|
import Carousel from "react-native-reanimated-carousel";
|
||||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||||
import { icons, img } from "../assets";
|
import { icons, img } from "../assets";
|
||||||
import { projectsRef } from "../config/firebase";
|
import { arrayRemove, arrayUnion, projectsRef } from "../config/firebase";
|
||||||
import useDataFromRef from "../hooks/useDataFromRef";
|
import useDataFromRef from "../hooks/useDataFromRef";
|
||||||
|
import { useUser } from "../providers/UserDataProvider";
|
||||||
import { Palette } from "../styles";
|
import { Palette } from "../styles";
|
||||||
import { FONT_FAMILY } from "../styles/Fonts";
|
import { FONT_FAMILY } from "../styles/Fonts";
|
||||||
import { size } from "../styles/Style";
|
import { size } from "../styles/Style";
|
||||||
|
|
||||||
const PlaybackItem = ({ item, isActive }) => {
|
const PlaybackItem = ({ item, isActive }) => {
|
||||||
|
const { currentUID } = useUser() || {};
|
||||||
const videoUrl = item?.playbackUrl || null;
|
const videoUrl = item?.playbackUrl || null;
|
||||||
const audioSource = useMemo(() => {
|
const audioSource = useMemo(() => {
|
||||||
const fromSong = item?.songUrl ? { uri: item.songUrl } : null;
|
const fromSong = item?.songUrl ? { uri: item.songUrl } : null;
|
||||||
@@ -20,12 +22,24 @@ const PlaybackItem = ({ item, isActive }) => {
|
|||||||
}, [item]);
|
}, [item]);
|
||||||
|
|
||||||
const hasExternalAudio = !!audioSource;
|
const hasExternalAudio = !!audioSource;
|
||||||
|
|
||||||
|
const initialLikedBy = Array.isArray(item?.likedBy) ? item.likedBy : [];
|
||||||
|
const [isLiked, setIsLiked] = useState(
|
||||||
|
currentUID ? initialLikedBy.includes(currentUID) : false
|
||||||
|
);
|
||||||
|
const [likesCount, setLikesCount] = useState(initialLikedBy.length);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const lb = Array.isArray(item?.likedBy) ? item.likedBy : [];
|
||||||
|
setLikesCount(lb.length);
|
||||||
|
setIsLiked(currentUID ? lb.includes(currentUID) : false);
|
||||||
|
}, [item?.likedBy, currentUID]);
|
||||||
console.log("has external audio : ", hasExternalAudio);
|
console.log("has external audio : ", hasExternalAudio);
|
||||||
|
|
||||||
const audioPlayer = useAudioPlayer(audioSource || undefined);
|
const audioPlayer = useAudioPlayer(audioSource || undefined);
|
||||||
const videoPlayer = useVideoPlayer(videoUrl || null, (p) => {
|
const videoPlayer = useVideoPlayer(videoUrl || null, (p) => {
|
||||||
p.loop = false; // vidéo et musique ont la même durée
|
p.loop = false;
|
||||||
p.muted = !!hasExternalAudio; // mute seulement si audio externe
|
p.muted = true;
|
||||||
p.timeUpdateEventInterval = 0.2;
|
p.timeUpdateEventInterval = 0.2;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -157,12 +171,50 @@ const PlaybackItem = ({ item, isActive }) => {
|
|||||||
</BlurView>
|
</BlurView>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</View>
|
</View>
|
||||||
<Pressable>
|
<Pressable
|
||||||
|
onPress={async () => {
|
||||||
|
try {
|
||||||
|
if (!currentUID || !item?.id) return;
|
||||||
|
const nextLiked = !isLiked;
|
||||||
|
setIsLiked(nextLiked);
|
||||||
|
setLikesCount((c) => Math.max(0, c + (nextLiked ? 1 : -1)));
|
||||||
|
|
||||||
|
const ref = projectsRef.doc(item.id);
|
||||||
|
await ref.set(
|
||||||
|
{
|
||||||
|
likedBy: nextLiked
|
||||||
|
? arrayUnion(currentUID)
|
||||||
|
: arrayRemove(currentUID),
|
||||||
|
// Optionally: updatedAt could be set if needed
|
||||||
|
},
|
||||||
|
{ merge: true }
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// rollback on failure
|
||||||
|
setIsLiked((v) => !v);
|
||||||
|
setLikesCount((c) => (isLiked ? c + 1 : Math.max(0, c - 1)));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
style={{ alignItems: "center" }}
|
||||||
|
>
|
||||||
<Image
|
<Image
|
||||||
source={icons.heartOutline}
|
source={isLiked ? icons.heart : icons.heartOutline}
|
||||||
style={size({ size: 26 })}
|
style={size({ size: 26 })}
|
||||||
resizeMode="contain"
|
resizeMode="contain"
|
||||||
/>
|
/>
|
||||||
|
{!!likesCount && (
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: Palette.white,
|
||||||
|
fontSize: 11,
|
||||||
|
marginTop: 4,
|
||||||
|
fontFamily: FONT_FAMILY.InterMedium,
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{likesCount}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</Pressable>
|
</Pressable>
|
||||||
<Pressable>
|
<Pressable>
|
||||||
<Image source={icons.share} style={size({ size: 26 })} />
|
<Image source={icons.share} style={size({ size: 26 })} />
|
||||||
|
|||||||
Reference in New Issue
Block a user