diff --git a/examples/buddybook/src/App.tsx b/examples/buddybook/src/App.tsx index 89634be..629b6eb 100644 --- a/examples/buddybook/src/App.tsx +++ b/examples/buddybook/src/App.tsx @@ -7,10 +7,11 @@ import { Button } from "@/components/ui/button" import { type LightNode } from "@waku/sdk" import { useWaku } from "@waku/react" import { Loader2 } from "lucide-react" -import { Routes, Route, Navigate, Link } from 'react-router-dom' +import { Routes, Route, Navigate, Link, useParams } from 'react-router-dom' import { BlockPayload, getMessagesFromStore, subscribeToFilter } from './lib/waku' import TelemetryOptIn from './components/TelemetryOptIn'; import TelemetryPage from './components/TelemetryPage'; +import SignSharedChain from './components/Chain/SignSharedChain' type Status = 'success' | 'in-progress' | 'error'; @@ -29,6 +30,7 @@ function App() { store: 'in-progress', }); const [telemetryOptIn, setTelemetryOptIn] = useState(null); + const [isLoadingChains, setIsLoadingChains] = useState(true); useEffect(() => { const storedOptIn = localStorage.getItem('telemetryOptIn'); @@ -65,12 +67,15 @@ function App() { console.log("Starting message listening") try { setWakuStatus(prev => ({ ...prev, store: 'in-progress' })); + setIsLoadingChains(true); const storeMessages = await getMessagesFromStore(node as LightNode) setChainsData(storeMessages) setWakuStatus(prev => ({ ...prev, store: 'success' })); } catch (error) { console.error("Error fetching messages from store:", error); setWakuStatus(prev => ({ ...prev, store: 'error' })); + } finally { + setIsLoadingChains(false); } try { @@ -115,10 +120,11 @@ function App() {
} /> - } /> + } /> } /> - } /> + } /> } /> + } />
diff --git a/examples/buddybook/src/components/Chain/SignSharedChain.tsx b/examples/buddybook/src/components/Chain/SignSharedChain.tsx new file mode 100644 index 0000000..867786f --- /dev/null +++ b/examples/buddybook/src/components/Chain/SignSharedChain.tsx @@ -0,0 +1,53 @@ +import React, { useEffect, useState } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import { BlockPayload } from '@/lib/waku'; +import SignChain from './SignChain'; +import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; + +interface SignSharedChainProps { + chainsData: BlockPayload[]; + onChainUpdate: (newBlock: BlockPayload) => void; +} + +const SignSharedChain: React.FC = ({ chainsData, onChainUpdate }) => { + const { chainUUID, blockUUID } = useParams(); + const [block, setBlock] = useState(null); + const navigate = useNavigate(); + + useEffect(() => { + const foundBlock = chainsData.find(b => b.chainUUID === chainUUID && b.blockUUID === blockUUID); + if (foundBlock) { + setBlock(foundBlock); + } + }, [chainsData, chainUUID, blockUUID]); + + if (!block) { + return ( + + + Chain Not Found + + +

The requested chain or block could not be found.

+ +
+
+ ); + } + + return ( + + + Sign Shared Chain + + +

{block.title}

+

{block.description}

+ +
+
+ ); +}; + +export default SignSharedChain; diff --git a/examples/buddybook/src/components/Chain/View/ChainList.tsx b/examples/buddybook/src/components/Chain/View/ChainList.tsx index a26c5da..39de0c7 100644 --- a/examples/buddybook/src/components/Chain/View/ChainList.tsx +++ b/examples/buddybook/src/components/Chain/View/ChainList.tsx @@ -1,15 +1,20 @@ import React from 'react'; -import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; +import { Card, CardHeader, CardTitle, CardContent} from "@/components/ui/card"; import { type BlockPayload } from '@/lib/waku'; import SignChain from '@/components/Chain/SignChain'; import { useEnsName } from 'wagmi'; +import { Button } from '@/components/ui/button'; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import QRCode from '@/components/QRCode'; +import { Loader2 } from "lucide-react"; interface ChainListProps { chainsData: BlockPayload[]; onChainUpdate: (newBlock: BlockPayload) => void; + isLoading: boolean; } -const ChainList: React.FC = ({ chainsData, onChainUpdate }) => { +const ChainList: React.FC = ({ chainsData, onChainUpdate, isLoading }) => { const handleChainUpdate = (newBlock: BlockPayload) => { onChainUpdate(newBlock); }; @@ -18,6 +23,8 @@ const ChainList: React.FC = ({ chainsData, onChainUpdate }) => { const childBlocks = chainsData.filter(b => b.parentBlockUUID === block.blockUUID); const totalSignatures = block.signatures.length + childBlocks.reduce((acc, child) => acc + child.signatures.length, 0); + const shareUrl = `${window.location.origin}/sign/${block.chainUUID ?? block.blockUUID}/${block.blockUUID}`; + return (
  • @@ -42,8 +49,28 @@ const ChainList: React.FC = ({ chainsData, onChainUpdate }) => {

    Block UUID: {block.blockUUID}

    -
    +
    + + + + + + + Share this Chain + +
    + +

    {shareUrl}

    + +
    +
    +
    @@ -70,7 +97,11 @@ const ChainList: React.FC = ({ chainsData, onChainUpdate }) => { Existing Chains - {rootBlocks.length === 0 ? ( + {isLoading ? ( +
    + +
    + ) : rootBlocks.length === 0 ? (

    No chains found.

    ) : (
      diff --git a/examples/buddybook/src/components/QRCode.tsx b/examples/buddybook/src/components/QRCode.tsx index 19814c7..a8b24c7 100644 --- a/examples/buddybook/src/components/QRCode.tsx +++ b/examples/buddybook/src/components/QRCode.tsx @@ -1,53 +1,18 @@ import React from 'react'; import { QRCodeSVG } from 'qrcode.react'; -import { BlockPayload } from '@/lib/waku'; -import { Button } from '@/components/ui/button'; -import { useEnsName } from 'wagmi'; interface QRCodeProps { - data: BlockPayload; - size?: number; - onSign?: () => void; + text: string; + width?: number; + height?: number; } -const QRCode: React.FC = ({ data, size = 256, onSign }) => { - const shareableLink = `${window.location.origin}/view/${data.chainUUID}/${data.blockUUID}`; - +const QRCode: React.FC = ({ text, width = 256, height = 256 }) => { return (
      - -
      -

      Title: {data.title}

      -

      Description: {data.description}

      -

      Timestamp: {new Date(data.timestamp).toLocaleString()}

      -

      Signed Message: {`0x${data.signedMessage.slice(2, 6)}....${data.signedMessage.slice(-6)}`}

      -

      Parent Block: {data.parentBlockUUID || 'Root'}

      -

      Signatures:

      -
        - {data.signatures.map((sig, index) => ( - - ))} -
      -
      - - {onSign && } +
      ); }; -const SignatureItem: React.FC<{ address: `0x${string}` }> = ({ address }) => { - const { data: ensName } = useEnsName({ address }); - - return ( -
    • - {ensName || `${address.slice(0, 6)}...${address.slice(-4)}`} -
    • - ); -}; - export default QRCode;