From e6ce73a39c5b745d082391ad71e931c4a98a6d8c Mon Sep 17 00:00:00 2001 From: 12core1 <12533753+visnkmr@users.noreply.github.com> Date: Thu, 14 Dec 2023 22:42:32 +0530 Subject: [PATCH] added send over internet option with webrtc --- package.json | 2 + src/components/initui.tsx | 10 +- src/components/sow.tsx | 448 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 src/components/sow.tsx diff --git a/package.json b/package.json index 225aeb0..6aafa5b 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "class-variance-authority": "^0.7.0", "fastest-levenshtein": "^1.0.16", "fuse.js": "^7.0.0", + "js-file-download": "^0.4.12", "next-optimized-images": "3.0.0-canary.10", "next-pwa": "^5.6.0", "react-fast-marquee": "^1.6.0", @@ -78,6 +79,7 @@ "react-lazy-load-image-component": "^1.6.0", "react-toastify": "^9.1.3", "react-wrap-balancer": "^1.0.0", + "simple-peer": "^9.11.1", "toast-notification-js": "^1.0.3" } } diff --git a/src/components/initui.tsx b/src/components/initui.tsx index ce76b20..a279998 100644 --- a/src/components/initui.tsx +++ b/src/components/initui.tsx @@ -15,6 +15,7 @@ import axios from "axios" import { Appslist } from './appslist'; import { DataTable } from './commits/data-table'; import { columns_full } from './commits/columns_full'; +import Sow from './sow'; // let ft = (ipaddress:string):returnedjson=>{ // let { data,isError } = useQuery({ // // enabled:false, @@ -52,7 +53,8 @@ export default function InitUI(){ const [toastv] = useGlobalState("toast-visible"); const [tablev] = useGlobalState("table-visible"); const [toastcontent] = useGlobalState("toast"); - const [ufvis,setufvis] = useState(true); + const [ufvis,setufvis] = useState(false); + const [sowvis,setsowvis] = useState(false); const [salvis,setsalvis] = useState(false); // const [helpvis,sethvis] = useState(false); const searchParams = useSearchParams(); @@ -272,6 +274,7 @@ export default function InitUI(){
+ @@ -327,6 +330,11 @@ export default function InitUI(){
+
+
+ + +
diff --git a/src/components/sow.tsx b/src/components/sow.tsx new file mode 100644 index 0000000..77a222b --- /dev/null +++ b/src/components/sow.tsx @@ -0,0 +1,448 @@ +'use client' +import React, { useEffect, useRef } from 'react' +import axios from "axios"; +import { Button } from './ui/button'; +// import './src/app/globals.css' + +// import nodeDatachannelPolyfill from 'node-datachannel/polyfill'; +import { useState } from 'react' +// import { createRequire } from 'module'; +// import wrtc from "wrtc" + +import Peer from 'simple-peer' +// import Ably from "ably" +import download from "js-file-download" +export enum MessageTypeDesc { + FILE = 'FILE', + OTHER = 'OTHER' + +} +function submittodb(id:string,listtosave:object){ + console.log("whenhere:\n"+JSON.stringify(listtosave)) + + return axios.request({ + url: `https://listallfrompscale.vercel.app/api/putredis/`, + method: 'POST', + data: {id: id, value: JSON.stringify(listtosave)}, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } +}) +// .then(response => { +// console.log(response) +// // value="\nsaved selected tab(s)\t"; +// // +title.substring(0,30); +// // response.json() +// } +// ) +// // .then(data => { +// // // Do something with the response data +// // console.log(data); +// // }) +// .catch(error => { +// // Handle any errors +// console.error(error); +// }); +} +function getfromdb(id:string){ + // console.log("whenhere:\n"+JSON.stringify(listtosave)) + + return axios.request({ + url: `https://listallfrompscale.vercel.app/api/getvalue/${id}`, + method: 'GET', + // data: {id: id, value: JSON.stringify(listtosave)}, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } +}) +// .then(response => { +// console.log(JSON.parse(response.data.data)) +// // value="\nsaved selected tab(s)\t"; +// // +title.substring(0,30); +// // response.json() +// } +// ) +// .then(data => { +// // Do something with the response data +// console.log(data); +// }) +// .catch(error => { +// // Handle any errors +// console.error(error); +// }); +} +// import { v4 as uuidv4 } from 'uuid'; + +// import { createClient } from "@vercel/kv"; + +export interface DataTypeDesc { + dataType: MessageTypeDesc + file?: Blob + fileName?: string + fileType?: string + message?: string +} +const de=true; +export const dlfd =(m)=>{ + if(de){ + + console.log(m) + } +} +export default function Sow(){ + const [sdp, setSdp] = useState('') + // const [channel, setchannel] = useState() + // var channel:Ably.Types.RealtimeChannelPromise; + // const [offer, setoffer] = useState('') + // const [answer, setanswer] = useState('') + // const [amitheinitiator, setinitiator] = useState(true) + // const [peer, setp] = useState(null) + var savepeer=useRef(); + var showornot=useRef(false) + var [readyforconn,setr]=useState(false) + var [readytosend,setrts]=useState(false) + var [joinoth,setjoth]=useState(false) + var peer:Peer=savepeer.current; + var saveui4=useRef(""); + // var ui4=saveui4.current; + const [showtext, setshowtext] = useState("") + // dlfd(peer) + const startconn=(amitheinitiator)=>{ + // useEffect(()=>{ + return new Peer({ + initiator: amitheinitiator, + trickle: false, + // wrtc: wrtc + // wrtc:nodeDatachannelPolyfill + }) + // setp(p) + // },[amitheinitiator]) + } + + // runonce.current=true; + // } + // },[]) + +// const setupchannel=()=>{ +// dlfd("setup channel name "+ui4) + +// channel=(ably.channels.get(ui4)); +// } + +// var onDataHandlerSetss = false; +//once an offer is instantiated +// const offerset=(offer)=>{ + +// // if(offer.trim().length!==0 ){ +// dlfd("setting offer on redis") + // useEffect(()=>{ + const setofferdata = async (recdata) => { + // if(!onDataHandlerSetss){ + let randomNumber = Math.floor(Date.now() % 10000); + console.log(randomNumber); + saveui4.current=randomNumber.toString(); + dlfd(saveui4.current) + // dlfd(recdata) + await submittodb(saveui4.current, recdata); + showornot.current=true + // await getoffer() + // dlfd(uuidv4()); // Outputs a unique UUID + // const session = await kvstore.get(ui4); + // dlfd(session) + setshowtext(saveui4.current) + dlfd("initiator uid---->"+saveui4.current) + // dlfd(ably) + // onDataHandlerSetss = true; + // try{ + + + // } + // catch(e){ + // dlfd("FAILED") + // dlfd(e) + // } + // // get the channel to subscribe to + // setupchannel() + // /* + // Subscribe to a channel. + // The promise resolves when the channel is attached + // (and resolves synchronously if the channel is already attached). + // */ + //subscribe to know when answers are being sent + // await channel.subscribe('answer', (message) => { + // answerrecieved(message.data) + // dlfd('Received a greeting message in realtime: ' + message.data) + // }); + // ably.close() + // } + // const data = await getData(1); + // setData(data); + } + + // const answerrecieved=(answer)=>{ + // dlfd("answerr recieved--------->"+answer) + // peer.signal(JSON.parse(answer)) + + // } + + // fetchData(offer); + // async ()=>{ + // } + // },[offer]) + // } +// } +// //once decided on initiator +// if(sdp.trim().length!==0) +// {useEffect(()=>{ +// const fetchData = async () => { +// var session; +// try{ +// session = await kv.get(sdp); +// setinitiator(false) +// peer.signal(JSON.parse(session)) +// //ably join the channel of sdp and close this ones channel +// setchannel(ably.channels.get(sdp)); + +// } +// catch(e){ + +// } + + +// // setshowtext(session) +// } + +// fetchData(); +// // async ()=>{ +// // } +// },[sdp])} +// //send answer to initiator +// if(answer.trim().length!==0) +// {useEffect(()=>{ + const setanswerdata = async (answer) => { + await submittodb(saveui4.current, answer); + dlfd("sent answer to db") + setr(true) + console.log(readyforconn) + // setupchannel() + //ably send the answer over the connection + // await channel.publish('answer', answer); + + // setshowtext(session) + } +const getoffer=async()=>{ + console.log(saveui4.current) + var resp=await getfromdb(saveui4.current); + +// Wait for the axios request to complete +var response = await resp; + +// Access the data property of the response + var offer = response.data.data; + dlfd("got offer"+JSON.parse(offer)) + peer.signal(JSON.parse(offer)) + +} +const getanswer=async()=>{ + console.log(saveui4.current) + var resp=await getfromdb(saveui4.current); + +// Wait for the axios request to complete +var response = await resp; + +// Access the data property of the response + var answer = response.data.data; + dlfd("answerr recieved--------->"+answer) + peer.signal(JSON.parse(answer)) + // peer.signal(offer) + +} +// fetchData(); +// // async ()=>{ +// // } +// },[answer])} + // var onDataHandlerSet=false; + // useEffect(() => { + const initpeer=()=>{ + + if (peer) { + // Check if 'data' event listener has already been set up + // if (!onDataHandlerSet) { + peer.on('error', err => dlfd('error'+ err)) + + peer.on('signal', data => { + let recdata=JSON.stringify(data) + dlfd('SIGNAL'+ recdata) + // setshowtext(JSON.stringify(data)) + if(data.type==="offer"){ + dlfd("offer signal recieved") + // dlfd(recdata) + // setoffer(recdata) + // dlfd(offer) + setofferdata(recdata) + }else if(data.type==="answer"){ + dlfd("answer signal recieved") + setanswerdata(recdata) + dlfd((peer)) + } + }) + peer.on('connect', () => { + dlfd('CONNECT') + setrts(true) + + // ably.close() + + }) + peer.on('data', data => { + dlfd(data) + var gd=JSON.parse(data) as DataTypeDesc; + if (gd.dataType === MessageTypeDesc.FILE) { + dlfd("recieved file") + download(gd.file || '', gd.fileName || "fileName", gd.fileType) + } + else{ + + dlfd('Received'+ gd.message); + // dlfd('Received', JSON.stringify(gd)); + // setm("Friend : " + gd.message) + } + }) + + // Mark 'data' event listener as set up + // onDataHandlerSet = true; + // } + } + // }, [peer]); + } + + const handleJoin=() => { + savepeer.current=startconn(false) + peer=savepeer.current + dlfd(JSON.stringify(peer)) + initpeer() + // dlfd("offer got from kvstore----->"+sdp) + + saveui4.current=sdp + // setupchannel() + + getoffer() + } + + + const sendMessage=()=> { + dlfd("sending message") + // send message at sender or receiver side + if (peer) { + let sm=(JSON.stringify( + { + dataType:MessageTypeDesc.OTHER, + message: + 'whatever' + Math.random() + + } as DataTypeDesc)) + // setm("Me : " + msg.value) + dlfd(sm) + peer.send(sm) + + } +} +const joinothenable=()=>{ + setjoth(true) +} + +const [fileList, setFileList] = React.useState<[File]>([]) + const [sendLoading, setSendLoading] = React.useState(false) + const handleUpload = async () => { + if(fileList){ + + if (fileList.length === 0) { + dlfd("Please select file") + return + } + dlfd(peer) + if (!peer) { + dlfd("Please select a connection") + return + } + try { + await setSendLoading(true); + let file = fileList[0] as unknown as File; + let blob = new Blob([file], {type: file.type}); + + await peer.send(JSON.stringify({ + dataType: MessageTypeDesc.FILE, + file: blob, + fileName: file.name, + fileType: file.type + } as DataTypeDesc)) + await setSendLoading(false) + dlfd("Send file successfully") + } catch (err) { + await setSendLoading(false) + dlfd(err) + dlfd("Error when sending file") + } + } + } + const addfile=(event) => { + console.log(peer) + event.preventDefault(); + const file = event.target.files[0]; + if (file) { + setFileList([file]); + } else { + setFileList([]); + } + } + + return ( +
+ {/*

Simple Next.js App

*/} + {/* */} +
+ + +
+ +
+
+

+ Share code: {showtext} +

+
+
+ +