Skip to content

Commit

Permalink
Merge branch 'master' into feat/homepage-revamp
Browse files Browse the repository at this point in the history
  • Loading branch information
kirkas authored Oct 8, 2024
2 parents daaec3d + a9afa5d commit 6bfb13e
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 18 deletions.
2 changes: 1 addition & 1 deletion apps/base-docs/tutorials/docs/0_deploy-with-foundry.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ To add the OpenZeppelin Contracts library to your project, run:
forge install openzeppelin/openzeppelin-contracts
```

In your project, delete the `src/Counter.sol` contract that was generated with the project and add the above code in a new file called `contracts/NFT.sol`. (You can also delete the `test/Counter.t.sol` and `script/Counter.s.sol` files, but you should add your own tests ASAP!).
In your project, delete the `src/Counter.sol` contract that was generated with the project and add the above code in a new file called `src/NFT.sol`. (You can also delete the `test/Counter.t.sol` and `script/Counter.s.sol` files, but you should add your own tests ASAP!).

To compile our basic NFT contract using Foundry, run:

Expand Down
29 changes: 29 additions & 0 deletions apps/web/app/frames/img-proxy/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NextRequest, NextResponse } from 'next/server';

export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const url = searchParams.get('url');

if (!url) {
return NextResponse.json({ error: 'Missing url' }, { status: 400 });
}

try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
const contentType = response.headers.get('content-type');
const imageBuffer = await response.arrayBuffer();
return new NextResponse(imageBuffer, {
status: 200,
headers: {
'Content-Type': contentType ?? 'application/octet-stream',
'Cache-Control': 'public, max-age=86400',
},
});
} catch (error) {
console.error('Error fetching image:', error);
return NextResponse.json({ error: 'Failed to fetch image' }, { status: 500 });
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ export default function FrameBuilder() {
alt="preview frame"
/>
) : (
<Frame url={debouncedNewFrameUrl} />
<Frame className="w-[414px]" url={debouncedNewFrameUrl} />
)}
</div>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import Modal from 'apps/web/src/components/Modal';
import { useFIDQuery } from 'apps/web/src/hooks/useFarcasterUserByFID';
import QRCode from 'qrcode.react';
import { useCallback, useMemo } from 'react';
import FarcasterIcon from './white-purple-farcaster-icon.svg';
import WPFarcasterIcon from './assets/white-purple-farcaster-icon.svg';
import PWFarcasterIcon from './assets/purple-white-farcaster-icon.svg';
import Image, { StaticImageData } from 'next/image';

export default function FarcasterAccountModal() {
const { farcasterSignerState, showFarcasterQRModal, setShowFarcasterQRModal } = useFrameContext();
Expand All @@ -19,7 +21,7 @@ export default function FarcasterAccountModal() {
[farcasterSignerState.signer],
);
const loading = useMemo(
() => !!farcasterSignerState.isLoadingSigner ?? false,
() => !!farcasterSignerState.isLoadingSigner,
[farcasterSignerState.isLoadingSigner],
);
const handleButtonClick = useCallback(() => {
Expand All @@ -32,21 +34,31 @@ export default function FarcasterAccountModal() {

return (
<Modal isOpen={showFarcasterQRModal} onClose={handleModalClose}>
<div className="max-w-72 rounded-lg bg-white">
<div className="min-w-80 rounded-lg bg-white">
{/* Sign-in section when the user is not signed in */}
{!farcasterUser && (
<div className="flex flex-col items-center gap-4">
<div className="flex flex-col items-center">
<h1 className="text-xl font-bold text-gray-80">Sign in with Farcaster</h1>
<p className="mt-2 text-sm text-gray-50">Use your Farcaster account to sign in.</p>
<p className="mt-1 text-xs text-red-50">Be careful! This action costs warps.</p>
<Image
src={PWFarcasterIcon as StaticImageData}
alt="farcaster icon"
width={156}
height={148}
className="mb-6"
/>
<h1 className="mb-1 font-display text-2xl font-medium text-illoblack">
Sign in with Warpcast
</h1>
<p className="text-sm text-palette-foregroundMuted">
You will need to pay warps to sign in.
</p>
</div>

<Button
disabled={loading}
variant={ButtonVariants.Black}
type="button"
className="mt-4 w-full"
className="flex w-full items-center justify-center rounded-full"
onClick={handleButtonClick}
>
{loading ? 'Signing in...' : 'Sign in'}
Expand Down Expand Up @@ -118,7 +130,7 @@ function IdentityState({ user, onLogout }: { user: FarcasterSigner; onLogout: ()

const imageSettings = {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
src: FarcasterIcon.src,
src: WPFarcasterIcon.src,
x: undefined,
y: undefined,
height: 60,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { FrameUIComponents, FrameUITheme } from '@frames.js/render/ui';
import classNames from 'classnames';
import Image from 'next/image';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import baseLoading from './base-loading.gif';

type StylingProps = {
Expand Down Expand Up @@ -40,6 +40,14 @@ export const theme: FrameUITheme<StylingProps> = {
},
};

function isDataUrl(url: string) {
return /^data:image\/[a-zA-Z]+;base64,/.test(url);
}

function isSvgDataUrl(url: string) {
return url.startsWith('data:image/svg+xml');
}

type TransitionWrapperProps = {
aspectRatio: '1:1' | '1.91:1';
src: string;
Expand Down Expand Up @@ -75,6 +83,24 @@ function TransitionWrapper({

const ar = aspectRatio.replace(':', '/');

const style = useMemo(
() => ({
'--frame-image-aspect-ratio': ar,
...(isCssProperties(stylingProps.style) && stylingProps.style),
}),
[ar, stylingProps.style],
);

const assetSrc = useMemo(
() =>
isLoading || isSvgDataUrl(src)
? '' // todo: in the svg case, add an error state instead
: isDataUrl(src)
? src
: `/frames/img-proxy?url=${encodeURIComponent(src)}`,
[isLoading, src],
);

return (
<div className="relative">
{/* Loading Screen */}
Expand All @@ -90,15 +116,12 @@ function TransitionWrapper({
{/* Image */}
<img
{...stylingProps}
src={isLoading ? undefined : src}
src={assetSrc}
alt={alt}
onLoad={onImageLoadEnd}
onError={onImageLoadEnd}
data-aspect-ratio={ar}
style={{
'--frame-image-aspect-ratio': ar,
...(isCssProperties(stylingProps.style) && stylingProps.style),
}}
style={style}
className={classNames('transition-opacity duration-500', {
'opacity-0': isLoading || isTransitioning,
'opacity-100': !isLoading && !isTransitioning,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Link from 'next/link';
import { useCallback } from 'react';
import cornerGarnish from './corner-garnish.svg';
import frameIcon from './frame-icon.svg';
import { Icon } from 'apps/web/src/components/Icon/Icon';

function SectionContent() {
const { profileUsername, currentWalletIsProfileOwner } = useUsernameProfile();
Expand Down Expand Up @@ -72,10 +73,10 @@ function SectionContent() {
{currentWalletIsProfileOwner && (
<Link
onClick={handleAddFrameLinkClick}
className="text-sm text-palette-foregroundMuted"
className="rounded-lg bg-palette-backgroundAlternate p-2 text-sm text-palette-foreground"
href={`/name/${profileUsername}/configure-frames`}
>
+ Add Frame
<Icon name="plus" color="currentColor" width="12px" height="12px" />
</Link>
)}
</div>
Expand Down

0 comments on commit 6bfb13e

Please sign in to comment.