diff --git a/src/screens/HitParade/HitParade.js b/src/screens/HitParade/HitParade.js index 78a1293..7b9aa64 100644 --- a/src/screens/HitParade/HitParade.js +++ b/src/screens/HitParade/HitParade.js @@ -1,27 +1,23 @@ -import { View, Text, Image, Pressable, FlatList } from "react-native"; import React, { useState } from "react"; -import Page from "../../layouts/Page"; +import { FlatList, Image, Pressable, Text, View } from "react-native"; +import { responsiveHeight } from "react-native-responsive-dimensions"; import { background, icons } from "../../assets"; -import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader"; +import BorderGradientButton from "../../components/BorderGradientButton"; +import { projectsRef } from "../../config/firebase"; +import useDataFromRef from "../../hooks/useDataFromRef"; +import Page from "../../layouts/Page"; +import { Routes } from "../../navigation"; +import { navigate } from "../../navigation/NavigationService"; import { Palette, Style } from "../../styles"; import { FONT_FAMILY } from "../../styles/Fonts"; -import BorderGradientButton from "../../components/BorderGradientButton"; -import SongCard from "./components/SongCard"; -import { responsiveHeight } from "react-native-responsive-dimensions"; +import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader"; import PlaybacksCard from "./components/PlaybacksCard"; -import firebase from "../../config/firebase"; -import useDataFromRef from "../../hooks/useDataFromRef"; -import { navigate } from "../../navigation/NavigationService"; -import { Routes } from "../../navigation"; +import SongCard from "./components/SongCard"; const HitParade = () => { const [selected, setSelected] = useState("Chansons"); const { data: latestSongs } = useDataFromRef({ - ref: firebase - .firestore() - .collection("projects") - .orderBy("createdAt", "desc") - .limit(10), + ref: projectsRef.orderBy("createdAt", "desc").limit(10), simpleRef: false, listener: true, condition: true, @@ -102,7 +98,9 @@ const HitParade = () => { title={item?.title || "Sans titre"} artist={"MusicLand"} coverUrl={item?.coverUrl || null} - onPress={() => navigate(Routes.MusicDetails, { projectId: item.id })} + onPress={() => + navigate(Routes.MusicDetails, { projectId: item.id }) + } /> )} /> diff --git a/src/screens/Library/MusicDetails.js b/src/screens/Library/MusicDetails.js index 65cda5c..65b3a34 100644 --- a/src/screens/Library/MusicDetails.js +++ b/src/screens/Library/MusicDetails.js @@ -16,6 +16,7 @@ import Slider from "../../components/Slider"; import firebase, { arrayRemove, arrayUnion, + increment, projectsRef, usersRef, } from "../../config/firebase"; @@ -25,6 +26,9 @@ import { Palette } from "../../styles"; import { FONT_FAMILY } from "../../styles/Fonts"; import Style, { gutters, size } from "../../styles/Style"; +// 20 secondes +const timeBeforeIncrement = 20000; + const MusicDetails = () => { const params = useRoute().params || {}; const action = params?.action; @@ -34,6 +38,9 @@ const MusicDetails = () => { const [isPlaying, setIsPlaying] = useState(false); const [progressInfo, setProgressInfo] = useState({ pos: 0, dur: 0 }); const wasPlayingBeforeSeek = React.useRef(false); + const listenedMsRef = React.useRef(0); + const incrementDoneRef = React.useRef(false); + const timerRef = React.useRef(null); const { data: project } = useDataFromRef({ ref: projectId @@ -82,6 +89,9 @@ const MusicDetails = () => { soundRef.current.setOnPlaybackStatusUpdate(null); soundRef.current = null; } + // Reset listen tracking per song load + listenedMsRef.current = 0; + incrementDoneRef.current = false; if (!songUrl) return; const { sound } = await Audio.Sound.createAsync( { uri: songUrl }, @@ -115,6 +125,40 @@ const MusicDetails = () => { }; }, [songUrl]); + // Start/stop a timer to accumulate listened milliseconds while playing + useEffect(() => { + const clearTimer = () => { + if (timerRef.current) { + global.clearInterval(timerRef.current); + timerRef.current = null; + } + }; + if (isPlaying && projectId) { + if (!timerRef.current) { + timerRef.current = global.setInterval(async () => { + try { + listenedMsRef.current += 500; + if ( + !incrementDoneRef.current && + listenedMsRef.current >= timeBeforeIncrement && + projectId + ) { + incrementDoneRef.current = true; + await projectsRef + .doc(projectId) + .set({ views: increment(1) }, { merge: true }); + } + } catch (e) { + // Silent fail for counter + } + }, 500); + } + } else { + clearTimer(); + } + return clearTimer; + }, [isPlaying, projectId]); + const fmt = (ms) => { const total = Math.max(0, Math.floor((ms || 0) / 1000)); const m = Math.floor(total / 60)