Files
NapCatQQ/packages/napcat-webui-frontend/src/pages/qq_login.tsx
手瓜一十雪 4fcbdc4d89 Remove music player and related context/hooks
Deleted the audio player component, songs context, and use-music hook, along with all related code and configuration. Updated affected components and pages to remove music player dependencies and UI. Also improved sidebar, background, and about page UI, and refactored site config icons to use react-icons.
2025-12-20 18:07:16 +08:00

184 lines
5.4 KiB
TypeScript

import { Button } from '@heroui/button';
import { CardBody, CardHeader } from '@heroui/card';
import { Image } from '@heroui/image';
import { Tab, Tabs } from '@heroui/tabs';
import { useEffect, useRef, useState } from 'react';
import { toast } from 'react-hot-toast';
import { useNavigate } from 'react-router-dom';
import logo from '@/assets/images/logo.png';
import HoverEffectCard from '@/components/effect_card';
import { title } from '@/components/primitives';
import QrCodeLogin from '@/components/qr_code_login';
import QuickLogin from '@/components/quick_login';
import type { QQItem } from '@/components/quick_login';
import { ThemeSwitch } from '@/components/theme-switch';
import QQManager from '@/controllers/qq_manager';
import PureLayout from '@/layouts/pure';
import { motion } from 'motion/react';
export default function QQLoginPage () {
const navigate = useNavigate();
const [uinValue, setUinValue] = useState<string>('');
const [isLoading, setIsLoading] = useState<boolean>(false);
const [qrcode, setQrcode] = useState<string>('');
const [qqList, setQQList] = useState<(QQItem | LoginListItem)[]>([]);
const [refresh, setRefresh] = useState<boolean>(false);
const firstLoad = useRef<boolean>(true);
const onSubmit = async () => {
if (!uinValue) {
toast.error('请选择快捷登录的QQ');
return;
}
setIsLoading(true);
try {
await QQManager.setQuickLogin(uinValue);
} catch (error) {
const msg = (error as Error).message;
toast.error(`快速登录QQ失败: ${msg}`);
} finally {
setTimeout(() => {
setIsLoading(false);
}, 1000);
}
};
const onUpdateQrCode = async () => {
if (firstLoad.current) setIsLoading(true);
try {
const data = await QQManager.checkQQLoginStatusWithQrcode();
if (firstLoad.current) {
setIsLoading(false);
firstLoad.current = false;
}
if (data.isLogin) {
toast.success('QQ登录成功');
navigate('/', { replace: true });
} else {
setQrcode(data.qrcodeurl);
}
} catch (error) {
const msg = (error as Error).message;
toast.error(`获取二维码失败: ${msg}`);
}
};
const onUpdateQQList = async () => {
setRefresh(true);
try {
const data = await QQManager.getQQQuickLoginListNew();
setQQList(data);
} catch (_error) {
try {
const data = await QQManager.getQQQuickLoginList();
const qqList = data.map((item) => ({
uin: item,
}));
setQQList(qqList);
} catch (_error) {
const msg = (_error as Error).message;
toast.error(`获取QQ列表失败: ${msg}`);
}
} finally {
setRefresh(false);
}
};
const handleSelectionChange: React.ChangeEventHandler<HTMLSelectElement> = (
e
) => {
setUinValue(e.target.value);
};
useEffect(() => {
const timer = setInterval(() => {
onUpdateQrCode();
}, 3000);
onUpdateQrCode();
onUpdateQQList();
return () => clearInterval(timer);
}, []);
return (
<>
<title>QQ登录 - NapCat WebUI</title>
<PureLayout>
<motion.div
initial={{ opacity: 0, y: 20, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{ duration: 0.5, type: 'spring', stiffness: 120, damping: 20 }}
className='w-[608px] max-w-full py-8 px-2 md:px-8 overflow-hidden'
>
<HoverEffectCard
className='items-center gap-4 pt-0 pb-6 bg-default-50'
maxXRotation={3}
maxYRotation={3}
>
<CardHeader className='inline-block max-w-lg text-center justify-center'>
<div className='flex items-center justify-center w-full gap-2 pt-10'>
<Image alt='logo' height='7em' src={logo} />
<div>
<span className={title()}>Web&nbsp;</span>
<span className={title({ color: 'violet' })}>
Login&nbsp;
</span>
</div>
</div>
<ThemeSwitch className='absolute right-4 top-4' />
</CardHeader>
<CardBody className='flex gap-5 p-10 pt-0'>
<Tabs
fullWidth
classNames={{
tabList: 'shadow-sm dark:shadow-none',
}}
isDisabled={isLoading}
size='lg'
>
<Tab key='shortcut' title='快速登录'>
<QuickLogin
handleSelectionChange={handleSelectionChange}
isLoading={isLoading}
qqList={qqList}
refresh={refresh}
selectedQQ={uinValue}
onSubmit={onSubmit}
onUpdateQQList={onUpdateQQList}
/>
</Tab>
<Tab key='qrcode' title='扫码登录'>
<QrCodeLogin qrcode={qrcode} />
</Tab>
</Tabs>
<Button
className='w-fit mx-auto'
variant='light'
color='primary'
onPress={() => {
navigate('/web_login', {
replace: true,
});
}}
>
Web Login
</Button>
</CardBody>
</HoverEffectCard>
</motion.div>
</PureLayout>
</>
);
}