import { useEffect, useState } from "react"; import { getAllStreams } from "../util/db"; import { formatSeconds, tsToDate, getDaysBetween, getDaysAfter, dateToTs } from "../util/time"; import RangeSlider from "react-range-slider-input"; import "react-range-slider-input/dist/style.css"; import type { stream } from "../model/types"; import { getFirstStreamDate, getLastStreamDate, getListenedTracks, getListenedArtists } from "../model/parser"; import { useNavigate } from "react-router-dom"; import { ArrowLeft as Back } from "lucide-react"; const StatView = () => { const [streams, setStreams] = useState([]); const [mostListenedSongs, setMostListenedSongs] = useState([]); const [mostListenedArtists, setMostListenedArtists] = useState([]); const [dateRange, setDateRange] = useState<[Date, Date]>([new Date(), new Date()]); const [firstStreamDate, setFirstStreamDate] = useState(); const [lastStreamDate, setLastStreamDate] = useState(); const [dynamicBackgrounds, setDynamicBackgrounds] = useState(false); const navigate = useNavigate(); useEffect(() => { getAllStreams() .then((streams) => { setStreams(streams); if (streams.length > 0) { const firstDate = tsToDate(getFirstStreamDate(streams)); const lastDate = tsToDate(getLastStreamDate(streams)); setFirstStreamDate(firstDate); setLastStreamDate(lastDate); setDateRange([firstDate, lastDate]); } }) .catch((error) => { console.error("Error fetching streams:", error); }); }, []); useEffect(() => { setMostListenedSongs(getListenedTracks(streams, dateToTs(dateRange[0]), dateToTs(dateRange[1]), 100)); setMostListenedArtists(getListenedArtists(streams, dateToTs(dateRange[0]), dateToTs(dateRange[1]), 100)); }, [dateRange]); if (streams.length === 0 || !firstStreamDate || !lastStreamDate) { return
Loading...
; } const stringToHash = (str: string) => { if (!str) return 0; let hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; // Convert to 32-bit integer } return Math.abs(hash); }; return (
navigate(-1)} />

Track Statistics

    {mostListenedSongs.map((track, index) => (
  • {index + 1}. {track.master_metadata_track_name}
    {formatSeconds(track.ms_played / 1000)}
  • ))}

Artist Statistics

    {mostListenedArtists.map((artist, index) => (
  • {index + 1}. {artist.master_metadata_album_artist_name}
    {formatSeconds(artist.ms_played / 1000)}
  • ))}
{ const startDate = getDaysAfter(firstStreamDate, value[0]); const endDate = getDaysAfter(firstStreamDate, value[1]); setDateRange([startDate, endDate]); }} className="w-full" />
{ if (new Date(e.target.value) > dateRange[1]) { alert("Start date cannot be after end date"); return; } // check if valid date if (isNaN(new Date(e.target.value).getTime())) { return; } setDateRange([new Date(e.target.value), dateRange[1]]); }} className="mr-2" /> { if (new Date(e.target.value) < dateRange[0]) { alert("End date cannot be before start date"); return; } // check if valid date if (isNaN(new Date(e.target.value).getTime())) { return; } setDateRange([dateRange[0], new Date(e.target.value)]); }} className="ml-2" />

({getDaysBetween(dateRange[0], dateRange[1])} days)

); }; export default StatView;