import { cx, css } from '@emotion/css' import { useEffect, useState, useMemo } from 'react' import qrCode from 'qrcode' import { useQuery } from 'react-query' import { checkLoginQrCodeStatus, fetchLoginQrCodeKey } from '@/web/api/auth' import toast from 'react-hot-toast' import { setCookies } from '@/web/utils/cookie' import uiStates from '@/web/states/uiStates' const QRCode = ({ className, text }: { className?: string; text: string }) => { const [image, setImage] = useState('') useEffect(() => { if (text) { qrCode .toString(text, { margin: 0, color: { light: '#ffffff00' }, type: 'svg', }) .then(image => { setImage(image) }) } }, [text]) const encodedImage = useMemo(() => encodeURIComponent(image), [image]) return ( ) } const LoginWithQRCode = () => { const { data: key, status: keyStatus, refetch: refetchKey, } = useQuery( 'qrCodeKey', async () => { const result = await fetchLoginQrCodeKey() if (result.data.code !== 200) { throw Error(`Failed to fetch QR code key: ${result.data.code}`) } return result }, { cacheTime: 0, retry: true, retryDelay: 500, refetchOnWindowFocus: false, refetchInterval: 1000 * 60 * 5, // 5 min } ) const { data: status } = useQuery( 'qrCodeStatus', async () => checkLoginQrCodeStatus({ key: key?.data?.unikey || '' }), { refetchInterval: 1000, enabled: !!key?.data?.unikey, onSuccess: status => { switch (status.code) { case 800: refetchKey() break case 801: // setQrCodeMessage('打开网易云音乐,扫码登录') break case 802: // setQrCodeMessage('等待确认') break case 803: if (!status.cookie) { toast('checkLoginQrCodeStatus returned 803 without cookie') break } setCookies(status.cookie) uiStates.showLoginPanel = false break } }, } ) const text = useMemo( () => key?.data?.unikey ? `https://music.163.com/login?codekey=${key.data.unikey}` : '', [key?.data?.unikey] ) return ( <>
Log in with NetEase QR
) } export default LoginWithQRCode