diff --git a/eslint.config.js b/eslint.config.js index b50ce987..4e22cb1c 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -6,4 +6,9 @@ export default [ { languageOptions: { globals: globals.browser } }, pluginJs.configs.recommended, ...tseslint.configs.recommended, + { + rules: { + "@typescript-eslint/no-explicit-any": "warn", + }, + }, ]; diff --git a/packages/main/package.json b/packages/main/package.json index 56352132..9fdcc7d8 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -24,6 +24,7 @@ "@eslint/js": "^9.3.0", "@types/electron-devtools-installer": "^2.2.5", "@types/fs-extra": "^11.0.4", + "@types/glob": "^8.1.0", "@types/gulp": "^4.0.17", "@types/lodash": "^4.17.4", "@types/mime-types": "^2.1.4", @@ -40,6 +41,7 @@ "esbuild": "^0.21.4", "esbuild-register": "^3.5.0", "eslint": "^9.3.0", + "glob": "^10.4.1", "globals": "^15.3.0", "gulp": "^5.0.0", "prebuild-install": "^7.1.2", diff --git a/packages/main/scripts/index.ts b/packages/main/scripts/index.ts index b5bfce03..aad1e2c3 100644 --- a/packages/main/scripts/index.ts +++ b/packages/main/scripts/index.ts @@ -65,7 +65,6 @@ async function watchTask() { }) .on("error", (error) => { consola.error(error); - process.exit(); }); return Promise.resolve(); } diff --git a/packages/main/src/controller/DownloadController.ts b/packages/main/src/controller/DownloadController.ts index 5cd09311..2c6949a1 100644 --- a/packages/main/src/controller/DownloadController.ts +++ b/packages/main/src/controller/DownloadController.ts @@ -27,7 +27,7 @@ export default class DownloadController implements Controller { @inject(TYPES.MainWindow) private readonly mainWindow: MainWindow, @inject(TYPES.WebviewService) - private readonly webviewService: WebviewService, + private readonly webviewService: WebviewService ) {} @handle("show-download-dialog") @@ -36,12 +36,12 @@ export default class DownloadController implements Controller { this.webviewService.sendToWindow( "show-download-dialog", data, - image.toDataURL(), + image.toDataURL() ); } @handle("add-download-item") - async addDownloadItem(e: IpcMainEvent, video: DownloadItem) { + async addDownloadItem(e: IpcMainEvent, video: Omit) { const item = await this.videoRepository.addVideo(video); // 这里向页面发送消息,通知页面更新 this.mainWindow.send("download-item-notifier", item); @@ -63,7 +63,7 @@ export default class DownloadController implements Controller { } @handle("download-now") - async downloadNow(e: IpcMainEvent, video: DownloadItem) { + async downloadNow(e: IpcMainEvent, video: Omit) { // 添加下载项 const item = await this.addDownloadItem(e, video); // 开始下载 diff --git a/packages/main/src/helper/utils.ts b/packages/main/src/helper/utils.ts index ff33cbed..5021867a 100644 --- a/packages/main/src/helper/utils.ts +++ b/packages/main/src/helper/utils.ts @@ -4,12 +4,11 @@ export async function sleep(second = 1): Promise { return new Promise((resolve) => setTimeout(resolve, second * 1000)); } -export function formatHeaders(headersStr: string): string { - const headers: Record | null = JSON.parse(headersStr); +export function formatHeaders(headers: Record): string { if (!headers) return ""; const formatted = Object.entries(headers) .map(([key, value]) => `${key}:${value}`) - .join("|"); + .join("\n"); return formatted; } diff --git a/packages/main/src/interfaces.ts b/packages/main/src/interfaces.ts index d0be1325..8f4f0069 100644 --- a/packages/main/src/interfaces.ts +++ b/packages/main/src/interfaces.ts @@ -8,6 +8,8 @@ export interface DownloadItem { headers?: string; status?: DownloadStatus; isLive?: boolean; + numberOfEpisodes?: number; + teleplay?: boolean; } export enum DownloadFilter { diff --git a/packages/main/src/preload.ts b/packages/main/src/preload.ts index c922ee97..2b547b61 100644 --- a/packages/main/src/preload.ts +++ b/packages/main/src/preload.ts @@ -23,7 +23,7 @@ const electronApi = { return ipcRenderer.invoke("get-favorites"); }, addFavorite( - favorite: Omit, + favorite: Omit ): Promise { return ipcRenderer.invoke("add-favorite", favorite); }, @@ -53,7 +53,7 @@ const electronApi = { }, setAppStore( key: keyof AppStore, - val: AppStore[keyof AppStore], + val: AppStore[keyof AppStore] ): Promise { return ipcRenderer.invoke("set-app-store", key, val); }, @@ -137,9 +137,6 @@ const electronApi = { setUserAgent(isMobile: boolean): Promise { return ipcRenderer.invoke("webview-change-user-agent", isMobile); }, - downloadItem(data: Omit) { - return ipcRenderer.invoke("add-download-item", data); - }, getDownloadLog(id: number): Promise { return ipcRenderer.invoke("get-download-log", id); }, diff --git a/packages/main/src/services/SniffingHelperService.ts b/packages/main/src/services/SniffingHelperService.ts index 4580d8f5..e43cd945 100644 --- a/packages/main/src/services/SniffingHelperService.ts +++ b/packages/main/src/services/SniffingHelperService.ts @@ -3,15 +3,15 @@ import { DownloadType } from "../interfaces.ts"; import { TYPES } from "../types.ts"; import ElectronLogger from "../vendor/ElectronLogger.ts"; import EventEmitter from "events"; -import { session } from "electron"; -import { PERSIST_WEBVIEW } from "../helper/index.ts"; -import { OnCompletedListenerDetails } from "electron/main"; +import { OnSendHeadersListenerDetails, session } from "electron"; +import { PERSIST_WEBVIEW, formatHeaders } from "../helper/index.ts"; export interface SourceParams { url: string; documentURL: string; name: string; type: DownloadType; + headers?: string; } export interface SourceFilter { @@ -49,7 +49,7 @@ export class SniffingHelper extends EventEmitter { constructor( @inject(TYPES.ElectronLogger) - private readonly logger: ElectronLogger, + private readonly logger: ElectronLogger ) { super(); } @@ -87,7 +87,7 @@ export class SniffingHelper extends EventEmitter { start() { const viewSession = session.fromPartition(PERSIST_WEBVIEW); - viewSession.webRequest.onCompleted(this.onCompleted); + viewSession.webRequest.onSendHeaders(this.onSendHeaders); } send = (item: SourceParams) => { @@ -100,8 +100,8 @@ export class SniffingHelper extends EventEmitter { } }; - private onCompleted = (details: OnCompletedListenerDetails): void => { - const { url } = details; + private onSendHeaders = (details: OnSendHeadersListenerDetails): void => { + const { url, requestHeaders } = details; const { title, url: documentURL } = this.pageInfo; listLoop: for (const filter of filterList) { @@ -117,6 +117,7 @@ export class SniffingHelper extends EventEmitter { documentURL, name: title, type: filter.type, + headers: formatHeaders(requestHeaders), }); break listLoop; } diff --git a/packages/plugin/src/components/BilibiliButton.ts b/packages/plugin/src/components/BilibiliButton.ts index d4b2213d..2e3c82c7 100644 --- a/packages/plugin/src/components/BilibiliButton.ts +++ b/packages/plugin/src/components/BilibiliButton.ts @@ -2,6 +2,7 @@ import { LitElement, html, css } from "lit"; import { customElement, property } from "lit/decorators.js"; import { BILIBILI_DOWNLOAD_BUTTON, showDownloadDialog } from "../helper"; import $ from "jquery"; +import { DownloadType } from "../types"; @customElement("bilibili-button") export class BilibiliButton extends LitElement { @@ -39,7 +40,7 @@ export class BilibiliButton extends LitElement { const videoImage = $(BILIBILI_DOWNLOAD_BUTTON).eq(this.index); const url = videoImage.attr("href") || ""; const name = videoImage.parent().find(".bili-video-card__info--tit").text(); - showDownloadDialog([{ name, url, type: "bilibili" }]); + showDownloadDialog([{ name, url, type: DownloadType.bilibili }]); } render() { diff --git a/packages/plugin/src/components/FloatButton.ts b/packages/plugin/src/components/FloatButton.ts index 9548d27d..965f3d1b 100644 --- a/packages/plugin/src/components/FloatButton.ts +++ b/packages/plugin/src/components/FloatButton.ts @@ -19,6 +19,7 @@ interface SourceData { documentURL: string; name: string; type: DownloadType; + headers?: string; } @customElement("float-button") @@ -133,7 +134,7 @@ export class FloatButton extends LitElement { getPosition = ( newLeft: number, - newTop: number, + newTop: number ): { left: number; top: number } => { if (!this.button) return { left: 0, top: 0 }; @@ -210,6 +211,8 @@ export class FloatButton extends LitElement { function init() { const floatButton = document.createElement("float-button"); + floatButton.style.position = "fixed"; + floatButton.style.zIndex = "9999999999999"; document.body.appendChild(floatButton); // 向主进程发送插件准备好的消息 diff --git a/packages/plugin/src/helper/index.ts b/packages/plugin/src/helper/index.ts index a76a905d..ef6d3455 100644 --- a/packages/plugin/src/helper/index.ts +++ b/packages/plugin/src/helper/index.ts @@ -1,4 +1,5 @@ import { nanoid } from "nanoid"; +import { DownloadItem } from "../../../main/types/interfaces"; const eventMap = new Map(); @@ -29,11 +30,7 @@ export interface Item { type: any; } -export function downloadItem(item: Item) { - window.electron.downloadItem(item); -} - -export function showDownloadDialog(item: Item[]) { +export function showDownloadDialog(item: Omit[]) { window.electron.showDownloadDialog(item); } diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 080f5080..aa1556fc 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -44,8 +44,6 @@ "@types/react-dom": "^18.3.0", "@types/react-redux": "^7.1.33", "@types/sort-by": "^1.2.3", - "@typescript-eslint/eslint-plugin": "^7.10.0", - "@typescript-eslint/parser": "7.10.0", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^9.3.0", "globals": "^15.3.0", diff --git a/packages/renderer/src/components/DownloadForm/index.tsx b/packages/renderer/src/components/DownloadForm/index.tsx index 4c67177f..49ca2bd4 100644 --- a/packages/renderer/src/components/DownloadForm/index.tsx +++ b/packages/renderer/src/components/DownloadForm/index.tsx @@ -1,184 +1,246 @@ import { ModalForm, + ProFormDigit, + ProFormSelect, ProFormSwitch, ProFormText, ProFormTextArea, } from "@ant-design/pro-components"; -import { Form } from "antd"; -import React, { FC } from "react"; +import { Button, Form } from "antd"; +import React, { forwardRef, useImperativeHandle } from "react"; import "./index.scss"; import { useTranslation } from "react-i18next"; +import { DownloadOutlined, PlusOutlined } from "@ant-design/icons"; export interface DownloadFormProps { - onFinish: (values: DownloadItem) => Promise; - trigger: JSX.Element; + trigger?: JSX.Element; isEdit?: boolean; item?: DownloadItem; + open?: boolean; + onOpenChange?: (open: boolean) => void; + onAddToList: (values: DownloadItem) => Promise; + onDownloadNow: (values: DownloadItem) => Promise; } -const preProcessHeaders = (value: string | null) => { - if (!value) return; - - let headers: Record = {}; - try { - headers = JSON.parse(value); - } catch (err) { - // empty - } - return Object.entries(headers) - .map(([key, value]) => { - return `${key}: ${value}`; - }) - .join("\n"); -}; - -const postProcessHeaders = (value: string | null) => { - if (!value) return ""; - - const headers = value - .split("\n") - .reduce>((prev, curr) => { - const [key, value] = curr.split(":"); - if (key) { - prev[key.trim()] = value ? value.trim() : ""; - } - return prev; - }, {}); - - return JSON.stringify(headers); -}; - -const DownloadFrom: FC = ({ - onFinish, - trigger, - isEdit, - item, -}) => { - const [form] = Form.useForm(); - const { t } = useTranslation(); +export interface DownloadFormRef { + setFieldsValue: (value: Partial) => void; + getFieldsValue: () => DownloadItem; +} - return ( - - key={isEdit ? "edit" : "new"} - title={isEdit ? t("editDownload") : t("newDownload")} - width={500} - trigger={trigger} - form={form} - autoFocusFirstInput - onOpenChange={() => { - if (item) { - // 处理 headers 字段 - const headers = preProcessHeaders(item.headers); +const DownloadForm = forwardRef( + (props, ref) => { + const { trigger, isEdit, open, onOpenChange, onAddToList, onDownloadNow } = + props; + const [form] = Form.useForm(); + const { t } = useTranslation(); - form.setFieldsValue({ - ...item, - headers, - }); - } - }} - modalProps={{ - destroyOnClose: true, - styles: { - body: { - paddingTop: 5, + useImperativeHandle( + ref, + () => { + return { + setFieldsValue: (value) => { + form.setFieldsValue(value); }, - }, - }} - submitTimeout={2000} - onFinish={(values) => { - // 处理 headers 字段 - const headers = postProcessHeaders(values.headers); + getFieldsValue: () => { + return form.getFieldsValue(); + }, + }; + }, + [] + ); - return onFinish({ ...values, headers }); - }} - labelCol={{ span: 4 }} - layout="horizontal" - colon={false} - > - {!isEdit && } - - {(form) => { - if (!isEdit && form.getFieldValue("batch")) { - return ( - + open={open} + key={isEdit ? "edit" : "new"} + title={isEdit ? t("editDownload") : t("newDownload")} + width={500} + trigger={trigger} + form={form} + autoFocusFirstInput + submitter={{ + render: () => { + return [ + , + , + ]; + }, }} - - - - ); -}; + submitTimeout={2000} + labelCol={{ span: 4 }} + layout="horizontal" + colon={false} + > + { + // { + // const item = downloadItems.find((item) => item.url === key); + // if (item) { + // setCurrentDownloadForm(item); + // } + // }} + // items={downloadItems.map((item) => ({ + // key: item.url, + // label: item.name, + // }))} + // /> + } + {!isEdit && } + + + {(form) => { + if (form.getFieldValue("type") !== "bilibili") { + return ( + + ); + } + }} + + + {(form) => { + if ( + form.getFieldValue("type") !== "bilibili" && + form.getFieldValue("teleplay") + ) { + return ( + + ); + } + }} + + + {(form) => { + if (!isEdit && form.getFieldValue("batch")) { + return ( + + ); + } else { + return ( + { + const file: any = e.dataTransfer.files[0]; + form.setFieldValue("url", `file://${file.path}`); + form.validateFields(["url"]); + }, + }} + /> + ); + } + }} + + + {(form) => { + if (isEdit || !form.getFieldValue("batch")) { + return ( + + ); + } + }} + + + {(form) => { + if (isEdit || !form.getFieldValue("batch")) { + return ( + + ); + } + }} + + + + ); + } +); -export default DownloadFrom; +export default DownloadForm; diff --git a/packages/renderer/src/components/WebView/index.tsx b/packages/renderer/src/components/WebView/index.tsx index 2b62abf2..4b930f54 100644 --- a/packages/renderer/src/components/WebView/index.tsx +++ b/packages/renderer/src/components/WebView/index.tsx @@ -10,12 +10,15 @@ interface DivRect { height: number; } -const computeRect = ({ left, top, width, height }: DivRect) => ({ - x: Math.floor(left), - y: Math.floor(top), - width: Math.floor(width), - height: Math.floor(height), -}); +const computeRect = (rect: DivRect) => { + if (!rect) return { x: 0, y: 0, width: 0, height: 0 }; + return { + x: Math.floor(rect.left), + y: Math.floor(rect.top), + width: Math.floor(rect.width), + height: Math.floor(rect.height), + }; +}; interface WebViewProps { className?: string; diff --git a/packages/renderer/src/i18n/index.ts b/packages/renderer/src/i18n/index.ts index 3ddd5e5e..47229913 100644 --- a/packages/renderer/src/i18n/index.ts +++ b/packages/renderer/src/i18n/index.ts @@ -126,8 +126,8 @@ Referer: http://www.example.com`, exportLog: "Export Log", showTerminal: "Show Console", consoleOutput: "Console", - downloadNow: "Download Now", - addToDownloadList: "Add to Download List", + downloadNow: "Download", + addToDownloadList: "Add", videoType: "Video Type", pleaseSelectVideoType: "Please select video type", numberOfEpisodes: "Number of episodes", @@ -248,8 +248,8 @@ Referer: http://www.example.com`, exportLog: "导出日志", showTerminal: "显示控制台", consoleOutput: "控制台", - downloadNow: "立即下载", - addToDownloadList: "添加到下载列表", + downloadNow: "下载", + addToDownloadList: "添加", videoType: "视频类型", pleaseSelectVideoType: "请选择视频类型", numberOfEpisodes: "集数", diff --git a/packages/renderer/src/nodes/HomePage/index.tsx b/packages/renderer/src/nodes/HomePage/index.tsx index 320625c9..b70e556b 100644 --- a/packages/renderer/src/nodes/HomePage/index.tsx +++ b/packages/renderer/src/nodes/HomePage/index.tsx @@ -25,7 +25,7 @@ import { } from "@ant-design/icons"; import { useSelector } from "react-redux"; import { selectAppStore } from "../../store"; -import DownloadFrom from "../../components/DownloadForm"; +import DownloadForm from "../../components/DownloadForm"; import { Trans, useTranslation } from "react-i18next"; import Terminal from "../../components/Terminal"; import { moment } from "../../utils"; @@ -71,11 +71,11 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => { { defaultPageSize: 50, refreshDeps: [filter], - }, + } ); const [converting, setConverting] = useState>({}); const [progress, setProgress] = useState>( - {}, + {} ); const [messageApi, contextHolder] = message.useMessage(); const [terminal, setTerminal] = useState({ @@ -105,7 +105,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => { const onDownloadMenuEvent = async ( e: any, - params: { action: string; payload: number }, + params: { action: string; payload: number } ) => { const { action, payload } = params; @@ -180,7 +180,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => { const renderEditForm = (item: DownloadItem) => { return ( - = ({ filter = DownloadFilter.list }) => { const renderActionButtons = ( dom: ReactNode, - item: DownloadItem, + item: DownloadItem ): ReactNode => { if (item.status === DownloadStatus.Ready) { return [ @@ -401,7 +401,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => { {t("openFolder")} {filter === DownloadFilter.list && ( - }>{t("newDownload")} } diff --git a/packages/renderer/src/nodes/SourceExtract/index.tsx b/packages/renderer/src/nodes/SourceExtract/index.tsx index 4017e4f6..c2297209 100644 --- a/packages/renderer/src/nodes/SourceExtract/index.tsx +++ b/packages/renderer/src/nodes/SourceExtract/index.tsx @@ -23,7 +23,6 @@ import { message, Space, Spin, - Tabs, } from "antd"; import React, { useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; @@ -31,13 +30,7 @@ import PageContainer from "../../components/PageContainer"; import useElectron from "../../hooks/electron"; import { generateUrl, getFavIcon } from "../../utils"; import "./index.scss"; -import { - ModalForm, - ProFormDigit, - ProFormSelect, - ProFormSwitch, - ProFormText, -} from "@ant-design/pro-components"; +import { ModalForm, ProFormText } from "@ant-design/pro-components"; import { BrowserStatus, PageMode, @@ -50,21 +43,12 @@ import { selectAppStore } from "../../store"; import { useTranslation } from "react-i18next"; import { nanoid } from "nanoid"; import localforage from "localforage"; -import { DownloadType } from "../../types"; +import DownloadForm, { DownloadFormRef } from "../../components/DownloadForm"; interface SourceExtractProps { page?: boolean; } -// 下载表单 -interface DownloadForm { - teleplay: boolean; - type: DownloadType; - name: string; - url: string; - numberOfEpisodes: number; -} - // 集数 interface NumberOfEpisodes { teleplay: boolean; @@ -98,12 +82,10 @@ const SourceExtract: React.FC = ({ page = false }) => { const [hoverId, setHoverId] = useState(-1); const store = useSelector(selectBrowserStore); const appStore = useSelector(selectAppStore); - const [form] = Form.useForm(); const [modalShow, setModalShow] = useState(false); const [placeHolder, setPlaceHolder] = useState(""); - const [modalReadyShow, setModalReadyShow] = useState(false); - const [downloadItems, setDownloadItems] = useState([]); const sessionId = useRef(""); + const downloadForm = useRef(null); const curIsFavorite = favoriteList.find((item) => item.url === store.url); @@ -121,7 +103,7 @@ const SourceExtract: React.FC = ({ page = false }) => { url: "", mode: PageMode.Browser, status: BrowserStatus.Loading, - }), + }) ); await webviewLoadURL(url); if (sessionId.current === id) { @@ -129,7 +111,7 @@ const SourceExtract: React.FC = ({ page = false }) => { setBrowserStore({ url: url, status: BrowserStatus.Loaded, - }), + }) ); } } catch (err) { @@ -138,7 +120,7 @@ const SourceExtract: React.FC = ({ page = false }) => { setBrowserStore({ status: BrowserStatus.Failed, errMsg: (err as any).message, - }), + }) ); } } @@ -186,7 +168,7 @@ const SourceExtract: React.FC = ({ page = false }) => { setBrowserStore({ url: "", mode: PageMode.Default, - }), + }) ); } }; @@ -197,7 +179,7 @@ const SourceExtract: React.FC = ({ page = false }) => { setBrowserStore({ url: "", mode: PageMode.Default, - }), + }) ); }; @@ -220,7 +202,7 @@ const SourceExtract: React.FC = ({ page = false }) => { setBrowserStore({ url: data.url, title: data.title, - }), + }) ); } }; @@ -233,7 +215,7 @@ const SourceExtract: React.FC = ({ page = false }) => { }: { action: string; payload: number; - }, + } ) => { if (action === "open") { const item = favoriteList.find((item) => item.id === payload); @@ -252,19 +234,20 @@ const SourceExtract: React.FC = ({ page = false }) => { }, []); // 设置当前的下载表单 - const setCurrentDownloadForm = async (data: DownloadForm) => { - const { type, url, name } = data; + const setCurrentDownloadForm = async (data: DownloadItem) => { + const { type, url, name, headers } = data; const noe = await localforage.getItem("numberOfEpisodes"); - const formData = form.getFieldsValue(); + const formData = downloadForm.current.getFieldsValue(); const teleplay = formData.teleplay || noe?.teleplay || false; const numberOfEpisodes = formData.numberOfEpisodes || noe?.numberOfEpisodes || 1; - form.setFieldsValue({ + downloadForm.current.setFieldsValue({ type, url, name, + headers, teleplay, numberOfEpisodes, }); @@ -272,17 +255,14 @@ const SourceExtract: React.FC = ({ page = false }) => { const onShowDownloadDialog = async ( e: unknown, - data: DownloadForm[], - image: string, + data: DownloadItem[], + image: string ) => { - setDownloadItems(data); + // FIXME: 选择 setCurrentDownloadForm(data[0]); setPlaceHolder(image); - setModalReadyShow(true); - setTimeout(() => { - setModalShow(true); - }, 0); + setModalShow(true); }; useEffect(() => { @@ -311,7 +291,7 @@ const SourceExtract: React.FC = ({ page = false }) => { dispatch( setAppStore({ isMobile: nextMode, - }), + }) ); }; @@ -407,7 +387,7 @@ const SourceExtract: React.FC = ({ page = false }) => { let content =
; if (store.status === BrowserStatus.Loading) { content = ; - } else if (modalReadyShow || modalShow) { + } else if (modalShow) { content = ( = ({ page = false }) => { const confirmDownload = async (now?: boolean) => { try { - const data = form.getFieldsValue(); + const data = downloadForm.current.getFieldsValue(); const { numberOfEpisodes, teleplay, ...item } = data; await localforage.setItem("numberOfEpisodes", { @@ -583,9 +563,9 @@ const SourceExtract: React.FC = ({ page = false }) => { } if (now) { - await downloadNow(item); + await downloadNow(data); } else { - await addDownloadItem(item); + await addDownloadItem(data); } // 提交成功后关闭弹窗 @@ -601,114 +581,14 @@ const SourceExtract: React.FC = ({ page = false }) => { // 渲染表单 const renderModalForm = () => { return ( - + { - return [ - , - okButton, - ]; - }, - }} - submitTimeout={2000} - onFinish={() => confirmDownload(true)} - labelCol={{ style: { width: "120px" } }} - layout="horizontal" - width={550} - labelAlign={"left"} - colon={false} - > - { - const item = downloadItems.find((item) => item.url === key); - if (item) { - setCurrentDownloadForm(item); - } - }} - items={downloadItems.map((item) => ({ - key: item.url, - label: item.name, - }))} - /> - - - {(form) => { - if (form.getFieldValue("type") !== "bilibili") { - return ( - - ); - } - }} - - - {(form) => { - if ( - form.getFieldValue("type") !== "bilibili" && - form.getFieldValue("teleplay") - ) { - return ( - - ); - } - }} - - - - - + onDownloadNow={() => confirmDownload(true)} + onAddToList={() => confirmDownload()} + /> ); }; diff --git a/packages/renderer/src/renderer.d.ts b/packages/renderer/src/renderer.d.ts index f0f8c32c..6bca6876 100644 --- a/packages/renderer/src/renderer.d.ts +++ b/packages/renderer/src/renderer.d.ts @@ -14,6 +14,8 @@ declare interface DownloadItem { headers?: string; status?: DownloadStatus; isLive?: boolean; + numberOfEpisodes?: number; + teleplay?: boolean; } declare interface VideoResponse { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8da68106..ad843864 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -149,6 +149,9 @@ importers: '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 + '@types/glob': + specifier: ^8.1.0 + version: 8.1.0 '@types/gulp': specifier: ^4.0.17 version: 4.0.17 @@ -197,6 +200,9 @@ importers: eslint: specifier: ^9.3.0 version: 9.3.0 + glob: + specifier: ^10.4.1 + version: 10.4.1 globals: specifier: ^15.3.0 version: 15.3.0 @@ -374,12 +380,6 @@ importers: '@types/sort-by': specifier: ^1.2.3 version: 1.2.3 - '@typescript-eslint/eslint-plugin': - specifier: ^7.10.0 - version: 7.10.0(@typescript-eslint/parser@7.10.0(eslint@9.3.0)(typescript@5.4.5))(eslint@9.3.0)(typescript@5.4.5) - '@typescript-eslint/parser': - specifier: 7.10.0 - version: 7.10.0(eslint@9.3.0)(typescript@5.4.5) '@vitejs/plugin-react-swc': specifier: ^3.7.0 version: 3.7.0(vite@5.2.11(@types/node@20.12.12)(sass@1.77.2)) @@ -1776,6 +1776,9 @@ packages: '@types/glob-stream@8.0.2': resolution: {integrity: sha512-kyuRfGE+yiSJWzSO3t74rXxdZNdYfLcllO0IUha4eX1fl40pm9L02Q/TEc3mykTLjoWz4STBNwYnUWdFu3I0DA==} + '@types/glob@8.1.0': + resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + '@types/gulp@4.0.17': resolution: {integrity: sha512-+pKQynu2C/HS16kgmDlAicjtFYP8kaa86eE9P0Ae7GB5W29we/E2TIdbOWtEZD5XkpY+jr8fyqfwO6SWZecLpQ==} @@ -1812,6 +1815,9 @@ packages: '@types/mime-types@2.1.4': resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} @@ -3304,13 +3310,14 @@ packages: resolution: {integrity: sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==} engines: {node: '>= 10.13.0'} - glob@10.3.16: - resolution: {integrity: sha512-JDKXl1DiuuHJ6fVS2FXjownaavciiHNUU4mOvV/B793RLh05vZL1rcPnCSaOgv1hDT6RDlY7AB7ZUvFYAtPgAw==} + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} engines: {node: '>=16 || 14 >=14.18'} hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} @@ -4100,8 +4107,8 @@ packages: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} - minipass@7.1.1: - resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} minisearch@6.3.0: @@ -7251,6 +7258,11 @@ snapshots: '@types/picomatch': 2.3.3 '@types/streamx': 2.9.5 + '@types/glob@8.1.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.12.12 + '@types/gulp@4.0.17': dependencies: '@types/node': 20.12.12 @@ -7292,6 +7304,8 @@ snapshots: '@types/mime-types@2.1.4': {} + '@types/minimatch@5.1.2': {} + '@types/ms@0.7.34': {} '@types/node-fetch@2.6.11': @@ -8309,7 +8323,7 @@ snapshots: config-file-ts@0.2.6: dependencies: - glob: 10.3.16 + glob: 10.4.1 typescript: 5.4.5 consola@3.2.3: {} @@ -9239,12 +9253,12 @@ snapshots: async-done: 2.0.0 chokidar: 3.6.0 - glob@10.3.16: + glob@10.4.1: dependencies: foreground-child: 3.1.1 jackspeak: 3.1.2 minimatch: 9.0.4 - minipass: 7.1.1 + minipass: 7.1.2 path-scurry: 1.11.1 glob@7.2.3: @@ -10032,7 +10046,7 @@ snapshots: minipass@5.0.0: {} - minipass@7.1.1: {} + minipass@7.1.2: {} minisearch@6.3.0: {} @@ -10305,7 +10319,7 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.2.2 - minipass: 7.1.1 + minipass: 7.1.2 path-to-regexp@2.4.0: {} @@ -11477,7 +11491,7 @@ snapshots: dayjs: 1.11.11 debug: 4.3.4 dotenv: 16.4.5 - glob: 10.3.16 + glob: 10.4.1 mkdirp: 2.1.6 reflect-metadata: 0.2.2 sha.js: 2.4.11