diff --git a/next-app/app/api/remcreds/route.ts b/next-app/app/api/remcreds/route.ts new file mode 100644 index 0000000..2c9e282 --- /dev/null +++ b/next-app/app/api/remcreds/route.ts @@ -0,0 +1,86 @@ +import { authOptions } from "@/lib/auth-options"; +import prisma from "@/lib/db"; +import { getServerSession } from "next-auth"; +import { NextRequest, NextResponse } from "next/server"; + + +export const POST = async (req:NextRequest)=>{ + + try{ + const session = await getServerSession(authOptions); + if (!session?.user.id) { + return NextResponse.json( + { + message: "Unauthenticated", + }, + { + status: 403, + }, + ); + } + const data = await req.json(); + if(!data.spaceId || (typeof data.spaceId)!=="string"){ + return NextResponse.json( + { + message: "Space Id is required", + }, + { + status: 403, + }, + ); + } + // check if space exists + const space = await prisma.space.findUnique({ + where: { id: data.spaceId }, + }); + if (!space) { + return NextResponse.json( + { + message: "Space not found", + }, + { + status: 403, + }, + ); + } + // check if users creds are available + const remainingCreds = await prisma.remainingCreds.findFirst({ + where: { + userId: session.user.id, + spaceId: data.spaceId, + }, + select: { remainingCreds: true }, + }); + + if(!remainingCreds){ + return NextResponse.json( + { + message: "No Credits available", + ok:false, + } + ) + } + + return NextResponse.json( + { + message: "Credits available", + ok:true, + } + ) + } + catch(error:any){ + if (error.message === "Unauthenticated Request") { + return NextResponse.json( + { success: false, message: "You must be logged in to create a space" }, + { status: 401 } + ); + } + + + return NextResponse.json( + { success: false, message: `An unexpected error occurred: ${error.message}` }, + { status: 500 } + ); + } + +} diff --git a/next-app/components/StreamView/AddSongForm.tsx b/next-app/components/StreamView/AddSongForm.tsx index c6186b1..a4e56e3 100644 --- a/next-app/components/StreamView/AddSongForm.tsx +++ b/next-app/components/StreamView/AddSongForm.tsx @@ -1,6 +1,6 @@ import { YT_REGEX } from "@/lib/utils"; import { useSocket } from "@/context/socket-context"; -import React from "react"; +import React, { useCallback, useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Card, CardContent } from "@/components/ui/card"; @@ -20,7 +20,8 @@ type Props = { loading: boolean; enqueueToast: (type: "error" | "success", message: string) => void; spaceId:string, - isSpectator:boolean + isSpectator:boolean, + checkIsDuplicate:(url:string)=>boolean }; export default function AddSongForm({ @@ -32,11 +33,13 @@ export default function AddSongForm({ userId, spaceId, isSpectator, + checkIsDuplicate }: Props) { const { sendMessage } = useSocket(); const wallet = useWallet(); const {connection} = useConnection(); const user = useSession().data?.user; + const [duplicateDiv, setDuplicateDiv] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -55,7 +58,57 @@ export default function AddSongForm({ setInputLink(""); }; - const handlePayAndPlay = async (e: React.FormEvent) => { + const finallyPlaySong = async (songLink:string)=>{ + if(!wallet.publicKey || !connection){ + enqueueToast("error", "Please connect your wallet"); + return; + } + // check if user creds for this space is pending or not + const response = await fetch(`/api/remcreds`,{ + method:"POST", + body:JSON.stringify({ + spaceId:spaceId, + }) + }); + const data = await response.json(); + + if(!data.ok){ + const transaction = new Transaction(); + transaction.add( + SystemProgram.transfer({ + fromPubkey: wallet.publicKey, + toPubkey: new PublicKey(process.env.NEXT_PUBLIC_PUBLICKEY as string), + lamports: Number(process.env.NEXT_PUBLIC_SOL_PER_PAYMENT) * LAMPORTS_PER_SOL, + }) + ) + + // sign Transaction steps + const blockHash = await connection.getLatestBlockhash(); + transaction.feePayer = wallet.publicKey; + transaction.recentBlockhash = blockHash.blockhash; + //@ts-ignore + const signed = await wallet.signTransaction(transaction); + + + const signature = await connection.sendRawTransaction(signed.serialize()); + + enqueueToast("success", `Transaction signature: ${signature}`); + await connection.confirmTransaction({ + blockhash: blockHash.blockhash, + lastValidBlockHeight: blockHash.lastValidBlockHeight, + signature + }); + enqueueToast("success", `Payment successful`); + } + + sendMessage("pay-and-play-next", { + spaceId, + userId: user?.id, + url:songLink + }); + } + + const handlePayAndPlay = useCallback(async (e: React.FormEvent) => { e.preventDefault(); if(!wallet.publicKey || !connection){ @@ -67,44 +120,31 @@ export default function AddSongForm({ } try{ setLoading(true); - const transaction = new Transaction(); - transaction.add( - SystemProgram.transfer({ - fromPubkey: wallet.publicKey, - toPubkey: new PublicKey(process.env.NEXT_PUBLIC_PUBLICKEY as string), - lamports: Number(process.env.NEXT_PUBLIC_SOL_PER_PAYMENT) * LAMPORTS_PER_SOL, - }) - ) - - // sign Transaction steps - const blockHash = await connection.getLatestBlockhash(); - transaction.feePayer = wallet.publicKey; - transaction.recentBlockhash = blockHash.blockhash; - //@ts-ignore - const signed = await wallet.signTransaction(transaction); - - const signature = await connection.sendRawTransaction(signed.serialize()); - - enqueueToast("success", `Transaction signature: ${signature}`); - await connection.confirmTransaction({ - blockhash: blockHash.blockhash, - lastValidBlockHeight: blockHash.lastValidBlockHeight, - signature - }); - enqueueToast("success", `Payment successful`); - sendMessage("pay-and-play-next", { - spaceId, - userId: user?.id, - url:inputLink - }); + //check if it is duplicate or not if it is accepted by user then play + if(checkIsDuplicate(inputLink)){ + + if(!duplicateDiv){ + setDuplicateDiv(true); + return; + } + if(duplicateDiv){ + + setDuplicateDiv(false); + await finallyPlaySong(inputLink); + setLoading(false); + } + return; + } + await finallyPlaySong(inputLink); + } catch(error){ enqueueToast("error", `Payment unsuccessful`); } setLoading(false); - }; + },[ duplicateDiv,wallet , connection, inputLink]); const videoId = inputLink ? inputLink.match(YT_REGEX)?.[1] : undefined; @@ -114,13 +154,31 @@ export default function AddSongForm({

Add a song

-
+ setInputLink(e.target.value)} /> + { duplicateDiv && +
+

Duplicate Song

+ + +
+ }