File size: 2,733 Bytes
ec4551b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'use client';

import React, {
  useCallback,
  useEffect,
  useState,
  useRef,
  FC,
  ReactNode,
} from 'react';
import { useNeynarContext } from '@neynar/react';
export const NeynarAuthButton: FC<{
  children: ReactNode;
  onLogin: (code: string) => void;
}> = (props) => {
  const { children, onLogin } = props;
  const { client_id } = useNeynarContext();
  const [showModal, setShowModal] = useState(false);
  const authWindowRef = useRef<Window | null>(null);
  const neynarLoginUrl = `${
    process.env.NEYNAR_LOGIN_URL ?? 'https://app.neynar.com/login'
  }?client_id=${client_id}`;
  const authOrigin = new URL(neynarLoginUrl).origin;
  const modalRef = useRef<HTMLDivElement>(null);
  const handleMessage = useCallback(
    async (event: MessageEvent) => {
      if (
        event.origin === authOrigin &&
        event.data &&
        event.data.is_authenticated
      ) {
        authWindowRef.current?.close();
        window.removeEventListener('message', handleMessage); // Remove listener here
        delete event.data.user.profile;
        const _user = {
          signer_uuid: event.data.signer_uuid,
          ...event.data.user,
        };
        onLogin(Buffer.from(JSON.stringify(_user)).toString('base64'));
      }
    },
    [client_id, onLogin]
  );
  const handleSignIn = useCallback(() => {
    const width = 600,
      height = 700;
    const left = window.screen.width / 2 - width / 2;
    const top = window.screen.height / 2 - height / 2;
    const windowFeatures = `width=${width},height=${height},top=${top},left=${left}`;
    authWindowRef.current = window.open(
      neynarLoginUrl,
      '_blank',
      windowFeatures
    );
    if (!authWindowRef.current) {
      console.error(
        'Failed to open the authentication window. Please check your pop-up blocker settings.'
      );
      return;
    }
    window.addEventListener('message', handleMessage, false);
  }, [client_id, handleMessage]);
  const closeModal = () => setShowModal(false);
  useEffect(() => {
    return () => {
      window.removeEventListener('message', handleMessage); // Cleanup function to remove listener
    };
  }, [handleMessage]);
  const handleOutsideClick = useCallback((event: any) => {
    if (modalRef.current && !modalRef.current.contains(event.target)) {
      closeModal();
    }
  }, []);
  useEffect(() => {
    if (showModal) {
      document.addEventListener('mousedown', handleOutsideClick);
    } else {
      document.removeEventListener('mousedown', handleOutsideClick);
    }
    return () => {
      document.removeEventListener('mousedown', handleOutsideClick);
    };
  }, [showModal, handleOutsideClick]);
  return <div onClick={handleSignIn} className="flex-1">{children}</div>;
};