diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a14dc9d..1169c6d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,9 @@ "ipfs-http-client": "^56.0.1", "moment": "^2.29.3", "omit-deep": "^0.3.0", + "ply": "^0.1.0", + "plyr-react": "^5.1.0", + "process": "^0.11.10", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^6.2.2", @@ -6789,6 +6792,11 @@ "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz", "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==" }, + "node_modules/custom-event-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz", + "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==" + }, "node_modules/dag-jose": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dag-jose/-/dag-jose-1.0.0.tgz", @@ -9571,6 +9579,11 @@ } } }, + "node_modules/loadjs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loadjs/-/loadjs-4.2.0.tgz", + "integrity": "sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA==" + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -11205,6 +11218,50 @@ "node": ">=4" } }, + "node_modules/ply": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ply/-/ply-0.1.0.tgz", + "integrity": "sha512-/Vot7EUC/7yzlz4RIng79wpSV2GK4sNQoi3TgI0YZXJFiSLXJ6SSk0O0yJNW6FHY4P9+Iapiq2sL2LaC7nAYmA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/plyr": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/plyr/-/plyr-3.7.3.tgz", + "integrity": "sha512-ORULENBvEvvzMYXRQBALDmEi8P+wZt1Hr/NvHqchu/t7E2xJKNkRYWx0qCA1HETIGZ6zobrOVgqeAUqWimS7fQ==", + "dependencies": { + "core-js": "^3.26.1", + "custom-event-polyfill": "^1.0.7", + "loadjs": "^4.2.0", + "rangetouch": "^2.0.1", + "url-polyfill": "^1.1.12" + } + }, + "node_modules/plyr-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plyr-react/-/plyr-react-5.1.0.tgz", + "integrity": "sha512-N0qIuN1wZZzpKUXngtNeZwTiWqvOb6qAzqcfMI48rLkRJGM5xM5MRWILd3hW1PWPbVBKsAH4Ged32ZZhkJVbXA==", + "dependencies": { + "plyr": "^3.7.2", + "react-aptor": "^2.0.0-alpha.1" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "plyr": "^3.7.2", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "plyr": { + "optional": false + }, + "react": { + "optional": true + } + } + }, "node_modules/pngjs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", @@ -11257,6 +11314,14 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "peer": true }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -11406,6 +11471,11 @@ "node": ">= 0.6" } }, + "node_modules/rangetouch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.1.tgz", + "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==" + }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -11418,6 +11488,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-aptor": { + "version": "2.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/react-aptor/-/react-aptor-2.0.0-alpha.1.tgz", + "integrity": "sha512-FbvxQKsZMUZcLr2WdrQEmxH0kifsN4N+v6YdL1g3At03zouJCEcPXv+o+bhP3Ci3ya4QPvNHK/bpbrCzuKWOMw==", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "node_modules/react-devtools-core": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.24.0.tgz", @@ -13209,6 +13295,11 @@ "requires-port": "^1.0.0" } }, + "node_modules/url-polyfill": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz", + "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==" + }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -18902,6 +18993,11 @@ "resolved": "https://registry.npmjs.org/custom-error-instance/-/custom-error-instance-2.1.1.tgz", "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==" }, + "custom-event-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz", + "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==" + }, "dag-jose": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dag-jose/-/dag-jose-1.0.0.tgz", @@ -20996,6 +21092,11 @@ } } }, + "loadjs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loadjs/-/loadjs-4.2.0.tgz", + "integrity": "sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA==" + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -22319,6 +22420,32 @@ } } }, + "ply": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ply/-/ply-0.1.0.tgz", + "integrity": "sha512-/Vot7EUC/7yzlz4RIng79wpSV2GK4sNQoi3TgI0YZXJFiSLXJ6SSk0O0yJNW6FHY4P9+Iapiq2sL2LaC7nAYmA==" + }, + "plyr": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/plyr/-/plyr-3.7.3.tgz", + "integrity": "sha512-ORULENBvEvvzMYXRQBALDmEi8P+wZt1Hr/NvHqchu/t7E2xJKNkRYWx0qCA1HETIGZ6zobrOVgqeAUqWimS7fQ==", + "requires": { + "core-js": "^3.26.1", + "custom-event-polyfill": "^1.0.7", + "loadjs": "^4.2.0", + "rangetouch": "^2.0.1", + "url-polyfill": "^1.1.12" + } + }, + "plyr-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plyr-react/-/plyr-react-5.1.0.tgz", + "integrity": "sha512-N0qIuN1wZZzpKUXngtNeZwTiWqvOb6qAzqcfMI48rLkRJGM5xM5MRWILd3hW1PWPbVBKsAH4Ged32ZZhkJVbXA==", + "requires": { + "plyr": "^3.7.2", + "react-aptor": "^2.0.0-alpha.1" + } + }, "pngjs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", @@ -22360,6 +22487,11 @@ } } }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -22485,6 +22617,11 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "peer": true }, + "rangetouch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.1.tgz", + "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==" + }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -22494,6 +22631,12 @@ "object-assign": "^4.1.1" } }, + "react-aptor": { + "version": "2.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/react-aptor/-/react-aptor-2.0.0-alpha.1.tgz", + "integrity": "sha512-FbvxQKsZMUZcLr2WdrQEmxH0kifsN4N+v6YdL1g3At03zouJCEcPXv+o+bhP3Ci3ya4QPvNHK/bpbrCzuKWOMw==", + "requires": {} + }, "react-devtools-core": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.24.0.tgz", @@ -23909,6 +24052,11 @@ "requires-port": "^1.0.0" } }, + "url-polyfill": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz", + "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==" + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index d7c1a1b..2267422 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,9 @@ "ipfs-http-client": "^56.0.1", "moment": "^2.29.3", "omit-deep": "^0.3.0", + "ply": "^0.1.0", + "plyr-react": "^5.1.0", + "process": "^0.11.10", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^6.2.2", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 46d5af4..69a1ec8 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -126,7 +126,7 @@ function App() { const { chains, provider } = configureChains( import.meta.env.VITE_CHAIN === 'mumbai' ? [chain.polygonMumbai] : [chain.polygon], [ - alchemyProvider({ apiKey: import.meta.env.ALCHEMY_ID }), + alchemyProvider({ apiKey: import.meta.env.VITE_ALCHEMY_ID }), publicProvider() ] ); diff --git a/frontend/src/components/Compose.jsx b/frontend/src/components/Compose.jsx index 440febf..418355b 100644 --- a/frontend/src/components/Compose.jsx +++ b/frontend/src/components/Compose.jsx @@ -3,6 +3,7 @@ import styled from 'styled-components' import { useMutation } from '@apollo/client' import { utils } from 'ethers' import omitDeep from 'omit-deep' +import { useAsset, useCreateAsset, useUpdateAsset } from '@livepeer/react'; import Button from './Button' import Card from './Card' @@ -101,6 +102,14 @@ const videoFileTypes = ['.mp4','.mov','.webm','.3gpp','.3gpp2','.flv','.mpeg'] const imageFileTypes = ['.jpg','.jpeg','.png','.gif'] +const isValidFileType = (validFileTypes, file) => { + if (!file.type) { + return false; + } + const fileType = "." + file.type.split("/").pop(); + return validFileTypes.includes(fileType); +} + const Compose = ({ profileId, profileName, @@ -125,46 +134,63 @@ const Compose = ({ // Uploading Video const [videoUploading, setVideoUploading] = useState(false); const [selectedFile, setSelectedFile] = useState(""); - const [video, setVideo] = useState("") - const [videoNftMetadata, setVideoNftMetadata] = useState({}) - - const videoUpload = async () => { - setVideoUploading(true) - const formData = new FormData(); - console.log(selectedFile) - formData.append( - "fileName", - selectedFile, - selectedFile.name - ); + const [videoIPFSData, setVideoIPFSData] = useState({}); + const { mutate: createAsset, data: createdAsset, uploadProgress, status: createStatus } = useCreateAsset( + selectedFile && isValidFileType(videoFileTypes, selectedFile) + ? { + sources: [{ name: selectedFile.name, file: selectedFile }], + } + : null, + ); + const { data: asset, status: assetStatus } = useAsset({ + assetId: createdAsset?.id, + refetchInterval: (asset) => + asset?.status?.phase !== 'ready' ? 5000 : false, + refetchInterval: (asset) => + asset?.storage?.status?.phase !== 'ready' ? 5000 : false, + }); + const { mutate: updateAsset, status, error } = useUpdateAsset({ + assetId: asset?.id, + storage: { ipfs: true }, + }); - const response = await fetch('https://irisxyz.herokuapp.com/upload', { method: "POST", body: formData, mode: "cors" }); - const data = await response.json(); + useEffect(() => { + const videoUpload = async () => { + if (!selectedFile) { return } - console.log(data); + console.log(selectedFile) + setVideoUploading(true) + console.log("Creating asset") + createAsset?.(); + } - // console.log("The nftmetadataURL ", data["nftMetadataGatewayUrl"]) + videoUpload() + }, [selectedFile]) - // Get metadata from livepeer - const responseVidNftMetadata = await fetch(data["nftMetadataGatewayUrl"], { method: "GET" }); - const vidNftData = await responseVidNftMetadata.json(); + useEffect(() => { + const exportToIPFS = async () => { + console.log("Export?") + if (asset?.status?.phase !== 'ready') { return } + console.log("Exporting to IPFS") + updateAsset?.(); + } - setVideoNftMetadata(vidNftData) - console.log("VideoNFTMetaData :", vidNftData) + exportToIPFS() + }, [asset?.status?.phase]) + useEffect(() => { + if (asset?.storage?.status?.phase !== 'ready') { return } + console.log("Exported to IPFS!") + setVideoIPFSData(asset?.storage?.ipfs) setVideoUploading(false) + console.log(asset?.storage?.ipfs?.nftMetadata) + console.log("CID", asset?.storage?.ipfs?.cid) + console.log("URL", asset?.storage?.ipfs?.url) - - // console.log(data); - // const ipfs = await fetch(`https://ipfs.io/${data.data.replace(":", "")}`); - // const nftMetadata = await ipfs.json() - // console.log(nftMetadata); - // setVideo(`https://ipfs.io/${nftMetadata.properties.video.replace(":", "")}`) - - } + }, [asset?.storage?.status?.phase]) const handleSubmit = async () => { - await handleCompose({description, lensHub, profileId, profileName, selectedVisibility, replyTo, mutateCommentTypedData, mutatePostTypedData}) + await handleCompose({description, lensHub, profileId, profileName, selectedVisibility, replyTo, videoIPFSData, mutateCommentTypedData, mutatePostTypedData}) } useEffect(() => { @@ -227,6 +253,7 @@ const Compose = ({ await pollUntilIndexed(tx.hash) setShowModal(false) setDescription('') + setSelectedFile('') setToastMsg({type: 'success', msg: 'Transaction indexed'}) return; } @@ -237,19 +264,12 @@ const Compose = ({ await pollUntilIndexed(txHash) setShowModal(false) setDescription('') + setSelectedFile('') setToastMsg({type: 'success', msg: 'Transaction indexed'}) } processBroadcast() }, [broadcastData.data]) - - const isValidFileType = (validFileTypes, file) => { - if (!file.type) { - return false; - } - const fileType = "." + file.type.split("/").pop(); - return validFileTypes.includes(fileType); - } return ( <> diff --git a/frontend/src/components/Livepeer.jsx b/frontend/src/components/Livepeer.jsx index a5c3d8b..a2f88e1 100644 --- a/frontend/src/components/Livepeer.jsx +++ b/frontend/src/components/Livepeer.jsx @@ -6,7 +6,7 @@ import { export const client = createReactClient({ provider: studioProvider({ - apiKey: process.env.REACT_APP_LIVEPEER_API_KEY + apiKey: import.meta.env.VITE_LIVEPEER_API_KEY }), }); diff --git a/frontend/src/components/Post.jsx b/frontend/src/components/Post.jsx index 9b93252..69af58f 100644 --- a/frontend/src/components/Post.jsx +++ b/frontend/src/components/Post.jsx @@ -333,20 +333,20 @@ function Post({ profileId, isCommunityPost, ...props }) {
{exclusiveDescription(postType)}}> : Video
+ returnVideo
}) }