From 64fcee340125ab657bb160811652e1d4d6eab693 Mon Sep 17 00:00:00 2001 From: Stephan Cilliers <5469870+stephancill@users.noreply.github.com> Date: Tue, 2 Apr 2024 16:25:12 +0200 Subject: [PATCH] fix: image loading state --- .changeset/rich-needles-move.md | 5 +++++ packages/render/src/frame-ui.tsx | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 .changeset/rich-needles-move.md diff --git a/.changeset/rich-needles-move.md b/.changeset/rich-needles-move.md new file mode 100644 index 000000000..ac674266c --- /dev/null +++ b/.changeset/rich-needles-move.md @@ -0,0 +1,5 @@ +--- +"@frames.js/render": patch +--- + +fix: image loading state diff --git a/packages/render/src/frame-ui.tsx b/packages/render/src/frame-ui.tsx index 7c3918ac7..181270899 100644 --- a/packages/render/src/frame-ui.tsx +++ b/packages/render/src/frame-ui.tsx @@ -1,5 +1,5 @@ import { FrameTheme, FrameState } from "./types.js"; -import React, { ImgHTMLAttributes } from "react"; +import React, { ImgHTMLAttributes, useEffect } from "react"; import { FrameButton } from "frames.js"; export const defaultTheme: Required<FrameTheme> = { @@ -26,6 +26,14 @@ export type FrameUIProps = { /** A UI component only, that should be easy for any app to integrate */ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) { + const [isImageLoading, setIsImageLoading] = React.useState(true); + + const isLoading = !!frameState.isLoading || isImageLoading; + + useEffect(() => { + if (frameState.frame?.image) setIsImageLoading(true); + }, [frameState]); + const resolvedTheme = getThemeWithDefaults(theme ?? {}); if (!frameState.homeframeUrl) return <div>Missing frame url</div>; if (frameState.error) { @@ -47,7 +55,7 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) { alt="Frame image" width={"100%"} style={{ - filter: frameState.isLoading ? "blur(4px)" : undefined, + filter: isLoading ? "blur(4px)" : undefined, borderTopLeftRadius: `${resolvedTheme.buttonRadius}px`, borderTopRightRadius: `${resolvedTheme.buttonRadius}px`, border: `1px solid ${resolvedTheme.buttonBorderColor}`, @@ -58,6 +66,10 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) { ? "1/1" : "1.91/1", }} + onLoad={() => { + setIsImageLoading(false); + }} + onError={() => setIsImageLoading(false)} /> {frameState.frame.inputText && ( <input @@ -84,9 +96,9 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) { (frameButton: FrameButton, index: number) => ( <button type="button" - disabled={!!frameState.isLoading} + disabled={isLoading} className={`p-2 ${ - frameState.isLoading ? "bg-gray-100" : "" + isLoading ? "bg-gray-100" : "" } border text-sm text-gray-800 rounded`} style={{ flex: "1 1 0px", @@ -94,7 +106,7 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) { backgroundColor: resolvedTheme.buttonBg, borderColor: resolvedTheme.buttonBorderColor, color: resolvedTheme.buttonColor, - cursor: frameState.isLoading ? undefined : "pointer", + cursor: isLoading ? undefined : "pointer", }} onClick={() => frameState.onButtonPress(frameButton, index)} key={index}