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
6 changes: 6 additions & 0 deletions src/pages/install/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@

useEffect(() => {
initAsync();
}, []);

Check warning on line 184 in src/pages/install/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

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

const [watchFile, setWatchFile] = useState(false);
const metadataLive = useMemo(() => (scriptInfo?.metadata || {}) as SCMetadata, [scriptInfo]);
Expand Down Expand Up @@ -216,7 +216,7 @@
}

return permissions;
}, [scriptInfo, metadataLive]);

Check warning on line 219 in src/pages/install/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

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

const description = useMemo(() => {
const description: JSX.Element[] = [];
Expand Down Expand Up @@ -247,7 +247,7 @@
}

return description;
}, [scriptInfo, metadataLive]);

Check warning on line 250 in src/pages/install/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

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

const antifeatures: { [key: string]: { color: string; title: string; description: string } } = {
"referral-link": {
Expand Down Expand Up @@ -292,7 +292,7 @@
if (upsertScript) {
document.title = `${!isUpdate ? t("install_script") : t("update_script")} - ${i18nName(upsertScript!)} - ScriptCat`;
}
}, [isUpdate, scriptInfo, upsertScript]);

Check warning on line 295 in src/pages/install/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

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

// 设置脚本状态
useEffect(() => {
Expand Down Expand Up @@ -442,6 +442,11 @@
}
}

async function onWatchFileError() {
// e.g. NotFoundError
setWatchFile(false);
}

const memoWatchFile = useMemo(() => {
return `${watchFile}.${scriptInfo?.uuid}.${localFileHandle?.name}`;
}, [watchFile, scriptInfo, localFileHandle]);
Expand All @@ -458,6 +463,7 @@
uuid,
fileName,
setCode: onWatchFileCodeChanged,
onFileError: onWatchFileError,
};
// 进行监听
startFileTrack(handle, ftInfo);
Expand Down Expand Up @@ -490,7 +496,7 @@
return () => {
unmountFileTrack(handle);
};
}, [memoWatchFile]);

Check warning on line 499 in src/pages/install/App.tsx

View workflow job for this annotation

GitHub Actions / Run tests

React Hook useEffect has missing dependencies: 'localFileHandle', 'scriptInfo?.uuid', 'setupWatchFile', and 'watchFile'. Either include them or remove the dependency array

return (
<div id="install-app-container">
Expand Down
65 changes: 50 additions & 15 deletions src/pkg/utils/file-tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,64 @@ export type FTInfo = {
fileName: string;
setCode(code: string, hideInfo?: boolean): void;
lastModified?: number;
onFileError(): void;
};

const getHandleRecord = async (root: FileSystemFileHandle, observer: FileSystemObserverInstance) => {
for (const [fileHandle, ftInfo, fileObserver] of handleRecords) {
if (fileObserver !== observer) continue;
try {
const isSame = await root.isSameEntry(fileHandle);
if (isSame) {
return ftInfo;
}
} catch (e) {
// 捕捉非预期错误
console.warn(e);
}
}
return null;
};

const callback = async (records: FileSystemChangeRecord[], observer: FileSystemObserverInstance) => {
for (const record of records) {
const { root, type } = record;
if (!(root instanceof FileSystemFileHandle) || type !== "modified") continue;
for (const [fileHandle, ftInfo, fileObserver] of handleRecords) {
if (fileObserver !== observer) continue;
try {
for (const record of records) {
const { root, type } = record;
if (!(root instanceof FileSystemFileHandle)) continue;
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

移除了 type !== "modified" 的检查,现在任何类型的变更事件都会被处理。这是一个重要的行为变更。建议在代码注释中说明为什么要处理所有类型的事件(包括 "appeared"、"disappeared"、"errored"、"moved" 等),特别是明确说明如何处理 "disappeared" 和 "moved" 事件,以符合 PR 描述中"对于改名或档案移动等,则不会继续监听"的设计意图。

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.

PR有寫啦

// 只要 FileSystemObserver 侦测到档案改变,就试一下找记录和读档
const ftInfo = await getHandleRecord(root, observer);
// 如没有记录则忽略
if (!ftInfo) continue;
let file: File | null = null;
try {
const isSame = await root.isSameEntry(fileHandle);
if (!isSame) continue;
// 调用安装
const file = await root.getFile();
// 避免重复更新
if (ftInfo.lastModified === file.lastModified) continue;
ftInfo.lastModified = file.lastModified;
const code = await file.text();
if (code && typeof code === "string") {
ftInfo.setCode(code, false);
const fRead = await root.getFile();
if (fRead && fRead.lastModified > 0 && fRead.size > 0) {
// 有档案内容读取权限,排除空档案
file = fRead;
}
} catch (e) {
// 档案改名或删掉时,或会被此捕捉(预期报错)
console.warn(e);
unmountFileTrack(root);
ftInfo.onFileError();
}
// 如读档失败则忽略
if (!file) continue;
// 如成功读档但显示为失败,则重新 observe
if (type === "errored") {
observer.observe(root);
}
// 以 lastModified 判断避免重复更新
if (ftInfo.lastModified === file.lastModified) continue;
ftInfo.lastModified = file.lastModified;
const code = await file.text();
if (code && typeof code === "string") {
ftInfo.setCode(code, false);
}
}
} catch (e) {
// 捕捉非预期错误
console.warn(e);
}
};

Expand All @@ -49,6 +83,7 @@ export const unmountFileTrack = async (fileHandle: FileSystemFileHandle) => {
}
}
} catch (e) {
// 捕捉非预期错误
console.warn(e);
}
return false;
Expand Down
Loading