@@ -558,8 +558,10 @@ export function useFrameApp({
558558type UseFrameAppInIframeReturn =
559559 | Exclude < UseFrameAppReturn , { status : "success" } >
560560 | ( {
561- onLoad : ( event : React . SyntheticEvent < HTMLIFrameElement > ) => void ;
562- src : string | undefined ;
561+ iframeProps : {
562+ onLoad : ( event : React . SyntheticEvent < HTMLIFrameElement > ) => void ;
563+ src : string | undefined ;
564+ } ;
563565 } & Extract < UseFrameAppReturn , { status : "success" } > ) ;
564566
565567/**
@@ -578,15 +580,20 @@ type UseFrameAppInIframeReturn =
578580 * const farcasterSigner = useFarcasterSigner({
579581 * // ...
580582 * });
581- * const frameAppProps = useFrameAppInIframe({
583+ * const frameApp = useFrameAppInIframe({
582584 * provider,
583585 * farcasterSigner,
584586 * // frame returned by useFrame() hook
585587 * frame: frameState.frame,
586588 * // ... handlers for frame app actions
587589 * });
588590 *
589- * return <iframe {...frameAppProps} />;
591+ * if (frameApp.status !== 'success') {
592+ * // render loading or error
593+ * return null;
594+ * }
595+ *
596+ * return <iframe {...frameApp.iframeProps} />;
590597 * }
591598 * ```
592599 */
@@ -625,27 +632,32 @@ export function useFrameAppInIframe(
625632 return {
626633 ...frameApp ,
627634 status : "success" ,
628- src : frameApp . frame . frame . button ?. action ?. url ,
629- onLoad ( event ) {
630- logDebugRef . current (
631- "@frames.js/render/unstable-use-frame-app: iframe loaded"
632- ) ;
633-
634- if ( ! ( event . currentTarget instanceof HTMLIFrameElement ) ) {
635- // eslint-disable-next-line no-console -- provide feedback to the developer
636- console . error (
637- '@frames.js/render/unstable-use-frame-app: "onLoad" called but event target is not an iframe'
635+ iframeProps : {
636+ src : frameApp . frame . frame . button ?. action ?. url ,
637+ onLoad ( event ) {
638+ logDebugRef . current (
639+ "@frames.js/render/unstable-use-frame-app: iframe loaded"
638640 ) ;
639641
640- return ;
641- }
642- if ( ! event . currentTarget . contentWindow ) {
643- return ;
644- }
642+ if ( ! ( event . currentTarget instanceof HTMLIFrameElement ) ) {
643+ // eslint-disable-next-line no-console -- provide feedback to the developer
644+ console . error (
645+ '@frames.js/render/unstable-use-frame-app: "onLoad" called but event target is not an iframe'
646+ ) ;
647+
648+ return ;
649+ }
650+ if ( ! event . currentTarget . contentWindow ) {
651+ return ;
652+ }
645653
646- const endpoint = windowEndpoint ( event . currentTarget . contentWindow ) ;
654+ const endpoint = windowEndpoint (
655+ event . currentTarget . contentWindow
656+ ) ;
647657
648- unregisterEndpointRef . current = frameApp . registerEndpoint ( endpoint ) ;
658+ unregisterEndpointRef . current =
659+ frameApp . registerEndpoint ( endpoint ) ;
660+ } ,
649661 } ,
650662 } ;
651663 }
@@ -665,12 +677,14 @@ type MessageEventListener = (event: ReactNativeMessageEvent) => void;
665677type UseFrameAppInWebViewReturn =
666678 | Exclude < UseFrameAppReturn , { status : "success" } >
667679 | ( Extract < UseFrameAppReturn , { status : "success" } > & {
668- source : WebViewProps [ "source" ] ;
669- onMessage : NonNullable < WebViewProps [ "onMessage" ] > ;
670- injectedJavaScriptBeforeContentLoaded : NonNullable <
671- WebViewProps [ "injectedJavaScriptBeforeContentLoaded" ]
672- > ;
673- ref : LegacyRef < WebView > ;
680+ webViewProps : {
681+ source : WebViewProps [ "source" ] ;
682+ onMessage : NonNullable < WebViewProps [ "onMessage" ] > ;
683+ injectedJavaScriptBeforeContentLoaded : NonNullable <
684+ WebViewProps [ "injectedJavaScriptBeforeContentLoaded" ]
685+ > ;
686+ ref : LegacyRef < WebView > ;
687+ } ;
674688 } ) ;
675689
676690const webViewEventParser = z . record ( z . any ( ) ) ;
@@ -691,15 +705,20 @@ const webViewEventParser = z.record(z.any());
691705 * const farcasterSigner = useFarcasterSigner({
692706 * // ...
693707 * });
694- * const frameAppProps = useFrameAppInWebView({
708+ * const frameApp = useFrameAppInWebView({
695709 * provider,
696710 * farcasterSigner,
697711 * // frame returned by useFrame() hook
698712 * frame: frameState.frame,
699713 * // ... handlers for frame app actions
700714 * });
701715 *
702- * return <WebView {...frameAppProps }/>;
716+ * if (frameApp.status !== 'success') {
717+ * // render loading or error
718+ * return null;
719+ * }
720+ *
721+ * return <WebView {...frameApp.webViewProps} />;
703722 * }
704723 * ```
705724 */
@@ -748,112 +767,116 @@ export function useFrameAppInWebView(
748767
749768 return {
750769 ...frameApp ,
751- source : frame . button ?. action ?. url
752- ? { uri : frame . button . action . url }
753- : undefined ,
754- onMessage ( event ) {
755- logDebugRef . current (
756- "@frames.js/render/unstable-use-frame-app: received an event" ,
757- event . nativeEvent . data
758- ) ;
759-
760- try {
761- const result = z
762- . preprocess ( ( value ) => {
763- return typeof value === "string" ? JSON . parse ( value ) : value ;
764- } , webViewEventParser )
765- . safeParse ( event . nativeEvent . data ) ;
766-
767- if ( ! result . success ) {
768- logDebugRef . current (
769- "@frames.js/render/unstable-use-frame-app: received event parsing error" ,
770- result . error
771- ) ;
772- return ;
773- }
774-
775- const messageEvent = {
776- origin : new URL ( event . nativeEvent . url ) . origin ,
777- data : result . data ,
778- } ;
779-
770+ webViewProps : {
771+ source : frame . button ?. action ?. url
772+ ? { uri : frame . button . action . url }
773+ : undefined ,
774+ onMessage ( event ) {
780775 logDebugRef . current (
781- "@frames.js/render/unstable-use-frame-app: received message from web view " ,
782- messageEvent
776+ "@frames.js/render/unstable-use-frame-app: received an event " ,
777+ event . nativeEvent . data
783778 ) ;
784779
785- messageListenersRef . current ?. forEach ( ( listener ) => {
786- listener ( messageEvent ) ;
787- } ) ;
788- } catch ( error ) {
789- logDebugRef . current (
790- "@frames.js/render/unstable-use-frame-app: event receiving error" ,
791- error
792- ) ;
793- }
794- } ,
795- // inject js code which handles message parsing between the frame app and the application.
796- // react native web view is able to send only string messages so we need to serialize/deserialize them
797- injectedJavaScriptBeforeContentLoaded : createMessageBridgeScript (
798- debugRef . current
799- ) ,
800- ref ( webView ) {
801- ref . current = webView ;
802-
803- if ( ! webView ) {
804- return ;
805- }
806-
807- unregisterEndpointRef . current = frameApp . registerEndpoint ( {
808- postMessage ( message ) {
809- logDebugRef . current (
810- "@frames.js/render/unstable-use-frame-app: sent message to web view" ,
811- message
812- ) ;
813-
814- webView . postMessage ( JSON . stringify ( message ) ) ;
815- } ,
816- addEventListener ( type , listener ) {
817- if ( type !== "message" ) {
818- throw new Error ( "Invalid event" ) ;
819- }
820-
821- if ( typeof listener === "function" ) {
822- messageListenersRef . current ?. add (
823- listener as unknown as MessageEventListener
824- ) ;
780+ try {
781+ const result = z
782+ . preprocess ( ( value ) => {
783+ return typeof value === "string"
784+ ? JSON . parse ( value )
785+ : value ;
786+ } , webViewEventParser )
787+ . safeParse ( event . nativeEvent . data ) ;
825788
789+ if ( ! result . success ) {
826790 logDebugRef . current (
827- "@frames.js/render/unstable-use-frame-app: registered an event listener " ,
828- listener
791+ "@frames.js/render/unstable-use-frame-app: received event parsing error " ,
792+ result . error
829793 ) ;
830- } else {
831- throw new Error ( 'Invalid listener, expected "function"' ) ;
832- }
833- } ,
834- removeEventListener ( type , listener ) {
835- if ( type !== "message" ) {
836- throw new Error ( "Invalid event" ) ;
794+ return ;
837795 }
838796
839- if ( typeof listener === "function" ) {
840- messageListenersRef . current ?. delete (
841- listener as unknown as MessageEventListener
842- ) ;
797+ const messageEvent = {
798+ origin : new URL ( event . nativeEvent . url ) . origin ,
799+ data : result . data ,
800+ } ;
801+
802+ logDebugRef . current (
803+ "@frames.js/render/unstable-use-frame-app: received message from web view" ,
804+ messageEvent
805+ ) ;
843806
807+ messageListenersRef . current ?. forEach ( ( listener ) => {
808+ listener ( messageEvent ) ;
809+ } ) ;
810+ } catch ( error ) {
811+ logDebugRef . current (
812+ "@frames.js/render/unstable-use-frame-app: event receiving error" ,
813+ error
814+ ) ;
815+ }
816+ } ,
817+ // inject js code which handles message parsing between the frame app and the application.
818+ // react native web view is able to send only string messages so we need to serialize/deserialize them
819+ injectedJavaScriptBeforeContentLoaded : createMessageBridgeScript (
820+ debugRef . current
821+ ) ,
822+ ref ( webView ) {
823+ ref . current = webView ;
824+
825+ if ( ! webView ) {
826+ return ;
827+ }
828+
829+ unregisterEndpointRef . current = frameApp . registerEndpoint ( {
830+ postMessage ( message ) {
844831 logDebugRef . current (
845- "@frames.js/render/unstable-use-frame-app: removed an event listener " ,
846- listener
832+ "@frames.js/render/unstable-use-frame-app: sent message to web view " ,
833+ message
847834 ) ;
848- } else {
849- throw new Error ( 'Invalid listener, expected "function"' ) ;
850- }
851- } ,
852- } ) ;
853835
854- logDebugRef . current (
855- "@frames.js/render/unstable-use-frame-app: registered web view endpoint"
856- ) ;
836+ webView . postMessage ( JSON . stringify ( message ) ) ;
837+ } ,
838+ addEventListener ( type , listener ) {
839+ if ( type !== "message" ) {
840+ throw new Error ( "Invalid event" ) ;
841+ }
842+
843+ if ( typeof listener === "function" ) {
844+ messageListenersRef . current ?. add (
845+ listener as unknown as MessageEventListener
846+ ) ;
847+
848+ logDebugRef . current (
849+ "@frames.js/render/unstable-use-frame-app: registered an event listener" ,
850+ listener
851+ ) ;
852+ } else {
853+ throw new Error ( 'Invalid listener, expected "function"' ) ;
854+ }
855+ } ,
856+ removeEventListener ( type , listener ) {
857+ if ( type !== "message" ) {
858+ throw new Error ( "Invalid event" ) ;
859+ }
860+
861+ if ( typeof listener === "function" ) {
862+ messageListenersRef . current ?. delete (
863+ listener as unknown as MessageEventListener
864+ ) ;
865+
866+ logDebugRef . current (
867+ "@frames.js/render/unstable-use-frame-app: removed an event listener" ,
868+ listener
869+ ) ;
870+ } else {
871+ throw new Error ( 'Invalid listener, expected "function"' ) ;
872+ }
873+ } ,
874+ } ) ;
875+
876+ logDebugRef . current (
877+ "@frames.js/render/unstable-use-frame-app: registered web view endpoint"
878+ ) ;
879+ } ,
857880 } ,
858881 } ;
859882 }
0 commit comments