mirror of
https://github.com/neynarxyz/create-farcaster-mini-app.git
synced 2025-12-06 17:32:31 -05:00
add initial demo app
This commit is contained in:
122
src/components/Demo.tsx
Normal file
122
src/components/Demo.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
import { useEffect, useCallback, useState } from "react";
|
||||
import sdk, { type FrameContext } from "@farcaster/frame-sdk";
|
||||
import { useAccount, useSendTransaction } from "wagmi";
|
||||
|
||||
import { Button } from "~/components/ui/Button";
|
||||
import { truncateAddress } from "~/lib/truncateAddress";
|
||||
|
||||
export default function Demo() {
|
||||
const [isSDKLoaded, setIsSDKLoaded] = useState(false);
|
||||
const [context, setContext] = useState<FrameContext>();
|
||||
const [isContextOpen, setIsContextOpen] = useState(false);
|
||||
|
||||
const { address, isConnected } = useAccount();
|
||||
const { sendTransaction } = useSendTransaction();
|
||||
|
||||
useEffect(() => {
|
||||
const load = async () => {
|
||||
setContext(await sdk.context);
|
||||
sdk.actions.ready();
|
||||
};
|
||||
if (sdk && !isSDKLoaded) {
|
||||
setIsSDKLoaded(true);
|
||||
load();
|
||||
}
|
||||
}, [isSDKLoaded]);
|
||||
|
||||
const openUrl = useCallback(() => {
|
||||
sdk.actions.openUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
||||
}, []);
|
||||
|
||||
const close = useCallback(() => {
|
||||
sdk.actions.close();
|
||||
}, []);
|
||||
|
||||
const sendTx = useCallback(() => {
|
||||
sendTransaction({
|
||||
to: "0x4bBFD120d9f352A0BEd7a014bd67913a2007a878",
|
||||
data: "0x9846cd9efc000023c0",
|
||||
});
|
||||
}, [sendTransaction]);
|
||||
|
||||
const toggleContext = useCallback(() => {
|
||||
setIsContextOpen((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
if (!isSDKLoaded) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w-[300px] mx-auto py-4 px-2">
|
||||
<h1 className="text-2xl font-bold text-center mb-4">Frames v2 Demo</h1>
|
||||
|
||||
<div className="mb-4">
|
||||
<h2 className="font-2xl font-bold">Context</h2>
|
||||
<button
|
||||
onClick={toggleContext}
|
||||
className="flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<span
|
||||
className={`transform transition-transform ${
|
||||
isContextOpen ? "rotate-90" : ""
|
||||
}`}
|
||||
>
|
||||
➤
|
||||
</span>
|
||||
Tap to expand
|
||||
</button>
|
||||
|
||||
{isContextOpen && (
|
||||
<div className="p-4 mt-2 bg-gray-100 dark:bg-gray-800 rounded-lg">
|
||||
<pre className="font-mono text-xs whitespace-pre-wrap break-words max-w-[260px] overflow-x-">
|
||||
{JSON.stringify(context, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 className="font-2xl font-bold">Actions</h2>
|
||||
|
||||
<div className="mb-4">
|
||||
<div className="p-2 bg-gray-100 dark:bg-gray-800 rounded-lg my-2">
|
||||
<pre className="font-mono text-xs whitespace-pre-wrap break-words max-w-[260px] overflow-x-">
|
||||
sdk.actions.openUrl
|
||||
</pre>
|
||||
</div>
|
||||
<Button onClick={openUrl}>Open Link</Button>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<div className="p-2 bg-gray-100 dark:bg-gray-800 rounded-lg my-2">
|
||||
<pre className="font-mono text-xs whitespace-pre-wrap break-words max-w-[260px] overflow-x-">
|
||||
sdk.actions.close
|
||||
</pre>
|
||||
</div>
|
||||
<Button onClick={close}>Close Frame</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 className="font-2xl font-bold">Wallet</h2>
|
||||
|
||||
{address && (
|
||||
<div className="my-2 text-xs">
|
||||
Address: <pre className="inline">{truncateAddress(address)}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isConnected && (
|
||||
<>
|
||||
<div className="mb-4">
|
||||
<Button onClick={sendTx} disabled={!isConnected}>
|
||||
Send Transaction
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user