diff --git a/src/pages/options/routes/ScriptList/ScriptCard.tsx b/src/pages/options/routes/ScriptList/ScriptCard.tsx index 41f151e52..5132ca0d8 100644 --- a/src/pages/options/routes/ScriptList/ScriptCard.tsx +++ b/src/pages/options/routes/ScriptList/ScriptCard.tsx @@ -33,6 +33,11 @@ import type { SearchType } from "@App/app/service/service_worker/types"; type DragCtx = Pick, "listeners" | "setActivatorNodeRef"> | null; const SortableDragCtx = createContext(null); +type DraggableEntryProps = { + recordUUID: string; + children: React.ReactElement; +}; + function composeRefs(...refs: React.Ref[]): (node: T | null) => void { return (node) => { for (const ref of refs) { @@ -45,38 +50,44 @@ function composeRefs(...refs: React.Ref[]): (node: T | null) => void { }; } -type DraggableEntryProps = { recordUUID: string } & React.HTMLAttributes; - -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, // Merge existing styles transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, zIndex: isDragging ? 10 : "auto", }; + const ref = (children as any).ref; + // Extract the child's existing ref and compose it with dnd-kit 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, + ...children.props, + ref: mergedRef, + style, + })} ); -}); -DraggableEntry.displayName = "DraggableEntry"; +}; +DraggableEntry.displayName = "DraggableEntry"; const DragHandle = () => { const sortable = useContext(SortableDragCtx); @@ -162,205 +173,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")} + + +
- -
+
+ ); },