All files / Rindu/components/VirtualizedList PlaylistsList.tsx

11.36% Statements 5/44
0% Branches 0/12
0% Functions 0/8
11.62% Lines 5/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 11519x       19x 19x 19x 19x                                                                                                                                                                                                                      
import { ReactElement, useCallback, useEffect, useState } from "react";
 
import { IndexRange } from "react-virtualized";
 
import VirtualizedList from "./VirtualizedList";
import LoadingSpinner from "components/LoadingSpinner";
import PlaylistText from "components/PlaylistText";
import { getUserPlaylists } from "utils/spotifyCalls";
 
export function PlaylistsList(): ReactElement {
  const [playlists, setPlaylists] = useState<
    SpotifyApi.PlaylistObjectSimplified[] | null
  >(null);
  const [totalPlaylists, setTotalPlaylists] = useState<number>(0);
  const [isLoading, setIsLoading] = useState(true);
 
  useEffect(() => {
    const fetchInitialPlaylists = async () => {
      try {
        const response = await getUserPlaylists(0);
 
        Iif (response?.items) {
          const initialPlaylists = response.items;
 
          setPlaylists(initialPlaylists);
          setTotalPlaylists(response.total);
        }
      } catch (error) {
        console.error("Error loading initial playlists:", error);
      } finally {
        setIsLoading(false);
      }
    };
 
    fetchInitialPlaylists();
  }, []);
 
  const splicePlaylists = useCallback(
    (
      allPlaylists: SpotifyApi.PlaylistObjectSimplified[] | null,
      newPlaylists: SpotifyApi.PlaylistObjectSimplified[],
      position: number
    ): SpotifyApi.PlaylistObjectSimplified[] => {
      Iif (!allPlaylists) {
        return [...newPlaylists];
      }
      const updatedPlaylists = [...allPlaylists];
      updatedPlaylists.splice(position, 50, ...newPlaylists);
      return updatedPlaylists;
    },
    []
  );
 
  const loadMorePlaylists = useCallback(
    async ({ startIndex }: IndexRange) => {
      Iif (startIndex === 0) return;
 
      try {
        const offset = Math.floor(startIndex / 50) * 50;
 
        const response = await getUserPlaylists(offset);
 
        Iif (response?.items) {
          const newPlaylists = response.items;
 
          setPlaylists((currentPlaylists) =>
            splicePlaylists(currentPlaylists, newPlaylists, startIndex)
          );
 
          Iif (startIndex === 0) {
            setTotalPlaylists(response.total);
          }
        }
      } catch (error) {
        console.error("Error loading playlists:", error);
      }
    },
    [splicePlaylists]
  );
 
  const isItemLoaded = useCallback(
    (index: number) => {
      return !!playlists?.[index]?.uri;
    },
    [playlists]
  );
 
  Iif (isLoading) {
    return <LoadingSpinner />;
  }
 
  return (
    <div style={{ width: "100%" }}>
      <VirtualizedList
        scrollElementSelector="#left .simplebar-content-wrapper"
        items={playlists}
        totalItems={totalPlaylists}
        itemHeight={26}
        loadMoreItems={loadMorePlaylists}
        isItemLoaded={isItemLoaded}
        renderItem={({ key, item: playlist, style }) => (
          <PlaylistText
            key={key}
            style={style}
            id={playlist?.id ?? ""}
            uri={playlist?.uri ?? ""}
            name={playlist?.name ?? ""}
            type={"playlist"}
          />
        )}
      />
    </div>
  );
}