diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 41f151e52..5aa5a17b0 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -33,49 +33,42 @@ import type { SearchType } from "@App/app/service/service_worker/types"; type DragCtx = Pick, "listeners" | "setActivatorNodeRef"> | null; const SortableDragCtx = createContext(null); -function composeRefs(...refs: React.Ref[]): (node: T | null) => void { - return (node) => { - for (const ref of refs) { - if (typeof ref === "function") { - ref(node); - } else if (ref) { - (ref as React.MutableRefObject).current = node; - } - } - }; -} - -type DraggableEntryProps = { recordUUID: string } & React.HTMLAttributes; +type DraggableEntryProps = { + recordUUID: string; + children: React.ReactElement; +}; -const DraggableEntry = React.forwardRef(({ recordUUID, ...rest }, ref) => { - const sortable = useSortable({ id: recordUUID }); - const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging } = sortable; +const DraggableEntry = ({ recordUUID, children }: DraggableEntryProps) => { + const { setNodeRef, transform, transition, listeners, setActivatorNodeRef, isDragging, attributes } = useSortable({ + id: recordUUID, + }); const style = { - // ScriptCard 移位渉及多个元件上下左右移动,DragEnd时不要使用 dnd-kit 提供的效果 + ...children.props.style, // 合并已有样式 transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, zIndex: isDragging ? 10 : "auto", }; - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); - const ctxValue = useMemo( () => ({ - listeners: listeners, - setActivatorNodeRef: setActivatorNodeRef, + listeners, + setActivatorNodeRef, }), [listeners, setActivatorNodeRef] ); return ( -
+ {React.cloneElement(children, { + ...attributes, + ref: setNodeRef, + style, + })} ); -}); -DraggableEntry.displayName = "DraggableEntry"; +}; const DragHandle = () => { const sortable = useContext(SortableDragCtx); @@ -162,205 +155,203 @@ export const ScriptCardItem = React.memo( return ( -
- -
-
-
-
- -
- - - {i18nName(item)} - -
- - {tags.length > 0 && ( - - {tags.map((tag) => ( - - {tag} - - ))} - - )} -
-
- { - updateScripts([item.uuid], { enableLoading: true }); - requestEnableScript({ uuid: item.uuid, enable: checked }); - }} - /> -
- + +
+
+
+
+ +
+ + + {i18nName(item)} +
+ + {tags.length > 0 && ( + + {tags.map((tag) => ( + + {tag} + + ))} + + )} +
+
+ { + updateScripts([item.uuid], { enableLoading: true }); + requestEnableScript({ uuid: item.uuid, enable: checked }); + }} + /> +
+
+
- {/* 版本和更新时间 */} -
- {item.metadata.version?.[0] && ( -
- - {t("version")} - {": "} - - {item.metadata.version[0]} -
- )} -
+ {/* 版本和更新时间 */} +
+ {item.metadata.version?.[0] && ( +
- {t("last_updated")} + {t("version")} {": "} - + {item.metadata.version[0]}
+ )} +
+ + {t("last_updated")} + {": "} + +
+
- {/* 运行状态 */} -
- {item.type !== SCRIPT_TYPE_NORMAL && ( -
- + {item.type !== SCRIPT_TYPE_NORMAL && ( +
+ + } + color="blue" + bordered + style={{ cursor: "pointer" }} + onClick={toLogger} > - } - color="blue" - bordered - style={{ cursor: "pointer" }} - onClick={toLogger} - > - {item.runStatus === SCRIPT_RUN_STATUS_RUNNING ? t("running") : t("completed")} - - -
- )} - -
+ {item.runStatus === SCRIPT_RUN_STATUS_RUNNING ? t("running") : t("completed")} + + +
+ )} + +
-
- {item.type === SCRIPT_TYPE_NORMAL && ( - - {favoriteMemo.trimmed.map((fav) => ( - { - if (fav.website) { - window.open(fav.website, "_blank"); - } - }} - /> - ))} - {favoriteMemo.originalLen > 8 && {"..."}} - +
+ {item.type === SCRIPT_TYPE_NORMAL && ( + + {favoriteMemo.trimmed.map((fav) => ( + { + if (fav.website) { + window.open(fav.website, "_blank"); + } + }} + /> + ))} + {favoriteMemo.originalLen > 8 && {"..."}} + + )} + +
+
+ {/* 操作按钮 */} +
+ +
+
+ {item.type !== SCRIPT_TYPE_NORMAL && ( + )} -
-
- {/* 操作按钮 */} -
- -
-
- {item.type !== SCRIPT_TYPE_NORMAL && ( +
+ + + + + {item.config && ( )} -
-
- - - - - {item.config && ( - - )} - {item.metadata.cloudcat && ( - - )} - } + size="mini" + onClick={() => setCloudScript(item)} + > + {t("cloud")} + + )} + } + onOk={() => handleDelete(item)} + > + - - -
+ {t("delete")} + + +
- -
+
+ ); }, @@ -410,10 +401,10 @@ const ScriptCard = ({ }: ScriptCardProps) => { const { t } = useTranslation(); - // Sensors — move them here (or even higher in parent) so they're stable + // 传感器 —— 放在这里(或更高层父组件)以保持稳定引用 const sensors = useSensors( useSensor(PointerSensor, { - activationConstraint: { distance: 3 }, // ← prevents accidental drag on click + activationConstraint: { distance: 3 }, // 防止点击时误触发拖拽 }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, diff --git a/src/pages/options/routes/ScriptList/ScriptTable.tsx b/src/pages/options/routes/ScriptList/ScriptTable.tsx index d9d64a5b3..f9982ba81 100644 --- a/src/pages/options/routes/ScriptList/ScriptTable.tsx +++ b/src/pages/options/routes/ScriptList/ScriptTable.tsx @@ -104,22 +104,11 @@ const DraggableContainer = React.forwardRef(...refs: React.Ref[]): (node: T | null) => void { - return (node) => { - for (const ref of refs) { - if (typeof ref === "function") { - ref(node); - } else if (ref) { - (ref as React.MutableRefObject).current = node; - } - } - }; -} - -const DraggableRow = React.forwardRef< - HTMLTableRowElement, - { record: ScriptLoading; index: number } & React.HTMLAttributes ->(({ record, index: _index, ...rest }, ref) => { +const DraggableRow = ({ + record, + index: _index, + ...rest +}: { record: ScriptLoading; index: number } & React.HTMLAttributes) => { const sortable = useSortable({ id: record.uuid }); const { setNodeRef, transform, transition, listeners, setActivatorNodeRef } = sortable; @@ -128,8 +117,6 @@ const DraggableRow = React.forwardRef< transition, }; - const mergedRef = React.useMemo(() => composeRefs(setNodeRef, ref), [setNodeRef, ref]); - const ctxValue = useMemo( () => ({ listeners: listeners, @@ -140,10 +127,11 @@ const DraggableRow = React.forwardRef< return ( - + ); -}); +}; + DraggableRow.displayName = "DraggableRow"; const DragHandle = () => {