├── Album.css ├── Album.js ├── Album.sol ├── App.css ├── App.js ├── App.test.js ├── AudioPlayer.css ├── AudioPlayer.js ├── CONTRIBUTION.md ├── CONTRIBUTOR.md ├── College.md ├── GMAIL.md ├── Hobby.md ├── Home.css ├── Home.js ├── README.md ├── albumList.js ├── index.css ├── index.html ├── index.js ├── logo.svg ├── manifest.json ├── metadata.js ├── music.js ├── package.json ├── reportWebVitals.js ├── robots.txt ├── setupTests.js ├── useAlbum.js ├── useAudio.js ├── useIPFS.js └── yarn.lock /Album.css: -------------------------------------------------------------------------------- 1 | .albumContent { 2 | padding: 10px 40px; 3 | } 4 | 5 | .topBan { 6 | display: flex; 7 | gap:30px; 8 | } 9 | 10 | .albumCover { 11 | width:200px; 12 | } 13 | 14 | .albumDeets { 15 | display: flex; 16 | flex-direction: column; 17 | justify-content: end; 18 | color: rgb(205, 203, 203); 19 | } 20 | 21 | .title { 22 | color:white; 23 | font-size: 40px; 24 | font-weight: bold; 25 | } 26 | 27 | .artist { 28 | font-size: 20px; 29 | color:white; 30 | } 31 | 32 | .playButton { 33 | padding: 10px; 34 | background-color: #1DB954; 35 | width: 120px; 36 | color:white; 37 | display: flex; 38 | justify-content: center; 39 | margin-top: 35px; 40 | margin-bottom: 35px; 41 | border-radius: 25px; 42 | letter-spacing: 1.5px; 43 | transition: transform 0.4s; 44 | } 45 | .openButton { 46 | padding: 10px; 47 | background-color: transparent; 48 | width: 200px; 49 | color:white; 50 | display: flex; 51 | justify-content: center; 52 | align-items: center; 53 | gap:10px; 54 | margin-top: 35px; 55 | margin-bottom: 35px; 56 | border: 2px solid white; 57 | border-radius: 25px; 58 | letter-spacing: 1.5px; 59 | transition: transform 0.4s; 60 | } 61 | 62 | .openLogo{ 63 | height:20px; 64 | } 65 | 66 | .playButton:hover { 67 | cursor: pointer; 68 | transform: scale(1.05);; 69 | } 70 | 71 | .openButton:hover{ 72 | cursor: pointer; 73 | transform: scale(1.05);; 74 | } 75 | 76 | .tableHeader { 77 | border-bottom: 1px solid rgb(67, 67, 67); 78 | display: flex; 79 | color: rgb(125, 125, 125); 80 | letter-spacing: 1.4px; 81 | font-size: 16px; 82 | font-weight: 500; 83 | padding-bottom: 8px; 84 | } 85 | 86 | .numberHeader { 87 | display: flex; 88 | justify-content: center; 89 | width: 10%; 90 | } 91 | 92 | .titleHeader { 93 | width: 80%; 94 | padding-left: 5%; 95 | display: flex; 96 | justify-content: start; 97 | } 98 | 99 | .tableContent { 100 | border-bottom: 1px solid rgb(67, 67, 67); 101 | display: flex; 102 | color: rgb(125, 125, 125); 103 | font-size: 16px; 104 | font-weight: 500; 105 | padding-bottom: 13px; 106 | padding-top: 13px; 107 | } 108 | -------------------------------------------------------------------------------- /Album.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useAlbum } from "../hooks/useAlbum"; 3 | import { useLocation } from "react-router"; 4 | import "./Album.css"; 5 | import Opensea from "../images/opensea.png"; 6 | import { ClockCircleOutlined } from "@ant-design/icons"; 7 | 8 | const bears = [ 9 | { 10 | src: "https://ipfs.moralis.io:2053/ipfs/Qmf8xEYZdMtQXYv56VxxmzbtUtEVjmaFaXGCgcBqGXDAA6/music/JTwinkle.mp3", 11 | cover: 12 | "https://upload.wikimedia.org/wikipedia/en/6/69/B.o.B_-_Strange_Clouds_-_LP_Cover.jpg", 13 | album: "Strange Clouds", 14 | song: "Airplanes", 15 | duration: "0:05", 16 | }, 17 | { 18 | src: "https://ipfs.moralis.io:2053/ipfs/QmUUhsAiUFq1B5JtzQH733CLBbUCnRekYXETMfeYG7PaZ3/music/JTiger.mp3", 19 | cover: 20 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 21 | album: "My Everything", 22 | song: "Side To Side", 23 | duration: "0:16", 24 | }, 25 | { 26 | src: "https://ipfs.moralis.io:2053/ipfs/QmUUhsAiUFq1B5JtzQH733CLBbUCnRekYXETMfeYG7PaZ3/music/JTiger.mp3", 27 | cover: 28 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 29 | album: "My Everything", 30 | song: "Pizza and A Coke", 31 | duration: "5:01", 32 | }, 33 | { 34 | src: "https://ipfs.moralis.io:2053/ipfs/QmUUhsAiUFq1B5JtzQH733CLBbUCnRekYXETMfeYG7PaZ3/music/JTiger.mp3", 35 | cover: 36 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 37 | album: "My Everything", 38 | song: "Iceberg Lettuce", 39 | duration: "0:24", 40 | }, 41 | { 42 | src: "https://ipfs.moralis.io:2053/ipfs/QmUUhsAiUFq1B5JtzQH733CLBbUCnRekYXETMfeYG7PaZ3/music/JTiger.mp3", 43 | cover: 44 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 45 | album: "My Everything", 46 | song: "Spitting Chicklets", 47 | duration: "1:03", 48 | }, 49 | { 50 | src: "https://ipfs.moralis.io:2053/ipfs/QmUUhsAiUFq1B5JtzQH733CLBbUCnRekYXETMfeYG7PaZ3/music/JTiger.mp3", 51 | cover: 52 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 53 | album: "My Everything", 54 | song: "Boomerang", 55 | duration: "2:16", 56 | }, 57 | ]; 58 | 59 | const Album = ({ setNftAlbum }) => { 60 | const { state: albumDetails } = useLocation(); 61 | const { album } = useAlbum(albumDetails.contract); 62 | 63 | return ( 64 | <> 65 |
66 |
67 | albumcover 72 |
73 |
ALBUM
74 |
{albumDetails.title}
75 |
76 | {album && JSON.parse(album[0].metadata).artist} 77 |
78 |
79 | {album && JSON.parse(album[0].metadata).year} •{" "} 80 | {album && album.length} Songs 81 |
82 |
83 |
84 |
85 |
setNftAlbum(album)}> 86 | PLAY 87 |
88 |
91 | window.open( 92 | `https://testnets.opensea.io/assets/mumbai/${albumDetails.contract}/1` 93 | ) 94 | } 95 | > 96 | OpenSea 97 | 98 |
99 |
100 |
101 |
#
102 |
TITLE
103 |
104 | 105 |
106 |
107 | {album && 108 | album.map((nft, i) => { 109 | nft = JSON.parse(nft.metadata); 110 | return ( 111 | <> 112 |
113 |
{i + 1}
114 |
118 | {nft.name} 119 |
120 |
{nft.duration}
121 |
122 | 123 | ); 124 | })} 125 |
126 | 127 | ); 128 | }; 129 | 130 | export default Album; 131 | -------------------------------------------------------------------------------- /Album.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.3; 3 | 4 | import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol"; 5 | import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; 6 | import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol"; 7 | 8 | 9 | contract NFT is ERC721URIStorage { 10 | using Counters for Counters.Counter; 11 | Counters.Counter private _tokenIds; 12 | address public owner; 13 | 14 | 15 | constructor() ERC721("NonFungiMusic", "NFM") { 16 | owner = msg.sender; 17 | } 18 | 19 | function createToken(string memory tokenURI) public returns (uint) { 20 | require(msg.sender == owner, "Only owner is allowed to createTokens"); 21 | _tokenIds.increment(); 22 | uint256 newItemId = _tokenIds.current(); 23 | 24 | _mint(msg.sender, newItemId); 25 | _setTokenURI(newItemId, tokenURI); 26 | return newItemId; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /App.css: -------------------------------------------------------------------------------- 1 | @import '~antd/dist/antd.css'; 2 | 3 | .ant-layout { 4 | min-height: 100vh; 5 | } 6 | 7 | .ant-layout-sider { 8 | background-image: linear-gradient(#1e2422, #000000); 9 | background-attachment:fixed; 10 | width: 800px; 11 | padding: 30px; 12 | } 13 | 14 | .ant-layout-content { 15 | background-image: linear-gradient(#494B4A, #030404); 16 | background-attachment:fixed; 17 | } 18 | 19 | .ant-layout-footer { 20 | background-color: #292929; 21 | padding-bottom: 4px; 22 | padding-top: 15px; 23 | } 24 | 25 | .ant-tabs-top > .ant-tabs-nav::before { 26 | border-bottom: 0px; 27 | } 28 | 29 | .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn { 30 | color: white; 31 | text-shadow: 0 0 0.25px currentcolor; 32 | } 33 | 34 | .ant-tabs-tab-btn:focus { 35 | color: white; 36 | } 37 | 38 | .ant-tabs-tab { 39 | color: rgb(125, 125, 125); 40 | font-size: 18px; 41 | letter-spacing: 2px; 42 | } 43 | 44 | .ant-tabs-tab:hover { 45 | color: white; 46 | } 47 | 48 | .ant-tabs-ink-bar { 49 | background: #1DB954; 50 | width: 10px; 51 | } 52 | 53 | .ant-slider-track { 54 | background-color: #1DB954; 55 | } 56 | 57 | .ant-slider:hover .ant-slider-track { 58 | background-color: #1DB954; 59 | } 60 | 61 | .ant-slider-handle { 62 | border: 0px 63 | } 64 | 65 | .ant-slider-rail { 66 | background-color: #3E3E3E; 67 | } 68 | 69 | .logo { 70 | width:50px; 71 | margin-bottom: 20px; 72 | } 73 | 74 | .searchBar { 75 | border-top: 2px solid rgb(125, 125, 125); 76 | border-bottom: 2px solid rgb(125, 125, 125); 77 | padding: 15px 0px; 78 | display: flex; 79 | justify-content: space-between; 80 | margin-bottom: 20px; 81 | } 82 | 83 | .sideBar { 84 | color: white; 85 | font-size: 20px; 86 | font-weight: 500; 87 | letter-spacing: 1px; 88 | } 89 | 90 | .recentPlayed { 91 | border-top: 2px solid rgb(125, 125, 125); 92 | border-bottom: 2px solid rgb(125, 125, 125); 93 | padding: 15px 0px; 94 | display: flex; 95 | flex-direction: column; 96 | justify-content: space-between; 97 | height: calc(100vh - 400px); 98 | } 99 | 100 | .recentTitle { 101 | color: rgb(125, 125, 125); 102 | font-size: 15px; 103 | font-weight: 400; 104 | } 105 | 106 | .install { 107 | display: flex; 108 | justify-content: space-between; 109 | } 110 | 111 | .contentWindow { 112 | padding: 50px 0px; 113 | } 114 | 115 | .footer { 116 | position: sticky; 117 | bottom: 0; 118 | display: flex; 119 | justify-content: space-between; 120 | align-items:center; 121 | background-color: #292929; 122 | color: rgb(205, 203, 203) !important; 123 | } 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useState } from 'react'; 3 | import { Routes, Route } from "react-router-dom"; 4 | import Home from "./pages/Home"; 5 | import Album from './pages/Album'; 6 | import './App.css'; 7 | import { Link } from "react-router-dom"; 8 | import Player from "./components/AudioPlayer"; 9 | import { Layout } from "antd"; 10 | import Spotify from "./images/Spotify.png"; 11 | import { SearchOutlined, DownCircleOutlined } from "@ant-design/icons"; 12 | 13 | const { Content, Sider, Footer } = Layout; 14 | 15 | const App = () => { 16 | 17 | const [nftAlbum, setNftAlbum] = useState(); 18 | return ( 19 | <> 20 | 21 | 22 | 23 | Logo 24 |
25 | Search 26 | 27 |
28 | 29 |

Home

30 | 31 |

Your Music

32 |
33 |

RECENTLY PLAYED

34 |
35 | Install App 36 | 37 |
38 |
39 |
40 | 41 | 42 | } /> 43 | } /> 44 | 45 | 46 |
47 | 54 |
55 | 56 | ); 57 | } 58 | 59 | 60 | export default App; 61 | -------------------------------------------------------------------------------- /App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /AudioPlayer.css: -------------------------------------------------------------------------------- 1 | .volume { 2 | width:100px; 3 | } 4 | 5 | .soundDiv { 6 | display: flex; 7 | gap:15px; 8 | font-size: 20px; 9 | align-items:center; 10 | width: 300px; 11 | justify-content: end; 12 | } 13 | 14 | .pauseplay { 15 | font-size: 35px; 16 | transition: transform 0.2s; 17 | } 18 | 19 | .pauseplay:hover { 20 | transform: scale(1.1); 21 | } 22 | 23 | .forback { 24 | font-size: 16px; 25 | transition: transform 0.2s; 26 | } 27 | 28 | .forback:hover { 29 | transform: scale(1.4); 30 | } 31 | 32 | .buttons { 33 | display: flex; 34 | justify-content: center; 35 | align-items: center; 36 | gap: 15px; 37 | margin-bottom: 5px; 38 | } 39 | 40 | .progress { 41 | width:400px; 42 | } 43 | 44 | .progress .ant-slider-track { 45 | background-color: #A7A7A7; 46 | } 47 | 48 | .progress .ant-slider-handle { 49 | background-color: transparent; 50 | } 51 | 52 | .cover { 53 | height: 80px; 54 | } 55 | 56 | .songTitle { 57 | font-size: 16px; 58 | color: white; 59 | } 60 | 61 | .songAlbum { 62 | font-size: 12px; 63 | } 64 | -------------------------------------------------------------------------------- /AudioPlayer.js: -------------------------------------------------------------------------------- 1 | import useAudio from "../hooks/useAudio"; 2 | import {Slider} from "antd"; 3 | import { useIPFS } from "../hooks/useIPFS"; 4 | import "./AudioPlayer.css"; 5 | import { SoundOutlined, StepBackwardOutlined, StepForwardOutlined, PlayCircleFilled, PauseCircleFilled} from "@ant-design/icons"; 6 | 7 | 8 | const Player = ({ url }) => { 9 | const {resolveLink} = useIPFS(); 10 | const [ 11 | playing, 12 | duration, 13 | toggle, 14 | toNextTrack, 15 | toPrevTrack, 16 | trackProgress, 17 | onSearch, 18 | onSearchEnd, 19 | onVolume, 20 | trackIndex 21 | ] = useAudio(url); 22 | 23 | 24 | const minSec = (secs) => { 25 | const minutes = Math.floor(secs / 60); 26 | const returnMin = minutes < 10 ? `0${minutes}` : minutes; 27 | const seconds = Math.floor(secs % 60); 28 | const returnSec = seconds < 10 ? `0${seconds}` : seconds; 29 | 30 | return `${returnMin}:${returnSec}`; 31 | }; 32 | 33 | return ( 34 | <> 35 |
36 | currentCover 37 |
38 |
{JSON.parse(url[trackIndex].metadata).name}
39 |
{url[trackIndex].name}
40 |
41 |
42 |
43 |
44 | 45 | {playing ? 46 | : 47 | 48 | } 49 | 50 |
51 |
52 | {minSec(trackProgress)} 53 | onSearch(value)} 61 | onAfterChange={onSearchEnd} 62 | /> 63 | {duration ? minSec(Math.round(duration)) : "00:00"} 64 |
65 |
66 |
67 | 68 | onVolume(value/100)} 73 | /> 74 |
75 | 76 | ); 77 | }; 78 | 79 | export default Player; 80 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # How to Contribute ? 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## _Code Reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Please follow Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google/conduct/). 29 | -------------------------------------------------------------------------------- /CONTRIBUTOR.md: -------------------------------------------------------------------------------- 1 | # Contributors : Update your name and create a PR 2 | 3 | 4 | 5 | - [Arpan Mondal](https://github.com/arpan-mondal) 6 | - [Shivansh Dwivedi](https://github.com/shivansh-magnus) 7 | - [Rikta Pramanik ](https://github.com/rikta99) 8 | - [Neel Ghosh](https://github.com/neelghosh1234) 9 | - [Sayan Das](https://github.com/SayanRicky) 10 | - [Romit Roy](https://github.com/MrRoyzz) 11 | - [Argha Ghosh](https://github.com/argha7417) 12 | - [Subhajit Mondal](https://github.com/subhajit9932) 13 | - [Mainak Banerjee](https://github.com/Mainak57) 14 | - [Pranjal Agarwal](https://github.com/Pranjal360Agarwal) 15 | - [Aryan Raj](https://github.com/aryan0103raj) 16 | - [Sayan Kundu](https://github.com/SayanKundu10) 17 | - [Debmalya Bhar](https://github.com/debmalyabhar) 18 | - [Soumyadip Das Adhikari](https://github.com/soumya07ad) 19 | - [Srinjoy Sen Chowdhury](https://github.com/AllMightLegend) 20 | - [Haathi Gosh](https://github.com/ChaHaoIn) 21 | - [Gopal Bhar](https://github.com/hello70world) 22 | -------------------------------------------------------------------------------- /College.md: -------------------------------------------------------------------------------- 1 | # Collage : Enter your collage name and Create Pull Request 2 | // Add your College 3 | 4 | 5 | - [Sister Nivedita University](https://github.com/arpan-mondal) 6 | - [Vivekananda School](https://github.com/arpan-mondal) 7 | - [Self Made University](https://github.com/neelghosh1234) 8 | - [Sister Nivedita University](https://github.com/SayanRicky) 9 | - [Sister Nivedita University](https://github.com/MrRoyzz) 10 | - [Sister Nivedita University](https://github.com/argha7417) 11 | - [Sister Nivedita University](https://github.com/subhajit9932) 12 | - [Sister Nivedita University](https://github.com/Mainak57) 13 | - [Jaypee University of Engineering and Technology](https://github.com/Pranjal360Agarwal) 14 | [Sister Nivedita University](https://github.com/aamrin786) 15 | - [Jadavpur University](https://github.com/aryan0103raj) 16 | - [Sister Nivedita University](https://github.com/SayanKundu10) 17 | - [Sister Nivedita University](https://github.com/debmalyabhar) 18 | - [Sister Nivedita University](https://github.com/soumya07ad) 19 | - [Techno Main Salt Lake](https://github.com/AllMightLegend) 20 | - [Techno Main Salt Lake](https://github.com/ChaoHaoIn) 21 | - [Jadavpur University](https://github.com/hello70world) 22 | -------------------------------------------------------------------------------- /GMAIL.md: -------------------------------------------------------------------------------- 1 | # Upload your mail and create a PR 2 | // Add your Email 3 | 4 | 5 | - [arpan.mondal633@gmail.com](https://github.com/arpan-mondal) 6 | - [prarikta937@gmail.com](https://github.com/rikta99) 7 | - [nghoserobinhood@gmail.com](https://github.com/neelghosh1234) 8 | - [sayanricky24@gmail.com](https://github.com/SayanRicky) 9 | - [meriradharani02@gmail.com](https://github.com/MrRoyzz) 10 | - [argha7417@gmail.com](https://github.com/argha7417) 11 | - [dwivediayush2002@gmail.com](https://github.com/shivansh-magnus) 12 | - [subhojit2002mondal@gmail.com](https://github.com/subhajit9932) 13 | - [mainakbanerjee79@gmail.com](https://github.com/Mainak57) 14 | - [materagarwal@gmail.com](https://github.com/Pranjal360Agarwal) 15 | - [aryan0103.raj@gmail.com](https://github.com/aryan0103raj) 16 | - [sayankundu0302@gmail.com](https://github.com/SayanKundu10) 17 | - [debmalyabhar1@gmail.com](https://github.com/debmalyabhar) 18 | - [adkhikarisouma7@gmail.com](https://github.com/souma07ad) 19 | - [srinjoysen123@gmail.com](https://github.com/AllMightLegend) 20 | - [srinjoysenchowdhury@gmail.com](https://github.com/ChaHaoIn) 21 | - [2003m.tushar@gmail.com](https://github.com/hello70world) 22 | -------------------------------------------------------------------------------- /Hobby.md: -------------------------------------------------------------------------------- 1 | # Hobby : Update your hobby and Create a PR 2 | 3 | 4 | 5 | - [Coding](https://github.com/arpan-mondal) 6 | - [Reading](https://github.com/rikta99) 7 | - [Drinking Water](https://github.com/neelghosh1234) 8 | - [Playing Guitar](https://github.com/SayanRicky) 9 | - [Programming](https://github.com/MrRoyzz) 10 | - [Sleeping](https://github.com/argha7417) 11 | - [Reading](https://github.com/KristenHarman) 12 | - [Online gaming](https://github.com/subhajit9932) 13 | - [Painting](https://github.com/aamrin786) 14 | [reading book](https://github.com/Mainak57) 15 | - [Football](https://github.com/Pranjal360Agarwal) 16 | - [Cricket](https://github.com/aryan0103raj) 17 | - [Football](https://github.com/SayanKundu10) 18 | - [coding](https://github.com/debmalyabhar) 19 | - [coding](https://github.com/soumya07ad) 20 | - [coding](https://github.com/AllMightLegend) 21 | - [gaming](https://github.com/ChaHaoIn) 22 | - [Dating](https://github.com/ChaHaoIn) 23 | - [Singing](https://github.com/hello70world) 24 | -------------------------------------------------------------------------------- /Home.css: -------------------------------------------------------------------------------- 1 | .featuredTitle { 2 | color: white; 3 | font-size: 35px; 4 | font-weight: 600; 5 | justify-content: center; 6 | display: flex; 7 | letter-spacing: 2px; 8 | margin-top: 20px; 9 | margin-bottom: 30px; 10 | } 11 | 12 | .albums { 13 | display: flex; 14 | flex-wrap: wrap; 15 | justify-content: center; 16 | margin: 0 auto; 17 | max-width: 1000px; 18 | width: 100%; 19 | gap: 20px; 20 | row-gap: 50px; 21 | -webkit-box-pack: start; 22 | } 23 | 24 | .albumSelection { 25 | color:rgb(205, 203, 203); 26 | text-align: center; 27 | transition: transform .4s; 28 | } 29 | 30 | .albumSelection:hover { 31 | color: white; 32 | transform: scale(1.05); 33 | } 34 | -------------------------------------------------------------------------------- /Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import "./Home.css"; 4 | import { Tabs } from "antd"; 5 | import { library } from "../helpers/albumList"; 6 | 7 | const { TabPane } = Tabs; 8 | 9 | const Home = () => { 10 | return ( 11 | <> 12 | 13 | 14 |

Today Is The Day

15 |
16 | {library.map((e) => ( 17 | 18 | bull 23 |

{e.title}

24 | 25 | ))} 26 |
27 |
28 | 29 |

Pop Music

30 |
31 | {library.slice(7, 13).map((e) => ( 32 | 33 | bull 38 |

{e.title}

39 | 40 | ))} 41 |
42 |

Top Hits

43 |
44 | {library.slice(5, 11).map((e) => ( 45 | 46 | bull 51 |

{e.title}

52 | 53 | ))} 54 |
55 |

Country

56 |
57 | {library.slice(0, 6).map((e) => ( 58 | 59 | bull 64 |

{e.title}

65 | 66 | ))} 67 |
68 |

Classics

69 |
70 | {library.slice(5, 11).map((e) => ( 71 | 72 | bull 77 |

{e.title}

78 | 79 | ))} 80 |
81 |
82 | 83 |

Hot Off The Press

84 |
85 | {library.map((e) => ( 86 | 87 | bull 92 |

{e.title}

93 | 94 | ))} 95 |
96 |
97 |
98 | 99 | ); 100 | }; 101 | 102 | export default Home; 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # De-Fi-Sportify Sub-branch Project of MegaVerse Corporation 2 | 3 | [![Open Source Love](https://firstcontributions.github.io/open-source-badges/badges/open-source-v1/open-source.svg)](https://github.com/firstcontributions/open-source-badges) 4 | [](https://join.slack.com/t/newworkspace-4xu3381/shared_invite/zt-1i1hem6hj-OmdKC6b0~Nklgb9VPrjN~A) 5 | [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) 6 | [![Open Source Helpers](https://www.codetriage.com/roshanjossey/first-contributions/badges/users.svg)](https://www.codetriage.com/roshanjossey/first-contributions) 7 | 8 | # First a fall Sign in for Hacktoberfest 2022 9 | 10 | # Contribute in these 4 md files for 4 PR 11 | 1. GMAIL 12 | 2. College 13 | 3. Hobby 14 | 4. CONTRIBUTOR (Search this files and just update to get a PR accepted) 15 | #### Your PR will automatically able to merge and enjoy free t-shirt or Plant a tree of your name from Hacktoberfest 2022 16 | 17 | ## Thanks to all the contributors ❤️ 18 | 19 | 20 | 21 | #### _Read this in [other languages](translations/Translations.md)._ 22 | 23 | [Shqip](translations/README.al.md) 24 | [Uzbek language](translations/README.uz.md) 25 | [Azərbaycan dili](translations/README.aze.md) 26 | [বাংলা](translations/README.bn.md) 27 | [Bulgarian](translations/README.bg.md) 28 | [Português](translations/README.pt_br.md) 29 | [Català](translations/README.ca.md) 30 | [中文 (Simplified)](translations/README.zh-cn.md) 31 | [Czech](translations/README.cs.md) 32 | [Deutsch](translations/README.de.md) 33 | [Dansk](translations/README.da.md) 34 | [العربية](translations/README.eg.md) 35 | [Española](translations/README.es.md) 36 | [Française](translations/README.fr.md) 37 | [Galego](translations/README.gl.md) 38 | [Ελληνικά](translations/README.gr.md) 39 | [ქართული](translations/README.ge.md) 40 | [Magyar](translations/README.hu.md) 41 | [Bahasa Indonesia](translations/README.id.md) 42 | [עִברִית](translations/README.hb.md) 43 | [हिंदी/ગુજરાતી/मराठी/മലയാളം/ಕನ್ನಡ/తెలుగు/छत्तीसगढ़ी/বাংলা/தமிழ்](translations/Translations.md) 44 | [தமிழ்](translations/README.ta.md) 45 | [فارسی](translations/README.fa.md) 46 | [Italiano](translations/README.it.md) 47 | [日本語](translations/README.ja.md) 48 | [සිංහල](translations/README.si.md) 49 | [Kiswahili (Kenya)](translations/README.kws.md) 50 | [한국어 한국어](translations/README.ko.md) 51 | [Lietuvių kalba](translations/README.lt.md) 52 | [Limba Română Limba Română](translations/README.ro.md) 53 | [မြန်မာ](translations/README.mm_unicode.md) 54 | [Македонски](translations/README.mk.md) 55 | [Español de México](translations/README.mx.md) 56 | [Bahasa Melayu / بهاس ملايو‎ / Malay](translations/README.my.md) 57 | [Dutch](translations/README.nl.md) 58 | [Norsk](translations/README.no.md) 59 | [नेपाली](translations/README.np.md) 60 | [Wikang Filipino](translations/README.tl.md) 61 | [English (Pirate)](translations/README.en-pirate.md) 62 | [اردو](translations/README.ur.md) 63 | [Polski](translations/README.pl.md) 64 | [Português (Portugal)](translations/README.pt-pt.md) 65 | [Русский язык](translations/README.ru.md) 66 | [عربى](translations/README.ar.md) 67 | [Svenska](translations/README.se.md) 68 | [Slovenčina](translations/README.slk.md) 69 | [Slovenščina](translations/README.sl.md) 70 | [ภาษาไทย](translations/README.th.md) 71 | [Türkçe](translations/README.tr.md) 72 | [中文(Traditional)](translations/README.zh-tw.md) 73 | [Українська](translations/README.ua.md) 74 | [Tiếng Việt](translations/README.vn.md) 75 | [Zulu (South Africa)](translations/README.zul.md) 76 | [Afrikaans (South Africa)](translations/README.afk.md) 77 | [Igbo (Nigeria)](translations/README.igb.md) 78 | [Yoruba (Nigeria)](translations/README.yor.md) 79 | [Hausa (Nigeria)](translations/README.hau.md) 80 | [Latvia](translations/README.lv.md) 81 | [Suomeksi](translations/README.fi.md) 82 | [Беларуская мова](translations/README.by.md) 83 | [Српски](translations/README.sr.md) 84 | [Қазақша](translations/README.kz.md) 85 | [Bosanski](translations/README.bih.md) 86 | 87 | 88 | # First Contributions 89 | 90 | This project aims to simplify and guide the way beginners make their first contribution. If you are looking to make your first contribution, follow the steps below. 91 | 92 | _If you're not comfortable with command line, [here are tutorials using GUI tools.](#tutorials-using-other-tools)_ 93 | 94 | 95 | fork this repository 96 | 97 | #### If you don't have git on your machine, [install it](https://help.github.com/articles/set-up-git/). 98 | 99 | ## Fork this repository 100 | 101 | Fork this repository by clicking on the fork button on the top of this page. 102 | This will create a copy of this repository in your account. 103 | 104 | ## Clone the repository 105 | 106 | clone this repository 107 | 108 | Now clone the forked repository to your machine. Go to your GitHub account, open the forked repository, click on the code button and then click the _copy to clipboard_ icon. 109 | 110 | Open a terminal and run the following git command: 111 | 112 | ``` 113 | git clone "url you just copied" 114 | ``` 115 | 116 | where "url you just copied" (without the quotation marks) is the url to this repository (your fork of this project). See the previous steps to obtain the url. 117 | 118 | copy URL to clipboard 119 | 120 | For example: 121 | 122 | ``` 123 | git clone https://github.com/arpan-mondal/De-Fi-Sportify- 124 | ``` 125 | 126 | where `this-is-you` is your GitHub username. Here you're copying the contents of the first-contributions repository on GitHub to your computer. 127 | 128 | ## Create a branch 129 | 130 | Change to the repository directory on your computer (if you are not already there): 131 | 132 | ``` 133 | cd first-contributions 134 | ``` 135 | 136 | Now create a branch using the `git switch` command: 137 | 138 | ``` 139 | git switch -c your-new-branch-name 140 | ``` 141 | 142 | For example: 143 | 144 | ``` 145 | git switch -c add-alonzo-church 146 | ``` 147 | 148 | ## Make necessary changes and commit those changes 149 | 150 | Now open `Contributors.md` file in a text editor, add your name to it. Don't add it at the beginning or end of the file. Put it anywhere in between. Now, save the file. 151 | 152 | git status 153 | 154 | If you go to the project directory and execute the command `git status`, you'll see there are changes. 155 | 156 | Add those changes to the branch you just created using the `git add` command: 157 | 158 | ``` 159 | git add Contributors.md 160 | ``` 161 | 162 | Now commit those changes using the `git commit` command: 163 | 164 | ``` 165 | git commit -m "Add your-name to Contributors list" 166 | ``` 167 | 168 | replacing `your-name` with your name. 169 | 170 | ## Push changes to GitHub 171 | 172 | Push your changes using the command `git push`: 173 | 174 | ``` 175 | git push origin -u your-branch-name 176 | ``` 177 | 178 | replacing `your-branch-name` with the name of the branch you created earlier. 179 | 180 |
181 | If you get any errors while pushing, click here: 182 | 183 | - ### Authentication Error 184 |
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
185 |   remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
186 |   fatal: Authentication failed for 'https://github.com//first-contributions.git/'
187 | Go to [GitHub's tutorial](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account) on generating and configuring an SSH key to your account. 188 | 189 |
190 | 191 | ## Submit your changes for review 192 | 193 | If you go to your repository on GitHub, you'll see a `Compare & pull request` button. Click on that button. 194 | 195 | 196 | 197 | Now submit the pull request. 198 | 199 | 200 | 201 | Soon I'll be merging all your changes into the main branch of this project. You will get a notification email once the changes have been merged. 202 | 203 | ## Where to go from here? 204 | 205 | Congrats! You just completed the standard _fork -> clone -> edit -> pull request_ workflow that you'll often encounter as a contributor! 206 | 207 | Celebrate your contribution and share it with your friends and followers. 208 | You could join our slack team if you need any help or have any questions. 209 | 210 | Now let's get you started with contributing to other projects. We've compiled a list of projects with easy issues you can get started on. Check out [the list of projects in the web app](https://firstcontributions.github.io/#project-list). 211 | 212 | ### [Additional material](additional-material/git_workflow_scenarios/additional-material.md) 213 | 214 | ## Tutorials Using Other Tools 215 | 216 | | GitHub Desktop | Visual Studio 2017 | GitKraken | VS Code | Sourcetree App | IntelliJ IDEA | 217 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 218 | | [GitHub Desktop](gui-tool-tutorials/github-desktop-tutorial.md) | [Visual Studio 2017](gui-tool-tutorials/github-windows-vs2017-tutorial.md) | [GitKraken](gui-tool-tutorials/gitkraken-tutorial.md) | [Visual Studio Code](gui-tool-tutorials/github-windows-vs-code-tutorial.md) | [Atlassian Sourcetree](gui-tool-tutorials/sourcetree-macos-tutorial.md) | [IntelliJ IDEA](gui-tool-tutorials/github-windows-intellij-tutorial.md) | 219 | -------------------------------------------------------------------------------- /albumList.js: -------------------------------------------------------------------------------- 1 | export const library = [ 2 | { 3 | title: "Hyperspace", 4 | image: 5 | "https://www.digitalartsonline.co.uk/cmsdata/slideshow/3776245/beck_-_hyperspace.jpg" 6 | }, 7 | { 8 | title: "Non Fungible", 9 | image: 10 | "https://ipfs.moralis.io:2053/ipfs/QmTbF7gLPmtrZuNr7kZJ8iufxBVEPqrAdJsxujSmu9qbuh/art/NonFungible.png", 11 | contract: "0x1C45d483515A92fCDD0aa5eaF03dbdf1B7d6898a", 12 | }, 13 | { 14 | title: "The Unknown", 15 | image: 16 | "https://350927.smushcdn.com/1388247/wp-content/uploads/2020/11/Unknown-Album-Cover-PP1.jpg?lossy=0&strip=1&webp=1", 17 | }, 18 | { 19 | title: "Get Rich Or Die Tryin'", 20 | image: "https://m.media-amazon.com/images/I/61AYpcmBtpL._SY450_.jpg", 21 | }, 22 | { 23 | title: "Starboy", 24 | image: 25 | "https://i.pinimg.com/originals/49/a0/7a/49a07a20041787942f62dbe900573ecb.jpg", 26 | }, 27 | { 28 | title: "Evolve", 29 | image: 30 | "https://external-preview.redd.it/v_5XzwOWnjqrz5gBDfENNoMV9Kl8OAAy3015hcTsVYs.jpg?auto=webp&s=5485881fc8e107c14bca6d16c61fa085a78b70b6", 31 | }, 32 | { 33 | title: "Ball Breaker", 34 | image: 35 | "https://scale.coolshop-cdn.com/product-media.coolshop-cdn.com/AN5W2E/b0cb0df8c30d479da36443c10bc85b96.jpg/f/ac-dc-ballbreaker-framed-album-cover-30x30cm.jpg", 36 | }, 37 | { 38 | title: "Flavors", 39 | image: 40 | "https://fiverr-res.cloudinary.com/images/q_auto,f_auto/gigs/125831034/original/c2e1426823f87d01f7b43085c6b20e61b0736794/create-you-a-special-artistic-album-cover.png", 41 | }, 42 | { 43 | title: "Shakira", 44 | image: 45 | "https://upload.wikimedia.org/wikipedia/en/3/35/Shakira_-_Shakira_%282014%29.png", 46 | }, 47 | { 48 | title: "Adele 21", 49 | image: 50 | "https://upload.wikimedia.org/wikipedia/fi/5/51/Adele21albumikansi.jpg", 51 | }, 52 | { 53 | title: "Strange Clouds", 54 | image: 55 | "https://upload.wikimedia.org/wikipedia/en/6/69/B.o.B_-_Strange_Clouds_-_LP_Cover.jpg", 56 | }, 57 | { 58 | title: "Shadow", 59 | image: 60 | "https://ipfs.moralis.io:2053/ipfs/QmX5NMV8hh1g5EcebX1e2Y55uQnVnKPk8YzW37wpnRWfXp/media/6", 61 | contract: "0x8A68d4e28515815CD6026416f4B2a4B647796F3E", 62 | }, 63 | { 64 | title: "Arctic Monkeys", 65 | image: 66 | "https://i.pinimg.com/originals/c1/83/44/c1834474ec73e7faa475d68fdd791a48.jpg", 67 | }, 68 | { 69 | title: "My Everything", 70 | image: 71 | "https://upload.wikimedia.org/wikipedia/en/d/d5/Ariana_Grande_My_Everything_2014_album_artwork.png", 72 | }, 73 | { 74 | title: "Have A Nice Day", 75 | image: 76 | "https://upload.wikimedia.org/wikipedia/de/thumb/e/e5/Bon_Jovi_Have_a_Nice_Day.svg/1200px-Bon_Jovi_Have_a_Nice_Day.svg.png", 77 | }, 78 | { 79 | title: "Happier", 80 | image: 81 | "https://upload.wikimedia.org/wikipedia/en/e/e5/Marshmello_and_Bastille_Happier.png", 82 | }, 83 | { 84 | title: "Stoney", 85 | image: 86 | "https://upload.wikimedia.org/wikipedia/fi/d/d9/Post_Malone_Stoney.jpg", 87 | }, 88 | { 89 | title: "The Eminem Show", 90 | image: 91 | "https://upload.wikimedia.org/wikipedia/en/3/35/The_Eminem_Show.jpg", 92 | }, 93 | 94 | ]; -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import { BrowserRouter } from "react-router-dom"; 7 | import { MoralisProvider } from "react-moralis"; 8 | 9 | 10 | ReactDOM.render( 11 | 12 | 13 | 14 | 15 | 16 | 17 | , 18 | document.getElementById('root') 19 | ); 20 | 21 | // If you want to start measuring performance in your app, pass a function 22 | // to log results (for example: reportWebVitals(console.log)) 23 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 24 | reportWebVitals(); 25 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /metadata.js: -------------------------------------------------------------------------------- 1 | let fs = require("fs"); 2 | let axios = require("axios"); 3 | 4 | let songs = []; 5 | let durations = []; 6 | let ipfsArray = []; 7 | 8 | for (let i = 0; i < songs.length; i++) { 9 | ipfsArray.push({ 10 | path: `metadata/${i}.json`, 11 | content: { 12 | image: `ipfs://xxx`, //xxx = hash 13 | name: songs[i], 14 | animation_url: `ipfs://xxx/`, //xxx = hash 15 | duration: durations[i], 16 | artist: "", 17 | year: "" 18 | }, 19 | }); 20 | } 21 | 22 | axios.post("https://deep-index.moralis.io/api/v2/ipfs/uploadFolder", ipfsArray, { 23 | headers: { 24 | "X-API-KEY": 25 | "", 26 | "Content-Type": "application/json", 27 | accept: "application/json", 28 | }, 29 | }) 30 | .then((res) => { 31 | console.log(res.data); 32 | }) 33 | .catch((error) => { 34 | console.log(error); 35 | }); 36 | -------------------------------------------------------------------------------- /music.js: -------------------------------------------------------------------------------- 1 | let fs = require("fs"); 2 | let axios = require("axios"); 3 | 4 | let media = []; 5 | let ipfsArray = []; 6 | let promises = []; 7 | 8 | for (let i = 0; i < media.length; i++) { 9 | promises.push( 10 | new Promise((res, rej) => { 11 | fs.readFile(`${__dirname}/export/${media[i]}`, (err, data) => { 12 | if (err) rej(); 13 | ipfsArray.push({ 14 | path: `media/${i}`, 15 | content: data.toString("base64"), 16 | }); 17 | res(); 18 | }); 19 | }) 20 | ); 21 | } 22 | Promise.all(promises).then(() => { 23 | axios 24 | .post("https://deep-index.moralis.io/api/v2/ipfs/uploadFolder", ipfsArray, { 25 | headers: { 26 | "X-API-KEY": 27 | "", 28 | "Content-Type": "application/json", 29 | accept: "application/json", 30 | }, 31 | }) 32 | .then((res) => { 33 | console.log(res.data); 34 | }) 35 | .catch((error) => { 36 | console.log(error); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amazon-clone", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.2", 7 | "@testing-library/react": "^12.1.2", 8 | "@testing-library/user-event": "^13.5.0", 9 | "antd": "^4.18.7", 10 | "moralis": "^1.3.2", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-moralis": "^1.3.1", 14 | "react-router-dom": "6", 15 | "react-scripts": "5.0.0", 16 | "web-vitals": "^2.1.4" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | // Also visit: MegaVerse https://www.megaverse.co.in/ 6 | import '@testing-library/jest-dom'; 7 | -------------------------------------------------------------------------------- /useAlbum.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { useMoralis, useMoralisWeb3Api } from "react-moralis"; 3 | 4 | export const useAlbum = (contract) => { 5 | const { token } = useMoralisWeb3Api(); 6 | const { isInitialized } = useMoralis(); 7 | 8 | const [album, setAlbum] = useState(); 9 | 10 | useEffect(() => { 11 | if (isInitialized) { 12 | fetchAlbum().then((songs) => { 13 | setAlbum(songs.result) 14 | }); 15 | } 16 | }, [isInitialized, contract]); 17 | 18 | const fetchAlbum = async () => { 19 | return await token 20 | .getAllTokenIds({ 21 | address: contract, 22 | chain: "mumbai" 23 | }) 24 | .then((result) => result); 25 | }; 26 | 27 | return { fetchAlbum, album }; 28 | }; -------------------------------------------------------------------------------- /useAudio.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useRef } from "react"; 2 | import { useIPFS } from "./useIPFS"; 3 | 4 | const useAudio = (url) => { 5 | const {resolveLink} = useIPFS(); 6 | const [audio, setAudio] = useState(url); 7 | const [trackIndex, setTrackIndex] = useState(0); 8 | const [newSong, setNewSong] = useState(0); 9 | const [trackProgress, setTrackProgress] = useState(0); 10 | const [isPlaying, setIsPlaying] = useState(false); 11 | const [volume, setVolume] = useState(1); 12 | const audioRef = useRef(new Audio(resolveLink(JSON.parse(audio[trackIndex].metadata).animation_url))); 13 | 14 | const intervalRef = useRef(); 15 | const isReady = useRef(false); 16 | 17 | const { duration } = audioRef.current; 18 | 19 | const toPrevTrack = () => { 20 | if (trackIndex - 1 < 0) { 21 | setTrackIndex(audio.length - 1); 22 | } else { 23 | setTrackIndex(trackIndex - 1); 24 | } 25 | }; 26 | 27 | const toNextTrack = () => { 28 | if (trackIndex < audio.length - 1) { 29 | setTrackIndex(trackIndex + 1); 30 | } else { 31 | setTrackIndex(0); 32 | } 33 | }; 34 | 35 | useEffect(() => { 36 | toggle(); 37 | setAudio(url); 38 | if(trackIndex === 0){ 39 | setNewSong(newSong+1) 40 | }else{ 41 | setTrackIndex(0); 42 | } 43 | }, [url]); 44 | 45 | useEffect(() => { 46 | if (isPlaying) { 47 | audioRef.current.play(); 48 | startTimer(); 49 | } else { 50 | clearInterval(intervalRef.current); 51 | audioRef.current.pause(); 52 | } 53 | }, [isPlaying]); 54 | 55 | useEffect(() => { 56 | return () => { 57 | audioRef.current.pause(); 58 | clearInterval(intervalRef.current); 59 | }; 60 | }, []); 61 | 62 | useEffect(() => { 63 | audioRef.current.pause(); 64 | audioRef.current = new Audio(resolveLink(JSON.parse(audio[trackIndex].metadata).animation_url)); 65 | audioRef.current.volume = volume; 66 | setTrackProgress(Math.round(audioRef.current.currentTime)); 67 | if (isReady.current) { 68 | audioRef.current.play(); 69 | setIsPlaying(true); 70 | startTimer(); 71 | } else { 72 | isReady.current = true; 73 | } 74 | }, [trackIndex, newSong]); 75 | 76 | const toggle = () => setIsPlaying(!isPlaying); 77 | 78 | const startTimer = () => { 79 | clearInterval(intervalRef.current); 80 | 81 | intervalRef.current = setInterval(() => { 82 | if (audioRef.current.ended) { 83 | toNextTrack(); 84 | } else { 85 | setTrackProgress(Math.round(audioRef.current.currentTime)); 86 | } 87 | }, [1000]); 88 | }; 89 | 90 | const onSearch = (value) => { 91 | clearInterval(intervalRef.current); 92 | audioRef.current.currentTime = value; 93 | setTrackProgress(audioRef.current.currentTime); 94 | } 95 | 96 | const onSearchEnd = () => { 97 | if (!isPlaying) { 98 | setIsPlaying(true); 99 | } 100 | startTimer(); 101 | } 102 | 103 | const onVolume = (vol) => { 104 | setVolume(vol); 105 | audioRef.current.volume = vol; 106 | }; 107 | 108 | return [isPlaying, duration,toggle, toNextTrack, toPrevTrack, trackProgress, onSearch, onSearchEnd, onVolume, trackIndex]; 109 | }; 110 | 111 | export default useAudio; -------------------------------------------------------------------------------- /useIPFS.js: -------------------------------------------------------------------------------- 1 | // uploading to IPFS 2 | export const useIPFS = () => { 3 | const resolveLink = (url) => { 4 | if (!url || !url.includes("ipfs://")) return url; 5 | return url.replace("ipfs://", "https://gateway.ipfs.io/ipfs/"); 6 | }; 7 | 8 | return { resolveLink }; 9 | }; 10 | --------------------------------------------------------------------------------