All files / Rindu/components/TrackListHeader TrackListHeader.tsx

21.05% Statements 4/19
0% Branches 0/24
0% Functions 0/5
21.05% Lines 4/19

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 115 116 117 118 119 120 121 122 123 124                19x   19x 19x 19x                                                                                                                                                                                                                              
import {
  Dispatch,
  MutableRefObject,
  ReactElement,
  SetStateAction,
  useEffect,
  useRef,
  useState,
} from "react";
 
import { CardType } from "components/CardTrack";
import { Clock } from "components/icons";
import { useOnSmallScreen, useTranslations } from "hooks";
 
export default function TrackListHeader({
  isPin,
  setIsPin,
  type: cardType,
}: Readonly<{
  isPin: boolean;
  setIsPin: Dispatch<SetStateAction<boolean>>;
  type: CardType;
}>): ReactElement {
  const ref = useRef<HTMLDivElement>();
  const { translations } = useTranslations();
  const [type, setType] = useState<CardType>(cardType);
 
  const isSmallScreen = useOnSmallScreen((isSmall) => {
    setType(isSmall ? CardType.Presentation : cardType);
  });
 
  useEffect(() => {
    const cachedRef = ref.current,
      observer = new IntersectionObserver(
        ([e]) => {
          if (e.intersectionRect.top >= 59) {
            setIsPin(true);
          } else {
            setIsPin(false);
          }
        },
        {
          rootMargin: `0px 0px -${Math.max(0, (window.innerHeight || 0) - 60)}px 0px`,
        }
      );
 
    observer.observe(cachedRef as Element);
 
    return function () {
      observer.unobserve(cachedRef as Element);
    };
  });
 
  return (
    <div
      className="trackListHeader"
      ref={ref as MutableRefObject<HTMLDivElement>}
    >
      <span>#</span>
      <span>{translations.playlistHeader.title}</span>
      {type === "playlist" ? (
        <>
          <span className="album">{translations.playlistHeader.album}</span>
          <span className="dataAdded">
            {translations.playlistHeader.dateAdded}
          </span>
        </>
      ) : null}
      <span className="emptynow"></span>
      <span className="clock">
        <Clock />
      </span>
      <style jsx>{`
        .trackListHeader {
          border-bottom: 1px solid transparent;
          box-sizing: content-box;
          height: 36px;
          margin: ${isPin ? "0 -32px 8px" : "0 -16px 8px"};
          padding: ${isPin ? "0 32px" : "0 16px"};
          position: sticky;
          top: 60px;
          z-index: 2;
          display: grid;
          grid-gap: 16px;
          background-color: ${isPin ? "#181818" : "transparent"};
          border-bottom: 1px solid #ffffff1a;
          grid-template-columns: ${type === "playlist"
            ? "[index] 48px [first] 14fr [var1] 8fr [var2] 3fr [popularity] 1fr [last] minmax(180px,2fr)"
            : type === "album"
              ? "[index] 48px [first] 14fr [popularity] 1fr [last] minmax(180px,2fr)"
              : "[index] 55px [first] 14fr [popularity] 1fr [last] minmax(180px,2fr)"};
        }
        .trackListHeader span {
          display: flex;
          align-items: center;
          font-size: 0.75rem;
          color: #ffffffb3;
          font-family: sans-serif;
        }
        .trackListHeader span:nth-of-type(1) {
          font-size: 16px;
          justify-self: center;
          margin-left: 16px;
        }
        .trackListHeader span:nth-of-type(2) {
          margin-left: ${isSmallScreen ? "0" : "70px"};
        }
        .clock {
          justify-content: center;
        }
        @media (max-width: 768px) {
          .trackListHeader {
            grid-template-columns: ${type === "playlist"
              ? "[index] 48px [first] 14fr [var1] 8fr [var2] 3fr [popularity] 1fr [last] minmax(60px,2fr)"
              : type === "album"
                ? "[index] 48px [first] 14fr [popularity] 1fr [last] minmax(60px,2fr)"
                : "[index] 55px [first] 14fr [popularity] 1fr [last] minmax(60px,2fr)"};
          }
        }
      `}</style>
    </div>
  );
}