Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 5 additions & 27 deletions src/pages/options/routes/ScriptList/ScriptCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import type { DragEndEvent } from "@dnd-kit/core";
import { closestCenter, DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { rectSwappingStrategy, SortableContext, sortableKeyboardCoordinates, useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { useAppContext } from "@App/pages/store/AppContext";
import { type SearchFilterRequest } from "./SearchFilter";
import type { SearchType } from "@App/app/service/service_worker/types";

Expand Down Expand Up @@ -410,28 +409,7 @@ const ScriptCard = ({
handleRunStop,
}: ScriptCardProps) => {
const { t } = useTranslation();
const { guideMode } = useAppContext();

// 如果是引导模式,且没有脚本,则创建一条演示数据
const list = useMemo(
() =>
guideMode && scriptList.length === 0
? [
{
uuid: "demo-uuid-1234",
name: "Demo Script",
namespace: "demo",
sort: 0,
createtime: Date.now(),
checktime: Date.now(),
metadata: {},
type: SCRIPT_TYPE_NORMAL,
favorite: [{ match: "Example", icon: "", website: "https://example.com" }],
} as ScriptLoading,
]
: scriptList,
[guideMode, scriptList]
);

// Sensors — move them here (or even higher in parent) so they're stable
const sensors = useSensors(
useSensor(PointerSensor, {
Expand All @@ -442,8 +420,8 @@ const ScriptCard = ({
})
);

// 故意生成一个字串 避免因 list 的参考频繁改动而导致 ctx sortableIds 参考出现非预期更改。
const sortableIdsString = list?.map((s) => s.uuid).join(",") || "";
// 基于 scriptList 的 uuid 生成稳定字串,避免因 scriptList 引用频繁变动导致 ctx 内部 sortableIds 参考出现非预期更改。
const sortableIdsString = scriptList?.map((s) => s.uuid).join(",") || "";

// sortableIds 应该只包含 ID 字符串数组,而不是对象数组,
// 且确保 items 属性接收的是纯 ID 列表,这样 dnd-kit 内部对比更高效。
Expand Down Expand Up @@ -529,7 +507,7 @@ const ScriptCard = ({
padding: "16px",
}}
>
{list.length === 0 ? (
{scriptList.length === 0 ? (
loadingList ? (
<div
style={{
Expand Down Expand Up @@ -566,7 +544,7 @@ const ScriptCard = ({
gap: "16px",
}}
>
{list.map((item) => (
{scriptList.map((item) => (
<ScriptCardItem
key={item.uuid}
item={item}
Expand Down
25 changes: 23 additions & 2 deletions src/pages/options/routes/ScriptList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import type { ScriptLoading } from "@App/pages/store/features/script";

import { type TSelectFilter, useScriptDataManagement, useScriptFilters } from "./hooks";
import { useAppContext } from "@App/pages/store/AppContext";

type TableProps = React.ComponentProps<typeof ScriptTable>;
type CardProps = React.ComponentProps<typeof ScriptCard>;
Expand All @@ -51,12 +52,28 @@

MainContent.displayName = "MainContent";

// 一条演示数据
const guideModeScriptList = [
{
uuid: "demo-uuid-1234",
name: "Demo Script",
namespace: "demo",
sort: 0,
createtime: Date.now(),
checktime: Date.now(),
metadata: {},
type: SCRIPT_TYPE_NORMAL,
favorite: [{ match: "Example", icon: "", website: "https://example.com" }],
} as ScriptLoading,
Comment on lines +55 to +67
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的演示脚本通过 as ScriptLoading 强行断言,但缺少 Script 必填字段(至少 statusrunStatus)。在表格视图里有 a.status - b.status 这类排序逻辑,statusundefined 会产生 NaN,导致排序/筛选行为异常。建议补齐必填字段并避免类型断言(例如给 demo 设置 status: SCRIPT_STATUS_DISABLErunStatus: SCRIPT_RUN_STATUS_COMPLETE 等)。

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2026-02-12 at 18 22 03

@CodFrm 改成 satisfies 就报错了

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

缺少字段,这里只是满足基本展示的示例,用as没关系

];
Comment on lines +55 to +68
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guideModeScriptList 定义在模块顶层且对象会在拖拽排序时被就地修改(例如后面会写入 s.sort = i)。这会让演示数据在组件卸载/重新进入引导模式后保留上一次的排序等状态,属于隐式的跨渲染共享状态。建议改为在组件内按需创建(例如用工厂函数/useMemo 返回新的数组与对象拷贝),避免被后续逻辑意外污染。

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看你要怎么的示例吧
现在的应该没这么多功能...


/**
* 主组件
*/
function ScriptList() {
const { t } = useTranslation();
const [usp] = useSearchParams();
const { guideMode } = useAppContext();

// 1. 基础 UI 状态
const [sidebarOpen, setSidebarOpen] = useState(() => localStorage.getItem("script-list-sidebar") === "1");
Expand Down Expand Up @@ -190,7 +207,11 @@
// 6. 执行过滤逻辑
useEffect(() => {
const { status, type, tags, source } = selectedFilters;
const list = scriptList.filter((s) => {

// 如果是引导模式,且没有脚本,则使用演示数据
const targetList = guideMode && scriptList.length === 0 ? guideModeScriptList : scriptList;

const list = targetList.filter((s) => {
Comment on lines +211 to +214
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里把演示数据注入到 filterScriptList 后,卡片/表格里的启用、删除、拖拽排序等操作仍会按 uuid 调用后端接口;但 demo 的 uuid 并不在真实脚本列表中,容易造成无效请求/错误提示。建议为 demo 增加明确标记(例如 isDemo)并在相关操作入口处禁用或短路处理,避免引导模式下对不存在的脚本执行写操作。

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

還好吧 ..?

if (status !== null) {
if (status === SCRIPT_STATUS_ENABLE || status === SCRIPT_STATUS_DISABLE) {
if (s.status !== status) return false;
Expand Down Expand Up @@ -221,7 +242,7 @@
return () => {
enableKeywordSearch = false;
};
}, [scriptList, selectedFilters, stats, searchRequest]);
}, [guideMode, scriptList, selectedFilters, stats, searchRequest]);

// 处理 URL 传参打开配置
useEffect(() => {
Expand All @@ -235,7 +256,7 @@
}
});
}
}, []);

Check warning on line 259 in src/pages/options/routes/ScriptList/index.tsx

View workflow job for this annotation

GitHub Actions / Run tests

React Hook useEffect has a missing dependency: 'usp'. Either include it or remove the dependency array

return (
<Card id="script-list" className="script-list" style={{ height: "100%", overflowY: "auto" }}>
Expand Down
Loading