import { Avatar, Button, Divider, Listbox, ListboxItem, ListboxSection, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Switch, Textarea, Tooltip, useDisclosure, Link, } from '@nextui-org/react'; import { PlusIcon } from '@web/components/PlusIcon'; import { trpc } from '@web/utils/trpc'; import { useMemo, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { toast } from 'sonner'; import dayjs from 'dayjs'; import { serverOriginUrl } from '@web/utils/env'; import ArticleList from './list'; const Feeds = () => { const { id } = useParams(); const { isOpen, onOpen, onOpenChange, onClose } = useDisclosure(); const { refetch: refetchFeedList, data: feedData } = trpc.feed.list.useQuery( {}, { refetchOnWindowFocus: true, }, ); const navigate = useNavigate(); const queryUtils = trpc.useUtils(); const { mutateAsync: getMpInfo, isLoading: isGetMpInfoLoading } = trpc.platform.getMpInfo.useMutation({}); const { mutateAsync: updateMpInfo } = trpc.feed.edit.useMutation({}); const { mutateAsync: addFeed, isLoading: isAddFeedLoading } = trpc.feed.add.useMutation({}); const { mutateAsync: refreshMpArticles, isLoading: isGetArticlesLoading } = trpc.feed.refreshArticles.useMutation(); const { mutateAsync: deleteFeed, isLoading: isDeleteFeedLoading } = trpc.feed.delete.useMutation({}); const [wxsLink, setWxsLink] = useState(''); const [currentMpId, setCurrentMpId] = useState(id || ''); const handleConfirm = async () => { // TODO show operation in progress const res = await getMpInfo({ wxsLink: wxsLink }); if (res[0]) { const item = res[0]; await addFeed({ id: item.id, mpName: item.name, mpCover: item.cover, mpIntro: item.intro, updateTime: item.updateTime, status: 1, }); await refreshMpArticles(item.id); toast.success('添加成功', { description: `公众号 ${item.name}`, }); refetchFeedList(); setWxsLink(''); onClose(); await queryUtils.article.list.reset(); } else { toast.error('添加失败', { description: '请检查链接是否正确' }); } }; const isActive = (key: string) => { return currentMpId === key; }; const currentMpInfo = useMemo(() => { return feedData?.items.find((item) => item.id === currentMpId); }, [currentMpId, feedData?.items]); const handleExportOpml = async (ev) => { ev.preventDefault(); ev.stopPropagation(); if (!feedData?.items?.length) { console.warn('没有订阅源'); return; } let opmlContent = ` WeWeRSS 所有订阅源 `; feedData?.items.forEach((sub) => { opmlContent += ` \n`; }); opmlContent += ` `; const blob = new Blob([opmlContent], { type: 'text/xml;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = 'WeWeRSS-All.opml'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; return ( <>
共{feedData?.items.length || 0}个订阅
{feedData?.items ? ( setCurrentMpId(key as string)} > } > 全部 {feedData?.items.map((item) => { return ( } > {item.mpName} ); }) || []} ) : ( '' )}

{currentMpInfo?.mpName || '全部'}

{currentMpInfo ? (
最后更新时间: {dayjs(currentMpInfo.syncTime * 1e3).format( 'YYYY-MM-DD HH:mm:ss', )}
{ ev.preventDefault(); ev.stopPropagation(); await refreshMpArticles(currentMpInfo.id); await refetchFeedList(); await queryUtils.article.list.reset(); }} > {isGetArticlesLoading ? '更新中...' : '立即更新'}
{ await updateMpInfo({ id: currentMpInfo.id, data: { status: value ? 1 : 0, }, }); await refetchFeedList(); }} isSelected={currentMpInfo?.status === 1} >
{ ev.preventDefault(); ev.stopPropagation(); if (window.confirm('确定删除吗?')) { await deleteFeed(currentMpInfo.id); navigate('/feeds'); await refetchFeedList(); } }} > 删除 可添加.atom/.rss/.json格式输出
}> RSS
) : (
导出OPML RSS
)}
{(onClose) => ( <> 添加公众号源