mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-01 08:10:25 +00:00
Add spinner during captcha verification
Show a loading spinner and message while captcha is being verified. Imported Spinner and added an optional captchaVerifying prop to PasswordLogin to toggle between the TencentCaptchaModal and a waiting state. In qq_login.tsx introduced captchaVerifying state, set it true before the captcha login request and reset it in finally, and passed the prop down to the PasswordLogin component.
This commit is contained in:
@@ -6,6 +6,7 @@ import { Input } from '@heroui/input';
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { toast } from 'react-hot-toast';
|
import { toast } from 'react-hot-toast';
|
||||||
import { IoChevronDown } from 'react-icons/io5';
|
import { IoChevronDown } from 'react-icons/io5';
|
||||||
|
import { Spinner } from '@heroui/spinner';
|
||||||
|
|
||||||
import type { QQItem } from '@/components/quick_login';
|
import type { QQItem } from '@/components/quick_login';
|
||||||
import { isQQQuickNewItem } from '@/utils/qq';
|
import { isQQQuickNewItem } from '@/utils/qq';
|
||||||
@@ -25,6 +26,7 @@ interface PasswordLoginProps {
|
|||||||
uin: string;
|
uin: string;
|
||||||
password: string;
|
password: string;
|
||||||
} | null;
|
} | null;
|
||||||
|
captchaVerifying?: boolean;
|
||||||
newDeviceState?: {
|
newDeviceState?: {
|
||||||
needNewDevice: boolean;
|
needNewDevice: boolean;
|
||||||
jumpUrl: string;
|
jumpUrl: string;
|
||||||
@@ -34,7 +36,7 @@ interface PasswordLoginProps {
|
|||||||
onNewDeviceCancel?: () => void;
|
onNewDeviceCancel?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PasswordLogin: React.FC<PasswordLoginProps> = ({ onSubmit, onCaptchaSubmit, onNewDeviceVerified, isLoading, qqList, captchaState, newDeviceState, onCaptchaCancel, onNewDeviceCancel }) => {
|
const PasswordLogin: React.FC<PasswordLoginProps> = ({ onSubmit, onCaptchaSubmit, onNewDeviceVerified, isLoading, qqList, captchaState, captchaVerifying, newDeviceState, onCaptchaCancel, onNewDeviceCancel }) => {
|
||||||
const [uin, setUin] = useState('');
|
const [uin, setUin] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
|
|
||||||
@@ -54,14 +56,25 @@ const PasswordLogin: React.FC<PasswordLoginProps> = ({ onSubmit, onCaptchaSubmit
|
|||||||
<div className='flex flex-col gap-8'>
|
<div className='flex flex-col gap-8'>
|
||||||
{captchaState?.needCaptcha && captchaState.proofWaterUrl ? (
|
{captchaState?.needCaptcha && captchaState.proofWaterUrl ? (
|
||||||
<div className='flex flex-col gap-4 items-center'>
|
<div className='flex flex-col gap-4 items-center'>
|
||||||
<p className='text-warning text-sm'>登录需要安全验证,请完成验证码</p>
|
{captchaVerifying ? (
|
||||||
<TencentCaptchaModal
|
<>
|
||||||
proofWaterUrl={captchaState.proofWaterUrl}
|
<p className='text-primary text-sm'>验证码已提交,正在等待服务器验证结果...</p>
|
||||||
onSuccess={(data) => {
|
<div className='flex items-center justify-center py-8 gap-3'>
|
||||||
onCaptchaSubmit?.(captchaState.uin, captchaState.password, data);
|
<Spinner size='lg' />
|
||||||
}}
|
</div>
|
||||||
onCancel={onCaptchaCancel}
|
</>
|
||||||
/>
|
) : (
|
||||||
|
<>
|
||||||
|
<p className='text-warning text-sm'>登录需要安全验证,请完成验证码</p>
|
||||||
|
<TencentCaptchaModal
|
||||||
|
proofWaterUrl={captchaState.proofWaterUrl}
|
||||||
|
onSuccess={(data) => {
|
||||||
|
onCaptchaSubmit?.(captchaState.uin, captchaState.password, data);
|
||||||
|
}}
|
||||||
|
onCancel={onCaptchaCancel}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
variant='light'
|
variant='light'
|
||||||
color='danger'
|
color='danger'
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ export default function QQLoginPage () {
|
|||||||
uin: string;
|
uin: string;
|
||||||
password: string;
|
password: string;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
const [captchaVerifying, setCaptchaVerifying] = useState(false);
|
||||||
const [newDeviceState, setNewDeviceState] = useState<{
|
const [newDeviceState, setNewDeviceState] = useState<{
|
||||||
needNewDevice: boolean;
|
needNewDevice: boolean;
|
||||||
jumpUrl: string;
|
jumpUrl: string;
|
||||||
@@ -130,6 +131,7 @@ export default function QQLoginPage () {
|
|||||||
|
|
||||||
const onCaptchaSubmit = async (uin: string, password: string, captchaData: CaptchaCallbackData) => {
|
const onCaptchaSubmit = async (uin: string, password: string, captchaData: CaptchaCallbackData) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
setCaptchaVerifying(true);
|
||||||
try {
|
try {
|
||||||
const passwordMd5 = CryptoJS.MD5(password).toString();
|
const passwordMd5 = CryptoJS.MD5(password).toString();
|
||||||
const result = await QQManager.captchaLogin(uin, passwordMd5, captchaData.ticket, captchaData.randstr, captchaData.sid);
|
const result = await QQManager.captchaLogin(uin, passwordMd5, captchaData.ticket, captchaData.randstr, captchaData.sid);
|
||||||
@@ -153,6 +155,7 @@ export default function QQLoginPage () {
|
|||||||
setCaptchaState(null);
|
setCaptchaState(null);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
setCaptchaVerifying(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -355,6 +358,7 @@ export default function QQLoginPage () {
|
|||||||
onNewDeviceVerified={onNewDeviceVerified}
|
onNewDeviceVerified={onNewDeviceVerified}
|
||||||
qqList={qqList}
|
qqList={qqList}
|
||||||
captchaState={captchaState}
|
captchaState={captchaState}
|
||||||
|
captchaVerifying={captchaVerifying}
|
||||||
newDeviceState={newDeviceState}
|
newDeviceState={newDeviceState}
|
||||||
onCaptchaCancel={onCaptchaCancel}
|
onCaptchaCancel={onCaptchaCancel}
|
||||||
onNewDeviceCancel={onNewDeviceCancel}
|
onNewDeviceCancel={onNewDeviceCancel}
|
||||||
|
|||||||
Reference in New Issue
Block a user