-
Notifications
You must be signed in to change notification settings - Fork 161
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
Showing
27 changed files
with
7,946 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,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
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,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
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,19 @@ | ||
# framegear | ||
|
||
Local frame devtools. | ||
|
||
## Getting Started | ||
|
||
First, run the development server: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
# or | ||
bun dev | ||
``` | ||
|
||
Open [http://localhost:1337](http://localhost:1337) with your browser to see the result. |
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,15 @@ | ||
import { NextRequest, NextResponse } from 'next/server'; | ||
|
||
export async function POST(req: NextRequest): Promise<NextResponse> { | ||
const data = await req.json(); | ||
try { | ||
const response = await fetch(data.url); | ||
const text = await response.text(); | ||
return NextResponse.json({ html: text }, { status: 200 }); | ||
} catch (error) { | ||
console.error('Error fetching frame:', error); | ||
return NextResponse.json({}, { status: 500, statusText: 'Internal Server Error' }); | ||
} | ||
} | ||
|
||
export const dynamic = 'force-dynamic'; |
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,29 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
:root { | ||
--foreground-rgb: 0, 0, 0; | ||
--background-start-rgb: 214, 219, 220; | ||
--background-end-rgb: 255, 255, 255; | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
--foreground-rgb: 255, 255, 255; | ||
--background-start-rgb: 0, 0, 0; | ||
--background-end-rgb: 0, 0, 0; | ||
} | ||
} | ||
|
||
body { | ||
color: rgb(var(--foreground-rgb)); | ||
background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) | ||
rgb(var(--background-start-rgb)); | ||
} | ||
|
||
@layer utilities { | ||
.text-balance { | ||
text-wrap: balance; | ||
} | ||
} |
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,22 @@ | ||
import type { Metadata } from 'next'; | ||
import { Inter } from 'next/font/google'; | ||
import './globals.css'; | ||
|
||
const inter = Inter({ subsets: ['latin'] }); | ||
|
||
export const metadata: Metadata = { | ||
title: 'framegear', | ||
description: 'local frame devtools', | ||
}; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body className={inter.className}>{children}</body> | ||
</html> | ||
); | ||
} |
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 @@ | ||
'use client'; | ||
import { Header } from '@/components/Header'; | ||
import { Frame } from '@/components/Frame'; | ||
import { FrameInput } from '@/components/FrameInput'; | ||
import { ValidationResults } from '@/components/ValidationResults'; | ||
import { MAX_WIDTH } from '@/utils/constants'; | ||
|
||
export default function Home() { | ||
return ( | ||
<div className="mx-auto flex flex-col items-center gap-8 pb-16"> | ||
<Header /> | ||
<div className={`grid w-full grid-cols-[5fr,4fr] gap-16 ${MAX_WIDTH}`}> | ||
<div className="flex flex-col gap-4"> | ||
<FrameInput /> | ||
<Frame /> | ||
</div> | ||
<ValidationResults /> | ||
</div> | ||
</div> | ||
); | ||
} |
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,90 @@ | ||
import { frameResultsAtom } from '@/utils/store'; | ||
import { useAtom } from 'jotai'; | ||
import { PropsWithChildren, useMemo } from 'react'; | ||
|
||
export function Frame() { | ||
const [results] = useAtom(frameResultsAtom); | ||
|
||
if (results.length === 0) { | ||
return <PlaceholderFrame />; | ||
} | ||
|
||
const latestFrame = results[results.length - 1]; | ||
|
||
if (!latestFrame.isValid) { | ||
return <ErrorFrame />; | ||
} | ||
|
||
return <ValidFrame tags={latestFrame.tags} />; | ||
} | ||
|
||
function ValidFrame({ tags }: { tags: Record<string, string> }) { | ||
const { image, imageAspectRatio, input, buttons } = useMemo(() => { | ||
const image = tags['fc:frame:image']; | ||
const imageAspectRatio = tags['fc:frame:image:aspect_ratio'] === '1:1' ? '1/1' : '1.91/1'; | ||
const input = tags['fc:frame:input:text']; | ||
// TODO: when debugger is live we will also need to extract actions, etc. | ||
const buttons = [1, 2, 3, 4].map((index) => { | ||
const key = `fc:frame:button:${index}`; | ||
const value = tags[key]; | ||
return value ? { key, value } : undefined; | ||
}); | ||
return { | ||
image, | ||
imageAspectRatio, | ||
input, | ||
buttons, | ||
}; | ||
}, [tags]); | ||
|
||
return ( | ||
<div> | ||
{/* eslint-disable-next-line @next/next/no-img-element */} | ||
<img className={`w-full rounded-t-xl aspect-[${imageAspectRatio}]`} src={image} alt="" /> | ||
<div className="flex flex-wrap gap-2 rounded-b-xl bg-[#f3f3f3] px-4 py-2"> | ||
{buttons.map((button) => | ||
button ? ( | ||
<button | ||
className="w-[45%] grow rounded-lg border border-[#cfd0d2] bg-white p-2 text-black" | ||
type="button" | ||
key={button.key} | ||
disabled | ||
> | ||
<span>{button.value}</span> | ||
</button> | ||
) : null, | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function ErrorFrame() { | ||
// TODO: implement -- decide how to handle | ||
// - simply show an error? | ||
// - best effort rendering of what they do have? | ||
return <PlaceholderFrame />; | ||
} | ||
|
||
function PlaceholderFrame() { | ||
return ( | ||
<div className="flex flex-col"> | ||
<div className="flex aspect-[1.91/1] w-full rounded-t-xl bg-[#855DCD]"></div> | ||
<div className="flex flex-wrap gap-2 rounded-b-xl bg-[#f3f3f3] px-4 py-2"> | ||
<FrameButton>Get Started</FrameButton> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function FrameButton({ children }: PropsWithChildren<{}>) { | ||
return ( | ||
<button | ||
className="w-[45%] grow rounded-lg border border-[#cfd0d2] bg-white p-2 text-black" | ||
type="button" | ||
disabled | ||
> | ||
<span>{children}</span> | ||
</button> | ||
); | ||
} |
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 @@ | ||
export { Frame } from './Frame'; |
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,38 @@ | ||
import { BORDER_COLOR } from '@/utils/constants'; | ||
import { fetchFrame } from '@/utils/fetchFrame'; | ||
import { frameResultsAtom } from '@/utils/store'; | ||
import { useAtom } from 'jotai'; | ||
import { useCallback, useState } from 'react'; | ||
|
||
export function FrameInput() { | ||
const [url, setUrl] = useState(''); | ||
const [_, setResults] = useAtom(frameResultsAtom); | ||
|
||
const getResults = useCallback(async () => { | ||
const result = await fetchFrame(url); | ||
setResults((prev) => [...prev, result]); | ||
}, [setResults, url]); | ||
|
||
return ( | ||
<div className="grid grid-cols-[2fr_1fr] gap-4"> | ||
<label className="flex flex-col"> | ||
Enter your frame URL | ||
<input | ||
className={`h-[40px] rounded-md border ${BORDER_COLOR} bg-[#191918] p-2`} | ||
type="url" | ||
placeholder="Enter URL" | ||
value={url} | ||
onChange={(e) => setUrl(e.target.value)} | ||
/> | ||
</label> | ||
<button | ||
className="h-[40px] self-end rounded-full bg-white text-black" | ||
type="button" | ||
onClick={getResults} | ||
disabled={url.length < 1} | ||
> | ||
Fetch | ||
</button> | ||
</div> | ||
); | ||
} |
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 @@ | ||
export { FrameInput } from './FrameInput'; |
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,54 @@ | ||
import { APP_NAME, BORDER_COLOR, MAX_WIDTH } from '@/utils/constants'; | ||
import Link from 'next/link'; | ||
|
||
export function Header() { | ||
return ( | ||
<div className={`flex w-full flex-col items-center gap-8 border-b ${BORDER_COLOR} py-8`}> | ||
<h1 className={`w-full ${MAX_WIDTH}`}> | ||
<AppName className="px-6 text-4xl" /> | ||
</h1> | ||
<Banner /> | ||
</div> | ||
); | ||
} | ||
|
||
function Banner() { | ||
return ( | ||
<div | ||
className={`flex w-full items-center justify-between rounded-lg border ${MAX_WIDTH} ${BORDER_COLOR} bg-[#141519] p-6`} | ||
> | ||
<div className="flex items-center gap-4"> | ||
<div className="text-3xl">⚒️</div> | ||
<section className="flex flex-col gap-2"> | ||
<h1 className="font-bold">This is a Frames debugger</h1> | ||
<p> | ||
Use <AppName /> to test out your Farcaster Frames and catch bugs! | ||
</p> | ||
</section> | ||
</div> | ||
<Link | ||
className="flex items-center gap-2 rounded-full bg-[#2E3137] px-4 py-2" | ||
href="https://docs.farcaster.xyz/reference/frames/spec" | ||
> | ||
<span>Farcaster Frames specs</span> {LINK_OUT_ICON} | ||
</Link> | ||
</div> | ||
); | ||
} | ||
|
||
function AppName({ className: additionalClasses = '' }: { className?: string }) { | ||
return ( | ||
<span className={`rounded-lg bg-slate-800 p-1 font-mono ${additionalClasses}`}>{APP_NAME}</span> | ||
); | ||
} | ||
|
||
const LINK_OUT_ICON = ( | ||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
<path | ||
d="M3 2C2.44772 2 2 2.44772 2 3V12C2 12.5523 2.44772 13 3 13H12C12.5523 13 13 12.5523 13 12V8.5C13 8.22386 12.7761 8 12.5 8C12.2239 8 12 8.22386 12 8.5V12H3V3L6.5 3C6.77614 3 7 2.77614 7 2.5C7 2.22386 6.77614 2 6.5 2H3ZM12.8536 2.14645C12.9015 2.19439 12.9377 2.24964 12.9621 2.30861C12.9861 2.36669 12.9996 2.4303 13 2.497L13 2.5V2.50049V5.5C13 5.77614 12.7761 6 12.5 6C12.2239 6 12 5.77614 12 5.5V3.70711L6.85355 8.85355C6.65829 9.04882 6.34171 9.04882 6.14645 8.85355C5.95118 8.65829 5.95118 8.34171 6.14645 8.14645L11.2929 3H9.5C9.22386 3 9 2.77614 9 2.5C9 2.22386 9.22386 2 9.5 2H12.4999H12.5C12.5678 2 12.6324 2.01349 12.6914 2.03794C12.7504 2.06234 12.8056 2.09851 12.8536 2.14645Z" | ||
fill="currentColor" | ||
fill-rule="evenodd" | ||
clip-rule="evenodd" | ||
></path> | ||
</svg> | ||
); |
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 @@ | ||
export { Header } from './Header'; |
46 changes: 46 additions & 0 deletions
46
framegear/components/ValidationResults/ValidationResults.tsx
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,46 @@ | ||
import { BORDER_COLOR } from '@/utils/constants'; | ||
import { frameResultsAtom } from '@/utils/store'; | ||
import { useAtom } from 'jotai'; | ||
|
||
export function ValidationResults() { | ||
const [results] = useAtom(frameResultsAtom); | ||
const latestResult = results[results.length - 1]; | ||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<h2> | ||
Frame validations{' '} | ||
{!!latestResult && ( | ||
<span className=""> | ||
(<b>tl;dr:</b> {latestResult.isValid ? 'lgtm ✅' : 'borked ❌'}) | ||
</span> | ||
)} | ||
</h2> | ||
<div className="flex w-full flex-col gap-4 rounded-xl bg-[#27282B] p-6"> | ||
{latestResult && ( | ||
<dl className="flex flex-col gap-4"> | ||
{Object.entries(latestResult.tags).map(([key, value]) => ( | ||
<ValidationEntry | ||
key={key} | ||
name={key} | ||
value={value} | ||
error={latestResult.errors[key]} | ||
/> | ||
))} | ||
</dl> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function ValidationEntry({ name, value, error }: { name: string; value: string; error?: string }) { | ||
return ( | ||
<div className={`flex flex-col gap-2 border-b ${BORDER_COLOR} pb-4 last:border-b-0 last:pb-0`}> | ||
<div className="flex justify-between"> | ||
<span>{name}</span> | ||
<span>{error ? '🔴' : '🟢'}</span> | ||
</div> | ||
<div className="font-mono">{value}</div> | ||
</div> | ||
); | ||
} |
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 @@ | ||
export { ValidationResults } from './ValidationResults'; |
Oops, something went wrong.