diff --git a/landing/connect-farcaster.react.js b/landing/connect-farcaster.react.js --- a/landing/connect-farcaster.react.js +++ b/landing/connect-farcaster.react.js @@ -48,15 +48,66 @@ const messageSentRef = React.useRef(false); const authenticated = isSuccess && validSignature; + const prevValsRef = React.useRef<{ +[key: string]: mixed }>({ + authenticated, + isError, + reconnect, + channelToken, + connect, + signIn, + url, + }); + const runRef = React.useRef(0); React.useEffect(() => { + const newVals: { +[key: string]: mixed } = { + authenticated, + isError, + reconnect, + channelToken, + connect, + signIn, + url, + }; + const keysChanged = []; + for (const key in newVals) { + if (newVals[key] !== prevValsRef.current[key]) { + keysChanged.push(key); + } + } + prevValsRef.current = newVals; + + const effectRunReason = + `effect #${runRef.current++} ran ` + + `due to changes in ${JSON.stringify(keysChanged)}`; + if (authenticated) { + postMessageToNativeWebView({ + type: 'farcaster_log', + log: `skipped effect because authenticated. ${effectRunReason}`, + }); return; } + if (isError) { messageSentRef.current = false; reconnect(); + postMessageToNativeWebView({ + type: 'farcaster_log', + log: `effect ran reconnect before signIn due to error. ${effectRunReason}`, + }); } else if (!channelToken) { connect(); + postMessageToNativeWebView({ + type: 'farcaster_log', + log: + 'effect ran connect before signIn due to no channelToken. ' + + effectRunReason, + }); + } else { + postMessageToNativeWebView({ + type: 'farcaster_log', + log: `effect ran signIn on its own. ${effectRunReason}`, + }); } signIn(); @@ -64,10 +115,21 @@ if (url && messageSentRef.current === false) { messageSentRef.current = true; + postMessageToNativeWebView({ + type: 'farcaster_log', + log: `effect posted ${url.toString()}. ${effectRunReason}`, + }); postMessageToNativeWebView({ type: 'farcaster_url', url: url.toString(), }); + } else if (url) { + postMessageToNativeWebView({ + type: 'farcaster_log', + log: + `effect skipped posting ${url.toString()} because already ` + + `posted. ${effectRunReason}`, + }); } }, [authenticated, isError, reconnect, channelToken, connect, signIn, url]); diff --git a/lib/types/farcaster-types.js b/lib/types/farcaster-types.js --- a/lib/types/farcaster-types.js +++ b/lib/types/farcaster-types.js @@ -12,6 +12,10 @@ | { +type: 'farcaster_data', +fid: string, + } + | { + +type: 'farcaster_log', + +log: string, }; export type NeynarUser = { diff --git a/native/components/farcaster-web-view.react.js b/native/components/farcaster-web-view.react.js --- a/native/components/farcaster-web-view.react.js +++ b/native/components/farcaster-web-view.react.js @@ -4,6 +4,7 @@ import { View, Linking } from 'react-native'; import WebView from 'react-native-webview'; +import { logTypes, useDebugLogs } from 'lib/components/debug-logs-context.js'; import type { FarcasterWebViewMessage } from 'lib/types/farcaster-types.js'; import type { WebViewMessageEvent } from '../types/web-view-types.js'; @@ -25,6 +26,7 @@ function FarcasterWebView(props: Props): React.Node { const { onSuccess, webViewState } = props; + const { addLog } = useDebugLogs(); const handleMessage = React.useCallback( (event: WebViewMessageEvent) => { const data: FarcasterWebViewMessage = JSON.parse(event.nativeEvent.data); @@ -33,9 +35,15 @@ void Linking.openURL(data.url); } else if (data.type === 'farcaster_data') { onSuccess(data.fid); + } else if (data.type === 'farcaster_log') { + addLog( + 'Farcaster: log from SIWF page', + data.log, + new Set([logTypes.FARCASTER]), + ); } }, - [onSuccess], + [onSuccess, addLog], ); const webView = React.useMemo(() => {