TwitchClone / src / components / uploadContent / index.tsx
index.tsx
Raw
import { useState } from "react";
import * as UpChunk from "@mux/upchunk";
import { api } from "../../utils/api";
import { v4 } from "uuid";
import { useRoomDataContext } from "../../utils/context/RoomDataContext";

type ErrorResponse = {
  detail: {
    message: string;
  };
};

type ProgressEvent = {
  detail: number;
};

const FileUpload = () => {
  const [progress, setProgress] = useState(0);
  const [statusMessage, setStatusMessage] = useState<string | null>(null);
  const [uploadId, setUploadId] = useState<string>("");
  const [uploadUrl, setUploadUrl] = useState<string>("");
  const [errorMessage, setErrorMessage] = useState("");
  const createVideoMutation = api.lambda.createVideo.useMutation();
  const createUserVideoMutation = api.lambda.createUserVideo.useMutation();
  let dataT = {
    id: "",
    url: "",
    assetId: "",
  };
  const [uploadForUser, setUploadForUser] = useState(false);
  const [userId, setUserId] = useState<string>("");
  const { roomData, setRoomData, userData, setUserData } = useRoomDataContext();
  const uuid_ = v4();
  console.log(uuid_, "uploader");
  if (!roomData) return <div>No room data</div>;
  const handleUpload = (inputRef: EventTarget & HTMLInputElement) => {
    try {
      const createUpload = async () => {
        try {
          return fetch(`/api/upload-video?input=${uuid_}`, {
            method: "POST",
          })
            .then((res) => res.json())
            .then(
              ({
                roomId,
                url,
                assetId,
              }: {
                roomId: string;
                url: string;
                assetId: string;
              }) => {
                console.log(roomId, url, assetId, "uploader");
                setUploadId(roomId);
                setRoomData((prev) => {
                  if (!prev) return null;
                  return {
                    ...prev,
                    streamerInfo: dataT,
                  };
                });
                setUploadUrl(url);
                dataT = { id: roomId, url, assetId }; //uuid is id here
                console.log(dataT, "uploader");
                return { url, roomId };
              }
            );
        } catch (e) {
          console.error("Error in createUpload", e);
          setErrorMessage("Error creating upload");
        }
      };
      const upload = UpChunk.createUpload({
        endpoint: () =>
          createUpload().then((url) => {
            console.log(url, inputRef.files, uploadId, uploadUrl, "uploader");
            return url?.url ?? "";
            //@@ts-ignore   // eslint-disable-next-line
          }),
        file: inputRef.files?.[0] as File,
        chunkSize: 5120,
      });
      console.log(upload, "uploader");
      upload.on("error", (err: ErrorResponse) => {
        setErrorMessage(err.detail.message);
      });

      upload.on("progress", (progress: ProgressEvent) => {
        setProgress(Math.floor(progress.detail));
      });

      upload.on("success", (res) => {
        console.log(uploadId, uploadUrl, "uploader");
        // Get the Asset using the uploadId
        // const asset = await fetch(`/api/get-asset?uploadId=${uploadId}`).then(
        //   (res) => res.json()
        // );
        // const playbackId = asset.playback_ids[0].id;
        console.log(uploadForUser, roomData, "playbackId");
        if (!roomData.streamerInfo) {
          console.log("no streamer id");
        }
        console.log(
          {
            userId: userId,
            roomId: dataT.id,
            playbackId: dataT.id,
            streamKey: "",
            assetId: dataT.assetId,
          },
          "verify upload"
        );
        if (uploadForUser && roomData) {
          console.log("uploadForUser", roomData.streamerId);
          createUserVideoMutation.mutate(
            {
              userId: userId,
              roomId: dataT.id,
              playbackId: dataT.id,
              streamKey: "",
              assetId: dataT.assetId,
              uuid: dataT.id,
            },
            {
              onSuccess: () => {
                const content = api.lambda.fetchAllContent.useQuery();
                console.log(content, "content");
                return content;
              },
            }
          );
        } else {
          createVideoMutation.mutate(
            { playbackId: dataT.id, streamKey: "", assetId: dataT.assetId },
            {
              onSuccess: () => {
                const content = api.lambda.fetchAllContent.useQuery();
                console.log(content, "content");
                return content;
              },
            }
          );
        }
      });
    } catch (error: any) {
      //@@ts-ignore  // eslint-disable-next-line
      if (error instanceof Error) {
        setStatusMessage(error.message);
      } else {
        setStatusMessage("Something went wrong");
      }
    }
  };

  if (statusMessage) {
    console.log(statusMessage, "upload error");
  }

  return (
    <div className="file-upload">
      <label htmlFor="file-picker">Select a video file:</label>
      <input
        type="file"
        onChange={(e) => handleUpload(e.target)}
        id="file-picker"
        name="file-picker"
      />
      <label htmlFor="upload-progress">Uploading progress:</label>
      <progress value={progress} max="100" />
      <em>{statusMessage}</em>
      <label>
        Upload for a specific user:
        <input
          type="checkbox"
          checked={uploadForUser}
          onChange={(e) => setUploadForUser(e.target.checked)}
        />
      </label>
      {uploadForUser && (
        <div>
          <label htmlFor="user-id">User ID:</label>
          <input
            type="text"
            id="user-id"
            name="user-id"
            value={userId}
            onChange={(e) => setUserId(e.target.value)}
          />
        </div>
      )}
    </div>
  );
};

export default FileUpload;