Fix merge conflict issues

This commit is contained in:
Shreyaschorge 2025-07-16 17:50:03 +05:30
parent 196378daeb
commit bf563154ca
No known key found for this signature in database
2 changed files with 36 additions and 170 deletions

View File

@ -5,8 +5,8 @@ import { useSignIn, UseSignInData } from '@farcaster/auth-kit';
import { useCallback, useEffect, useState, useRef } from 'react'; import { useCallback, useEffect, useState, useRef } from 'react';
import { cn } from '~/lib/utils'; import { cn } from '~/lib/utils';
import { Button } from '~/components/ui/Button'; import { Button } from '~/components/ui/Button';
import { AuthDialog } from '~/components/ui/NeynarAuthButton/AuthDialog';
import { ProfileButton } from '~/components/ui/NeynarAuthButton/ProfileButton'; import { ProfileButton } from '~/components/ui/NeynarAuthButton/ProfileButton';
import { AuthDialog } from '~/components/ui/NeynarAuthButton/AuthDialog';
import { getItem, removeItem, setItem } from '~/lib/localStorage'; import { getItem, removeItem, setItem } from '~/lib/localStorage';
import { useMiniApp } from '@neynar/react'; import { useMiniApp } from '@neynar/react';
import { import {
@ -141,7 +141,7 @@ export function NeynarAuthButton() {
const updateSessionWithSigners = useCallback( const updateSessionWithSigners = useCallback(
async ( async (
signers: StoredAuthState['signers'], signers: StoredAuthState['signers'],
user: StoredAuthState['user'], user: StoredAuthState['user']
) => { ) => {
if (!useBackendFlow) return; if (!useBackendFlow) return;
@ -384,146 +384,7 @@ export function NeynarAuthButton() {
generateNonce(); generateNonce();
}, []); }, []);
// Backend flow using QuickAuth // Load stored auth state on mount (only for frontend flow)
const handleBackendSignIn = useCallback(async () => {
if (!nonce) {
console.error('❌ No nonce available for backend sign-in');
return;
}
try {
setSignersLoading(true);
const result = await sdk.actions.signIn({ nonce });
setMessage(result.message);
setSignature(result.signature);
// Use QuickAuth to sign in
const signInResult = await quickAuthSignIn();
// Fetch user profile after sign in
if (quickAuthUser?.fid) {
const user = await fetchUserData(quickAuthUser.fid);
setBackendUserProfile({
username: user?.username || '',
pfpUrl: user?.pfp_url || '',
});
}
} catch (e) {
if (e instanceof SignInCore.RejectedByUser) {
console.log(' Sign-in rejected by user');
} else {
console.error('❌ Backend sign-in error:', e);
}
}
}, [useBackendFlow]);
// Auth Kit data synchronization (only for browser flow)
useEffect(() => {
if (!useBackendFlow) {
setMessage(data?.message || null);
setSignature(data?.signature || null);
// Reset the signer flow flag when message/signature change
if (data?.message && data?.signature) {
signerFlowStartedRef.current = false;
}
}
}, [useBackendFlow, data?.message, data?.signature]);
// Connect for frontend flow when nonce is available (only for browser flow)
useEffect(() => {
if (!useBackendFlow && nonce && !channelToken) {
connect();
}
}, [useBackendFlow, quickAuthUser?.fid, fetchUserData]);
const handleFrontEndSignIn = useCallback(async () => {
try {
setSignersLoading(true);
const result = await sdk.actions.signIn({ nonce: nonce || '' });
setMessage(result.message);
setSignature(result.signature);
// For frontend flow, we'll handle the signer flow in the useEffect
} catch (e) {
if (e instanceof SignInCore.RejectedByUser) {
console.log(' Sign-in rejected by user');
} else {
console.error('❌ Frontend sign-in error:', e);
}
} finally {
setSignersLoading(false);
}
}, [nonce]);
const handleSignOut = useCallback(async () => {
try {
setSignersLoading(true);
if (useBackendFlow) {
// Use QuickAuth sign out
await quickAuthSignOut();
} else {
// Frontend flow sign out
setStoredAuth(null);
}
// Common cleanup for both flows
setShowDialog(false);
setDialogStep('signin');
setSignerApprovalUrl(null);
setMessage(null);
setSignature(null);
// Reset polling interval
if (pollingInterval) {
clearInterval(pollingInterval);
setPollingInterval(null);
}
// Reset signer flow flag
signerFlowStartedRef.current = false;
} catch (error) {
console.error('❌ Error during sign out:', error);
// Optionally handle error state
} finally {
setSignersLoading(false);
}
}, [useBackendFlow, pollingInterval, quickAuthSignOut]);
// Backend flow using QuickAuth
const handleBackendSignIn = useCallback(async () => {
if (!nonce) {
console.error('❌ No nonce available for backend sign-in');
return;
}
try {
setSignersLoading(true);
const result = await sdk.actions.signIn({ nonce });
setMessage(result.message);
setSignature(result.signature);
// Use QuickAuth to sign in
const signInResult = await quickAuthSignIn();
// Fetch user profile after sign in
if (quickAuthUser?.fid) {
const user = await fetchUserData(quickAuthUser.fid);
setBackendUserProfile({
username: user?.username || '',
pfpUrl: user?.pfp_url || '',
});
}
} catch (e) {
if (e instanceof SignInCore.RejectedByUser) {
console.log(' Sign-in rejected by user');
} else {
console.error('❌ Backend sign-in error:', e);
}
}
}, [nonce, quickAuthSignIn, quickAuthUser, fetchUserData]);
// Fetch user profile when quickAuthUser.fid changes (for backend flow)
useEffect(() => { useEffect(() => {
if (!useBackendFlow) { if (!useBackendFlow) {
const stored = getItem<StoredAuthState>(STORAGE_KEY); const stored = getItem<StoredAuthState>(STORAGE_KEY);
@ -598,7 +459,12 @@ export function NeynarAuthButton() {
// Handle fetching signers after successful authentication // Handle fetching signers after successful authentication
useEffect(() => { useEffect(() => {
if (message && signature && !isSignerFlowRunning && !signerFlowStartedRef.current) { if (
message &&
signature &&
!isSignerFlowRunning &&
!signerFlowStartedRef.current
) {
signerFlowStartedRef.current = true; signerFlowStartedRef.current = true;
const handleSignerFlow = async () => { const handleSignerFlow = async () => {

View File

@ -1,12 +1,12 @@
'use client'; 'use client';
import { useCallback, useState } from "react"; import { useCallback, useState } from 'react';
import { useMiniApp } from "@neynar/react"; import { useMiniApp } from '@neynar/react';
import { ShareButton } from "../Share"; import { ShareButton } from '../Share';
import { Button } from "../Button"; import { Button } from '../Button';
import { SignIn } from "../wallet/SignIn"; import { SignIn } from '../wallet/SignIn';
import { type Haptics } from "@farcaster/miniapp-sdk"; import { type Haptics } from '@farcaster/miniapp-sdk';
import { APP_URL } from "~/lib/constants"; import { APP_URL } from '~/lib/constants';
import { NeynarAuthButton } from '../NeynarAuthButton/index'; import { NeynarAuthButton } from '../NeynarAuthButton/index';
/** /**
@ -124,16 +124,16 @@ export function ActionsTab() {
// --- Render --- // --- Render ---
return ( return (
<div className='space-y-3 px-6 w-full max-w-md mx-auto'> <div className="space-y-3 px-6 w-full max-w-md mx-auto">
{/* Share functionality */} {/* Share functionality */}
<ShareButton <ShareButton
buttonText='Share Mini App' buttonText="Share Mini App"
cast={{ cast={{
text: 'Check out this awesome frame @1 @2 @3! 🚀🪐', text: 'Check out this awesome frame @1 @2 @3! 🚀🪐',
bestFriends: true, bestFriends: true,
embeds: [`${APP_URL}/share/${context?.user?.fid || ''}`] embeds: [`${APP_URL}/share/${context?.user?.fid || ''}`],
}} }}
className='w-full' className="w-full"
/> />
{/* Authentication */} {/* Authentication */}
@ -147,25 +147,25 @@ export function ActionsTab() {
onClick={() => onClick={() =>
actions.openUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ') actions.openUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
} }
className='w-full' className="w-full"
> >
Open Link Open Link
</Button> </Button>
<Button onClick={actions.addMiniApp} disabled={added} className='w-full'> <Button onClick={actions.addMiniApp} disabled={added} className="w-full">
Add Mini App to Client Add Mini App to Client
</Button> </Button>
{/* Notification functionality */} {/* Notification functionality */}
{notificationState.sendStatus && ( {notificationState.sendStatus && (
<div className='text-sm w-full'> <div className="text-sm w-full">
Send notification result: {notificationState.sendStatus} Send notification result: {notificationState.sendStatus}
</div> </div>
)} )}
<Button <Button
onClick={sendFarcasterNotification} onClick={sendFarcasterNotification}
disabled={!notificationDetails} disabled={!notificationDetails}
className='w-full' className="w-full"
> >
Send notification Send notification
</Button> </Button>
@ -174,14 +174,14 @@ export function ActionsTab() {
<Button <Button
onClick={copyUserShareUrl} onClick={copyUserShareUrl}
disabled={!context?.user?.fid} disabled={!context?.user?.fid}
className='w-full' className="w-full"
> >
{notificationState.shareUrlCopied ? 'Copied!' : 'Copy share URL'} {notificationState.shareUrlCopied ? 'Copied!' : 'Copy share URL'}
</Button> </Button>
{/* Haptic feedback controls */} {/* Haptic feedback controls */}
<div className='space-y-2'> <div className="space-y-2">
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300'> <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
Haptic Intensity Haptic Intensity
</label> </label>
<select <select
@ -191,7 +191,7 @@ export function ActionsTab() {
e.target.value as Haptics.ImpactOccurredType e.target.value as Haptics.ImpactOccurredType
) )
} }
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary' className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-primary"
> >
<option value={'light'}>Light</option> <option value={'light'}>Light</option>
<option value={'medium'}>Medium</option> <option value={'medium'}>Medium</option>
@ -199,7 +199,7 @@ export function ActionsTab() {
<option value={'soft'}>Soft</option> <option value={'soft'}>Soft</option>
<option value={'rigid'}>Rigid</option> <option value={'rigid'}>Rigid</option>
</select> </select>
<Button onClick={triggerHapticFeedback} className='w-full'> <Button onClick={triggerHapticFeedback} className="w-full">
Trigger Haptic Feedback Trigger Haptic Feedback
</Button> </Button>
</div> </div>