Skip to content

V0.6.3#543

Open
maotoumao wants to merge 49 commits intomasterfrom
dev
Open

V0.6.3#543
maotoumao wants to merge 49 commits intomasterfrom
dev

Conversation

@maotoumao
Copy link
Owner

No description provided.

@safe1ine
Copy link

safe1ine commented Feb 6, 2026

@MonkeyCode-AI review 一下

@MonkeyCode-AI
Copy link

MonkeyCode-AI 正在分析任务...

Copy link

@MonkeyCode-AI MonkeyCode-AI left a comment

Choose a reason for hiding this comment

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

我是 MonkeyCode AI 编程助手,你可以在 GitHub 仓库的 PR 中 at @MonkeyCode-AI 来呼唤我。

任务执行细节请参考: https://monkeycode-ai.com/tasks/public?id=3bf6c2c9-0e32-4b48-8aa6-cb803e5c869d

代码审查结果

PR 0.6.3-beta.1 引入 telemetry 与歌单管理/排序重构整体方向合理,但存在封面保存路径错误、潜在崩溃/泄漏与类型不兼容等问题,需修复后再合并。

✨ 代码亮点

  • 将错误/性能数据上报统一封装到 telemetry,并在 ErrorBoundary 与 bootstrap 关键路径上打点,便于定位线上问题
  • SortableFlatList 重构为基于 gesture+FlashList 的 SortableFlashList,避免旧实现对触摸/滚动的复杂耦合
  • 新增歌单管理页(sheetEditor)与未保存变更拦截(beforeRemove + SimpleDialog),提升可用性
  • 权限页新增电池优化相关能力(Android),并补齐 Native 模块接口
🚨 Critical ⚠️ Warning 💡 Suggestion
3 0 0

Comment on lines +77 to +82
MusicSheet.updateMusicSheetBase(musicSheet.id, {
coverImg: newCoverImg ? addRandomHash(newCoverImg) : undefined,
}).then(() => {
Toast.success(t("editMusicSheetInfo.toast.success"));
});

Choose a reason for hiding this comment

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

Caution

🚨 更新歌单封面写入了错误的路径(使用了未复制的 source uri),导致封面更新可能无效

setCoverImageHandler 中当用户选择新图片时,会把图片复制到 targetImagePath,但 updateMusicSheetBase 里写入 coverImg 时使用的是 addRandomHash(newCoverImg)。newCoverImg 仍然是原始选择的 uri(可能是 content:// 或临时 uri),而不是复制后的 targetImagePath。结果:Android content:// 很可能无法在后续稳定读取;即使复制成功也没有使用复制后的本地路径;resetCover 分支与复制分支行为不一致。应当在复制成功后,用 targetImagePath(再 addRandomHash)写入歌单封面。

建议: 将 updateMusicSheetBase 的 coverImg 来源改为复制后的 targetImagePath(或 reset 时为 undefined),不要使用原始 newCoverImg。

Suggested change
MusicSheet.updateMusicSheetBase(musicSheet.id, {
coverImg: newCoverImg ? addRandomHash(newCoverImg) : undefined,
}).then(() => {
Toast.success(t("editMusicSheetInfo.toast.success"));
});
// 更新歌单信息
MusicSheet.updateMusicSheetBase(musicSheet.id, {
coverImg: resetCover
? undefined
: (newCoverImg && newCoverImg !== musicSheet?.coverImg
? addRandomHash(targetImagePath)
: (newCoverImg ? addRandomHash(newCoverImg) : undefined)),
}).then(() => {
Toast.success(t("editMusicSheetInfo.toast.success"));
});

Comment on lines +193 to +194
draggingElementOffsetValue.value = Math.min(Math.max(evt.y - itemHeightValue.value / 2, 0), (listLayout!.height - itemHeightValue.value));
}

Choose a reason for hiding this comment

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

Caution

🚨 对 listLayout 进行了非空断言但 onUpdate 仍可能在 listLayout 为 null 时触发,存在崩溃风险

onUpdate 内部使用 (listLayout!.height - itemHeightValue.value) 做上界,但 gesture 的 enabled(!!listLayout) 与 shouldCancelWhenOutside(false) 不能保证回调期间 listLayout 永远非空(例如 layout 变化、卸载、首次拖拽触发时序),会导致空指针崩溃。

建议: 在 onUpdate 中显式检查 listLayout 是否存在;不存在时直接 return。

Suggested change
draggingElementOffsetValue.value = Math.min(Math.max(evt.y - itemHeightValue.value / 2, 0), (listLayout!.height - itemHeightValue.value));
}
const onUpdate = (evt: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
if (!listLayout) {
return;
}
// 移动高亮元素位置
if (draggingIndexRef.current !== -1) {
draggingElementOffsetValue.value = Math.min(
Math.max(evt.y - itemHeightValue.value / 2, 0),
listLayout.height - itemHeightValue.value,
);
}
};


// 自动滚动
const listRef = useRef<FlashList<T>>(null);
const scrollTimerRef = useRef<NodeJS.Timeout>();

Choose a reason for hiding this comment

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

Caution

🚨 在 React Native 环境中使用 NodeJS.Timeout 类型不兼容,可能导致 TS 编译/类型检查失败

scrollTimerRef 声明为 useRef<NodeJS.Timeout>()。React Native/TypeScript 环境里 setInterval 返回类型通常是 number(或 ReturnType),NodeJS.Timeout 依赖 node 类型声明,容易造成类型不一致。

建议: 改成 ReturnType(或 number)以兼容 RN。

Suggested change
const scrollTimerRef = useRef<NodeJS.Timeout>();
const scrollTimerRef = useRef<ReturnType<typeof setInterval> | undefined>();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants