import { FeedsCard, addMenuItem, forEachFeedsCard } from '@/components/feeds/api' import { ComponentEntry } from '@/components/types' import { getBlob } from '@/core/ajax' import { DownloadPackage } from '@/core/download' import { Toast } from '@/core/toast' import { matchUrlPattern, retrieveImageUrl } from '@/core/utils' import { formatTitle } from '@/core/utils/title' import { feedsUrls } from '@/core/utils/urls' export const setupFeedImageExporter: ComponentEntry = async ({ settings: { options } }) => { if (!feedsUrls.some(url => matchUrlPattern(url))) { return } const addExportButton = (card: FeedsCard) => { addMenuItem(card, { className: 'image-export', text: '导出图片', action: async () => { const imageUrls: { url: string; extension: string }[] = [] dqa(card.element, '.main-content .img-content, .bili-album__preview__picture__img').forEach((img: HTMLImageElement | HTMLDivElement) => { const urlData = retrieveImageUrl(img) if (urlData && !imageUrls.some(({ url }) => url === urlData.url)) { imageUrls.push(urlData) } }) if (imageUrls.length === 0) { Toast.info('此条动态没有检测到任何图片.', '导出图片') return } const toast = Toast.info('下载中...', '导出图片') let downloadedCount = 0 const imageBlobs = await Promise.all(imageUrls.map(async ({ url }) => { const blob = await getBlob(url) downloadedCount++ toast.message = `下载中... (${downloadedCount}/${imageUrls.length})` return blob })) const pack = new DownloadPackage() const { feedFormat } = options imageBlobs.forEach((blob, index) => { const titleData = { user: card.username, id: card.id, n: (index + 1).toString(), } pack.add(`${formatTitle(feedFormat, false, titleData)}${imageUrls[index].extension}`, blob) }) toast.dismiss() const packTitleData = { user: card.username, id: card.id, n: '', } await pack.emit(`${formatTitle(feedFormat, false, packTitleData)}.zip`) }, }) } forEachFeedsCard({ added: addExportButton, }) }