-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1e4bc0d
Showing
38 changed files
with
2,250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.env | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
socialfi-music-dapp/ | ||
├── contracts/ # Aptos Move Smart Contracts | ||
│ ├── music_nft.move # Handles NFT creation, ownership, metadata | ||
│ ├── royalty_distribution.move # Manages splitting of royalties to NFT owners, artists, platform | ||
│ ├── fractional_ownership.move # Allows for partial ownership of NFTs | ||
│ ├── tip_jar.move # Securely handles direct artist tipping | ||
│ ├── governance.move # (Optional) Community voting on platform decisions | ||
│ ├── token.move # (Optional) If using social tokens for community membership | ||
│ └── ... # Other contracts as needed (e.g., for subscriptions) | ||
├── client/ # Frontend (Web App) | ||
│ ├── public/ # Static assets | ||
│ │ ├── index.html | ||
│ │ ├── favicon.ico | ||
│ │ ├── logo.png | ||
│ │ └── ... | ||
│ ├── src/ # Source code | ||
│ │ ├── components/ # Reusable UI elements | ||
│ │ │ ├── MusicNFTCard.jsx | ||
│ │ │ ├── ArtistProfile.jsx | ||
│ │ │ ├── LiveStreamPlayer.jsx | ||
│ │ │ ├── FanClubChat.jsx | ||
│ │ │ ├── TipJar.jsx | ||
│ │ │ └── ... | ||
│ │ ├── pages/ # Main views | ||
│ │ │ ├── Home.jsx # Music feed | ||
│ │ │ ├── Explore.jsx # Discover new artists | ||
│ │ │ ├── ArtistPage.jsx | ||
│ │ │ ├── FanClubPage.jsx | ||
│ │ │ └── ... | ||
│ │ ├── utils/ # Helper functions | ||
│ │ │ ├── aptos.js # Aptos SDK interaction (transactions, etc.) | ||
│ │ │ ├── nft.js # NFT handling (metadata, image display, etc.) --- API: 66c8607b.997e5e6cd4be4dd8aa3560fed7d31fa5 | ||
│ │ │ ├── web3Storage.js # (Optional) For decentralized storage | ||
│ │ │ └── ... | ||
│ │ ├── context/ # (Optional) Context API for global state | ||
│ │ ├── hooks/ # Custom React hooks | ||
│ │ ├── store/ # (Optional) If using Redux/Zustand | ||
│ │ ├── App.jsx | ||
│ │ ├── index.jsx | ||
│ │ └── ... | ||
│ ├── package.json | ||
│ ├── .env # Environment variables | ||
│ └── ... | ||
server/ | ||
├── src/ # Source code | ||
│ ├── app.js # Main application entry point (or index.js) | ||
│ ├── routes/ # API route definitions | ||
│ │ ├── artists.js | ||
│ │ ├── nfts.js | ||
│ │ ├── fanclubs.js | ||
│ │ ├── live-streams.js | ||
│ │ └── auth.js # (For authentication/authorization) | ||
│ ├── controllers/ # Logic for handling API requests | ||
│ │ ├── artists.js | ||
│ │ ├── nfts.js | ||
│ │ ├── fanclubs.js | ||
│ │ ├── live-streams.js | ||
│ │ └── auth.js | ||
│ ├── middleware/ | ||
│ │ ├── auth.js | ||
│ │ └── errorHandler.js | ||
│ ├── utils/ # Helper functions (e.g., Aptos interaction) | ||
│ │ ├── aptos.js # Interaction with Aptos blockchain | ||
│ │ ├── caching.js # (Optional) Caching to reduce blockchain reads | ||
│ │ └── ... | ||
│ └── index.js # (If using a different entry point than app.js) | ||
├── public/ # Static files (if needed) | ||
│ ├── images/ | ||
│ └── ... | ||
├── tests/ # Unit and integration tests | ||
│ ├── routes/ | ||
│ ├── controllers/ | ||
│ └── ... | ||
│ ├── package.json | ||
│ └── ... | ||
├── scripts/ # Deployment scripts | ||
│ ├── deploy_contracts.sh | ||
│ ├── setup_testnet.sh | ||
│ └── ... | ||
├── tests/ # Unit, integration tests | ||
│ ├── contracts/ | ||
│ ├── client/ | ||
│ ├── server/ | ||
│ └── ... | ||
├── .gitignore | ||
├── README.md # Project documentation |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>SocialFi Music dApp</title> | ||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | ||
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> | ||
|
||
<script src="https://unpkg.com/@aptos-labs/wallet-adapter-react"></script> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
|
||
<script src="https://unpkg.com/web3modal"></script> | ||
|
||
<script src="%PUBLIC_URL%/bundle.js"></script> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useEffect } from 'react'; | ||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; | ||
import { WalletProvider, useWallet } from '@aptos-labs/wallet-adapter-react'; | ||
import { PetraWallet, MartianWallet } from 'petra-plugin-wallet-adapter'; | ||
import { createTheme, ThemeProvider, CssBaseline, Box, CircularProgress } from '@mui/material'; | ||
import { ToastContainer } from 'react-toastify'; | ||
import 'react-toastify/dist/ReactToastify.css'; | ||
import Home from './pages/Home'; | ||
import Explore from './pages/Explore'; | ||
import ArtistPage from './pages/ArtistPage'; | ||
import FanClubPage from './pages/FanClubPage'; | ||
import Navbar from './components/Navbar'; | ||
|
||
// Custom theme for Material UI | ||
const theme = createTheme({ | ||
// ... your custom theme settings | ||
}); | ||
|
||
function AppContent() { | ||
const { connected, connect } = useWallet(); | ||
const [isLoading, setIsLoading] = useState(true); | ||
|
||
useEffect(() => { | ||
const connectWallet = async () => { | ||
try { | ||
await connect(); | ||
setIsLoading(false); | ||
} catch (error) { | ||
console.error('Error connecting wallet:', error); | ||
toast.error('Could not connect wallet'); // Display error message to user | ||
} | ||
}; | ||
|
||
if (!connected) { | ||
connectWallet(); | ||
} else { | ||
setIsLoading(false); // If already connected, remove loading state | ||
} | ||
}, [connected]); | ||
|
||
return ( | ||
<ThemeProvider theme={theme}> | ||
<CssBaseline /> | ||
<Router> | ||
<Navbar /> | ||
<ToastContainer /> | ||
{isLoading ? ( // Show loading indicator until wallet is connected | ||
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}> | ||
<CircularProgress /> | ||
</Box> | ||
) : ( | ||
<Routes> | ||
<Route path="/" element={<Home />} /> | ||
<Route path="/explore" element={<Explore />} /> | ||
<Route path="/artist/:artistAddress" element={<ArtistPage />} /> | ||
<Route path="/fanclub/:artistAddress" element={<FanClubPage />} /> | ||
{/* ... other routes as needed */} | ||
</Routes> | ||
)} | ||
</Router> | ||
</ThemeProvider> | ||
); | ||
} | ||
|
||
function App() { | ||
const wallets = [ | ||
new PetraWallet(), | ||
new MartianWallet() | ||
]; | ||
|
||
return ( | ||
<WalletProvider | ||
wallets={wallets} | ||
autoConnect={true} | ||
> | ||
<AppContent /> | ||
</WalletProvider> | ||
); | ||
} | ||
|
||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import React, { useState, useEffect } from 'react'; | ||
import { useParams, useNavigate } from 'react-router-dom'; | ||
import { useWallet } from '@aptos-labs/wallet-adapter-react'; | ||
import { AptosClient, Types } from 'aptos'; | ||
import { toast } from 'react-toastify'; | ||
import 'react-toastify/dist/ReactToastify.css'; | ||
import MusicNFTCard from './MusicNFTCard'; | ||
import FanClubChat from './FanClubChat'; | ||
import { getArtistProfile, getNFTsByArtist } from '../utils/aptos'; // Assuming you have these utility functions | ||
|
||
const nodeUrl = 'https://fullnode.devnet.aptoslabs.com/v1'; | ||
const client = new AptosClient(nodeUrl); | ||
|
||
const ArtistProfile = () => { | ||
const { artistAddress } = useParams(); | ||
const { account } = useWallet(); | ||
const navigate = useNavigate(); | ||
const [artistNFTs, setArtistNFTs] = useState([]); | ||
const [artistProfile, setArtistProfile] = useState(null); | ||
|
||
useEffect(() => { | ||
const fetchData = async () => { | ||
try { | ||
const profile = await getArtistProfile(client, artistAddress); | ||
if (profile) { | ||
setArtistProfile(profile); | ||
} else { | ||
toast.error('Artist profile not found.'); | ||
navigate('/'); // Redirect to home if profile doesn't exist | ||
} | ||
|
||
const nfts = await getNFTsByArtist(client, artistAddress); | ||
setArtistNFTs(nfts); | ||
} catch (error) { | ||
console.error('Error fetching artist data:', error); | ||
toast.error('Error fetching artist data.'); | ||
} | ||
}; | ||
fetchData(); | ||
}, [artistAddress, navigate]); | ||
|
||
// ... (handleNFTPurchase and generateTransactionPayload functions remain the same) | ||
|
||
return ( | ||
<div className="artist-profile"> | ||
{artistProfile ? ( | ||
<> | ||
{/* ... (artist profile display) */} | ||
</> | ||
) : ( | ||
<p>Loading artist profile...</p> // Display loading message | ||
)} | ||
|
||
<h3>NFTs</h3> | ||
{!artistNFTs.length ? ( | ||
<p>No NFTs found for this artist.</p> | ||
) : ( | ||
<div className="nft-grid"> | ||
{artistNFTs.map((nft) => ( | ||
<MusicNFTCard | ||
key={nft.tokenId} | ||
nft={nft} | ||
onBuy={handleNFTPurchase} | ||
connectedWalletAddress={account?.address} | ||
/> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default ArtistProfile; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React, { useState, useEffect, useRef } from 'react'; | ||
import { useParams } from 'react-router-dom'; | ||
import { useWallet } from '@aptos-labs/wallet-adapter-react'; | ||
|
||
const FanClubChat = ({ artistAddress }) => { | ||
const { connected, account } = useWallet(); | ||
const [messages, setMessages] = useState([]); | ||
const [newMessage, setNewMessage] = useState(''); | ||
const chatContainerRef = useRef(null); | ||
|
||
useEffect(() => { | ||
// Fetch initial messages from the backend | ||
const fetchMessages = async () => { | ||
try { | ||
const response = await fetch(`/api/fanclubs/${artistAddress}/messages`); | ||
const data = await response.json(); | ||
setMessages(data); | ||
} catch (error) { | ||
console.error('Error fetching messages:', error); | ||
} | ||
}; | ||
fetchMessages(); | ||
|
||
// Set up real-time updates (e.g., WebSockets, polling) | ||
// ... (Implementation depends on your backend/chat service) | ||
}, [artistAddress]); | ||
|
||
useEffect(() => { | ||
// Auto-scroll to the bottom when new messages arrive | ||
if (chatContainerRef.current) { | ||
chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight; | ||
} | ||
}, [messages]); | ||
|
||
const handleSendMessage = async () => { | ||
if (!connected || !account) { | ||
alert('Please connect your wallet to join the chat.'); | ||
return; | ||
} | ||
|
||
try { | ||
const response = await fetch(`/api/fanclubs/${artistAddress}/messages`, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ | ||
sender: account.address, | ||
content: newMessage | ||
}) | ||
}); | ||
|
||
if (response.ok) { | ||
setNewMessage(''); | ||
// Fetch updated messages (or update via real-time updates) | ||
} else { | ||
console.error('Error sending message:', response.statusText); | ||
} | ||
} catch (error) { | ||
console.error('Error sending message:', error); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className="fan-club-chat"> | ||
<div className="chat-messages" ref={chatContainerRef}> | ||
{messages.map((message, index) => ( | ||
<div key={index} className={`message ${message.sender === account?.address ? 'sent' : 'received'}`}> | ||
<p>{message.content}</p> | ||
</div> | ||
))} | ||
</div> | ||
<div className="chat-input"> | ||
<input | ||
type="text" | ||
value={newMessage} | ||
onChange={(e) => setNewMessage(e.target.value)} | ||
/> | ||
<button onClick={handleSendMessage}>Send</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default FanClubChat; |
Oops, something went wrong.