All files / Rindu/components/CardContentContextMenu CardContentContextMenu.tsx

100% Statements 24/24
100% Branches 8/8
100% Functions 5/5
100% Lines 24/24

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 10219x   19x   19x   19x 19x     19x           19x 19x                         19x     1x             11x     11x 11x 11x 11x   11x   11x 2x 2x                           1x         1x                       1x 1x           1x                      
import { ReactElement, useCallback } from "react";
 
import { useRouter } from "next/router";
 
import { EmbedModal } from "components";
import { CardType } from "components/CardContent";
import { useContextMenu, useToast, useTranslations } from "hooks";
import { menuContextStyles } from "styles/menuContextStyles";
import { ICardContentContextMenuData } from "types/contextMenu";
import { Modify } from "types/customTypes";
import { getSiteUrl, handleAsyncError, templateReplace } from "utils";
import {
  follow,
  followAlbums,
  followPlaylist,
  saveShowsToLibrary,
} from "utils/spotifyCalls";
import { Follow_type } from "utils/spotifyCalls/follow";
 
type SaveFunctionTypes =
  | CardType.ALBUM
  | CardType.PLAYLIST
  | CardType.ARTIST
  | CardType.SHOW;
 
type SaveFunctions = Modify<
  Partial<Record<CardType, never>>,
  Record<SaveFunctionTypes, (id: string) => Promise<boolean | null>>
>;
 
const saveFunctions: SaveFunctions = {
  album: followAlbums,
  show: saveShowsToLibrary,
  artist: (id: string) => follow(Follow_type.Artist, id),
  playlist: followPlaylist,
};
 
export interface ICardContentContextMenu {
  data: ICardContentContextMenuData["data"];
}
export default function CardContentContextMenu({
  data,
}: Readonly<ICardContentContextMenu>): ReactElement {
  const { removeContextMenu, setModalData } = useContextMenu();
  const router = useRouter();
  const { addToast } = useToast();
  const { translations } = useTranslations();
 
  const saveFunction = saveFunctions[data.type];
 
  const handleGoToClick = useCallback(async () => {
    removeContextMenu();
    await router.push(`${getSiteUrl()}/${data.type || "track"}/${data.id}`);
  }, [data.id, data.type, removeContextMenu, router]);
 
  return (
    <ul>
      <li>
        <button type="button" onClick={handleAsyncError(handleGoToClick)}>
          Go to {data.type || "track"}
        </button>
      </li>
      {data.type && data.type !== "genre" && data.id && (
        <li>
          <button
            onClick={() => {
              setModalData({
                title: `Embed ${data.type}`,
                modalElement: <EmbedModal type={data.type} id={data.id} />,
                maxHeight: "100%",
              });
              removeContextMenu();
            }}
          >
            Embed {data.type}
          </button>
        </li>
      )}
      {saveFunction && (
        <li>
          <button
            type="button"
            onClick={() => {
              saveFunction(data.id);
              addToast({
                message: templateReplace(translations.toastMessages.addedTo, [
                  translations.contentType.library,
                ]),
                variant: "success",
              });
              removeContextMenu();
            }}
          >
            Save {data.type}
          </button>
        </li>
      )}
      <style jsx>{menuContextStyles}</style>
    </ul>
  );
}